Repository navigation
Conversation
The release-docs workflow runs in a checkout of main and extracted the release tag with `tar -x -C dist/docs/<version>` into a directory that did not exist yet. That always failed and fell through to an unconditional fallback that extracted the tag over main's own docs/ tree, then moved the merged result into the snapshot. Every page that exists only on main ended up in the frozen "<version>" snapshot: the 3.2.4 snapshot PR carried five (reference/trust-json, the training-agent GCS runbook and three 3.3 story pages) and the merged 3.1.27 snapshot carries about fifty 3.2 and 3.3 pages. Extract through scripts/extract-release-docs-snapshot.sh instead. It extracts `git archive <ref> -- docs` into an empty directory, leaves the checkout's docs/ untouched, and fails closed unless the snapshot's file list equals the ref's. The only exception is the three 3.3 preview story pages that the stable 3.2 navigation already links; a stable 3.2.x snapshot carries exactly those, loudly and covered by tests, until the preview group is removed from the navigation. Existing dist/docs snapshots are not changed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated path requires human/CODEOWNERS approval.
This PR modifies .github/workflows/release-docs.yml, which matches the deterministic hard approval gate (gated_paths: true). review_decision is REVIEW_REQUIRED, not APPROVED, so the gate is NOT satisfied and the outcome must be escalate per decision table row 2.
Escalation reasons
.github/workflows/release-docs.ymlis under a hard approval gate (.github/workflows/**); human/CODEOWNERS review is required before merge.
The change itself looks clean: it replaces broken inline release-docs extraction with scripts/extract-release-docs-snapshot.sh, which extracts a git archive of the ref into an empty dir and fails closed unless the file list matches the tag. Exactness checks cover files and symlinks with matching collation and core.quotepath=off; the 3.3-preview exception is gated, logged, and fail-closed; tests cover exactness, tag-wins-over-main, checkout-untouched, stale replacement, and fail-closed paths. No Critical/High/Medium findings, no changeset required (not protocol-scoped). Once a human/CODEOWNERS approval lands, this is approvable.
Why human review
- .github/workflows/release-docs.yml is under a hard approval gate (.github/workflows/**) and review_decision is REVIEW_REQUIRED — human/CODEOWNERS approval required before merge.
- This PR touches a path under a hard, non-overridable approval gate (.github/workflows/release-docs.yml (modified) matches
.github/workflows/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
…mmitted A rerun of the release-docs workflow on a version whose dist/docs snapshot is already tracked in the checkout would delete and rewrite a published, immutable release record. The extraction script now fails before touching it when the snapshot exists in the HEAD tree or the index. Only untracked output left by an interrupted run is replaced. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated path requires human/CODEOWNERS approval.
This PR modifies .github/workflows/release-docs.yml, which matches the hard, path-based approval gate .github/workflows/** (gated_paths: true). The current GitHub review_decision is REVIEW_REQUIRED, not APPROVED, so the gate is not satisfied and Ladon cannot auto-approve regardless of how clean the diff is.
The change itself is sound: the reviewer found no blocking issues. The delta adds a fail-closed immutability guard to scripts/extract-release-docs-snapshot.sh (checks both HEAD tree and index for dist/docs/<version> before any mutation, so published snapshots can never be rewritten and rm -rf only reaches untracked scratch), plus two well-constructed tests (committed, staged, different-ref rerun; bytes and git status asserted unchanged). This aligns with the immutable-released-artifacts floor. No critical/high/medium findings surfaced.
Escalation reasons
.github/workflows/release-docs.yml(modified) is under a hard approval gate (.github/workflows/**) andreview_decisionisREVIEW_REQUIRED, notAPPROVED. A human/CODEOWNERS approval must be recorded before this can merge.
Once a human/CODEOWNERS approval lands, this PR should fall through to approve on its next run — the diff is clean with no actionable findings.
Why human review
- .github/workflows/release-docs.yml is under a hard approval gate (.github/workflows/**) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval is required before merge.
- This PR touches a path under a hard, non-overridable approval gate (.github/workflows/release-docs.yml (modified) matches
.github/workflows/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
The frozen docs snapshot for 3.2.4 (bot PR #8150) failed its checks because the release-docs workflow leaks main-only pages into it. This fixes the extraction. It does not touch any existing
dist/docs/<semver>snapshot.Root cause
release-docs.ymlruns in a checkout ofmainand didgit archive "$SOURCE_REF" -- docs | tar -x -C "dist/docs/$VERSION" --strip-components=1 || { …fallback… }. The target directory does not exist yet, sotar -Calways fails and the fallback always runs: it extracts the tag over main's owndocs/tree andmv docs/*s the merged result into the snapshot. Every page that exists only on main lands in the "frozen" snapshot. Reproduced locally: 393 files forv3.2.4, whose tag has 388.Effects found:
dist/docs/3.2.4) carries 5 pages not in the tag:reference/trust-json(the actualbroken-links/nav-coverage failure),runbooks/training-agent-gcs-reporting.md, and the three 3.3 preview pages.v3.1.27tag (3.2 and 3.3 pages). It is immutable and not changed here; whether and how to treat it is a maintainer decision.The other #8150 failures ("Missing runtime schema snapshot 3.2.4" in the production docs index smoke and the dependent server tests) are fixed by the 3.2.4 forward merge, #8153, not by this PR.
Change
scripts/extract-release-docs-snapshot.shextractsgit archive <ref> -- docsinto an empty directory, leaves the checkout'sdocs/untouched, and fails closed unless the snapshot's file list equals the ref's.3.2.xsince chore(docs): sync 3.2.3 maintenance snapshot navigation #8000) links a "3.3 preview" group (reference/whats-new-in-3-3,reference/3-3-beta,reference/migration/3-2-to-3-3). A stable3.2.xsnapshot carries exactly those three from the checkout, logged, with their development-only warnings, until that nav group is removed. Nothing else leaks. Removing the group and this list is a docs-owner decision I did not make here.dist/docs/<version>is already tracked in the checkout's HEAD tree or index, so a rerun can never rewrite a published snapshot. Only untracked scratch output from an interrupted run is replaced. A regression commits a published snapshot, reruns extraction (same and different ref), expects failure, and verifies the bytes and git status are unchanged.release-docs.ymlcalls the script;tests/extract-release-docs-snapshot.test.cjscovers exactness, tag-wins-over-main, other lines carry nothing, checkout untouched, stale-snapshot replacement, fail-closed cases, and that the workflow no longer has the overlay fallback. Wired intonpm test.Evidence
main: exact-tag extraction + the existing link rewrite +update-release-docs-nav.mjs 3.2.4 3.2gives 391 files (388 + the 3 preview pages), anddocs-nav-validationpasses 49/49 (trust-json is reported as awaiting the next snapshot, as designed). The result matches chore: snapshot docs for v3.2.4 #8150's tree except it dropstrust-jsonand the runbook, and the two preview pages are newer because main moved;docs.json,.dockerignore,llms-current.mdandschema-tools.tsmatch chore: snapshot docs for v3.2.4 #8150 exactly.No changeset: the files are not protocol-scoped (
check-changeset-protocol-scopepasses).Follow-ups (not in this PR)
release-docs.ymlis identical on3.2.x; therelease: publishedevent runs the tag's workflow copy, so cherry-pick to3.2.xafter this lands for the next 3.2.x snapshot.release-docs.ymlfor3.2.4onmain. It reuses the branchauto/docs-v3.2.4, so the existing bot PR is updated rather than replaced.🤖 Generated with Claude Code