Skip to content

doctor: check and repair the v1.1 committed-read mirror - #1350

Merged
computermode merged 6 commits into
mainfrom
doctor-v11-mirror-check
Jun 4, 2026
Merged

doctor: check and repair the v1.1 committed-read mirror#1350
computermode merged 6 commits into
mainfrom
doctor-v11-mirror-check

Conversation

@computermode

@computermode computermode commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/501

What

Follow-up to #1335. That PR established the v1.1 committed-ref contract: reads resolve refs/entire/checkpoints/v1.1 as-is — read paths no longer create, repair, or advance the mirror. That leaves no repair path when the mirror drifts (pre-#1335 state, a raw git fetch of v1 outside entire, a crash between v1 write and mirror update, external ref meddling). A drifted mirror silently makes v1.1 reads miss checkpoints.

This PR makes entire doctor the repair tool:

  • strategy.DiagnoseCommittedMetadataMirror — read-only classifier of the mirror against the local v1 tip: NOT CONFIGURED | OK | NO METADATA | MISSING | STALE (behind) | DIVERGED | V1 BRANCH MISSING. Returns the resolved CommittedRefs so callers repair via the existing MirrorCommittedMetadataRef.
  • entire doctor check Move "clean" root command to "session cleanup", some refactoring #2 (right after the disconnected-metadata check, which rewrites v1 and re-mirrors — this catches residual drift):
    • silent in v1 mode; ✓ OK when healthy (including fresh repos with no metadata yet)
    • MISSING / STALE / DIVERGED → explain, confirm (auto with --force), point the mirror at the v1 tip; the diverged copy explicitly says the discarded commits aren't on v1
    • mirror-outlives-v1 anomaly → warn-only with a pasteable git fetch suggestion (never auto-"fixed", even under --force)
    • check errors accumulate like the existing checks without aborting the rest of doctor
  • entire doctor bundle — new entire-refs.txt: for-each-ref over entire's ref namespaces (v1 branch, v1.1 mirror, shadow/trails branches, origin tracking) plus a mirror status: STALE (mirror abc1234, v1 def5678) diagnosis line. Best-effort and goes through the standard redaction path.

Design notes

  • Status labels have one source: doctor headlines and the bundle line both render MirrorStatus.String(), so the two surfaces can't drift.
  • Messages and the fetch suggestion render diag.Refs.Primary rather than hardcoding entire/checkpoints/v1, so doctor's guidance survives a future topology flip.
  • Diagnosis deliberately does not reuse strategy.IsAncestorOf: that helper is a depth-capped (1000), error-swallowing log walk, and a long-lived v1 branch grows one commit per condensation — a merely-stale mirror past the cap would misclassify as DIVERGED with misleading messaging. The diagnosis uses go-git's exact ancestry and surfaces errors.
  • The confirm prompt is extracted to confirmDoctorFix, now shared with checkDisconnectedMetadata.
  • Restoring a deleted v1 branch is out of scope (warn-only); so are mirror-ref deletion in entire clean and the v1.1 remote-fetch story for entire resume (separate follow-ups).

Coverage

  • strategy: table-driven TestDiagnoseCommittedMetadataMirror — all seven states, plus the read-only invariant (diagnosis never creates/moves/deletes the ref).
  • cli: table-driven TestCheckCommittedMetadataMirror — per-state output, --force repairs actually move the ref to the v1 tip, warn-only state stays untouched; TestRunSessionsFix_IncludesMirrorCheck proves the wiring into the main doctor flow.
  • cli: TestWriteDoctorBundle_CapturesEntireRefs — bundle contains entire-refs.txt with the refs and the diagnosis line.
  • Docs: sessions-and-checkpoints.md v1.1 section now names doctor as the repair path.

Verification

  • mise run fmt
  • mise run lint
  • mise run test:ci (incl. Vogon canary), re-run after merging main

🤖 Generated with Claude Code


Note

Medium Risk
Repairs rewrite the local mirror ref to match v1 (diverged case discards mirror-only commits after user confirmation), which directly affects checkpoint read visibility but does not change v1 writes or remote sync.

Overview
Adds a checkpoints v1.1 read-mirror repair path to entire doctor, following the contract that read paths use refs/entire/checkpoints/v1.1 as-is.

Strategy: Introduces DiagnoseCommittedMetadataMirror and MirrorStatus labels (MISSING, STALE, DIVERGED, etc.) to compare the local mirror to the entire/checkpoints/v1 tip using go-git ancestry (not the depth-capped helper). Repair still uses MirrorCommittedMetadataRef.

Doctor: New check #2 runs after disconnected-metadata reconciliation; it is silent in v1-only mode, can auto-repair missing/stale/diverged mirrors with --force or after confirm via shared confirmDoctorFix, and stays warn-only when the mirror exists but v1 is gone (suggested git fetch). Mirror check failures accumulate like other doctor errors.

