The mechanical half, riding on the census in the previous commit.
* 342 in-process construction sites in 65 files now take
`new_with_roots` / `open_with_roots` with `iso::roots()`. The isolated
base is a pure function of `CARGO_TARGET_TMPDIR` — no counter, no
`OnceLock` — so two copies of the module in one binary agree instead of
racing, and the tree lives somewhere `cargo clean` owns rather than
leaking into `/tmp` once per run. It is shared deliberately:
materialization is content-gated and idempotent, so a per-test
directory would repeat it ~330 times per run for a byte-identical
result.
* `journey_acceptance` keeps the ambient `EditorState::open`, because
proving the production entry point has a caller is the whole of what
that ratchet is for. Rev 2's "isolated by the environment its binary is
launched with" was not a mechanism — cargo launches each test binary
with the caller's environment, and a binary cannot re-point its own
roots before its tests run. Each test is now a thin parent that
re-execs this binary for its own name with controlled roots, and the
child runs the body against production's call. Two pins guard it: the
child asserts all four roots resolve inside the controlled base, and
the suite asserts against its own source that it has not quietly taken
the seam. The parent also asserts the child ran `1 passed` — a stale
`--exact` filter would otherwise hollow the whole thing out silently.
* The shared spawners take all five storage variables.
`spawn_daemon_process_with_env` set `HOME` and `XDG_CONFIG_HOME` only;
`HOME` is a FALLBACK, so it isolates a root only while the matching
`XDG_*` is unset — the harness's apparent adequacy was a property of
one developer's environment. The PTY spawner backfills whichever of the
five its caller did not pin. The 10 direct `Command::new` daemon and
attach spawns get the same treatment.
Three suites had `mod common;` behind `#[cfg(feature = "crdt")]`;
`common::iso` is needed in every build, so those are ungated. Files that
already pull in `common` reach `iso` through a `use` rather than a second
`#[path]` declaration — loading one file as two modules is
`clippy::duplicate_mod`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lv428Fth9LRtffwJSsqH7T
`version_mismatch_clean_disconnect` asserted that the `VersionMismatch`
`server` field equals `ADVERTISED_PROTOCOL_VERSION`. Until this stage
that constant and `PROTOCOL_VERSION` were both 20, so the assertion could
not distinguish them and happened to pin the wrong one. Stage 2B-3 splits
them — the advertised value is a compatibility floor, `PROTOCOL_VERSION`
is the ceiling a frontend may counter-offer up to — and the daemon
correctly reports the ceiling, so the stale assertion failed on all four
CI Test legs.
The production behaviour is right and is unchanged here. Only the test
moves, and it now pins the divergence in both directions: the `Hello`
assertion above holds the advertised floor, a new `assert_ne!` holds the
fact that the reported version is deliberately not that floor.
That second assertion is why this is not a one-character edit. Stage
2B-3's own pin for this rule, `an_unsupported_offer_is_refused_by_name`,
is `#[cfg(feature = "crdt")]` and CI never enables `crdt` — so it is dark,
and `m5_5_acceptance` is the only live guard CI runs on this behaviour.
Bite: reverting `src/daemon.rs:757` to `ADVERTISED_PROTOCOL_VERSION`
fails the test with `left: 20, right: 21` and the named message; restored,
it passes. Verified against the whole suite under an isolated
`XDG_CONFIG_HOME` — 3303 tests, 100 binaries, zero failures.
Reserve the additive v21 panel schema without advertising it in the
server-first production handshake. Pin a real shipped-v20 client attach,
make the two aggregate-budget ratchets exactly one byte over, and update
the framing, coherence audit, handoff, and volatile lane record.
Root cause of the CI Lint regression: commit 6113c53 bumped
rust-version 1.85 -> 1.95. clippy::collapsible_if is MSRV-gated —
collapsing `if let { if let }` needs let-chains, stabilized in Rust
1.95. At MSRV 1.85 clippy suppressed these; at 1.95 it emits them.
The patterns were pre-existing; the MSRV bump surfaced 47 of them
and turned `Lint (luajit)` / `Lint (lua54)` red at HEAD (was green
through PR #7; red from PR #8 = the release-prep MSRV bump).
Resolution (operator-chosen: autofix into let-chains): applied
`cargo clippy --fix` across the luajit, lua54, and crdt lanes
(--all-targets). The fix only applied with the lint at warn level;
`-- -D warnings` turns it into an error and blocks --fix.
Verified on the pinned 1.95.0, all three lanes:
clippy --all-targets -D warnings clean (luajit / lua54 / crdt);
fmt 0 diffs; lib tests 1223/0.
Note: the prior #6 "quiescent audit, clippy clean" was inaccurate —
clippy was not actually re-run there (build/version/fmt only), so
this MSRV-gated regression went uncaught until the live attach-debug
investigation surfaced it. This commit restores genuine clippy
cleanliness at MSRV 1.95.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Post-ship-gate completion of M10.10 (optimistic local edit
application, Path β). The milestone core landed in 45be65b
"M10.10 ship gate"; this commit completes the frontend keystroke
path and absorbs Day-5 corrections.
Completes:
- optimistic::frontend_event_for_keystroke — keystroke orchestrator
(classify_key predicate → mirror-ready check → CrdtOp or Key
fallback per Refinement 4 graceful degradation).
- BufferMirror cursor tracking (active_buffer, cursor_byte_pos via
CursorByte) + char-boundary-aware delete helpers (prev/next_char_len)
so multibyte backspace/delete don't trip loro's mid-codepoint
rejection.
- buffer.rs: crdt_state accessor (was test-only) now production —
daemon's BufferSnapshot export path uses it.
Day-5 corrections:
- packages/manifest.rs: fix pre-existing M8-era proptest generator
that produced ".."-containing entry paths the parser correctly
rejects (segment-structured regex; stale regression seed removed).
Out of M10.10 scope; absorbed so future milestone sweeps see clean
output instead of a known-failing test requiring prose.
- tests: extract inline PTY/daemon helpers to shared tests/common/
module (m5_5, m5_8 now import; no coverage change — m5_5 retains
19 m10_10 tests). tests/common/ added (required for compilation).
Audit history (M10.10-AUDIT.md is gitignored internal-only; this
message is the sole version-controlled record):
M10.10 PASSES within Path β scope (end-of-line optimistic visual
paint; mid-line/delete-forward round-trip; full CRDT-op exchange
across the text-input scope). The initial audit verdict was WRONG —
optimistic-apply was structurally unreachable in the production
binary (build_capabilities advertised crdt_replica: false). Six
post-audit review rounds surfaced 28 findings (F5–F32) beyond the
framing pass's original 4. Six M10-era discipline additions emerged,
each empirically grounded: end-to-end-exercise check (bidirectional
scope), composition-consistency check, verification-milestone premise
check, library-API verification check, forward-pointer-comment
hygiene, methodology-composition check.
Scorecard adopts Option C dual methodology: layer (a) framing-pass
accuracy is 7/8 milestones-not-findings AND 2/8 findings-as-failures
— the 5/8 spread is the density diagnostic (M10.10's defining
characteristic; neither number alone is honest). Layer (c): 7/8 and
6/8 (M10.8 inherited-gap cluster). Budget honesty: 5-day
pre-authorization covered anticipated implementation surprises (K1,
Risk #6 a); Finding 3 was a third surprise absorbed via compression,
not structural slack; the six post-audit rounds were entirely
unbudgeted and are the milestone's dominant cost. M10.10's density
is partly forecastable — it is the only M10 milestone with all three
of: architectural reversal, multi-milestone integration, and
verification depending on incomplete cross-milestone wiring.
Ship-gate clean on clean checkout (cargo clean + rebuild): luajit+crdt
1364/1364, luajit 1211/1211, lua54+crdt 1364/1364, lua54 1211/1211,
m5_5 daemon-e2e 36/36, perf 1MB=1.1ms vs 10ms gate, clippy 0 across
feature combos, fmt clean. One transient flake observed
(async_runtime::supersede_cancels_in_flight_job_within_50ms — timing
test starved under concurrent compile load, non-reproducible in
isolation, known infra pattern, not an M10.10 regression).
Next: M10.11 (two-laptop acceptance) inherits all six discipline
additions; v1.0 ships after M10.11.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Land the optimistic local-edit-application layer on top of the M10 CRDT
foundation: frontend-side rope replica with local edit application,
daemon-authoritative broadcast, and bidirectional cursor reconciliation.
Keystrokes feel instantaneous because the local replica answers next-render
queries before the daemon round-trip completes, while the daemon remains
the single source of truth for conflict resolution and broadcast to remote
replicas.
Architecture beats:
- BufferMirror (src/buffer_mirror.rs) holds a per-frontend rope replica
with explicit cursor-staleness tracking. Every event that may move the
active cursor or swap the active buffer marks the mirror stale; the
next CursorByte from the daemon clears it.
- CrdtOpOrigin {OptimisticReplica(FrontendId), DaemonKey} routes broadcast.
OptimisticReplica skips re-application on the originating frontend
(already applied locally); DaemonKey broadcasts to all replicas including
source -- covers Lua-driven and generated-buffer edits that bypass the
optimistic path.
- Generated buffers (*help*, *workers*, *pmacs-instance*, *errors*) funnel
apply_edit output through queue_daemon_origin_crdt_op so post-attach
CRDT upgrades don't drop their edits.
- forbid(unsafe_code) preserved throughout; loro 1.12 added as the CRDT
engine.
Audit posture: M10.10 shipped through six post-audit review rounds with
twenty-eight cumulative findings, most categorized as "incomplete
application of a prior round's mechanism." The audit doc records
grep-driven exhaustiveness as the standing countermeasure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>