gabriel / muse public
Open #32 Bug
filed by gabriel human · 5 days ago

push --dry-run overcounts commits_sent by ignoring remote have negotiation

0 Anchors
Blast radius
Churn 30d
0 Proposals

Background

muse push --dry-run reports an inflated commits_sent count that does not match what the live push actually sends. Observed during the phase1-merge-engine merge (2026-06-12):

  • muse push local main --force-with-lease --dry-run reported commits_sent: 1271
  • The live push sent commits_sent: 0

The same pattern appeared earlier in the same session:

  • muse push local dev --force-with-lease --dry-run (muse repo) reported commits_sent: 16, live sent 0
  • muse push local dev --force-with-lease --dry-run (musehub repo) reported commits_sent: 4, live sent 0

The root cause: the dry-run walks the local DAG and counts commits reachable from the local tip but not reachable from the remote branch tip being pushed to. It does not simulate the full have negotiation that the live push performs — specifically, it does not account for other remote branch tips the server already knows about.

In the live push, step 0 fetches all remote branch heads (dev, main, task/phase1-merge-engine, etc.) and adds them all to the have set. Step 1 then computes want - have, which correctly returns 0 when the target commit is already reachable via another remote branch. The dry-run skips this and computes want - {remote_branch_tip} only, which counts the entire history between the two tips.

This is misleading and erodes trust in dry-run output. An agent or human seeing commits_sent: 1271 before a push will reasonably pause and investigate, wasting time.


Goal

muse push --dry-run produces a commits_sent count that matches what the live push would actually send, using the same have negotiation logic.


Phases

Phase 1 — Reproduce and characterise

Deliverables:

  • RC_01 — Write a test that sets up a repo with two branches on the remote (e.g. dev and main), advances main locally to match dev, then asserts that push --dry-run main reports commits_sent: 0 (matching the live push). Test must be red before the fix.

Phase 2 — Fix dry-run have negotiation

Deliverables:

  • FX_01 — Update the dry-run path in muse push to fetch all remote branch heads (same as step 0 of the live push) and use the full set as have when computing new_commits.
  • FX_02RC_01 is now green.
  • FX_03 — Existing push tests remain green.

Phase 3 — Validate the fix end-to-end

Deliverables:

  • VL_01 — Run the exact scenario that triggered this report: local main fast-forwarded to match remote dev; push --dry-run main reports commits_sent: 0.
  • VL_02 — Confirm that when there ARE genuinely new commits, dry-run still reports the correct non-zero count.

Acceptance criteria

  1. muse push --dry-run commits_sent always matches what the live push sends.
  2. RC_01, FX_01–03, VL_01–02 all checked off.
  3. No regression in existing push tests.

Out of scope

  • Changing the live push have negotiation (it is already correct).
  • Dry-run accuracy for objects_sent (separate concern, lower priority).
Activity
gabriel opened this issue 5 days ago
No activity yet. Use the CLI to comment.