2026 07 25 int 001 edit path
Verification result
PASS — round 5, no conditions and no pre-authorisation: the verifier inspected the final state itself.
This row went through five rounds across two verification threads. The FAIL records are kept alongside:
- 2026-07-25-int-002-delete-preview-round-1-FAIL.md (rounds 1–2, which covered INT-001 and INT-002 together)
- 2026-07-25-int-001-edit-path-round-4-FAIL.md
Why this row took five rounds
The row's cited files did not include src/core/commands/library_bridge.cpp —
the bridge carrying most of its "edit" claim. The round-2 pass audits the files a
row points at, so it never looked there, and at that moment the bridge was
silently erasing every vendor TaggedValue on each bridged edit. Its conditional
clearance of INT-001 would, if acted on, have stamped verified on a data-loss
defect inside the row's own edit clause.
check_conformance_matrix.py check [3] validates that cited paths exist, never
that relevant paths are cited. Nothing else catches this. The citation gap was
not bookkeeping — it was the mechanism.
Scope
- Requirement IDs: SACM23-INT-001. Not re-litigated: SACM23-INT-002 (already
verified), SACM23-LIB-002 (verifiedby a separate thread), COMPAT rows. - Files inspected (round 5 and 4):
src/core/commands/library_bridge.{h,cpp},src/core/audit/event_replayer.cpp(BridgeViaLegacy),src/core/audit/strategy_migration.cpp,src/core/commands/command_bus.{h,cpp},src/core/app_state.cpp(sync_library_document),src/sacm_adapter/library_load.{h,cpp},libs/sacm/include/sacm/compat/preserve.h,tools/sacm/check_conformance_matrix.py,tests/test_save_from_library.cpp. - Ran: Release build clean (layer gate passed),
ctest -C Release→ 792/792,check_conformance_matrix.py→ all five checks OK, targeted run of both INT-001 preservation tests and the four INT-002 controller tests → 10/10.
Findings
Blocking findings from rounds 1 and 4, and their resolutions:
| Severity | Finding | Resolution |
|---|---|---|
| Major (round 4) | The same self-rebuild-through-a-lossy-projection pattern survived at two more sites, neither using the preservation-restoring reload: AppState::sync_library_document and the command bus's Stage-5 net. Reachable without a project: a file opened standalone takes the no-bus dispatch branch, which syncs after every command, so one edit erased preserved foreign XML and the next save wrote the degraded document to disk. In-project, any unflipped command (NodeOnly removal, undo) did the same. |
Both now use reload_document_keeping_compatibility_content. Pinned by SACM23_INT_001_NoBusEditPreservesUnknownContentThroughSync and ..._UnflippedBusCommandPreservesUnknownContentInTheDocument, each confirmed to fail with its line reverted. |
| Major (round 4, second pass) | The Stage-5 net fix was unpinned. No assertion anywhere could fail if it were reverted: the only test reaching that branch compares canonical hashes, and those drop preserved content on both sides. A fix with no test that can fail is not evidence — and this was the third occurrence of the pattern in one session, where twice already the untested sibling is where the defect lived on. | Test added; falsification confirmed. The verifier additionally checked reachability structurally: library_synced is only ever assigned false, so the branch guard reduces to exactly what the test asserts. |
| Minor (round 4) | The row's cited files omitted the bridge. library_bridge.cpp and event_replayer.cpp were cited on LIB-002, not INT-001. |
Both added, plus command_bus.cpp. |
| Major (rounds 1–2) | Matrix note named the wrong delete policy (DeleteReferencingRelationships; code uses ScrubReferences), repeated in the apply_delete_element header comment. |
Corrected in both places. |
Open, non-blocking:
| Severity | Requirement ID | Finding | Required fix |
|---|---|---|---|
| Info | SACM23-INT-001 | CommandContext::library_synced is dead state — declared, reset false each dispatch, read once, never set true. The comment at command_bus.cpp:181 describes it as the flag a command sets when it routes its edit through a library operation; no command does, and the exclusion is carried entirely by library_primary. Harmless, but it is comment-vs-code drift of the same class this session has been chasing, sitting in the branch that just cost four rounds. Deliberately not fixed here: changing code after the pass that cleared it is the habit this row exists to warn against. |
Remove the field and the clause, or set it where the comment claims. |
| Info | SACM23-INT-002 | Prior non-blocking items unchanged: no document_revision on DeletePreview; preview/apply disagreement on unresolvable ids; preview_delete_elements' unsupported comment rationale; ACP consequences sourced from loaded_case.acps rather than the library document. |
Follow-up slices. |
Matrix updates allowed
- May mark verified:
SACM23-INT-001, citing this record. - Unchanged:
SACM23-INT-002andSACM23-LIB-002stayverified. LIB-002's note needs correcting — the fix landed under a different row, so its "unflipped path is lossy" disclosure was accurate when written and only became stale afterwards — and that correction belongs to LIB-002's own verifier, not to this record and not to the implementer.
On process
Recorded because it changed the outcome twice, in the verifier's own words:
Holding the row and asking me to confirm the final state — rather than acting on my pre-authorisation — is what caught both the unpinned Stage-5 fix and, before it, the bridge defect. The pre-authorisations I offered in rounds 2 and 3 would each have stamped
verifiedon real data loss. I would keep that habit for any row whose fix arrives after the pass that cleared it.
Follow-up slice suggestions
- Retire the lossy-overload footgun. Four sites, three defects, one session, and the shorter call is still the wrong one. Its own slice with its own verification — and flip the default rather than only renaming, so a new caller has to opt out of preservation deliberately.
- A preservation assertion in the convergence fixtures. Give
EditFixturea byte-level "vendor content survives" helper and apply it to every unflipped-command test, making the property structural rather than per-site. The canonical hash is blind to this class by design. - Citation-coverage check in
check_conformance_matrix.py— flag a row citing a file that no ID-bearing test exercises. This row is the empirical case: the gap was invisible to all five existing checks.