Commit Graph

27 Commits

Author SHA1 Message Date
Levi Neuwirth ed78465aa7 CI fixes v4 2026-05-18 13:32:56 -04:00
Levi Neuwirth fbfc6a105a CI fixes v3 2026-05-18 13:23:18 -04:00
Levi Neuwirth e76526023a CI fixes v2 2026-05-18 13:12:10 -04:00
Levi Neuwirth 146583d32a CI fixes 2026-05-18 12:24:35 -04:00
Levi Neuwirth b6689a3927 rust-toolchain.toml: add rust-analyzer component (pin regression fix)
The 1.95.0 pin (7171282) shipped components = [clippy, rustfmt],
profile = minimal. The M4 LSP acceptance suite
(tests/m4_acceptance.rs:1111 m4_5_rust_analyzer_initializes) spawns
`rust-analyzer`; its skip-guard only checks PATH presence. The
`rust-analyzer` on PATH is a rustup proxy shim — with the directory
override active it resolves against the pinned toolchain, finds no
rust-analyzer component, and the spawn dies before the LSP
handshake, so the test runs (doesn't skip) and panics "must observe
Initialized event". This was masked in CI before the pin because the
Test job died at compile (rope.rs:1076); fixing compile unmasked it.

A pin must ship a toolchain complete for the project's own test
surface. Adding `rust-analyzer` to components.

Verified under 1.95.0: `rust-analyzer --version` resolves;
m4_5_rust_analyzer_initializes passes (was the sole failure in the
ubuntu Test legs — CI log showed m4_acceptance 52 passed / 1 failed,
all other suites ok). rust-toolchain.toml-only; no code change.

Still independent / triage-pending (unchanged): macOS F9 nix
PeerCredentials (Test (macos-*)), M1/M4/M6 perf/fuzz gates.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 11:58:46 -04:00
Levi Neuwirth 7171282b57 Pin toolchain to 1.95.0 + mechanical clippy/rustc fixes
CI was red on every recent main commit (pre-existing, not from the
V0.2/audit work): the workflow installs rolling `stable`, which on
the runners is ~1 year newer than the local toolchain that validated
the code. Under `RUSTFLAGS: -D warnings` + `clippy -- -D warnings`,
new rustc/clippy lints across pre-existing code became hard failures.
Confirmed identical on the 4 commits before v1.0-rc (e.g. the
`rope.rs:1076` unused_parens compile error is byte-identical there).

Resolution:

- `rust-toolchain.toml` pins channel 1.95.0 (the validated version).
  The repo directory override makes every cargo invocation use it
  regardless of what the CI action installs, eliminating the
  local/CI toolchain-drift class permanently. Bump deliberately.
- Mechanical lint fixes (~17 sites, all the trivial/auto-fixable
  class — no logic change): `cargo clippy --fix` + `cargo fix`
  applied the machine-applicable set; hand-fixed the residuals:
  daemon.rs (duplicated #[allow]), completion_framework.rs
  (sort_by -> sort_by_key/Reverse), attach.rs (map().unwrap_or ->
  map_or, crdt), buffer.rs (is_some+expect -> match, crdt),
  m10_11_acceptance.rs (if -> match guard x2, crdt).
- `cargo fmt --all` (clippy --fix left overlay_paint.rs unformatted).

Verified clean under 1.95.0, all lanes: fmt 0 diffs; clippy
--all-targets -D warnings clean for luajit, lua54, AND crdt;
-D warnings build clean luajit+lua54; doc tests pass; lib 1223/0;
autofix-modified tests (m7_5, m8_1 incl. the Finding-2 fs_watch fix)
pass.

Scope: this clears CI red class #1 (toolchain-gap lints) only.
Independent and still triage-pending: #2 macOS F9 nix
PeerCredentials portability (Test (macos-*)), #3 M1/M4/M6 perf/fuzz
gates. Per plan, those are triaged after CI confirms #1 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 11:38:57 -04:00
Levi Neuwirth c50db222d3 V0.2-prerequisite pull-forward + M10.11 clean audit round
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>
2026-05-18 10:31:31 -04:00
Levi Neuwirth 04ac1fbd8d stderr default 2026-05-17 22:17:36 -04:00
Levi Neuwirth 789633a56b support fish over daemon 2026-05-17 21:37:07 -04:00
Levi Neuwirth e913467a9f force -T 2 2026-05-17 19:28:48 -04:00
Levi Neuwirth 99beaa7e47 force -T 2026-05-17 19:23:31 -04:00
Levi Neuwirth b5da42b954 write to fd1 2026-05-17 19:18:16 -04:00
Levi Neuwirth fa1ee116bf daemon 2 2026-05-17 19:11:32 -04:00
Levi Neuwirth e226d01ec9 daemon debugging 2026-05-17 19:03:47 -04:00
Levi Neuwirth a8a8697c6f daemon remote fix 2026-05-17 18:54:20 -04:00
Levi Neuwirth 8490e79bbb M10.11 fixes 2026-05-15 22:04:42 -04:00
Levi Neuwirth b6c07cb840 M10.11: adversarial two-laptop acceptance + jitter; the M10 arc verified
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>
2026-05-15 20:51:00 -04:00
Levi Neuwirth 05fbbd9919 M10.10: complete optimistic-apply keystroke path + Day-5 corrections
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>
2026-05-15 16:40:46 -04:00
Levi Neuwirth 45be65b026 M10.10 ship gate
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>
2026-05-13 16:28:46 -04:00
Levi Neuwirth f1e9e209c0 gitignore: add /M*-API-SURVEY.md to internal-only patterns
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>
2026-05-09 17:38:48 -04:00
Levi Neuwirth 587a2a15de M9 ship gate
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>
2026-05-09 15:04:23 -04:00
Levi Neuwirth 3a35d0b0f8 M8 ship gate 2026-05-07 16:55:14 -04:00
Levi Neuwirth 3bbe5bf95d M8.1: filesystem worker primitives" 2026-05-07 16:54:29 -04:00
Levi Neuwirth 0b715de505 M7 tail: package system, audit lint, lockfile, resolver 2026-05-07 16:50:37 -04:00
Levi Neuwirth 291eb0fd8d Fix CI and Documentation issues 2026-05-04 10:19:19 -04:00
Levi Neuwirth c8d0d67615 Fix PTY final-output drain race 2026-05-04 09:44:30 -04:00
Levi Neuwirth 4da4b09d5d Initial commit: v0.1.0 2026-05-03 19:51:06 -04:00