From e544b02a2bd266c9f7f07de28eec272ea11e7676 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 20:39:40 +0200 Subject: [PATCH 1/5] Rebuild daily release PRs with canonical changelog metadata --- .agents/pm/features/pm-github-c093.toon | 11 +- .agents/pm/history/pm-github-c093.jsonl | 4 + .agents/pm/history/pm-github-l1ot.jsonl | 10 ++ .agents/pm/history/pm-github-sagl.jsonl | 2 + .agents/pm/issues/pm-github-l1ot.toon | 21 +++- .agents/pm/tasks/pm-github-sagl.toon | 13 +++ .github/workflows/release.yml | 86 ++++++++-------- CHANGELOG.md | 1 + docs/daily-release-refresh.md | 127 ++++++++++++++++++++++++ scripts/daily-release-plan.ts | 22 ++++ test/daily-release-plan.test.ts | 44 ++++++++ 11 files changed, 288 insertions(+), 53 deletions(-) create mode 100644 .agents/pm/history/pm-github-sagl.jsonl create mode 100644 .agents/pm/tasks/pm-github-sagl.toon create mode 100644 docs/daily-release-refresh.md create mode 100644 scripts/daily-release-plan.ts create mode 100644 test/daily-release-plan.test.ts diff --git a/.agents/pm/features/pm-github-c093.toon b/.agents/pm/features/pm-github-c093.toon index d847dcc4..7a5931e5 100644 --- a/.agents/pm/features/pm-github-c093.toon +++ b/.agents/pm/features/pm-github-c093.toon @@ -6,9 +6,11 @@ status: in_progress priority: 2 tags[4]: changelog-unreleased,fidelity,github,import created_at: "2026-10-16T22:29:39.865Z" -updated_at: "2026-10-17T13:40:47.560Z" +updated_at: "2026-10-18T18:29:20.384Z" +assignee: codex-agent +claim_principal: codex-agent author: codex-agent -comments[35]{created_at,author,text}: +comments[37]{created_at,author,text}: "2026-10-16T22:30:04.918Z",codex-agent,"Read all twelve unresolved Sourcery threads and the changed tracker/changelog files in the six consumer sync PRs. Scope: fix import only; preserve append-only history and leave unrelated closeout work untouched. The pinned SDK exposes completedAt but reserves created_at, updated_at and closed_at; source timestamp metadata plus an explicit SDK-gap receipt is required unless a supported import path proves otherwise. No upstream SDK issue will be filed under the queue rules." "2026-10-16T22:35:10.689Z",codex-agent,"Found public SDK import primitives beyond high-level create/update: item locks, canonical document serialization, before/after history entries and appendHistoryEntry. Implementing an idempotent finalization event with real native dates and source metadata, without modifying any historical record. Existing provider owners receive provenance links only; their content, native lifecycle, release and export identity remain authoritative. Local Git calendar tag dates select the first release at or after source closure; later closures remain pending. GraphQL ClosedEvent closer provides actual closing PR attribution where REST commit_id is null." "2026-10-16T23:09:24.995Z",codex-agent,"SDK candidate: bulk compensation captures native updated_at and passes it to restore as a history timestamp. Backdating that field disconnects the rollback version from its event. Preserve source creation/closure/completion natively for momentum and cycle time, and retain the exact source update date in github_updated_at while native updated_at stays the SDK mutation clock. Lifecycle finalization now runs at the SDK committing transition before the journal commits, with real compensation acceptance and a post-recovery idempotent check. No historical entries are rewritten." @@ -44,6 +46,8 @@ comments[35]{created_at,author,text}: "2026-10-17T12:18:26.459Z",codex-agent,"Focused branch repair proof passes 3/3 under c8: refused cancellation, refused provider linking, and identity edge cases with undefined github_url. V8 receipts show execution of the previously uncovered locator fallback and the refused-link throw at index.ts:3470. Test compilation and lint pass. No production logic changed after the four behavioral-revert controls; only provider-fixture identity and an absent-value case were corrected. Starting a clean full npm release:check with CI identity, then the independent Bun release:check at unchanged policy." "2026-10-17T13:12:31.216Z",codex-agent,"Clean CI-identity npm run release:check PASSED on installed Node 26: 797/797 tests, zero failures/skips/cancellations/TODOs. Exact all-source coverage across 14 authored modules: 10438/10438 lines and statements, 273/273 functions, 3157/3157 branches. Type checks, docstrings, lint, zero duplication, privacy, production audit, package dry-run, changelog and publish attestation all passed. Starting the independent literal bun run release:check sequentially with fresh HOME and disabled global/system Git identity; policy, SDK pins and package lock remain unchanged." "2026-10-17T13:40:46.635Z",codex-agent,"Round 1 implementation and local verification complete. Both literal CI-identity release gates PASSED: npm run release:check and bun run release:check each 797/797 tests, zero failures/skips/cancellations/TODOs, exact 100/100/100/100 across 14 authored modules (10438/10438 lines/statements, 273/273 functions, 3157/3157 branches). Audit found zero vulnerabilities; docstrings, lint, duplication, privacy, packing, changelog and attestation pass. Four function-only behavioral reverts produced the expected assertion failures. README partial-write and empty-plan qualifications are verified with real trackers. Marker startup probe is bounded separately while retaining its 10-second work deadline and a forced-spin control. Existing pm-github-sah1 remains open for its original acceptance-watchdog case. Releasing the coding claim for orchestrator verification; next actions are commit/push, replies to the five original review threads, and bounded CI monitoring. No items will be closed." + "2026-10-18T18:19:03.447Z",codex-agent,"Read-only real-public-data verification will use main build and dry-run gated plans in scratch clones. Caller blockers: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Evidence will compare source dates, release placement and pm-brief momentum without editing consumer checkouts." + "2026-10-18T18:28:36.151Z",codex-agent,"Main dc86e83 built without importer source changes. Live public dry-run gated atomic plans completed for pm-csv (3 issues), pm-brief (2), and pm-context (5; 2 new open plus 3 existing terminal). All 8 previously terminal imports match source created_at, closed_at, github_state and github_updated_at; durable tracker fingerprints are unchanged. Projected completed_at follows the existing adapter source closure assignment; no importer apply ran. Real pm-changelog stdin rendering includes every projected historical item under its explicit containing release and none under Unreleased. Real pm-brief summarizeMomentum reports GitHub lifetimes of 1.2 to 7.0 days instead of the old zero-day imports (or distorted older owners). No import defect found; no import-fix PR is needed." files[13]{path,scope}: import-fidelity.ts,project index.ts,project @@ -61,6 +65,7 @@ files[13]{path,scope}: tests[2]{command,scope,timeout_seconds,provenance{author,created_at,source_kind,source_ref}}: node --test test/import-fidelity.test.ts,project,2400,codex-agent,"2026-10-16T23:09:21.738Z",local_mutation,feat/import-fidelity "node --test --test-name-pattern=\"closure evidence accepts forward skew\" test/import-fidelity.test.ts",project,2400,codex-agent,"2026-10-17T10:34:46.689Z",local_mutation,feat/import-fidelity -docs[1]{path,scope}: +docs[2]{path,scope}: + docs/daily-release-refresh.md,project README.md,project body: "" diff --git a/.agents/pm/history/pm-github-c093.jsonl b/.agents/pm/history/pm-github-c093.jsonl index 4330645d..5d0158d5 100644 --- a/.agents/pm/history/pm-github-c093.jsonl +++ b/.agents/pm/history/pm-github-c093.jsonl @@ -49,3 +49,7 @@ {"hash_algorithm":"sha256","ts":"2026-10-17T13:12:31.216Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"043799c84ec1b103f8c35f0e","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/33","value":{"created_at":"2026-10-17T13:12:31.216Z","author":"codex-agent","text":"Clean CI-identity npm run release:check PASSED on installed Node 26: 797/797 tests, zero failures/skips/cancellations/TODOs. Exact all-source coverage across 14 authored modules: 10438/10438 lines and statements, 273/273 functions, 3157/3157 branches. Type checks, docstrings, lint, zero duplication, privacy, production audit, package dry-run, changelog and publish attestation all passed. Starting the independent literal bun run release:check sequentially with fresh HOME and disabled global/system Git identity; policy, SDK pins and package lock remain unchanged."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:12:31.216Z"}],"before_hash":"eda66d60618d714f8bc540625a1e17949764590b8058bcf4058fa5e169a7b503","after_hash":"15d3771447836a04a8d8d93aa07103d64ef82555944ad4d94eda34693d63a34b","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"d7ffa4ecbcc242ef81fa861f9e9def70e993fb9fa4f326249266bb910cea4bff"} {"hash_algorithm":"sha256","ts":"2026-10-17T13:40:46.635Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"043799c84ec1b103f8c35f0e","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/34","value":{"created_at":"2026-10-17T13:40:46.635Z","author":"codex-agent","text":"Round 1 implementation and local verification complete. Both literal CI-identity release gates PASSED: npm run release:check and bun run release:check each 797/797 tests, zero failures/skips/cancellations/TODOs, exact 100/100/100/100 across 14 authored modules (10438/10438 lines/statements, 273/273 functions, 3157/3157 branches). Audit found zero vulnerabilities; docstrings, lint, duplication, privacy, packing, changelog and attestation pass. Four function-only behavioral reverts produced the expected assertion failures. README partial-write and empty-plan qualifications are verified with real trackers. Marker startup probe is bounded separately while retaining its 10-second work deadline and a forced-spin control. Existing pm-github-sah1 remains open for its original acceptance-watchdog case. Releasing the coding claim for orchestrator verification; next actions are commit/push, replies to the five original review threads, and bounded CI monitoring. No items will be closed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:40:46.635Z"}],"before_hash":"15d3771447836a04a8d8d93aa07103d64ef82555944ad4d94eda34693d63a34b","after_hash":"8752acecb505866e371a3e567e7c4375cfa45ea1290de8f620209e2b89f43a96","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"a4636433cd6c133621a7791c6fff8c19ae1a52bb5188255b3e376bbf9c6949f5"} {"hash_algorithm":"sha256","ts":"2026-10-17T13:40:47.560Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"043799c84ec1b103f8c35f0e","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"release","patch":[{"op":"remove","path":"/metadata/claim_principal"},{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:40:47.560Z"}],"before_hash":"8752acecb505866e371a3e567e7c4375cfa45ea1290de8f620209e2b89f43a96","after_hash":"43ab1cf609be9527eb33197c9943ff1aa96cdd5df31993ed6ace87854ec18ff5","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"c6cc15ecd82ea75538882b5f650496b3dafafbd2c5a30bf5fc26107b2c9982a3"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:18:52.826Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:18:52.826Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"43ab1cf609be9527eb33197c9943ff1aa96cdd5df31993ed6ace87854ec18ff5","after_hash":"ccf913de56ca9f01b100a0ee8a012f6ed68b13245e2bc7e869e955117debcfa8","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"7496d943913d1b94e3a28ff3afdafbceb8e5e009422b3a7decf3635165a0906d"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:19:03.447Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/35","value":{"created_at":"2026-10-18T18:19:03.447Z","author":"codex-agent","text":"Read-only real-public-data verification will use main build and dry-run gated plans in scratch clones. Caller blockers: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Evidence will compare source dates, release placement and pm-brief momentum without editing consumer checkouts."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:19:03.447Z"}],"before_hash":"ccf913de56ca9f01b100a0ee8a012f6ed68b13245e2bc7e869e955117debcfa8","after_hash":"a248e86243a0ebd975cf3bcb98113dae05fee44c46cd9da1598c32f18e7e9850","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"6a5624ec341a812f9f975169e5a3d5fc540af618dbc33fe911e4fe8ab800c967"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:28:36.151Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/36","value":{"created_at":"2026-10-18T18:28:36.151Z","author":"codex-agent","text":"Main dc86e83 built without importer source changes. Live public dry-run gated atomic plans completed for pm-csv (3 issues), pm-brief (2), and pm-context (5; 2 new open plus 3 existing terminal). All 8 previously terminal imports match source created_at, closed_at, github_state and github_updated_at; durable tracker fingerprints are unchanged. Projected completed_at follows the existing adapter source closure assignment; no importer apply ran. Real pm-changelog stdin rendering includes every projected historical item under its explicit containing release and none under Unreleased. Real pm-brief summarizeMomentum reports GitHub lifetimes of 1.2 to 7.0 days instead of the old zero-day imports (or distorted older owners). No import defect found; no import-fix PR is needed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:28:36.151Z"}],"before_hash":"a248e86243a0ebd975cf3bcb98113dae05fee44c46cd9da1598c32f18e7e9850","after_hash":"8285da5cbd858b07e58aad96e2fd8c33ee6a42bde54da3d900d104a3fff6cc32","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"2ca46efc180655b236dd30a7a63724a069dbdfeaddb3cedf27332ab55336bec8"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:29:20.384Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/docs/0/path","value":"docs/daily-release-refresh.md"},{"op":"add","path":"/metadata/docs/1","value":{"path":"README.md","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:29:20.384Z"}],"before_hash":"8285da5cbd858b07e58aad96e2fd8c33ee6a42bde54da3d900d104a3fff6cc32","after_hash":"12984bb7416ac210dfcb792e8baa55b1b30fa0d32ec6706c8d9f10b612ad24ca","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"7fac4370a11d171307b09f46c654c7693870bac42e42dd80636d77dc4f8493f9"} diff --git a/.agents/pm/history/pm-github-l1ot.jsonl b/.agents/pm/history/pm-github-l1ot.jsonl index fd910068..f3f07be1 100644 --- a/.agents/pm/history/pm-github-l1ot.jsonl +++ b/.agents/pm/history/pm-github-l1ot.jsonl @@ -1,2 +1,12 @@ {"hash_algorithm":"sha256","ts":"2026-10-15T09:25:36.259Z","author":"claude-hub","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-opus-5-5","agent_model_source":"probe","agent_instance":"0400d60929071b1beaa422c1","agent_provenance":{"model":{"value":"claude-opus-5-5","source":"probe"},"effort":{"value":"xhigh","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.300","source":"probe"}},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-l1ot"},{"op":"add","path":"/metadata/title","value":"The daily release regenerates the changelog with a different status filter than release:check, so an open item delivered since the last tag fails the release"},{"op":"add","path":"/metadata/description","value":"On 2026-10-15 the scheduled pm-github release (run 38705391245) failed in Run release checks with 'Changelog is out of date'. The release step 'Generate changelog and release notes' runs npx pm-changelog in replace mode with its default closed-only status filter, then npm run release:check runs changelog:check through scripts/generate-changelog.ts, which passes closed plus every status present in the tracker. pm-github-wrmt (delivered by PR 122) was still in_progress, so it appeared only in the check's output and the release aborted after bumping in the runner (nothing was published). The release workflow and the package scripts must generate the changelog through one code path (the repo's changelog:full script), so a release cannot fail on a disagreement between two generators of the same file."},{"op":"add","path":"/metadata/type","value":"Issue"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":1},{"op":"add","path":"/metadata/tags","value":["changelog","release"]},{"op":"add","path":"/metadata/created_at","value":"2026-10-15T09:25:36.259Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-10-15T09:25:36.259Z"},{"op":"add","path":"/metadata/author","value":"claude-hub"},{"op":"add","path":"/metadata/acceptance_criteria","value":"release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item delivered since the last tag either succeeds or fails before any bump with a clear reason"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"4893666f20619a1aec9c36e63192f424dc722126aa2ab719bd27f450df629136","item_hash_version":3,"message":"","context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"claude_session_file","rule_version":"v1"},"version":{"status":"resolved","resolver":"claude_session_file","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"83936020b2f64b50ccbc46b83862dbe2d776bda868257e725086d32eda46e1e8"} {"hash_algorithm":"sha256","ts":"2026-10-15T10:59:09.456Z","author":"claude-hub","author_source":"asserted","agent_harness":"claude-code","agent_model":"claude-fable-5-1","agent_model_source":"probe","agent_instance":"288a1bcb65e947ca3afe5490","agent_provenance":{"model":{"value":"claude-fable-5-1","source":"probe"},"effort":{"value":"high","source":"environment"},"role":{"value":"implementer","source":"argv"},"topic":null,"version":{"value":"2.1.300","source":"probe"}},"op":"update","patch":[{"op":"replace","path":"/metadata/acceptance_criteria","value":"release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-15T10:59:09.456Z"},{"op":"replace","path":"/metadata/description","value":"On 2026-10-15 the scheduled pm-github release (run 38705391245) failed in Run release checks with 'Changelog is out of date'. The release step 'Generate changelog and release notes' runs npx pm-changelog in replace mode with its default closed-only status filter, then npm run release:check runs changelog:check through scripts/generate-changelog.ts, which retains closed items and non-closed items tagged changelog-unreleased, then passes closed plus the statuses of those retained items. pm-github-wrmt (delivered by PR 122) was still in_progress and had the changelog-unreleased tag, so it appeared only in the check's output and the release aborted after bumping in the runner (nothing was published). The release workflow and the package scripts must generate the changelog through one code path (the repo's changelog:full script), so a release cannot fail on a disagreement between two generators of the same file."},{"op":"replace","path":"/metadata/title","value":"The daily release regenerates the changelog with a different status filter than release:check, so an open changelog-unreleased item delivered since the last tag fails the release"}],"before_hash":"4893666f20619a1aec9c36e63192f424dc722126aa2ab719bd27f450df629136","after_hash":"8c5e53ac241315dc9a1e0966dc657addaae0acfefc57378b32d5221ec1e5e383","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"claude_session_file","rule_version":"v1"},"version":{"status":"resolved","resolver":"claude_session_file","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"7960c9e95fadb1406ae59b63b6fb9b5e2c1cd0d35dde09c5857e35a1b1bf58f9"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:18:44.974Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:18:44.974Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"8c5e53ac241315dc9a1e0966dc657addaae0acfefc57378b32d5221ec1e5e383","after_hash":"6be47f0ad862456a282aa85e2f515a7affd903e70014cc2e1334683fde2cc4a9","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"4480e51e5a5983b4bf9639e0ed889ba016bcc2fd31fe8ae60852509e20b471c9"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:18:48.628Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:18:48.628Z"},{"op":"replace","path":"/metadata/status","value":"in_progress"}],"before_hash":"6be47f0ad862456a282aa85e2f515a7affd903e70014cc2e1334683fde2cc4a9","after_hash":"062d9d69e13dbbec7a7978d72b91ce59a9a27c691b169a5d36a0fd914268e3d6","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"293679935d4e56473e6a6ebea7c3cb08f5153a1e332d472895a749daf2042d59"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:19:00.875Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:19:00.875Z"},{"op":"add","path":"/metadata/comments","value":[{"created_at":"2026-10-18T18:19:00.873Z","author":"codex-agent","text":"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33"}]}],"before_hash":"062d9d69e13dbbec7a7978d72b91ce59a9a27c691b169a5d36a0fd914268e3d6","after_hash":"4f5a307868932555a0af1a27e0fdfabbf8457368708511945067a60ea54c9979","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"d826f9797b3e42951fe9b7e5e0bf07836530b7c80e2c6b389d100a7739f944cd"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:20:41.085Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:20:41.085Z"},{"op":"replace","path":"/metadata/tags/1","value":"changelog-unreleased"},{"op":"add","path":"/metadata/tags/2","value":"release"}],"before_hash":"4f5a307868932555a0af1a27e0fdfabbf8457368708511945067a60ea54c9979","after_hash":"52d3979af7c5f7073941e08b42ba93c6db11fd9b303ea10f440052de8d098c80","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"69d5780a5e32c9e342a84917be1655d6d2f1835a05fd7dc0c12f9ac5f409800d"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:20:45.969Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:20:45.969Z"},{"op":"add","path":"/metadata/files","value":[{"path":".github/workflows/release.yml","scope":"project"},{"path":"scripts/daily-release-plan.ts","scope":"project"},{"path":"test/daily-release-plan.test.ts","scope":"project"}]}],"before_hash":"52d3979af7c5f7073941e08b42ba93c6db11fd9b303ea10f440052de8d098c80","after_hash":"8c694e3621c8008f3ff0f0916299d46861b8a62b5af298cb3768f6661ebd156f","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"646ee3d2e4319507beab55d841d80e6c8ad50093336c141ece5ba98b6c4f861b"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:20:50.727Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"tests_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:20:50.727Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"node --test test/daily-release-plan.test.ts test/release-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T18:20:50.608Z","source_kind":"local_mutation","source_ref":"fix/daily-release-refreshes-stale-pr"}}]}],"before_hash":"8c694e3621c8008f3ff0f0916299d46861b8a62b5af298cb3768f6661ebd156f","after_hash":"14b66fceb96225b9b5e329f4f65588cc4947bc44629e691d33775f0ceae4b477","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"3864a64cc6bc9c3f7b1e12f3f7a87553dab7e4ff1215bf3acf9240b91577cee4"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:22:11.208Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/1","value":{"created_at":"2026-10-18T18:22:11.207Z","author":"codex-agent","text":"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:22:11.208Z"}],"before_hash":"14b66fceb96225b9b5e329f4f65588cc4947bc44629e691d33775f0ceae4b477","after_hash":"d37f55f40cabb30052615a7f6728750ef3d4cbaef8382aa677c6aff86a16cf0c","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"d137e91b92d65a6f85a97f4c49ee07dd8ee778a0e5f56c8f7cadf424de8cbad4"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:29:34.750Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:29:34.750Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/daily-release-refresh.md","scope":"project"}]}],"before_hash":"d37f55f40cabb30052615a7f6728750ef3d4cbaef8382aa677c6aff86a16cf0c","after_hash":"5816a8ee0bfaffaa0038f8dc8d9220ecb5720eb454745a82c9baaf019cf7eafd","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"eda1159068ec256356ea6b6a11eca8e34d57a0ca1d87e628b5cb4fc233967848"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:32:32.900Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/2","value":{"created_at":"2026-10-18T18:32:32.900Z","author":"codex-agent","text":"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:32:32.900Z"}],"before_hash":"5816a8ee0bfaffaa0038f8dc8d9220ecb5720eb454745a82c9baaf019cf7eafd","after_hash":"87b5f34ee5b3c38fc3654b77410f7fa2e34567e9ecc2346c35a414093c62eec0","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"6f27859fa3771d93e2efe1f9867ffa36fbb6cbab2bc7c53175b243c603584f57"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:34:34.711Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/3","value":{"created_at":"2026-10-18T18:34:34.710Z","author":"codex-agent","text":"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:34:34.711Z"}],"before_hash":"87b5f34ee5b3c38fc3654b77410f7fa2e34567e9ecc2346c35a414093c62eec0","after_hash":"20fae5b27385d4ef9bcca8afcda0440fbddf347223fa98316fabfb35e2d74594","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"94809b69378897c00cdf822a8934a9e17b29ad0a55c27d770068a76e8303762d"} diff --git a/.agents/pm/history/pm-github-sagl.jsonl b/.agents/pm/history/pm-github-sagl.jsonl new file mode 100644 index 00000000..17945f11 --- /dev/null +++ b/.agents/pm/history/pm-github-sagl.jsonl @@ -0,0 +1,2 @@ +{"hash_algorithm":"sha256","ts":"2026-10-18T18:32:44.499Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-sagl"},{"op":"add","path":"/metadata/title","value":"Audit copied fleet release workflows for canonical generation and one daily publication"},{"op":"add","path":"/metadata/description","value":"Read-only inventory found 25 sibling workflows with the same numeric-suffix decision block. No shared release template exists in pm-ops. Use the sibling inventory in docs/daily-release-refresh.md to plan package-owned follow-up work without modifying other repositories in the current task."},{"op":"add","path":"/metadata/type","value":"Task"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":2},{"op":"add","path":"/metadata/tags","value":[]},{"op":"add","path":"/metadata/created_at","value":"2026-10-18T18:32:44.499Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-10-18T18:32:44.499Z"},{"op":"add","path":"/metadata/author","value":"codex-agent"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"23bec3bcd7f2942dc14cc4043cd0c21fa2f7e66a8a1f1d1e71ea678486a16e92","item_hash_version":3,"message":"","context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"b7986d02b1b3498de2d67f2e4d44aec8bc0f7b8b492514ff10133b5e447ceede"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:34:24.577Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:34:24.577Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/daily-release-refresh.md","scope":"project"}]}],"before_hash":"23bec3bcd7f2942dc14cc4043cd0c21fa2f7e66a8a1f1d1e71ea678486a16e92","after_hash":"3de444fe01e06f0697cbb202ea6efc7cce878903a04ff0ce2fa12f3025858269","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"754955ca6100249170a1175a6ff204cb18edb50025e7bc8912d47137994d1966"} diff --git a/.agents/pm/issues/pm-github-l1ot.toon b/.agents/pm/issues/pm-github-l1ot.toon index 883c7e0c..16bcd2ab 100644 --- a/.agents/pm/issues/pm-github-l1ot.toon +++ b/.agents/pm/issues/pm-github-l1ot.toon @@ -2,11 +2,26 @@ id: pm-github-l1ot title: "The daily release regenerates the changelog with a different status filter than release:check, so an open changelog-unreleased item delivered since the last tag fails the release" description: "On 2026-10-15 the scheduled pm-github release (run 38705391245) failed in Run release checks with 'Changelog is out of date'. The release step 'Generate changelog and release notes' runs npx pm-changelog in replace mode with its default closed-only status filter, then npm run release:check runs changelog:check through scripts/generate-changelog.ts, which retains closed items and non-closed items tagged changelog-unreleased, then passes closed plus the statuses of those retained items. pm-github-wrmt (delivered by PR 122) was still in_progress and had the changelog-unreleased tag, so it appeared only in the check's output and the release aborted after bumping in the runner (nothing was published). The release workflow and the package scripts must generate the changelog through one code path (the repo's changelog:full script), so a release cannot fail on a disagreement between two generators of the same file." type: Issue -status: open +status: in_progress priority: 1 -tags[2]: changelog,release +tags[3]: changelog,changelog-unreleased,release created_at: "2026-10-15T09:25:36.259Z" -updated_at: "2026-10-15T10:59:09.456Z" +updated_at: "2026-10-18T18:34:34.711Z" +assignee: codex-agent +claim_principal: codex-agent author: claude-hub acceptance_criteria: "release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason" +comments[4]{created_at,author,text}: + "2026-10-18T18:19:00.873Z",codex-agent,"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33" + "2026-10-18T18:22:11.207Z",codex-agent,"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today." + "2026-10-18T18:32:32.900Z",codex-agent,"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected." + "2026-10-18T18:34:34.710Z",codex-agent,"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment." +files[3]{path,scope}: + .github/workflows/release.yml,project + scripts/daily-release-plan.ts,project + test/daily-release-plan.test.ts,project +tests[1]{command,scope,provenance{author,created_at,source_kind,source_ref}}: + node --test test/daily-release-plan.test.ts test/release-workflow.test.ts,project,codex-agent,"2026-10-18T18:20:50.608Z",local_mutation,fix/daily-release-refreshes-stale-pr +docs[1]{path,scope}: + docs/daily-release-refresh.md,project body: "" diff --git a/.agents/pm/tasks/pm-github-sagl.toon b/.agents/pm/tasks/pm-github-sagl.toon new file mode 100644 index 00000000..d7d24a55 --- /dev/null +++ b/.agents/pm/tasks/pm-github-sagl.toon @@ -0,0 +1,13 @@ +id: pm-github-sagl +title: Audit copied fleet release workflows for canonical generation and one daily publication +description: Read-only inventory found 25 sibling workflows with the same numeric-suffix decision block. No shared release template exists in pm-ops. Use the sibling inventory in docs/daily-release-refresh.md to plan package-owned follow-up work without modifying other repositories in the current task. +type: Task +status: open +priority: 2 +tags: [] +created_at: "2026-10-18T18:32:44.499Z" +updated_at: "2026-10-18T18:34:24.577Z" +author: codex-agent +docs[1]{path,scope}: + docs/daily-release-refresh.md,project +body: "" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c045eba..a15e8e8a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,6 +37,13 @@ jobs: fetch-depth: 0 fetch-tags: true + - name: Refresh release base + shell: bash + run: | + set -euo pipefail + git fetch origin main --force + git checkout --detach origin/main + - name: Setup Node.js uses: actions/setup-node@v7 with: @@ -74,54 +81,34 @@ jobs: - name: Decide release id: decide + env: + GH_TOKEN: ${{ github.token }} shell: bash run: | set -euo pipefail git fetch --force --tags - latest_tag="$(git tag --sort=-creatordate | head -n 1 || true)" - if [[ -n "$latest_tag" ]] && git diff --quiet "$latest_tag"..HEAD -- .; then - echo "should_release=false" >> "$GITHUB_OUTPUT" - echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT" - echo "No changes since $latest_tag; skipping release." >> "$GITHUB_STEP_SUMMARY" - exit 0 + latest_tag="$(git tag --sort=-version:refname | head -n 1 || true)" + export RELEASE_TODAY="$(TZ="$RELEASE_TIMEZONE" date +%Y.%m.%d)" + export RELEASE_MAIN_SHA="$(git rev-parse HEAD)" + export RELEASE_LAST_TAG="$latest_tag" + export RELEASE_LAST_SHA="" + if [[ -n "$latest_tag" ]]; then + export RELEASE_LAST_SHA="$(git rev-list -n 1 "$latest_tag")" fi - - release_date="$(TZ="$RELEASE_TIMEZONE" date +%Y.%m.%d)" - base_tag="v${release_date}" - max_suffix=-1 - while IFS= read -r existing_tag; do - if [[ "$existing_tag" == "$base_tag" ]]; then - (( max_suffix < 0 )) && max_suffix=0 - continue - fi - if [[ "$existing_tag" == "$base_tag-"* ]]; then - suffix="${existing_tag#"$base_tag-"}" - if [[ "$suffix" =~ ^[0-9]+$ ]] && (( suffix > max_suffix )); then - max_suffix="$suffix" - fi - fi - done < <(git tag -l "${base_tag}*") - - if (( max_suffix >= 0 )); then - tag="${base_tag}-$((max_suffix + 1))" - else - tag="$base_tag" - fi - - version_core="${tag#v}" - year="${version_core%%.*}" - version_tail="${version_core#*.}" - month="${version_tail%%.*}" - day_and_suffix="${version_tail#*.}" - day="${day_and_suffix%%-*}" - suffix="${day_and_suffix#"$day"}" - npm_version="$((10#$year)).$((10#$month)).$((10#$day))${suffix}" - - echo "should_release=true" >> "$GITHUB_OUTPUT" - echo "latest_tag=$latest_tag" >> "$GITHUB_OUTPUT" - echo "tag=$tag" >> "$GITHUB_OUTPUT" - echo "npm_version=$npm_version" >> "$GITHUB_OUTPUT" - echo "base_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + export RELEASE_EXISTING_PR="$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open \ + --json number,headRefName --jq '[.[] | select(.headRefName | startswith("release/"))][0] // null')" + node --input-type=module <<'NODE' >> "$GITHUB_OUTPUT" + import { decideDailyRelease } from './scripts/daily-release-plan.ts'; + const e = process.env; + const pr = JSON.parse(e.RELEASE_EXISTING_PR); + const plan = decideDailyRelease({ + existingPr: pr && { number: pr.number, branch: pr.headRefName }, + mainSha: e.RELEASE_MAIN_SHA, today: e.RELEASE_TODAY, + lastRelease: e.RELEASE_LAST_TAG ? { tag: e.RELEASE_LAST_TAG, sha: e.RELEASE_LAST_SHA } : null, + }); + for (const [key, value] of Object.entries(plan)) console.log(`${key}=${value}`); + console.log(`latest_tag=${e.RELEASE_LAST_TAG}`); + NODE # Refuse non-main release runs BEFORE publishing. `github.ref` is the # authoritative workflow trigger ref: schedule -> refs/heads/main; @@ -262,9 +249,9 @@ jobs: shell: bash run: | set -euo pipefail - npx pm-changelog --pm-root .agents/pm --mode replace --output CHANGELOG.md --all-release-tags --release-version-from-package --date-from-version --item-url-base https://github.com/unbraind/pm-github/blob/main/.agents/pm --respect-item-release --pm-bin ./node_modules/.bin/pm --pm-arg=--output-budget --pm-arg=unbounded --pm-arg=--output-limit --pm-arg=unbounded --github-step-summary - npx pm-changelog --pm-root .agents/pm --mode replace --output CHANGELOG.md --all-release-tags --release-version-from-package --date-from-version --item-url-base https://github.com/unbraind/pm-github/blob/main/.agents/pm --respect-item-release --pm-bin ./node_modules/.bin/pm --pm-arg=--output-budget --pm-arg=unbounded --pm-arg=--output-limit --pm-arg=unbounded --check - npx pm-changelog --pm-root .agents/pm --stdout --since-previous-tag --until-release-tag --release-version-from-package --date-from-version --item-url-base https://github.com/unbraind/pm-github/blob/main/.agents/pm --respect-item-release --pm-bin ./node_modules/.bin/pm --pm-arg=--output-budget --pm-arg=unbounded --pm-arg=--output-limit --pm-arg=unbounded > RELEASE_NOTES.md + npm run changelog:full -- --github-step-summary + npm run changelog:check + npm run --silent release:notes > RELEASE_NOTES.md - name: Run release checks if: steps.decide.outputs.should_release == 'true' @@ -299,6 +286,7 @@ jobs: RELEASE_BASE_SHA: ${{ steps.decide.outputs.base_sha }} RELEASE_TAG: ${{ steps.decide.outputs.tag }} NPM_VERSION: ${{ steps.decide.outputs.npm_version }} + RELEASE_BRANCH: ${{ steps.decide.outputs.release_branch }} run: | set -euo pipefail git fetch origin main --force @@ -308,7 +296,7 @@ jobs: exit 1 fi - release_branch="release/${RELEASE_TAG#v}" + release_branch="$RELEASE_BRANCH" release_commit="$(git rev-parse HEAD)" if [[ "$release_commit" == "$current_main_sha" ]]; then echo "Release metadata is already present on main; resuming the publish/tag transaction." @@ -346,6 +334,10 @@ jobs: --title "Release pm-github ${RELEASE_TAG}" \ --body "Automated daily release metadata for \`${RELEASE_TAG}\`. The release gate passed before this PR was created; npm publication and tagging remain blocked until this protected PR is merged.")" pr_number="${pr_url##*/}" + else + gh pr edit "$pr_number" --repo "$GITHUB_REPOSITORY" \ + --title "Release pm-github ${RELEASE_TAG}" \ + --body "Automated daily release metadata for \`${RELEASE_TAG}\`, rebuilt from current main. The release gate passed before refresh; publication and tagging wait for the protected PR." fi owner="${GITHUB_REPOSITORY%/*}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e0dc4bf..851129f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed +- The daily release regenerates the changelog with a different status filter than release:check, so an open changelog-unreleased item delivered since the last tag fails the release ([pm-github-l1ot](https://github.com/unbraind/pm-github/blob/main/.agents/pm/issues/pm-github-l1ot.toon)) - Release timeout must report current workflow approval state ([pm-github-b145](https://github.com/unbraind/pm-github/blob/main/.agents/pm/issues/pm-github-b145.toon)) - Preserve legacy GitHub ownership across copied provider examples ([pm-github-b143](https://github.com/unbraind/pm-github/blob/main/.agents/pm/issues/pm-github-b143.toon)) - Reject malformed effective-rule discriminators before closeout ([pm-github-b141](https://github.com/unbraind/pm-github/blob/main/.agents/pm/issues/pm-github-b141.toon)) diff --git a/docs/daily-release-refresh.md b/docs/daily-release-refresh.md new file mode 100644 index 00000000..e1ca9b62 --- /dev/null +++ b/docs/daily-release-refresh.md @@ -0,0 +1,127 @@ +# Daily release refresh and public import evidence + +Unchanged importer source: main `dc86e83be87f915dabef831e720edcf3cdc562e8`. Public API observation: 2026-10-18. + +## Release root cause + +The release job generates closed-only history by invoking pm-changelog directly. Its changelog:check invokes scripts/generate-changelog.ts, which also includes unfinished items tagged changelog-unreleased. After main gains such tracker changes, a later run fails release:check before reaching the existing lease-protected branch push. Date-derived branch selection also abandons an older open PR on the next day; numeric suffixes permit multiple same-day publications. + +The job now fetches current main before preparation and uses the canonical changelog scripts. A pure decision over existing PR, main SHA, last release and today selects the existing release branch for rebuilding, updates its title/version to today and refuses a second version after today has a release tag. A concurrent main update still refuses publication; a subsequent run rebuilds it. + +## Public-data method + +Temporary clones contain the real caller sync PR heads. The unchanged main build runs runImport with state=all, gate=true, atomic=true and dry-run=true against the live API. Certified complete SDK reads and durable tracker fingerprints prove zero durable tracker writes. pm-context also accounts for two new open issues. + +Each historical plan row is projected into real pm-changelog stdin rendering and the actual pm-brief summarizeMomentum export. The renderer must include the item under its explicit containing release and omit it from Unreleased. No importer apply ran. The dry-run schema omits completed_at: below it is explicitly projected from the existing persistImportFidelity assignment, which writes both terminal fields from github_closed_at. Existing real-tracker import-fidelity regressions exercise those durable assignments. + +Baseline Unreleased membership comes from the actual caller PR CHANGELOG.md. All projected GitHub states equal closed; the canceled item retains local status canceled. Momentum observes each source closure plus one second with a 3650-day window, to inspect its historical lifetime; baseline momentum is observed on 2026-10-18. This is not a production now-window throughput claim. + +| Repository | Caller PR head | +| --- | --- | +| unbraind/pm-csv | `fea199155e101b250e34d3fcb5eebda0544b0c42` | +| unbraind/pm-brief | `25495e6b35572d1d7c9218eb91ace4ed5925c9dd` | +| unbraind/pm-context | `7d9ed21dedcf104ab921bc34dc11fd9019738dd6` | + +## Before versus main plan + +| Repo / issue | Field | Caller sync PR | Main plan / projection | +| --- | --- | --- | --- | +| unbraind/pm-csv#72 | created_at | `2026-08-20T19:28:52.262Z` | `2026-08-20T19:42:05Z` | +| unbraind/pm-csv#72 | closed_at | `2026-10-18T07:17:46.393Z` | `2026-08-27T04:12:45Z` | +| unbraind/pm-csv#72 | completed_at | `2026-08-27T04:12:45.000Z` | `2026-08-27T04:12:45Z` | +| unbraind/pm-csv#72 | github_state | `open` | `closed` | +| unbraind/pm-csv#72 | github_updated_at | `2026-08-20T19:42:05Z` | `2026-10-14T11:34:13Z` | +| unbraind/pm-csv#72 | release | `absent` | `v2026.08.28` | +| unbraind/pm-csv#134 | created_at | `2026-10-18T07:17:46.545Z` | `2026-09-23T08:54:00Z` | +| unbraind/pm-csv#134 | closed_at | `2026-10-18T07:17:46.631Z` | `2026-09-25T07:52:12Z` | +| unbraind/pm-csv#134 | completed_at | `2026-09-25T07:52:12.000Z` | `2026-09-25T07:52:12Z` | +| unbraind/pm-csv#134 | github_state | `absent` | `closed` | +| unbraind/pm-csv#134 | github_updated_at | `absent` | `2026-09-25T07:52:12Z` | +| unbraind/pm-csv#134 | release | `absent` | `v2026.09.26` | +| unbraind/pm-csv#86 | created_at | `2026-10-18T07:17:46.426Z` | `2026-08-27T14:29:39Z` | +| unbraind/pm-csv#86 | closed_at | `2026-10-18T07:17:46.520Z` | `2026-09-01T04:51:41Z` | +| unbraind/pm-csv#86 | completed_at | `2026-09-01T04:51:41.000Z` | `2026-09-01T04:51:41Z` | +| unbraind/pm-csv#86 | github_state | `absent` | `closed` | +| unbraind/pm-csv#86 | github_updated_at | `absent` | `2026-09-01T04:51:41Z` | +| unbraind/pm-csv#86 | release | `absent` | `v2026.09.01` | +| unbraind/pm-brief#135 | created_at | `2026-10-18T08:08:52.780Z` | `2026-10-05T05:06:12Z` | +| unbraind/pm-brief#135 | closed_at | `2026-10-18T08:08:52.862Z` | `2026-10-07T12:19:04Z` | +| unbraind/pm-brief#135 | completed_at | `2026-10-07T12:19:04.000Z` | `2026-10-07T12:19:04Z` | +| unbraind/pm-brief#135 | github_state | `absent` | `closed` | +| unbraind/pm-brief#135 | github_updated_at | `absent` | `2026-10-09T09:17:10Z` | +| unbraind/pm-brief#135 | release | `absent` | `v2026.10.08` | +| unbraind/pm-brief#84 | created_at | `2026-10-18T08:08:52.630Z` | `2026-08-25T04:12:33Z` | +| unbraind/pm-brief#84 | closed_at | `2026-10-18T08:08:52.752Z` | `2026-09-01T04:51:37Z` | +| unbraind/pm-brief#84 | completed_at | `2026-09-01T04:51:37.000Z` | `2026-09-01T04:51:37Z` | +| unbraind/pm-brief#84 | github_state | `absent` | `closed` | +| unbraind/pm-brief#84 | github_updated_at | `absent` | `2026-09-01T04:51:37Z` | +| unbraind/pm-brief#84 | release | `absent` | `v2026.09.01` | +| unbraind/pm-context#136 | created_at | `2026-10-12T12:44:54.969Z` | `2026-10-11T10:07:01Z` | +| unbraind/pm-context#136 | closed_at | `2026-10-13T22:21:15.749Z` | `2026-10-13T17:54:36Z` | +| unbraind/pm-context#136 | completed_at | `2026-10-13T22:21:15.749Z` | `2026-10-13T17:54:36Z` | +| unbraind/pm-context#136 | github_state | `absent` | `closed` | +| unbraind/pm-context#136 | github_updated_at | `absent` | `2026-10-14T12:32:31Z` | +| unbraind/pm-context#136 | release | `absent` | `v2026.10.14` | +| unbraind/pm-context#81 | created_at | `2026-10-16T05:55:33.608Z` | `2026-08-27T14:24:37Z` | +| unbraind/pm-context#81 | closed_at | `2026-10-16T05:55:33.687Z` | `2026-09-01T04:51:39Z` | +| unbraind/pm-context#81 | completed_at | `2026-09-01T04:51:39.000Z` | `2026-09-01T04:51:39Z` | +| unbraind/pm-context#81 | github_state | `absent` | `closed` | +| unbraind/pm-context#81 | github_updated_at | `absent` | `2026-09-01T04:51:39Z` | +| unbraind/pm-context#81 | release | `absent` | `v2026.09.06` | +| unbraind/pm-context#53 | created_at | `2026-10-16T05:55:33.525Z` | `2026-08-07T16:55:49Z` | +| unbraind/pm-context#53 | closed_at | `absent` | `2026-08-08T22:24:46Z` | +| unbraind/pm-context#53 | completed_at | `absent` | `2026-08-08T22:24:46Z` | +| unbraind/pm-context#53 | github_state | `absent` | `closed` | +| unbraind/pm-context#53 | github_updated_at | `absent` | `2026-10-14T11:34:09Z` | +| unbraind/pm-context#53 | release | `absent` | `v2026.08.09` | + +| Repo / issue | Unreleased before → main | Momentum cycle days before → main | +| --- | --- | --- | +| unbraind/pm-csv#72 | yes → no | 58.5 → 6.4 | +| unbraind/pm-csv#134 | yes → no | 0 → 2 | +| unbraind/pm-csv#86 | yes → no | 0 → 4.6 | +| unbraind/pm-brief#135 | yes → no | 0 → 2.3 | +| unbraind/pm-brief#84 | yes → no | 0 → 7 | +| unbraind/pm-context#136 | no → no | 1.4 → 2.3 | +| unbraind/pm-context#81 | yes → no | 0 → 4.6 | +| unbraind/pm-context#53 | no → no | 0 → 1.2 | + +## Caller adoption + +https://github.com/unbraind/pm-beads/pull/145, https://github.com/unbraind/pm-brief/pull/154, https://github.com/unbraind/pm-context/pull/147, https://github.com/unbraind/pm-csv/pull/163, https://github.com/unbraind/pm-linear/pull/150, https://github.com/unbraind/pm-slack-standup/pull/127. Publication alone does not update their pins; adoption remains tracked in pm-github-aiok. + +## Copied workflow exposure + +The same numeric-suffix block exists in the following 25 sibling workflows. pm-ops has the copied workflow too, but its only tracked executable template is prepare-merge-driver.ts; no shared release workflow template was found. This patch changes pm-github only. + +- pm-ado +- pm-beads +- pm-brief +- pm-changelog +- pm-context +- pm-csv +- pm-gantt-chart +- pm-graph +- pm-jev +- pm-jira +- pm-linear +- pm-lint +- pm-ops +- pm-presets +- pm-review +- pm-rl +- pm-rust +- pm-slack +- pm-slack-standup +- pm-starter +- pm-swarm +- pm-todos +- pm-ts-starter +- pm-vcs +- pm-web + +## Validation + +Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). Restored release suites pass 13/13. npm and Bun release:check retain unchanged thresholds; final receipts are recorded in the linked tracker items and PR. + +GitHub documents that GITHUB_TOKEN-created pull-request runs may require approval; existing bounded approval diagnostics remain: https://docs.github.com/en/actions/concepts/security/github_token. Refresh correctness does not certify GitHub approval or npm publisher policy. diff --git a/scripts/daily-release-plan.ts b/scripts/daily-release-plan.ts new file mode 100644 index 00000000..1ce99430 --- /dev/null +++ b/scripts/daily-release-plan.ts @@ -0,0 +1,22 @@ +/** Facts needed to rebuild a protected release PR without a second daily publication. */ +export interface DailyReleaseInput { + existingPr: { number: number; branch: string } | null; + mainSha: string; + lastRelease: { tag: string; sha: string } | null; + today: string; +} + +/** Rebuild from current main on every eligible run, reusing even yesterday's open PR. */ +export function decideDailyRelease(input: DailyReleaseInput) { + const version = input.today.split(".").map(Number).join("."); + const releasedVersion = input.lastRelease?.tag.replace(/^v/, "").split("-")[0]?.split(".").map(Number).join("."); + const shouldRelease = releasedVersion !== version && input.lastRelease?.sha !== input.mainSha; + return { + should_release: shouldRelease, + action: !shouldRelease ? "skip" : input.existingPr ? "refresh" : "create", + tag: `v${input.today}`, + npm_version: version, + base_sha: input.mainSha, + release_branch: input.existingPr?.branch ?? `release/${input.today}`, + }; +} diff --git a/test/daily-release-plan.test.ts b/test/daily-release-plan.test.ts new file mode 100644 index 00000000..7d96932d --- /dev/null +++ b/test/daily-release-plan.test.ts @@ -0,0 +1,44 @@ +/** Daily release policy is independent of GitHub and the wall clock. */ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; +import { decideDailyRelease, type DailyReleaseInput } from "../scripts/daily-release-plan.ts"; + +const input: DailyReleaseInput = { existingPr: null, mainSha: "new-main", lastRelease: null, today: "2026.10.18" }; + +test("first release uses today's stable npm version and current main", () => { + assert.deepEqual(decideDailyRelease(input), { should_release: true, action: "create", tag: "v2026.10.18", + npm_version: "2026.10.18", base_sha: "new-main", release_branch: "release/2026.10.18" }); + assert.equal(decideDailyRelease({ ...input, today: "2026.01.02" }).npm_version, "2026.1.2"); +}); + +test("an existing stale PR is rebuilt from current main and today's date", () => { + const plan = decideDailyRelease({ ...input, existingPr: { number: 144, branch: "release/2026.10.17" }, + lastRelease: { tag: "v2026.10.16", sha: "released-main" } }); + assert.equal(plan.action, "refresh"); + assert.equal(plan.should_release, true); + assert.equal(plan.base_sha, "new-main"); + assert.equal(plan.release_branch, "release/2026.10.17"); + assert.equal(plan.tag, "v2026.10.18"); +}); + +test("an unchanged release or a publication already dated today skips, even after new main changes", () => { + for (const tag of ["v2026.10.18", "v2026.10.18-1", "v2026.010.018"]) { + assert.equal(decideDailyRelease({ ...input, lastRelease: { tag, sha: "earlier-main" } }).should_release, false); + } + assert.equal(decideDailyRelease({ ...input, lastRelease: { tag: "v2026.10.17", sha: input.mainSha } }).action, "skip"); +}); + +test("workflow rebuilds before preparation and runs the canonical generator before checks and leased PR refresh", () => { + const workflow = readFileSync(new URL("../.github/workflows/release.yml", import.meta.url), "utf8"); + assert.match(workflow, /import \{ decideDailyRelease \} from '\.\/scripts\/daily-release-plan\.ts'/); + assert.ok(workflow.indexOf("git checkout --detach origin/main") < workflow.indexOf("- name: Install dependencies")); + const generation = workflow.slice(workflow.indexOf("- name: Generate changelog"), workflow.indexOf("- name: Run release checks")); + assert.match(generation, /npm run changelog:full/); + assert.match(generation, /npm run changelog:check/); + assert.match(generation, /npm run --silent release:notes/); + assert.doesNotMatch(generation, /npx pm-changelog/); + assert.match(workflow, /release_branch="\$RELEASE_BRANCH"/); + assert.match(workflow, /--force-with-lease=/); + assert.match(workflow, /gh pr edit "\$pr_number"/); +}); From 12601d6d325d6e6ad1264c0729ff70bb18c90feb Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 20:57:27 +0200 Subject: [PATCH 2/5] Use an auditor-compatible release decision invocation --- .agents/pm/history/pm-github-l1ot.jsonl | 2 ++ .agents/pm/history/pm-github-sagl.jsonl | 1 + .agents/pm/issues/pm-github-l1ot.toon | 6 ++++-- .agents/pm/tasks/pm-github-sagl.toon | 4 +++- .github/workflows/release.yml | 10 +++++----- test/daily-release-plan.test.ts | 2 +- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.agents/pm/history/pm-github-l1ot.jsonl b/.agents/pm/history/pm-github-l1ot.jsonl index f3f07be1..ff6acb70 100644 --- a/.agents/pm/history/pm-github-l1ot.jsonl +++ b/.agents/pm/history/pm-github-l1ot.jsonl @@ -10,3 +10,5 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T18:29:34.750Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:29:34.750Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/daily-release-refresh.md","scope":"project"}]}],"before_hash":"d37f55f40cabb30052615a7f6728750ef3d4cbaef8382aa677c6aff86a16cf0c","after_hash":"5816a8ee0bfaffaa0038f8dc8d9220ecb5720eb454745a82c9baaf019cf7eafd","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"eda1159068ec256356ea6b6a11eca8e34d57a0ca1d87e628b5cb4fc233967848"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:32:32.900Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/2","value":{"created_at":"2026-10-18T18:32:32.900Z","author":"codex-agent","text":"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:32:32.900Z"}],"before_hash":"5816a8ee0bfaffaa0038f8dc8d9220ecb5720eb454745a82c9baaf019cf7eafd","after_hash":"87b5f34ee5b3c38fc3654b77410f7fa2e34567e9ecc2346c35a414093c62eec0","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"6f27859fa3771d93e2efe1f9867ffa36fbb6cbab2bc7c53175b243c603584f57"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:34:34.711Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/3","value":{"created_at":"2026-10-18T18:34:34.710Z","author":"codex-agent","text":"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:34:34.711Z"}],"before_hash":"87b5f34ee5b3c38fc3654b77410f7fa2e34567e9ecc2346c35a414093c62eec0","after_hash":"20fae5b27385d4ef9bcca8afcda0440fbddf347223fa98316fabfb35e2d74594","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"94809b69378897c00cdf822a8934a9e17b29ad0a55c27d770068a76e8303762d"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:48:05.868Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/4","value":{"created_at":"2026-10-18T18:48:05.868Z","author":"codex-agent","text":"PR https://github.com/unbraind/pm-github/pull/149 is open at e544b02a2bd266c9f7f07de28eec272ea11e7676. A fresh --no-local clone passed strict health with required merge drivers in an isolated home. Current-head function-only revert copies fail exactly 2/4 decision tests; positive suites pass 13/13. Independent decision coverage is 22/22 lines and statements, 12/12 branches and 1/1 functions. Full npm/Bun gates and Node 22/26 CI remain in progress; no merge, release dispatch, tag or publish occurred."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:48:05.868Z"}],"before_hash":"20fae5b27385d4ef9bcca8afcda0440fbddf347223fa98316fabfb35e2d74594","after_hash":"5201c16a25b3ad96ecbe4f0431def20e07f2e6b641e0678fbf184cfd64f630f5","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"4d591e0bffaaa3ac6cb291eae816a66a7f6bc1659dd130b15b7fb7997f0b5275"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:57:13.394Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/5","value":{"created_at":"2026-10-18T18:57:13.394Z","author":"codex-agent","text":"CI Node 26 measured exact 100/100/100/100 across all 15 authored modules, but 1 of 897 tests failed: the pinned pm-ops attestation auditor interpreted the new Node heredoc body as shell publish paths. Replaced that heredoc with a single-quoted node -e expression; the canonical auditor now recognizes exactly one publish invocation with provenance. No auditor code, dependency pin, threshold or exclusion was changed. This is a package-owned compatibility workaround for the pinned shell model; full gates are restarting."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:57:13.394Z"}],"before_hash":"5201c16a25b3ad96ecbe4f0431def20e07f2e6b641e0678fbf184cfd64f630f5","after_hash":"b71924a9316c0b133ee8b7a743c9c5f8670577bc12c59d8b5025b7d12af7f27d","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"026baab09626afe6671ba63efda24fd42fe905a51ed9f2ed67ceb01b38e6c7b6"} diff --git a/.agents/pm/history/pm-github-sagl.jsonl b/.agents/pm/history/pm-github-sagl.jsonl index 17945f11..a0f24a95 100644 --- a/.agents/pm/history/pm-github-sagl.jsonl +++ b/.agents/pm/history/pm-github-sagl.jsonl @@ -1,2 +1,3 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T18:32:44.499Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-sagl"},{"op":"add","path":"/metadata/title","value":"Audit copied fleet release workflows for canonical generation and one daily publication"},{"op":"add","path":"/metadata/description","value":"Read-only inventory found 25 sibling workflows with the same numeric-suffix decision block. No shared release template exists in pm-ops. Use the sibling inventory in docs/daily-release-refresh.md to plan package-owned follow-up work without modifying other repositories in the current task."},{"op":"add","path":"/metadata/type","value":"Task"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":2},{"op":"add","path":"/metadata/tags","value":[]},{"op":"add","path":"/metadata/created_at","value":"2026-10-18T18:32:44.499Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-10-18T18:32:44.499Z"},{"op":"add","path":"/metadata/author","value":"codex-agent"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"23bec3bcd7f2942dc14cc4043cd0c21fa2f7e66a8a1f1d1e71ea678486a16e92","item_hash_version":3,"message":"","context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"b7986d02b1b3498de2d67f2e4d44aec8bc0f7b8b492514ff10133b5e447ceede"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:34:24.577Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:34:24.577Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/daily-release-refresh.md","scope":"project"}]}],"before_hash":"23bec3bcd7f2942dc14cc4043cd0c21fa2f7e66a8a1f1d1e71ea678486a16e92","after_hash":"3de444fe01e06f0697cbb202ea6efc7cce878903a04ff0ce2fa12f3025858269","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"754955ca6100249170a1175a6ff204cb18edb50025e7bc8912d47137994d1966"} +{"hash_algorithm":"sha256","ts":"2026-10-18T18:48:31.996Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:48:31.996Z"},{"op":"add","path":"/metadata/comments","value":[{"created_at":"2026-10-18T18:48:31.995Z","author":"codex-agent","text":"Shared-block follow-up only; the current code change is limited to pm-github PR https://github.com/unbraind/pm-github/pull/149. The report names every copied sibling workflow; no pm-ops release template was found and no sibling repository was edited."}]}],"before_hash":"3de444fe01e06f0697cbb202ea6efc7cce878903a04ff0ce2fa12f3025858269","after_hash":"c33fec9226b33533190d8208c064f0bf2193567e4e256a00394bbd3be14176c0","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"e1438142971be65089549dfcf4e7634147b06f6c8d69bec4edb133a40a864e66"} diff --git a/.agents/pm/issues/pm-github-l1ot.toon b/.agents/pm/issues/pm-github-l1ot.toon index 16bcd2ab..67ce4247 100644 --- a/.agents/pm/issues/pm-github-l1ot.toon +++ b/.agents/pm/issues/pm-github-l1ot.toon @@ -6,16 +6,18 @@ status: in_progress priority: 1 tags[3]: changelog,changelog-unreleased,release created_at: "2026-10-15T09:25:36.259Z" -updated_at: "2026-10-18T18:34:34.711Z" +updated_at: "2026-10-18T18:57:13.394Z" assignee: codex-agent claim_principal: codex-agent author: claude-hub acceptance_criteria: "release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason" -comments[4]{created_at,author,text}: +comments[6]{created_at,author,text}: "2026-10-18T18:19:00.873Z",codex-agent,"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33" "2026-10-18T18:22:11.207Z",codex-agent,"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today." "2026-10-18T18:32:32.900Z",codex-agent,"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected." "2026-10-18T18:34:34.710Z",codex-agent,"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment." + "2026-10-18T18:48:05.868Z",codex-agent,"PR https://github.com/unbraind/pm-github/pull/149 is open at e544b02a2bd266c9f7f07de28eec272ea11e7676. A fresh --no-local clone passed strict health with required merge drivers in an isolated home. Current-head function-only revert copies fail exactly 2/4 decision tests; positive suites pass 13/13. Independent decision coverage is 22/22 lines and statements, 12/12 branches and 1/1 functions. Full npm/Bun gates and Node 22/26 CI remain in progress; no merge, release dispatch, tag or publish occurred." + "2026-10-18T18:57:13.394Z",codex-agent,"CI Node 26 measured exact 100/100/100/100 across all 15 authored modules, but 1 of 897 tests failed: the pinned pm-ops attestation auditor interpreted the new Node heredoc body as shell publish paths. Replaced that heredoc with a single-quoted node -e expression; the canonical auditor now recognizes exactly one publish invocation with provenance. No auditor code, dependency pin, threshold or exclusion was changed. This is a package-owned compatibility workaround for the pinned shell model; full gates are restarting." files[3]{path,scope}: .github/workflows/release.yml,project scripts/daily-release-plan.ts,project diff --git a/.agents/pm/tasks/pm-github-sagl.toon b/.agents/pm/tasks/pm-github-sagl.toon index d7d24a55..0eaa97af 100644 --- a/.agents/pm/tasks/pm-github-sagl.toon +++ b/.agents/pm/tasks/pm-github-sagl.toon @@ -6,8 +6,10 @@ status: open priority: 2 tags: [] created_at: "2026-10-18T18:32:44.499Z" -updated_at: "2026-10-18T18:34:24.577Z" +updated_at: "2026-10-18T18:48:31.996Z" author: codex-agent +comments[1]{created_at,author,text}: + "2026-10-18T18:48:31.995Z",codex-agent,"Shared-block follow-up only; the current code change is limited to pm-github PR https://github.com/unbraind/pm-github/pull/149. The report names every copied sibling workflow; no pm-ops release template was found and no sibling repository was edited." docs[1]{path,scope}: docs/daily-release-refresh.md,project body: "" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a15e8e8a..27cfe1fb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,8 +97,8 @@ jobs: fi export RELEASE_EXISTING_PR="$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open \ --json number,headRefName --jq '[.[] | select(.headRefName | startswith("release/"))][0] // null')" - node --input-type=module <<'NODE' >> "$GITHUB_OUTPUT" - import { decideDailyRelease } from './scripts/daily-release-plan.ts'; + node --input-type=module -e ' + import { decideDailyRelease } from "./scripts/daily-release-plan.ts"; const e = process.env; const pr = JSON.parse(e.RELEASE_EXISTING_PR); const plan = decideDailyRelease({ @@ -106,9 +106,9 @@ jobs: mainSha: e.RELEASE_MAIN_SHA, today: e.RELEASE_TODAY, lastRelease: e.RELEASE_LAST_TAG ? { tag: e.RELEASE_LAST_TAG, sha: e.RELEASE_LAST_SHA } : null, }); - for (const [key, value] of Object.entries(plan)) console.log(`${key}=${value}`); - console.log(`latest_tag=${e.RELEASE_LAST_TAG}`); - NODE + for (const [key, value] of Object.entries(plan)) console.log(key + "=" + value); + console.log("latest_tag=" + e.RELEASE_LAST_TAG); + ' >> "$GITHUB_OUTPUT" # Refuse non-main release runs BEFORE publishing. `github.ref` is the # authoritative workflow trigger ref: schedule -> refs/heads/main; diff --git a/test/daily-release-plan.test.ts b/test/daily-release-plan.test.ts index 7d96932d..d830b90a 100644 --- a/test/daily-release-plan.test.ts +++ b/test/daily-release-plan.test.ts @@ -31,7 +31,7 @@ test("an unchanged release or a publication already dated today skips, even afte test("workflow rebuilds before preparation and runs the canonical generator before checks and leased PR refresh", () => { const workflow = readFileSync(new URL("../.github/workflows/release.yml", import.meta.url), "utf8"); - assert.match(workflow, /import \{ decideDailyRelease \} from '\.\/scripts\/daily-release-plan\.ts'/); + assert.match(workflow, /import \{ decideDailyRelease \} from "\.\/scripts\/daily-release-plan\.ts"/); assert.ok(workflow.indexOf("git checkout --detach origin/main") < workflow.indexOf("- name: Install dependencies")); const generation = workflow.slice(workflow.indexOf("- name: Generate changelog"), workflow.indexOf("- name: Run release checks")); assert.match(generation, /npm run changelog:full/); From 3de8cde015db5979d6c0ebc9a749bbccd5656d7d Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Mon, 19 Oct 2026 00:08:07 +0200 Subject: [PATCH 3/5] Record release gates and real import proof receipts --- .agents/pm/features/pm-github-c093.toon | 36 ++++++++++++++++++++----- .agents/pm/history/pm-github-c093.jsonl | 5 ++++ .agents/pm/history/pm-github-l1ot.jsonl | 4 +++ .agents/pm/issues/pm-github-l1ot.toon | 11 ++++---- docs/daily-release-refresh.md | 8 +++++- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/.agents/pm/features/pm-github-c093.toon b/.agents/pm/features/pm-github-c093.toon index 7a5931e5..9d452324 100644 --- a/.agents/pm/features/pm-github-c093.toon +++ b/.agents/pm/features/pm-github-c093.toon @@ -6,11 +6,9 @@ status: in_progress priority: 2 tags[4]: changelog-unreleased,fidelity,github,import created_at: "2026-10-16T22:29:39.865Z" -updated_at: "2026-10-18T18:29:20.384Z" -assignee: codex-agent -claim_principal: codex-agent +updated_at: "2026-10-18T22:04:28.505Z" author: codex-agent -comments[37]{created_at,author,text}: +comments[40]{created_at,author,text}: "2026-10-16T22:30:04.918Z",codex-agent,"Read all twelve unresolved Sourcery threads and the changed tracker/changelog files in the six consumer sync PRs. Scope: fix import only; preserve append-only history and leave unrelated closeout work untouched. The pinned SDK exposes completedAt but reserves created_at, updated_at and closed_at; source timestamp metadata plus an explicit SDK-gap receipt is required unless a supported import path proves otherwise. No upstream SDK issue will be filed under the queue rules." "2026-10-16T22:35:10.689Z",codex-agent,"Found public SDK import primitives beyond high-level create/update: item locks, canonical document serialization, before/after history entries and appendHistoryEntry. Implementing an idempotent finalization event with real native dates and source metadata, without modifying any historical record. Existing provider owners receive provenance links only; their content, native lifecycle, release and export identity remain authoritative. Local Git calendar tag dates select the first release at or after source closure; later closures remain pending. GraphQL ClosedEvent closer provides actual closing PR attribution where REST commit_id is null." "2026-10-16T23:09:24.995Z",codex-agent,"SDK candidate: bulk compensation captures native updated_at and passes it to restore as a history timestamp. Backdating that field disconnects the rollback version from its event. Preserve source creation/closure/completion natively for momentum and cycle time, and retain the exact source update date in github_updated_at while native updated_at stays the SDK mutation clock. Lifecycle finalization now runs at the SDK committing transition before the journal commits, with real compensation acceptance and a post-recovery idempotent check. No historical entries are rewritten." @@ -48,6 +46,9 @@ comments[37]{created_at,author,text}: "2026-10-17T13:40:46.635Z",codex-agent,"Round 1 implementation and local verification complete. Both literal CI-identity release gates PASSED: npm run release:check and bun run release:check each 797/797 tests, zero failures/skips/cancellations/TODOs, exact 100/100/100/100 across 14 authored modules (10438/10438 lines/statements, 273/273 functions, 3157/3157 branches). Audit found zero vulnerabilities; docstrings, lint, duplication, privacy, packing, changelog and attestation pass. Four function-only behavioral reverts produced the expected assertion failures. README partial-write and empty-plan qualifications are verified with real trackers. Marker startup probe is bounded separately while retaining its 10-second work deadline and a forced-spin control. Existing pm-github-sah1 remains open for its original acceptance-watchdog case. Releasing the coding claim for orchestrator verification; next actions are commit/push, replies to the five original review threads, and bounded CI monitoring. No items will be closed." "2026-10-18T18:19:03.447Z",codex-agent,"Read-only real-public-data verification will use main build and dry-run gated plans in scratch clones. Caller blockers: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Evidence will compare source dates, release placement and pm-brief momentum without editing consumer checkouts." "2026-10-18T18:28:36.151Z",codex-agent,"Main dc86e83 built without importer source changes. Live public dry-run gated atomic plans completed for pm-csv (3 issues), pm-brief (2), and pm-context (5; 2 new open plus 3 existing terminal). All 8 previously terminal imports match source created_at, closed_at, github_state and github_updated_at; durable tracker fingerprints are unchanged. Projected completed_at follows the existing adapter source closure assignment; no importer apply ran. Real pm-changelog stdin rendering includes every projected historical item under its explicit containing release and none under Unreleased. Real pm-brief summarizeMomentum reports GitHub lifetimes of 1.2 to 7.0 days instead of the old zero-day imports (or distorted older owners). No import defect found; no import-fix PR is needed." + "2026-10-18T19:03:42.812Z",codex-agent,"Additional real-consumer proof at a normal seven-day window (observation 2026-10-18T19:00:00Z): the eight baseline terminal records produce closedCount=8 and median cycle=0 days. Projected main fields produce closedCount=1 and median cycle=2.3 days; only pm-context issue 136 remains, with GitHub closed_at=2026-10-13T17:54:36Z. All seven older imports leave current throughput. The actual pm-brief summarizeMomentum export ran on both sets; importer apply remains unused. Updated docs/daily-release-refresh.md with this bounded result." + "2026-10-18T19:05:50.551Z",codex-agent,"Present-window proof is now verified from certified COMPLETE SDK records for the scratch caller heads, preserving the native updated_at fallback required by legacy terminal rows. The first scratch attempt used only selected table columns and correctly failed its baseline-count assertion because updated_at was absent from that projection. The complete records pass: recent closures 8 to 1, median cycle 0 to 2.3 days, only pm-context issue 136 remains. This is a verification-harness correction, not a pm-github or pm-brief defect; no importer apply ran and no historical event was rewritten." + "2026-10-18T22:03:48.244Z",codex-agent,"Real-public-data proof is complete for pm-csv issues 72, 134 and 86; pm-brief issues 135 and 84; and pm-context issues 136, 81 and canceled 53. Main gated atomic dry runs account for every fetched issue and preserve all durable tracker fingerprints. Planned created_at, closed_at, github_state and github_updated_at match GitHub. completed_at is explicitly projected from the existing persistence assignment because the dry-run schema omits it; the linked real-SDK pm-brief-135 fidelity test passed 1/1. Actual pm-changelog rendering includes every projected row in a historical release; six prior Unreleased entries become zero. Actual pm-brief momentum over these eight records at the documented seven-day observation changes 8 recent closures to 1 and median cycle 0 to 2.3 days. Full package npm and Bun release checks each passed 897/897 tests and exact 100/100/100/100. No importer defect remains and no import apply or caller edit occurred. Evidence: docs/daily-release-refresh.md; PR https://github.com/unbraind/pm-github/pull/149. Release/adoption remains with the orchestrator and pm-github-aiok." files[13]{path,scope}: import-fidelity.ts,project index.ts,project @@ -62,9 +63,30 @@ files[13]{path,scope}: test/import-gate.test.ts,project test/import-lock.test.ts,project test/import-selection.test.ts,project -tests[2]{command,scope,timeout_seconds,provenance{author,created_at,source_kind,source_ref}}: - node --test test/import-fidelity.test.ts,project,2400,codex-agent,"2026-10-16T23:09:21.738Z",local_mutation,feat/import-fidelity - "node --test --test-name-pattern=\"closure evidence accepts forward skew\" test/import-fidelity.test.ts",project,2400,codex-agent,"2026-10-17T10:34:46.689Z",local_mutation,feat/import-fidelity +tests[3]: + - command: node --test test/import-fidelity.test.ts + scope: project + timeout_seconds: 2400 + provenance: + author: codex-agent + created_at: "2026-10-16T23:09:21.738Z" + source_kind: local_mutation + source_ref: feat/import-fidelity + - command: "node --test --test-name-pattern=\"closure evidence accepts forward skew\" test/import-fidelity.test.ts" + scope: project + timeout_seconds: 2400 + provenance: + author: codex-agent + created_at: "2026-10-17T10:34:46.689Z" + source_kind: local_mutation + source_ref: feat/import-fidelity + - command: node --test --test-name-pattern='pm-brief-135' test/import-fidelity.test.ts + scope: project + provenance: + author: codex-agent + created_at: "2026-10-18T20:33:13.416Z" + source_kind: local_mutation + source_ref: fix/daily-release-refreshes-stale-pr docs[2]{path,scope}: docs/daily-release-refresh.md,project README.md,project diff --git a/.agents/pm/history/pm-github-c093.jsonl b/.agents/pm/history/pm-github-c093.jsonl index 5d0158d5..fb5ac117 100644 --- a/.agents/pm/history/pm-github-c093.jsonl +++ b/.agents/pm/history/pm-github-c093.jsonl @@ -53,3 +53,8 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T18:19:03.447Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/35","value":{"created_at":"2026-10-18T18:19:03.447Z","author":"codex-agent","text":"Read-only real-public-data verification will use main build and dry-run gated plans in scratch clones. Caller blockers: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Evidence will compare source dates, release placement and pm-brief momentum without editing consumer checkouts."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:19:03.447Z"}],"before_hash":"ccf913de56ca9f01b100a0ee8a012f6ed68b13245e2bc7e869e955117debcfa8","after_hash":"a248e86243a0ebd975cf3bcb98113dae05fee44c46cd9da1598c32f18e7e9850","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"6a5624ec341a812f9f975169e5a3d5fc540af618dbc33fe911e4fe8ab800c967"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:28:36.151Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/36","value":{"created_at":"2026-10-18T18:28:36.151Z","author":"codex-agent","text":"Main dc86e83 built without importer source changes. Live public dry-run gated atomic plans completed for pm-csv (3 issues), pm-brief (2), and pm-context (5; 2 new open plus 3 existing terminal). All 8 previously terminal imports match source created_at, closed_at, github_state and github_updated_at; durable tracker fingerprints are unchanged. Projected completed_at follows the existing adapter source closure assignment; no importer apply ran. Real pm-changelog stdin rendering includes every projected historical item under its explicit containing release and none under Unreleased. Real pm-brief summarizeMomentum reports GitHub lifetimes of 1.2 to 7.0 days instead of the old zero-day imports (or distorted older owners). No import defect found; no import-fix PR is needed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:28:36.151Z"}],"before_hash":"a248e86243a0ebd975cf3bcb98113dae05fee44c46cd9da1598c32f18e7e9850","after_hash":"8285da5cbd858b07e58aad96e2fd8c33ee6a42bde54da3d900d104a3fff6cc32","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"2ca46efc180655b236dd30a7a63724a069dbdfeaddb3cedf27332ab55336bec8"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:29:20.384Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"replace","path":"/metadata/docs/0/path","value":"docs/daily-release-refresh.md"},{"op":"add","path":"/metadata/docs/1","value":{"path":"README.md","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:29:20.384Z"}],"before_hash":"8285da5cbd858b07e58aad96e2fd8c33ee6a42bde54da3d900d104a3fff6cc32","after_hash":"12984bb7416ac210dfcb792e8baa55b1b30fa0d32ec6706c8d9f10b612ad24ca","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"7fac4370a11d171307b09f46c654c7693870bac42e42dd80636d77dc4f8493f9"} +{"hash_algorithm":"sha256","ts":"2026-10-18T19:03:42.812Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/37","value":{"created_at":"2026-10-18T19:03:42.812Z","author":"codex-agent","text":"Additional real-consumer proof at a normal seven-day window (observation 2026-10-18T19:00:00Z): the eight baseline terminal records produce closedCount=8 and median cycle=0 days. Projected main fields produce closedCount=1 and median cycle=2.3 days; only pm-context issue 136 remains, with GitHub closed_at=2026-10-13T17:54:36Z. All seven older imports leave current throughput. The actual pm-brief summarizeMomentum export ran on both sets; importer apply remains unused. Updated docs/daily-release-refresh.md with this bounded result."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T19:03:42.812Z"}],"before_hash":"12984bb7416ac210dfcb792e8baa55b1b30fa0d32ec6706c8d9f10b612ad24ca","after_hash":"a19a77974353c4d7e0d89eb47b789495a4c0036e90f77cee2e0a77b63ad9c8f8","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"e1cac4fa8f24f01c0206d8cffad98def176e2ad30ef0b045d4ab1ed58a7e2fc8"} +{"hash_algorithm":"sha256","ts":"2026-10-18T19:05:50.551Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/38","value":{"created_at":"2026-10-18T19:05:50.551Z","author":"codex-agent","text":"Present-window proof is now verified from certified COMPLETE SDK records for the scratch caller heads, preserving the native updated_at fallback required by legacy terminal rows. The first scratch attempt used only selected table columns and correctly failed its baseline-count assertion because updated_at was absent from that projection. The complete records pass: recent closures 8 to 1, median cycle 0 to 2.3 days, only pm-context issue 136 remains. This is a verification-harness correction, not a pm-github or pm-brief defect; no importer apply ran and no historical event was rewritten."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T19:05:50.551Z"}],"before_hash":"a19a77974353c4d7e0d89eb47b789495a4c0036e90f77cee2e0a77b63ad9c8f8","after_hash":"9fe15b89a9d906467b9d5f2d9e3be77efbdf91c0fc47f1188728c88903b593d0","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"efc6828e55b567991e3793bf22910ce33b52c248144b3977ac009bf9f89ba579"} +{"hash_algorithm":"sha256","ts":"2026-10-18T20:33:13.736Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"tests_add","patch":[{"op":"add","path":"/metadata/tests/2","value":{"command":"node --test --test-name-pattern='pm-brief-135' test/import-fidelity.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T20:33:13.416Z","source_kind":"local_mutation","source_ref":"fix/daily-release-refreshes-stale-pr"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T20:33:13.736Z"}],"before_hash":"9fe15b89a9d906467b9d5f2d9e3be77efbdf91c0fc47f1188728c88903b593d0","after_hash":"589a0a69af3b221680aa82c5362c241a795f2614deb9a316396edda566a4300b","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"a66b26fb11219ea92b96a4bcbc3affe0599354308d25140b9c4f046295e45e09"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:03:48.247Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/39","value":{"created_at":"2026-10-18T22:03:48.244Z","author":"codex-agent","text":"Real-public-data proof is complete for pm-csv issues 72, 134 and 86; pm-brief issues 135 and 84; and pm-context issues 136, 81 and canceled 53. Main gated atomic dry runs account for every fetched issue and preserve all durable tracker fingerprints. Planned created_at, closed_at, github_state and github_updated_at match GitHub. completed_at is explicitly projected from the existing persistence assignment because the dry-run schema omits it; the linked real-SDK pm-brief-135 fidelity test passed 1/1. Actual pm-changelog rendering includes every projected row in a historical release; six prior Unreleased entries become zero. Actual pm-brief momentum over these eight records at the documented seven-day observation changes 8 recent closures to 1 and median cycle 0 to 2.3 days. Full package npm and Bun release checks each passed 897/897 tests and exact 100/100/100/100. No importer defect remains and no import apply or caller edit occurred. Evidence: docs/daily-release-refresh.md; PR https://github.com/unbraind/pm-github/pull/149. Release/adoption remains with the orchestrator and pm-github-aiok."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:03:48.247Z"}],"before_hash":"589a0a69af3b221680aa82c5362c241a795f2614deb9a316396edda566a4300b","after_hash":"5c89abc43c4c4976e425043feb296eea6c0e5945d357dcdd879910f80208769a","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"21ecfac705601f63fb105a74a8d1cef7b8166d21905cda35c35774d4b68c454e"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:04:28.505Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"release","patch":[{"op":"remove","path":"/metadata/claim_principal"},{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:04:28.505Z"}],"before_hash":"5c89abc43c4c4976e425043feb296eea6c0e5945d357dcdd879910f80208769a","after_hash":"0fd58257a56704475ae4b6ab459baf4f4a3b07ea2149b9e222af2ecadef1c7e8","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"6698a9f74b7c506ca2881f85f5653fc4141f93727d769586a230986c4248f1cb"} diff --git a/.agents/pm/history/pm-github-l1ot.jsonl b/.agents/pm/history/pm-github-l1ot.jsonl index ff6acb70..764bd5a2 100644 --- a/.agents/pm/history/pm-github-l1ot.jsonl +++ b/.agents/pm/history/pm-github-l1ot.jsonl @@ -12,3 +12,7 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T18:34:34.711Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/3","value":{"created_at":"2026-10-18T18:34:34.710Z","author":"codex-agent","text":"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:34:34.711Z"}],"before_hash":"87b5f34ee5b3c38fc3654b77410f7fa2e34567e9ecc2346c35a414093c62eec0","after_hash":"20fae5b27385d4ef9bcca8afcda0440fbddf347223fa98316fabfb35e2d74594","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"94809b69378897c00cdf822a8934a9e17b29ad0a55c27d770068a76e8303762d"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:48:05.868Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/4","value":{"created_at":"2026-10-18T18:48:05.868Z","author":"codex-agent","text":"PR https://github.com/unbraind/pm-github/pull/149 is open at e544b02a2bd266c9f7f07de28eec272ea11e7676. A fresh --no-local clone passed strict health with required merge drivers in an isolated home. Current-head function-only revert copies fail exactly 2/4 decision tests; positive suites pass 13/13. Independent decision coverage is 22/22 lines and statements, 12/12 branches and 1/1 functions. Full npm/Bun gates and Node 22/26 CI remain in progress; no merge, release dispatch, tag or publish occurred."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:48:05.868Z"}],"before_hash":"20fae5b27385d4ef9bcca8afcda0440fbddf347223fa98316fabfb35e2d74594","after_hash":"5201c16a25b3ad96ecbe4f0431def20e07f2e6b641e0678fbf184cfd64f630f5","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"4d591e0bffaaa3ac6cb291eae816a66a7f6bc1659dd130b15b7fb7997f0b5275"} {"hash_algorithm":"sha256","ts":"2026-10-18T18:57:13.394Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/5","value":{"created_at":"2026-10-18T18:57:13.394Z","author":"codex-agent","text":"CI Node 26 measured exact 100/100/100/100 across all 15 authored modules, but 1 of 897 tests failed: the pinned pm-ops attestation auditor interpreted the new Node heredoc body as shell publish paths. Replaced that heredoc with a single-quoted node -e expression; the canonical auditor now recognizes exactly one publish invocation with provenance. No auditor code, dependency pin, threshold or exclusion was changed. This is a package-owned compatibility workaround for the pinned shell model; full gates are restarting."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T18:57:13.394Z"}],"before_hash":"5201c16a25b3ad96ecbe4f0431def20e07f2e6b641e0678fbf184cfd64f630f5","after_hash":"b71924a9316c0b133ee8b7a743c9c5f8670577bc12c59d8b5025b7d12af7f27d","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"026baab09626afe6671ba63efda24fd42fe905a51ed9f2ed67ceb01b38e6c7b6"} +{"hash_algorithm":"sha256","ts":"2026-10-18T19:11:03.790Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"tests_add","patch":[{"op":"add","path":"/metadata/tests/1","value":{"command":"node --test test/daily-release-plan.test.ts test/release-workflow.test.ts test/verify-release-publish-attestation.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T19:11:03.374Z","source_kind":"local_mutation","source_ref":"fix/daily-release-refreshes-stale-pr"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T19:11:03.790Z"}],"before_hash":"b71924a9316c0b133ee8b7a743c9c5f8670577bc12c59d8b5025b7d12af7f27d","after_hash":"c0e1a3775c88a58bbe59aed84703dd4b2d506ea2c5e2a2f53274f529f3e2c653","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"93cebba2181f8e17813a80a31dd20c3a1e3eb2a43180d8336888f3e738ebee6e"} +{"hash_algorithm":"sha256","ts":"2026-10-18T21:12:31.150Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/6","value":{"created_at":"2026-10-18T21:12:31.150Z","author":"codex-agent","text":"Code-head CI is green at 12601d6d325d6e6ad1264c0729ff70bb18c90feb: Node 22 and 26 passed, each with 897/897 tests and exact 100/100/100/100 coverage over 15 authored modules. CodeQL and Semgrep passed. Full local npm and Bun release checks are still running through workflow acceptance; no local completion is claimed yet. Sourcery is quota-limited, CodeRabbit skipped review, and Greptile reports an ended trial, so reviewer approval remains missing. CI: https://github.com/unbraind/pm-github/actions/runs/39156572837."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T21:12:31.150Z"}],"before_hash":"c0e1a3775c88a58bbe59aed84703dd4b2d506ea2c5e2a2f53274f529f3e2c653","after_hash":"a86c272e6e376460b91551a3f29c9724c5af614b62e1c3f7cc046e1efb41f83d","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"3a2621a594d3861c1514fbcb5a37951a891a880be51c95d1254fefadd63453d4"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:03:27.935Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/7","value":{"created_at":"2026-10-18T22:03:27.935Z","author":"codex-agent","text":"Full local npm run release:check and bun run release:check both exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, skips or cancellations and measured exact 100/100/100/100 over all 15 authored modules at unchanged thresholds and dependency pins. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication-attestation checks passed. The linked current decision/workflow/auditor suite also passed 21/21. Function-only revert failed the stale-PR and same-day regressions. Final receipt changes contain tracker records and documentation; changelog regeneration and final-head CI follow before handoff. No merge, release dispatch, tag or publication was performed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:03:27.935Z"}],"before_hash":"a86c272e6e376460b91551a3f29c9724c5af614b62e1c3f7cc046e1efb41f83d","after_hash":"227410138b6a56169dc33593005bfc4515ebcba880bdc98df79d6303b01d5454","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"b42f888aadf82dbf9081322bb53d3891fa84ac6c869c47ee88f30e55dba6b40e"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:04:18.419Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"release","patch":[{"op":"remove","path":"/metadata/claim_principal"},{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:04:18.419Z"}],"before_hash":"227410138b6a56169dc33593005bfc4515ebcba880bdc98df79d6303b01d5454","after_hash":"e68bf993ba3e5f64655f1bdc00ecb5c3fdef1cf506398d38c5c975acbbff3e32","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"a6fd3b3fd0b6af5b0fd43e655a0a9414c6f2e72bbbc57a8654aacc9700280d9c"} diff --git a/.agents/pm/issues/pm-github-l1ot.toon b/.agents/pm/issues/pm-github-l1ot.toon index 67ce4247..54c3769b 100644 --- a/.agents/pm/issues/pm-github-l1ot.toon +++ b/.agents/pm/issues/pm-github-l1ot.toon @@ -6,24 +6,25 @@ status: in_progress priority: 1 tags[3]: changelog,changelog-unreleased,release created_at: "2026-10-15T09:25:36.259Z" -updated_at: "2026-10-18T18:57:13.394Z" -assignee: codex-agent -claim_principal: codex-agent +updated_at: "2026-10-18T22:04:18.419Z" author: claude-hub acceptance_criteria: "release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason" -comments[6]{created_at,author,text}: +comments[8]{created_at,author,text}: "2026-10-18T18:19:00.873Z",codex-agent,"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33" "2026-10-18T18:22:11.207Z",codex-agent,"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today." "2026-10-18T18:32:32.900Z",codex-agent,"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected." "2026-10-18T18:34:34.710Z",codex-agent,"Verified the installed gh read boundary against the real repository: number/headRefName selects existing release PR 144. Removed an unnecessary baseRefOid query field that this gh version does not expose. The pure decision uses existing PR identity, current main SHA, last release and today; it intentionally rebuilds even if the existing PR is already based on current main. Focused release tests pass 13/13 after this compatibility adjustment." "2026-10-18T18:48:05.868Z",codex-agent,"PR https://github.com/unbraind/pm-github/pull/149 is open at e544b02a2bd266c9f7f07de28eec272ea11e7676. A fresh --no-local clone passed strict health with required merge drivers in an isolated home. Current-head function-only revert copies fail exactly 2/4 decision tests; positive suites pass 13/13. Independent decision coverage is 22/22 lines and statements, 12/12 branches and 1/1 functions. Full npm/Bun gates and Node 22/26 CI remain in progress; no merge, release dispatch, tag or publish occurred." "2026-10-18T18:57:13.394Z",codex-agent,"CI Node 26 measured exact 100/100/100/100 across all 15 authored modules, but 1 of 897 tests failed: the pinned pm-ops attestation auditor interpreted the new Node heredoc body as shell publish paths. Replaced that heredoc with a single-quoted node -e expression; the canonical auditor now recognizes exactly one publish invocation with provenance. No auditor code, dependency pin, threshold or exclusion was changed. This is a package-owned compatibility workaround for the pinned shell model; full gates are restarting." + "2026-10-18T21:12:31.150Z",codex-agent,"Code-head CI is green at 12601d6d325d6e6ad1264c0729ff70bb18c90feb: Node 22 and 26 passed, each with 897/897 tests and exact 100/100/100/100 coverage over 15 authored modules. CodeQL and Semgrep passed. Full local npm and Bun release checks are still running through workflow acceptance; no local completion is claimed yet. Sourcery is quota-limited, CodeRabbit skipped review, and Greptile reports an ended trial, so reviewer approval remains missing. CI: https://github.com/unbraind/pm-github/actions/runs/39156572837." + "2026-10-18T22:03:27.935Z",codex-agent,"Full local npm run release:check and bun run release:check both exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, skips or cancellations and measured exact 100/100/100/100 over all 15 authored modules at unchanged thresholds and dependency pins. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication-attestation checks passed. The linked current decision/workflow/auditor suite also passed 21/21. Function-only revert failed the stale-PR and same-day regressions. Final receipt changes contain tracker records and documentation; changelog regeneration and final-head CI follow before handoff. No merge, release dispatch, tag or publication was performed." files[3]{path,scope}: .github/workflows/release.yml,project scripts/daily-release-plan.ts,project test/daily-release-plan.test.ts,project -tests[1]{command,scope,provenance{author,created_at,source_kind,source_ref}}: +tests[2]{command,scope,provenance{author,created_at,source_kind,source_ref}}: node --test test/daily-release-plan.test.ts test/release-workflow.test.ts,project,codex-agent,"2026-10-18T18:20:50.608Z",local_mutation,fix/daily-release-refreshes-stale-pr + node --test test/daily-release-plan.test.ts test/release-workflow.test.ts test/verify-release-publish-attestation.test.ts,project,codex-agent,"2026-10-18T19:11:03.374Z",local_mutation,fix/daily-release-refreshes-stale-pr docs[1]{path,scope}: docs/daily-release-refresh.md,project body: "" diff --git a/docs/daily-release-refresh.md b/docs/daily-release-refresh.md index e1ca9b62..ec2e928d 100644 --- a/docs/daily-release-refresh.md +++ b/docs/daily-release-refresh.md @@ -86,6 +86,10 @@ Baseline Unreleased membership comes from the actual caller PR CHANGELOG.md. All | unbraind/pm-context#81 | yes → no | 0 → 4.6 | | unbraind/pm-context#53 | no → no | 0 → 1.2 | +## Present-window momentum + +The same real pm-brief export was also run at 2026-10-18T19:00:00Z with its normal seven-day window over all eight baseline/projected terminal records. This calculation uses certified complete SDK records, retaining native updated_at for legacy terminal records without closed_at; the selected columns in the comparison table are not its input. The baseline counts all 8 as recent closures and has a 0-day median. Main counts only the genuinely recent pm-context issue 136, using its GitHub closure on 2026-10-13T17:54:36Z and a 2.3-day cycle. The seven older imports leave the recent-throughput window. The importer remains dry-run only. + ## Caller adoption https://github.com/unbraind/pm-beads/pull/145, https://github.com/unbraind/pm-brief/pull/154, https://github.com/unbraind/pm-context/pull/147, https://github.com/unbraind/pm-csv/pull/163, https://github.com/unbraind/pm-linear/pull/150, https://github.com/unbraind/pm-slack-standup/pull/127. Publication alone does not update their pins; adoption remains tracked in pm-github-aiok. @@ -122,6 +126,8 @@ The same numeric-suffix block exists in the following 25 sibling workflows. pm-o ## Validation -Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). Restored release suites pass 13/13. npm and Bun release:check retain unchanged thresholds; final receipts are recorded in the linked tracker items and PR. +Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). The current release decision, workflow and publication-auditor suites pass 21/21. + +Both npm run release:check and bun run release:check exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, cancellations or skips. Both measured exact 100/100/100/100 over all 15 authored modules, at unchanged thresholds and pins: 10466/10466 lines and statements, 275/275 functions, and 3171/3171 (npm) or 3172/3172 (Bun invocation) branches. All remaining release-check stages passed. Final tracker/documentation receipts are regenerated and checked separately; final-head CI and fresh-clone strict health are reported in the PR. GitHub documents that GITHUB_TOKEN-created pull-request runs may require approval; existing bounded approval diagnostics remain: https://docs.github.com/en/actions/concepts/security/github_token. Refresh correctness does not certify GitHub approval or npm publisher policy. From febd1215f941369be9e2de2e69dcfc0fc84f25be Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Mon, 19 Oct 2026 00:53:23 +0200 Subject: [PATCH 4/5] Restrict daily release refresh to verified workflow PRs --- .agents/pm/history/pm-github-l1ot.jsonl | 3 ++ .agents/pm/issues/pm-github-l1ot.toon | 8 ++- .github/workflows/release.yml | 39 ++++++-------- docs/daily-release-refresh.md | 4 +- scripts/daily-release-plan.ts | 11 ++-- test/daily-release-plan.test.ts | 69 +++++++++++++++++++++++-- 6 files changed, 103 insertions(+), 31 deletions(-) diff --git a/.agents/pm/history/pm-github-l1ot.jsonl b/.agents/pm/history/pm-github-l1ot.jsonl index 764bd5a2..ef1c6ca8 100644 --- a/.agents/pm/history/pm-github-l1ot.jsonl +++ b/.agents/pm/history/pm-github-l1ot.jsonl @@ -16,3 +16,6 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T21:12:31.150Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/6","value":{"created_at":"2026-10-18T21:12:31.150Z","author":"codex-agent","text":"Code-head CI is green at 12601d6d325d6e6ad1264c0729ff70bb18c90feb: Node 22 and 26 passed, each with 897/897 tests and exact 100/100/100/100 coverage over 15 authored modules. CodeQL and Semgrep passed. Full local npm and Bun release checks are still running through workflow acceptance; no local completion is claimed yet. Sourcery is quota-limited, CodeRabbit skipped review, and Greptile reports an ended trial, so reviewer approval remains missing. CI: https://github.com/unbraind/pm-github/actions/runs/39156572837."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T21:12:31.150Z"}],"before_hash":"c0e1a3775c88a58bbe59aed84703dd4b2d506ea2c5e2a2f53274f529f3e2c653","after_hash":"a86c272e6e376460b91551a3f29c9724c5af614b62e1c3f7cc046e1efb41f83d","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"3a2621a594d3861c1514fbcb5a37951a891a880be51c95d1254fefadd63453d4"} {"hash_algorithm":"sha256","ts":"2026-10-18T22:03:27.935Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/7","value":{"created_at":"2026-10-18T22:03:27.935Z","author":"codex-agent","text":"Full local npm run release:check and bun run release:check both exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, skips or cancellations and measured exact 100/100/100/100 over all 15 authored modules at unchanged thresholds and dependency pins. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication-attestation checks passed. The linked current decision/workflow/auditor suite also passed 21/21. Function-only revert failed the stale-PR and same-day regressions. Final receipt changes contain tracker records and documentation; changelog regeneration and final-head CI follow before handoff. No merge, release dispatch, tag or publication was performed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:03:27.935Z"}],"before_hash":"a86c272e6e376460b91551a3f29c9724c5af614b62e1c3f7cc046e1efb41f83d","after_hash":"227410138b6a56169dc33593005bfc4515ebcba880bdc98df79d6303b01d5454","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"b42f888aadf82dbf9081322bb53d3891fa84ac6c869c47ee88f30e55dba6b40e"} {"hash_algorithm":"sha256","ts":"2026-10-18T22:04:18.419Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"release","patch":[{"op":"remove","path":"/metadata/claim_principal"},{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:04:18.419Z"}],"before_hash":"227410138b6a56169dc33593005bfc4515ebcba880bdc98df79d6303b01d5454","after_hash":"e68bf993ba3e5f64655f1bdc00ecb5c3fdef1cf506398d38c5c975acbbff3e32","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"a6fd3b3fd0b6af5b0fd43e655a0a9414c6f2e72bbbc57a8654aacc9700280d9c"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:51:50.082Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:51:50.082Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"e68bf993ba3e5f64655f1bdc00ecb5c3fdef1cf506398d38c5c975acbbff3e32","after_hash":"68b8778c8b6bcd5c17ad370e29f5bb82c52390b1ea431d5110e07137766a8d1a","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"d437784711d469b1b567ca26fcc751d488e95adc4a52e98d5ee722734a731957"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:51:56.036Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/8","value":{"created_at":"2026-10-18T22:51:56.035Z","author":"codex-agent","text":"Review round 1: PR149 threads PRRT_kwDOTbN4pM6tu6Ys and PRRT_kwDOTbN4pM6tu6Y7 remain unresolved. Trace confirms untrusted release-prefix PRs flow to force-push and by-head PR editing. Restrict the pure planner to same-repository PRs authored by the workflow identity with date-shaped branches, carry the selected PR number to editing, and refuse fresh-branch collisions. Add independent filter regressions and function-only revert proofs. Link completed receipts in report and tracker; new review gates remain pending. PR150 has no review threads; its completed source and validation remain unchanged. No review-thread replies or resolutions will be made."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:51:56.036Z"}],"before_hash":"68b8778c8b6bcd5c17ad370e29f5bb82c52390b1ea431d5110e07137766a8d1a","after_hash":"79841fb3fcb73af5457af85ecdf153340b5c643dd1248fd89dc45aaa0edc7cb1","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"cefb82040296419b26772d8c7ac21d0b0126bb65287ffb74f047433d4432a84e"} +{"hash_algorithm":"sha256","ts":"2026-10-18T22:53:06.496Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/9","value":{"created_at":"2026-10-18T22:53:06.496Z","author":"codex-agent","text":"Review security regression proof: reverting only the same-repository predicate makes the cross-repository test fail with ERR_ASSERTION; reverting only exact workflow-author equality makes the foreign-author test fail; reverting only the date-branch predicate makes the non-date branch test fail. Each isolated run exits 1, with tests and remaining implementation retained. Correct implementation passes the 27-test decision/workflow/publication suite, including legitimate stale PR reuse, unpadded dates, GitHub lookup failure propagation and existing-ref collision refusal before push or cleanup. Report now links immutable completed local receipts and final-head CI for the prior heads: https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl and https://github.com/unbraind/pm-github/actions/runs/39170908685 . Review-round full gates remain pending."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:53:06.496Z"}],"before_hash":"79841fb3fcb73af5457af85ecdf153340b5c643dd1248fd89dc45aaa0edc7cb1","after_hash":"209f6918543c1ce885950b52ca9ca55fac335c856ffa0b76be339762d7b2e3b4","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"697a398532f73dd9a4b862eb269b2de5a3049ba557e2731dbe8f65eaa5f09ece"} diff --git a/.agents/pm/issues/pm-github-l1ot.toon b/.agents/pm/issues/pm-github-l1ot.toon index 54c3769b..aece193c 100644 --- a/.agents/pm/issues/pm-github-l1ot.toon +++ b/.agents/pm/issues/pm-github-l1ot.toon @@ -6,10 +6,12 @@ status: in_progress priority: 1 tags[3]: changelog,changelog-unreleased,release created_at: "2026-10-15T09:25:36.259Z" -updated_at: "2026-10-18T22:04:18.419Z" +updated_at: "2026-10-18T22:53:06.496Z" +assignee: codex-agent +claim_principal: codex-agent author: claude-hub acceptance_criteria: "release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason" -comments[8]{created_at,author,text}: +comments[10]{created_at,author,text}: "2026-10-18T18:19:00.873Z",codex-agent,"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33" "2026-10-18T18:22:11.207Z",codex-agent,"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today." "2026-10-18T18:32:32.900Z",codex-agent,"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected." @@ -18,6 +20,8 @@ comments[8]{created_at,author,text}: "2026-10-18T18:57:13.394Z",codex-agent,"CI Node 26 measured exact 100/100/100/100 across all 15 authored modules, but 1 of 897 tests failed: the pinned pm-ops attestation auditor interpreted the new Node heredoc body as shell publish paths. Replaced that heredoc with a single-quoted node -e expression; the canonical auditor now recognizes exactly one publish invocation with provenance. No auditor code, dependency pin, threshold or exclusion was changed. This is a package-owned compatibility workaround for the pinned shell model; full gates are restarting." "2026-10-18T21:12:31.150Z",codex-agent,"Code-head CI is green at 12601d6d325d6e6ad1264c0729ff70bb18c90feb: Node 22 and 26 passed, each with 897/897 tests and exact 100/100/100/100 coverage over 15 authored modules. CodeQL and Semgrep passed. Full local npm and Bun release checks are still running through workflow acceptance; no local completion is claimed yet. Sourcery is quota-limited, CodeRabbit skipped review, and Greptile reports an ended trial, so reviewer approval remains missing. CI: https://github.com/unbraind/pm-github/actions/runs/39156572837." "2026-10-18T22:03:27.935Z",codex-agent,"Full local npm run release:check and bun run release:check both exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, skips or cancellations and measured exact 100/100/100/100 over all 15 authored modules at unchanged thresholds and dependency pins. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication-attestation checks passed. The linked current decision/workflow/auditor suite also passed 21/21. Function-only revert failed the stale-PR and same-day regressions. Final receipt changes contain tracker records and documentation; changelog regeneration and final-head CI follow before handoff. No merge, release dispatch, tag or publication was performed." + "2026-10-18T22:51:56.035Z",codex-agent,"Review round 1: PR149 threads PRRT_kwDOTbN4pM6tu6Ys and PRRT_kwDOTbN4pM6tu6Y7 remain unresolved. Trace confirms untrusted release-prefix PRs flow to force-push and by-head PR editing. Restrict the pure planner to same-repository PRs authored by the workflow identity with date-shaped branches, carry the selected PR number to editing, and refuse fresh-branch collisions. Add independent filter regressions and function-only revert proofs. Link completed receipts in report and tracker; new review gates remain pending. PR150 has no review threads; its completed source and validation remain unchanged. No review-thread replies or resolutions will be made." + "2026-10-18T22:53:06.496Z",codex-agent,"Review security regression proof: reverting only the same-repository predicate makes the cross-repository test fail with ERR_ASSERTION; reverting only exact workflow-author equality makes the foreign-author test fail; reverting only the date-branch predicate makes the non-date branch test fail. Each isolated run exits 1, with tests and remaining implementation retained. Correct implementation passes the 27-test decision/workflow/publication suite, including legitimate stale PR reuse, unpadded dates, GitHub lookup failure propagation and existing-ref collision refusal before push or cleanup. Report now links immutable completed local receipts and final-head CI for the prior heads: https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl and https://github.com/unbraind/pm-github/actions/runs/39170908685 . Review-round full gates remain pending." files[3]{path,scope}: .github/workflows/release.yml,project scripts/daily-release-plan.ts,project diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 27cfe1fb..70f98bff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,14 +95,14 @@ jobs: if [[ -n "$latest_tag" ]]; then export RELEASE_LAST_SHA="$(git rev-list -n 1 "$latest_tag")" fi - export RELEASE_EXISTING_PR="$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open \ - --json number,headRefName --jq '[.[] | select(.headRefName | startswith("release/"))][0] // null')" + RELEASE_EXISTING_PRS="$(gh pr list --repo "$GITHUB_REPOSITORY" --base main --state open \ + --json number,headRefName,isCrossRepository,author)" + export RELEASE_EXISTING_PRS node --input-type=module -e ' import { decideDailyRelease } from "./scripts/daily-release-plan.ts"; const e = process.env; - const pr = JSON.parse(e.RELEASE_EXISTING_PR); const plan = decideDailyRelease({ - existingPr: pr && { number: pr.number, branch: pr.headRefName }, + existingPrs: JSON.parse(e.RELEASE_EXISTING_PRS), mainSha: e.RELEASE_MAIN_SHA, today: e.RELEASE_TODAY, lastRelease: e.RELEASE_LAST_TAG ? { tag: e.RELEASE_LAST_TAG, sha: e.RELEASE_LAST_SHA } : null, }); @@ -287,6 +287,7 @@ jobs: RELEASE_TAG: ${{ steps.decide.outputs.tag }} NPM_VERSION: ${{ steps.decide.outputs.npm_version }} RELEASE_BRANCH: ${{ steps.decide.outputs.release_branch }} + RELEASE_PR_NUMBER: ${{ steps.decide.outputs.pr_number }} run: | set -euo pipefail git fetch origin main --force @@ -297,11 +298,18 @@ jobs: fi release_branch="$RELEASE_BRANCH" + pr_number="$RELEASE_PR_NUMBER" + remote_branch_sha="$(git ls-remote --heads origin "refs/heads/${release_branch}" | cut -f1)" + if [[ -z "$pr_number" && -n "$remote_branch_sha" ]]; then + echo "::error::Refusing to overwrite a release branch without a verified workflow PR." + exit 1 + fi release_commit="$(git rev-parse HEAD)" if [[ "$release_commit" == "$current_main_sha" ]]; then echo "Release metadata is already present on main; resuming the publish/tag transaction." - if git ls-remote --exit-code --heads origin "refs/heads/${release_branch}" > /dev/null 2>&1; then - git push origin --delete "$release_branch" + if [[ -n "$remote_branch_sha" ]]; then + git push --force-with-lease="refs/heads/${release_branch}:${remote_branch_sha}" \ + origin ":refs/heads/${release_branch}" fi { echo "merged_sha=$current_main_sha" @@ -310,22 +318,9 @@ jobs: exit 0 fi - remote_branch_sha="$(git ls-remote --heads origin "refs/heads/${release_branch}" | cut -f1)" - if [[ -n "$remote_branch_sha" ]]; then - git push \ - --force-with-lease="refs/heads/${release_branch}:${remote_branch_sha}" \ - origin "HEAD:refs/heads/${release_branch}" - else - git push origin "HEAD:refs/heads/${release_branch}" - fi - - pr_number="$(gh pr list \ - --repo "$GITHUB_REPOSITORY" \ - --base main \ - --head "$release_branch" \ - --state open \ - --json number \ - --jq '.[0].number // empty')" + git push \ + --force-with-lease="refs/heads/${release_branch}:${remote_branch_sha}" \ + origin "HEAD:refs/heads/${release_branch}" if [[ -z "$pr_number" ]]; then pr_url="$(gh pr create \ --repo "$GITHUB_REPOSITORY" \ diff --git a/docs/daily-release-refresh.md b/docs/daily-release-refresh.md index ec2e928d..0b80d986 100644 --- a/docs/daily-release-refresh.md +++ b/docs/daily-release-refresh.md @@ -128,6 +128,8 @@ The same numeric-suffix block exists in the following 25 sibling workflows. pm-o Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). The current release decision, workflow and publication-auditor suites pass 21/21. -Both npm run release:check and bun run release:check exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, cancellations or skips. Both measured exact 100/100/100/100 over all 15 authored modules, at unchanged thresholds and pins: 10466/10466 lines and statements, 275/275 functions, and 3171/3171 (npm) or 3172/3172 (Bun invocation) branches. All remaining release-check stages passed. Final tracker/documentation receipts are regenerated and checked separately; final-head CI and fresh-clone strict health are reported in the PR. +Both npm run release:check and bun run release:check exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, cancellations or skips. Both measured exact 100/100/100/100 over all 15 authored modules, at unchanged thresholds and pins: 10466/10466 lines and statements, 275/275 functions, and 3171/3171 (npm) or 3172/3172 (Bun invocation) branches. All remaining release-check stages passed. The completed local results were recorded at 2026-10-18T22:03:27Z in the [append-only tracker receipt](https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl); earlier pending comments describe earlier runs. The subsequent documentation/tracker head 3de8cde015db5979d6c0ebc9a749bbccd5656d7d passed [Node 22/26 CI](https://github.com/unbraind/pm-github/actions/runs/39170908685) and fresh-clone strict health. These receipts certify those heads; review-round changes require new gates. + +Review round 1 restricts reusable PRs to the same repository, the exact GITHUB_TOKEN workflow author (`app/github-actions` in gh JSON), and date-shaped release branches. The pure planner selects the PR number used for editing. New branches use an empty force-with-lease expectation and refuse existing refs without a verified workflow PR, including before cleanup. Cross-repository, foreign-author and non-date candidates each plan a fresh PR; mixed candidates still find a legitimate stale workflow PR. Review-round full gates are pending until their completion is recorded below. GitHub documents that GITHUB_TOKEN-created pull-request runs may require approval; existing bounded approval diagnostics remain: https://docs.github.com/en/actions/concepts/security/github_token. Refresh correctness does not certify GitHub approval or npm publisher policy. diff --git a/scripts/daily-release-plan.ts b/scripts/daily-release-plan.ts index 1ce99430..1aab4496 100644 --- a/scripts/daily-release-plan.ts +++ b/scripts/daily-release-plan.ts @@ -1,6 +1,6 @@ /** Facts needed to rebuild a protected release PR without a second daily publication. */ export interface DailyReleaseInput { - existingPr: { number: number; branch: string } | null; + existingPrs: { number: number; headRefName: string; isCrossRepository: boolean; author: { login: string } }[]; mainSha: string; lastRelease: { tag: string; sha: string } | null; today: string; @@ -8,15 +8,20 @@ export interface DailyReleaseInput { /** Rebuild from current main on every eligible run, reusing even yesterday's open PR. */ export function decideDailyRelease(input: DailyReleaseInput) { + // gh represents the GITHUB_TOKEN author as app/github-actions. + const existingPr = input.existingPrs.find(pr => pr.isCrossRepository === false + && pr.author.login === "app/github-actions" + && /^release\/\d{4}\.\d{1,2}\.\d{1,2}$/.test(pr.headRefName)); const version = input.today.split(".").map(Number).join("."); const releasedVersion = input.lastRelease?.tag.replace(/^v/, "").split("-")[0]?.split(".").map(Number).join("."); const shouldRelease = releasedVersion !== version && input.lastRelease?.sha !== input.mainSha; return { should_release: shouldRelease, - action: !shouldRelease ? "skip" : input.existingPr ? "refresh" : "create", + action: !shouldRelease ? "skip" : existingPr ? "refresh" : "create", tag: `v${input.today}`, npm_version: version, base_sha: input.mainSha, - release_branch: input.existingPr?.branch ?? `release/${input.today}`, + release_branch: existingPr?.headRefName ?? `release/${input.today}`, + pr_number: existingPr?.number ?? "", }; } diff --git a/test/daily-release-plan.test.ts b/test/daily-release-plan.test.ts index d830b90a..10e12734 100644 --- a/test/daily-release-plan.test.ts +++ b/test/daily-release-plan.test.ts @@ -1,25 +1,62 @@ /** Daily release policy is independent of GitHub and the wall clock. */ import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; import { readFileSync } from "node:fs"; import test from "node:test"; import { decideDailyRelease, type DailyReleaseInput } from "../scripts/daily-release-plan.ts"; -const input: DailyReleaseInput = { existingPr: null, mainSha: "new-main", lastRelease: null, today: "2026.10.18" }; +const input: DailyReleaseInput = { existingPrs: [], mainSha: "new-main", lastRelease: null, today: "2026.10.18" }; +const workflowPr = { number: 144, headRefName: "release/2026.10.17", isCrossRepository: false, + author: { login: "app/github-actions" } }; test("first release uses today's stable npm version and current main", () => { assert.deepEqual(decideDailyRelease(input), { should_release: true, action: "create", tag: "v2026.10.18", - npm_version: "2026.10.18", base_sha: "new-main", release_branch: "release/2026.10.18" }); + npm_version: "2026.10.18", base_sha: "new-main", release_branch: "release/2026.10.18", pr_number: "" }); assert.equal(decideDailyRelease({ ...input, today: "2026.01.02" }).npm_version, "2026.1.2"); }); test("an existing stale PR is rebuilt from current main and today's date", () => { - const plan = decideDailyRelease({ ...input, existingPr: { number: 144, branch: "release/2026.10.17" }, + const plan = decideDailyRelease({ ...input, existingPrs: [workflowPr], lastRelease: { tag: "v2026.10.16", sha: "released-main" } }); assert.equal(plan.action, "refresh"); assert.equal(plan.should_release, true); assert.equal(plan.base_sha, "new-main"); assert.equal(plan.release_branch, "release/2026.10.17"); assert.equal(plan.tag, "v2026.10.18"); + assert.equal(plan.pr_number, 144); +}); + +test("a cross-repository release PR is ignored and a fresh PR is planned", () => { + const plan = decideDailyRelease({ ...input, existingPrs: [{ ...workflowPr, isCrossRepository: true }] }); + assert.equal(plan.action, "create"); + assert.equal(plan.pr_number, ""); + assert.equal(plan.release_branch, "release/2026.10.18"); +}); + +test("a foreign author's release PR is ignored and a fresh PR is planned", () => { + const plan = decideDailyRelease({ ...input, existingPrs: [{ ...workflowPr, author: { login: "app/other-bot" } }] }); + assert.equal(plan.action, "create"); + assert.equal(plan.pr_number, ""); + assert.equal(plan.release_branch, "release/2026.10.18"); +}); + +test("a non-date release branch is ignored and a fresh PR is planned", () => { + for (const headRefName of ["release/v2-notes", "release/2026.10.17-notes", "release/2026.100.17", "release/2026.10.17\n"]) { + const plan = decideDailyRelease({ ...input, existingPrs: [{ ...workflowPr, headRefName }] }); + assert.equal(plan.action, "create", headRefName); + assert.equal(plan.pr_number, ""); + assert.equal(plan.release_branch, "release/2026.10.18"); + } +}); + +test("selection skips untrusted candidates and accepts the workflow's unpadded date branches", () => { + const plan = decideDailyRelease({ ...input, existingPrs: [ + { ...workflowPr, isCrossRepository: true }, + { ...workflowPr, number: 155, headRefName: "release/2026.1.2" }, + ] }); + assert.equal(plan.action, "refresh"); + assert.equal(plan.pr_number, 155); + assert.equal(plan.release_branch, "release/2026.1.2"); }); test("an unchanged release or a publication already dated today skips, even after new main changes", () => { @@ -41,4 +78,30 @@ test("workflow rebuilds before preparation and runs the canonical generator befo assert.match(workflow, /release_branch="\$RELEASE_BRANCH"/); assert.match(workflow, /--force-with-lease=/); assert.match(workflow, /gh pr edit "\$pr_number"/); + assert.match(workflow, /pr_number="\$RELEASE_PR_NUMBER"/); + assert.match(workflow, /RELEASE_PR_NUMBER: \$\{\{ steps.decide.outputs.pr_number \}\}/); + assert.equal(workflow.match(/gh pr list/g)?.length, 1); + assert.match(workflow, /--json number,headRefName,isCrossRepository,author/); + assert.doesNotMatch(workflow, /export RELEASE_EXISTING_PRS=/); + assert.ok(workflow.indexOf("Refusing to overwrite a release branch") < workflow.indexOf('origin ":refs/heads/${release_branch}"')); +}); + +test("a failed GitHub candidate lookup aborts instead of exporting an empty success", () => { + const workflow = readFileSync(new URL("../.github/workflows/release.yml", import.meta.url), "utf8"); + const lookup = workflow.slice(workflow.indexOf(' RELEASE_EXISTING_PRS="$('), workflow.indexOf(" node --input-type=module -e '")); + const result = spawnSync("bash", ["-c", `set -eu; gh() { return 47; }; ${lookup}\nprintf continued`], + { encoding: "utf8", env: { ...process.env, GITHUB_REPOSITORY: "example/package" } }); + assert.equal(result.status, 47); + assert.equal(result.stdout, ""); +}); + +test("the push and cleanup boundary refuses an existing ref without a selected workflow PR", () => { + const workflow = readFileSync(new URL("../.github/workflows/release.yml", import.meta.url), "utf8"); + const guard = workflow.slice(workflow.indexOf(' release_branch="$RELEASE_BRANCH"'), workflow.indexOf(' release_commit="$(git rev-parse HEAD)"')); + for (const [prNumber, ref, status] of [["", "existing-sha", 1], ["144", "existing-sha", 0], ["", "", 0]] as const) { + const result = spawnSync("bash", ["-c", `set -eu; git() { printf '%s' "$TEST_REF"; }; ${guard}`], + { encoding: "utf8", env: { ...process.env, RELEASE_BRANCH: "release/2026.10.18", RELEASE_PR_NUMBER: prNumber, TEST_REF: ref } }); + assert.equal(result.status, status, result.stderr); + if (status === 1) assert.match(result.stdout, /Refusing to overwrite/); + } }); From 7b61575b5e1a29ed929358f188456412f6b3b769 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Mon, 19 Oct 2026 02:15:46 +0200 Subject: [PATCH 5/5] Record verified release review and gate receipts --- .agents/pm/history/pm-github-l1ot.jsonl | 3 +++ .agents/pm/issues/pm-github-l1ot.toon | 8 ++++---- docs/daily-release-refresh.md | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.agents/pm/history/pm-github-l1ot.jsonl b/.agents/pm/history/pm-github-l1ot.jsonl index ef1c6ca8..4079ee74 100644 --- a/.agents/pm/history/pm-github-l1ot.jsonl +++ b/.agents/pm/history/pm-github-l1ot.jsonl @@ -19,3 +19,6 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T22:51:50.082Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"claim","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:51:50.082Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"e68bf993ba3e5f64655f1bdc00ecb5c3fdef1cf506398d38c5c975acbbff3e32","after_hash":"68b8778c8b6bcd5c17ad370e29f5bb82c52390b1ea431d5110e07137766a8d1a","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"d437784711d469b1b567ca26fcc751d488e95adc4a52e98d5ee722734a731957"} {"hash_algorithm":"sha256","ts":"2026-10-18T22:51:56.036Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/8","value":{"created_at":"2026-10-18T22:51:56.035Z","author":"codex-agent","text":"Review round 1: PR149 threads PRRT_kwDOTbN4pM6tu6Ys and PRRT_kwDOTbN4pM6tu6Y7 remain unresolved. Trace confirms untrusted release-prefix PRs flow to force-push and by-head PR editing. Restrict the pure planner to same-repository PRs authored by the workflow identity with date-shaped branches, carry the selected PR number to editing, and refuse fresh-branch collisions. Add independent filter regressions and function-only revert proofs. Link completed receipts in report and tracker; new review gates remain pending. PR150 has no review threads; its completed source and validation remain unchanged. No review-thread replies or resolutions will be made."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:51:56.036Z"}],"before_hash":"68b8778c8b6bcd5c17ad370e29f5bb82c52390b1ea431d5110e07137766a8d1a","after_hash":"79841fb3fcb73af5457af85ecdf153340b5c643dd1248fd89dc45aaa0edc7cb1","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"cefb82040296419b26772d8c7ac21d0b0126bb65287ffb74f047433d4432a84e"} {"hash_algorithm":"sha256","ts":"2026-10-18T22:53:06.496Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/9","value":{"created_at":"2026-10-18T22:53:06.496Z","author":"codex-agent","text":"Review security regression proof: reverting only the same-repository predicate makes the cross-repository test fail with ERR_ASSERTION; reverting only exact workflow-author equality makes the foreign-author test fail; reverting only the date-branch predicate makes the non-date branch test fail. Each isolated run exits 1, with tests and remaining implementation retained. Correct implementation passes the 27-test decision/workflow/publication suite, including legitimate stale PR reuse, unpadded dates, GitHub lookup failure propagation and existing-ref collision refusal before push or cleanup. Report now links immutable completed local receipts and final-head CI for the prior heads: https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl and https://github.com/unbraind/pm-github/actions/runs/39170908685 . Review-round full gates remain pending."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T22:53:06.496Z"}],"before_hash":"79841fb3fcb73af5457af85ecdf153340b5c643dd1248fd89dc45aaa0edc7cb1","after_hash":"209f6918543c1ce885950b52ca9ca55fac335c856ffa0b76be339762d7b2e3b4","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"697a398532f73dd9a4b862eb269b2de5a3049ba557e2731dbe8f65eaa5f09ece"} +{"hash_algorithm":"sha256","ts":"2026-10-18T23:32:50.519Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/10","value":{"created_at":"2026-10-18T23:32:50.519Z","author":"codex-agent","text":"Review code-head CI is green at febd1215f941369be9e2de2e69dcfc0fc84f25be: Node22 and Node26, CodeQL and Semgrep passed within 40 minutes with 60-second polling. Node26 logs confirm 903/903 Node tests, exact 100/100/100/100 over 15 authored modules, and 903 native Bun tests across 41 files. CI receipt: https://github.com/unbraind/pm-github/actions/runs/39174854832 . Both explicit local release checks are still running, so their completion is not claimed. Review threads have not been replied to or resolved."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T23:32:50.519Z"}],"before_hash":"209f6918543c1ce885950b52ca9ca55fac335c856ffa0b76be339762d7b2e3b4","after_hash":"75c6b572fc2d9a6f183ad208a9c10f95e3a6ee63ebf0b85497c2ca5ff2299d27","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"0fa706e0a395f1df03ae3279c5cd29f7f08b80be54fd573139f584bcb142592b"} +{"hash_algorithm":"sha256","ts":"2026-10-19T00:15:30.141Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/11","value":{"created_at":"2026-10-19T00:15:30.141Z","author":"codex-agent","text":"Review round 1 full local gates completed: npm run release:check and bun run release:check both exited 0 at code head febd1215f941369be9e2de2e69dcfc0fc84f25be. Each passed 903/903 tests, zero failures/skips/cancellations, exact 100/100/100/100 over 15 authored modules at unchanged thresholds and pins. Lines/statements 10471/10471; functions 275/275; branches npm 3177/3177 and Bun invocation 3175/3175. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication attestation passed. Focused suite 27/27; each of the three planner safety predicates independently reverted causes its regression to fail. Legitimate stale bot PR reuse, single-day cap, GitHub read failure propagation and ref collision refusal remain covered. docs/daily-release-refresh.md links prior completed receipts and the current review receipt, distinguishing historical pending comments from completion. Code-head CI: https://github.com/unbraind/pm-github/actions/runs/39174854832 . Receipt-only head CI and independent fresh-clone strict health follow in the PR. No review-thread replies/resolutions or release actions occurred."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-19T00:15:30.141Z"}],"before_hash":"75c6b572fc2d9a6f183ad208a9c10f95e3a6ee63ebf0b85497c2ca5ff2299d27","after_hash":"a9d7651b6a226160e067f3d128b2b3b7e0044834722ef16839e828ab7d6cdb9a","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"substantive","record_hash_version":1,"record_hash":"ecc5bdf24b4b11818335acfa339f57a52aaad1a23e525cad143308edf2505a3f"} +{"hash_algorithm":"sha256","ts":"2026-10-19T00:15:34.559Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e4446d2a1278b42fdf0b9f7f","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":{"value":"implementer","source":"argv"},"topic":null},"op":"release","patch":[{"op":"remove","path":"/metadata/claim_principal"},{"op":"remove","path":"/metadata/assignee"},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-19T00:15:34.559Z"}],"before_hash":"a9d7651b6a226160e067f3d128b2b3b7e0044834722ef16839e828ab7d6cdb9a","after_hash":"273cfdf9c1c85cf55bb28e4f45550605918f6095b5593e777483c1cbc6fdab1e","item_hash_version":3,"context":{"agent_provenance_outcomes":{"model":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"effort":{"status":"resolved","resolver":"codex_session_file","rule_version":"v1"},"version":{"status":"unavailable","reason":"harness_unavailable","resolver":"ai_agent_version","rule_version":"v1"}}},"event_class":"maintenance","record_hash_version":1,"record_hash":"c4c7e9ab81e1f35ccba06bff852c69074fd83539935a5c59c98b37f2f60ea258"} diff --git a/.agents/pm/issues/pm-github-l1ot.toon b/.agents/pm/issues/pm-github-l1ot.toon index aece193c..ca30cb37 100644 --- a/.agents/pm/issues/pm-github-l1ot.toon +++ b/.agents/pm/issues/pm-github-l1ot.toon @@ -6,12 +6,10 @@ status: in_progress priority: 1 tags[3]: changelog,changelog-unreleased,release created_at: "2026-10-15T09:25:36.259Z" -updated_at: "2026-10-18T22:53:06.496Z" -assignee: codex-agent -claim_principal: codex-agent +updated_at: "2026-10-19T00:15:34.559Z" author: claude-hub acceptance_criteria: "release.yml generates CHANGELOG.md and the release notes through the package's own changelog scripts with the same status filter as changelog:check; a test fails if the two disagree; a release run with an in_progress item tagged changelog-unreleased and delivered since the last tag either succeeds or fails before any bump with a clear reason" -comments[10]{created_at,author,text}: +comments[12]{created_at,author,text}: "2026-10-18T18:19:00.873Z",codex-agent,"Reproduced the release generator split: release.yml uses pm-changelog closed-only output while changelog:check includes tagged pending work. The next run fails before refreshing the protected release PR. Plan: one canonical generator, rebuild from freshly fetched main, refresh or supersede stale PRs, and enforce one release per calendar day with pure decision regressions. Related: https://github.com/unbraind/pm-github/pull/144 and https://github.com/unbraind/pm-ado/issues/33" "2026-10-18T18:22:11.207Z",codex-agent,"Behavioral function-only revert proof: keeping the same decision function and tests, restored the old unconditional same-day eligibility and today-only branch selection. node --test test/daily-release-plan.test.ts failed 2/4 assertions: the old PR branch was abandoned and a second same-day release was allowed. Restored implementation: focused release suites passed 13/13 and the linked PM command passed. The release generator now invokes changelog:full, changelog:check and release:notes; lease-protected refresh updates the reused PR title/version to today." "2026-10-18T18:32:32.900Z",codex-agent,"Consumer context: https://github.com/unbraind/pm-beads/pull/145 https://github.com/unbraind/pm-brief/pull/154 https://github.com/unbraind/pm-context/pull/147 https://github.com/unbraind/pm-csv/pull/163 https://github.com/unbraind/pm-linear/pull/150 https://github.com/unbraind/pm-slack-standup/pull/127. Separate attribution fix: https://github.com/unbraind/pm-ado/issues/33. The proof report contains all 8 real imported terminal rows, exact before/main lifecycle fields, explicit completed_at projection limits, historical release placement and momentum. Six baseline entries are under Unreleased; all 8 projected rows render under historical releases when terminal statuses are selected." @@ -22,6 +20,8 @@ comments[10]{created_at,author,text}: "2026-10-18T22:03:27.935Z",codex-agent,"Full local npm run release:check and bun run release:check both exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, skips or cancellations and measured exact 100/100/100/100 over all 15 authored modules at unchanged thresholds and dependency pins. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication-attestation checks passed. The linked current decision/workflow/auditor suite also passed 21/21. Function-only revert failed the stale-PR and same-day regressions. Final receipt changes contain tracker records and documentation; changelog regeneration and final-head CI follow before handoff. No merge, release dispatch, tag or publication was performed." "2026-10-18T22:51:56.035Z",codex-agent,"Review round 1: PR149 threads PRRT_kwDOTbN4pM6tu6Ys and PRRT_kwDOTbN4pM6tu6Y7 remain unresolved. Trace confirms untrusted release-prefix PRs flow to force-push and by-head PR editing. Restrict the pure planner to same-repository PRs authored by the workflow identity with date-shaped branches, carry the selected PR number to editing, and refuse fresh-branch collisions. Add independent filter regressions and function-only revert proofs. Link completed receipts in report and tracker; new review gates remain pending. PR150 has no review threads; its completed source and validation remain unchanged. No review-thread replies or resolutions will be made." "2026-10-18T22:53:06.496Z",codex-agent,"Review security regression proof: reverting only the same-repository predicate makes the cross-repository test fail with ERR_ASSERTION; reverting only exact workflow-author equality makes the foreign-author test fail; reverting only the date-branch predicate makes the non-date branch test fail. Each isolated run exits 1, with tests and remaining implementation retained. Correct implementation passes the 27-test decision/workflow/publication suite, including legitimate stale PR reuse, unpadded dates, GitHub lookup failure propagation and existing-ref collision refusal before push or cleanup. Report now links immutable completed local receipts and final-head CI for the prior heads: https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl and https://github.com/unbraind/pm-github/actions/runs/39170908685 . Review-round full gates remain pending." + "2026-10-18T23:32:50.519Z",codex-agent,"Review code-head CI is green at febd1215f941369be9e2de2e69dcfc0fc84f25be: Node22 and Node26, CodeQL and Semgrep passed within 40 minutes with 60-second polling. Node26 logs confirm 903/903 Node tests, exact 100/100/100/100 over 15 authored modules, and 903 native Bun tests across 41 files. CI receipt: https://github.com/unbraind/pm-github/actions/runs/39174854832 . Both explicit local release checks are still running, so their completion is not claimed. Review threads have not been replied to or resolved." + "2026-10-19T00:15:30.141Z",codex-agent,"Review round 1 full local gates completed: npm run release:check and bun run release:check both exited 0 at code head febd1215f941369be9e2de2e69dcfc0fc84f25be. Each passed 903/903 tests, zero failures/skips/cancellations, exact 100/100/100/100 over 15 authored modules at unchanged thresholds and pins. Lines/statements 10471/10471; functions 275/275; branches npm 3177/3177 and Bun invocation 3175/3175. Typecheck, build, docstrings, lint, duplication, privacy, production audit, pack dry run, changelog check and publication attestation passed. Focused suite 27/27; each of the three planner safety predicates independently reverted causes its regression to fail. Legitimate stale bot PR reuse, single-day cap, GitHub read failure propagation and ref collision refusal remain covered. docs/daily-release-refresh.md links prior completed receipts and the current review receipt, distinguishing historical pending comments from completion. Code-head CI: https://github.com/unbraind/pm-github/actions/runs/39174854832 . Receipt-only head CI and independent fresh-clone strict health follow in the PR. No review-thread replies/resolutions or release actions occurred." files[3]{path,scope}: .github/workflows/release.yml,project scripts/daily-release-plan.ts,project diff --git a/docs/daily-release-refresh.md b/docs/daily-release-refresh.md index 0b80d986..440d00f7 100644 --- a/docs/daily-release-refresh.md +++ b/docs/daily-release-refresh.md @@ -126,10 +126,12 @@ The same numeric-suffix block exists in the following 25 sibling workflows. pm-o ## Validation -Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). The current release decision, workflow and publication-auditor suites pass 21/21. +Function-only behavioral revert restores today-only branch selection and same-day eligibility, retaining the tests. The stale-PR and once-per-day regressions fail (2 failures). At the pre-review code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb, the release decision, workflow and publication-auditor suites passed 21/21. Both npm run release:check and bun run release:check exited 0 at code head 12601d6d325d6e6ad1264c0729ff70bb18c90feb. Each ran 897/897 tests with zero failures, cancellations or skips. Both measured exact 100/100/100/100 over all 15 authored modules, at unchanged thresholds and pins: 10466/10466 lines and statements, 275/275 functions, and 3171/3171 (npm) or 3172/3172 (Bun invocation) branches. All remaining release-check stages passed. The completed local results were recorded at 2026-10-18T22:03:27Z in the [append-only tracker receipt](https://github.com/unbraind/pm-github/blob/3de8cde015db5979d6c0ebc9a749bbccd5656d7d/.agents/pm/history/pm-github-l1ot.jsonl); earlier pending comments describe earlier runs. The subsequent documentation/tracker head 3de8cde015db5979d6c0ebc9a749bbccd5656d7d passed [Node 22/26 CI](https://github.com/unbraind/pm-github/actions/runs/39170908685) and fresh-clone strict health. These receipts certify those heads; review-round changes require new gates. -Review round 1 restricts reusable PRs to the same repository, the exact GITHUB_TOKEN workflow author (`app/github-actions` in gh JSON), and date-shaped release branches. The pure planner selects the PR number used for editing. New branches use an empty force-with-lease expectation and refuse existing refs without a verified workflow PR, including before cleanup. Cross-repository, foreign-author and non-date candidates each plan a fresh PR; mixed candidates still find a legitimate stale workflow PR. Review-round full gates are pending until their completion is recorded below. +Review round 1 restricts reusable PRs to the same repository, the exact GITHUB_TOKEN workflow author (`app/github-actions` in gh JSON), and date-shaped release branches. The pure planner selects the PR number used for editing. New branches use an empty force-with-lease expectation and refuse existing refs without a verified workflow PR, including before cleanup. Cross-repository, foreign-author and non-date candidates each plan a fresh PR; mixed candidates still find a legitimate stale workflow PR. Each safety predicate was reverted independently while retaining the tests and other implementation: cross-repository, foreign-author and non-date regressions each fail with ERR_ASSERTION (exit 1). The restored decision/workflow/publication suite passes 27/27. + +At review code head febd1215f941369be9e2de2e69dcfc0fc84f25be, both npm run release:check and bun run release:check exited 0. Each passed 903/903 tests with zero failures, cancellations or skips and exact 100/100/100/100 across 15 authored modules. Both measured 10471/10471 lines and statements and 275/275 functions; branches were 3177/3177 (npm) and 3175/3175 (Bun invocation). All release-check stages passed with unchanged thresholds and dependency pins. The [review-round tracker receipt](../.agents/pm/history/pm-github-l1ot.jsonl) records these completed local results; earlier pending comments describe earlier runs. [Code-head CI](https://github.com/unbraind/pm-github/actions/runs/39174854832) passed Node 22/26, each with 903 Node tests, 903 native Bun tests across 41 files and exact authored-source coverage, plus CodeQL and Semgrep. Receipt-head CI and fresh-clone health are recorded in the PR after that head is pushed. GitHub documents that GITHUB_TOKEN-created pull-request runs may require approval; existing bounded approval diagnostics remain: https://docs.github.com/en/actions/concepts/security/github_token. Refresh correctness does not certify GitHub approval or npm publisher policy.