diff --git a/.agents/pm/chores/pm-linear-9848.toon b/.agents/pm/chores/pm-linear-9848.toon new file mode 100644 index 00000000..4da1b374 --- /dev/null +++ b/.agents/pm/chores/pm-linear-9848.toon @@ -0,0 +1,37 @@ +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 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: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 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[5]{path,scope}: + .gitattributes,project + .github/workflows/ci.yml,project + CHANGELOG.md,project + package-lock.json,project + package.json,project +tests[2]: + - command: "npm run release:check" + scope: project + - command: pm health --strict-exit + scope: project + timeout_seconds: 120 +docs[2]{path,scope,note}: + "https://github.com/unbraind/pm-cli/issues/921",global,upstream durable merge-attestation gap + "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 new file mode 100644 index 00000000..48522062 --- /dev/null +++ b/.agents/pm/history/pm-linear-9848.jsonl @@ -0,0 +1,12 @@ +{"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: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":"58d9c7b34aefdaea308af1ee90eedb6dccf244f3f8db6e85c69daf21bcb19e04","after_hash":"76beefbb3c7a0328f5865dbfe7fe78ccf80883eeb1fa013d8cbd7878a9a1e0de"} +{"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":"76beefbb3c7a0328f5865dbfe7fe78ccf80883eeb1fa013d8cbd7878a9a1e0de","after_hash":"95aff2d58c1b32e699f395f14391b989bf6cf15d08c4b95d59ad7f2f796e36d1"} +{"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":"95aff2d58c1b32e699f395f14391b989bf6cf15d08c4b95d59ad7f2f796e36d1","after_hash":"535abf729040109c7c6c8125bf8648ca68df0255cfd4a7b41b815665c814ba0f"} +{"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/.gitattributes b/.gitattributes index c3e7c664..4755b628 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 @@ -25,4 +27,6 @@ ".agents/pm/history/*.jsonl" merge=pm-history ".agents/pm/settings.json" merge=pm-json ".agents/pm/**/*.json" merge=pm-json +".agents/pm/extensions/**" -merge +".agents/pm/extensions/.managed-extensions.json" merge=pm-json # pm-cli:merge-drivers:end diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cbad742a..8527639b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,24 @@ jobs: - name: Install dependencies run: npm ci + - name: Verify tracked pm project health + shell: bash + run: | + set -euo pipefail + # Catch durable checkout-visible failures: conflict markers, parse failures, + # 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 + # history drift, but reconciliation or history repair can remove that signal. + # Keep receipt review as a local pre-push step; pm-cli#921 and pm-cli#922 track + # the missing durable proof. + # + # `--strict-exit` is load-bearing: non-strict health may report findings while + # still exiting successfully. + ./node_modules/.bin/pm health --strict-exit + - name: Type check run: npm run typecheck diff --git a/CHANGELOG.md b/CHANGELOG.md index 836ad5b4..5b3a6462 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 diff --git a/package-lock.json b/package-lock.json index eb04123f..723b2348 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 6e353065..14fd9fed 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": {