From f9080aca2e09d2070577dbbfe3ebd4f05e180710 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:00:23 +0200 Subject: [PATCH 1/5] Gate CI on pm health to block silently discarded peer edits Add a CI step that runs `./node_modules/.bin/pm health --strict-exit` immediately after `npm ci`. When two agents edit the same scalar field of one pm item on two branches, the field-aware merge driver picks a winner and records the loser in a clone-local receipt. The merged `.toon` has no conflict markers and is valid TOON already holding the winning value, yet git still marks the path `UU`. The standard resolution idiom (`git add` the marker-free file, then commit) then succeeds and the peer agent's edit is gone, with no trace in any pushed artifact. `pm validate` returns ok:true on that result because the file really is valid TOON, so it cannot gate this. Only `pm health` goes red, via integrity.counts.pending_merge_decisions, naming the affected items in integrity.details.pending_merge_decision_items. `--strict-exit` is load-bearing: a bare `pm health` exits 0 even when ok:false. A fresh runner checkout has no merge drivers installed, which is a warn rather than a failure, so the step does not need `pm merge install`. --- .agents/pm/chores/pm-linear-9848.toon | 15 +++++++++++++++ .agents/pm/history/pm-linear-9848.jsonl | 2 ++ .github/workflows/ci.yml | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 .agents/pm/chores/pm-linear-9848.toon create mode 100644 .agents/pm/history/pm-linear-9848.jsonl diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon new file mode 100644 index 0000000..4cf0f67 --- /dev/null +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -0,0 +1,15 @@ +id: pm-linear-9848 +title: Gate CI on pm health so a silently discarded peer edit cannot merge +description: "" +type: Chore +status: closed +priority: 2 +tags: [] +created_at: "2026-08-06T20:46:45.382Z" +updated_at: "2026-08-06T20:47:03.390Z" +closed_at: "2026-08-06T20:47:03.366Z" +completed_at: "2026-08-06T20:47:03.366Z" +author: pi-agent +acceptance_criteria: "CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build" +close_reason: Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit. +body: "" diff --git a/.agents/pm/history/pm-linear-9848.jsonl b/.agents/pm/history/pm-linear-9848.jsonl new file mode 100644 index 0000000..2b3d6e3 --- /dev/null +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -0,0 +1,2 @@ +{"ts":"2026-08-06T20:46:45.382Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-linear-9848"},{"op":"add","path":"/metadata/title","value":"Gate CI on pm health so a silently discarded peer edit cannot merge"},{"op":"add","path":"/metadata/description","value":""},{"op":"add","path":"/metadata/type","value":"Chore"},{"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-06T20:46:45.382Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-08-06T20:46:45.382Z"},{"op":"add","path":"/metadata/author","value":"pi-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","message":""} +{"ts":"2026-08-06T20:47:03.390Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T20:47:03.390Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/close_reason","value":"Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit."}],"before_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","after_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68"} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbad742..60caa8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,24 @@ jobs: - name: Install dependencies run: npm ci + - name: Verify pm project integrity and merge safety + shell: bash + run: | + set -euo pipefail + # `pm validate` is deliberately NOT the command here. After a same-field merge + # conflict the field-aware driver writes a marker-free .toon that already holds + # the winning value and records the discarded peer value in a clone-local + # receipt. That file is valid TOON, so `pm validate` returns ok:true while + # another agent's edit has been silently dropped. `pm health` is the only + # surface that goes red, via integrity.counts.pending_merge_decisions. + # + # --strict-exit is load-bearing: a bare `pm health` exits 0 EVEN WHEN ok:false, + # so without this flag the step is a no-op that always passes. + # + # A fresh runner checkout has no merge drivers installed. That is a warn, not a + # failure (upstream GH-815), so this gate does not need `pm merge install`. + ./node_modules/.bin/pm health --strict-exit + - name: Type check run: npm run typecheck From efcef76e68ae2372575107392517fe5ef9fe4b92 Mon Sep 17 00:00:00 2001 From: SteveBot <1153461+unbraind@users.noreply.github.com> Date: Thu, 6 Aug 2026 23:28:27 +0200 Subject: [PATCH 2/5] Correct the gate's claim: it does not catch discarded peer edits The step and its tracker item both said this gate blocks a merge that silently discarded a peer agent's edit. Verified today that it does not, and cannot as built: merge-decision receipts live in .agents/pm/runtime/, which pm init gitignores, so they are never pushed. On the same commit, the merge-performing clone reports one receipt and exits 1, while a fresh clone - which is what CI checks out - reports zero and exits 0. The pushed history does not disambiguate it either. Both writes are present in timestamp order and the item matches the latest, so history verification reports ok. Filed upstream as unbraind/pm-cli#922; flagged first by Greptile on every PR in this rollout. The step is kept, because what it does catch is real and CI-observable: conflict markers in item and history files, parse failures, invalid history JSON, hash drift, unknown-author events, stale in-progress work and tracked runtime cache files. Only the overstated claim is removed. A gate whose documentation promises more than it delivers is worse than no gate, because it stops people looking for the hazard it does not cover. --- .agents/pm/chores/pm-linear-9848.toon | 6 ++++-- .agents/pm/history/pm-linear-9848.jsonl | 2 ++ .github/workflows/ci.yml | 24 +++++++++++++++++------- CHANGELOG.md | 6 ++++++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon index 4cf0f67..e2b7c60 100644 --- a/.agents/pm/chores/pm-linear-9848.toon +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -1,15 +1,17 @@ id: pm-linear-9848 -title: Gate CI on pm health so a silently discarded peer edit cannot merge +title: "Gate CI on pm health for tracker integrity (does not cover discarded peer edits, see pm-cli 922)" description: "" type: Chore status: closed priority: 2 tags: [] created_at: "2026-08-06T20:46:45.382Z" -updated_at: "2026-08-06T20:47:03.390Z" +updated_at: "2026-08-06T21:27:22.151Z" closed_at: "2026-08-06T20:47:03.366Z" completed_at: "2026-08-06T20:47:03.366Z" author: pi-agent acceptance_criteria: "CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build" +notes[1]{created_at,author,text}: + "2026-08-06T21:27:21.498Z","harness:claude-code","CORRECTION 2026-08-06, verified directly rather than reasoned about. This item's original close reason overstated what the gate does, and the CI comment has been rewritten to match reality.\n\nWHAT WAS WRONG. The gate was described as blocking a silently discarded peer edit. It does not, and cannot as currently built. Merge-decision receipts are written to .agents/pm/runtime/, which pm init itself gitignores, so they are never pushed. Measured on the same commit: the clone that performed the merge reports 1 receipt and the strict health check exits 1, while a fresh clone of that exact commit reports 0 receipts and the strict health check exits 0. CI checks out the fresh state, so the discarded edit passes.\n\nTHE PUSHED HISTORY DOES NOT DISAMBIGUATE IT EITHER. The merged history stream contains both writes in timestamp order and the item matches the latest one, so history verification reports current_matches_latest true with matching hashes. From pushed state alone, two concurrent branch edits where one was discarded look exactly like two sequential edits where the second superseded the first.\n\nRECONCILE PUBLISHES THE EVIDENCE BUT DOES NOT MAKE IT GATEABLE. Running merge reconcile appends a merge_reconcile event into tracked history carrying conflict_fields, retained_hash and discarded_hash, so durable evidence can exist. But the strict health check then exits 0 in both clones, and reconcile is optional anyway. There is no configuration in which CI observes the loss.\n\nCREDIT. Greptile flagged this as P1 on every gate PR in the rollout before it merged. Verified independently and filed upstream as pm-cli 922.\n\nWHAT THE GATE ACTUALLY DOES, all observable in a fresh checkout and all worth gating on: conflict markers left in item or history files, item parse failures, invalid history JSON, history hash drift, unknown-author history events, stale in-progress work, and tracked runtime cache files. The strict-exit flag remains load-bearing because a bare health check exits 0 even when not ok.\n\nThe step is kept for that real value. Only the claim was wrong, and a gate whose documentation overstates its guarantee is worse than no gate because it stops people looking for the real hazard." close_reason: Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit. body: "" diff --git a/.agents/pm/history/pm-linear-9848.jsonl b/.agents/pm/history/pm-linear-9848.jsonl index 2b3d6e3..ef9c01b 100644 --- a/.agents/pm/history/pm-linear-9848.jsonl +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -1,2 +1,4 @@ {"ts":"2026-08-06T20:46:45.382Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-linear-9848"},{"op":"add","path":"/metadata/title","value":"Gate CI on pm health so a silently discarded peer edit cannot merge"},{"op":"add","path":"/metadata/description","value":""},{"op":"add","path":"/metadata/type","value":"Chore"},{"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-06T20:46:45.382Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-08-06T20:46:45.382Z"},{"op":"add","path":"/metadata/author","value":"pi-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","message":""} {"ts":"2026-08-06T20:47:03.390Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T20:47:03.390Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/close_reason","value":"Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit."}],"before_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","after_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68"} +{"ts":"2026-08-06T21:27:21.498Z","author":"harness:claude-code","author_source":"asserted","agent_harness":"claude-code","agent_instance":"db7a36e250bba74236c8424b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"note_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:27:21.498Z"},{"op":"add","path":"/metadata/notes","value":[{"created_at":"2026-08-06T21:27:21.498Z","author":"harness:claude-code","text":"CORRECTION 2026-08-06, verified directly rather than reasoned about. This item's original close reason overstated what the gate does, and the CI comment has been rewritten to match reality.\n\nWHAT WAS WRONG. The gate was described as blocking a silently discarded peer edit. It does not, and cannot as currently built. Merge-decision receipts are written to .agents/pm/runtime/, which pm init itself gitignores, so they are never pushed. Measured on the same commit: the clone that performed the merge reports 1 receipt and the strict health check exits 1, while a fresh clone of that exact commit reports 0 receipts and the strict health check exits 0. CI checks out the fresh state, so the discarded edit passes.\n\nTHE PUSHED HISTORY DOES NOT DISAMBIGUATE IT EITHER. The merged history stream contains both writes in timestamp order and the item matches the latest one, so history verification reports current_matches_latest true with matching hashes. From pushed state alone, two concurrent branch edits where one was discarded look exactly like two sequential edits where the second superseded the first.\n\nRECONCILE PUBLISHES THE EVIDENCE BUT DOES NOT MAKE IT GATEABLE. Running merge reconcile appends a merge_reconcile event into tracked history carrying conflict_fields, retained_hash and discarded_hash, so durable evidence can exist. But the strict health check then exits 0 in both clones, and reconcile is optional anyway. There is no configuration in which CI observes the loss.\n\nCREDIT. Greptile flagged this as P1 on every gate PR in the rollout before it merged. Verified independently and filed upstream as pm-cli 922.\n\nWHAT THE GATE ACTUALLY DOES, all observable in a fresh checkout and all worth gating on: conflict markers left in item or history files, item parse failures, invalid history JSON, history hash drift, unknown-author history events, stale in-progress work, and tracked runtime cache files. The strict-exit flag remains load-bearing because a bare health check exits 0 even when not ok.\n\nThe step is kept for that real value. Only the claim was wrong, and a gate whose documentation overstates its guarantee is worse than no gate because it stops people looking for the real hazard."}]}],"before_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68","after_hash":"10870373e39563d873d52ac97982697186a817d7e913d504895cd895743f7efc"} +{"ts":"2026-08-06T21:27:22.151Z","author":"harness:claude-code","author_source":"asserted","agent_harness":"claude-code","agent_instance":"db7a36e250bba74236c8424b","agent_provenance":{"model":null,"effort":{"value":"xhigh","source":"environment"},"role":{"value":"1","source":"environment"},"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:27:22.151Z"},{"op":"replace","path":"/metadata/title","value":"Gate CI on pm health for tracker integrity (does not cover discarded peer edits, see pm-cli 922)"}],"before_hash":"10870373e39563d873d52ac97982697186a817d7e913d504895cd895743f7efc","after_hash":"065c4fcc2cce4007d6ad61174a083157742dd38cda961bbb89091fcd44d99c28"} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60caa8a..0af2413 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,16 +37,26 @@ jobs: - name: Install dependencies run: npm ci - - name: Verify pm project integrity and merge safety + - name: Verify pm tracker integrity shell: bash run: | set -euo pipefail - # `pm validate` is deliberately NOT the command here. After a same-field merge - # conflict the field-aware driver writes a marker-free .toon that already holds - # the winning value and records the discarded peer value in a clone-local - # receipt. That file is valid TOON, so `pm validate` returns ok:true while - # another agent's edit has been silently dropped. `pm health` is the only - # surface that goes red, via integrity.counts.pending_merge_decisions. + # WHAT THIS CATCHES, all visible in a fresh checkout: conflict markers left in + # item or history files, item parse failures, invalid history JSON, history hash + # drift, unknown-author history events, stale in-progress work, and tracked + # runtime cache files. + # + # WHAT THIS DOES NOT CATCH - stated explicitly so nobody relies on it. It does + # NOT detect a merge that silently discarded a peer agent's edit. When two + # branches edit the same scalar field, the field-aware driver keeps one value and + # records the discarded one in a merge receipt under .agents/pm/runtime/, which + # `pm init` gitignores, so the receipt is never pushed. A fresh checkout of that + # commit reports zero pending decisions and this step exits 0 - verified + # directly, not assumed. The pushed history does not disambiguate it either: + # both writes are present in timestamp order and the item matches the latest, so + # `pm history --verify` reports ok too. Tracked upstream as + # unbraind/pm-cli#922. Do not add a comment here claiming merge safety until + # that is closed. # # --strict-exit is load-bearing: a bare `pm health` exits 0 EVEN WHEN ok:false, # so without this flag the step is a no-op that always passes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 836ad5b..cb5a93b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Other + +- Gate CI on pm health for tracker integrity (does not cover discarded peer edits, see pm-cli 922) ([pm-linear-9848](https://github.com/unbraind/pm-linear/blob/main/.agents/pm/chores/pm-linear-9848.toon)) + ## 2026.8.4 - 2026-08-04 ### Other From 1e958aa7b3da7fc7922d85708f0ffef9a2e2a28b Mon Sep 17 00:00:00 2001 From: Stefan Preu Date: Thu, 6 Aug 2026 23:52:08 +0200 Subject: [PATCH 3/5] fix(ci): scope pm health gate to durable tracker state --- .agents/pm/chores/pm-linear-9848.toon | 23 ++++++++++++++++++----- .agents/pm/history/pm-linear-9848.jsonl | 2 ++ .github/workflows/ci.yml | 21 +++++++++------------ CHANGELOG.md | 6 ++++++ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon index 4cf0f67..6ae79f2 100644 --- a/.agents/pm/chores/pm-linear-9848.toon +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -1,15 +1,28 @@ id: pm-linear-9848 -title: Gate CI on pm health so a silently discarded peer edit cannot merge -description: "" +title: Gate CI on strict tracked pm project health +description: "Run pm health --strict-exit in CI to reject durable tracker-health failures. The fresh runner cannot inspect clone-local merge receipts; pm-cli#921 tracks the remaining attestation gap, so receipt reconciliation stays a local pre-push responsibility." type: Chore status: closed priority: 2 tags: [] created_at: "2026-08-06T20:46:45.382Z" -updated_at: "2026-08-06T20:47:03.390Z" +updated_at: "2026-08-06T21:50:59.633Z" closed_at: "2026-08-06T20:47:03.366Z" completed_at: "2026-08-06T20:47:03.366Z" author: pi-agent -acceptance_criteria: "CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build" -close_reason: Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit. +acceptance_criteria: "CI runs pm health --strict-exit immediately after dependency installation; clean durable repository state exits 0; tracked history, attribution, cache, extension, or available merge-evidence failures block CI; documentation does not claim fresh CI can inspect clone-local receipts" +resolution: Added a strict tracked-state health gate and corrected the merge-safety boundary after exact reviewer feedback. +expected_result: CI rejects durable pm project-health failures without overstating coverage of clone-local merge receipts. +actual_result: "Package health passes locally. Published pm 2026.8.6 black-box proof showed pending receipts disappear in a fresh clone, durable history drift blocks the unrepaired merge, and history-repair can erase that last CI signal; upstream pm-cli#921 records the gap." +notes[1]{created_at,author,text}: + "2026-08-06T21:21:15.836Z",codex,"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee." +tests[2]: + - command: "npm run release:check" + scope: project + - command: pm health --strict-exit + scope: project + timeout_seconds: 120 +docs[1]{path,scope,note}: + "https://github.com/unbraind/pm-cli/issues/921",global,upstream durable merge-attestation gap +close_reason: "Added the CI tracked-state health gate, corrected workflow and changelog language after Greptile identified the fresh-clone receipt boundary, retained local receipt reconciliation as a pre-push requirement, and filed pm-cli#921 with 2026.8.6 black-box evidence." body: "" diff --git a/.agents/pm/history/pm-linear-9848.jsonl b/.agents/pm/history/pm-linear-9848.jsonl index 2b3d6e3..4342d33 100644 --- a/.agents/pm/history/pm-linear-9848.jsonl +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -1,2 +1,4 @@ {"ts":"2026-08-06T20:46:45.382Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-linear-9848"},{"op":"add","path":"/metadata/title","value":"Gate CI on pm health so a silently discarded peer edit cannot merge"},{"op":"add","path":"/metadata/description","value":""},{"op":"add","path":"/metadata/type","value":"Chore"},{"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-06T20:46:45.382Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-08-06T20:46:45.382Z"},{"op":"add","path":"/metadata/author","value":"pi-agent"},{"op":"add","path":"/metadata/acceptance_criteria","value":"CI runs the pm health command with the strict-exit flag immediately after npm ci; the gate uses pm health rather than pm validate, because pm validate returns ok:true after a same-field merge silently discards a peer edit; the strict-exit flag is present so an ok:false health result fails the build"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","message":""} {"ts":"2026-08-06T20:47:03.390Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T20:47:03.390Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/close_reason","value":"Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit."}],"before_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","after_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68"} +{"ts":"2026-08-06T21:21:15.856Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/close_reason","value":"Added the CI tracked-state health gate, corrected workflow and changelog language after Greptile identified the fresh-clone receipt boundary, retained local receipt reconciliation as a pre-push requirement, and filed pm-cli#921 with 2026.8.6 black-box evidence."},{"op":"replace","path":"/metadata/acceptance_criteria","value":"CI runs pm health --strict-exit immediately after dependency installation; clean durable repository state exits 0; tracked history, attribution, cache, extension, or available merge-evidence failures block CI; documentation does not claim fresh CI can inspect clone-local receipts"},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:21:15.856Z"},{"op":"replace","path":"/metadata/description","value":"Run pm health --strict-exit in CI to reject durable tracker-health failures. The fresh runner cannot inspect clone-local merge receipts; pm-cli#921 tracks the remaining attestation gap, so receipt reconciliation stays a local pre-push responsibility."},{"op":"replace","path":"/metadata/title","value":"Gate CI on strict tracked pm project health"},{"op":"add","path":"/metadata/resolution","value":"Added a strict tracked-state health gate and corrected the merge-safety boundary after exact reviewer feedback."},{"op":"add","path":"/metadata/expected_result","value":"CI rejects durable pm project-health failures without overstating coverage of clone-local merge receipts."},{"op":"add","path":"/metadata/actual_result","value":"Package health passes locally. Published pm 2026.8.6 black-box proof showed pending receipts disappear in a fresh clone, durable history drift blocks the unrepaired merge, and history-repair can erase that last CI signal; upstream pm-cli#921 records the gap."},{"op":"add","path":"/metadata/notes","value":[{"created_at":"2026-08-06T21:21:15.836Z","author":"codex","text":"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee."}]},{"op":"add","path":"/metadata/tests","value":[{"command":"pm health --strict-exit","scope":"project","timeout_seconds":120}]},{"op":"add","path":"/metadata/docs","value":[{"path":"https://github.com/unbraind/pm-cli/issues/921","scope":"global","note":"upstream durable merge-attestation gap"}]}],"before_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68","after_hash":"58d9c7b34aefdaea308af1ee90eedb6dccf244f3f8db6e85c69daf21bcb19e04","message":"Correct the CI gate contract after fresh-clone black-box proof"} +{"ts":"2026-08-06T21:50:59.633Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"tests_add","patch":[{"op":"remove","path":"/metadata/tests/0/timeout_seconds"},{"op":"replace","path":"/metadata/tests/0/command","value":"npm run release:check"},{"op":"add","path":"/metadata/tests/1","value":{"command":"pm health --strict-exit","scope":"project","timeout_seconds":120}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:50:59.633Z"}],"before_hash":"58d9c7b34aefdaea308af1ee90eedb6dccf244f3f8db6e85c69daf21bcb19e04","after_hash":"a9c161d79eb65d6df9b0c0601800f95ef1d97222834e616dc724e794fb6f2118"} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60caa8a..9a84b46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,22 +37,19 @@ jobs: - name: Install dependencies run: npm ci - - name: Verify pm project integrity and merge safety + - name: Verify tracked pm project health shell: bash run: | set -euo pipefail - # `pm validate` is deliberately NOT the command here. After a same-field merge - # conflict the field-aware driver writes a marker-free .toon that already holds - # the winning value and records the discarded peer value in a clone-local - # receipt. That file is valid TOON, so `pm validate` returns ok:true while - # another agent's edit has been silently dropped. `pm health` is the only - # surface that goes red, via integrity.counts.pending_merge_decisions. + # Gate durable workspace health: history integrity, attribution, tracked caches, + # extension state, and any merge evidence that exists in this checkout. + # `--strict-exit` is required because non-strict health reports findings without + # necessarily failing the shell command. # - # --strict-exit is load-bearing: a bare `pm health` exits 0 EVEN WHEN ok:false, - # so without this flag the step is a no-op that always passes. - # - # A fresh runner checkout has no merge drivers installed. That is a warn, not a - # failure (upstream GH-815), so this gate does not need `pm merge install`. + # This fresh checkout cannot inspect clone-local merge receipts. It can catch an + # unreconciled lossy merge through tracked history drift, but pm-cli#921 documents + # a repair path that can erase that signal. Receipt reconciliation remains a local + # pre-push responsibility until pm provides durable CI-verifiable attestation. ./node_modules/.bin/pm health --strict-exit - name: Type check diff --git a/CHANGELOG.md b/CHANGELOG.md index 836ad5b..5b3a646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Other + +- Gate CI on strict tracked pm project health ([pm-linear-9848](https://github.com/unbraind/pm-linear/blob/main/.agents/pm/chores/pm-linear-9848.toon)) + ## 2026.8.4 - 2026-08-04 ### Other From ba36bd7289603457f8e4e31b3efecd3df59783ef Mon Sep 17 00:00:00 2001 From: Stefan Preu Date: Fri, 7 Aug 2026 00:04:57 +0200 Subject: [PATCH 4/5] chore(deps): validate gates with pm 2026.8.6 --- .agents/pm/chores/pm-linear-9848.toon | 9 +- .agents/pm/history/pm-linear-9848.jsonl | 2 + .gitattributes | 2 + package-lock.json | 167 +++++++++++++++++------- package.json | 4 +- 5 files changed, 130 insertions(+), 54 deletions(-) diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon index 6ae79f2..5637d7c 100644 --- a/.agents/pm/chores/pm-linear-9848.toon +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -6,7 +6,7 @@ status: closed priority: 2 tags: [] created_at: "2026-08-06T20:46:45.382Z" -updated_at: "2026-08-06T21:50:59.633Z" +updated_at: "2026-08-06T22:00:34.126Z" closed_at: "2026-08-06T20:47:03.366Z" completed_at: "2026-08-06T20:47:03.366Z" author: pi-agent @@ -14,8 +14,13 @@ acceptance_criteria: "CI runs pm health --strict-exit immediately after dependen resolution: Added a strict tracked-state health gate and corrected the merge-safety boundary after exact reviewer feedback. expected_result: CI rejects durable pm project-health failures without overstating coverage of clone-local merge receipts. actual_result: "Package health passes locally. Published pm 2026.8.6 black-box proof showed pending receipts disappear in a fresh clone, durable history drift blocks the unrepaired merge, and history-repair can erase that last CI signal; upstream pm-cli#921 records the gap." -notes[1]{created_at,author,text}: +notes[2]{created_at,author,text}: "2026-08-06T21:21:15.836Z",codex,"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee." + "2026-08-06T22:00:34.125Z",codex,"Refreshed the package's development/runtime lock projection to @unbrained/pm-cli 2026.8.6 and pm-changelog 2026.8.6 where applicable, so the health and changelog gates execute against the current published contracts. Existing peer minima remain compatibility claims, not the tested tool version." +files[3]{path,scope}: + .gitattributes,project + package-lock.json,project + package.json,project tests[2]: - command: "npm run release:check" scope: project diff --git a/.agents/pm/history/pm-linear-9848.jsonl b/.agents/pm/history/pm-linear-9848.jsonl index 4342d33..08ef795 100644 --- a/.agents/pm/history/pm-linear-9848.jsonl +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -2,3 +2,5 @@ {"ts":"2026-08-06T20:47:03.390Z","author":"pi-agent","author_source":"asserted","agent_harness":"pi","agent_model":"glm-5.2","agent_model_source":"environment","agent_instance":"d3caddd5ad2246337c1689d0","agent_provenance":{"model":{"value":"glm-5.2","source":"environment"},"effort":null,"role":null,"topic":null},"op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T20:47:03.390Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/closed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/completed_at","value":"2026-08-06T20:47:03.366Z"},{"op":"add","path":"/metadata/close_reason","value":"Added the pm health strict-exit CI step immediately after Install dependencies. Verified the gate exits 0 on a clean tree and exits 1 naming the affected item under pending_merge_decision_items on a reproduced same-field merge that discarded a peer title edit."}],"before_hash":"4dbc190058ae7e0ed9cc3b37807ae8ae03dd7c5ba1b6d46f1eb885b7e98e3cd6","after_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68"} {"ts":"2026-08-06T21:21:15.856Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/close_reason","value":"Added the CI tracked-state health gate, corrected workflow and changelog language after Greptile identified the fresh-clone receipt boundary, retained local receipt reconciliation as a pre-push requirement, and filed pm-cli#921 with 2026.8.6 black-box evidence."},{"op":"replace","path":"/metadata/acceptance_criteria","value":"CI runs pm health --strict-exit immediately after dependency installation; clean durable repository state exits 0; tracked history, attribution, cache, extension, or available merge-evidence failures block CI; documentation does not claim fresh CI can inspect clone-local receipts"},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:21:15.856Z"},{"op":"replace","path":"/metadata/description","value":"Run pm health --strict-exit in CI to reject durable tracker-health failures. The fresh runner cannot inspect clone-local merge receipts; pm-cli#921 tracks the remaining attestation gap, so receipt reconciliation stays a local pre-push responsibility."},{"op":"replace","path":"/metadata/title","value":"Gate CI on strict tracked pm project health"},{"op":"add","path":"/metadata/resolution","value":"Added a strict tracked-state health gate and corrected the merge-safety boundary after exact reviewer feedback."},{"op":"add","path":"/metadata/expected_result","value":"CI rejects durable pm project-health failures without overstating coverage of clone-local merge receipts."},{"op":"add","path":"/metadata/actual_result","value":"Package health passes locally. Published pm 2026.8.6 black-box proof showed pending receipts disappear in a fresh clone, durable history drift blocks the unrepaired merge, and history-repair can erase that last CI signal; upstream pm-cli#921 records the gap."},{"op":"add","path":"/metadata/notes","value":[{"created_at":"2026-08-06T21:21:15.836Z","author":"codex","text":"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee."}]},{"op":"add","path":"/metadata/tests","value":[{"command":"pm health --strict-exit","scope":"project","timeout_seconds":120}]},{"op":"add","path":"/metadata/docs","value":[{"path":"https://github.com/unbraind/pm-cli/issues/921","scope":"global","note":"upstream durable merge-attestation gap"}]}],"before_hash":"5edbf75155c19b606849bcceb5c2c4be023ca09f879eb7864d08afd7df1a7c68","after_hash":"58d9c7b34aefdaea308af1ee90eedb6dccf244f3f8db6e85c69daf21bcb19e04","message":"Correct the CI gate contract after fresh-clone black-box proof"} {"ts":"2026-08-06T21:50:59.633Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"tests_add","patch":[{"op":"remove","path":"/metadata/tests/0/timeout_seconds"},{"op":"replace","path":"/metadata/tests/0/command","value":"npm run release:check"},{"op":"add","path":"/metadata/tests/1","value":{"command":"pm health --strict-exit","scope":"project","timeout_seconds":120}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T21:50:59.633Z"}],"before_hash":"58d9c7b34aefdaea308af1ee90eedb6dccf244f3f8db6e85c69daf21bcb19e04","after_hash":"a9c161d79eb65d6df9b0c0601800f95ef1d97222834e616dc724e794fb6f2118"} +{"ts":"2026-08-06T22:00:33.677Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:00:33.677Z"},{"op":"add","path":"/metadata/files","value":[{"path":".gitattributes","scope":"project"},{"path":"package-lock.json","scope":"project"},{"path":"package.json","scope":"project"}]}],"before_hash":"a9c161d79eb65d6df9b0c0601800f95ef1d97222834e616dc724e794fb6f2118","after_hash":"bf51d308a7d2870d6958952ca08b4159f95e58b391079a5ba17d81c81191cca0"} +{"ts":"2026-08-06T22:00:34.126Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/1","value":{"created_at":"2026-08-06T22:00:34.125Z","author":"codex","text":"Refreshed the package's development/runtime lock projection to @unbrained/pm-cli 2026.8.6 and pm-changelog 2026.8.6 where applicable, so the health and changelog gates execute against the current published contracts. Existing peer minima remain compatibility claims, not the tested tool version."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:00:34.126Z"}],"before_hash":"bf51d308a7d2870d6958952ca08b4159f95e58b391079a5ba17d81c81191cca0","after_hash":"b2e8929b42cb8b6f1c0c49196ab30518662190d87f75707be80c32b5f8bb158e"} diff --git a/.gitattributes b/.gitattributes index c3e7c66..fe696ab 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,6 @@ # pm-cli:merge-drivers:start +".agents/pm/**/*.toon" merge=pm-item-toon +".agents/pm/**/*.md" merge=pm-item-markdown ".agents/pm/chores/*.toon" merge=pm-item-toon ".agents/pm/chores/*.md" merge=pm-item-markdown ".agents/pm/decisions/*.toon" merge=pm-item-toon diff --git a/package-lock.json b/package-lock.json index eb04123..723b234 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "license": "MIT", "devDependencies": { "@types/node": "^26.1.1", - "@unbrained/pm-cli": "^2026.7.29", - "pm-changelog": "^2026.7.25", + "@unbrained/pm-cli": "^2026.8.6", + "pm-changelog": "^2026.8.6", "typescript": "^7.0.2" }, "engines": { @@ -40,13 +40,13 @@ } }, "node_modules/@apm-js-collab/code-transformer-bundler-plugins": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.7.2.tgz", - "integrity": "sha512-GvpKWDmzBFzbtVElU+tEDMDYyMY8SnMH4NNwwlUQioNHZvE6sSuHEqNkfU3iYhWL+/XO5Ej+MzhVJoqM10NYCQ==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.7.4.tgz", + "integrity": "sha512-nAfOeZPSUAQvJa1iFT/5oCrTm5YQhMMrfCNthNnaXHZiOQhu1KGuLoIx7HtbAi3wfwaBYLaICPIeenIaEwcXIg==", "dev": true, "license": "MIT", "dependencies": { - "@apm-js-collab/code-transformer": "^0.18.0", + "@apm-js-collab/code-transformer": "^0.18.1", "es-module-lexer": "^2.1.0", "magic-string": "^0.30.21", "module-details-from-path": "^1.0.4" @@ -67,6 +67,19 @@ "module-details-from-path": "^1.0.4" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -244,9 +257,9 @@ } }, "node_modules/@sentry/core": { - "version": "10.67.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.67.0.tgz", - "integrity": "sha512-b6U3pJ8AUvN9aouq0vl+VZI8KT8RslBsfGMFuNwRr313zOmdmFJBZqTiUw9VGgJ2jGKxLO9alm9rlxBfX4hf+w==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.69.0.tgz", + "integrity": "sha512-+uuqVEeiDzYuAKjZLqsROKXvRTbl/QeH0gfGRtpYib1cud4rAFWRIkFmcR7Jb7JGFYwmReyQotiTj/hcDszTZg==", "dev": true, "license": "MIT", "dependencies": { @@ -257,9 +270,9 @@ } }, "node_modules/@sentry/node": { - "version": "10.67.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.67.0.tgz", - "integrity": "sha512-SFKpZGqOCEFSmP93NdDP6ikZp4NS7A/JR8+2ofK3jF6Y9Vyox7pX0pxdOnPLpFcPtMybMahfWqSAWJvsFs4RmA==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.69.0.tgz", + "integrity": "sha512-xEXA1YGIiTZbrW6MWV34uS6JGQuQg2ijTI0zed+FsJb9JZKPYel/GZK8Km26vfTVb+yCXFmWZNBesKegNcVdzg==", "dev": true, "license": "MIT", "dependencies": { @@ -267,10 +280,10 @@ "@opentelemetry/instrumentation": "^0.220.0", "@opentelemetry/sdk-trace-base": "^2.9.0", "@sentry/conventions": "^0.16.0", - "@sentry/core": "10.67.0", - "@sentry/node-core": "10.67.0", - "@sentry/opentelemetry": "10.67.0", - "@sentry/server-utils": "10.67.0", + "@sentry/core": "10.69.0", + "@sentry/node-core": "10.69.0", + "@sentry/opentelemetry": "10.69.0", + "@sentry/server-utils": "10.69.0", "import-in-the-middle": "^3.0.0" }, "engines": { @@ -278,15 +291,15 @@ } }, "node_modules/@sentry/node-core": { - "version": "10.67.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.67.0.tgz", - "integrity": "sha512-dBHHRwZyan1pOnFJ+sNBvR8TkXbZAfZU/jpxmALS3JZ2/8AGR7cQKL+b7SleKuJ7iUDZyklN3Nqi0i5JkcA+HA==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.69.0.tgz", + "integrity": "sha512-IgArHczrZJxkgxoffHscj0NxQrG6kCazgmGQnlf3j58J1ec21YaUu8Tu+7G4Lo5tCiW3teQnwlKW1ttMXSqWRw==", "dev": true, "license": "MIT", "dependencies": { "@sentry/conventions": "^0.16.0", - "@sentry/core": "10.67.0", - "@sentry/opentelemetry": "10.67.0", + "@sentry/core": "10.69.0", + "@sentry/opentelemetry": "10.69.0", "import-in-the-middle": "^3.0.0" }, "engines": { @@ -318,14 +331,14 @@ } }, "node_modules/@sentry/opentelemetry": { - "version": "10.67.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.67.0.tgz", - "integrity": "sha512-oLTOrAK1rOqmYRktOJZwz37B1seXPx1W2FTMVtzTVNjMFA/LZwGzePeZzhUOgzZgfLHixMd/ceWtGqoxAndcjQ==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.69.0.tgz", + "integrity": "sha512-3FyWV6YcEJuvLrlaKGE1dHXCI+1YO0a62w7PkwlRg8yp6K6YXkmdwu9GjqaYD+Ju4tm7uC7mHIsGFQMm0M7pqQ==", "dev": true, "license": "MIT", "dependencies": { "@sentry/conventions": "^0.16.0", - "@sentry/core": "10.67.0" + "@sentry/core": "10.69.0" }, "engines": { "node": ">=18" @@ -337,16 +350,17 @@ } }, "node_modules/@sentry/server-utils": { - "version": "10.67.0", - "resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.67.0.tgz", - "integrity": "sha512-GQ9t+RSTx5s3b/aZrLFuL4nrwPLMah5NiZk5cjxJmgmOSgm3nMdO8gdqCedDch5B13F3YsxtaQYjSJnzLz8M5A==", + "version": "10.69.0", + "resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.69.0.tgz", + "integrity": "sha512-0MwHrA8+nNvMIsqf8m3cXwCBlUjr6AS7N6CZvHJtY1DkqEvQqEbD5VIrhzEyHN/KMZIgQ8XeDCQRhjnXFQGRhg==", "dev": true, "license": "MIT", "dependencies": { - "@apm-js-collab/code-transformer-bundler-plugins": "^0.7.1", + "@apm-js-collab/code-transformer-bundler-plugins": "^0.7.3", "@apm-js-collab/tracing-hooks": "^0.13.0", "@sentry/conventions": "^0.16.0", - "@sentry/core": "10.67.0" + "@sentry/core": "10.69.0", + "meriyah": "^6.1.4" }, "engines": { "node": ">=18" @@ -717,19 +731,20 @@ } }, "node_modules/@unbrained/pm-cli": { - "version": "2026.7.29", - "resolved": "https://registry.npmjs.org/@unbrained/pm-cli/-/pm-cli-2026.7.29.tgz", - "integrity": "sha512-ByTNEwyvxTqG3NyHMRapK+6hbbiAOoGSSr1OlXRavX4+i+N8DiEJm3KQV46iX3FX0La+FdSbNhIyW0+ubNxYng==", + "version": "2026.8.6", + "resolved": "https://registry.npmjs.org/@unbrained/pm-cli/-/pm-cli-2026.8.6.tgz", + "integrity": "sha512-98pay0mtwwcWhc9dORhPo3wAmcXV1E5snPv/QMrSd9CXNhCUB3mwYRf194iYR29ttUSfMfGtrF/G8tjbC+fPKQ==", "dev": true, "license": "MIT", "dependencies": { - "@sentry/node": "10.67.0", + "@sentry/node": "10.69.0", "@toon-format/toon": "^4.1.0", "@types/node": ">=22", "commander": "^15.0.0", "fast-glob": "^3.3.3", "fast-json-patch": "^3.1.1", - "npm-package-arg": "^13.0.2" + "npm-package-arg": "^13.0.2", + "tar": "7.5.22" }, "bin": { "pm": "dist/cli.js", @@ -738,14 +753,6 @@ }, "engines": { "node": ">=22.18.0" - }, - "peerDependencies": { - "typebox": "*" - }, - "peerDependenciesMeta": { - "typebox": { - "optional": true - } } }, "node_modules/astring": { @@ -771,6 +778,16 @@ "node": ">=8" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/cjs-module-lexer": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", @@ -910,9 +927,9 @@ } }, "node_modules/import-in-the-middle": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.3.2.tgz", - "integrity": "sha512-jTd2FfOgOWOdgjkHuk/1Ms8VKFXkPs15ymYBETw1sAOrO/dY3XeGVRWir9qBbw7pXr0T2eTFwfCZ+N02HmiNGA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.3.3.tgz", + "integrity": "sha512-AiohS3H80sXO6owEltjGX+glb7qXaDhBoJb9XcQVH4UI207xu/bDLUcadVKp7Qe576reg9yr/PXZjV5qx8gfbA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1011,6 +1028,29 @@ "node": ">=8.6" } }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/module-details-from-path": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", @@ -1055,9 +1095,9 @@ } }, "node_modules/pm-changelog": { - "version": "2026.8.3", - "resolved": "https://registry.npmjs.org/pm-changelog/-/pm-changelog-2026.8.3.tgz", - "integrity": "sha512-yDnkdHEm85q7Gx0sQpW7BV5AEB+dQ6vmRiHkEK1VYYsDHxLvHf4wzN695zy1XjKs23wo3buCpePQS5k0/zz1hQ==", + "version": "2026.8.6", + "resolved": "https://registry.npmjs.org/pm-changelog/-/pm-changelog-2026.8.6.tgz", + "integrity": "sha512-W9TPsz5PBuK7Uug2GifWmgvPojf3lsAKJAL9D6AAxg9ZuhvZz/2X49FfPzJmQbREzbE6f8TpnVGyk7+DKfgFIQ==", "dev": true, "license": "MIT", "bin": { @@ -1067,7 +1107,7 @@ "node": ">=22.18.0" }, "peerDependencies": { - "@unbrained/pm-cli": ">=2026.7.29" + "@unbrained/pm-cli": ">=2026.8.3" } }, "node_modules/proc-log": { @@ -1180,6 +1220,23 @@ "node": ">=0.10.0" } }, + "node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1244,6 +1301,16 @@ "engines": { "node": "^20.17.0 || >=22.9.0" } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } } } } diff --git a/package.json b/package.json index 6e35306..14fd9fe 100644 --- a/package.json +++ b/package.json @@ -58,8 +58,8 @@ }, "devDependencies": { "@types/node": "^26.1.1", - "@unbrained/pm-cli": "^2026.7.29", - "pm-changelog": "^2026.7.25", + "@unbrained/pm-cli": "^2026.8.6", + "pm-changelog": "^2026.8.6", "typescript": "^7.0.2" }, "engines": { From db6c58328708bb7ec497f55606698755e774b9ca Mon Sep 17 00:00:00 2001 From: Stefan Preu Date: Fri, 7 Aug 2026 00:33:33 +0200 Subject: [PATCH 5/5] docs(ci): resolve exact-head health-gate findings --- .agents/pm/chores/pm-linear-9848.toon | 15 +++++++++------ .agents/pm/history/pm-linear-9848.jsonl | 3 +++ .github/workflows/ci.yml | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon index 743be1c..4da1b37 100644 --- a/.agents/pm/chores/pm-linear-9848.toon +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -1,25 +1,27 @@ id: pm-linear-9848 title: Gate CI on strict tracked pm project health -description: "Run pm health --strict-exit in CI to reject durable tracker-health failures. The fresh runner cannot inspect clone-local merge receipts; pm-cli#921 tracks the remaining attestation gap, so receipt reconciliation stays a local pre-push responsibility." +description: Run pm health --strict-exit in CI to reject durable tracker-health failures without claiming lossless merge attestation. pm-cli#921 covers history-repair erasing a durable drift signal; pm-cli#922 covers a lossy merge shape whose fresh clone is already green because receipts are local and tracked history resembles sequential edits. type: Chore status: closed priority: 2 tags: [] created_at: "2026-08-06T20:46:45.382Z" -updated_at: "2026-08-06T22:00:34.126Z" +updated_at: "2026-08-06T22:32:37.010Z" closed_at: "2026-08-06T20:47:03.366Z" completed_at: "2026-08-06T20:47:03.366Z" author: pi-agent acceptance_criteria: "CI runs pm health --strict-exit immediately after dependency installation; clean durable repository state exits 0; tracked history, attribution, cache, extension, or available merge-evidence failures block CI; documentation does not claim fresh CI can inspect clone-local receipts" resolution: Added a strict tracked-state health gate and corrected the merge-safety boundary after exact reviewer feedback. expected_result: CI rejects durable pm project-health failures without overstating coverage of clone-local merge receipts. -actual_result: "Package health passes locally. Published pm 2026.8.6 black-box proof showed pending receipts disappear in a fresh clone, durable history drift blocks the unrepaired merge, and history-repair can erase that last CI signal; upstream pm-cli#921 records the gap." +actual_result: "Package health and release checks pass with pm 2026.8.6. Black-box proofs establish two distinct blind spots: #921 shows repair can erase the last durable signal, while #922 shows a directly green fresh-clone shape; local receipt review remains mandatory." notes[3]{created_at,author,text}: "2026-08-06T21:21:15.836Z",codex,"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee." "2026-08-06T21:27:21.498Z","harness:claude-code","CORRECTION 2026-08-06, verified directly rather than reasoned about. This item's original close reason overstated what the gate does, and the CI comment has been rewritten to match reality.\n\nWHAT WAS WRONG. The gate was described as blocking a silently discarded peer edit. It does not, and cannot as currently built. Merge-decision receipts are written to .agents/pm/runtime/, which pm init itself gitignores, so they are never pushed. Measured on the same commit: the clone that performed the merge reports 1 receipt and the strict health check exits 1, while a fresh clone of that exact commit reports 0 receipts and the strict health check exits 0. CI checks out the fresh state, so the discarded edit passes.\n\nTHE PUSHED HISTORY DOES NOT DISAMBIGUATE IT EITHER. The merged history stream contains both writes in timestamp order and the item matches the latest one, so history verification reports current_matches_latest true with matching hashes. From pushed state alone, two concurrent branch edits where one was discarded look exactly like two sequential edits where the second superseded the first.\n\nRECONCILE PUBLISHES THE EVIDENCE BUT DOES NOT MAKE IT GATEABLE. Running merge reconcile appends a merge_reconcile event into tracked history carrying conflict_fields, retained_hash and discarded_hash, so durable evidence can exist. But the strict health check then exits 0 in both clones, and reconcile is optional anyway. There is no configuration in which CI observes the loss.\n\nCREDIT. Greptile flagged this as P1 on every gate PR in the rollout before it merged. Verified independently and filed upstream as pm-cli 922.\n\nWHAT THE GATE ACTUALLY DOES, all observable in a fresh checkout and all worth gating on: conflict markers left in item or history files, item parse failures, invalid history JSON, history hash drift, unknown-author history events, stale in-progress work, and tracked runtime cache files. The strict-exit flag remains load-bearing because a bare health check exits 0 even when not ok.\n\nThe step is kept for that real value. Only the claim was wrong, and a gate whose documentation overstates its guarantee is worse than no gate because it stops people looking for the real hazard." "2026-08-06T22:00:34.125Z",codex,"Refreshed the package's development/runtime lock projection to @unbrained/pm-cli 2026.8.6 and pm-changelog 2026.8.6 where applicable, so the health and changelog gates execute against the current published contracts. Existing peer minima remain compatibility claims, not the tested tool version." -files[3]{path,scope}: +files[5]{path,scope}: .gitattributes,project + .github/workflows/ci.yml,project + CHANGELOG.md,project package-lock.json,project package.json,project tests[2]: @@ -28,7 +30,8 @@ tests[2]: - command: pm health --strict-exit scope: project timeout_seconds: 120 -docs[1]{path,scope,note}: +docs[2]{path,scope,note}: "https://github.com/unbraind/pm-cli/issues/921",global,upstream durable merge-attestation gap -close_reason: "Added the CI tracked-state health gate, corrected workflow and changelog language after Greptile identified the fresh-clone receipt boundary, retained local receipt reconciliation as a pre-push requirement, and filed pm-cli#921 with 2026.8.6 black-box evidence." + "https://github.com/unbraind/pm-cli/issues/922",global,direct fresh-clone receipt and sequential-looking history shape +close_reason: "Added the tracked-state health gate, corrected its boundary after bot review, linked both distinct upstream blind spots (#921 repair bypass and #922 directly green fresh-clone shape), recorded every affected file, and retained local receipt reconciliation as a pre-push requirement." body: "" diff --git a/.agents/pm/history/pm-linear-9848.jsonl b/.agents/pm/history/pm-linear-9848.jsonl index 4239991..4852206 100644 --- a/.agents/pm/history/pm-linear-9848.jsonl +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -7,3 +7,6 @@ {"ts":"2026-08-06T22:00:33.677Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:00:33.677Z"},{"op":"add","path":"/metadata/files","value":[{"path":".gitattributes","scope":"project"},{"path":"package-lock.json","scope":"project"},{"path":"package.json","scope":"project"}]}],"before_hash":"535abf729040109c7c6c8125bf8648ca68df0255cfd4a7b41b815665c814ba0f","after_hash":"cc4906bb1738fe5b6f45b1ca6a00cb2ec7858888c0b18a5974f7ba5910ffb500"} {"ts":"2026-08-06T22:00:34.126Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"note_add","patch":[{"op":"add","path":"/metadata/notes/1","value":{"created_at":"2026-08-06T22:00:34.125Z","author":"codex","text":"Refreshed the package's development/runtime lock projection to @unbrained/pm-cli 2026.8.6 and pm-changelog 2026.8.6 where applicable, so the health and changelog gates execute against the current published contracts. Existing peer minima remain compatibility claims, not the tested tool version."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:00:34.126Z"}],"before_hash":"cc4906bb1738fe5b6f45b1ca6a00cb2ec7858888c0b18a5974f7ba5910ffb500","after_hash":"f011dfcf74ea23c8c5da22dabaff23734f3ede7a93a1ebe5886ec2c23e0e9fa1"} {"ts":"2026-08-06T22:22:28.526Z","author":"codex","op":"merge_reconcile","patch":[{"op":"replace","path":"/metadata/notes/1/text","value":"CORRECTION 2026-08-06, verified directly rather than reasoned about. This item's original close reason overstated what the gate does, and the CI comment has been rewritten to match reality.\n\nWHAT WAS WRONG. The gate was described as blocking a silently discarded peer edit. It does not, and cannot as currently built. Merge-decision receipts are written to .agents/pm/runtime/, which pm init itself gitignores, so they are never pushed. Measured on the same commit: the clone that performed the merge reports 1 receipt and the strict health check exits 1, while a fresh clone of that exact commit reports 0 receipts and the strict health check exits 0. CI checks out the fresh state, so the discarded edit passes.\n\nTHE PUSHED HISTORY DOES NOT DISAMBIGUATE IT EITHER. The merged history stream contains both writes in timestamp order and the item matches the latest one, so history verification reports current_matches_latest true with matching hashes. From pushed state alone, two concurrent branch edits where one was discarded look exactly like two sequential edits where the second superseded the first.\n\nRECONCILE PUBLISHES THE EVIDENCE BUT DOES NOT MAKE IT GATEABLE. Running merge reconcile appends a merge_reconcile event into tracked history carrying conflict_fields, retained_hash and discarded_hash, so durable evidence can exist. But the strict health check then exits 0 in both clones, and reconcile is optional anyway. There is no configuration in which CI observes the loss.\n\nCREDIT. Greptile flagged this as P1 on every gate PR in the rollout before it merged. Verified independently and filed upstream as pm-cli 922.\n\nWHAT THE GATE ACTUALLY DOES, all observable in a fresh checkout and all worth gating on: conflict markers left in item or history files, item parse failures, invalid history JSON, history hash drift, unknown-author history events, stale in-progress work, and tracked runtime cache files. The strict-exit flag remains load-bearing because a bare health check exits 0 even when not ok.\n\nThe step is kept for that real value. Only the claim was wrong, and a gate whose documentation overstates its guarantee is worse than no gate because it stops people looking for the real hazard."},{"op":"replace","path":"/metadata/notes/1/author","value":"harness:claude-code"},{"op":"replace","path":"/metadata/notes/1/created_at","value":"2026-08-06T21:27:21.498Z"},{"op":"replace","path":"/metadata/notes/0/text","value":"Greptile P1 was valid as a scope correction: a fresh checkout cannot inspect .git-local receipts. The gate remains useful for durable health and catches unrepaired lossy merges through history drift,but it is not a complete no-loss guarantee."},{"op":"replace","path":"/metadata/notes/0/author","value":"codex"},{"op":"replace","path":"/metadata/notes/0/created_at","value":"2026-08-06T21:21:15.836Z"},{"op":"add","path":"/metadata/notes/2","value":{"created_at":"2026-08-06T22:00:34.125Z","author":"codex","text":"Refreshed the package's development/runtime lock projection to @unbrained/pm-cli 2026.8.6 and pm-changelog 2026.8.6 where applicable, so the health and changelog gates execute against the current published contracts. Existing peer minima remain compatibility claims, not the tested tool version."}},{"op":"replace","path":"/metadata/title","value":"Gate CI on strict tracked pm project health"}],"before_hash":"f011dfcf74ea23c8c5da22dabaff23734f3ede7a93a1ebe5886ec2c23e0e9fa1","after_hash":"ddbf186ebb768de0fcd27aeefdfe9b9089f24cb9b2a1d870008335f3e9131d61","message":"Reconcile concurrent CI health-gate corrections; retain the tracked-health title and preserve both verification notes.","context":{"merge":{"receipts":[{"receipt_id":"f1de5b4d-612a-4dd9-bf5a-9ed1c012753b","item_id":"pm-linear-9848","item_path":".agents/pm/chores/pm-linear-9848.toon","conflict_fields":["title"],"fields_from_theirs":[],"union_fields":["notes"],"preferred":"ours","decisions":[{"field":"title","retained_hash":"6e2cb795a02ef2c0855ea5d7fc45290809683f5d1f83a76377fcd99b3097a7b6","discarded_hash":"55081b31c9da7e54d0cc27e76fde64b73a7188ce3c2fce9f824ada324e5b8dcf"}]}]}}} +{"ts":"2026-08-06T22:32:36.130Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"files_add","patch":[{"op":"replace","path":"/metadata/files/2/path","value":"CHANGELOG.md"},{"op":"replace","path":"/metadata/files/1/path","value":".github/workflows/ci.yml"},{"op":"add","path":"/metadata/files/3","value":{"path":"package-lock.json","scope":"project"}},{"op":"add","path":"/metadata/files/4","value":{"path":"package.json","scope":"project"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:32:36.130Z"}],"before_hash":"ddbf186ebb768de0fcd27aeefdfe9b9089f24cb9b2a1d870008335f3e9131d61","after_hash":"1926aaf3f6785395d8e3cba236fdac1d6925b09cefdfd3e42f3679c44951943e"} +{"ts":"2026-08-06T22:32:36.569Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"docs_add","patch":[{"op":"add","path":"/metadata/docs/1","value":{"path":"https://github.com/unbraind/pm-cli/issues/922","scope":"global","note":"direct fresh-clone receipt and sequential-looking history shape"}},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:32:36.569Z"}],"before_hash":"1926aaf3f6785395d8e3cba236fdac1d6925b09cefdfd3e42f3679c44951943e","after_hash":"57086811d459ff18fc37491b50d5bc72aca908122311c135ba1482a0b0441720"} +{"ts":"2026-08-06T22:32:37.010Z","author":"codex","author_source":"asserted","agent_harness":"codex","agent_instance":"f1530d70463641787965c6dc","agent_provenance":{"model":null,"effort":null,"role":null,"topic":null},"op":"update","patch":[{"op":"replace","path":"/metadata/close_reason","value":"Added the tracked-state health gate, corrected its boundary after bot review, linked both distinct upstream blind spots (#921 repair bypass and #922 directly green fresh-clone shape), recorded every affected file, and retained local receipt reconciliation as a pre-push requirement."},{"op":"replace","path":"/metadata/actual_result","value":"Package health and release checks pass with pm 2026.8.6. Black-box proofs establish two distinct blind spots: #921 shows repair can erase the last durable signal, while #922 shows a directly green fresh-clone shape; local receipt review remains mandatory."},{"op":"replace","path":"/metadata/updated_at","value":"2026-08-06T22:32:37.010Z"},{"op":"replace","path":"/metadata/description","value":"Run pm health --strict-exit in CI to reject durable tracker-health failures without claiming lossless merge attestation. pm-cli#921 covers history-repair erasing a durable drift signal; pm-cli#922 covers a lossy merge shape whose fresh clone is already green because receipts are local and tracked history resembles sequential edits."}],"before_hash":"57086811d459ff18fc37491b50d5bc72aca908122311c135ba1482a0b0441720","after_hash":"1281a6461ee5da97e4459abadbe47a179aa4ed41aeaaca5891bf7e73109459cc","message":"Address exact-head bot findings about gate scope, upstream issue mapping, and affected-file evidence"} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98ea5b9..8527639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: run: | set -euo pipefail # Catch durable checkout-visible failures: conflict markers, parse failures, - # invalid or drifted history, attribution failures, tracked runtime caches, - # extension health, and any merge evidence present in this clone. + # invalid or drifted history, tracked runtime caches, extension health, + # stale in-progress work, and any merge evidence present in this clone. # # This is not a lossless-merge attestation. Merge receipts are clone-local and # absent from a fresh CI checkout. Some unreconciled loss shapes surface as