Skip to content

pm history-repair cements cross-author data loss after a lossy merge; pm validate then reports fully green (no revert warning / replay check) #603

Closed

Description

@unbraind

Summary

After a lossy merge resolution (item .toon taken from one side, history union-merged), pm history-repair reconciles the chain by appending a reverting patch that discards the other author's mutation from the effective state, and pm validate then reports a fully green result (drift 0, ok: true). Nothing surfaces that a teammate agent's change was reverted — the data loss is cemented and invisible to every pm command. This directly undermines the multi-agent "merge, then validate → repair → validate" workflow.

Environment

  • pm-cli 2026.7.18

Reproduction

git init -b main && export PM_PATH="$PWD/pm" && pm init --yes
pm create "Bug X" --type Task --author seed          # -> pm-je79
git add -A && git commit -m seed

git checkout -b A && pm append pm-je79 "A body" --author agent-a && git add -A && git commit -m A
git checkout main && git checkout -b B && pm update pm-je79 --priority 1 --author agent-b && git add -A && git commit -m B

git checkout A && git merge B          # conflicts in .toon + history/*.jsonl
# hurried resolution: union the history jsonl, take OUR .toon (drops agent-b's priority=1 from the item)
git checkout --ours pm/tasks/pm-je79.toon
git add -A

State now: item priority: 2 (agent-b's 1 dropped), but history still records agent-b update priority=1.

pm validate      # history_drift: warn, drifted_items_count: 1   (ok: true)   ✅ correctly flags divergence
pm history-repair pm-je79 --author agent-c --message "post-merge repair"
#   reconciled_with_item: true, entries_rehashed: 1, verify_ok: true
pm validate      # ok: true, has_warnings (metadata only), history_drift: drifted_items_count: 0   ← FULLY GREEN

The repair appended:

{"author":"agent-c","op":"history_repair","patch":[["/metadata/updated_at","…"],["/metadata/priority",2]]}

i.e. a patch that reverts priority back to 2, cementing agent-b's loss. History replay minus repair markers yields priority: 1 (agent-b's intent); the item is 2; validate is green and no command reports the divergence.

Impact

The natural multi-agent recovery loop — merge → validate (sees drift) → history-repair → validate (green) — gives a clean bill of health precisely when another agent's committed change has been silently discarded. history-repair's reconcile-to-item behavior is reasonable, but it is indistinguishable from "everything is fine," and the audit trail (raw jsonl) is the only place the loss is visible.

Suggested fix (any subset)

  1. history-repair should report reverted_mutations: [{ts, author, op, paths}] whenever the reconcile patch overwrites non-repair history mutations authored by someone else, and require --acknowledge-reverts (or a non-empty --message) when that set is non-empty.
  2. Add pm validate --check-replay-consistency: replay each stream (skipping repair markers) and diff against the item, flagging semantic divergence even when hashes are anchored.
  3. Surface reconcile/repair patches in pm history <id> output (not only in raw jsonl) so the revert is visible in the normal audit view.

Confidence: high for the mechanism (reproduced end-to-end on 2026.7.18: reverting patch + green validate verified). Framed as a multi-agent safety/observability gap, not a claim that repair is "broken."

Activity

  1. coderabbitai commented on Jul 18, 2026

    @coderabbitai
    🔗 Related PRs

    #44 - feat(history): audited history-repair re-anchor command; clear legacy drift so pm health is ok [closed]
    #67 - Harden history lock windows and add in-process CLI runner foundation [closed]
    #68 - Harden history lock-window reliability and repin release workflow action [closed]
    #200 - Add validation self-repair and agent ergonomics primitives [closed]
    #406 - feat(mcp): extension-aware built-in actions + action-scoped name schema (pm-zumn, pm-fq80) [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-gpo7

  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-gpo7 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