Repository navigation
docs(releases-maintenance): three sentences still describe the pre-ADR-0125 publish lane — "both lanes are workflow_dispatch" and a typed-version GA dispatch that no longer exists #11239
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentation
on Aug 23, 2026 Triage:
pm:queue,domain:devx, Task — lands indocs/releases-maintenance.md, mechanism prose only. Constraints the dispatcher must carry: ① the 2026-08-07「版本发布必须是人工的」ruling quotation is preserved verbatim — the correction is to the mechanism sentences around it, never the ruling text; ② serial/rebase constraint with in-flight PR #11238 (same file, same sections) — land after it or rebase onto it; fold-or-serial is the devx seat's five-gate call at claim time.
Generated by Claude Code
Claim: devx lane PM seat, session
e2eac1a7-8000-5c95-9749-38aec2ace6fc, branchclaude/issue-11239-releases-maintenance-publish-lane.⚠️ Thecontent/docs/releases/rule and why this card is allowed under it.CLAUDE.mdforbids touching release pages as a rider on code changes, because release notes are compiled centrally and the currentreleases/v<major>.mdxis the repo's hottest conflict magnet. It explicitly permits the other route: "If you believe a releases page has a factual error, file an issue or make it a dedicated docs-only PR — never a rider on code changes."This card is that route: an issue was filed, and its PR must be docs-only and carry nothing else. ⛔ Do not add a changeset, do not touch code, do not fold in any other correction you notice — report those instead.
If you are a different session and you see this comment before starting work, this card is taken — pick another.
Generated by Claude Code
{
"issue": 11239,
"status": "done",
"branch": "claude/issue-11239-releases-maintenance-publish-lane",
"pr": "#11818",
"premise_still_valid": true,
"summary": "All three sentences were still wrong on origin/main (7e83932) and all three are corrected in docs/releases-maintenance.md — NOT in content/docs/releases/, which is untouched (the file is the repo-level maintenance playbook, 12 commits in its whole history, so this PR does not go near the conflict magnet CLAUDE.md protects). Docs-only: one file, no code, no changeset, no workflow, no test. The workflows AGREE with ADR-0125, so the docs were the drifted party and the correction is to the ADR as written: release.yml carrieson: push: branches: [main]+environment: releaseon the publish job (D1/D2) and a workflow_dispatch whose inputs areforceandrefresh_version_prwith NOversioninput (D4); cut-rc.yml is still dispatch-only with a required typedversion, so every rc half is unchanged. The 2026-08-07 ruling quotation is byte-identical to origin/main (sha256 of the extracted quotation matches); only the mechanism prose around it changed. Blocking constraint from the card's triage cleared: #11238 MERGED as 3ece770 and is in this branch's base, so no rebase was needed and no conflict exists.",
"tests": "Docs-only card; no package tests apply. Gate families derived, not recalled:node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no hand-typed path list; script takes the change set from the merge base) -> 4 matched, re-derived AFTER the final commit and unchanged ('change set derived from git - 1 path(s) vs merge base 7e83932'; 'committed 1, working tree 0, untracked 0'). ALL GATES RUN AT FINAL COMMIT 75e91e8, exit codes captured before any pipe, verdict lines quoted from the gates themselves (never a bare $?): check:doc-authoring -> '✓ doc authoring guard: 389 files clean - no bare metadata literals.'; check:doc-formula-expressions -> '✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 421 files / 1448 TS blocks judged clean by @objectstack/formula.'; check:required-contexts -> '✓ check-required-contexts: 6 required context name(s) pinned across 2 workflow(s); 5 instruction surface(s) scanned against 2 retired name(s) (#9491).' (same script is the required-set-patrol.yml roster entry); check:nul-bytes -> 'check-nul-bytes: OK (scanned 6589 text file(s) -- 6589 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).'. Every --self-test leg green first (doc-formula 50 cases, required-contexts 150 assertions, nul-bytes 75 assertions, doc-authoring green). Dependency closure BUILT BEFORE JUDGING:pnpm --filter '@objectstack/lint...' buildexit 0, so no gate read a stale dist; the --filter echoed its script name ('> @objectstack/lint@17.2.0 check:doc-formula-expressions'), guarding the zero-match-filter-exits-0 trap. Both heavy runs via scripts/pm/os-verify-lock.sh: 'VERDICT command-exit 0 - held the lock 5s - waited 188s (3m08s)' (install) and 'VERDICT command-exit 0 - held the lock 127s (2m07s) - waited 0s' (build); the 3m08s wait was spent on lock-free work per the queueing rule, not idling. NARROWING DECLARED AND MEASURED (repo-widepnpm lint), three pieces: (1) population read from eslint's own config resolution -npx eslint --no-inline-config --format json docs/releases-maintenance.mdreturns 'File ignored because no matching configuration was supplied', i.e. the changed file is outside the linted population entirely; (2) file count read from --format json: 1 file, 0 errors, 1 warning (that notice); (3) config invariance: the diff changes no eslint config, no TS and no JS, so no untouched file's verdict can move. CONTROLS - counts that must not move, and did not: ruling quotation 1 -> 1 AND byte-identical (sha256 6b3293fc2fe9993d14637e15ee0bf6a45fba95281b0f660e1ff8f5e88efe9fa3 before and after); 'three lanes' (the release.yml lane count asserted at the end of the same section) 1 -> 1; files changed 1. Declared as MOVED BY DESIGN, not offered as a control: '#11233' 3 -> 4, because the new parenthetical in sentence 1 cites it for the schedule trigger. POSITIVE CONTROLS - every zero paired with a probe shown able to fire: grep 'Both lanes areworkflow_dispatch' -> 0 PAIRED WITH grep 'Both lanes are' -> 1 (same file, same tool); grep 'then dispatch |' -> 0 PAIRED WITH grep 'approve thereleaseenvironment |' -> 1; grep 'Run workflow** with the version' -> 0 PAIRED WITHgrep -rn 'Run workflow' docs/adr/0125-*.md-> 2 hits on a page I did NOT touch (its Before column and its Alternatives section), so the probe pattern demonstrably fires; control-byte self-scangrep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]'-> no match (exit 1) PAIRED WITH check:nul-bytes' 75-assertion self-test, which includes the red-when-injected leg. On-disk proof of each edit was anchored to the text being replaced (removed-text count -> 0 AND injected-text count -> 1 for all three), not inferred from an editor exit code; the edit script additionally asserted each anchor matched exactly once and aborted otherwise.",
"open_questions": [],
"out_of_scope_findings": [
"NOT FILED - the dispatch explicitly reserved filing to the PM ('Report it; I will file it'), which narrows my standing rule to file findings as unassigned issues. Flagging the conflict rather than silently picking a side; say the word and I will file all three.",
"AGENTS.md Prime Directive #15 (line 194) is stale in the SAME drift class as this card, different file: 'That PR is bot-authored and standing-open by design: it is regenerated on every push tomain'. Since #11233/#11238 version-pr runs on a 6-hourly schedule plus an on-demand refresh_version_pr dispatch, never on push. The rest of that directive is current (it already names ADR-0125 and the approval act).",
"docs/adr/0125-release-approval-gate-replaces-the-typed-version.md line 3 still reads 'Status: Proposed (2026-08-20) - awaiting the maintainer's hand-merge, which is itself the acceptance act for a governed surface' - but the hand-merge happened and the implementation is on main (release.yml references ADR-0125 11 times). The status line was never flipped to Accepted, so the record that is now the authority for the publish lane still describes itself as pending.",
"docs/releases-maintenance.md paragraph ordering in Cutting a GA release: the 'Merge the version packages PR ...' instruction sits in the intro paragraph, BEFORE the paragraph headed 'First, check #4935 is current' that #11238 appended. Cosmetic, pre-existing, deliberately not reordered here - reordering is a second correction and this PR is only permitted because it carries one."
]
}
Generated by Claude Code
Filed unassigned by the dev agent on #11233 as an out-of-scope finding. Not caused by that card's change, and deliberately not fixed in its PR (#11238): these predate it, one sits inside the 2026-08-07 ruling narrative, and correcting them is a separate reading of ADR-0125.
What is stale
ADR-0125 (2026-08-20) moved
release.yml'spublishjob offworkflow_dispatchand ontopush, replacing the typed-version confirmation with two acts: merge the Version Packages PR (the decision), approve thereleaseenvironment (the authorisation).release.yml's own header says so at length.docs/releases-maintenance.mdwas not updated to match, and still carries three claims from the previous design:§Cutting a release, immediately under the rc-vs-GA table:
Half wrong since ADR-0125.
cut-rc.ymlis still dispatch-only, butrelease.yml's publish lane is started by a push to main (it is then held at the environment gate). The environment-gate half is correct and is now the whole barrier —release.yml's header states exactly that.The same table's Trigger row for GA: "merge the Version Packages PR, then dispatch".
§Cutting a GA release: "then Actions → Release → Run workflow with the version
mainnow carries" — the typed version this instructs a releaser to supply was removed by ADR-0125 D2; the run they would start is the repair lane, not the normal GA path.Why it is worth fixing rather than leaving
(3) is the one with teeth: a releaser following the written procedure dispatches a workflow looking for a version field that is gone, on a lane that is not the GA path. (1) reads as an invariant and will be quoted as one — it is adjacent to the 「版本发布必须是人工的」 ruling, which is itself unchanged and must stay verbatim.
Care required
The 2026-08-07 ruling quotation must be preserved word for word (it is quoted, not paraphrased, in both
release.ymland this doc). The correction is to the mechanism sentences around it, not to the ruling: after ADR-0125 the human act moved, the requirement that there be a human act did not.Note on adjacent state
#11238 (for #11233) is in flight against the same file and moves
version-pronto a schedule; it updates only the sentences its own change falsifies. Whoever takes this should rebase onto it to avoid a conflict in §Why this lane exists and §Cutting a GA release.