Skip to content

pm history <id> --verify exits 0 when verification.ok is false; no --strict-exit flag (unlike pm validate) — unusable as a merge-safety gate #604

Closed

Description

@unbraind

Summary

pm history <id> --verify is the dedicated per-item integrity verifier — its whole job is to detect a broken/forked hash chain. But when the chain is broken it prints verification.ok: false and still exits 0, and there is no --strict-exit flag to make it fail. This is inconsistent with pm validate, which does ship --strict-exit / --fail-on-warn.

The consequence lands squarely on the multi-agent branch-merge workflow: after two agents edit the same item on separate branches and the append-only history/<id>.jsonl is union-resolved (see #599), the hash chain forks. An agent or CI hook that wants to gate the merge on integrity cannot use the obvious command:

pm history <id> --verify || echo "chain broken"   # never fires — exit is always 0

To gate, callers must instead capture JSON and parse verification.ok themselves. Every naive set -e pre-merge/pre-commit hook built around --verify passes green over a corrupted chain.

Environment

  • pm-cli 2026.7.18

Reproduction

git init -b main repo && cd repo && pm init
ID=$(pm --json create Issue "Shared item" --author alice | jq -r .item.id)
git add -A && git commit -qm seed

git checkout -b agent-a
pm comment "$ID" "Alice" --author alice && pm update "$ID" --status in_progress --author alice
git add -A && git commit -qm a

git checkout main && git checkout -b agent-b
pm comment "$ID" "Bob" --author bob && pm update "$ID" --status blocked --author bob
git add -A && git commit -qm b

git merge agent-a                       # CONFLICT in history/<id>.jsonl and issues/<id>.toon
# union-resolve the jsonl (drop <<<< ==== >>>> markers, keep both sides), pick either .toon side
git add -A && git commit -qm resolve

pm history "$ID" --verify | tail -8     # -> verification.ok: false, before_hash_mismatch, current_item_hash_mismatch
pm history "$ID" --verify >/dev/null; echo "exit=$?"   # -> exit=0   <-- BUG

Observed:

verification:
  ok: false
  errors:
    - "verify_failed:before_hash_mismatch:entry_4"
    - "verify_failed:current_item_hash_mismatch"
  current_matches_latest: false
exit=0

pm validate on the same repo also reports the drift (hash_mismatches: 1, chain_mismatches: 1) — and it can be made to fail with --strict-exit. Only the per-item --verify path lacks the equivalent.

Expected

pm history <id> --verify should return a non-zero exit when verification.ok is false — either unconditionally, or via a --strict-exit / --fail-on-warn flag mirroring pm validate. That single change makes --verify usable as a drop-in merge-safety gate in CI and git hooks, which is the primary reason the command exists.

Impact

  • Severity: medium — silent false-green on the exact command agents reach for to guard concurrent merges.
  • Scope: any multi-agent / multi-branch workflow (the documented use case).
  • Workaround: parse --format json for .verification.ok instead of relying on exit code.

Related: #599 (no merge driver for append-only history — the cause of the fork), #603 (history-repair cements the loss and validate then greens). This issue is narrower and orthogonal: the verifier's exit contract.

Activity

  1. coderabbitai commented on Jul 18, 2026

    @coderabbitai
    🔗 Related PRs

    #37 - Improve agent token UX and blocked dependency handling [closed]
    #44 - feat(history): audited history-repair re-anchor command; clear legacy drift so pm health is ok [closed]
    #68 - Harden history lock-window reliability and repin release workflow action [closed]
    #200 - Add validation self-repair and agent ergonomics primitives [closed]
    #549 - feat(sdk): ship history time travel, rich reads, and runtime integrity [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. unbraind commented on Jul 19, 2026

    @unbraind
    OwnerAuthor

    pm tracker item: pm-ol3p

  3. unbraind commented on Jul 19, 2026

    @unbraind
    OwnerAuthor

    Fixed via PR#614 (SDK-first field-aware merge safety and storage integrity, merged 2026-07-19). Tracker item pm-ol3p closed with resolution + packed Git acceptance evidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions