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.