Bundle: entire doctor bundle adds entire-refs.txt listing entire-related refs plus a mirror status: line using the same status strings.

Tests cover diagnosis, doctor wiring, and bundle capture; architecture docs name doctor as the mirror repair tool.

Reviewed by Cursor Bugbot for commit 39b2bbc. Configure here.

computermode and others added 4 commits June 3, 2026 10:28
Read paths use the v1.1 mirror as-is (no read-time self-repair), so a
missing, stale, or diverged refs/entire/checkpoints/v1.1 silently makes
v1.1 reads miss checkpoints with no repair path. Make doctor the repair
tool:

- strategy.DiagnoseCommittedMetadataMirror classifies the mirror against
  the local v1 tip (read-only): not configured, ok, missing, behind,
  diverged, or v1-branch-missing.
- entire doctor reports the state and repairs missing/stale/diverged
  with confirmation (auto under --force) via the existing
  MirrorCommittedMetadataRef. The mirror-outlives-v1 anomaly is warn-only
  with a fetch suggestion; restoring v1 is out of scope.
- entire doctor bundle captures entire-related refs plus the mirror
  diagnosis in entire-refs.txt for bug reports.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 1513a1ef2b6b
- Split MirrorNoMetadata out of MirrorPrimaryMissing so the diagnosis is
  self-describing; the bundle no longer labels a fresh v1.1 repo V1 MISSING.
- Derive doctor headlines from MirrorStatus.String() — one source for
  status labels across doctor and bundle output.
- Render the primary ref from diag.Refs.Primary instead of hardcoding
  entire/checkpoints/v1, so guidance survives a future topology flip.
- Extract confirmDoctorFix, shared with checkDisconnectedMetadata.
- Document why the bundle's for-each-ref globs are broader than the
  resolved topology refs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: dbe157735b54
Collapse the seven checkCommittedMetadataMirror tests into one
table-driven test (setup returns the expected final mirror state) and
cut comment prose throughout the mirror check, diagnosis, and bundle
report to the essentials.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 2e1b1751fbc2
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 3, 2026 18:13

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 39b2bbc. Configure here.

Comment thread cmd/entire/cli/doctor.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated repair path for the v1.1 committed-read mirror (refs/entire/checkpoints/v1.1) by moving drift detection/repair into entire doctor, plus bundling ref-state diagnostics for supportability. This fits the post-#1335 contract where read paths must treat the mirror “as-is” and never implicitly repair it.

Changes:

  • Introduces strategy.DiagnoseCommittedMetadataMirror with a shared MirrorStatus classifier to detect missing/stale/diverged/outlived-primary mirror states.
  • Wires a new entire doctor check to diagnose and (optionally / --force) repair the v1.1 read mirror via existing mirroring logic.
  • Extends entire doctor bundle to capture entire-related refs and mirror diagnosis in entire-refs.txt, with tests and docs updates.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/architecture/sessions-and-checkpoints.md Documents entire doctor as the explicit v1.1 mirror repair tool and notes bundle capture.
cmd/entire/cli/strategy/v1_custom_ref_mirror.go Adds MirrorStatus, MirrorDiagnosis, and DiagnoseCommittedMetadataMirror (read-only diagnosis).
cmd/entire/cli/strategy/v1_custom_ref_mirror_test.go Adds table-driven coverage for all mirror diagnosis states + read-only invariant.
cmd/entire/cli/doctor.go Adds doctor check to diagnose/repair mirror drift; factors prompt into confirmDoctorFix.
cmd/entire/cli/doctor_test.go Adds tests for mirror check output/behavior, wiring into main doctor flow, and force repair behavior.
cmd/entire/cli/doctor_bundle.go Adds entire-refs.txt to bundles and includes mirror status line derived from shared status strings.
cmd/entire/cli/doctor_bundle_test.go Verifies entire-refs.txt contains entire refs and mirror diagnosis line.

Comment thread cmd/entire/cli/doctor_bundle.go
Comment thread cmd/entire/cli/doctor.go Outdated
- confirmDoctorFix now runs via RunWithContext and treats a cancelled
  command context as a clean skip (guards before huh opens the TTY),
  honoring interrupts instead of surfacing a wrapped error.
- Fix the STALE headline: "advance the mirror to the <primary> tip"
  instead of the contradictory "to its tip".
- Close the go-git repo opened in mirrorStatusReportLine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 82c0ad9a1407
@computermode
computermode marked this pull request as ready for review June 4, 2026 17:59
@computermode
computermode requested a review from a team as a code owner June 4, 2026 17:59
@computermode
computermode merged commit 2f5f7c1 into main Jun 4, 2026
9 checks passed
@computermode
computermode deleted the doctor-v11-mirror-check branch June 4, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants