codex: sync Jesssullivan/main -> tinyland/main (#534 keep-both + truth docs, 2026-07-06)#71
Merged
Jess Sullivan (Jesssullivan) merged 21 commits intoJul 6, 2026
Conversation
…livan#513 protocol, blahaj ban, dogfood mandate)
…(ledger item 9, TIN-1417) Verified-in-source semantics of tcfs device revoke (local signed mark, no auto remote sync, revocation-sticky merge), the wrap-mode effect matrix, the roll-call coupling that puts the 3 local-fileprovider-* ghosts on the PerDevice critical path, residual risks (FP identity liveness pre-check), and the exact parked operator packet. Doc-only: no devices revoked.
…genuinely diverged repos Design-first doc for the non-fast-forward half of G5-git-5, grounded in the merged Jesssullivan#513 semantics. Core insight: the loser's objects already roam while refs conflict, so keep-both = parking losing heads as refs/tcfs/theirs/<device>/** via git update-ref — no data movement, both histories fsck-clean, human merges with ordinary git. Flags two LIVE corruption vectors to fence first (per-file ResolveConflict RPC + NATS auto-resolve splice). Increments PR-1..PR-4 with per-PR evidence bars; new harness rows G5-git-6..14; G5-git-13 flips G5-git-5/T10/T11 green. Six open operator questions gate PR-3.
… `tcfs conflicts` read verb Rung 1 of the divergent-.git keep-both design (docs/design/ git-divergent-keep-both-2026-07-02.md §5 PR-1, Jesssullivan#523). Pure safety + visibility: zero new write capability, no operator decision, no deploy dependency. Closes two .git-corruption vectors reachable on the fleet today. Live vectors fenced: - grpc.rs resolve_conflict had no .git guard, reachable via CLI `tcfs resolve` and the MCP resolve_conflict tool (passthrough to the same RPC): keep_remote/keep_both on a .git ref splice one device's ref/index over the other's object store (G5-git-5 fsck corruption; no lock, no fsck, no objects-before-refs order). - daemon.rs NATS auto-resolve applied AutoResolver per file with zero .git awareness, auto-downloading a remote ref over the local object store. Pieces: 1. grpc.rs: refuse keep_local/keep_remote/keep_both on any .git-internal path with repo-group guidance; defer stays a no-op (allowed). Non-.git files resolve exactly as before. Auto-covers the MCP tool. 2. daemon.rs: NATS conflict_mode=auto defers .git-internal conflicts (record + skip); non-.git conflicts keep today's auto behavior. 3. tcfs-cli: new read-only `tcfs conflicts` verb — reads the state cache (no daemon RPC), groups .git conflicts by repo root, shows local HEAD (git log --oneline -1), age, times_recorded, honest remote-HEAD degradation; --json. No writes. 4. ConflictInfo.times_recorded: u64 (serde(default)), bumped at the reconcile record site on re-record (detected_at preserved) so a forever-Conflict repo is visible; old state caches deserialize to 0. 5. cmd_resolve interactive prompt now loads the real ConflictInfo from the state cache instead of a dummy placeholder. Tests: .git fence refuses keep_* / allows defer / ignores normal files; NATS-auto defers .git; ConflictInfo round-trips without times_recorded -> 0; `tcfs conflicts` groups by repo and classifies head-ref vs other .git paths. Later rungs: PR-2 hard lock respect (+ remote_manifest_key), PR-3 the resolve_git_keep_both verb (gated on §6 Q1-Q6), PR-4 loser-side no-loss guard.
…pr1-fence feat(keep-both PR-1): fence .git conflicts from per-file resolution + `tcfs conflicts` read verb
…host-device-revocation-safety docs(ops): ghost-device revocation safety analysis + parked packet (ledger item 9, TIN-1417)
…ecord-2026-07 docs: dated decision record for the 2026-07-01 operator session
Close alias bypasses by checking resolved paths and stored conflict rel_path, persist deferred git auto-conflicts before acking NATS events, and normalize conflict grouping paths.
…ix (Jesssullivan#529) Adversarial-review fixes for the live .git keep-both write path. BLOCKING 1 — operator-deliberate (CLI-only) execute path: - MCP resolve_conflict now rejects any resolution starting with "git_keep_both" before it can reach the daemon RPC, pointing at the CLI (tcfs-mcp/src/server.rs). - Add proto field ResolveConflictRequest.operator_cli (field 3), set only by the `tcfs resolve` CLI. The daemon gates git_keep_both_* dispatch on it and fails closed when absent; MCP's ResolveConflictInput cannot set it, and no auto/NATS path does (tcfsd/src/grpc.rs, tcfs-cli/src/main.rs, proto). BLOCKING 2 — undo bundle out of the repo .git: - write_undo_bundle now writes to <state_dir>/keep-both-undo/<repo-hash>/ under the machine-local state dir (never a sync root), only when refs actually change (conflict_git.rs, grpc.rs undo_bundle_state_dir). - blacklist fail-closed denies any .git/tcfs-undo/** path so a pre-existing in-tree bundle can never roam (tcfs-sync/src/blacklist.rs). CHANGES-NEEDED 3 — real end-to-end Execute test: - Two genuinely divergent repos: asserts theirs parked at the correct SHA, winner head/HEAD/objects untouched, `git fsck --full` clean, both heads reachable, and a second Execute is idempotent (conflict_git.rs tests). CHANGES-NEEDED 4 — veto over-breadth reconciled: - collect_repo_conflicts only vetoes genuinely unparkable ref-class paths (packed-refs, refs/ outside refs/heads/, detached HEAD, submodule refs); index/logs/COMMIT_EDITMSG ride kept-local so the verb works on real divergent repos. Reuses reconcile::is_git_ref_class_path (now pub(crate)).
…pr3-repo-resolve feat(sync): add repo git keep-both resolver
…oy-gated Adds an implementation-status table + the ratified operator §6 answers + the PR-3 adversarial security note (operator-CLI-only execute; state-dir undo bundle). PR-1 (Jesssullivan#526/afd84b2), Jesssullivan#527 hardening, PR-2 (Jesssullivan#528/1e41a23), PR-3 (Jesssullivan#529/831d363b) all merged; PR-4 (loser-side no-loss guard) is the only remaining rung and is gated on the fleet reaching a common tcfs version end-to-end (neo v0.12.16 deploy, itself blocked on the PZM builder hardware).
…rgent-keep-both design: divergent .git keep-both (T10/T11 — the non-FF half of G5-git-5)
…alf (TIN-1620) (Jesssullivan#532) honey<->neo bidirectional .git roam converges via Jesssullivan#513 FF resolution on the deployed v0.12.16 fleet, both directions, 0 conflicts, fsck clean — where the 2026-06-09 canary stalled at 5 conflicts. The R3 handoff works: work on either host, resume on the other.
…oupled from Jesssullivan#517 crypto) (Jesssullivan#531) Delivers the stated purpose of Jesssullivan#517 (evidence rescue) WITHOUT the bundled WIP key-rotate crypto, which is BLOCKED (revocation-defeating defects, 65 commits stale — see Jesssullivan#517 review). 36 evidence files missing from main: the large-workdir-20260526 parity packet, shadow-inventory, and related roam-canary artifacts. Docs-only; no code.
…ivan#534) * git keep-both: park loser heads before ref pulls * docs: mark keep-both PR-4 in remote validation * git keep-both: defer non-head ref overwrites * harness(G5-git-13): loser-side no-loss guard two-machine convergence Add the G5-git-13 stage to the .git-as-files fsck/conflict harness — the PASS counterpart to Stage 4's corruption-risk evidence. It reproduces the keep-both PR-4 loser-side no-loss guard (design S10) at the ref level with pure git on BOTH machines and asserts the no-loss invariant: after a divergent .git pull overwrites refs/heads/main with the winner head, the loser's committed head is parked at refs/tcfs/theirs/<self_device>/heads/* first, so both sides' committed heads stay reachable (rev-list --all) and each .git is fsck-clean. This is the two-machine convergence row that flips G5-git-5 green (closes the converges-never gap). Fail-before/pass-after verified: with the park the stage exits 0 (PASS); neutralizing the park orphans the loser tip and the stage exits 1 ("loser tip unreachable (ORPHANED)"). * git keep-both: harden loser guard edge cases * fix(keep-both PR-4): test helper reads manifest key from remote index The loser_guard tests' upload_ref_blob helper returned UploadResult.hash (the file-CONTENT hash) as the pull manifest_hash, but the ref blob is retrievable only at its remote-index manifest key (manifest_object_id). download_ref_sha_from_manifest therefore always returned None, so every guard path fell through to the "incoming SHA unreadable" DEFER — which the three defer-expecting tests passed on coincidentally while loser_guard_parks_divergent_local_head_before_ref_pull (which needs the incoming SHA to prove the non-ancestor overwrite and park) failed on CI. Read the manifest key from list_remote_index(...).manifest_hash, matching the working git_ff_resolution seeding pattern. All four loser_guard tests now exercise a real incoming-SHA download: the parks test parks + applies, the defer tests defer via their intended non-parkable/module paths. * git keep-both: guard ref deletes and suffix collisions * docs: correct PR-4 builder blocker framing * git keep-both: CAS-protect loser ref mutations * git keep-both: close ref-class raw fallthroughs * git keep-both: guard symbolic submodule HEAD * git keep-both: validate new packed-refs syntax
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Linear: TIN-2552, TIN-1620
Validation
No local cargo/nix builds were run on neo; this sync relies on GitHub CI.