From b6d44a0acdb1c3a62a800f9345a4505e32826fee Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sat, 17 Oct 2026 16:17:54 +0200 Subject: [PATCH 1/9] Run eligible PR checks and maintain automated proposal branches --- .agents/pm/history/pm-github-8r7c.jsonl | 27 ++++ .agents/pm/history/pm-github-aiok.jsonl | 2 + .agents/pm/history/pm-github-lfcf.jsonl | 1 + .agents/pm/issues/pm-github-8r7c.toon | 39 +++++ .agents/pm/issues/pm-github-lfcf.toon | 12 ++ .agents/pm/tasks/pm-github-aiok.toon | 7 +- .github/workflows/pm-github-closeout.yml | 156 ++++++++++++++++++- .github/workflows/pm-github-sync.yml | 155 ++++++++++++++++++- README.md | 68 +++++++-- docs/bot-pr-automation.md | 155 +++++++++++++++++++ docs/closeout-workflow-caller.yml | 6 +- docs/sync-workflow-caller.yml | 8 +- test/bot-pr-workflow.test.ts | 187 +++++++++++++++++++++++ test/closeout-workflow.test.ts | 4 +- test/import-gate.test.ts | 25 ++- 15 files changed, 812 insertions(+), 40 deletions(-) create mode 100644 .agents/pm/history/pm-github-8r7c.jsonl create mode 100644 .agents/pm/history/pm-github-lfcf.jsonl create mode 100644 .agents/pm/issues/pm-github-8r7c.toon create mode 100644 .agents/pm/issues/pm-github-lfcf.toon create mode 100644 docs/bot-pr-automation.md create mode 100644 test/bot-pr-workflow.test.ts diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl new file mode 100644 index 00000000..12d22eb3 --- /dev/null +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -0,0 +1,27 @@ +{"hash_algorithm":"sha256","ts":"2026-10-17T09:26:43.864Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-8r7c"},{"op":"add","path":"/metadata/title","value":"Keep automated sync and closeout PRs current and dispatch caller checks"},{"op":"add","path":"/metadata/description","value":"GITHUB_TOKEN PR workflows wait for approval; only ci.yml is dispatched, CodeQL is absent, no auto-merge is enabled, and daily release advances the protected base."},{"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":[]},{"op":"add","path":"/metadata/created_at","value":"2026-10-17T09:26:43.864Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-10-17T09:26:43.864Z"},{"op":"add","path":"/metadata/author","value":"codex-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass."}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"d0fa3ae95fd06929208feb808668bc670a338130e38723831396756064668ef9","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":"245eb289d64e21fd73a9c3f327d8154fa7a54962dbe4dc61d65fbd7e0642e928"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:27:11.527Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:27:11.527Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"d0fa3ae95fd06929208feb808668bc670a338130e38723831396756064668ef9","after_hash":"b275c484bc6f5d8d2f46658ff57f3f59630561a6c6bc760678c7739973b598b0","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":"ac698238adb91d5dcf46fced87dd174582f811db9d9866d3f413e7c6e6ea773f"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:27:16.991Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:27:16.991Z"},{"op":"replace","path":"/metadata/status","value":"in_progress"}],"before_hash":"b275c484bc6f5d8d2f46658ff57f3f59630561a6c6bc760678c7739973b598b0","after_hash":"82a8ab3cc89cb7d71b7adbf8c9ede40490ba2640fb66a68b016ec6f01b47766b","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":"f185de3cb142a616aa8c9dd0c2ad97a71e09e4f28cbd88101b40b59c7b97cb88"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:27:20.424Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:27:20.424Z"},{"op":"add","path":"/metadata/comments","value":[{"created_at":"2026-10-17T09:27:20.424Z","author":"codex-agent","text":"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched."}]}],"before_hash":"82a8ab3cc89cb7d71b7adbf8c9ede40490ba2640fb66a68b016ec6f01b47766b","after_hash":"3630ad92bf5ef06fc7899a214c9a87c4b77384df44e4c419e7298ca4ddc94af8","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":"04ab4660236567f4f03db57360195b61ada0cc6d56f8ecccacf8a0071dd4c547"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:34:40.209Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:34:40.209Z","author":"codex-agent","text":"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T09:34:40.209Z"}],"before_hash":"3630ad92bf5ef06fc7899a214c9a87c4b77384df44e4c419e7298ca4ddc94af8","after_hash":"030663141d8a3b14ba39cffe687f48a2bd59488480638d3db189292e7538fd5b","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":"49c0bebb2b7cf89816fde6a617a219e324fa0a8cac445466daa441f15ca23ab7"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:34:47.340Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:34:47.340Z"},{"op":"add","path":"/metadata/files","value":[{"path":".github/workflows/pm-github-sync.yml","scope":"project"}]}],"before_hash":"030663141d8a3b14ba39cffe687f48a2bd59488480638d3db189292e7538fd5b","after_hash":"039dd4d9c74d395e7ff9f065003c6299f3e61c77391cef5367e9a12550098ac2","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":"e3691ad764de8aaeec79af7d53752f7a3df7d76f19439db7a9f50736f9ecf964"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:34:54.768Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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/files/0/path","value":".github/workflows/pm-github-closeout.yml"},{"op":"add","path":"/metadata/files/1","value":{"path":".github/workflows/pm-github-sync.yml","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T09:34:54.768Z"}],"before_hash":"039dd4d9c74d395e7ff9f065003c6299f3e61c77391cef5367e9a12550098ac2","after_hash":"304cc5b44f99900f4728d370286969d080ac14c96b77bbc7c25054471d671e83","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":"cab24dbef703bf17a149088286756540e93100e33e802d487e1428c34727fe6d"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:35:03.457Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"files_add","patch":[{"op":"add","path":"/metadata/files/2","value":{"path":"test/bot-pr-workflow.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T09:35:03.457Z"}],"before_hash":"304cc5b44f99900f4728d370286969d080ac14c96b77bbc7c25054471d671e83","after_hash":"93e771b7466f9d5793372c67fe3fcfbe87e8f52a35d67ce78555268b8d0a4bbd","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":"45ff238630104066f4bb3d129b4552d5ac42952463dfd31bfff0fd1e7f606529"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:35:12.342Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:35:12.342Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/bot-pr-automation.md","scope":"project"}]}],"before_hash":"93e771b7466f9d5793372c67fe3fcfbe87e8f52a35d67ce78555268b8d0a4bbd","after_hash":"b59ae5f40b9628492f4d7fe230c1160a13724cf0ea6588d3c589b32ccd8d0655","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":"78e42e36c65721a4fd0713cab18be33980c3fa4af191bc9595040501615742eb"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:35:21.591Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:35:21.591Z"},{"op":"add","path":"/metadata/tests","value":[{"command":"node --test test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-17T09:35:21.256Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}]}],"before_hash":"b59ae5f40b9628492f4d7fe230c1160a13724cf0ea6588d3c589b32ccd8d0655","after_hash":"f892486756fe2035b027852fbd47220511926887df41bdbd7b82348c9fd3b872","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":"11918c8f65505557c7022cfd5e53da5520bbbe7af6168faf2b369c6dde9ee844"} +{"hash_algorithm":"sha256","ts":"2026-10-17T09:46:00.517Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T09:46:00.517Z","author":"codex-agent","text":"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T09:46:00.517Z"}],"before_hash":"f892486756fe2035b027852fbd47220511926887df41bdbd7b82348c9fd3b872","after_hash":"622c07ff4dfd231aeb7f3376e92898dede3b03bab7e8b148f5bf38a04a546e20","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":"3917ee1d8221f15916944f60f3c39ffc82135eaf18068f7ae35577d9c3c1b3f9"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:08:37.108Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:08:37.108Z","author":"codex-agent","text":"The full integration gate exposed a real diagnostic regression in the new dispatch helper: Bash ERR traps were not inherited by functions, so dispatch denial exited without the required token diagnostic. Set errtrace for the maintenance step and added fast denial regressions for both workflows. Fixed denial cases pass 2/2; reverting only errtrace fails 2/2. No protection was bypassed, and dispatch failure still exits before auto-merge. Full gates are being rerun with final code."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:08:37.108Z"}],"before_hash":"622c07ff4dfd231aeb7f3376e92898dede3b03bab7e8b148f5bf38a04a546e20","after_hash":"c8a2ca343564f288524032784460f73b239275b2c95322306dab177e0f6c8de3","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":"da7a2ab79b45f93b07042fb1454079f6d74df5b469816279f84a94738097038e"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:18:08.976Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:18:08.975Z","author":"codex-agent","text":"The final PM-run regression suite passes 13/13 with zero skipped tests. Reverting only the maintenance bodies fails 12/13 cases; reverting only Bash error tracing fails both denial cases. All 24 audited callers already permit auto-merge and squash, so repository merge settings need no current change. Caller setup remains the documented CodeQL trigger, explicit CI override, and required-check policy declarations. Full npm/Bun CI-identity retries retain every assertion and threshold."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:18:08.976Z"}],"before_hash":"c8a2ca343564f288524032784460f73b239275b2c95322306dab177e0f6c8de3","after_hash":"4a904abd13b553f5ee488ec7f15e35a1f12cc888259f4143d543e7511319d275","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":"cf7faaafb0ee339cef70efece458c483160aacf56a7efac64acda100bef63560"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:31:30.754Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:31:30.754Z","author":"codex-agent","text":"Additional root cause verified in current GitHub documentation: workflow_dispatch job checks are excluded from PR evaluation and cannot satisfy required branch-rule checks, even when green on the head SHA. This explains the REST-versus-PR-checks discrepancy. Implement the documented GitHub App path: optional client ID plus private-key secret, mint a current-repository token only after local gates, use it for publication and refresh to trigger eligible native pull_request runs, and retain default GITHUB_TOKEN with an explicit setup notice. Native protections remain enforced; no copied or synthetic green statuses. App-enabled maintenance must end inside the one-hour token lifetime. Source: https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks and https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:31:30.754Z"}],"before_hash":"4a904abd13b553f5ee488ec7f15e35a1f12cc888259f4143d543e7511319d275","after_hash":"1fb5ccbe7283a34c4a2d64885f225bf6e9dc5e504596d16e8402285fcbe4fedf","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":"a3dfe8d8cbab64b44e52210e59690cd33b4ffa8a68fdb5092b5490d26306383e"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:33.282Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:58:33.282Z","author":"codex-agent","text":"Final design adds the documented optional App path because manual head checks are ineligible for PR branch rules. The pinned official token action requests only the caller repository and five explicit permissions (contents/pull-requests/actions write; checks/statuses read), with job-end revocation. Key material is supplied only after caller scripts and local gates. Publication and refresh use the App token to trigger eligible native PR runs; empty config retains GITHUB_TOKEN with a notice, and partial config fails. A forty-minute absolute deadline starts immediately after minting so publication delay counts against token lifetime. App-focused regressions pass 8/8, and the complete focused suite passes 21/21. Rollout follow-up is enriched in existing pm-github-aiok; no caller operations were performed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:58:33.282Z"}],"before_hash":"1fb5ccbe7283a34c4a2d64885f225bf6e9dc5e504596d16e8402285fcbe4fedf","after_hash":"c68fb2be6119d70921d0d4fdcc4275d09dcd8934eb5fb59e7c115cf6d42d3e22","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":"eb8b295642ef41393ef807ed83e94ff5eafd345ac7b37fb6fb6b762da3facfdc"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:46.730Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"files_add","patch":[{"op":"add","path":"/metadata/files/3","value":{"path":"test/import-gate.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:58:46.730Z"}],"before_hash":"c68fb2be6119d70921d0d4fdcc4275d09dcd8934eb5fb59e7c115cf6d42d3e22","after_hash":"3ed78749559aea2b90c149cb57048bdb9fc2e9b48f925eebacc29f6104c0a1be","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":"1bf583cb5d9b98a8e675766fd4342a1fa94cb31867ff49a5268c327151144c3f"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:57.624Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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/files/3/path","value":"test/closeout-workflow.test.ts"},{"op":"add","path":"/metadata/files/4","value":{"path":"test/import-gate.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:58:57.624Z"}],"before_hash":"3ed78749559aea2b90c149cb57048bdb9fc2e9b48f925eebacc29f6104c0a1be","after_hash":"56bd2f49dfa2c33f32eb972a70a82b42c7de0696cdfaad415759fcb405a3ef1f","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":"b3ae9ee91388d6c50a243a21a0919404d535e54ea3e04b93c3e5cd695a5b563e"} +{"hash_algorithm":"sha256","ts":"2026-10-17T11:12:34.627Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T11:12:34.627Z","author":"codex-agent","text":"Read-only ancestry audit found pm-ado#32 reported UNKNOWN while its head was two base commits behind. Maintenance now checks compare API behind_by independently of merge-state labels. Added real-Git regressions for BLOCKED plus base advance; both workflow cases pass. No caller workflows were dispatched."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T11:12:34.627Z"}],"before_hash":"56bd2f49dfa2c33f32eb972a70a82b42c7de0696cdfaad415759fcb405a3ef1f","after_hash":"ac2b5ac1a14f18d4c35b531296abb600313b1363590f5e136c1ba483b60ce350","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":"7f8a994b80c14bd760fb4a12bf39ca9532279685e78ac575ea2692d9fac58cfe"} +{"hash_algorithm":"sha256","ts":"2026-10-17T11:14:04.928Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T11:14:04.919Z","author":"codex-agent","text":"Behavioural revert proof: in an isolated copy, replacing only the ancestry-based refresh condition with merge-state BEHIND makes both masked-base-advance regressions fail (0/2 pass); restoring the compare-ancestry condition passes 2/2 with zero skips. Existing maintenance revert fails 18 of 21 regressions; App credential-pair guard revert fails 2/2; dispatch ERR-inheritance revert fails 2/2. No production workflow was invoked for these proofs."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T11:14:04.928Z"}],"before_hash":"ac2b5ac1a14f18d4c35b531296abb600313b1363590f5e136c1ba483b60ce350","after_hash":"b35fdff564adc37489d2c55cea225ecb8a705990e99402478b26399905358c4f","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":"fd99fbdcdf238118b14f79f5b0e53b393fa03613b842335f070e51cbc8348411"} +{"hash_algorithm":"sha256","ts":"2026-10-17T12:22:22.139Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T12:22:22.139Z","author":"codex-agent","text":"The full gate exposed a stale default-branch integration assertion: publication now re-queries the owned PR to retain its verified number, so the old fixed request count is no longer valid. Preserve the behavioral assertions instead: every request uses the caller base, exactly one PR is created, and the final request verifies the owned PR. Restart full gates after this test correction; no runtime safety check is weakened."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T12:22:22.139Z"}],"before_hash":"b35fdff564adc37489d2c55cea225ecb8a705990e99402478b26399905358c4f","after_hash":"671ad7d3f39f690a5f4e19982133d0b1422f0896e54f067e7c3b2706374c51ee","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":"824b1703f281d65aee24b00df465859eba4f4e3dc9b14c50be86d45aa698d4a1"} +{"hash_algorithm":"sha256","ts":"2026-10-17T12:27:21.029Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T12:27:21.029Z","author":"codex-agent","text":"Standalone integration reproduction exposed fixture host skew: bare pm initialized scratch trackers using the newer global host, while workflow replay used the repository pin, changing merge attributes and correctly triggering the scope refusal. Resolve the fixture executable from node_modules/.bin so direct runs and npm/CI use the same pinned host. Production scope rules stay unchanged."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T12:27:21.029Z"}],"before_hash":"671ad7d3f39f690a5f4e19982133d0b1422f0896e54f067e7c3b2706374c51ee","after_hash":"c56af00b0eb7c0ecc025f0976fea4e84bfcd00dbf22a4f7602cf49aeac07b634","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":"f40dea52b5878695d7fc80c5491f064c4340362c2419bc2e9c4d662cf2f377ac"} +{"hash_algorithm":"sha256","ts":"2026-10-17T12:31:53.874Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T12:31:53.874Z","author":"codex-agent","text":"The pinned-host reproduction reached the actual dispatch guard: positive shared caller fixtures lacked a real ci.yml, which the former unfiltered dispatcher never inspected. Seed a committed pull_request/workflow_dispatch CI file in positive fixtures while keeping the dedicated no-dispatchable-workflow regressions unchanged. The additional owned-PR lookup also requires the property-based request assertions already added. Production safety refusals remain intact."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T12:31:53.874Z"}],"before_hash":"c56af00b0eb7c0ecc025f0976fea4e84bfcd00dbf22a4f7602cf49aeac07b634","after_hash":"7dfbdcf4dc7edc1732eb862659b495483f9a7fb2c8119fea1dcac16de64263ee","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":"61bd09d27e49801f5ab5087f0170c6f331b662ad4f4b311114b27a905816d4c6"} +{"hash_algorithm":"sha256","ts":"2026-10-17T13:38:31.747Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-name-pattern='^(the caller default branch trunk flows from schedule guard through real Git preparation and review|the workflow never edits a fork PR sharing the sync branch name|npm-project-dir subdirectory CLI and SDK keep the tracker and publication at the repository root)$' test/import-gate.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-17T13:38:31.648Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:38:31.747Z"}],"before_hash":"7dfbdcf4dc7edc1732eb862659b495483f9a7fb2c8119fea1dcac16de64263ee","after_hash":"ffa5d802d1b614be6dd92fc9a2d4fd839650d1dc36ae4a5be496d3093d245663","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":"4ea081f36d691fd247af0295c23ded65273d8678b7b1d6ce9e98d8587f8c3e12"} +{"hash_algorithm":"sha256","ts":"2026-10-17T13:38:34.141Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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/12","value":{"created_at":"2026-10-17T13:38:34.138Z","author":"codex-agent","text":"Corrected positive fixtures pass 3/3: caller trunk through real preparation/publication, fork PR isolation, and nested npm project. Full restarted npm suite passes 777/777 with zero failures/skips; coverage aggregation and remaining release gates are still pending. Workflow behavior remains protected; fixture initialization is pinned and positive fixtures now include dispatchable CI."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:38:34.141Z"}],"before_hash":"ffa5d802d1b614be6dd92fc9a2d4fd839650d1dc36ae4a5be496d3093d245663","after_hash":"27181a34479722197e8c5684b4784b7e25ca42a0d0b1d5f74b1ee86d1079206b","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":"032aec2a1ffec683a2f7f5e499002af1e6b47263def35fd3003a65dcea9317af"} +{"hash_algorithm":"sha256","ts":"2026-10-17T13:46:22.650Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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/13","value":{"created_at":"2026-10-17T13:46:22.650Z","author":"codex-agent","text":"Final behavioral revert receipt against the complete current 23-case file: restoring only the two original workflow implementations in an isolated copy yields 1 pass and 22 failures, zero skips. Fixed implementations pass 23/23 (including under the full 777/777 npm suite). The independent ancestry-only revert fails both masked-base-advance cases; restoring ancestry passes 2/2. Full npm release gate exits 0 with all 13 authored modules at exact 100/100/100/100; Bun release gate remains running."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T13:46:22.650Z"}],"before_hash":"27181a34479722197e8c5684b4784b7e25ca42a0d0b1d5f74b1ee86d1079206b","after_hash":"9d1b35c0df5576faf19b6fd5aee3ea0088e9fc9f87993d99e799954463098e9d","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":"08ad69369b8efeac0f8cffca8e52222f17d023a7c3ecf39bb9e6e0b433b09b58"} +{"hash_algorithm":"sha256","ts":"2026-10-17T14:16:09.163Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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/14","value":{"created_at":"2026-10-17T14:16:09.163Z","author":"codex-agent","text":"Final local gates PASS with isolated CI identity (HOME scratch, global/system Git config disabled): npm run release:check and bun run release:check both exit 0, each 777/777 tests, zero failures/skips, all 13 authored modules at exact 100% statements/branches/functions/lines. Linked pm commands pass 23/23 maintenance plus 3/3 real-workflow positive fixtures. Revert receipts: original workflow implementations fail 22/23; ancestry-only, ERR-inheritance and App-pairing reverts each fail 2/2. Caller audit is read-only; all 24 setup requirements are documented, rollout tracked in pm-github-aiok, changelog-placement finding in pm-github-lfcf. No caller dispatch, merge or release performed; PR 142 remains separate."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T14:16:09.163Z"}],"before_hash":"9d1b35c0df5576faf19b6fd5aee3ea0088e9fc9f87993d99e799954463098e9d","after_hash":"1b271a103c77915dfd5b5baf95d89fbb5cf965a5b3d8a86c07eb015a5507d260","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":"4eb3072ed7c4570bd76c7fd4e459c386b2fc320ac317c0a4cd8d694b70f115f9"} +{"hash_algorithm":"sha256","ts":"2026-10-17T14:16:10.371Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T14:16:10.371Z"}],"before_hash":"1b271a103c77915dfd5b5baf95d89fbb5cf965a5b3d8a86c07eb015a5507d260","after_hash":"63ff6e56038a7598dd367423ebc52b103be994102d9362bf26d2d65fafb16d8f","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":"7c06ce7f48f34e7bed264b669ae9972b76a04c47b8e74950b2acd1e2c7db361a"} diff --git a/.agents/pm/history/pm-github-aiok.jsonl b/.agents/pm/history/pm-github-aiok.jsonl index 0ff91d03..23052bfa 100644 --- a/.agents/pm/history/pm-github-aiok.jsonl +++ b/.agents/pm/history/pm-github-aiok.jsonl @@ -3,3 +3,5 @@ {"hash_algorithm":"sha256","ts":"2026-10-05T09:25:59.227Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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-05T09:25:59.227Z"},{"op":"add","path":"/metadata/files","value":[{"path":"docs/sync-workflow-caller.yml","scope":"project"}]}],"before_hash":"afd27b09ad086b7bc0339128cf19fecc80e654e03c3f8f44b06ee0d0ca5b9ae8","after_hash":"b5f06d9ff353748e0db7b1603a7082e45cc6d3931e045f83f39bfa9f4f38c13c","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":"b582f9f159f845f61c14bb7c6f626954807d6a764b5a15b48382001b8034ec0f"} {"hash_algorithm":"sha256","ts":"2026-10-05T09:26:00.035Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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/files/0/path","value":".github/workflows/pm-github-sync.yml"},{"op":"add","path":"/metadata/files/1","value":{"path":"docs/sync-workflow-caller.yml","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-05T09:26:00.035Z"}],"before_hash":"b5f06d9ff353748e0db7b1603a7082e45cc6d3931e045f83f39bfa9f4f38c13c","after_hash":"ace7fe3eed738ae79e924bb2dcd5d737884f92d56c645dd0bfd26feedbae41c0","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":"6bce5babc0899063bf4fadb1a8438d2f6d0e543952b1bc83240f32b20d96103d"} {"hash_algorithm":"sha256","ts":"2026-10-05T09:32:54.787Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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-05T09:32:54.787Z"},{"op":"add","path":"/metadata/dependencies","value":[{"id":"pm-github-f1at","kind":"related","created_at":"2026-10-05T09:32:54.728Z","author":"codex-sol","source_kind":"cli:update:dep","author_source":"detected"}]}],"before_hash":"ace7fe3eed738ae79e924bb2dcd5d737884f92d56c645dd0bfd26feedbae41c0","after_hash":"7c5c3f9c474ddf2c45bd4673bfc27442e51863889c3561690fe1400acc597e4a","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":"dbe2f513aac4d1acb373693cfdccf5517d680c1ffa049f1a9c29f2b7bc92e2a2"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:16.179Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:58:16.179Z","author":"codex-agent","text":"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:58:16.179Z"}],"before_hash":"7c5c3f9c474ddf2c45bd4673bfc27442e51863889c3561690fe1400acc597e4a","after_hash":"96d5a54411a5b5324e69fc1049e9883754836b4c413b65beb62e12e8678d5f9c","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":"4167a192b1875176e986cc601c20252a091ea3dfd3b86184f0e66d27fe34a24c"} +{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:24.790Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:58:24.790Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/bot-pr-automation.md","scope":"project"}]}],"before_hash":"96d5a54411a5b5324e69fc1049e9883754836b4c413b65beb62e12e8678d5f9c","after_hash":"53235e2f01e75d86f844a25e2e28a0d7ad95ee1f9ac9c7f8ca984c74181a499d","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":"7565a55a5b727fcbde5e91ad216bf3cc0ac5581a2c617109027989c2b1bf6430"} diff --git a/.agents/pm/history/pm-github-lfcf.jsonl b/.agents/pm/history/pm-github-lfcf.jsonl new file mode 100644 index 00000000..45dcd793 --- /dev/null +++ b/.agents/pm/history/pm-github-lfcf.jsonl @@ -0,0 +1 @@ +{"hash_algorithm":"sha256","ts":"2026-10-17T09:45:00.893Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-lfcf"},{"op":"add","path":"/metadata/title","value":"Closeout changelog generation attributes new deliveries to an old package release"},{"op":"add","path":"/metadata/description","value":"Verified unresolved review at https://github.com/unbraind/pm-ado/pull/32#discussion_r4301991646: October delivery is rendered under package version 2026.9.2 and its September heading. Auto-merge must leave conversation resolution intact. Investigate caller changelog/release policy separately from check dispatch and PR freshness; coordinate with import-fidelity PR 142 without changing that branch."},{"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":[]},{"op":"add","path":"/metadata/created_at","value":"2026-10-17T09:45:00.893Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-10-17T09:45:00.893Z"},{"op":"add","path":"/metadata/author","value":"codex-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"Regenerated closeout output keeps historical release sections intact and presents post-release deliveries under the correct unreleased or released heading; regression fails when the release placement rule is reverted."}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"c5fcf4565a8cf49ba7253e9a88a4233ccc42447f347e22403ab5ee2f22e12a14","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":"739a16db9790d6b39d0fd693f6f93d4fd2aba291a407c24b9adb723a20acd30d"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon new file mode 100644 index 00000000..0b6400f0 --- /dev/null +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -0,0 +1,39 @@ +id: pm-github-8r7c +title: Keep automated sync and closeout PRs current and dispatch caller checks +description: "GITHUB_TOKEN PR workflows wait for approval; only ci.yml is dispatched, CodeQL is absent, no auto-merge is enabled, and daily release advances the protected base." +type: Issue +status: in_progress +priority: 1 +tags: [] +created_at: "2026-10-17T09:26:43.864Z" +updated_at: "2026-10-17T14:16:10.371Z" +author: codex-agent +acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. +comments[15]{created_at,author,text}: + "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." + "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." + "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." + "2026-10-17T10:08:37.108Z",codex-agent,"The full integration gate exposed a real diagnostic regression in the new dispatch helper: Bash ERR traps were not inherited by functions, so dispatch denial exited without the required token diagnostic. Set errtrace for the maintenance step and added fast denial regressions for both workflows. Fixed denial cases pass 2/2; reverting only errtrace fails 2/2. No protection was bypassed, and dispatch failure still exits before auto-merge. Full gates are being rerun with final code." + "2026-10-17T10:18:08.975Z",codex-agent,"The final PM-run regression suite passes 13/13 with zero skipped tests. Reverting only the maintenance bodies fails 12/13 cases; reverting only Bash error tracing fails both denial cases. All 24 audited callers already permit auto-merge and squash, so repository merge settings need no current change. Caller setup remains the documented CodeQL trigger, explicit CI override, and required-check policy declarations. Full npm/Bun CI-identity retries retain every assertion and threshold." + "2026-10-17T10:31:30.754Z",codex-agent,"Additional root cause verified in current GitHub documentation: workflow_dispatch job checks are excluded from PR evaluation and cannot satisfy required branch-rule checks, even when green on the head SHA. This explains the REST-versus-PR-checks discrepancy. Implement the documented GitHub App path: optional client ID plus private-key secret, mint a current-repository token only after local gates, use it for publication and refresh to trigger eligible native pull_request runs, and retain default GITHUB_TOKEN with an explicit setup notice. Native protections remain enforced; no copied or synthetic green statuses. App-enabled maintenance must end inside the one-hour token lifetime. Source: https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks and https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow" + "2026-10-17T10:58:33.282Z",codex-agent,"Final design adds the documented optional App path because manual head checks are ineligible for PR branch rules. The pinned official token action requests only the caller repository and five explicit permissions (contents/pull-requests/actions write; checks/statuses read), with job-end revocation. Key material is supplied only after caller scripts and local gates. Publication and refresh use the App token to trigger eligible native PR runs; empty config retains GITHUB_TOKEN with a notice, and partial config fails. A forty-minute absolute deadline starts immediately after minting so publication delay counts against token lifetime. App-focused regressions pass 8/8, and the complete focused suite passes 21/21. Rollout follow-up is enriched in existing pm-github-aiok; no caller operations were performed." + "2026-10-17T11:12:34.627Z",codex-agent,Read-only ancestry audit found pm-ado#32 reported UNKNOWN while its head was two base commits behind. Maintenance now checks compare API behind_by independently of merge-state labels. Added real-Git regressions for BLOCKED plus base advance; both workflow cases pass. No caller workflows were dispatched. + "2026-10-17T11:14:04.919Z",codex-agent,"Behavioural revert proof: in an isolated copy, replacing only the ancestry-based refresh condition with merge-state BEHIND makes both masked-base-advance regressions fail (0/2 pass); restoring the compare-ancestry condition passes 2/2 with zero skips. Existing maintenance revert fails 18 of 21 regressions; App credential-pair guard revert fails 2/2; dispatch ERR-inheritance revert fails 2/2. No production workflow was invoked for these proofs." + "2026-10-17T12:22:22.139Z",codex-agent,"The full gate exposed a stale default-branch integration assertion: publication now re-queries the owned PR to retain its verified number, so the old fixed request count is no longer valid. Preserve the behavioral assertions instead: every request uses the caller base, exactly one PR is created, and the final request verifies the owned PR. Restart full gates after this test correction; no runtime safety check is weakened." + "2026-10-17T12:27:21.029Z",codex-agent,"Standalone integration reproduction exposed fixture host skew: bare pm initialized scratch trackers using the newer global host, while workflow replay used the repository pin, changing merge attributes and correctly triggering the scope refusal. Resolve the fixture executable from node_modules/.bin so direct runs and npm/CI use the same pinned host. Production scope rules stay unchanged." + "2026-10-17T12:31:53.874Z",codex-agent,"The pinned-host reproduction reached the actual dispatch guard: positive shared caller fixtures lacked a real ci.yml, which the former unfiltered dispatcher never inspected. Seed a committed pull_request/workflow_dispatch CI file in positive fixtures while keeping the dedicated no-dispatchable-workflow regressions unchanged. The additional owned-PR lookup also requires the property-based request assertions already added. Production safety refusals remain intact." + "2026-10-17T13:38:34.138Z",codex-agent,"Corrected positive fixtures pass 3/3: caller trunk through real preparation/publication, fork PR isolation, and nested npm project. Full restarted npm suite passes 777/777 with zero failures/skips; coverage aggregation and remaining release gates are still pending. Workflow behavior remains protected; fixture initialization is pinned and positive fixtures now include dispatchable CI." + "2026-10-17T13:46:22.650Z",codex-agent,"Final behavioral revert receipt against the complete current 23-case file: restoring only the two original workflow implementations in an isolated copy yields 1 pass and 22 failures, zero skips. Fixed implementations pass 23/23 (including under the full 777/777 npm suite). The independent ancestry-only revert fails both masked-base-advance cases; restoring ancestry passes 2/2. Full npm release gate exits 0 with all 13 authored modules at exact 100/100/100/100; Bun release gate remains running." + "2026-10-17T14:16:09.163Z",codex-agent,"Final local gates PASS with isolated CI identity (HOME scratch, global/system Git config disabled): npm run release:check and bun run release:check both exit 0, each 777/777 tests, zero failures/skips, all 13 authored modules at exact 100% statements/branches/functions/lines. Linked pm commands pass 23/23 maintenance plus 3/3 real-workflow positive fixtures. Revert receipts: original workflow implementations fail 22/23; ancestry-only, ERR-inheritance and App-pairing reverts each fail 2/2. Caller audit is read-only; all 24 setup requirements are documented, rollout tracked in pm-github-aiok, changelog-placement finding in pm-github-lfcf. No caller dispatch, merge or release performed; PR 142 remains separate." +files[5]{path,scope}: + .github/workflows/pm-github-closeout.yml,project + .github/workflows/pm-github-sync.yml,project + test/bot-pr-workflow.test.ts,project + test/closeout-workflow.test.ts,project + test/import-gate.test.ts,project +tests[2]{command,scope,provenance{author,created_at,source_kind,source_ref}}: + node --test test/bot-pr-workflow.test.ts,project,codex-agent,"2026-10-17T09:35:21.256Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current + node --test --test-name-pattern='^(the caller default branch trunk flows from schedule guard through real Git preparation and review|the workflow never edits a fork PR sharing the sync branch name|npm-project-dir subdirectory CLI and SDK keep the tracker and publication at the repository root)$' test/import-gate.test.ts,project,codex-agent,"2026-10-17T13:38:31.648Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current +docs[1]{path,scope}: + docs/bot-pr-automation.md,project +body: "" diff --git a/.agents/pm/issues/pm-github-lfcf.toon b/.agents/pm/issues/pm-github-lfcf.toon new file mode 100644 index 00000000..9bcabcd5 --- /dev/null +++ b/.agents/pm/issues/pm-github-lfcf.toon @@ -0,0 +1,12 @@ +id: pm-github-lfcf +title: Closeout changelog generation attributes new deliveries to an old package release +description: "Verified unresolved review at https://github.com/unbraind/pm-ado/pull/32#discussion_r4301991646: October delivery is rendered under package version 2026.9.2 and its September heading. Auto-merge must leave conversation resolution intact. Investigate caller changelog/release policy separately from check dispatch and PR freshness; coordinate with import-fidelity PR 142 without changing that branch." +type: Issue +status: open +priority: 1 +tags: [] +created_at: "2026-10-17T09:45:00.893Z" +updated_at: "2026-10-17T09:45:00.893Z" +author: codex-agent +acceptance_criteria: Regenerated closeout output keeps historical release sections intact and presents post-release deliveries under the correct unreleased or released heading; regression fails when the release placement rule is reverted. +body: "" diff --git a/.agents/pm/tasks/pm-github-aiok.toon b/.agents/pm/tasks/pm-github-aiok.toon index 775f9a9e..f2a3a9d0 100644 --- a/.agents/pm/tasks/pm-github-aiok.toon +++ b/.agents/pm/tasks/pm-github-aiok.toon @@ -6,13 +6,16 @@ status: open priority: 1 tags: [] created_at: "2026-10-05T09:23:42.980Z" -updated_at: "2026-10-05T09:32:54.787Z" +updated_at: "2026-10-17T10:58:24.790Z" author: codex-sol dependencies[1]{id,kind,created_at,author,source_kind,author_source}: pm-github-f1at,related,"2026-10-05T09:32:54.728Z",codex-sol,"cli:update:dep",detected -comments[1]{created_at,author,text}: +comments[2]{created_at,author,text}: "2026-10-05T09:25:31.280Z",codex-sol,"The caller example intentionally uses release commit and exact version placeholders. The currently published extension predates the gate, and this work is authorized only in the pm-github worktree. No pilot workflow in another repository was changed, enabled, or dispatched. Resolve the placeholders only after a reviewed release and separately authorized caller adoption." + "2026-10-17T10:58:16.179Z",codex-agent,"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them." files[2]{path,scope}: .github/workflows/pm-github-sync.yml,project docs/sync-workflow-caller.yml,project +docs[1]{path,scope}: + docs/bot-pr-automation.md,project body: "" diff --git a/.github/workflows/pm-github-closeout.yml b/.github/workflows/pm-github-closeout.yml index 852ae4e9..148e8628 100644 --- a/.github/workflows/pm-github-closeout.yml +++ b/.github/workflows/pm-github-closeout.yml @@ -27,21 +27,31 @@ on: required: false default: "changelog:full" ci-workflows: - description: "Whitespace-separated caller workflow filenames with workflow_dispatch; empty disables dispatch" + description: "Caller workflow filenames with workflow_dispatch; empty disables dispatch and auto-merge" type: string required: false - default: "ci.yml" + default: "ci.yml codeql.yml" required-checks: description: "One required context name per line; spaces are preserved and blank lines ignored; used when protection metadata is unavailable" type: string required: false default: "" + automation-app-client-id: + description: "Optional GitHub App client ID; pair with automation_app_private_key for eligible native PR checks" + type: string + required: false + default: "" node-version: description: "Node.js version for the pm CLI" type: string required: false default: "22.18.0" + secrets: + automation_app_private_key: + description: "Private key for the optional automation App installed on the calling repository" + required: false + concurrency: group: pm-github-closeout-${{ github.repository }} cancel-in-progress: false @@ -333,9 +343,49 @@ jobs: - name: Verify strict pm health run: pm health --strict-exit + # Mint only after caller scripts and local gates have finished. The key + # is passed only to the pinned official action; its token is repo-scoped. + - name: Create automation app token + id: automation_token + if: inputs.automation-app-client-id != '' + uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 + with: + client-id: ${{ inputs.automation-app-client-id }} + private-key: ${{ secrets.automation_app_private_key }} + repositories: ${{ github.repository }} + skip-token-revoke: false + permission-contents: write + permission-pull-requests: write + permission-actions: write + permission-checks: read + permission-statuses: read + + - name: Validate publication credentials + id: publication_auth + env: + APP_CLIENT_ID: ${{ inputs.automation-app-client-id }} + HAS_APP_PRIVATE_KEY: ${{ secrets.automation_app_private_key != '' }} + HAS_AUTOMATION_TOKEN: ${{ steps.automation_token.outputs.token != '' }} + shell: bash + run: | + set -euo pipefail + if [[ -z "${APP_CLIENT_ID:-}" ]]; then + if [[ "${HAS_APP_PRIVATE_KEY:-false}" == true ]]; then + echo "::error::automation_app_private_key requires automation-app-client-id." + exit 1 + fi + echo "::notice::Using GITHUB_TOKEN: native PR runs require approval, and dispatched checks cannot satisfy PR branch rules. Configure the optional automation App for unattended landing." + elif [[ "${HAS_APP_PRIVATE_KEY:-false}" != true || "${HAS_AUTOMATION_TOKEN:-false}" != true ]]; then + echo "::error::Configured automation App did not produce a token; check its private key, installation and repository permissions." + exit 1 + else + # Start the App deadline immediately after minting, before publication. + printf 'deadline=%s\n' "$(( $(date +%s) + 2400 ))" >> "${GITHUB_OUTPUT}" + fi + - name: Commit gated closeout changes and open review PR env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.automation_token.outputs.token || github.token }} shell: bash run: | set -euo pipefail @@ -431,18 +481,32 @@ jobs: else gh pr edit "${pr_number}" -R "${REPOSITORY}" --title "chore(pm): close items delivered by merged pull requests" --body-file "${body_file}" fi + pr_number="$(own_open_pr)" + [[ "${pr_number}" =~ ^[0-9]+$ ]] || { echo "::error::Cannot resolve the owned automation PR number."; exit 1; } + export SYNC_PR_NUMBER="${pr_number}" + printf 'SYNC_PR_NUMBER=%s\n' "${pr_number}" >> "${GITHUB_ENV}" export SYNC_PUBLISHED=true printf 'SYNC_PUBLISHED=true\n' >> "${GITHUB_ENV}" - name: Dispatch caller CI and report parked runs if: env.SYNC_PUBLISHED == 'true' env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.automation_token.outputs.token || github.token }} + MAINTENANCE_ATTEMPTS: ${{ steps.automation_token.outputs.token != '' && '40' || '120' }} + MAINTENANCE_SECONDS: ${{ steps.automation_token.outputs.token != '' && '2400' || '7200' }} + APP_DEADLINE: ${{ steps.publication_auth.outputs.deadline }} shell: bash run: | - set -euo pipefail - trap 'echo "::error::Caller CI dispatch failed; token requires actions:write and configured workflows must support workflow_dispatch. The review PR remains unmerged."' ERR + set -Eeuo pipefail + trap 'echo "::error::Caller check dispatch or PR maintenance failed; token requires actions:write, contents:write and pull-requests:write, and selected workflows must support workflow_dispatch. Inspect the bot PR state; no protection was bypassed."' ERR [[ "${SYNC_PUBLISHED:-false}" == true ]] || exit 0 + # Default inventory covers the fleet's CI and CodeQL names. An explicit + # list replaces it; empty disables dispatch AND automatic landing. + if [[ -z "${CI_WORKFLOWS}" ]]; then + echo "::notice::Caller CI dispatch and automatic landing are disabled by ci-workflows." + exit 0 + fi + workflows=() while IFS= read -r workflow_file; do [[ -n "${workflow_file}" ]] || continue [[ "${workflow_file}" =~ ^[a-zA-Z0-9_.-]+\.ya?ml$ ]] || { echo "::error::ci-workflows must contain workflow filenames."; exit 1; } @@ -450,11 +514,87 @@ jobs: echo "::notice::Skipping missing caller workflow: ${workflow_file}" continue fi - gh workflow run "${workflow_file}" -R "${REPOSITORY}" --ref "${SYNC_BRANCH}" + # Standard block and compact trigger forms; nested job/input keys + # cannot make a workflow dispatchable. Unknown forms fail closed. + if ! awk ' + /^on: *workflow_dispatch *(#.*)?$/ { found=1 } + /^on: *\[([^]]*, *)?workflow_dispatch *(,|\])/ { found=1 } + /^on: *($|#)/ { in_on=1; next } + /^[^[:space:]#]/ { in_on=0 } + in_on && /^ workflow_dispatch:/ { found=1 } + END { exit !found } + ' ".github/workflows/${workflow_file}"; then + echo "::warning::Skipping non-dispatchable caller workflow: ${workflow_file}. Add workflow_dispatch: under on: on the default branch for manual head validation. Eligible native PR checks must still pass." + continue + fi + mapfile -O "${#workflows[@]}" -t workflows < <(printf '%s\n' "${workflow_file}") done < <(printf '%s\n' "${CI_WORKFLOWS}" | tr ' \t\r' '\n') + if [[ ${#workflows[@]} == 0 ]]; then + echo "::error::No dispatchable caller workflow; automatic landing refused." + exit 1 + fi + # Dispatch every selected workflow before requesting protected auto-merge. + dispatch_checks() { + local workflow_file + for workflow_file in "${workflows[@]}"; do + gh workflow run "${workflow_file}" -R "${REPOSITORY}" --ref "${SYNC_BRANCH}" + done + } + # --auto respects required checks and conversation resolution. The SHA + # guard refuses a changed head; a disabled repository setting is soft. + enable_auto_merge() { + if ! gh pr merge "${SYNC_PR_NUMBER}" -R "${REPOSITORY}" --auto --squash --match-head-commit "${head_sha}"; then + echo "::notice::Squash auto-merge unavailable for the bot PR; repository settings or branch rules require attention. No protection was bypassed." + fi + } head_sha="$(git rev-parse HEAD)" + dispatch_checks + enable_auto_merge parked_runs="$(gh run list -R "${REPOSITORY}" --commit "${head_sha}" --status action_required --limit 100 --json url --jq '.[].url')" while IFS= read -r run_url; do [[ -n "${run_url}" ]] || continue - echo "::notice::A pull-request workflow requires maintainer approval: ${run_url}. Review this parked run if needed; caller CI dispatch runs are separate." + echo "::notice::A pull-request workflow requires maintainer approval: ${run_url}. Dispatched head checks do not satisfy PR branch rules; the optional automation App starts eligible native PR runs." done <<< "${parked_runs}" + # A daily release can advance the base AFTER publication. Keep this + # same daily run alive rather than adding push triggers. App tokens + # expire after one hour, so their monitor stops within forty minutes. + # Concurrency serializes runs of this kind; it is not a daily quota. + last_dispatched="${head_sha}" + update_requested="" + maintenance_deadline=$((SECONDS + ${MAINTENANCE_SECONDS:-7200})) + if [[ -n "${APP_DEADLINE:-}" ]]; then + remaining_auth_seconds=$((APP_DEADLINE - $(date +%s))) + (( remaining_auth_seconds > 0 )) || remaining_auth_seconds=0 + maintenance_deadline=$((SECONDS + remaining_auth_seconds)) + fi + base_ref="$(jq -nr --arg ref "${DEFAULT_BRANCH}" '$ref | @uri')" + max_attempts="${MAINTENANCE_ATTEMPTS:-120}" + for ((attempt=0; attempt 0 )) && [[ "${update_requested}" != "${head_sha}" ]]; then + number="$(jq -er '.number | select(type == "number")' <<< "${pr}")" + # GitHub merges the current protected base into this same-repo bot + # branch. expected_head_sha prevents racing another branch writer. + if gh api --method PUT "repos/${REPOSITORY}/pulls/${number}/update-branch" -f "expected_head_sha=${head_sha}" >/dev/null; then + update_requested="${head_sha}" + echo "::notice::Updating the behind bot branch; checks will be dispatched again when the new head appears." + else + echo "::notice::Bot branch update refused; retrying without bypassing protections." + fi + fi + sleep 60 + done + echo "::notice::Bot PR maintenance reached its configured bound; auto-merge remains enabled when allowed. The next scheduled run rebuilds from the current default branch. Unresolved conversations still require resolution." diff --git a/.github/workflows/pm-github-sync.yml b/.github/workflows/pm-github-sync.yml index 96de84ef..4d300589 100644 --- a/.github/workflows/pm-github-sync.yml +++ b/.github/workflows/pm-github-sync.yml @@ -44,16 +44,26 @@ on: required: false default: "changelog:full" ci-workflows: - description: "Whitespace-separated caller workflow filenames with workflow_dispatch; empty disables dispatch" + description: "Caller workflow filenames with workflow_dispatch; empty disables dispatch and auto-merge" type: string required: false - default: "ci.yml" + default: "ci.yml codeql.yml" + automation-app-client-id: + description: "Optional GitHub App client ID; pair with automation_app_private_key for eligible native PR checks" + type: string + required: false + default: "" node-version: description: "Node.js version for the pm CLI" type: string required: false default: "22.18.0" + secrets: + automation_app_private_key: + description: "Private key for the optional automation App installed on the calling repository" + required: false + concurrency: group: pm-github-sync-${{ inputs.repository }} cancel-in-progress: false @@ -362,9 +372,49 @@ jobs: - name: Verify strict pm health run: pm health --strict-exit + # Mint only after caller scripts and local gates have finished. The key + # is passed only to the pinned official action; its token is repo-scoped. + - name: Create automation app token + id: automation_token + if: inputs.automation-app-client-id != '' + uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 + with: + client-id: ${{ inputs.automation-app-client-id }} + private-key: ${{ secrets.automation_app_private_key }} + repositories: ${{ github.repository }} + skip-token-revoke: false + permission-contents: write + permission-pull-requests: write + permission-actions: write + permission-checks: read + permission-statuses: read + + - name: Validate publication credentials + id: publication_auth + env: + APP_CLIENT_ID: ${{ inputs.automation-app-client-id }} + HAS_APP_PRIVATE_KEY: ${{ secrets.automation_app_private_key != '' }} + HAS_AUTOMATION_TOKEN: ${{ steps.automation_token.outputs.token != '' }} + shell: bash + run: | + set -euo pipefail + if [[ -z "${APP_CLIENT_ID:-}" ]]; then + if [[ "${HAS_APP_PRIVATE_KEY:-false}" == true ]]; then + echo "::error::automation_app_private_key requires automation-app-client-id." + exit 1 + fi + echo "::notice::Using GITHUB_TOKEN: native PR runs require approval, and dispatched checks cannot satisfy PR branch rules. Configure the optional automation App for unattended landing." + elif [[ "${HAS_APP_PRIVATE_KEY:-false}" != true || "${HAS_AUTOMATION_TOKEN:-false}" != true ]]; then + echo "::error::Configured automation App did not produce a token; check its private key, installation and repository permissions." + exit 1 + else + # Start the App deadline immediately after minting, before publication. + printf 'deadline=%s\n' "$(( $(date +%s) + 2400 ))" >> "${GITHUB_OUTPUT}" + fi + - name: Commit gated sync changes and open review PR env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.automation_token.outputs.token || github.token }} shell: bash run: | set -euo pipefail @@ -445,17 +495,32 @@ jobs: else gh pr edit "${pr_number}" -R "${REPOSITORY}" --body-file "${body_file}" fi + pr_number="$(own_open_pr)" + [[ "${pr_number}" =~ ^[0-9]+$ ]] || { echo "::error::Cannot resolve the owned automation PR number."; exit 1; } + export SYNC_PR_NUMBER="${pr_number}" + printf 'SYNC_PR_NUMBER=%s\n' "${pr_number}" >> "${GITHUB_ENV}" export SYNC_PUBLISHED=true printf 'SYNC_PUBLISHED=true\n' >> "${GITHUB_ENV}" - name: Dispatch caller CI and report parked runs if: env.SYNC_PUBLISHED == 'true' env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.automation_token.outputs.token || github.token }} + MAINTENANCE_ATTEMPTS: ${{ steps.automation_token.outputs.token != '' && '40' || '120' }} + MAINTENANCE_SECONDS: ${{ steps.automation_token.outputs.token != '' && '2400' || '7200' }} + APP_DEADLINE: ${{ steps.publication_auth.outputs.deadline }} shell: bash run: | - set -euo pipefail + set -Eeuo pipefail + trap 'echo "::error::Caller check dispatch or PR maintenance failed; token requires actions:write, contents:write and pull-requests:write, and selected workflows must support workflow_dispatch. Inspect the bot PR state; no protection was bypassed."' ERR [[ "${SYNC_PUBLISHED:-false}" == true ]] || exit 0 + # Default inventory covers the fleet's CI and CodeQL names. An explicit + # list replaces it; empty disables dispatch AND automatic landing. + if [[ -z "${CI_WORKFLOWS}" ]]; then + echo "::notice::Caller CI dispatch and automatic landing are disabled by ci-workflows." + exit 0 + fi + workflows=() while IFS= read -r workflow_file; do [[ -n "${workflow_file}" ]] || continue [[ "${workflow_file}" =~ ^[a-zA-Z0-9_.-]+\.ya?ml$ ]] || { echo "::error::ci-workflows must contain workflow filenames."; exit 1; } @@ -463,11 +528,87 @@ jobs: echo "::notice::Skipping missing caller workflow: ${workflow_file}" continue fi - gh workflow run "${workflow_file}" -R "${REPOSITORY}" --ref "${SYNC_BRANCH}" + # Standard block and compact trigger forms; nested job/input keys + # cannot make a workflow dispatchable. Unknown forms fail closed. + if ! awk ' + /^on: *workflow_dispatch *(#.*)?$/ { found=1 } + /^on: *\[([^]]*, *)?workflow_dispatch *(,|\])/ { found=1 } + /^on: *($|#)/ { in_on=1; next } + /^[^[:space:]#]/ { in_on=0 } + in_on && /^ workflow_dispatch:/ { found=1 } + END { exit !found } + ' ".github/workflows/${workflow_file}"; then + echo "::warning::Skipping non-dispatchable caller workflow: ${workflow_file}. Add workflow_dispatch: under on: on the default branch for manual head validation. Eligible native PR checks must still pass." + continue + fi + mapfile -O "${#workflows[@]}" -t workflows < <(printf '%s\n' "${workflow_file}") done < <(printf '%s\n' "${CI_WORKFLOWS}" | tr ' \t\r' '\n') + if [[ ${#workflows[@]} == 0 ]]; then + echo "::error::No dispatchable caller workflow; automatic landing refused." + exit 1 + fi + # Dispatch every selected workflow before requesting protected auto-merge. + dispatch_checks() { + local workflow_file + for workflow_file in "${workflows[@]}"; do + gh workflow run "${workflow_file}" -R "${REPOSITORY}" --ref "${SYNC_BRANCH}" + done + } + # --auto respects required checks and conversation resolution. The SHA + # guard refuses a changed head; a disabled repository setting is soft. + enable_auto_merge() { + if ! gh pr merge "${SYNC_PR_NUMBER}" -R "${REPOSITORY}" --auto --squash --match-head-commit "${head_sha}"; then + echo "::notice::Squash auto-merge unavailable for the bot PR; repository settings or branch rules require attention. No protection was bypassed." + fi + } head_sha="$(git rev-parse HEAD)" + dispatch_checks + enable_auto_merge parked_runs="$(gh run list -R "${REPOSITORY}" --commit "${head_sha}" --status action_required --limit 100 --json url --jq '.[].url')" while IFS= read -r run_url; do [[ -n "${run_url}" ]] || continue - echo "::notice::A pull-request workflow requires maintainer approval: ${run_url}. Review this parked run if needed; caller CI dispatch runs are separate." + echo "::notice::A pull-request workflow requires maintainer approval: ${run_url}. Dispatched head checks do not satisfy PR branch rules; the optional automation App starts eligible native PR runs." done <<< "${parked_runs}" + # A daily release can advance the base AFTER publication. Keep this + # same daily run alive rather than adding push triggers. App tokens + # expire after one hour, so their monitor stops within forty minutes. + # Concurrency serializes runs of this kind; it is not a daily quota. + last_dispatched="${head_sha}" + update_requested="" + maintenance_deadline=$((SECONDS + ${MAINTENANCE_SECONDS:-7200})) + if [[ -n "${APP_DEADLINE:-}" ]]; then + remaining_auth_seconds=$((APP_DEADLINE - $(date +%s))) + (( remaining_auth_seconds > 0 )) || remaining_auth_seconds=0 + maintenance_deadline=$((SECONDS + remaining_auth_seconds)) + fi + base_ref="$(jq -nr --arg ref "${DEFAULT_BRANCH}" '$ref | @uri')" + max_attempts="${MAINTENANCE_ATTEMPTS:-120}" + for ((attempt=0; attempt 0 )) && [[ "${update_requested}" != "${head_sha}" ]]; then + number="$(jq -er '.number | select(type == "number")' <<< "${pr}")" + # GitHub merges the current protected base into this same-repo bot + # branch. expected_head_sha prevents racing another branch writer. + if gh api --method PUT "repos/${REPOSITORY}/pulls/${number}/update-branch" -f "expected_head_sha=${head_sha}" >/dev/null; then + update_requested="${head_sha}" + echo "::notice::Updating the behind bot branch; checks will be dispatched again when the new head appears." + else + echo "::notice::Bot branch update refused; retrying without bypassing protections." + fi + fi + sleep 60 + done + echo "::notice::Bot PR maintenance reached its configured bound; auto-merge remains enabled when allowed. The next scheduled run rebuilds from the current default branch. Unresolved conversations still require resolution." diff --git a/README.md b/README.md index b19f2caa..099bc3aa 100644 --- a/README.md +++ b/README.md @@ -478,7 +478,7 @@ The resolver uses public `git ls-remote --tags https://github.com/unbraind/pm-gi peeled `^{}` commit (never the tag object), strips `v`, and requires an exact numeric version `N.N.N` or `N.N.N-N`. It reads all matching refs in one request, without API pagination or new credentials. Lookup errors and multiple release -versions on one commit fail closed. No GitHub App or release-time workflow +versions on one commit fail closed. Release version discovery needs no GitHub App or release-time workflow stamping is required; the release workflow keeps its existing token behavior. Pin **release commit SHAs**, with their matching tag in a same-line comment @@ -592,15 +592,45 @@ The script must emit the root `CHANGELOG.md` and remain inside the publication s | Validation | Strict PM health; explicit item/history scope committed together | | Branch and PR | Explicit force-with-lease against the observed bot ref; push only bot branch; owned PR lookup excludes forks | | No-op | Zero closes or no tracker diff creates no remote branch or PR; caller-only drift unpublished; stale owned PR closed | -| CI | Caller workflow dispatch after PR create/update; parked approval-required runs reported; no merge | - -`ci-workflows` defaults to `ci.yml`; use whitespace-separated filenames for every -required caller CI workflow. Each must support `workflow_dispatch` and produce -its required checks on that event. Missing files are skipped with a notice, -matching sync; empty disables dispatch. CI dispatch starts checks; it does not -certify that they passed. Review and required-check enforcement remain with the -caller's protected branch. A repository concurrency group serializes closeout -runs, and the explicit lease rejects competing writers. +| CI and landing | Dispatch caller checks after publication and branch refresh; request protected squash auto-merge; report parked approval-required runs | + +`ci-workflows` defaults to `ci.yml codeql.yml`, covering the fleet's CI and +CodeQL workflows without querying branch protection. An explicit list replaces +that inventory (use `ci.yaml` or `codeql.yaml` when appropriate). Missing files +emit a notice; existing files without a recognized `workflow_dispatch` trigger +emit a warning naming the one-line repair. Standard block triggers and compact +`on: workflow_dispatch` / `on: [pull_request, workflow_dispatch]` forms are +supported. Each dispatched workflow must emit its required context names on +that event. Zero dispatchable workflows fails; `""` deliberately disables both +dispatch and automatic landing. Dispatch errors fail the run. + +GitHub does not evaluate `workflow_dispatch` job checks for PR branch rules, +even when those checks pass on the head SHA. For unattended landing, configure +`automation-app-client-id` and the optional `automation_app_private_key` secret. +After the local gates, the pinned official App-token action mints a token for +only the caller repository, with contents/pull-requests/actions write and +checks/statuses read. Publication and refresh use that token, so native +`pull_request` workflows run without the GITHUB_TOKEN approval prompt and +provide eligible required checks. Manual head dispatch remains additional +verification. Empty credentials retain GITHUB_TOKEN and emit a setup notice; +partial or failed App credentials stop publication. The private key is passed +only to the token action, after caller scripts have completed. + +After dispatch the workflow requests `gh pr merge --auto --squash` with the +expected head SHA. A repository that disallows auto-merge emits a notice. +GitHub enforces required checks and conversation resolution. The same run +polls once per minute: when the PR is `BEHIND`, it requests a branch update +against the expected head, then dispatches all selected workflows and requests +auto-merge again when the new head appears. App mode stops within forty minutes, +inside its token's one-hour lifetime; legacy mode has a two-hour bound. The +existing daily schedules and separate sync/closeout concurrency groups remain. +A base change after the monitor window waits for the next daily rebuild. +Unresolved conversations continue to block landing. + +See [the caller audit and one-time setup](docs/bot-pr-automation.md) for the App +credential mapping, CodeQL trigger changes and explicit CI overrides. GitHub +documents [the token approval behavior](https://docs.github.com/en/actions/concepts/security/github_token) +and [why manual job checks do not satisfy PR branch rules](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks). The caller template uses top-level `permissions: {}` and grants its `gated-closeout` job only `contents: write`, `pull-requests: write`, `checks: read` @@ -643,7 +673,8 @@ Optional inputs: | --- | --- | --- | | `npm-project-dir` | `.` | Relative npm project directory for `npm ci --ignore-scripts`, the CLI `node_modules/.bin` PATH entry, and `post-import-script`. Must have `package.json`, contain no `..` segments, and resolve inside the workspace (including symlinks); invalid paths fail before caching/install. The tracker and publication scope stay at the repository root. | | `post-import-script` | `changelog:full` | Caller npm script name invoked with `npm run --if-present` after import and before the final scan. Override for a different package script, or set `""` to disable. Missing scripts are skipped. Raw shell commands are not accepted. Generated `CHANGELOG.md` is staged with the tracker. Changing any file outside the documented scope fails the run, whether staged, unstaged, or untracked. | -| `ci-workflows` | `ci.yml` | Whitespace-separated filenames in the caller's `.github/workflows`, for example `ci.yml codeql.yml`. Missing files emit a notice and are skipped; set `""` to disable dispatch. Existing workflows must enable `workflow_dispatch`; dispatch errors fail the sync job. | +| `automation-app-client-id` | `""` | Optional GitHub App client ID, paired with the `automation_app_private_key` workflow-call secret. Enables eligible native PR runs through a fresh repo-scoped token; absent credentials retain GITHUB_TOKEN with a notice. | +| `ci-workflows` | `ci.yml codeql.yml` | Explicit whitespace-separated filename override in the caller's `.github/workflows`. Missing/non-dispatchable workflows are reported; zero dispatchable workflows fails. Empty disables dispatch and auto-merge. See the CI and landing contract above. | A fleet repo owns the schedule and calls it with a pinned release SHA (see [`docs/sync-workflow-caller.yml`](docs/sync-workflow-caller.yml)): @@ -663,6 +694,10 @@ permissions: jobs: gated-sync: uses: unbraind/pm-github/.github/workflows/pm-github-sync.yml@RELEASE_COMMIT_SHA # vRELEASE_VERSION + with: + automation-app-client-id: ${{ vars.PM_GITHUB_APP_CLIENT_ID }} + secrets: + automation_app_private_key: ${{ secrets.PM_GITHUB_APP_PRIVATE_KEY }} ``` Replace `RELEASE_COMMIT_SHA` with a reviewed release commit containing this change and `vRELEASE_VERSION` with its matching tag. Configure [Dependabot](#self-versioned-workflows-and-dependabot) to maintain future pins automatically. The selected npm project needs a committed npm lockfile (`package-lock.json` or `npm-shrinkwrap.json`) and `@unbrained/pm-cli` as a devDependency (the workflow's `npm ci` provides the CLI) and its pm tracker at `.agents/pm` committed on the caller's default branch. Under **Settings → Actions → General → Workflow permissions** it must allow read and write token permissions and enable **Allow GitHub Actions to create and approve pull requests** (an organization can disable this), or the run pushes the sync branch and then fails to open the review PR. The caller must grant `actions: write`; a reusable workflow cannot elevate its caller's permissions. @@ -673,7 +708,16 @@ provides the CLI and post-import npm script; Git and pm tracker operations still run from the repository root. A script that regenerates the changelog must write the repository-root `CHANGELOG.md` to stay within the publication allowlist. -Bot-created review PRs may have missing required checks or `pull_request` runs parked in `action_required`. After a successful push and PR creation/update, the reusable workflow uses the job's `GITHUB_TOKEN` to run `gh workflow run --ref "$SYNC_BRANCH"` for each configured caller CI workflow. Explicit `workflow_dispatch` creates runs on the sync head, so callers must enable that trigger and ensure those runs produce their required check names (and do not restrict the required jobs to the `pull_request` event). It also lists `action_required` runs for the exact pushed SHA and prints their URLs as notices without failing because approval is needed. Missing workflows, disabled dispatch, or approval notices do not establish that required CI passed; inspect the dispatched checks. A no-change sync closes its stale own review PR and dispatches nothing. See GitHub's [GITHUB_TOKEN event rules](https://docs.github.com/en/actions/concepts/security/github_token) and [dispatch trigger and permission requirements](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event). +Bot-created PRs using GITHUB_TOKEN may have `pull_request` runs parked in +`action_required`. The optional App token makes publication and branch refresh +start native eligible PR workflows automatically. Configured manual workflows +are also dispatched on the bot head; these jobs are additional verification, +because GitHub excludes manual job checks from PR branch-rule evaluation. Each +manual workflow must support `workflow_dispatch` and produce its intended check +names on that event. Parked-run notices include their URLs. A no-change sync +closes its stale owned review PR and dispatches nothing. See GitHub's +[token event rules](https://docs.github.com/en/actions/concepts/security/github_token) +and [required-check eligibility](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks). ### Installed CLI timeout acceptance diff --git a/docs/bot-pr-automation.md b/docs/bot-pr-automation.md new file mode 100644 index 00000000..74963083 --- /dev/null +++ b/docs/bot-pr-automation.md @@ -0,0 +1,155 @@ +# Automated proposal landing + +Both reusable workflows dispatch `ci.yml codeql.yml` by default, filtered to +existing files declaring workflow_dispatch. Explicit `ci-workflows` replaces +that list. Both CI and CodeQL must produce the same required contexts when +manually dispatched as for a pull request. No branch-protection API access is +needed or assumed for selecting workflows. + +## Eligible native PR checks and one-time App setup + +GitHub excludes job checks triggered by workflow_dispatch from PR checks and +required branch-rule evaluation, even when they pass on the head SHA. This is +why REST check-runs can show green CI while `gh pr checks` omits it. Dispatching +CodeQL alone cannot fix unattended merging. The documented supported path is +publication with a GitHub App installation token, which starts eligible native +pull_request runs without the GITHUB_TOKEN approval prompt. + +Install an automation App on the selected callers with Contents, Pull requests +and Actions write, plus Checks and Commit statuses read. Set its client ID as +`PM_GITHUB_APP_CLIENT_ID` and private key as `PM_GITHUB_APP_PRIVATE_KEY` in each +caller's Actions variable/secret settings. Map them once in each reusable caller: + +```yaml + with: + automation-app-client-id: ${{ vars.PM_GITHUB_APP_CLIENT_ID }} + secrets: + automation_app_private_key: ${{ secrets.PM_GITHUB_APP_PRIVATE_KEY }} +``` + +Existing `with` fields stay in that mapping. This credential boundary makes the +one-time caller opt-in unavoidable: a reusable workflow cannot read its own +provider repository's private secrets while running in a caller. Empty inputs +retain GITHUB_TOKEN and emit a notice; partial credentials or failed token +creation stop before publication. Configuring the App is the step that enables +unattended eligible PR runs; manual check dispatch remains extra head validation. + +The official create-github-app-token action is pinned by immutable commit in +both workflows, and Dependabot maintains that pin. Its token is restricted to the current +caller and the listed permissions, and is automatically revoked at job end. +The private key is supplied only to that action after local gates and caller +scripts finish. App-enabled monitoring has forty polls and a forty-minute +absolute deadline recorded immediately after token creation, so publication +time also counts toward the budget. This stays inside the one-hour token lifetime. Legacy +GITHUB_TOKEN monitoring retains the two-hour bound and cannot guarantee landing +without approval. Required checks and conversations stay enforced by GitHub. + +Sources: [GitHub token event behavior](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow), +[required-check eligibility](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks), +and [official App-token action](https://github.com/actions/create-github-app-token). + +## Caller audit (2026-10-17) + +The following 24 callers all have `.github/workflows/codeql.yml` with a +pull_request trigger and no workflow_dispatch trigger: + +`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-slack`, `pm-slack-standup`, `pm-starter`, `pm-swarm`, `pm-todos`, `pm-ts-starter`, `pm-vcs`, `pm-web`. + +All 24 callers currently allow repository auto-merge and squash merging. + +Every listed caller needs this one-line addition under `on:` in codeql.yml: + +```yaml + workflow_dispatch: +``` + +All 24 closeout callers also explicitly set `ci-workflows: "ci.yml"`. Remove +that line to inherit the new default, or change its value to `"ci.yml codeql.yml"`. +Preserving explicit overrides makes this a one-time caller configuration change; +a reusable workflow cannot alter its caller's event triggers. No caller was +modified or dispatched during this audit. Missing-trigger warnings name the +workflow, but cannot satisfy its required checks. + +The required `codeql` context currently blocks pm-jev, pm-lint, pm-review and +pm-swarm. Other callers do not currently require CodeQL; enabling dispatch still +ensures their security analysis runs on automation heads. Additional required +jobs (including Windows acceptance) are in ci.yml and run on dispatch. + +Observed closeout PRs pm-ado#32, pm-jev#23, pm-lint#11 and pm-review#18 have +successful dispatched test (22)/test (26) checks on their head SHA while their +pull_request CI/CodeQL runs are action_required. None has auto-merge enabled. +The named sync PRs also have successful dispatched head checks; several have +base advances. The request names eleven PRs in total, all inspected read-only. Those REST results establish manual head execution; they do not satisfy PR +branch rules. Eligible native PR runs require the App setup described above. + +## Existing closeout evidence policy + +Current main also fails closed when branch-protection metadata cannot be read +and `required-checks` is empty. The audited closeout callers have no such input, +so adopting this release also needs the one-time newline-separated required +context declaration. This policy comes from PR #140 and is preserved here; +workflow selection is not proof of which checks branch protection requires. +The audit read protection with the operator credential, not GITHUB_TOKEN. + +| Caller | Required contexts at audit time | +| --- | --- | +| pm-ado | `test (22)`, `test (26)` | +| pm-beads | `test (22)`, `test (26)` | +| pm-brief | `audit-windows`, `test (22)`, `test (26)` | +| pm-changelog | `test (22)`, `test (26)` | +| pm-context | `test (22)`, `test (26)` | +| pm-csv | `test (22)`, `test (26)` | +| pm-gantt-chart | `test (26)`, `test (22.18.0)` | +| pm-graph | `test (22)`, `test (26)`, `windows-prepare-lifecycle` | +| pm-jev | `test (22)`, `test (26)`, `codeql` | +| pm-jira | `test (22)`, `test (26)` | +| pm-linear | `test (22)`, `test (26)` | +| pm-lint | `test (22)`, `test (26)`, `codeql` | +| pm-ops | `test (22)`, `test (26)` | +| pm-presets | `test (22)`, `test (26)`, `windows-prepare-lifecycle` | +| pm-review | `test (22)`, `test (26)`, `codeql` | +| pm-rl | `test (22)`, `test (26)` | +| pm-slack | `test (22)`, `test (26)` | +| pm-slack-standup | `test (26)`, `test (22.18.0)` | +| pm-starter | `test (22)`, `test (26)` | +| pm-swarm | `test (22)`, `test (26)`, `codeql` | +| pm-todos | `test (26)`, `test (22.18.0)` | +| pm-ts-starter | `test (22)`, `test (26)` | +| pm-vcs | `test (22)`, `test (26)`, `windows-acceptance-launcher (22)`, `windows-acceptance-launcher (26)` | +| pm-web | `test (22)`, `test (26)` | + +The declaration must be maintained when protection changes. Reusable workflow +code cannot safely infer unknown required context names from workflow filenames. + +## Freshness and protected merging + +The proposal is rebuilt on the default branch each daily run. After publication, +a bounded monitor handles a base advance (including the daily release) by +checking compare-API ancestry even when the merge label is BLOCKED or UNKNOWN, +requesting update-branch with expected_head_sha, then redispatching every +selected workflow for the new head. It requests squash auto-merge with a matching +head SHA; GitHub still enforces required checks and conversation resolution. +Disallowed auto-merge is a notice, failed check dispatch is an error. No bypass +or thread resolution is attempted. App mode stops within forty minutes and legacy mode within two hours. A base +change outside that window is handled by the next daily run, so permanent freshness is not claimed. + +The existing daily schedules and per-kind concurrency groups are retained. No +push trigger is added: concurrency permits one active run per kind, not one +run per day; manually dispatched runs remain explicit operator requests. +Historical import/changelog review findings are separately owned by PR #142. +The unresolved pm-ado#32 review additionally concerns October closeout delivery +being attributed to its old September package release; follow-up pm-github-lfcf +tracks that distinct caller changelog/release-policy finding. Successful checks +and enabled auto-merge do not resolve that conversation. + +## Regression evidence + +`test/bot-pr-workflow.test.ts` executes each workflow's actual maintenance shell +against a real local Git remote. It advances the base with a release commit, +performs a real branch merge, and verifies that both workflows are dispatched +again on the changed head. Receipt-only GitHub commands keep caller repositories +untouched. Cases also cover explicit overrides, no dispatchable workflow, +CodeQL without a dispatch trigger, dispatch-denial diagnostics, App credential +pairing, token scope/bindings, token-lifetime bounds, disallowed auto-merge and a blocked PR reaching +the monitor bound. Existing end-to-end import and closeout suites retain the +privacy, scope, ownership, lease and no-op boundaries. diff --git a/docs/closeout-workflow-caller.yml b/docs/closeout-workflow-caller.yml index 395ade8c..4f622ec1 100644 --- a/docs/closeout-workflow-caller.yml +++ b/docs/closeout-workflow-caller.yml @@ -3,6 +3,7 @@ # See README.md for the daily github-actions pm-toolchain group configuration. # Callers need no guard of their own: API default-branch resolution supports schedule # payloads without repository metadata; manual dispatch from another branch fails closed. +# Unattended landing needs the optional App client ID/key mapping below. # Configure required CI workflows to support workflow_dispatch and emit their usual checks. # Missing CI filenames are skipped with a notice, matching the reusable sync workflow. # Settings -> Actions -> General must allow Actions to create pull requests. @@ -21,10 +22,13 @@ jobs: actions: write uses: unbraind/pm-github/.github/workflows/pm-github-closeout.yml@RELEASE_COMMIT_SHA # vRELEASE_VERSION with: + automation-app-client-id: ${{ vars.PM_GITHUB_APP_CLIENT_ID }} npm-project-dir: "." # Use tools/oracle or another contained npm project when needed. post-closeout-script: "changelog:full" # Missing script skips; "" disables it. # One context per line; match your repository's required checks when metadata cannot be read. required-checks: | test (22) test (26) - ci-workflows: "ci.yml" # Whitespace-separated workflow filenames; "" disables dispatch. + ci-workflows: "ci.yml codeql.yml" # Whitespace-separated workflow filenames; "" disables dispatch and auto-merge. + secrets: + automation_app_private_key: ${{ secrets.PM_GITHUB_APP_PRIVATE_KEY }} diff --git a/docs/sync-workflow-caller.yml b/docs/sync-workflow-caller.yml index a73b7148..241bd44d 100644 --- a/docs/sync-workflow-caller.yml +++ b/docs/sync-workflow-caller.yml @@ -1,6 +1,7 @@ # Pin a reviewed release SHA and its matching tag comment; Dependabot maintains both. # The workflow resolves its exact package version from the release tag on that SHA. # See README.md for the daily github-actions pm-toolchain group configuration. +# Unattended landing needs the optional App client ID/key mapping below. # Each configured CI workflow must enable workflow_dispatch and produce its required # check names on that event. Missing files are skipped with a notice. # Parked action_required PR runs are reported with URLs; dispatch runs separately. @@ -29,7 +30,10 @@ jobs: gated-sync: uses: unbraind/pm-github/.github/workflows/pm-github-sync.yml@RELEASE_COMMIT_SHA # vRELEASE_VERSION with: + automation-app-client-id: ${{ vars.PM_GITHUB_APP_CLIENT_ID }} npm-project-dir: "." # For pm-rust, use: npm-project-dir: tests/oracle - # Defaults shown explicitly; use "" to disable either optional action. + # Defaults shown explicitly; use "" to disable an optional action; empty CI also disables auto-merge. post-import-script: "changelog:full" - ci-workflows: "ci.yml" # Whitespace-separated filenames, e.g. "ci.yml codeql.yml". + ci-workflows: "ci.yml codeql.yml" # Whitespace-separated filenames, e.g. "ci.yml codeql.yml". + secrets: + automation_app_private_key: ${{ secrets.PM_GITHUB_APP_PRIVATE_KEY }} diff --git a/test/bot-pr-workflow.test.ts b/test/bot-pr-workflow.test.ts new file mode 100644 index 00000000..57473226 --- /dev/null +++ b/test/bot-pr-workflow.test.ts @@ -0,0 +1,187 @@ +/** Exercise the exact reusable maintenance shell with real Git and receipt-only GitHub commands. */ +import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join, resolve } from "node:path"; +import test from "node:test"; + +const root = resolve(import.meta.dirname, ".."); + +/** Extract the final executable step, including every function used by production. */ +function maintenance(kind: string): string { + return stepShell(kind, "Dispatch caller CI and report parked runs"); +} + +/** Read one executable block without interpreting GitHub expression bindings. */ +function stepShell(kind: string, name: string): string { + const workflow = readFileSync(join(root, `.github/workflows/pm-github-${kind}.yml`), "utf8"); + return workflow.split(` - name: ${name}\n`)[1]!.split(" - name: ")[0]!.split(" run: |\n")[1]! + .split("\n").filter(line => line.startsWith(" ")).map(line => line.slice(10)).join("\n"); +} + +/** Model only the remote GitHub API; branch update performs a real merge against a real remote. */ +function fixture(run: (f: { dir: string; env: NodeJS.ProcessEnv; receipts: () => string; execute: (kind: string) => ReturnType }) => void): void { + const dir = mkdtempSync(join(tmpdir(), "bot-pr-")); + const bin = join(dir, "bin"); + const env: NodeJS.ProcessEnv & { RECEIPTS: string } = { ...process.env, GIT_CONFIG_GLOBAL: "/dev/null", GIT_CONFIG_NOSYSTEM: "1", + GIT_AUTHOR_NAME: "Fixture", GIT_COMMITTER_NAME: "Fixture", GIT_AUTHOR_EMAIL: "fixture@users.noreply.github.com", GIT_COMMITTER_EMAIL: "fixture@users.noreply.github.com", + REPOSITORY: "acme/widgets", DEFAULT_BRANCH: "trunk", SYNC_BRANCH: "automation/proposal", SYNC_PUBLISHED: "true", SYNC_PR_NUMBER: "7", CI_WORKFLOWS: "ci.yml codeql.yml", + RECEIPTS: join(dir, "receipts"), STATE: join(dir, "state"), PATH: bin + ":" + process.env.PATH }; + const git = (...args: string[]) => { + const r = spawnSync("git", args, { cwd: dir, env, encoding: "utf8" }); + assert.equal(r.status, 0, r.stderr); return r.stdout.trim(); + }; + try { + mkdirSync(bin); mkdirSync(join(dir, ".github/workflows"), { recursive: true }); + for (const name of ["ci", "codeql"]) writeFileSync(join(dir, `.github/workflows/${name}.yml`), "on:\n pull_request:\n workflow_dispatch:\n"); + git("init", "-q", "-b", "trunk"); git("add", ".github"); git("commit", "-qm", "Caller base"); + git("init", "--bare", "-q", join(dir, "remote.git")); git("remote", "add", "origin", join(dir, "remote.git")); git("push", "-q", "origin", "trunk"); + git("switch", "-qc", "automation/proposal"); git("commit", "--allow-empty", "-qm", "Proposal"); + let releaseCreated = false; + writeFileSync(join(bin, "gh"), `#!/usr/bin/env bash +set -euo pipefail +printf '%s HEAD=%s\\n' "$*" "$(git rev-parse HEAD)" >> "$RECEIPTS" +case "$1 $2" in + 'workflow run') exit "\${DISPATCH_DENIED:-0}" ;; + 'pr merge') exit "\${AUTO_DENIED:-0}" ;; + 'run list') ;; + 'pr view') + if [[ "\${BEHIND:-false}" == true && ! -f "$STATE" ]]; then + printf '{"number":7,"state":"OPEN","headRefOid":"%s","mergeStateStatus":"%s"}' "$(git rev-parse HEAD)" "\${MERGE_STATE:-BEHIND}" + elif [[ "\${BEHIND:-false}" == true && ! -f "$STATE.done" ]]; then + touch "$STATE.done" + printf '{"number":7,"state":"OPEN","headRefOid":"%s","mergeStateStatus":"BLOCKED"}' "$(git rev-parse HEAD)" + elif [[ "\${BLOCKED:-false}" == true ]]; then + printf '{"number":7,"state":"OPEN","headRefOid":"%s","mergeStateStatus":"BLOCKED"}' "$(git rev-parse HEAD)" + else printf '{"state":"MERGED"}'; fi ;; + 'api repos/acme/widgets/compare/'*) git rev-list --count HEAD..origin/trunk ;; + 'api --method') + [[ "$*" == *"expected_head_sha=$(git rev-parse HEAD)"* ]] || exit 9 + git fetch -q origin trunk + git merge -q --no-edit origin/trunk + touch "$STATE" ;; + *) exit 8 ;; +esac +`, { mode: 0o755 }); + writeFileSync(join(bin, "date"), '#!/usr/bin/env bash\nprintf "%s\\n" "${FAKE_NOW:-1700000000}"\n', { mode: 0o755 }); + writeFileSync(join(bin, "sleep"), "#!/usr/bin/env bash\nexit 0\n", { mode: 0o755 }); + run({ dir, env, receipts: () => { try { return readFileSync(env.RECEIPTS, "utf8"); } catch { return ""; } }, + execute: kind => { + if (env.BEHIND === "true" && !releaseCreated) { + git("switch", "-q", "trunk"); writeFileSync(join(dir, "release.txt"), "Release advances base\n"); + git("add", "release.txt"); git("commit", "-qm", "Release"); git("push", "-q", "origin", "trunk"); git("switch", "-q", "automation/proposal"); + releaseCreated = true; + } + return spawnSync("bash", ["-c", maintenance(kind)], { cwd: dir, env, encoding: "utf8" }); + } }); + } finally { rmSync(dir, { recursive: true, force: true }); } +} + +for (const kind of ["sync", "closeout"]) { + test(`${kind}: default selects CI and CodeQL, respecting explicit overrides`, () => fixture(f => { + const source = readFileSync(join(root, `.github/workflows/pm-github-${kind}.yml`), "utf8"); + assert.match(source, /default: "ci.yml codeql.yml"/); + f.env.CI_WORKFLOWS = "ci.yml"; + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.match(f.receipts(), /workflow run ci.yml/); assert.doesNotMatch(f.receipts(), /workflow run codeql.yml/); + assert.match(f.receipts(), /pr merge 7 .*--auto --squash --match-head-commit [a-f0-9]{40}/); + assert.doesNotMatch(f.receipts(), /--admin|--force|resolve/); + })); + test(`${kind}: no dispatchable workflow refuses automatic landing`, () => fixture(f => { + for (const name of ["ci", "codeql"]) writeFileSync(join(f.dir, `.github/workflows/${name}.yml`), "on:\n pull_request:\nenv:\n workflow_dispatch: ignored\njobs:\n test:\n workflow_dispatch: ignored\n"); + const r = f.execute(kind); assert.equal(r.status, 1); assert.match(String(r.stdout), /No dispatchable caller workflow/); + assert.doesNotMatch(f.receipts(), /workflow run|pr merge/); + })); + test(`${kind}: CodeQL without dispatch reports the trigger repair and leaves required checks intact`, () => fixture(f => { + writeFileSync(join(f.dir, ".github/workflows/codeql.yml"), "on:\n pull_request:\n"); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.match(String(r.stdout), /codeql.yml. Add workflow_dispatch: under on:/); + assert.match(f.receipts(), /workflow run ci.yml/); assert.doesNotMatch(f.receipts(), /workflow run codeql.yml/); + })); + test(`${kind}: a daily release makes the proposal BEHIND, updates with a SHA lease and redispatches both workflows`, () => fixture(f => { + f.env.BEHIND = "true"; + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + const dispatches = f.receipts().split("\n").filter(line => line.startsWith("workflow run")); + assert.equal(dispatches.length, 4); assert.match(dispatches[0]!, /ci.yml/); assert.match(dispatches[1]!, /codeql.yml/); + const heads = dispatches.map(line => line.split("HEAD=")[1]); + assert.equal(heads[0], heads[1]); assert.equal(heads[2], heads[3]); assert.notEqual(heads[0], heads[2]); + assert.match(f.receipts(), /api --method PUT repos\/acme\/widgets\/pulls\/7\/update-branch -f expected_head_sha=/); + assert.equal(readFileSync(join(f.dir, "release.txt"), "utf8"), "Release advances base\n"); + })); + test(`${kind}: a blocked merge label cannot hide a base advance`, () => fixture(f => { + Object.assign(f.env, { BEHIND: "true", MERGE_STATE: "BLOCKED", MAINTENANCE_ATTEMPTS: "2" }); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.match(f.receipts(), /api repos\/acme\/widgets\/compare\/trunk\.\.\./); + assert.match(f.receipts(), /update-branch/); + assert.equal(f.receipts().split("\n").filter(line => line.startsWith("workflow run")).length, 4); + assert.equal(readFileSync(join(f.dir, "release.txt"), "utf8"), "Release advances base\n"); + })); + test(`${kind}: dispatch denial reports the token diagnostic before auto-merge`, () => fixture(f => { + f.env.DISPATCH_DENIED = "1"; + const r = f.execute(kind); assert.equal(r.status, 1, String(r.stderr)); + assert.match(String(r.stdout), /token requires actions:write/); + assert.doesNotMatch(f.receipts(), /pr merge|pr view/); + })); + test(`${kind}: disabled auto-merge is a notice, unresolved conversations stay blocked at the time bound`, () => fixture(f => { + f.env.AUTO_DENIED = "1"; f.env.BLOCKED = "true"; + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.match(String(r.stdout), /Squash auto-merge unavailable/); assert.match(String(r.stdout), /configured bound/); + assert.equal(f.receipts().split("\n").filter(line => line.startsWith("pr view")).length, 120); + assert.doesNotMatch(f.receipts(), /update-branch|--admin|resolve/); + })); +} + +test("sync and closeout execute identical PR maintenance", () => assert.equal(maintenance("sync"), maintenance("closeout"))); + +for (const kind of ["sync", "closeout"]) { + test(`${kind}: App publication uses a pinned repo-scoped token after gates and bounds its lifetime`, () => { + const source = readFileSync(join(root, `.github/workflows/pm-github-${kind}.yml`), "utf8"); + const mint = source.split(" - name: Create automation app token\n")[1]!.split(" - name: ")[0]!; + assert.match(mint, /uses: actions\/create-github-app-token@[a-f0-9]{40} # v[0-9]+\.[0-9]+\.[0-9]+/); + assert.match(mint, /if: inputs.automation-app-client-id != ''/); + assert.match(mint, /client-id: \$\{\{ inputs.automation-app-client-id \}\}/); + assert.match(mint, /private-key: \$\{\{ secrets.automation_app_private_key \}\}/); + assert.match(mint, /^ repositories: \$\{\{ github.repository \}\}$/m); + const grants = [...mint.matchAll(/^ permission-([a-z-]+): (read|write)$/gm)]; + const permissions = Object.fromEntries(grants.map(match => [match[1]!, match[2]!])); + assert.equal(grants.length, Object.keys(permissions).length); + assert.deepEqual(permissions, { contents: "write", "pull-requests": "write", actions: "write", checks: "read", statuses: "read" }); + assert.doesNotMatch(mint, /^ (owner|enterprise):/m); + assert.match(mint, /skip-token-revoke: false/); + assert.ok(source.indexOf("name: Verify strict pm health") < source.indexOf("name: Create automation app token")); + assert.ok(source.indexOf("name: Validate publication credentials") < source.indexOf("name: Commit gated")); + assert.equal(source.split("GH_TOKEN: ${{ steps.automation_token.outputs.token || github.token }}").length - 1, 2); + assert.match(source, /MAINTENANCE_ATTEMPTS: \$\{\{ steps.automation_token.outputs.token != '' && '40' \|\| '120' \}\}/); + assert.equal((source.match(/secrets\.automation_app_private_key/g) ?? []).length, 2); + assert.match(source, /APP_DEADLINE: \$\{\{ steps.publication_auth.outputs.deadline \}\}/); + assert.match(source, /MAINTENANCE_SECONDS: \$\{\{ steps.automation_token.outputs.token != '' && '2400' \|\| '7200' \}\}/); + assert.doesNotMatch(source, /--admin|gh pr review|resolveReviewThread|\/check-runs.*--method POST/); + }); + test(`${kind}: partial App credentials fail closed and legacy mode reports check ineligibility`, () => fixture(f => { + for (const [clientId, key, token, status] of [["", "false", "false", 0], ["", "true", "false", 1], + ["Iv1.fixture", "false", "false", 1], ["Iv1.fixture", "true", "false", 1], ["Iv1.fixture", "true", "true", 0]] as const) { + const r = spawnSync("bash", ["-c", stepShell(kind, "Validate publication credentials")], { + env: { ...f.env, GITHUB_OUTPUT: join(f.dir, "auth-output"), APP_CLIENT_ID: clientId, HAS_APP_PRIVATE_KEY: key, HAS_AUTOMATION_TOKEN: token }, encoding: "utf8", + }); + assert.equal(r.status, status, r.stderr + r.stdout); + if (!clientId && status === 0) assert.match(r.stdout, /dispatched checks cannot satisfy PR branch rules/); + if (clientId && status === 0) { + assert.doesNotMatch(r.stdout, /Using GITHUB_TOKEN/); + assert.equal(readFileSync(join(f.dir, "auth-output"), "utf8"), "deadline=1700002400\n"); + } + } + })); + test(`${kind}: App maintenance ends at its configured poll bound`, () => fixture(f => { + Object.assign(f.env, { MAINTENANCE_ATTEMPTS: "1", MAINTENANCE_SECONDS: "2400", BLOCKED: "true" }); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.equal(f.receipts().split("\n").filter(line => line.startsWith("pr view")).length, 1); + assert.match(String(r.stdout), /configured bound/); + })); + test(`${kind}: the elapsed-time deadline also ends maintenance before token expiry`, () => fixture(f => { + Object.assign(f.env, { MAINTENANCE_ATTEMPTS: "40", MAINTENANCE_SECONDS: "2400", APP_DEADLINE: "1700002400", FAKE_NOW: "1700002500", BLOCKED: "true" }); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr)); + assert.doesNotMatch(f.receipts(), /pr view/); + assert.match(String(r.stdout), /configured bound/); + })); +} diff --git a/test/closeout-workflow.test.ts b/test/closeout-workflow.test.ts index d52a41bc..b086ac92 100644 --- a/test/closeout-workflow.test.ts +++ b/test/closeout-workflow.test.ts @@ -129,6 +129,8 @@ case "$1 $2" in if [[ "$1" == --body-file ]]; then cp "$2" "$PR_BODY"; break; fi shift done ;; + "pr merge") [[ "\${AUTO_MERGE_DENIED:-false}" != true ]] || exit 1 ;; + "pr view") printf '{"state":"MERGED"}\\n' ;; "pr close") rm -f "$PR_STATE" ;; "workflow run") [[ "\${DISPATCH_DENIED:-false}" != true ]] || exit 1 ;; "run list") ;; @@ -181,7 +183,7 @@ ${shell(name, source)} const setup = ["Require caller default branch", "Validate closeout inputs", "Validate npm project directory", "Prepare sync branch from default branch", "Install dependencies", "Resolve sync commit scope", "Install pinned pm-github extension", "Configure PM merge drivers", "Verify gate is available"]; const finish = ["Close delivered tracker items", "Run caller post-closeout script", "Gate tracker and regenerated changelog", "Verify strict pm health", - "Commit gated closeout changes and open review PR", "Dispatch caller CI and report parked runs"]; + "Validate publication credentials", "Commit gated closeout changes and open review PR", "Dispatch caller CI and report parked runs"]; /** No remote bot ref is the publication invariant for every refused or no-op run. */ function unpublished(git: (...args: string[]) => string): void { diff --git a/test/import-gate.test.ts b/test/import-gate.test.ts index 6750bcd6..958a77e1 100644 --- a/test/import-gate.test.ts +++ b/test/import-gate.test.ts @@ -41,7 +41,8 @@ const MANIFEST_CAPABILITIES = ["commands", "importers", "schema", "hooks", "pref const harnessPromise: Promise = createExtensionTestHarness(extension, { capabilities: [...MANIFEST_CAPABILITIES] }); -const PM_BIN = process.platform === "win32" ? "pm.cmd" : "pm"; +// Match npm and CI even when this file is invoked directly beside a newer global host. +const PM_BIN = path.resolve(import.meta.dirname, "../node_modules/.bin", process.platform === "win32" ? "pm.cmd" : "pm"); // Real scratch trackers must not inherit unrelated globally installed extensions. const fixtureGlobalRoot = fs.mkdtempSync(path.join(os.tmpdir(), "pm-github-gate-global-")); test.after(() => fs.rmSync(fixtureGlobalRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 })); @@ -593,7 +594,7 @@ test("the reusable sync workflow is a workflow_call with an optional legacy vers assert.match(workflow, /pm-github-version:\n\s+description:[^\n]+\n\s+type: string\n\s+required: false/); assert.match(workflow, /repository:\n\s+description:/); assert.match(workflow, /post-import-script:[\s\S]*?default: "changelog:full"/); - assert.match(workflow, /ci-workflows:[\s\S]*?default: "ci.yml"/); + assert.match(workflow, /ci-workflows:[\s\S]*?default: "ci.yml codeql.yml"/); assert.doesNotMatch(workflow, /^on:\n schedule:/m, "the schedule stays with the caller"); // Job permissions cover issue reads, branch pushes, review PR writes and dispatch. const permissions = /^ permissions:\n contents: write\n pull-requests: write\n issues: read\n actions: write\n/m; @@ -614,6 +615,7 @@ test("the caller default branch guard is first and preserves the remaining step "Revalidate GitHub blockers (report only)", "Preview GitHub to pm plan", "Gated GitHub to pm import", "Verify repeat import is a no-op", "Run caller post-import script", "Gate tracker and regenerated changelog", "Verify strict pm health", + "Create automation app token", "Validate publication credentials", "Commit gated sync changes and open review PR", "Dispatch caller CI and report parked runs", ]); assert.match(steps[0]!, /RUN_REF: \$\{\{ github.ref \}\}/); @@ -811,7 +813,13 @@ async function prepareWorkflowFixture(root: string, base: string): Promise> "\${REVIEW_ACTIONS}.pr-args" entries="" + if [[ -z "\${OWN_OPEN_PR:-}" && -s "\${REVIEW_RECEIPT}" ]]; then OWN_OPEN_PR=1; fi if [[ -n "\${OWN_OPEN_PR:-}" ]]; then entries+="{\\"number\\":\${OWN_OPEN_PR},\\"headRepository\\":{\\"name\\":\\"\${REPOSITORY#*/}\\"},\\"headRepositoryOwner\\":{\\"login\\":\\"\${REPOSITORY%%/*}\\"},\\"isCrossRepository\\":false}," fi @@ -847,6 +856,8 @@ case "$1 $2" in done printf 'https://example.invalid/review/1\\n' ;; + "pr merge") exit "\${AUTO_MERGE_STATUS:-0}" ;; + "pr view") printf '{"state":"MERGED"}\\n' ;; "pr close") printf 'close\\n' >> "\${REVIEW_ACTIONS}" while [[ $# -gt 0 ]]; do @@ -871,7 +882,7 @@ esac GH_TOKEN: "synthetic-test-token", GITHUB_TOKEN: "synthetic-test-token", PM_AUTHOR: "codex-sol", PM_GLOBAL_PATH: fixtureGlobalRoot, PM_TELEMETRY_INLINE_FLUSH: "1", PM_PATH: path.join(root, ".agents", "pm"), REPOSITORY: "acme/widgets", CALLING_REPOSITORY: "acme/widgets", NPM_PROJECT_PATH: root, GITHUB_WORKSPACE: root, - POST_IMPORT_SCRIPT: "changelog:full", CI_WORKFLOWS: "ci.yml", + POST_IMPORT_SCRIPT: "changelog:full", CI_WORKFLOWS: "ci.yml", SYNC_PR_NUMBER: "1", PM_GITHUB_VERSION: "2026.10.4", DEFAULT_BRANCH: "main", SYNC_BRANCH, SYNC_LEASE: "", RUNNER_TEMP: base, GITHUB_ENV: path.join(base, "job-env"), REVIEW_RECEIPT: path.join(base, "review.md"), REVIEW_ACTIONS: path.join(base, "review-actions") }; const packageRoot = path.resolve(import.meta.dirname, ".."); @@ -888,7 +899,7 @@ esac const WORKFLOW_IMPORT_SEQUENCE = ["Resolve sync commit scope", "Validate GitHub access", "Revalidate GitHub blockers (report only)", "Preview GitHub to pm plan", "Gated GitHub to pm import", "Verify repeat import is a no-op", "Run caller post-import script", "Gate tracker and regenerated changelog", - "Verify strict pm health", "Commit gated sync changes and open review PR", "Dispatch caller CI and report parked runs"] as const; + "Verify strict pm health", "Validate publication credentials", "Commit gated sync changes and open review PR", "Dispatch caller CI and report parked runs"] as const; test("workflow packing isolates prepare from the caller tracker in clones and linked worktrees", async () => { const { root, base } = initSyncRepo(); @@ -1069,10 +1080,10 @@ test("the caller default branch trunk flows from schedule guard through real Git assert.equal(result.code, 0, result.stdout + result.stderr); assert.deepEqual(remoteRefs(bare), ["refs/heads/" + SYNC_BRANCH, "refs/heads/trunk"].sort()); const prArgs = fs.readFileSync(env.REVIEW_ACTIONS! + ".pr-args", "utf8").trim().split("\n"); - assert.equal(prArgs.length, 2); for (const args of prArgs) assert.match(args, /--base trunk(?: |$)/); assert.match(prArgs[0]!, /^pr list /); - assert.match(prArgs[1]!, /^pr create /); + assert.equal(prArgs.filter(args => /^pr create /.test(args)).length, 1, "create only one proposal"); + assert.match(prArgs.at(-1)!, /^pr list /, "retain the verified owned PR number after publication"); const body = fs.readFileSync(env.REVIEW_RECEIPT!, "utf8"); assert.match(body, /https:\/\/github\.com\/acme\/widgets\/blob\/trunk\/\.agents\/pm\/issues\/[^)]+\.toon/); assert.ok(body.includes("`trunk` is never pushed directly.")); From ea77a5a03e841aeedf1faaf756569d50c44990e8 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 06:21:51 +0200 Subject: [PATCH 2/9] Run isolated npm and Bun release validation --- .agents/pm/chores/pm-github-julo.toon | 5 ++- .agents/pm/history/pm-github-8r7c.jsonl | 2 + .agents/pm/history/pm-github-julo.jsonl | 1 + .agents/pm/issues/pm-github-8r7c.toon | 6 ++- .../workflows/round-release-validation.yml | 39 +++++++++++++++++++ 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/round-release-validation.yml diff --git a/.agents/pm/chores/pm-github-julo.toon b/.agents/pm/chores/pm-github-julo.toon index 59ddf9d4..ac87803d 100644 --- a/.agents/pm/chores/pm-github-julo.toon +++ b/.agents/pm/chores/pm-github-julo.toon @@ -6,11 +6,11 @@ status: in_progress priority: 2 tags[4]: cli,dependencies,release-readiness,sdk created_at: "2026-10-04T10:20:50.548Z" -updated_at: "2026-10-04T11:51:32.498Z" +updated_at: "2026-10-18T04:13:47.598Z" author: pi-glm acceptance_criteria: "npm run release:check passes (privacy, docstring, coverage gates intact); pm health with the repo-pinned 2026.10.4 binary is clean; packed tarball exercises validate/import/export-preview/sync-preview against a real repo read-only via npx @unbrained/pm-cli@2026.10.4 and bunx with zero GitHub mutation" actual_result: "Exact CLI/ops/changelog 2026.10.4 and development pins; canonical launcher unchanged; isolated lookup-loop suite 8/8. Clean npm ci and serialized release:check PASS 309/309, zero skips, unchanged coverage and privacy gate passed; both audit scopes 0, no open alerts. Packed own-tracker npx/bunx read-only commands pass (108 create + 1 update export preview, sync planned 1 / wouldSync 0 / skipped 1), no GitHub writes; scratch removed. Health exits 0 with stale_in_progress_items:2 advisory and no gate-failing findings, correcting the earlier zero-warning text. CodeRabbit and Greptile substantive reviews find no new actionable issues; other required reviews unavailable/pending. Leave item and PR open." -comments[7]{created_at,author,text}: +comments[8]{created_at,author,text}: "2026-10-04T10:21:00.651Z",pi-glm,"Starting at 2daff95 (Release pm-github v2026.10.04). Plan: pm-cli 2026.9.26->2026.10.4, pm-ops 2026.9.28->2026.10.4, @types/node ->26.6.4 in range, codeql-action SHA group 1c5b6756->2892aa5 from #104; recopy canonical prepare-merge-driver.ts from pm-ops 2026.10.4; full release gate + read-only dogfood (validate/import/export dry-run/sync dry-run) + previews." "2026-10-04T10:26:29.326Z",pi-glm,"Real-tracker dogfood PASS (read-only on GitHub). Packed pm-github-2026.10.4.tgz installed into a scratch copy of this repo's real .agents/pm and registered via pm package install with CLI 2026.10.4. npm path (npx -y @unbrained/pm-cli@2026.10.4): github validate --repo unbraind/pm-github -> ok (token via gh CLI, HTTP 200, quota 4813/5000); github import unbraind/pm-github -> no open issues found (truthful, both this repo and unbraind/pm-csv have zero open issues); github import unbraind/pm-cli -> Imported 26 new (real open issue data fetched read-only); re-import -> 0 new / 26 updated proving gh:owner/repo#N provenance idempotency; github export --dry-run -> create/update plan only, writes nothing; github sync --dry-run --repo unbraind/pm-csv -> planned 0. bun path (bunx @unbrained/pm-cli@2026.10.4): github validate -> ok; github import unbraind/pm-cli -> 0 new / 26 updated; export --dry-run and sync --dry-run identical. Zero GitHub mutation (reads + local scratch writes only); scratch deleted after evidence capture." "2026-10-04T10:27:47.809Z",pi-glm,"pm-github installed as managed project extension from npm at latest 2026.10.4 (self-extension registration; extensions are per-clone/gitignored). Read-only previews against unbraind/pm-github: github validate -> ok (HTTP 200, quota 4776/5000); github export --dry-run -> plan only, writes nothing; github sync --dry-run -> planned 1 / skipped 1, no mutation. No issues created/modified, no scheduled sync enabled." @@ -18,6 +18,7 @@ comments[7]{created_at,author,text}: "2026-10-04T11:19:04.632Z",codex-sol,"Also applied the verified cross-repo fixture findings: Node junction type for unconditional Windows-compatible lookup fixtures, and cleared ambient NODE_PATH in the normal prepare helper while preserving the explicit looping lookup. No launcher changes, no new skips. Clean npm ci now succeeds and both audit scopes are clean." "2026-10-04T11:30:44.957Z",codex-sol,"Resumption validation PASS: all devDependencies exact; CLI/ops/changelog 2026.10.4. Clean npm ci and flock-serialized npm run release:check passed 309/309, zero skips, unchanged configured coverage (2 measured sources), privacy 3052 Git objects clean, both audit scopes 0. Requested lookup-loop regression and hostile NODE_PATH fixture test pass 8/8, no skips; canonical launcher unchanged. Packed real own tracker npm/bun dogfood: npx -y @unbrained/pm-cli@2026.10.4 github validate --repo unbraind/pm-github; github import unbraind/pm-github --dry-run; github export --dry-run --repo unbraind/pm-github; github sync --dry-run --repo unbraind/pm-github; equivalent bunx @unbrained/pm-cli@2026.10.4 commands all pass. Export preview renders 108 creates + 1 update from 109 real items; sync planned 1, wouldSync 0, skipped 1; zero GitHub mutation. Scratch removed. Pinned npx pm health ok without warnings; managed pm-github 2026.10.4 own-repo sync preview returns planned 1 / wouldSync 0 / skipped 1. Review availability remains a separate gate." "2026-10-04T11:51:30.969Z",codex-sol,"Final health receipt correction: the complete pinned health receipt has stale_in_progress_items:2 advisory, not zero warnings as the earlier resumption text claimed. Health exits 0 with no gate-failing findings. Existing items remain open for their owners. Package code, 309/309 full gate result, clean audits, packed read-only real-tracker dogfood and substantive CodeRabbit/Greptile reviews are unchanged." + "2026-10-18T04:13:47.579Z",codex-agent,"Round 1 additional health evidence: repository-pinned host 2026.10.13 reports extension_host_pm_cli_version_skew against the installed extension SDK 2026.10.17 in both current worktrees. Item validation and history_drift pass. Queue policy leaves SDK dependency bumps to Dependabot; this remains certification follow-up rather than an import/workflow fix." files[5]: - path: .github/workflows/codeql.yml scope: project diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index 61e7c58b..da8d08a5 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -31,3 +31,5 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T04:06:44.203Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"files_add","patch":[{"op":"add","path":"/metadata/files/5","value":{"path":"test/self-versioned-workflows.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:06:44.203Z"}],"before_hash":"e97248bea1b2a207835fd29f77ee15a6ca2c110e05c3a643345da852e927a00f","after_hash":"83595824dc2b4773285398a6ed287f1da86db7ec32512b4f4f23551a76c8f21d","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":"4070b1a344030b1c803b219cf44ff00a73516840c50bea5195c9c4c971118bfb"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:06:49.015Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/16","value":{"created_at":"2026-10-18T04:06:49.014Z","author":"codex-agent","text":"Round 1 fixes: both detectors accept quoted on keys, one/four-space children, indented and indentless event sequences while rejecting nested input keys. Both auto-merge functions require the App deadline; GITHUB_TOKEN fallback still dispatches checks without arming a merge. README separates App-free version lookup from no release-time stamping. Revert proofs retain every new test: reverting only both detectors fails 16/16 trigger cases; reverting only both auto-merge guards fails 2/2 fallback cases; reverting only the README sentence fails 1/1 documentation contract. Restored fixes pass the focused 21/21 cases."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:06:49.015Z"}],"before_hash":"83595824dc2b4773285398a6ed287f1da86db7ec32512b4f4f23551a76c8f21d","after_hash":"c5f8417a2124f33b767dcf81c89af9fb2288cdd40c961a28e4c33de7ea51e784","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":"8f839e407663a01c0880ec934771594cce61b2974f6372374487f41023146ef2"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:06:53.435Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:06:53.435Z"}],"before_hash":"c5f8417a2124f33b767dcf81c89af9fb2288cdd40c961a28e4c33de7ea51e784","after_hash":"4b851e6317c94e8a4589cb76ecd3577fca40edb91df6f7173da843c7c9495a65","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":"460ea9d320a2d8047637d03487247bcde7d97b378dddbf1dfdb355241b4341fe"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:12:29.407Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/17","value":{"created_at":"2026-10-18T04:12:29.407Z","author":"codex-agent","text":"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:12:29.407Z"}],"before_hash":"4b851e6317c94e8a4589cb76ecd3577fca40edb91df6f7173da843c7c9495a65","after_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","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":"8ea5628e6d1eb9e95d7c7467ec093c2f8d3fe779b6e83bccf2698730091c8423"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:21:37.815Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/18","value":{"created_at":"2026-10-18T04:21:37.815Z","author":"codex-agent","text":"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:21:37.815Z"}],"before_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","after_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","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":"58df1e85607c044fe6ba5b1def59e432539bf811e736f6defcc3b94810692353"} diff --git a/.agents/pm/history/pm-github-julo.jsonl b/.agents/pm/history/pm-github-julo.jsonl index 3b52117d..5f52ec7d 100644 --- a/.agents/pm/history/pm-github-julo.jsonl +++ b/.agents/pm/history/pm-github-julo.jsonl @@ -27,3 +27,4 @@ {"hash_algorithm":"sha256","ts":"2026-10-04T11:51:30.969Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"59daee2cb1c27c169a02145c","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-04T11:51:30.969Z","author":"codex-sol","text":"Final health receipt correction: the complete pinned health receipt has stale_in_progress_items:2 advisory, not zero warnings as the earlier resumption text claimed. Health exits 0 with no gate-failing findings. Existing items remain open for their owners. Package code, 309/309 full gate result, clean audits, packed read-only real-tracker dogfood and substantive CodeRabbit/Greptile reviews are unchanged."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-04T11:51:30.969Z"}],"before_hash":"82417f91a5bd95f8a9ecb37f888b92cd08930f7152ef3f851c330ff4fb349c90","after_hash":"3bf3fb5518f01cf94173ba43b9201f200903e8f63bf9a48a613a4562b968e218","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":"646636e1f98f08774322b0015213dd2c7ea81dabc4b13ef73751b4b28a9aaa26"} {"hash_algorithm":"sha256","ts":"2026-10-04T11:51:31.689Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"59daee2cb1c27c169a02145c","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/actual_result","value":"Exact CLI/ops/changelog 2026.10.4 and development pins; canonical launcher unchanged; isolated lookup-loop suite 8/8. Clean npm ci and serialized release:check PASS 309/309, zero skips, unchanged coverage and privacy gate passed; both audit scopes 0, no open alerts. Packed own-tracker npx/bunx read-only commands pass (108 create + 1 update export preview, sync planned 1 / wouldSync 0 / skipped 1), no GitHub writes; scratch removed. Health exits 0 with stale_in_progress_items:2 advisory and no gate-failing findings, correcting the earlier zero-warning text. CodeRabbit and Greptile substantive reviews find no new actionable issues; other required reviews unavailable/pending. Leave item and PR open."},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-04T11:51:31.689Z"}],"before_hash":"3bf3fb5518f01cf94173ba43b9201f200903e8f63bf9a48a613a4562b968e218","after_hash":"9fad513c388f7f4de48cfd8b0bbf6cf958ce73149d21cf6cc1968f6d709bb671","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":"ef14000ff3460cc79a7296b7e111483c50e64c9d840fa7c99b0df44f61e61738"} {"hash_algorithm":"sha256","ts":"2026-10-04T11:51:32.498Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"59daee2cb1c27c169a02145c","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-04T11:51:32.498Z"}],"before_hash":"9fad513c388f7f4de48cfd8b0bbf6cf958ce73149d21cf6cc1968f6d709bb671","after_hash":"3b6f2979acbfab890a2691c15e6f264fa0e14bb1059bfc1ae4ede47a15f919de","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":"b0135ebdcae8b7ea856b424154082e5e7c266d9298b5b50a828b6f9de2e0e728"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:13:47.598Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:13:47.579Z","author":"codex-agent","text":"Round 1 additional health evidence: repository-pinned host 2026.10.13 reports extension_host_pm_cli_version_skew against the installed extension SDK 2026.10.17 in both current worktrees. Item validation and history_drift pass. Queue policy leaves SDK dependency bumps to Dependabot; this remains certification follow-up rather than an import/workflow fix."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:13:47.598Z"}],"before_hash":"3b6f2979acbfab890a2691c15e6f264fa0e14bb1059bfc1ae4ede47a15f919de","after_hash":"ba7986861d0dc0955470a01486fc9063ebdb1f935993dc46e8991574f8512110","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":"cb16607f000aa4c7ee8f1ae188314c27e8e3d5bb4521478ae6b8ab43eee143fd"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index 425351d4..4ed80847 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,10 +6,10 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T04:06:53.435Z" +updated_at: "2026-10-18T04:21:37.815Z" author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[17]{created_at,author,text}: +comments[19]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -27,6 +27,8 @@ comments[17]{created_at,author,text}: "2026-10-17T14:16:09.163Z",codex-agent,"Final local gates PASS with isolated CI identity (HOME scratch, global/system Git config disabled): npm run release:check and bun run release:check both exit 0, each 777/777 tests, zero failures/skips, all 13 authored modules at exact 100% statements/branches/functions/lines. Linked pm commands pass 23/23 maintenance plus 3/3 real-workflow positive fixtures. Revert receipts: original workflow implementations fail 22/23; ancestry-only, ERR-inheritance and App-pairing reverts each fail 2/2. Caller audit is read-only; all 24 setup requirements are documented, rollout tracked in pm-github-aiok, changelog-placement finding in pm-github-lfcf. No caller dispatch, merge or release performed; PR 142 remains separate." "2026-10-18T04:03:26.253Z",codex-agent,"Round 1: merge origin/main preserving import fidelity, address all five review threads with isolated revert proofs, then run both release gates under isolated CI identity. The review body has no outside-diff or nitpick findings. The merge driver attempted history re-anchoring; restored the existing PR history unchanged and replayed the main-branch rollout note through the pinned CLI instead." "2026-10-18T04:06:49.014Z",codex-agent,"Round 1 fixes: both detectors accept quoted on keys, one/four-space children, indented and indentless event sequences while rejecting nested input keys. Both auto-merge functions require the App deadline; GITHUB_TOKEN fallback still dispatches checks without arming a merge. README separates App-free version lookup from no release-time stamping. Revert proofs retain every new test: reverting only both detectors fails 16/16 trigger cases; reverting only both auto-merge guards fails 2/2 fallback cases; reverting only the README sentence fails 1/1 documentation contract. Restored fixes pass the focused 21/21 cases." + "2026-10-18T04:12:29.407Z",codex-agent,"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules." + "2026-10-18T04:21:37.815Z",codex-agent,"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project diff --git a/.github/workflows/round-release-validation.yml b/.github/workflows/round-release-validation.yml new file mode 100644 index 00000000..233e611d --- /dev/null +++ b/.github/workflows/round-release-validation.yml @@ -0,0 +1,39 @@ +name: Round release validation +on: + pull_request: + paths: + - .github/workflows/round-release-validation.yml + workflow_dispatch: +permissions: + contents: read +jobs: + release-gate: + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + host: [npm, bun] + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + fetch-depth: 0 + fetch-tags: true + - name: Setup Node.js + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: 26 + cache: npm + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: "1.3.14" + - name: Install dependencies + run: npm ci + - name: Release check with CI identity + shell: bash + env: + PACKAGE_HOST: ${{ matrix.host }} + run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 "$PACKAGE_HOST" run release:check From 498fd15aa927b325a4a87a314503b0d1943e187f Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 06:29:05 +0200 Subject: [PATCH 3/9] Use literal validation commands and preserve main tracker history --- .agents/pm/history/pm-github-8r7c.jsonl | 1 + .agents/pm/history/pm-github-aiok.jsonl | 6 +++--- .agents/pm/issues/pm-github-8r7c.toon | 5 +++-- .agents/pm/tasks/pm-github-aiok.toon | 6 +++--- .github/workflows/round-release-validation.yml | 11 +++++++---- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index da8d08a5..ec9e78b2 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -33,3 +33,4 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T04:06:53.435Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:06:53.435Z"}],"before_hash":"c5f8417a2124f33b767dcf81c89af9fb2288cdd40c961a28e4c33de7ea51e784","after_hash":"4b851e6317c94e8a4589cb76ecd3577fca40edb91df6f7173da843c7c9495a65","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":"460ea9d320a2d8047637d03487247bcde7d97b378dddbf1dfdb355241b4341fe"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:12:29.407Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/17","value":{"created_at":"2026-10-18T04:12:29.407Z","author":"codex-agent","text":"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:12:29.407Z"}],"before_hash":"4b851e6317c94e8a4589cb76ecd3577fca40edb91df6f7173da843c7c9495a65","after_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","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":"8ea5628e6d1eb9e95d7c7467ec093c2f8d3fe779b6e83bccf2698730091c8423"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:21:37.815Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/18","value":{"created_at":"2026-10-18T04:21:37.815Z","author":"codex-agent","text":"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:21:37.815Z"}],"before_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","after_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","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":"58df1e85607c044fe6ba5b1def59e432539bf811e736f6defcc3b94810692353"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:25:27.134Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/19","value":{"created_at":"2026-10-18T04:25:27.134Z","author":"codex-agent","text":"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:25:27.134Z"}],"before_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","after_hash":"cd746989aadfadd9c7b69163fb0715522488d27ddfbdcf6eed7ed2526f580c2d","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":"39198fc21a7e6d0dda3be0beabc3ad93443469287fab2e3c964d29dfe843a9d5"} diff --git a/.agents/pm/history/pm-github-aiok.jsonl b/.agents/pm/history/pm-github-aiok.jsonl index d08f75a9..52463a34 100644 --- a/.agents/pm/history/pm-github-aiok.jsonl +++ b/.agents/pm/history/pm-github-aiok.jsonl @@ -3,6 +3,6 @@ {"hash_algorithm":"sha256","ts":"2026-10-05T09:25:59.227Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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-05T09:25:59.227Z"},{"op":"add","path":"/metadata/files","value":[{"path":"docs/sync-workflow-caller.yml","scope":"project"}]}],"before_hash":"afd27b09ad086b7bc0339128cf19fecc80e654e03c3f8f44b06ee0d0ca5b9ae8","after_hash":"b5f06d9ff353748e0db7b1603a7082e45cc6d3931e045f83f39bfa9f4f38c13c","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":"b582f9f159f845f61c14bb7c6f626954807d6a764b5a15b48382001b8034ec0f"} {"hash_algorithm":"sha256","ts":"2026-10-05T09:26:00.035Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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/files/0/path","value":".github/workflows/pm-github-sync.yml"},{"op":"add","path":"/metadata/files/1","value":{"path":"docs/sync-workflow-caller.yml","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-05T09:26:00.035Z"}],"before_hash":"b5f06d9ff353748e0db7b1603a7082e45cc6d3931e045f83f39bfa9f4f38c13c","after_hash":"ace7fe3eed738ae79e924bb2dcd5d737884f92d56c645dd0bfd26feedbae41c0","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":"6bce5babc0899063bf4fadb1a8438d2f6d0e543952b1bc83240f32b20d96103d"} {"hash_algorithm":"sha256","ts":"2026-10-05T09:32:54.787Z","author":"codex-sol","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"0221c1e0bd861e4e03844581","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-05T09:32:54.787Z"},{"op":"add","path":"/metadata/dependencies","value":[{"id":"pm-github-f1at","kind":"related","created_at":"2026-10-05T09:32:54.728Z","author":"codex-sol","source_kind":"cli:update:dep","author_source":"detected"}]}],"before_hash":"ace7fe3eed738ae79e924bb2dcd5d737884f92d56c645dd0bfd26feedbae41c0","after_hash":"7c5c3f9c474ddf2c45bd4673bfc27442e51863889c3561690fe1400acc597e4a","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":"dbe2f513aac4d1acb373693cfdccf5517d680c1ffa049f1a9c29f2b7bc92e2a2"} -{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:16.179Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:58:16.179Z","author":"codex-agent","text":"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T10:58:16.179Z"}],"before_hash":"7c5c3f9c474ddf2c45bd4673bfc27442e51863889c3561690fe1400acc597e4a","after_hash":"96d5a54411a5b5324e69fc1049e9883754836b4c413b65beb62e12e8678d5f9c","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":"4167a192b1875176e986cc601c20252a091ea3dfd3b86184f0e66d27fe34a24c"} -{"hash_algorithm":"sha256","ts":"2026-10-17T10:58:24.790Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"e6c75eb6477900f1d6cb8502","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-17T10:58:24.790Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/bot-pr-automation.md","scope":"project"}]}],"before_hash":"96d5a54411a5b5324e69fc1049e9883754836b4c413b65beb62e12e8678d5f9c","after_hash":"53235e2f01e75d86f844a25e2e28a0d7ad95ee1f9ac9c7f8ca984c74181a499d","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":"7565a55a5b727fcbde5e91ad216bf3cc0ac5581a2c617109027989c2b1bf6430"} -{"hash_algorithm":"sha256","ts":"2026-10-18T04:03:19.282Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:03:19.282Z","author":"codex-agent","text":"Additional release-adoption dependency from pm-github-c093: the default-branch pm-github-sync callers in pm-beads, pm-brief, pm-context, pm-csv, pm-linear and pm-slack-standup all pin workflow SHA 67a5e3e1514fddeeae29951da00513f06f7aa0ab and pm-github-version 2026.10.16. Regeneration with the import-fidelity fix requires adoption of its reviewed release in both pins; the next scheduled sync using that release can then regenerate the existing sync PRs. Keep rollout as separately authorized work; the import-fidelity task does not change or dispatch consumer workflows."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:03:19.282Z"}],"before_hash":"53235e2f01e75d86f844a25e2e28a0d7ad95ee1f9ac9c7f8ca984c74181a499d","after_hash":"d7a75720c639e0f41c3cc25e7ed9dc64ac4ed6613e0e42e4802285b564e6c023","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":"e8efff195b6c114d0cd81839f989f35ba34c51f89d0a73f9543125882f46e79b"} +{"hash_algorithm":"sha256","ts":"2026-10-17T00:39:26.413Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3d7aa25e172d487bf4e14dde","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-17T00:39:26.413Z","author":"codex-agent","text":"Additional release-adoption dependency from pm-github-c093: the default-branch pm-github-sync callers in pm-beads, pm-brief, pm-context, pm-csv, pm-linear and pm-slack-standup all pin workflow SHA 67a5e3e1514fddeeae29951da00513f06f7aa0ab and pm-github-version 2026.10.16. Regeneration with the import-fidelity fix requires adoption of its reviewed release in both pins; the next scheduled sync using that release can then regenerate the existing sync PRs. Keep rollout as separately authorized work; the import-fidelity task does not change or dispatch consumer workflows."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-17T00:39:26.413Z"}],"before_hash":"7c5c3f9c474ddf2c45bd4673bfc27442e51863889c3561690fe1400acc597e4a","after_hash":"2289a391f07aa6dd799e43bad0fb93ff1752ad59c4abfd35e7ae4d3859913499","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":"9598a2a9ffde09a64f21c9f04f85bde4843dcf72c2bd1ebdb71b9903362be32f"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:25:11.088Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:25:11.088Z","author":"codex-agent","text":"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:25:11.088Z"}],"before_hash":"2289a391f07aa6dd799e43bad0fb93ff1752ad59c4abfd35e7ae4d3859913499","after_hash":"a1dead3e69bb02cb5e8bcf1b09885bc2fa578de091e3117b48decdc60d0e3ca9","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":"f1953b56e302b662969558eefbd38367259f2096ce958c7bfdac80fb157325be"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:25:18.737Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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-18T04:25:18.737Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"docs/bot-pr-automation.md","scope":"project"}]}],"before_hash":"a1dead3e69bb02cb5e8bcf1b09885bc2fa578de091e3117b48decdc60d0e3ca9","after_hash":"597c6808eda5bc3875a67ac11b0f118e70990fc89794092d27f1c2a5482027ae","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":"1ed9499a079ec2fdc1a006f7b3086e68fc64a3167568e85f14014b44335fab7b"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index 4ed80847..6d0afcef 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,10 +6,10 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T04:21:37.815Z" +updated_at: "2026-10-18T04:25:27.134Z" author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[19]{created_at,author,text}: +comments[20]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -29,6 +29,7 @@ comments[19]{created_at,author,text}: "2026-10-18T04:06:49.014Z",codex-agent,"Round 1 fixes: both detectors accept quoted on keys, one/four-space children, indented and indentless event sequences while rejecting nested input keys. Both auto-merge functions require the App deadline; GITHUB_TOKEN fallback still dispatches checks without arming a merge. README separates App-free version lookup from no release-time stamping. Revert proofs retain every new test: reverting only both detectors fails 16/16 trigger cases; reverting only both auto-merge guards fails 2/2 fallback cases; reverting only the README sentence fails 1/1 documentation contract. Restored fixes pass the focused 21/21 cases." "2026-10-18T04:12:29.407Z",codex-agent,"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules." "2026-10-18T04:21:37.815Z",codex-agent,"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change." + "2026-10-18T04:25:27.134Z",codex-agent,"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project diff --git a/.agents/pm/tasks/pm-github-aiok.toon b/.agents/pm/tasks/pm-github-aiok.toon index ba0883fe..a14e2f95 100644 --- a/.agents/pm/tasks/pm-github-aiok.toon +++ b/.agents/pm/tasks/pm-github-aiok.toon @@ -6,14 +6,14 @@ status: open priority: 1 tags: [] created_at: "2026-10-05T09:23:42.980Z" -updated_at: "2026-10-18T04:03:19.282Z" +updated_at: "2026-10-18T04:25:18.737Z" author: codex-sol dependencies[1]{id,kind,created_at,author,source_kind,author_source}: pm-github-f1at,related,"2026-10-05T09:32:54.728Z",codex-sol,"cli:update:dep",detected comments[3]{created_at,author,text}: "2026-10-05T09:25:31.280Z",codex-sol,"The caller example intentionally uses release commit and exact version placeholders. The currently published extension predates the gate, and this work is authorized only in the pm-github worktree. No pilot workflow in another repository was changed, enabled, or dispatched. Resolve the placeholders only after a reviewed release and separately authorized caller adoption." - "2026-10-17T10:58:16.179Z",codex-agent,"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them." - "2026-10-18T04:03:19.282Z",codex-agent,"Additional release-adoption dependency from pm-github-c093: the default-branch pm-github-sync callers in pm-beads, pm-brief, pm-context, pm-csv, pm-linear and pm-slack-standup all pin workflow SHA 67a5e3e1514fddeeae29951da00513f06f7aa0ab and pm-github-version 2026.10.16. Regeneration with the import-fidelity fix requires adoption of its reviewed release in both pins; the next scheduled sync using that release can then regenerate the existing sync PRs. Keep rollout as separately authorized work; the import-fidelity task does not change or dispatch consumer workflows." + "2026-10-17T00:39:26.413Z",codex-agent,"Additional release-adoption dependency from pm-github-c093: the default-branch pm-github-sync callers in pm-beads, pm-brief, pm-context, pm-csv, pm-linear and pm-slack-standup all pin workflow SHA 67a5e3e1514fddeeae29951da00513f06f7aa0ab and pm-github-version 2026.10.16. Regeneration with the import-fidelity fix requires adoption of its reviewed release in both pins; the next scheduled sync using that release can then regenerate the existing sync PRs. Keep rollout as separately authorized work; the import-fidelity task does not change or dispatch consumer workflows." + "2026-10-18T04:25:11.088Z",codex-agent,"Remaining rollout follow-up for pm-github-8r7c: GitHub excludes workflow_dispatch job checks from PR branch rules. After the reviewed provider release, authorize one-time caller App client-ID/private-key mapping for eligible native PR runs, add CodeQL workflow_dispatch for additional head verification, remove or expand explicit closeout ci.yml overrides, and declare required-checks per current protection policy. docs/bot-pr-automation.md lists all 24 callers and contexts. Preserve existing disabled pilot states until separately authorized; this task inspected callers read-only and did not change, enable or dispatch them." files[2]{path,scope}: .github/workflows/pm-github-sync.yml,project docs/sync-workflow-caller.yml,project diff --git a/.github/workflows/round-release-validation.yml b/.github/workflows/round-release-validation.yml index 233e611d..d8b9f891 100644 --- a/.github/workflows/round-release-validation.yml +++ b/.github/workflows/round-release-validation.yml @@ -32,8 +32,11 @@ jobs: bun-version: "1.3.14" - name: Install dependencies run: npm ci - - name: Release check with CI identity + - name: npm release check with CI identity + if: matrix.host == 'npm' shell: bash - env: - PACKAGE_HOST: ${{ matrix.host }} - run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 "$PACKAGE_HOST" run release:check + run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 npm run release:check + - name: Bun release check with CI identity + if: matrix.host == 'bun' + shell: bash + run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 bun run release:check From ca4c61bdb7361120a9c5c24f0dc56747af158ac3 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 06:45:40 +0200 Subject: [PATCH 4/9] Record round 1 gates and remove temporary validation --- .agents/pm/history/pm-github-8r7c.jsonl | 1 + .agents/pm/issues/pm-github-8r7c.toon | 5 ++- .../workflows/round-release-validation.yml | 42 ------------------- 3 files changed, 4 insertions(+), 44 deletions(-) delete mode 100644 .github/workflows/round-release-validation.yml diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index ec9e78b2..8c36a0e0 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -34,3 +34,4 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T04:12:29.407Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/17","value":{"created_at":"2026-10-18T04:12:29.407Z","author":"codex-agent","text":"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:12:29.407Z"}],"before_hash":"4b851e6317c94e8a4589cb76ecd3577fca40edb91df6f7173da843c7c9495a65","after_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","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":"8ea5628e6d1eb9e95d7c7467ec093c2f8d3fe779b6e83bccf2698730091c8423"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:21:37.815Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/18","value":{"created_at":"2026-10-18T04:21:37.815Z","author":"codex-agent","text":"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:21:37.815Z"}],"before_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","after_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","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":"58df1e85607c044fe6ba5b1def59e432539bf811e736f6defcc3b94810692353"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:25:27.134Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/19","value":{"created_at":"2026-10-18T04:25:27.134Z","author":"codex-agent","text":"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:25:27.134Z"}],"before_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","after_hash":"cd746989aadfadd9c7b69163fb0715522488d27ddfbdcf6eed7ed2526f580c2d","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":"39198fc21a7e6d0dda3be0beabc3ad93443469287fab2e3c964d29dfe843a9d5"} +{"hash_algorithm":"sha256","ts":"2026-10-18T04:45:15.168Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/20","value":{"created_at":"2026-10-18T04:45:15.168Z","author":"codex-agent","text":"Round 1 release gates PASS at 498fd15aa927b325a4a87a314503b0d1943e187f: npm run release:check and bun run release:check with isolated HOME and disabled global/system Git identity each pass 841/841, zero failures/skips/cancellations/todos, exact 100/100/100/100 coverage across all 14 authored modules. Receipts: https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199894 and https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199798 . Linked pm commands pass; detector/App-guard/README revert proofs remain 16/16, 2/2 and 1/1 failures respectively. All five review threads received post-push replies. Remove the temporary validation workflow; implementation and tests remain identical. The main-based rollout history verifies 8/8 with current-item hash equality. Local duplicate full runs were stopped; full gate receipts are from CI. Leave item in progress and unclaimed for orchestrator verification."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:45:15.168Z"}],"before_hash":"cd746989aadfadd9c7b69163fb0715522488d27ddfbdcf6eed7ed2526f580c2d","after_hash":"597ca2babd214664490a23a898043f77fc4a09ccf28b579161c7bdf632f80b90","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":"a7c036bddc979fcbf0eb3612b5e00620732e8ce85052fe20edbfd8484b91f6d3"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index 6d0afcef..adb1e37f 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,10 +6,10 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T04:25:27.134Z" +updated_at: "2026-10-18T04:45:15.168Z" author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[20]{created_at,author,text}: +comments[21]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -30,6 +30,7 @@ comments[20]{created_at,author,text}: "2026-10-18T04:12:29.407Z",codex-agent,"Merge verification: all existing PR history records remain byte-identical; the main-branch rollout note was appended through the pinned CLI. Discarded this operation’s generated merge-driver receipts after restoring authoritative item/history state; no reconcile or history repair ran. Additional strict health reports extension host version skew (pinned 2026.10.13 versus installed extension SDK 2026.10.17) and pre-existing stale items; history_drift is clean. Dependency pins remain unchanged per queue rules." "2026-10-18T04:21:37.815Z",codex-agent,"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change." "2026-10-18T04:25:27.134Z",codex-agent,"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved." + "2026-10-18T04:45:15.168Z",codex-agent,"Round 1 release gates PASS at 498fd15aa927b325a4a87a314503b0d1943e187f: npm run release:check and bun run release:check with isolated HOME and disabled global/system Git identity each pass 841/841, zero failures/skips/cancellations/todos, exact 100/100/100/100 coverage across all 14 authored modules. Receipts: https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199894 and https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199798 . Linked pm commands pass; detector/App-guard/README revert proofs remain 16/16, 2/2 and 1/1 failures respectively. All five review threads received post-push replies. Remove the temporary validation workflow; implementation and tests remain identical. The main-based rollout history verifies 8/8 with current-item hash equality. Local duplicate full runs were stopped; full gate receipts are from CI. Leave item in progress and unclaimed for orchestrator verification." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project diff --git a/.github/workflows/round-release-validation.yml b/.github/workflows/round-release-validation.yml deleted file mode 100644 index d8b9f891..00000000 --- a/.github/workflows/round-release-validation.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Round release validation -on: - pull_request: - paths: - - .github/workflows/round-release-validation.yml - workflow_dispatch: -permissions: - contents: read -jobs: - release-gate: - runs-on: ubuntu-latest - timeout-minutes: 30 - strategy: - fail-fast: false - matrix: - host: [npm, bun] - steps: - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - fetch-depth: 0 - fetch-tags: true - - name: Setup Node.js - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version: 26 - cache: npm - - name: Setup Bun - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - with: - bun-version: "1.3.14" - - name: Install dependencies - run: npm ci - - name: npm release check with CI identity - if: matrix.host == 'npm' - shell: bash - run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 npm run release:check - - name: Bun release check with CI identity - if: matrix.host == 'bun' - shell: bash - run: env HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 bun run release:check From d6ff66de07368e02f7a7d4642c1bd74cadcc4b2d Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 08:38:24 +0200 Subject: [PATCH 5/9] Retry transient bot PR monitor reads and document maintainer approval --- .agents/pm/history/pm-github-8r7c.jsonl | 3 ++ .agents/pm/issues/pm-github-8r7c.toon | 10 ++++-- .github/workflows/pm-github-closeout.yml | 12 +++++-- .github/workflows/pm-github-sync.yml | 12 +++++-- docs/bot-pr-automation.md | 43 ++++++++++++++++++++---- test/bot-pr-workflow.test.ts | 42 ++++++++++++++++++++++- 6 files changed, 107 insertions(+), 15 deletions(-) diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index 8c36a0e0..2e8b5963 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -35,3 +35,6 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T04:21:37.815Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/18","value":{"created_at":"2026-10-18T04:21:37.815Z","author":"codex-agent","text":"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:21:37.815Z"}],"before_hash":"e3fcaff7b806cefb818d723e0147ea09a4716cb0bf435c551e3d8c2adca1356a","after_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","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":"58df1e85607c044fe6ba5b1def59e432539bf811e736f6defcc3b94810692353"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:25:27.134Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/19","value":{"created_at":"2026-10-18T04:25:27.134Z","author":"codex-agent","text":"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:25:27.134Z"}],"before_hash":"a5aa25c6af6b7c1fbf0ea7f97c6d582dc97f7645448e518cb3922eb8b2aeefc0","after_hash":"cd746989aadfadd9c7b69163fb0715522488d27ddfbdcf6eed7ed2526f580c2d","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":"39198fc21a7e6d0dda3be0beabc3ad93443469287fab2e3c964d29dfe843a9d5"} {"hash_algorithm":"sha256","ts":"2026-10-18T04:45:15.168Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"62a55eab777c0a2218185c7a","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/20","value":{"created_at":"2026-10-18T04:45:15.168Z","author":"codex-agent","text":"Round 1 release gates PASS at 498fd15aa927b325a4a87a314503b0d1943e187f: npm run release:check and bun run release:check with isolated HOME and disabled global/system Git identity each pass 841/841, zero failures/skips/cancellations/todos, exact 100/100/100/100 coverage across all 14 authored modules. Receipts: https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199894 and https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199798 . Linked pm commands pass; detector/App-guard/README revert proofs remain 16/16, 2/2 and 1/1 failures respectively. All five review threads received post-push replies. Remove the temporary validation workflow; implementation and tests remain identical. The main-based rollout history verifies 8/8 with current-item hash equality. Local duplicate full runs were stopped; full gate receipts are from CI. Leave item in progress and unclaimed for orchestrator verification."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T04:45:15.168Z"}],"before_hash":"cd746989aadfadd9c7b69163fb0715522488d27ddfbdcf6eed7ed2526f580c2d","after_hash":"597ca2babd214664490a23a898043f77fc4a09ccf28b579161c7bdf632f80b90","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":"a7c036bddc979fcbf0eb3612b5e00620732e8ce85052fe20edbfd8484b91f6d3"} +{"hash_algorithm":"sha256","ts":"2026-10-18T06:35:15.751Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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-18T06:35:15.751Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"597ca2babd214664490a23a898043f77fc4a09ccf28b579161c7bdf632f80b90","after_hash":"e66027bd652c8335624951a7ebdefde1452f022af4597d90c347837d688ec271","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":"60bee5ead8b92fd9164ec6716b2513bb0430be68186806ae7eb10e3809a6f2a5"} +{"hash_algorithm":"sha256","ts":"2026-10-18T06:35:25.995Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/21","value":{"created_at":"2026-10-18T06:35:25.995Z","author":"codex-agent","text":"Round 2: verified both unresolved CodeRabbit findings on PR #146. Retry failed PR-state and ancestry reads within the existing monitor bounds; retain fail-closed validation of successful ancestry responses. Add real-shell regressions and behavioral revert proofs. Document the orchestrator-verified no-App action_required approval path. Main attestation compatibility merged before changes; no dependency bump. PR #148 has no CodeRabbit review yet."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:35:25.995Z"}],"before_hash":"e66027bd652c8335624951a7ebdefde1452f022af4597d90c347837d688ec271","after_hash":"330831dc95a71125246aace1836194502395081c36b6f233e82b635a9ad46076","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":"9882eb88df3be4787ee27220f240cfd4b4c1bbd4fa8e2a5b3c6b815302064185"} +{"hash_algorithm":"sha256","ts":"2026-10-18T06:36:42.344Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/3","value":{"command":"node --test --test-name-pattern=\"poll failure|poll errors|invalid data\" test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T06:36:41.942Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:36:42.344Z"}],"before_hash":"330831dc95a71125246aace1836194502395081c36b6f233e82b635a9ad46076","after_hash":"970df8274e3cef56705d893c4f7b5a58b3d8579755c918893d838a2ddc831a21","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":"b694f7b6dae753c27771f127106013d4f9767d97a3c3130b073725bba189741c"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index adb1e37f..f504946d 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,10 +6,12 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T04:45:15.168Z" +updated_at: "2026-10-18T06:36:42.344Z" +assignee: codex-agent +claim_principal: codex-agent author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[21]{created_at,author,text}: +comments[22]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -31,6 +33,7 @@ comments[21]{created_at,author,text}: "2026-10-18T04:21:37.815Z",codex-agent,"Local full gates remain running on a heavily loaded host. Add a temporary read-only GitHub validation workflow to execute the exact npm and Bun release:check commands with isolated HOME and Git identity on dedicated runners. Remove it before final delivery; no thresholds, assertions, protection rules or publication behavior change." "2026-10-18T04:25:27.134Z",codex-agent,"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved." "2026-10-18T04:45:15.168Z",codex-agent,"Round 1 release gates PASS at 498fd15aa927b325a4a87a314503b0d1943e187f: npm run release:check and bun run release:check with isolated HOME and disabled global/system Git identity each pass 841/841, zero failures/skips/cancellations/todos, exact 100/100/100/100 coverage across all 14 authored modules. Receipts: https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199894 and https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199798 . Linked pm commands pass; detector/App-guard/README revert proofs remain 16/16, 2/2 and 1/1 failures respectively. All five review threads received post-push replies. Remove the temporary validation workflow; implementation and tests remain identical. The main-based rollout history verifies 8/8 with current-item hash equality. Local duplicate full runs were stopped; full gate receipts are from CI. Leave item in progress and unclaimed for orchestrator verification." + "2026-10-18T06:35:25.995Z",codex-agent,"Round 2: verified both unresolved CodeRabbit findings on PR #146. Retry failed PR-state and ancestry reads within the existing monitor bounds; retain fail-closed validation of successful ancestry responses. Add real-shell regressions and behavioral revert proofs. Document the orchestrator-verified no-App action_required approval path. Main attestation compatibility merged before changes; no dependency bump. PR #148 has no CodeRabbit review yet." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project @@ -38,10 +41,11 @@ files[6]{path,scope}: test/closeout-workflow.test.ts,project test/import-gate.test.ts,project test/self-versioned-workflows.test.ts,project -tests[3]{command,scope,provenance{author,created_at,source_kind,source_ref}}: +tests[4]{command,scope,provenance{author,created_at,source_kind,source_ref}}: node --test test/bot-pr-workflow.test.ts,project,codex-agent,"2026-10-17T09:35:21.256Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current node --test --test-name-pattern='^(the caller default branch trunk flows from schedule guard through real Git preparation and review|the workflow never edits a fork PR sharing the sync branch name|npm-project-dir subdirectory CLI and SDK keep the tracker and publication at the repository root)$' test/import-gate.test.ts,project,codex-agent,"2026-10-17T13:38:31.648Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current node --test test/self-versioned-workflows.test.ts,project,codex-agent,"2026-10-18T04:06:14.124Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current + "node --test --test-name-pattern=\"poll failure|poll errors|invalid data\" test/bot-pr-workflow.test.ts",project,codex-agent,"2026-10-18T06:36:41.942Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current docs[1]{path,scope}: docs/bot-pr-automation.md,project body: "" diff --git a/.github/workflows/pm-github-closeout.yml b/.github/workflows/pm-github-closeout.yml index 7f14ed03..013dbea2 100644 --- a/.github/workflows/pm-github-closeout.yml +++ b/.github/workflows/pm-github-closeout.yml @@ -588,7 +588,11 @@ jobs: max_attempts="${MAINTENANCE_ATTEMPTS:-120}" for ((attempt=0; attempt 0 )) && [[ "${update_requested}" != "${head_sha}" ]]; then number="$(jq -er '.number | select(type == "number")' <<< "${pr}")" diff --git a/.github/workflows/pm-github-sync.yml b/.github/workflows/pm-github-sync.yml index d39549a6..8282f2b6 100644 --- a/.github/workflows/pm-github-sync.yml +++ b/.github/workflows/pm-github-sync.yml @@ -602,7 +602,11 @@ jobs: max_attempts="${MAINTENANCE_ATTEMPTS:-120}" for ((attempt=0; attempt 0 )) && [[ "${update_requested}" != "${head_sha}" ]]; then number="$(jq -er '.number | select(type == "number")' <<< "${pr}")" diff --git a/docs/bot-pr-automation.md b/docs/bot-pr-automation.md index 5ad724ed..f2058509 100644 --- a/docs/bot-pr-automation.md +++ b/docs/bot-pr-automation.md @@ -6,14 +6,40 @@ that list. Both CI and CodeQL must produce the same required contexts when manually dispatched as for a pull request. No branch-protection API access is needed or assumed for selecting workflows. -## Eligible native PR checks and one-time App setup +## Eligible native PR checks and optional App setup GitHub excludes job checks triggered by workflow_dispatch from PR checks and required branch-rule evaluation, even when they pass on the head SHA. This is why REST check-runs can show green CI while `gh pr checks` omits it. Dispatching -CodeQL alone cannot fix unattended merging. The documented supported path is -publication with a GitHub App installation token, which starts eligible native -pull_request runs without the GITHUB_TOKEN approval prompt. +CodeQL alone cannot fix unattended merging. Two supported paths are +maintainer approval of the parked native pull_request runs, or optional +publication with a GitHub App installation token to start those runs without +the GITHUB_TOKEN approval prompt. + +### No-App path: approve the native PR runs + +Leave the App inputs empty to keep GITHUB_TOKEN publication. After reviewing +the bot PR and its workflow changes, a maintainer can select **Approve workflows +to run** in the PR, or approve each parked native run with an operator credential: + +```sh +gh run list -R OWNER/REPO --commit HEAD_SHA --event pull_request \ + --status action_required --json databaseId,url +gh api --method POST repos/OWNER/REPO/actions/runs/RUN_ID/approve +``` + +Select each RUN_ID from that exact-head list and repeat the POST for each +approval-required run. The orchestrator verified that this endpoint unparks +bot-PR action_required runs without an App. GitHub documents write access for +the PR approval UI and Actions write permission for fine-grained tokens on the +[approval endpoint](https://docs.github.com/en/rest/actions/workflow-runs#approve-a-workflow-run-for-a-fork-pull-request). +Use the maintainer's authorized credential; this reusable workflow does not +approve itself. Wait for the native PR checks to pass and required conversations +to be resolved, then merge through the protected PR using the maintainer +credential. The fallback does not arm auto-merge. A new bot head may require +approval again. Manually dispatched checks remain extra head validation. + +### App path: unattended native PR runs Install an automation App on the selected callers with Contents, Pull requests and Actions write, plus Checks and Commit statuses read. Set its client ID as @@ -46,6 +72,7 @@ a maintainer must approve eligible runs and merge the protected PR. Required che Sources: [GitHub token event behavior](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow), [required-check eligibility](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/troubleshooting-required-status-checks), +[GITHUB_TOKEN PR approval behavior](https://docs.github.com/en/actions/concepts/security/github_token), and [official App-token action](https://github.com/actions/create-github-app-token). ## Caller audit (2026-10-17) @@ -80,7 +107,8 @@ successful dispatched test (22)/test (26) checks on their head SHA while their pull_request CI/CodeQL runs are action_required. None has auto-merge enabled. The named sync PRs also have successful dispatched head checks; several have base advances. The request names eleven PRs in total, all inspected read-only. Those REST results establish manual head execution; they do not satisfy PR -branch rules. Eligible native PR runs require the App setup described above. +branch rules. Eligible native PR runs can be unparked through the no-App approval path +above; App setup removes that approval step for unattended operation. ## Existing closeout evidence policy @@ -124,13 +152,14 @@ code cannot safely infer unknown required context names from workflow filenames. ## Freshness and protected merging The proposal is rebuilt on the default branch each daily run. After publication, -a bounded monitor handles a base advance (including the daily release) by +a bounded monitor retries failed PR-state and ancestry reads, and handles a base advance (including the daily release) by checking compare-API ancestry even when the merge label is BLOCKED or UNKNOWN, requesting update-branch with expected_head_sha, then redispatching every selected workflow for the new head. In App mode it requests squash auto-merge with a matching head SHA; GitHub still enforces required checks and conversation resolution. Disallowed auto-merge is a notice, failed check dispatch is an error. No bypass -or thread resolution is attempted. App mode stops within forty minutes and legacy mode within two hours. A base +or thread resolution is attempted. Successful ancestry responses must still contain a nonnegative integer; invalid +values fail closed. App mode stops within forty minutes and legacy mode within two hours. A base change outside that window is handled by the next daily run, so permanent freshness is not claimed. The existing daily schedules and per-kind concurrency groups are retained. No diff --git a/test/bot-pr-workflow.test.ts b/test/bot-pr-workflow.test.ts index a921e121..92be3212 100644 --- a/test/bot-pr-workflow.test.ts +++ b/test/bot-pr-workflow.test.ts @@ -47,6 +47,11 @@ case "$1 $2" in 'pr merge') exit "\${AUTO_DENIED:-0}" ;; 'run list') ;; 'pr view') + if [[ "\${PR_READ_FAILURE:-none}" != none ]]; then + if [[ "\${PR_READ_FAILURE}" == always || ! -f "$STATE.pr-read" ]]; then + touch "$STATE.pr-read"; exit 1 + fi + fi if [[ "\${BEHIND:-false}" == true && ! -f "$STATE" ]]; then printf '{"number":7,"state":"OPEN","headRefOid":"%s","mergeStateStatus":"%s"}' "$(git rev-parse HEAD)" "\${MERGE_STATE:-BEHIND}" elif [[ "\${BEHIND:-false}" == true && ! -f "$STATE.done" ]]; then @@ -55,7 +60,14 @@ case "$1 $2" in elif [[ "\${BLOCKED:-false}" == true ]]; then printf '{"number":7,"state":"OPEN","headRefOid":"%s","mergeStateStatus":"BLOCKED"}' "$(git rev-parse HEAD)" else printf '{"state":"MERGED"}'; fi ;; - 'api repos/acme/widgets/compare/'*) git rev-list --count HEAD..origin/trunk ;; + 'api repos/acme/widgets/compare/'*) + if [[ "\${COMPARE_READ_FAILURE:-none}" != none ]]; then + if [[ "\${COMPARE_READ_FAILURE}" == always || ! -f "$STATE.compare-read" ]]; then + touch "$STATE.compare-read"; exit 1 + fi + fi + if [[ "\${INVALID_ANCESTRY:-false}" == true ]]; then printf 'invalid'; + else git rev-list --count HEAD..origin/trunk; fi ;; 'api --method') [[ "$*" == *"expected_head_sha=$(git rev-parse HEAD)"* ]] || exit 9 git fetch -q origin trunk @@ -143,6 +155,34 @@ for (const kind of ["sync", "closeout"]) { assert.equal(f.receipts().split("\n").filter(line => line.startsWith("workflow run")).length, 4); assert.equal(readFileSync(join(f.dir, "release.txt"), "utf8"), "Release advances base\n"); })); + for (const boundary of ["PR", "COMPARE"]) { + test(`${kind}: transient ${boundary} poll failure retries and still updates and redispatches`, () => fixture(f => { + Object.assign(f.env, { BEHIND: "true", MAINTENANCE_ATTEMPTS: "4", [`${boundary}_READ_FAILURE`]: "once" }); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr) + String(r.stdout)); + assert.match(String(r.stdout), /unavailable; retrying/); + assert.doesNotMatch(String(r.stdout), /Cannot verify|token requires/); + assert.match(f.receipts(), /update-branch/); + const dispatches = f.receipts().split("\n").filter(line => line.startsWith("workflow run")); + assert.equal(dispatches.length, 4); + assert.notEqual(dispatches[0]!.split("HEAD=")[1], dispatches[2]!.split("HEAD=")[1]); + assert.equal(readFileSync(join(f.dir, "release.txt"), "utf8"), "Release advances base\n"); + })); + test(`${kind}: persistent ${boundary} poll errors stop at the configured bound`, () => fixture(f => { + Object.assign(f.env, { BLOCKED: "true", MAINTENANCE_ATTEMPTS: "3", [`${boundary}_READ_FAILURE`]: "always" }); + const r = f.execute(kind); assert.equal(r.status, 0, String(r.stderr) + String(r.stdout)); + assert.match(String(r.stdout), /configured bound/); + assert.equal(f.receipts().split("\n").filter(line => line.startsWith("pr view")).length, 3); + assert.doesNotMatch(f.receipts(), /update-branch/); + })); + } + test(`${kind}: successful ancestry reads with invalid data still fail closed`, () => fixture(f => { + Object.assign(f.env, { BLOCKED: "true", INVALID_ANCESTRY: "true", MAINTENANCE_ATTEMPTS: "3" }); + const r = f.execute(kind); assert.equal(r.status, 1, String(r.stderr)); + assert.match(String(r.stdout), /Cannot verify bot branch ancestry/); + assert.doesNotMatch(String(r.stdout), /unavailable; retrying/); + assert.doesNotMatch(f.receipts(), /update-branch/); + assert.equal(f.receipts().split("\n").filter(line => line.startsWith("pr view")).length, 1); + })); test(`${kind}: dispatch denial reports the token diagnostic before auto-merge`, () => fixture(f => { f.env.DISPATCH_DENIED = "1"; const r = f.execute(kind); assert.equal(r.status, 1, String(r.stderr)); From db37fdb9522627d6de7f7009890a748d7052389a Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 08:44:40 +0200 Subject: [PATCH 6/9] Record revert proofs and run isolated release command validation --- .agents/pm/history/pm-github-8r7c.jsonl | 2 ++ .agents/pm/issues/pm-github-8r7c.toon | 6 ++-- .github/workflows/review-release-check.yml | 38 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/review-release-check.yml diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index 2e8b5963..77371998 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -38,3 +38,5 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T06:35:15.751Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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-18T06:35:15.751Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"597ca2babd214664490a23a898043f77fc4a09ccf28b579161c7bdf632f80b90","after_hash":"e66027bd652c8335624951a7ebdefde1452f022af4597d90c347837d688ec271","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":"60bee5ead8b92fd9164ec6716b2513bb0430be68186806ae7eb10e3809a6f2a5"} {"hash_algorithm":"sha256","ts":"2026-10-18T06:35:25.995Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/21","value":{"created_at":"2026-10-18T06:35:25.995Z","author":"codex-agent","text":"Round 2: verified both unresolved CodeRabbit findings on PR #146. Retry failed PR-state and ancestry reads within the existing monitor bounds; retain fail-closed validation of successful ancestry responses. Add real-shell regressions and behavioral revert proofs. Document the orchestrator-verified no-App action_required approval path. Main attestation compatibility merged before changes; no dependency bump. PR #148 has no CodeRabbit review yet."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:35:25.995Z"}],"before_hash":"e66027bd652c8335624951a7ebdefde1452f022af4597d90c347837d688ec271","after_hash":"330831dc95a71125246aace1836194502395081c36b6f233e82b635a9ad46076","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":"9882eb88df3be4787ee27220f240cfd4b4c1bbd4fa8e2a5b3c6b815302064185"} {"hash_algorithm":"sha256","ts":"2026-10-18T06:36:42.344Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/3","value":{"command":"node --test --test-name-pattern=\"poll failure|poll errors|invalid data\" test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T06:36:41.942Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:36:42.344Z"}],"before_hash":"330831dc95a71125246aace1836194502395081c36b6f233e82b635a9ad46076","after_hash":"970df8274e3cef56705d893c4f7b5a58b3d8579755c918893d838a2ddc831a21","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":"b694f7b6dae753c27771f127106013d4f9767d97a3c3130b073725bba189741c"} +{"hash_algorithm":"sha256","ts":"2026-10-18T06:42:43.566Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/22","value":{"created_at":"2026-10-18T06:42:43.566Z","author":"codex-agent","text":"Behavioral revert proofs retain all new tests: restoring only the PR-state read assignments fails all 4 PR poll regressions (sync and closeout, transient and persistent); restoring only the ancestry read assignments fails all 4 COMPARE poll regressions. Restoring the fix passes 10/10 focused cases, including 2 invalid-success-response fail-closed controls. No SDK mocks or live GitHub mutations; shell executes real local Git merges and checks redispatch on the new head."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:42:43.566Z"}],"before_hash":"970df8274e3cef56705d893c4f7b5a58b3d8579755c918893d838a2ddc831a21","after_hash":"21fbc1f731c3e4d4f42bfbc1e0bfc35df537867663b65ab86acd4394fb30806d","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":"662321581cada965e333c88172d482dc4e6dc532fe584c6cbdc77fc0f04d533b"} +{"hash_algorithm":"sha256","ts":"2026-10-18T06:44:22.666Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/23","value":{"created_at":"2026-10-18T06:44:22.666Z","author":"codex-agent","text":"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:44:22.666Z"}],"before_hash":"21fbc1f731c3e4d4f42bfbc1e0bfc35df537867663b65ab86acd4394fb30806d","after_hash":"74c3406f1444482e6550972b1e863be9b656bacfc088c3c124f1b7dadf2cdd08","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":"58bc459d35ea7a9695fd8a69764ca19826be5fb74c94620d15ad74af20ccc88e"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index f504946d..23ff5b11 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,12 +6,12 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T06:36:42.344Z" +updated_at: "2026-10-18T06:44:22.666Z" assignee: codex-agent claim_principal: codex-agent author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[22]{created_at,author,text}: +comments[24]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -34,6 +34,8 @@ comments[22]{created_at,author,text}: "2026-10-18T04:25:27.134Z",codex-agent,"Final merge audit correction: keep the intact origin/main history as the canonical chain, so the PR diff against main removes no existing record. Replay the branch rollout note and documentation link through the pinned CLI. The prior PR-fork records remain byte-identical in merge parent b6d44a0; no record was re-anchored, repaired or edited. This supersedes the earlier choice of the PR fork as primary. Both main and branch rollout context are preserved." "2026-10-18T04:45:15.168Z",codex-agent,"Round 1 release gates PASS at 498fd15aa927b325a4a87a314503b0d1943e187f: npm run release:check and bun run release:check with isolated HOME and disabled global/system Git identity each pass 841/841, zero failures/skips/cancellations/todos, exact 100/100/100/100 coverage across all 14 authored modules. Receipts: https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199894 and https://github.com/unbraind/pm-github/actions/runs/39097266861/job/117586199798 . Linked pm commands pass; detector/App-guard/README revert proofs remain 16/16, 2/2 and 1/1 failures respectively. All five review threads received post-push replies. Remove the temporary validation workflow; implementation and tests remain identical. The main-based rollout history verifies 8/8 with current-item hash equality. Local duplicate full runs were stopped; full gate receipts are from CI. Leave item in progress and unclaimed for orchestrator verification." "2026-10-18T06:35:25.995Z",codex-agent,"Round 2: verified both unresolved CodeRabbit findings on PR #146. Retry failed PR-state and ancestry reads within the existing monitor bounds; retain fail-closed validation of successful ancestry responses. Add real-shell regressions and behavioral revert proofs. Document the orchestrator-verified no-App action_required approval path. Main attestation compatibility merged before changes; no dependency bump. PR #148 has no CodeRabbit review yet." + "2026-10-18T06:42:43.566Z",codex-agent,"Behavioral revert proofs retain all new tests: restoring only the PR-state read assignments fails all 4 PR poll regressions (sync and closeout, transient and persistent); restoring only the ancestry read assignments fails all 4 COMPARE poll regressions. Restoring the fix passes 10/10 focused cases, including 2 invalid-success-response fail-closed controls. No SDK mocks or live GitHub mutations; shell executes real local Git merges and checks redispatch on the new head." + "2026-10-18T06:44:22.666Z",codex-agent,"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project diff --git a/.github/workflows/review-release-check.yml b/.github/workflows/review-release-check.yml new file mode 100644 index 00000000..b01f2330 --- /dev/null +++ b/.github/workflows/review-release-check.yml @@ -0,0 +1,38 @@ +name: Review release commands +on: + push: + branches: ["fix/bot-prs-run-required-checks-and-stay-current"] +permissions: + contents: read +jobs: + release-check: + runs-on: ubuntu-latest + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + runtime: [npm, bun] + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 26 + cache: npm + - uses: oven-sh/setup-bun@v2.2.0 + with: + bun-version: "1.3.14" + - run: npm ci + - name: Exact release command with isolated identity + shell: bash + env: + REVIEW_RUNTIME: ${{ matrix.runtime }} + run: | + set -euo pipefail + export HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 + if [[ "$REVIEW_RUNTIME" == npm ]]; then + npm run release:check + else + bun run release:check + fi From d9c5ef462de523394a1e1e6be936d1a661c92a66 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 09:00:25 +0200 Subject: [PATCH 7/9] Record review gates and remove temporary command validation --- .agents/pm/history/pm-github-8r7c.jsonl | 2 ++ .agents/pm/issues/pm-github-8r7c.toon | 7 ++-- .github/workflows/review-release-check.yml | 38 ---------------------- 3 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 .github/workflows/review-release-check.yml diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index 77371998..fa06671f 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -40,3 +40,5 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T06:36:42.344Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/3","value":{"command":"node --test --test-name-pattern=\"poll failure|poll errors|invalid data\" test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T06:36:41.942Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:36:42.344Z"}],"before_hash":"330831dc95a71125246aace1836194502395081c36b6f233e82b635a9ad46076","after_hash":"970df8274e3cef56705d893c4f7b5a58b3d8579755c918893d838a2ddc831a21","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":"b694f7b6dae753c27771f127106013d4f9767d97a3c3130b073725bba189741c"} {"hash_algorithm":"sha256","ts":"2026-10-18T06:42:43.566Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/22","value":{"created_at":"2026-10-18T06:42:43.566Z","author":"codex-agent","text":"Behavioral revert proofs retain all new tests: restoring only the PR-state read assignments fails all 4 PR poll regressions (sync and closeout, transient and persistent); restoring only the ancestry read assignments fails all 4 COMPARE poll regressions. Restoring the fix passes 10/10 focused cases, including 2 invalid-success-response fail-closed controls. No SDK mocks or live GitHub mutations; shell executes real local Git merges and checks redispatch on the new head."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:42:43.566Z"}],"before_hash":"970df8274e3cef56705d893c4f7b5a58b3d8579755c918893d838a2ddc831a21","after_hash":"21fbc1f731c3e4d4f42bfbc1e0bfc35df537867663b65ab86acd4394fb30806d","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":"662321581cada965e333c88172d482dc4e6dc532fe584c6cbdc77fc0f04d533b"} {"hash_algorithm":"sha256","ts":"2026-10-18T06:44:22.666Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/23","value":{"created_at":"2026-10-18T06:44:22.666Z","author":"codex-agent","text":"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:44:22.666Z"}],"before_hash":"21fbc1f731c3e4d4f42bfbc1e0bfc35df537867663b65ab86acd4394fb30806d","after_hash":"74c3406f1444482e6550972b1e863be9b656bacfc088c3c124f1b7dadf2cdd08","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":"58bc459d35ea7a9695fd8a69764ca19826be5fb74c94620d15ad74af20ccc88e"} +{"hash_algorithm":"sha256","ts":"2026-10-18T07:00:15.003Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/24","value":{"created_at":"2026-10-18T07:00:15.003Z","author":"codex-agent","text":"Round 2 final gate receipts: npm run release:check and bun run release:check pass 863/863 each at db37fdb9522627d6de7f7009890a748d7052389a, zero failures/skips/cancellations/todos, all 14 authored modules at exact 100/100/100/100. CI identity uses isolated HOME and disabled global/system Git config; lint, duplication, privacy, production audit, package dry run, changelog and attestation checks pass. Receipts: https://github.com/unbraind/pm-github/actions/runs/39105126247 (npm job 117609196631, Bun job 117609196775). Linked PM retries pass 53/53 maintenance and 3/3 integration cases with a 600-second runner budget; existing workflow-version suite and new focused 10/10 regressions also pass. Independent reverts fail 4/4 PR-read cases and 4/4 ancestry-read cases. Fresh-clone strict health passes. Both review threads received post-push replies and CodeRabbit marked them addressed; no manual thread resolution. Remove the temporary validation workflow; source, tests, docs and pins remain identical. Final-head CI will be recorded in the PR body. No PR merge or package release performed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T07:00:15.003Z"}],"before_hash":"74c3406f1444482e6550972b1e863be9b656bacfc088c3c124f1b7dadf2cdd08","after_hash":"3ec51371fe8ced5d090ed82a22c1e9a16a8399cb3bb05cacae29f1853725ff53","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":"83e81b045f0aebc76df159006e2429b05be35c40448b5c7570eff7052dd6ad69"} +{"hash_algorithm":"sha256","ts":"2026-10-18T07:00:19.021Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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-18T07:00:19.021Z"}],"before_hash":"3ec51371fe8ced5d090ed82a22c1e9a16a8399cb3bb05cacae29f1853725ff53","after_hash":"5db820270630d74a2c159ab9dfe2eb3ba675b6abaaa5a8d8664d94ff381a4e02","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":"3dec109a40ea2489d399d40fbd00c987420c0359abe23c75e64e672a5a768d1c"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index 23ff5b11..b655995e 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,12 +6,10 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T06:44:22.666Z" -assignee: codex-agent -claim_principal: codex-agent +updated_at: "2026-10-18T07:00:19.021Z" author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[24]{created_at,author,text}: +comments[25]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -36,6 +34,7 @@ comments[24]{created_at,author,text}: "2026-10-18T06:35:25.995Z",codex-agent,"Round 2: verified both unresolved CodeRabbit findings on PR #146. Retry failed PR-state and ancestry reads within the existing monitor bounds; retain fail-closed validation of successful ancestry responses. Add real-shell regressions and behavioral revert proofs. Document the orchestrator-verified no-App action_required approval path. Main attestation compatibility merged before changes; no dependency bump. PR #148 has no CodeRabbit review yet." "2026-10-18T06:42:43.566Z",codex-agent,"Behavioral revert proofs retain all new tests: restoring only the PR-state read assignments fails all 4 PR poll regressions (sync and closeout, transient and persistent); restoring only the ancestry read assignments fails all 4 COMPARE poll regressions. Restoring the fix passes 10/10 focused cases, including 2 invalid-success-response fail-closed controls. No SDK mocks or live GitHub mutations; shell executes real local Git merges and checks redispatch on the new head." "2026-10-18T06:44:22.666Z",codex-agent,"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds." + "2026-10-18T07:00:15.003Z",codex-agent,"Round 2 final gate receipts: npm run release:check and bun run release:check pass 863/863 each at db37fdb9522627d6de7f7009890a748d7052389a, zero failures/skips/cancellations/todos, all 14 authored modules at exact 100/100/100/100. CI identity uses isolated HOME and disabled global/system Git config; lint, duplication, privacy, production audit, package dry run, changelog and attestation checks pass. Receipts: https://github.com/unbraind/pm-github/actions/runs/39105126247 (npm job 117609196631, Bun job 117609196775). Linked PM retries pass 53/53 maintenance and 3/3 integration cases with a 600-second runner budget; existing workflow-version suite and new focused 10/10 regressions also pass. Independent reverts fail 4/4 PR-read cases and 4/4 ancestry-read cases. Fresh-clone strict health passes. Both review threads received post-push replies and CodeRabbit marked them addressed; no manual thread resolution. Remove the temporary validation workflow; source, tests, docs and pins remain identical. Final-head CI will be recorded in the PR body. No PR merge or package release performed." files[6]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project diff --git a/.github/workflows/review-release-check.yml b/.github/workflows/review-release-check.yml deleted file mode 100644 index b01f2330..00000000 --- a/.github/workflows/review-release-check.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Review release commands -on: - push: - branches: ["fix/bot-prs-run-required-checks-and-stay-current"] -permissions: - contents: read -jobs: - release-check: - runs-on: ubuntu-latest - timeout-minutes: 40 - strategy: - fail-fast: false - matrix: - runtime: [npm, bun] - steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: 26 - cache: npm - - uses: oven-sh/setup-bun@v2.2.0 - with: - bun-version: "1.3.14" - - run: npm ci - - name: Exact release command with isolated identity - shell: bash - env: - REVIEW_RUNTIME: ${{ matrix.runtime }} - run: | - set -euo pipefail - export HOME="$(mktemp -d)" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 - if [[ "$REVIEW_RUNTIME" == npm ]]; then - npm run release:check - else - bun run release:check - fi From 9fdc0fc583c02dba9a25bd9c1f362678f75e4760 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 10:46:40 +0200 Subject: [PATCH 8/9] docs: distinguish App and maintainer bot PR landing --- .agents/pm/history/pm-github-8r7c.jsonl | 7 +++++++ .agents/pm/issues/pm-github-8r7c.toon | 18 +++++++++++++----- README.md | 15 +++++++++------ test/bot-pr-workflow.test.ts | 7 +++++++ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index fa06671f..6afa2f77 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -42,3 +42,10 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T06:44:22.666Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/23","value":{"created_at":"2026-10-18T06:44:22.666Z","author":"codex-agent","text":"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T06:44:22.666Z"}],"before_hash":"21fbc1f731c3e4d4f42bfbc1e0bfc35df537867663b65ab86acd4394fb30806d","after_hash":"74c3406f1444482e6550972b1e863be9b656bacfc088c3c124f1b7dadf2cdd08","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":"58bc459d35ea7a9695fd8a69764ca19826be5fb74c94620d15ad74af20ccc88e"} {"hash_algorithm":"sha256","ts":"2026-10-18T07:00:15.003Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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/24","value":{"created_at":"2026-10-18T07:00:15.003Z","author":"codex-agent","text":"Round 2 final gate receipts: npm run release:check and bun run release:check pass 863/863 each at db37fdb9522627d6de7f7009890a748d7052389a, zero failures/skips/cancellations/todos, all 14 authored modules at exact 100/100/100/100. CI identity uses isolated HOME and disabled global/system Git config; lint, duplication, privacy, production audit, package dry run, changelog and attestation checks pass. Receipts: https://github.com/unbraind/pm-github/actions/runs/39105126247 (npm job 117609196631, Bun job 117609196775). Linked PM retries pass 53/53 maintenance and 3/3 integration cases with a 600-second runner budget; existing workflow-version suite and new focused 10/10 regressions also pass. Independent reverts fail 4/4 PR-read cases and 4/4 ancestry-read cases. Fresh-clone strict health passes. Both review threads received post-push replies and CodeRabbit marked them addressed; no manual thread resolution. Remove the temporary validation workflow; source, tests, docs and pins remain identical. Final-head CI will be recorded in the PR body. No PR merge or package release performed."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T07:00:15.003Z"}],"before_hash":"74c3406f1444482e6550972b1e863be9b656bacfc088c3c124f1b7dadf2cdd08","after_hash":"3ec51371fe8ced5d090ed82a22c1e9a16a8399cb3bb05cacae29f1853725ff53","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":"83e81b045f0aebc76df159006e2429b05be35c40448b5c7570eff7052dd6ad69"} {"hash_algorithm":"sha256","ts":"2026-10-18T07:00:19.021Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"35bde0385948133b9731885a","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-18T07:00:19.021Z"}],"before_hash":"3ec51371fe8ced5d090ed82a22c1e9a16a8399cb3bb05cacae29f1853725ff53","after_hash":"5db820270630d74a2c159ab9dfe2eb3ba675b6abaaa5a8d8664d94ff381a4e02","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":"3dec109a40ea2489d399d40fbd00c987420c0359abe23c75e64e672a5a768d1c"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:40:09.668Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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-18T08:40:09.668Z"},{"op":"add","path":"/metadata/assignee","value":"codex-agent"},{"op":"add","path":"/metadata/claim_principal","value":"codex-agent"}],"before_hash":"5db820270630d74a2c159ab9dfe2eb3ba675b6abaaa5a8d8664d94ff381a4e02","after_hash":"52043cde37381a8bf787630d2602d1a6c9e7fd3e9630dbc46b34642bcb68f537","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":"5229669130ba57bc7518d9bf5c0b6dde1cc9cc22d007e2fda41008b65ef86b33"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:40:14.560Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/25","value":{"created_at":"2026-10-18T08:40:14.559Z","author":"codex-agent","text":"PR #146 review round 3: read the full unresolved README thread and newest CodeRabbit review, with no outside-diff/nitpick findings or open issues naming this PR. The auto-merge paragraph contradicts the App-only workflow guard. Scope: qualify initial and repeated auto-merge requests as App mode; state no-App maintainer approval and authorized merge explicitly; add a documentation contract regression with README-only revert proof. Current main is already an ancestor; no merge or receipt reconciliation needed. Published PM CLI is 2026.10.18; retain the pinned 2026.10.13 dependency."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:40:14.560Z"}],"before_hash":"52043cde37381a8bf787630d2602d1a6c9e7fd3e9630dbc46b34642bcb68f537","after_hash":"3ab59fcda30b7ebb62a89f13c93dc1bd687fb666a87aa65e99b203835ebabb3c","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":"bba381363c4e2707d1380413eff2ced7cd086f3369ef3016a2286eca9790002c"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:40:53.019Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/files/5/path","value":"test/import-gate.test.ts"},{"op":"replace","path":"/metadata/files/4/path","value":"test/closeout-workflow.test.ts"},{"op":"replace","path":"/metadata/files/3/path","value":"test/bot-pr-workflow.test.ts"},{"op":"replace","path":"/metadata/files/2/path","value":"README.md"},{"op":"add","path":"/metadata/files/6","value":{"path":"test/self-versioned-workflows.test.ts","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:40:53.019Z"}],"before_hash":"3ab59fcda30b7ebb62a89f13c93dc1bd687fb666a87aa65e99b203835ebabb3c","after_hash":"26adcc59df375dd79d594933fb7c356a827f904e283c96db66fbd2eae68cb66b","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":"58f8d5919f46334934520fa80466377acdc50cd888c267bcd04fb0f1efe4d881"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:40:57.516Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","agent_provenance":{"model":{"value":"gpt-6.1-sol","source":"probe"},"effort":{"value":"high","source":"probe"},"role":null,"topic":null},"op":"docs_add","patch":[{"op":"add","path":"/metadata/docs/1","value":{"path":"README.md","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:40:57.516Z"}],"before_hash":"26adcc59df375dd79d594933fb7c356a827f904e283c96db66fbd2eae68cb66b","after_hash":"d01e0067ffbcbc0b336e7ee8e6114324692487d9a2dd8ed192715149bc49cab5","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":"3e8dfe8d07b81b2658296f4303f021c88d93bc5d5be4b7194c284ed7682ddcd3"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:41:07.433Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/4","value":{"command":"node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T08:41:07.079Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:41:07.433Z"}],"before_hash":"d01e0067ffbcbc0b336e7ee8e6114324692487d9a2dd8ed192715149bc49cab5","after_hash":"cc1c918f3220d32ed9d987d23a9ffd3fd84e0c899613f0fb622a063cb8792e9e","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":"60c44e2fac993c494daa1a3f0151f9926f3e2e93c5f0a336269bc7dbf538611f"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:41:30.864Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/26","value":{"created_at":"2026-10-18T08:41:30.864Z","author":"codex-agent","text":"Regression proof: node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts passes 1/1. Keeping the new test and restoring only README.md from d9c5ef4 produces 0 pass / 1 fail at the App-only auto-merge assertion. Restoring the README fix passes 1/1. The README also qualifies redispatch auto-merge and the parity table; workflow code and thresholds are unchanged."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:41:30.864Z"}],"before_hash":"cc1c918f3220d32ed9d987d23a9ffd3fd84e0c899613f0fb622a063cb8792e9e","after_hash":"b5be5cdd622b62ab57527a335d8c1a0a67459d77dd098abb9f5645e1f13c8652","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":"29b4933f29f354d99506680848efc48c7c73422f21ece42acf2dd6ac3c8707f7"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:46:34.644Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/27","value":{"created_at":"2026-10-18T08:46:34.644Z","author":"codex-agent","text":"All five linked test commands pass via pm test pm-github-8r7c --run --progress --timeout 600: maintenance 54/54, workflow integration 3/3, workflow versioning 43/43, polling regressions 10/10, README contract 1/1; zero failures/skips. Test-result tracking is disabled by repository policy, so this comment preserves the result without changing policy. The normal host strict-health probe reports host/pinned SDK version skew; fresh-clone health will run with CI identity isolation. npm release:check is progressing under that isolation; Bun follows sequentially to avoid shared coverage output collisions."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:46:34.644Z"}],"before_hash":"b5be5cdd622b62ab57527a335d8c1a0a67459d77dd098abb9f5645e1f13c8652","after_hash":"c2a8fb0c2eff44efdaf67fa9ad62342448bc6f63e7ff53d9633ec4a881869e87","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":"d1821e8dc7d4ac440bbd2aee45e05db0120ec28d850e87077fe176db06e9e02d"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index b655995e..7fc5ffa9 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,10 +6,12 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T07:00:19.021Z" +updated_at: "2026-10-18T08:46:34.644Z" +assignee: codex-agent +claim_principal: codex-agent author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[25]{created_at,author,text}: +comments[28]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -35,18 +37,24 @@ comments[25]{created_at,author,text}: "2026-10-18T06:42:43.566Z",codex-agent,"Behavioral revert proofs retain all new tests: restoring only the PR-state read assignments fails all 4 PR poll regressions (sync and closeout, transient and persistent); restoring only the ancestry read assignments fails all 4 COMPARE poll regressions. Restoring the fix passes 10/10 focused cases, including 2 invalid-success-response fail-closed controls. No SDK mocks or live GitHub mutations; shell executes real local Git merges and checks redispatch on the new head." "2026-10-18T06:44:22.666Z",codex-agent,"Local duplicate release gates were stopped before completion because of shared-host contention; no pass is claimed. Run both exact npm and Bun release commands on isolated-identity GitHub runners using a temporary validation workflow, then remove it and verify final-head CI. Initial linked PM run passed the new 10-case regression and workflow-version suite, while two older commands exceeded their 120-second runner limit; rerun those with a 600-second limit without changing assertions or thresholds." "2026-10-18T07:00:15.003Z",codex-agent,"Round 2 final gate receipts: npm run release:check and bun run release:check pass 863/863 each at db37fdb9522627d6de7f7009890a748d7052389a, zero failures/skips/cancellations/todos, all 14 authored modules at exact 100/100/100/100. CI identity uses isolated HOME and disabled global/system Git config; lint, duplication, privacy, production audit, package dry run, changelog and attestation checks pass. Receipts: https://github.com/unbraind/pm-github/actions/runs/39105126247 (npm job 117609196631, Bun job 117609196775). Linked PM retries pass 53/53 maintenance and 3/3 integration cases with a 600-second runner budget; existing workflow-version suite and new focused 10/10 regressions also pass. Independent reverts fail 4/4 PR-read cases and 4/4 ancestry-read cases. Fresh-clone strict health passes. Both review threads received post-push replies and CodeRabbit marked them addressed; no manual thread resolution. Remove the temporary validation workflow; source, tests, docs and pins remain identical. Final-head CI will be recorded in the PR body. No PR merge or package release performed." -files[6]{path,scope}: + "2026-10-18T08:40:14.559Z",codex-agent,"PR #146 review round 3: read the full unresolved README thread and newest CodeRabbit review, with no outside-diff/nitpick findings or open issues naming this PR. The auto-merge paragraph contradicts the App-only workflow guard. Scope: qualify initial and repeated auto-merge requests as App mode; state no-App maintainer approval and authorized merge explicitly; add a documentation contract regression with README-only revert proof. Current main is already an ancestor; no merge or receipt reconciliation needed. Published PM CLI is 2026.10.18; retain the pinned 2026.10.13 dependency." + "2026-10-18T08:41:30.864Z",codex-agent,"Regression proof: node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts passes 1/1. Keeping the new test and restoring only README.md from d9c5ef4 produces 0 pass / 1 fail at the App-only auto-merge assertion. Restoring the README fix passes 1/1. The README also qualifies redispatch auto-merge and the parity table; workflow code and thresholds are unchanged." + "2026-10-18T08:46:34.644Z",codex-agent,"All five linked test commands pass via pm test pm-github-8r7c --run --progress --timeout 600: maintenance 54/54, workflow integration 3/3, workflow versioning 43/43, polling regressions 10/10, README contract 1/1; zero failures/skips. Test-result tracking is disabled by repository policy, so this comment preserves the result without changing policy. The normal host strict-health probe reports host/pinned SDK version skew; fresh-clone health will run with CI identity isolation. npm release:check is progressing under that isolation; Bun follows sequentially to avoid shared coverage output collisions." +files[7]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project + README.md,project test/bot-pr-workflow.test.ts,project test/closeout-workflow.test.ts,project test/import-gate.test.ts,project test/self-versioned-workflows.test.ts,project -tests[4]{command,scope,provenance{author,created_at,source_kind,source_ref}}: +tests[5]{command,scope,provenance{author,created_at,source_kind,source_ref}}: node --test test/bot-pr-workflow.test.ts,project,codex-agent,"2026-10-17T09:35:21.256Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current node --test --test-name-pattern='^(the caller default branch trunk flows from schedule guard through real Git preparation and review|the workflow never edits a fork PR sharing the sync branch name|npm-project-dir subdirectory CLI and SDK keep the tracker and publication at the repository root)$' test/import-gate.test.ts,project,codex-agent,"2026-10-17T13:38:31.648Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current node --test test/self-versioned-workflows.test.ts,project,codex-agent,"2026-10-18T04:06:14.124Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current "node --test --test-name-pattern=\"poll failure|poll errors|invalid data\" test/bot-pr-workflow.test.ts",project,codex-agent,"2026-10-18T06:36:41.942Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current -docs[1]{path,scope}: + "node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts",project,codex-agent,"2026-10-18T08:41:07.079Z",local_mutation,fix/bot-prs-run-required-checks-and-stay-current +docs[2]{path,scope}: docs/bot-pr-automation.md,project + README.md,project body: "" diff --git a/README.md b/README.md index 21c5f2bf..94671138 100644 --- a/README.md +++ b/README.md @@ -592,7 +592,7 @@ The script must emit the root `CHANGELOG.md` and remain inside the publication s | Validation | Strict PM health; explicit item/history scope committed together | | Branch and PR | Explicit force-with-lease against the observed bot ref; push only bot branch; owned PR lookup excludes forks | | No-op | Zero closes or no tracker diff creates no remote branch or PR; caller-only drift unpublished; stale owned PR closed | -| CI and landing | Dispatch caller checks after publication and branch refresh; request protected squash auto-merge; report parked approval-required runs | +| CI and landing | Dispatch caller checks after publication and branch refresh; request protected squash auto-merge in App mode; report parked approval-required runs | `ci-workflows` defaults to `ci.yml codeql.yml`, covering the fleet's CI and CodeQL workflows without querying branch protection. An explicit list replaces @@ -616,13 +616,16 @@ verification. Empty credentials retain GITHUB_TOKEN and emit a setup notice; partial or failed App credentials stop publication. The private key is passed only to the token action, after caller scripts have completed. -After dispatch the workflow requests `gh pr merge --auto --squash` with the -expected head SHA. A repository that disallows auto-merge emits a notice. +In App mode, after dispatch the workflow requests `gh pr merge --auto --squash` +with the expected head SHA. A repository that disallows auto-merge emits a notice. +Without an App, maintainers approve native PR runs, wait for required checks and +conversations, and merge with an authorized credential; the workflow does not arm +auto-merge. GitHub enforces required checks and conversation resolution. The same run polls once per minute: when the PR is `BEHIND`, it requests a branch update -against the expected head, then dispatches all selected workflows and requests -auto-merge again when the new head appears. App mode stops within forty minutes, -inside its token's one-hour lifetime; legacy mode has a two-hour bound. The +against the expected head, then dispatches all selected workflows and, in App +mode, requests auto-merge again when the new head appears. App mode stops within +forty minutes, inside its token's one-hour lifetime; legacy mode has a two-hour bound. The existing daily schedules and separate sync/closeout concurrency groups remain. A base change after the monitor window waits for the next daily rebuild. Unresolved conversations continue to block landing. diff --git a/test/bot-pr-workflow.test.ts b/test/bot-pr-workflow.test.ts index 92be3212..90259845 100644 --- a/test/bot-pr-workflow.test.ts +++ b/test/bot-pr-workflow.test.ts @@ -90,6 +90,13 @@ esac } finally { rmSync(dir, { recursive: true, force: true }); } } +test("README distinguishes App auto-merge from no-App maintainer landing", () => { + const readme = readFileSync(join(root, "README.md"), "utf8").replace(/\s+/g, " "); + assert.match(readme, /In App mode, after dispatch the workflow requests `gh pr merge --auto --squash` with the expected head SHA/); + assert.match(readme, /Without an App, maintainers approve native PR runs, wait for required checks and conversations, and merge with an authorized credential; the workflow does not arm auto-merge/); + assert.match(readme, /dispatches all selected workflows and, in App mode, requests auto-merge again when the new head appears/); +}); + for (const kind of ["sync", "closeout"]) { test(`${kind}: default selects CI and CodeQL, respecting explicit overrides`, () => fixture(f => { const source = readFileSync(join(root, `.github/workflows/pm-github-${kind}.yml`), "utf8"); From 1a0fb90ff6468376789e3151a02494f715584914 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Sun, 18 Oct 2026 11:07:20 +0200 Subject: [PATCH 9/9] chore: record PR 146 review verification receipts --- .agents/pm/history/pm-github-8r7c.jsonl | 4 ++++ .agents/pm/issues/pm-github-8r7c.toon | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.agents/pm/history/pm-github-8r7c.jsonl b/.agents/pm/history/pm-github-8r7c.jsonl index 6afa2f77..3213741c 100644 --- a/.agents/pm/history/pm-github-8r7c.jsonl +++ b/.agents/pm/history/pm-github-8r7c.jsonl @@ -49,3 +49,7 @@ {"hash_algorithm":"sha256","ts":"2026-10-18T08:41:07.433Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/4","value":{"command":"node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts","scope":"project","provenance":{"author":"codex-agent","created_at":"2026-10-18T08:41:07.079Z","source_kind":"local_mutation","source_ref":"fix/bot-prs-run-required-checks-and-stay-current"}}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:41:07.433Z"}],"before_hash":"d01e0067ffbcbc0b336e7ee8e6114324692487d9a2dd8ed192715149bc49cab5","after_hash":"cc1c918f3220d32ed9d987d23a9ffd3fd84e0c899613f0fb622a063cb8792e9e","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":"60c44e2fac993c494daa1a3f0151f9926f3e2e93c5f0a336269bc7dbf538611f"} {"hash_algorithm":"sha256","ts":"2026-10-18T08:41:30.864Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/26","value":{"created_at":"2026-10-18T08:41:30.864Z","author":"codex-agent","text":"Regression proof: node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts passes 1/1. Keeping the new test and restoring only README.md from d9c5ef4 produces 0 pass / 1 fail at the App-only auto-merge assertion. Restoring the README fix passes 1/1. The README also qualifies redispatch auto-merge and the parity table; workflow code and thresholds are unchanged."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:41:30.864Z"}],"before_hash":"cc1c918f3220d32ed9d987d23a9ffd3fd84e0c899613f0fb622a063cb8792e9e","after_hash":"b5be5cdd622b62ab57527a335d8c1a0a67459d77dd098abb9f5645e1f13c8652","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":"29b4933f29f354d99506680848efc48c7c73422f21ece42acf2dd6ac3c8707f7"} {"hash_algorithm":"sha256","ts":"2026-10-18T08:46:34.644Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/27","value":{"created_at":"2026-10-18T08:46:34.644Z","author":"codex-agent","text":"All five linked test commands pass via pm test pm-github-8r7c --run --progress --timeout 600: maintenance 54/54, workflow integration 3/3, workflow versioning 43/43, polling regressions 10/10, README contract 1/1; zero failures/skips. Test-result tracking is disabled by repository policy, so this comment preserves the result without changing policy. The normal host strict-health probe reports host/pinned SDK version skew; fresh-clone health will run with CI identity isolation. npm release:check is progressing under that isolation; Bun follows sequentially to avoid shared coverage output collisions."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:46:34.644Z"}],"before_hash":"b5be5cdd622b62ab57527a335d8c1a0a67459d77dd098abb9f5645e1f13c8652","after_hash":"c2a8fb0c2eff44efdaf67fa9ad62342448bc6f63e7ff53d9633ec4a881869e87","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":"d1821e8dc7d4ac440bbd2aee45e05db0120ec28d850e87077fe176db06e9e02d"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:50:22.195Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/28","value":{"created_at":"2026-10-18T08:50:22.195Z","author":"codex-agent","text":"Fresh git clone --no-local of 9fdc0fc583c02dba9a25bd9c1f362678f75e4760: npm ci succeeds; with a fresh HOME and global/system Git identity disabled, node_modules/.bin/pm health --strict-exit --require-merge-drivers exits 0. Integrity, append-only history drift, and installed merge drivers pass. Only advisory telemetry_queue_pending:1 and stale_in_progress_items:3 remain; no gate-failing finding. No merge was needed because origin/main is already an ancestor."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:50:22.195Z"}],"before_hash":"c2a8fb0c2eff44efdaf67fa9ad62342448bc6f63e7ff53d9633ec4a881869e87","after_hash":"fdcaba2aee16d745c2274926032892d609b59bf0816b604b212cee2db435a3dc","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":"51563f6fcbbe778d91bfa893788a77764b293cc451ff7331a091d26e2317b7ce"} +{"hash_algorithm":"sha256","ts":"2026-10-18T08:53:38.237Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/29","value":{"created_at":"2026-10-18T08:53:38.237Z","author":"codex-agent","text":"Shared-host load exceeded 23 runnable tasks for four available CPUs. The incomplete local npm gate was stopped after passing initial gates and progressing integration cases; it is not a passing gate receipt. Both exact release commands now run on hosted runners via a temporary validation branch, whose checkout explicitly selects source commit 9fdc0fc583c02dba9a25bd9c1f362678f75e4760. The validation-only workflow stays outside the PR source. npm and Bun use fresh HOME and disabled global/system Git identity, with unchanged gate thresholds. Full receipts will be recorded after completion."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T08:53:38.237Z"}],"before_hash":"fdcaba2aee16d745c2274926032892d609b59bf0816b604b212cee2db435a3dc","after_hash":"d979d108757cea500fab6bd62be793a72a6eac48876d9cb4b675874868814458","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":"a31b31b8e1555fb891b841e1526608b7cd62890d9cf973f34e5ebf2674ddabb4"} +{"hash_algorithm":"sha256","ts":"2026-10-18T09:07:14.916Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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/30","value":{"created_at":"2026-10-18T09:07:14.916Z","author":"codex-agent","text":"Completed exact gates on source 9fdc0fc583c02dba9a25bd9c1f362678f75e4760 with fresh HOME and global/system Git identity disabled: npm run release:check passes 864/864 (https://github.com/unbraind/pm-github/actions/runs/39113186520/job/117633459391); bun run release:check passes 864/864 (https://github.com/unbraind/pm-github/actions/runs/39113186520/job/117633459200). Both report zero failures, cancellations, skips or todos and exact 100/100/100/100 coverage for all 14 authored modules. Typecheck, build, docstrings, lint, unchanged duplication/privacy gates, production audit, package dry run, changelog check and publish attestation pass. Only tracker receipt updates follow this validated source. Releasing this claim without closing the item; final-head CI is monitored after push, and the README review thread receives the pushed SHA and test evidence. No PM CLI/SDK defect was encountered; host SDK skew is avoided by CI identity isolation."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-10-18T09:07:14.916Z"}],"before_hash":"d979d108757cea500fab6bd62be793a72a6eac48876d9cb4b675874868814458","after_hash":"dcd5b7d8def4bb58cc640ea7d1211994b210d734f45c07fd65b27935b097cdba","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":"229b4e3fe9afc161ea8cb39539205c5864df92ba2eb1e8a881d1dc45019f5ea2"} +{"hash_algorithm":"sha256","ts":"2026-10-18T09:07:16.810Z","author":"codex-agent","author_source":"asserted","agent_harness":"codex","agent_model":"gpt-6.1-sol","agent_model_source":"probe","agent_instance":"3e9cf20fe719b2989da2daa0","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-18T09:07:16.810Z"}],"before_hash":"dcd5b7d8def4bb58cc640ea7d1211994b210d734f45c07fd65b27935b097cdba","after_hash":"0e2f8c01c43e3d7b022222e5226525c251336055ca4895cd3942dce4941593bf","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":"e782894b579bbbd1f1743f9fd1e84769eeba1b5d2dec311ea63f459af011a9c7"} diff --git a/.agents/pm/issues/pm-github-8r7c.toon b/.agents/pm/issues/pm-github-8r7c.toon index 7fc5ffa9..3f992e04 100644 --- a/.agents/pm/issues/pm-github-8r7c.toon +++ b/.agents/pm/issues/pm-github-8r7c.toon @@ -6,12 +6,10 @@ status: in_progress priority: 1 tags: [] created_at: "2026-10-17T09:26:43.864Z" -updated_at: "2026-10-18T08:46:34.644Z" -assignee: codex-agent -claim_principal: codex-agent +updated_at: "2026-10-18T09:07:16.810Z" author: codex-agent acceptance_criteria: Dispatch declared caller workflows on the proposal head; refresh behind proposals; request protected squash auto-merge; adversarial executable workflow regressions and npm/Bun release gates pass. -comments[28]{created_at,author,text}: +comments[31]{created_at,author,text}: "2026-10-17T09:27:20.424Z",codex-agent,"Live audit: all 24 caller CodeQL workflows lack workflow_dispatch. Required codeql is missing on pm-jev, pm-lint, pm-review and pm-swarm bot heads; dispatched CI checks succeed on heads despite parked pull_request runs. All closeout callers explicitly select ci.yml. Preserve override semantics and document one-time trigger/override setup. Refresh against the latest default branch, request protected squash auto-merge, and execute adversarial workflow tests. Keep import-fidelity PR 142 untouched." "2026-10-17T09:34:40.209Z",codex-agent,"Regression proof: replacing only both final dispatch/maintenance step bodies with origin/main makes the new bot PR suite fail; fixed suite passes 11/11. Tests perform a real default-branch advance and merge and require both CI and CodeQL to redispatch on the new SHA. Missing CodeQL dispatch is warned; zero dispatchable workflows fails; auto-merge denial is soft; unresolved conversations stay blocked. Maintenance is bounded to two hours, with the next daily run rebuilding afterward. Existing explicit ci.yml overrides require one-time removal or expansion alongside the CodeQL trigger." "2026-10-17T09:46:00.517Z",codex-agent,"Read-only follow-up audit: pm-ado PR 32 is also blocked by an unresolved changelog placement review (October delivery under the September package release), tracked separately as pm-github-lfcf. Required conversations are preserved. The new monitor uses the verified owned PR number so same-name fork branches cannot be selected for auto-merge." @@ -40,6 +38,9 @@ comments[28]{created_at,author,text}: "2026-10-18T08:40:14.559Z",codex-agent,"PR #146 review round 3: read the full unresolved README thread and newest CodeRabbit review, with no outside-diff/nitpick findings or open issues naming this PR. The auto-merge paragraph contradicts the App-only workflow guard. Scope: qualify initial and repeated auto-merge requests as App mode; state no-App maintainer approval and authorized merge explicitly; add a documentation contract regression with README-only revert proof. Current main is already an ancestor; no merge or receipt reconciliation needed. Published PM CLI is 2026.10.18; retain the pinned 2026.10.13 dependency." "2026-10-18T08:41:30.864Z",codex-agent,"Regression proof: node --test --test-name-pattern=\"README distinguishes\" test/bot-pr-workflow.test.ts passes 1/1. Keeping the new test and restoring only README.md from d9c5ef4 produces 0 pass / 1 fail at the App-only auto-merge assertion. Restoring the README fix passes 1/1. The README also qualifies redispatch auto-merge and the parity table; workflow code and thresholds are unchanged." "2026-10-18T08:46:34.644Z",codex-agent,"All five linked test commands pass via pm test pm-github-8r7c --run --progress --timeout 600: maintenance 54/54, workflow integration 3/3, workflow versioning 43/43, polling regressions 10/10, README contract 1/1; zero failures/skips. Test-result tracking is disabled by repository policy, so this comment preserves the result without changing policy. The normal host strict-health probe reports host/pinned SDK version skew; fresh-clone health will run with CI identity isolation. npm release:check is progressing under that isolation; Bun follows sequentially to avoid shared coverage output collisions." + "2026-10-18T08:50:22.195Z",codex-agent,"Fresh git clone --no-local of 9fdc0fc583c02dba9a25bd9c1f362678f75e4760: npm ci succeeds; with a fresh HOME and global/system Git identity disabled, node_modules/.bin/pm health --strict-exit --require-merge-drivers exits 0. Integrity, append-only history drift, and installed merge drivers pass. Only advisory telemetry_queue_pending:1 and stale_in_progress_items:3 remain; no gate-failing finding. No merge was needed because origin/main is already an ancestor." + "2026-10-18T08:53:38.237Z",codex-agent,"Shared-host load exceeded 23 runnable tasks for four available CPUs. The incomplete local npm gate was stopped after passing initial gates and progressing integration cases; it is not a passing gate receipt. Both exact release commands now run on hosted runners via a temporary validation branch, whose checkout explicitly selects source commit 9fdc0fc583c02dba9a25bd9c1f362678f75e4760. The validation-only workflow stays outside the PR source. npm and Bun use fresh HOME and disabled global/system Git identity, with unchanged gate thresholds. Full receipts will be recorded after completion." + "2026-10-18T09:07:14.916Z",codex-agent,"Completed exact gates on source 9fdc0fc583c02dba9a25bd9c1f362678f75e4760 with fresh HOME and global/system Git identity disabled: npm run release:check passes 864/864 (https://github.com/unbraind/pm-github/actions/runs/39113186520/job/117633459391); bun run release:check passes 864/864 (https://github.com/unbraind/pm-github/actions/runs/39113186520/job/117633459200). Both report zero failures, cancellations, skips or todos and exact 100/100/100/100 coverage for all 14 authored modules. Typecheck, build, docstrings, lint, unchanged duplication/privacy gates, production audit, package dry run, changelog check and publish attestation pass. Only tracker receipt updates follow this validated source. Releasing this claim without closing the item; final-head CI is monitored after push, and the README review thread receives the pushed SHA and test evidence. No PM CLI/SDK defect was encountered; host SDK skew is avoided by CI identity isolation." files[7]{path,scope}: .github/workflows/pm-github-closeout.yml,project .github/workflows/pm-github-sync.yml,project