Automerge backed Markdown editor for the Atmosphere
README.md

Structural Coverage #

tests/structural-coverage/runner.mjs measures a bounded behavioral matrix against the normal app at http://localhost:7480/.

The denominator is 9 cases x 2 modes = 18 cells. It is not a code-coverage percentage and does not claim coverage of the full structural-edit universe. Every cell uses a fresh browser context, creates types/task.json and a uniquely named note through the public Vault API, types the seed through CM6, and performs the operation with browser keyboard input. No writer query flag, raw Automerge marker seed, mock, delete-user-data step, or sync server is used. Type-tagged fixtures receive explicit fields through the actual Record widget.

Run one tracer cell first:

nix develop --command sh -c 'PLAYWRIGHT_CHROMIUM_BIN="$(command -v chromium)" REAMS_STRUCTURAL_COVERAGE_CASE=list-join npm run test:structural-coverage'

Run the matrix after the parent starts port 7480:

nix develop --command sh -c 'PLAYWRIGHT_CHROMIUM_BIN="$(command -v chromium)" npm run test:structural-coverage'

The machine-readable result is written to docs/verification/structural-coverage/sparse-original-report.json. passed requires actual CM text, persisted text, valid sparse native indexes at every stage, exact owner/fact placement, non-vacuous opaque payload preservation on typed owners, original identities/facts/payloads on undo, resulting identities/facts/payloads on redo, and reload to agree. Failures and unavailable setup produce a nonzero exit status. setup-error is distinct from an assertion failure. If the parent server is absent, the report records parent-not-started-unknown-environment rather than inventing a pass. The disposable server must use VITE_DISABLE_WEBSOCKET_SYNC=1; that network safeguard is independent of writer selection.

Existing Browser Evidence #

These supporting rows are not additional cells in the 18-cell denominator:

Existing row Reference Scope
Text-first acceptance tests/spikes/text-first-browser.acceptance.test.ts IndexedDB durability, undo/redo, CRLF and plain-text spike fixture
Structural keyboard invariants tests/invariants/bombadil/structural-keyboard.test.ts and tests/invariants/bombadil/structural-actions.ts CM6 keyboard mapping, structural identity and Bombadil campaigns
Structural integration tests/format-preservation/editor/block-ops.integration.test.ts Editor block operations and readMarkdown assertions

The current original-matrix run is recorded in sparse-original-report.json; the additional Gate 1 matrix is recorded in sparse-gate1-report.json. The older report.json is retained as historical dense-contract evidence and is not current certification. A red cell is a real behavioral failure, including an unavailable native node index; the runner records the phase, expected text, actual text, native status, nodes, and decoded facts instead of converting it to setup success.

Latest Measured Results #

Checkpoint a8577896 records the original 10 passing / 8 failing matrix. After the structural fixes, the parent reran the same cases and assertions: 18 passing cells, 0 failing cells, and 0 setup errors. These counts include source and live-preview separately. No case expectations were weakened to make the fixes pass.

Operation Source Live Preview Observation
Root-level list join Pass Pass Left identity and untouched sibling survive; undo restores the source
Typed root-level list join Pass Pass Friday/Monday destination-wins facts survive undo/redo/reload
Delete two task items Pass Pass Deletes owned markers/facts, preserves sibling, and restores original IDs/fields on undo
Paragraph to heading Pass Pass Native kind follows the AST while original identity and opaque data survive
Paragraph to code fence Pass Pass Reversible native marker update follows the code block
Plain paste introducing paragraphs Pass Pass New owners are included in the paste history entry; redo reuses the same IDs
Single nested-list indentation Pass Pass Tested item IDs survive indentation, undo/redo, and reload
Cut and restore a Type tag Pass Pass Same subjects and stored fields survive removal/restoration
Tagged paragraph split Pass Pass Tagged fragment retains identity and fields; redo reuses fresh ID

The Type-tag case does not yet prove pasting that tag onto another existing subject. The indentation case is one shallow item, not arbitrary subtree edits. The denominator is deliberately finite; neither these passes nor the earlier happy-path smoke scripts imply complete structural coverage.

Additional focused tests cover nested-child deletion, mixed full/partial deletion ranges, replacement preserving an existing task, native scalar type mismatch, conflicting source markers, and repeated heading/paragraph/fence transitions without awaiting a projection refresh. The latest Gate 1/2-focused projection/accounting run passed 49/49 tests; typecheck and diff check also passed.

The additional Gate 1 matrix now covers parent-line deletion with retained children, owned-block splitting, multi-block formatting, and paste spanning existing blocks. Remote structural interleaving and arbitrary subtree edits remain outside this bounded matrix. The broad legacy-test migration is separate; 18/18 plus 16/16 is not a claim that the full regression suite is green.