Skip to content
Merged
9 changes: 9 additions & 0 deletions .agents/pm/history/pm-github-v2kt.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{"ts":"2026-08-10T15:27:52.482Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"535c4c4bbb093654ea2cf13c","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":null,"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-github-v2kt"},{"op":"add","path":"/metadata/title","value":"Fix release publish ordering ahead of protected main push"},{"op":"add","path":"/metadata/description","value":"The daily release workflow published to npm and then pushed the version bump straight to a protected main branch. Branch protection rejected that push with GH006, and the job's fail-fast shell mode killed it before the tag push, so npm ended up ahead of git: main stayed on an older version with no matching tag. The release metadata is now merged through a protected PR before npm publish runs, and only the release tag is pushed after a successful publish. Ported from the verified fix in pm-beads."},{"op":"add","path":"/metadata/type","value":"Issue"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":2},{"op":"add","path":"/metadata/tags","value":[]},{"op":"add","path":"/metadata/created_at","value":"2026-08-10T15:27:52.482Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-08-10T15:27:52.482Z"},{"op":"add","path":"/metadata/author","value":"pi-agent"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"f44791f47d30aed6d9a71f17d902212f1d835d3fd27d28ba1b63456dd0281231","message":""}
{"ts":"2026-08-10T15:27:52.883Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2:cloud","agent_model_source":"environment","agent_instance":"535c4c4bbb093654ea2cf13c","agent_provenance":{"model":{"value":"glm-5.2:cloud","source":"environment"},"effort":null,"role":null,"topic":null},"op":"note_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T15:27:52.883Z"},{"op":"add","path":"/metadata/notes","value":[{"created_at":"2026-08-10T15:27:52.883Z","author":"pi-agent","text":"Applied the pm-beads release ordering fix to .github/workflows/release.yml: added pull-requests write permission, captured base_sha in the decide step, and replaced the publish-then-push-to-main steps with a protected-PR merge, a verify-merged-release check, the npm publish (with idempotence guard), and a tag-only push. dist is gitignored here so it is excluded from the verify diff. Gates npm ci, build, test, release:check and yaml all pass."}]}],"before_hash":"f44791f47d30aed6d9a71f17d902212f1d835d3fd27d28ba1b63456dd0281231","after_hash":"4ca4b9a8e0a17de8ffa66feb82066420e4f8c2e7c002292248f3decbde5cc3fc"}
{"ts":"2026-08-10T15:30:44.660Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/1","value":{"created_at":"2026-08-10T15:30:44.660Z","author":"claude","text":"Greptile reported that creating the release pull request with GITHUB_TOKEN suppresses its pull_request event so CI never starts. Measured against pm-changelog, the event is not suppressed: a run was created at 04:54:24Z with event pull_request for branch release/2026.8.9. The real blocker is that attempt 1 concluded action_required, meaning GitHub parked the run awaiting workflow approval under the fork pull request contributor approval policy of first_time_contributors, because github-actions had no merged pull request in that repository yet. A parked run never appears in the status check rollup, so it is indistinguishable from a required check that failed. The merge wait now detects parked runs, reports the run URL, attempts approval using the actions write permission, and separates awaiting approval from a failed check in the deadline error."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T15:30:44.660Z"}],"before_hash":"4ca4b9a8e0a17de8ffa66feb82066420e4f8c2e7c002292248f3decbde5cc3fc","after_hash":"489e4f927f5a520731d4d3db368e9b51a39c3ff0343a479fbc9a294e99548eaf"}
{"ts":"2026-08-10T15:55:22.540Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/2","value":{"created_at":"2026-08-10T15:55:22.540Z","author":"claude","text":"Round two review fixes. CodeRabbit found that the Push release tag step consulted only the local tag database, while the last tag fetch happens back in Decide release, so a tag created on origin in between would be missed, git tag would succeed locally and the push would be rejected as non-fast-forward after a successful publish, which is exactly the npm ahead of git state this work removes. The step now fetches tags and compares against the remote tag target, exiting cleanly when the tag already points at the verified commit. CodeRabbit also found that the dist entry in the verification diff verified nothing, because nothing rebuilds before it so git diff compared dist against itself and always passed, and git diff cannot see untracked or orphaned artifacts. Where dist is tracked the step now rebuilds from clean and uses git status porcelain with untracked files included. Reproducibility was confirmed locally in every repository that tracks dist before shipping the check."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T15:55:22.540Z"}],"before_hash":"489e4f927f5a520731d4d3db368e9b51a39c3ff0343a479fbc9a294e99548eaf","after_hash":"d18bf7219a7db06356b24f76adfa5a43c63714e1f9fe8b0ccfb1c563e436c837"}
{"ts":"2026-08-10T16:03:35.223Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/3","value":{"created_at":"2026-08-10T16:03:35.223Z","author":"claude","text":"CodeRabbit found a security regression in the thread resolution I added. The loop resolved every unresolved review thread on the release pull request, which would also clear a human reviewer's blocking thread and remove exactly the protection required_conversation_resolution provides for release commits. The GraphQL query now selects the first comment's author type and only bot authored threads are resolved. The jq filter was verified against a sample payload containing one bot thread and one human thread, and it returned only the bot thread."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T16:03:35.223Z"}],"before_hash":"d18bf7219a7db06356b24f76adfa5a43c63714e1f9fe8b0ccfb1c563e436c837","after_hash":"2042d4ef91b97c5533970b13e101ea72b5bb5d1b5430fe11c41f1428dfeb0718"}
{"ts":"2026-08-10T16:14:01.418Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/4","value":{"created_at":"2026-08-10T16:14:01.418Z","author":"claude","text":"Round four review fixes. Greptile found that classifying a review thread by its first comment lets a bot opened thread with a substantive human reply be auto resolved, bypassing the human concern. A thread now counts as advisory only when every comment on it is bot authored, and threads with no comments are excluded. Verified against four thread shapes, all bot, bot then human, human only, and empty, selecting only the all bot thread. CodeRabbit found the dist rebuild check omitted ignored matching so newly generated ignored artifacts under dist would stay hidden."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T16:14:01.418Z"}],"before_hash":"2042d4ef91b97c5533970b13e101ea72b5bb5d1b5430fe11c41f1428dfeb0718","after_hash":"3c3705b49ccf9e87c5c38880c9f76b3a952bc615f9f98c5b67b43a33fad89a3b"}
{"ts":"2026-08-10T16:23:19.099Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/5","value":{"created_at":"2026-08-10T16:23:19.099Z","author":"claude","text":"Round five review fixes. CodeRabbit found that the tracking note claimed dist validation that pm-web's workflow did not actually contain. An audit showed seven repositories track dist but had no rebuild check, because the earlier patch keyed on a diff paths idiom those repositories do not use: pm-changelog, pm-context, pm-gantt-chart, pm-graph, pm-jira, pm-ops and pm-web. All seven now rebuild dist from clean and compare with git status including untracked and ignored files, and reproducibility was confirmed locally in each before enabling the check. Greptile found that fetching only the first hundred thread comments lets a human reply past that page escape the all bot predicate, so the filter now refuses to resolve any thread whose comment total exceeds the comments actually returned. Verified against a truncated thread with a total of one hundred fifty and two fetched nodes, which is correctly not resolved."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T16:23:19.099Z"}],"before_hash":"3c3705b49ccf9e87c5c38880c9f76b3a952bc615f9f98c5b67b43a33fad89a3b","after_hash":"9efe94e308a4cc092b2ee8bc790c2f8a59f3bb9925bfe2e5c5e54332972e336d"}
{"ts":"2026-08-10T16:41:09.417Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/6","value":{"created_at":"2026-08-10T16:41:09.417Z","author":"claude","text":"CodeRabbit reported that git ls-remote --tags returns both the tag object and its peeled commit for an annotated tag, so cut -f1 would yield two SHAs and git rev-list would fail. Tested against a real annotated tag pushed to a local bare remote. The peeled entry appears when ls-remote is called with no pattern or with a glob, but NOT with the exact refspec form this workflow uses, which returned a single line. The finding therefore does not reproduce against our call. The suggested form was adopted anyway because it costs nothing, states the intent explicitly, and keeps the code correct if the pattern is ever loosened to a glob."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T16:41:09.417Z"}],"before_hash":"9efe94e308a4cc092b2ee8bc790c2f8a59f3bb9925bfe2e5c5e54332972e336d","after_hash":"3bfec546b57470fc9666cf1d55906411f8350b7988f4d966b0f8451e2e054341"}
{"ts":"2026-08-10T16:57:16.322Z","author":"claude","author_source":"asserted","agent_harness":"claude-code","agent_instance":"304c86ad9f9d7cbae7f44c3b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/7","value":{"created_at":"2026-08-10T16:57:16.322Z","author":"claude","text":"Round six follow up. CodeRabbit noted the parked run detection reads only the first page of the workflow runs endpoint, whose default page size is thirty, so a parked run past that page would go undetected. The query now requests one hundred per page. This is a diagnostic path rather than a safety one, since an undetected parked run simply means the release is not approved and times out without publishing, but the larger page costs nothing. Thread level pagination was declined separately because unfetched threads are never resolved and therefore keep blocking, which is the safe direction."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-10T16:57:16.322Z"}],"before_hash":"3bfec546b57470fc9666cf1d55906411f8350b7988f4d966b0f8451e2e054341","after_hash":"ccb2819974d107822f82a38d930bb36e486d490bb0ed619c32057eb6e86bf0bb"}
20 changes: 20 additions & 0 deletions .agents/pm/issues/pm-github-v2kt.toon
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
id: pm-github-v2kt
title: Fix release publish ordering ahead of protected main push
description: "The daily release workflow published to npm and then pushed the version bump straight to a protected main branch. Branch protection rejected that push with GH006, and the job's fail-fast shell mode killed it before the tag push, so npm ended up ahead of git: main stayed on an older version with no matching tag. The release metadata is now merged through a protected PR before npm publish runs, and only the release tag is pushed after a successful publish. Ported from the verified fix in pm-beads."
type: Issue
status: open
priority: 2
tags: []
created_at: "2026-08-10T15:27:52.482Z"
updated_at: "2026-08-10T16:57:16.322Z"
author: pi-agent
notes[8]{created_at,author,text}:
"2026-08-10T15:27:52.883Z",pi-agent,"Applied the pm-beads release ordering fix to .github/workflows/release.yml: added pull-requests write permission, captured base_sha in the decide step, and replaced the publish-then-push-to-main steps with a protected-PR merge, a verify-merged-release check, the npm publish (with idempotence guard), and a tag-only push. dist is gitignored here so it is excluded from the verify diff. Gates npm ci, build, test, release:check and yaml all pass."
"2026-08-10T15:30:44.660Z",claude,"Greptile reported that creating the release pull request with GITHUB_TOKEN suppresses its pull_request event so CI never starts. Measured against pm-changelog, the event is not suppressed: a run was created at 04:54:24Z with event pull_request for branch release/2026.8.9. The real blocker is that attempt 1 concluded action_required, meaning GitHub parked the run awaiting workflow approval under the fork pull request contributor approval policy of first_time_contributors, because github-actions had no merged pull request in that repository yet. A parked run never appears in the status check rollup, so it is indistinguishable from a required check that failed. The merge wait now detects parked runs, reports the run URL, attempts approval using the actions write permission, and separates awaiting approval from a failed check in the deadline error."
"2026-08-10T15:55:22.540Z",claude,"Round two review fixes. CodeRabbit found that the Push release tag step consulted only the local tag database, while the last tag fetch happens back in Decide release, so a tag created on origin in between would be missed, git tag would succeed locally and the push would be rejected as non-fast-forward after a successful publish, which is exactly the npm ahead of git state this work removes. The step now fetches tags and compares against the remote tag target, exiting cleanly when the tag already points at the verified commit. CodeRabbit also found that the dist entry in the verification diff verified nothing, because nothing rebuilds before it so git diff compared dist against itself and always passed, and git diff cannot see untracked or orphaned artifacts. Where dist is tracked the step now rebuilds from clean and uses git status porcelain with untracked files included. Reproducibility was confirmed locally in every repository that tracks dist before shipping the check."
"2026-08-10T16:03:35.223Z",claude,"CodeRabbit found a security regression in the thread resolution I added. The loop resolved every unresolved review thread on the release pull request, which would also clear a human reviewer's blocking thread and remove exactly the protection required_conversation_resolution provides for release commits. The GraphQL query now selects the first comment's author type and only bot authored threads are resolved. The jq filter was verified against a sample payload containing one bot thread and one human thread, and it returned only the bot thread."
"2026-08-10T16:14:01.418Z",claude,"Round four review fixes. Greptile found that classifying a review thread by its first comment lets a bot opened thread with a substantive human reply be auto resolved, bypassing the human concern. A thread now counts as advisory only when every comment on it is bot authored, and threads with no comments are excluded. Verified against four thread shapes, all bot, bot then human, human only, and empty, selecting only the all bot thread. CodeRabbit found the dist rebuild check omitted ignored matching so newly generated ignored artifacts under dist would stay hidden."
"2026-08-10T16:23:19.099Z",claude,"Round five review fixes. CodeRabbit found that the tracking note claimed dist validation that pm-web's workflow did not actually contain. An audit showed seven repositories track dist but had no rebuild check, because the earlier patch keyed on a diff paths idiom those repositories do not use: pm-changelog, pm-context, pm-gantt-chart, pm-graph, pm-jira, pm-ops and pm-web. All seven now rebuild dist from clean and compare with git status including untracked and ignored files, and reproducibility was confirmed locally in each before enabling the check. Greptile found that fetching only the first hundred thread comments lets a human reply past that page escape the all bot predicate, so the filter now refuses to resolve any thread whose comment total exceeds the comments actually returned. Verified against a truncated thread with a total of one hundred fifty and two fetched nodes, which is correctly not resolved."
"2026-08-10T16:41:09.417Z",claude,"CodeRabbit reported that git ls-remote --tags returns both the tag object and its peeled commit for an annotated tag, so cut -f1 would yield two SHAs and git rev-list would fail. Tested against a real annotated tag pushed to a local bare remote. The peeled entry appears when ls-remote is called with no pattern or with a glob, but NOT with the exact refspec form this workflow uses, which returned a single line. The finding therefore does not reproduce against our call. The suggested form was adopted anyway because it costs nothing, states the intent explicitly, and keeps the code correct if the pattern is ever loosened to a glob."
"2026-08-10T16:57:16.322Z",claude,"Round six follow up. CodeRabbit noted the parked run detection reads only the first page of the workflow runs endpoint, whose default page size is thirty, so a parked run past that page would go undetected. The query now requests one hundred per page. This is a diagnostic path rather than a safety one, since an undetected parked run simply means the release is not approved and times out without publishing, but the larger page costs nothing. Thread level pagination was declined separately because unfetched threads are never resolved and therefore keep blocking, which is the safe direction."
body: ""
Loading