Editor starter-product checks
Every case here is a starter-product check, owned by docs/starter, not a Protocol tier. All existing byte-preservation and edit assertions remain in CI. Directories describe content; corpus-index.json determines each case’s single owner.
Compatible editors apply structured edits to a .uw.md file and produce a new .uw.md that:
- Round-trips formatting for unrelated regions (untouched bytes stay identical, ignoring trailing whitespace).
- Honors the supersede vs replace policy from
BUILTIN_EDIT_POLICIES(UW_PROTOCOL.mdPart V). - Updates
_metaprovenance correctly (newversion,timestamp,actor, etc.). - Updates frontmatter
last_modifiedon every write.
Fixtures
Each scenario lives in its own subdirectory:
fixtures/<scenario-id>/
├── before.uwx.md Input file
├── operation.json The EditOperation to apply
└── after.uwx.md Expected outputEach scenario also includes a context.json describing the actor invoking the edit (source, agent_id, agent_version, actor) — required by the reference runner to populate _meta provenance.
Provided scenarios
| Scenario | Operation | What it tests |
|---|---|---|
frontmatter-set-recommendation | frontmatter_set of recommendation | Frontmatter update + last_modified bump |
section-replace-property | section_replace of property (manual source) | In-place section replace per BUILTIN_EDIT_POLICIES (no supersede) |
section-supersede-risk-rating | section_replace of risk_assessment (agent source) | Supersede chain: prior version flagged superseded: true, new version appended |
gaps-section-update | frontmatter_set with options.json: {maintainGaps: true} | Post-write maintainer hook regenerates the gaps section under actor system/gaps-maintainer |
parent-hash-stamp | section_supersede with options.json: {integrity: true} and context.json carrying parentHash | applyEditAsync recomputes content_hash and stamps parent_hash against the prior block's hash; content_hash is masked as <volatile> in baseline because canonicalization includes the timestamp |
stale-parent-rejected | section_supersede with context.parentHash deliberately wrong | Negative-path fixture: expected-error.json asserts applyEditAsync rejects with INT-02 |
Optional fixture siblings
context.json—EditContext(source, agent_id, agent_version, actor, optionalparentHash).options.json—ApplyEditOptions({integrity?: boolean, maintainGaps?: boolean, …}); whenintegrity: truethe runner routes the edit throughapplyEditAsync.expected-error.json—{code, category}for negative-path fixtures. When present, the runner asserts the edit fails with that code instead of comparing againstafter.uwx.md.
A compatible starter editor's output for before.uwx.md + operation.json MUST match after.uwx.md after both files are normalized (stripping trailing whitespace, CRLF differences, and volatile fields: last_modified, _meta.provenance.timestamp, ts= fence attributes).
Run via:
node scripts/run-conformance.mjs --suite=starter-editor