Pulls a set of planned V0.2 prerequisites forward to ship in v1.0,
plus the clean audit-review round over that work.
V0.2-prereq implementations (documented promotions, not M11
surprises; operator raised the v1.0 public-API ceiling to absorb
them — see V0.2-PREREQUISITES.md "v1.0 pull-forward"):
- CC-1: `bypass_intercept` opts on buffer insert/delete/replace —
skips the Lua intercept chain only; preserves the same-buffer
re-entry guard, undo/dirty bookkeeping, view notifications, and
CRDT broadcast queueing.
- CC-2: `pmacs.buffer.on_removed(buf, cb)` + idempotent `:remove()`
handle; buffer-local keymaps pruned on removal. Fires for both
`pmacs.buffer.remove` and `.kill` (incl. interactive C-x k);
callback errors logged to *errors* without failing the removal.
- SP-4: `pmacs.buffer.from_file`.
- SP-5: `pmacs.fs.watch` (polling; `:cancel()`/`:is_cancelled()`).
- SP-7: `pmacs.async.yield_to_next_tick` (worker-free next-tick
yield); outline-aggregate repaint now uses it instead of
workers.sleep(0):await(), pinning propagation to one async tick.
- SP-1: `pmacs.editor.move_to_line` (0-based, clamps out-of-range).
- SP-6: `pmacs.outline.query` published by pmacs-outline.
- SP-3: audit rule 15 `reach-around-require-field` (Info).
- CC-3: runtime API-availability documented (docs-only).
Clean audit-review round (M10.11 framing stop-condition pass):
- Finding 1 (fixed): clippy needless_raw_string_hashes blocked
`clippy -D warnings` on both lanes; raw-string delimiter fixed.
- Finding 2 (fixed): fs_watch acceptance test was racy — the
`pending == 1` gate could not distinguish the in-flight baseline
stat from the steady-state poll sleep, so under load the mutation
raced the baseline (~1/3 fail in the default lane). Rewritten to
re-emit a distinct change each pump iteration; 6/6 on the
previously-failing invocation.
- Finding 3 (fixed): documented fs.watch's async-baseline startup
window and size+mtime-granularity detection limit.
- Finding 4 / SP-8 (logged, non-blocking, out of diff): a
pre-existing PTY-lifecycle test timing flake under severe CPU
oversubscription; src/process.rs untouched here.
CC-1's opts-extension-counts question resolved explicitly
(consistent treatment: counted; ceiling raised to fit).
Gate at normal load, both lanes: fmt clean; clippy --all-targets
-D warnings clean; non-crdt lib 1223/0; crdt lib 1377/0;
m8_1/m8_9/m8_10 green.
Not in scope here: v1.0 CHANGELOG body, version bump, the M10.11
Finding-4 (reattach undo) user-facing artifact, and the recorded
two-laptop manual acceptance — tracked as the remaining v1.0 steps.
.gitignore: M*-FRAMING.md added to the internal-only block for
consistency with the M*-AUDIT.md / M*-SHIP-GATE.md siblings.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The M10 acceptance milestone (two-laptop edit). Framing-pass review
reframed it from confirmatory to **adversarial** verification: the
verification-milestone premise check (M10.11's own discipline,
extracted at M10.10 Day-4) caught its own first-draft framing
asserting "the architecture is complete; this is the verification
milestone" — M10.10's initial verdict was wrong and took six
post-audit rounds, so the M10 arc's correctness is not safely
assumable. M10.11 actively tries to break the arc rather than
confirm it.
Implementation (src/daemon.rs, tests/m10_11_acceptance.rs,
tests/m10_11_perf.rs; prior-pass synthesis/PTY-doubled/Drop-guard
fixtures landed in 05fbbd9's tree, completed here):
- Jitter seam: PMACS_INSTANCE_LATENCY_JITTER_MS + _SEED (SplitMix64,
no-unsafe/no-dep, default 0xC0FFEE). Q6's "no new injection seams"
preserved — one sleep-site; jitter-mode delays CellDelta|CrdtOp,
fixed-latency mode stays CellDelta-only so criterion-1 behavior is
byte-identical. No drops (Tension B: "packet loss" = latency
variation only).
- Q13 adversarial scenarios: cat-1 (concurrent same-position
inserts → deterministic peer-id tiebreak, pinned "A1B1"), cat-2
(per-frontend undo under causally-pending delayed delivery → B's
no-op undo doesn't reach A's ops; converge "12"), cat-3 narrowed
(CRDT state converges across reattach via BufferSnapshot, pinned
"a1b1"; undo-across-reattach deliberately NOT asserted per
Finding 4).
- Q8 convergence-under-jitter (seed-pinned; delivery-order-
independent, pinned "aAbB").
- cat-1/cat-2 pass clean — the arc holds under attack at runtime.
Five findings, all pre-embed (framing-time / Day-1 grep / Day-2
implementation), zero post-audit revision rounds (audit/framing/
prereq docs are gitignored internal-only; this message is the sole
version-controlled record):
- F1 (framing-time): verification-milestone premise check caught its
own reframe — third arc instance of a discipline addition catching
a contemporaneous failure.
- F2 (Day-1): framing cited stale fixture locations (β
framing-pass-time incompleteness, not α temporal drift); Q3
promotion already done by 05fbbd9's DRY refactor.
- F3 (Day-1): adversarial layer empirically absent in prior
implementation — validates the reframe (everything confirmatory
existed, nothing adversarial did).
- F4 (Day-1, M5.8-inherited): reconnect issues a fresh FrontendId
(no handle_reattach), orphaning per-frontend undo across reattach.
Classified C; v1.0 action B-i (MANUAL-TEST-CHECKLIST Scenario 4
documents the limitation honestly + workaround) + B-ii
(V0.2-PREREQUISITES: SO_PEERCRED-min / token-extended paths).
Fourth end-to-end-exercise case; first extending the pattern
beyond M10.8 to a second prior milestone (M5.8).
- F5 (Day-2): Q6×Q8 composition miss — jitter target (CellDelta) ≠
criterion-3 assertion target (CrdtOp); caught pre-embed by the
composition-consistency discipline; resolved (B). M10.11-internal
composition miss (M10.10 Finding-2/4 shape), not inherited.
Scorecard (Option C dual): layer (a) 6/8 milestones-not-findings
(M10.11 joins M10.10 via F5's composition cluster) / 1/8
findings-as-failures; layer (c) 6/8 (M5.8 joins M10.8 via F4;
two clusters — CRDT-pipeline {F1,F3,F5a-M10.8}, reconnect-identity
{F4-M5.8}). Dual-value: layer (a) prediction failed on F5;
pause-point value held (caught pre-embed). M10.11's 5-finding
density empirically validates M10.10's predictive-density model —
property-(b)-at-max, no (a)/(c) → moderate, all pre-embed, zero
post-audit rounds. First validation of the model M10.10 produced.
Verification (clean checkout): lib luajit+crdt 1364/1364, luajit
1211/1211; m5_5 crdt 36/36 (criterion-1 byte-preserved through the
latency-site restructure) + non-crdt 15/15; m10_11 CI-default 5/5
(3 PTY-doubled #[ignore]d, operator-invoked pre-tag); clippy 0
both lanes; fmt clean.
The M10 arc is verified. v1.0 ships after M10.12 (release tag +
TRANSITION-M10.md + collaboration user guide, which inherits the
Scenario-4 honest wording).
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>
M10.1 produced an API survey doc as its working artifact (the audit-trail for
the loro-vs-yrs benchmark evidence). The existing patterns covered AUDIT.md /
SHIP-GATE.md / PREREQUISITES.md but not the survey shape; future research /
decision tasks producing similar empirical-evaluation docs are also covered
by this generalization.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Land the Model Context Protocol (MCP) integration as a transport binding,
not a built-in feature. Six Lua functions plus userdata methods expose
the substance of three MCP feature areas (resources, tools, prompts), a
notification dispatcher, and a non-trivial AI-assistance example package
that meets the architectural ship gate (spec/pmacs-spec.tex:1572): zero
direct calls into the Rust core, zero special-cased MCP handling outside
the public API, source under 2000 lines of Lua.
The M9.5 -> M9.6 -> M9.7 -> M9.8 layered composition validates the claim
"AI is a transport binding, not a feature" -- pmacs-mcp-ai composes with
pmacs-mcp-prompts.render and inherits notification handling transitively
through M9.7's package, demonstrating that the AI domain is a layer
above MCP, not a thread woven through the core.
Subtask shape:
M9.1 stdio transport + initialize handshake + restart policy
M9.2 resources with in-flight + settled cache and per-uri invalidation
M9.3 tools with isError-vs-JSON-RPC-error semantics + cancellation
M9.4 prompts with required-argument validation
M9.5 notification dispatcher (on_notification, off_notification)
M9.6 tools-as-commands fixture package + 12 audit findings disposed
M9.7 prompts-as-result-buffers fixture package + tree-sitter-md grammar
M9.8 AI-assistance fixture package (363+ LoC; 17/17 acceptance tests)
M9.9 formal package audit -- PASS on all three criteria
M9.10 release: TRANSITION-M9.md + MCP-for-package-authors guide
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>