Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .agents/pm/chores/pm-github-eh1h.toon
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
id: pm-github-eh1h
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:44:51.948Z"
updated_at: "2026-08-06T22:32:19.477Z"
closed_at: "2026-08-06T20:44:52.355Z"
completed_at: "2026-08-06T20:44:52.355Z"
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:14.406Z",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:18.017Z","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:22.491Z",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: ""
Loading