CtrlK
BlogDocsLog inGet started
Tessl Logo

pr-publication-safety

Use when changing PR body rendering, home-path redaction, artifact path publication, pipeline-attestation markers, or pre-push attestation.

SKILL.md
Quality
Evals
Security

Home-Path Redaction in Published PR Content (security)

  • internal/safepath is the one owner of home-directory redaction, the path analogue of internal/safeurl. RedactText rewrites the process's own home plus /home/<user>, /Users/<user>, and C:\Users\<user> to ~, unconditionally and for every occurrence. Add new shapes there rather than scrubbing paths at a call site. Candidate resolution must stay free of filepath.IsAbs/VolumeName and of any reliance on filepath.Clean's separator normalisation: those answer for the build platform, and on Windows IsAbs discards the POSIX-rooted HOME that Git Bash, MSYS2, and Cygwin set - silently disabling redaction instead of failing. Regression: TestUsableHomeCandidate_AcceptsBothPlatformSpellings, TestHomeCandidates_AreSeparatorSpellingIndependent.
  • redactPRContent in pr.go owns the publication redaction boundary. PRStep.buildPRContent uses it for ordinary drafts; template creation and live author-preserving updates use it through composeOwnedPRContent before stamping their byte-integrity guard. Every source that can reach a PR body - agent prose, extracted intent, findings, fix summaries, step errors, artifact path, artifact captions, and captured output embedded from evidence files - is covered there, so a new rendering path cannot reintroduce the leak. Ordinary drafts redact after length caps (the placeholder never grows a path); template composition redacts before its integrity guard and fail-closed size check. pr_ownership.go owns that marked-appendix contract: never feed live author text through heading-based stripping/clamping, and keep rebindOwnedPRAttestation in the pre-push restamp path so its integrity guard remains valid. Regressions: pr_template_test.go, pr_ownership_test.go.
  • The artifacts[].path description in testFindingsSchema (common.go) must not solicit absolute paths, and must not forbid them either. The renderer's allowlist is the worktree or the run's evidence directory and a path under neither is dropped, while the evidence directory defaults under the operator's home - so soliciting more just re-supplies what the boundary has to strip, and a blanket "never report a home directory path" clause makes an obedient agent drop its own evidence. Publication safety is the pr.go boundary's job; the schema only stops soliciting paths from elsewhere on the machine. Regressions: TestTestFindingsSchema_DoesNotSolicitAbsolutePaths, TestTestFindingsSchema_KeepsEvidenceDirectoryPathsReportable.
  • Two other public surfaces deliberately do NOT share this rendering and are not covered: agent-authored commit subjects (commitAgentFixes -> Commit.RenderFixMessage), which reach the remote through Push, and the opt-in evidence branch (test.evidence.store_in_repo), which copies artifact files verbatim. Keep the internal/safepath package doc honest about that scope.
  • The PR body must contain exactly ONE live pipeline-attestation marker, the run's own. require-no-mistakes (.github/actions/require-no-mistakes/verify.py) binds the FIRST marker in the RAW body to the PR head, so a foreign copy placed earlier fails a PR the pipeline did produce - and a code fence is no defense, because that scan is raw text. Step agents embed foreign markers routinely, by capturing a generated PR body as evidence.
  • A CI repair that publishes a new head rewrites only that live marker's head_sha in the current PR body (restampPublishedAttestation) and does not send a title. It never inserts a marker that was not already there. Hosts without a PR content reader skip the restamp instead of failing the push. Regressions: TestCIStep_PublishRepairRebindsAttestationAcrossRepairPushes, TestCIStep_PublishRepairDoesNotMintAttestation, TestCIStep_PublishRepairSkipsRestampWithoutReader, TestRestampPRAttestation_PreservesContentEditedWhilePreparingRewrite, TestUpdatePROmitsTitleWhenEmpty.
  • Neutralize at the assembly choke point (appendGeneratedSectionsToCleanBodyWithinLimit plus the two intent paths), never per render path. pipelineMD alone carries the real marker and is left intact; BuildPipelineSummaryFor neutralizes its own step-detail blocks, which quote agent text. A first attempt put this in escapePipelineFoldMarkers - per-render-path - and shipped three live foreign markers to #831 anyway. Regressions: TestPRStep_ForeignAttestationsInEveryComponentDoNotShadowTheRealOne (all components at once), plus the per-component guards in pr_test.go.
  • Regressions: internal/safepath/redact_test.go, internal/pipeline/steps/pr_homepath_test.go.

Pre-Push Pipeline Attestation

  • publishRunHead must write an existing PR attestation for the proposed head before pushing it on every supported provider with raw content reads. docs/src/content/docs/reference/repo-config.md (pr.template) owns provider-specific ownership/budget and visible Bitbucket metadata caveats. The protocol has single-publisher scope because the daemon enforces one active run per repository branch; do not add cross-publisher coordination without a separate requirement. Detailed behavior is owned by docs/src/content/docs/reference/pipeline-steps.md; local rationale lives in attestHeadBeforePush and publishRunHead. Regressions: TestPushStep_AttestsHeadBeforePush, TestPushStep_AttestationWriteFailureAbortsBeforePush, TestPushStep_UnavailableSCMLeavesStaleAttestationFailingClosed, TestPushStep_PushFailureAfterAttestationLeavesBodyAhead, and TestCIStep_PublishRepairRebindsAttestationAcrossRepairPushes.
Repository
kunchenguid/no-mistakes
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.