pr-publication-safety
SkillMediaUse when changing PR body rendering, home-path redaction, artifact path publication, or pipeline-attestation markers.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the pr-publication-safety skill
What this skill tells your AI
The instructions your AI receives, as published by kunchenguid/no-mistakes in .agents/skills/pr-publication-safety/SKILL.md and read by ahel’s review.
Home-Path Redaction in Published PR Content (security)
internal/safepathis the one owner of home-directory redaction, the path analogue ofinternal/safeurl.RedactTextrewrites the process's own home plus/home/<user>,/Users/<user>, andC:\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 offilepath.IsAbs/VolumeNameand of any reliance onfilepath.Clean's separator normalisation: those answer for the build platform, and on WindowsIsAbsdiscards the POSIX-rootedHOMEthat Git Bash, MSYS2, and Cygwin set - silently disabling redaction instead of failing. Regression:TestUsableHomeCandidate_AcceptsBothPlatformSpellings,TestHomeCandidates_AreSeparatorSpellingIndependent.PRStep.buildPRContentis the single render boundary: it drafts throughdraftPRContentand returnsredactPRContent(content), andExecutepublishes exactly that. Every source that can reach a PR body - agent prose, extracted intent, findings, fix summaries, step errors, artifactpath, artifact captions, and captured output embedded from evidence files - is covered there, so a new rendering path cannot reintroduce the leak. Redaction runs after every length cap, which is only safe because the placeholder is never longer than the path it replaces.- The
artifacts[].pathdescription intestFindingsSchema(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 thepr.goboundary'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 theinternal/safepathpackage 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_shain 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 (
appendGeneratedSectionsToCleanBodyWithinLimitplus the two intent paths), never per render path.pipelineMDalone carries the real marker and is left intact;BuildPipelineSummaryForneutralizes its own step-detail blocks, which quote agent text. A first attempt put this inescapePipelineFoldMarkers- per-render-path - and shipped three live foreign markers to #831 anyway. Regressions:TestPRStep_ForeignAttestationsInEveryComponentDoNotShadowTheRealOne(all components at once), plus the per-component guards inpr_test.go. - Regressions:
internal/safepath/redact_test.go,internal/pipeline/steps/pr_homepath_test.go.
Signals
- GitHub stars
- 8k
- Forks
- 855
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
pr-publication-safety- Source
- github.com/kunchenguid/no-mistakes