test(drift): RED — anchor-presence must scope to jsonc fenced blocks
Adds `anchor_presence_check_is_scoped_to_jsonc_blocks` to
`design_schema_drift.rs`. The test pins the property in two
directions: an anchor mentioned only in prose must report ABSENT
under the scoped helper; an anchor inside a ```jsonc``` block must
report PRESENT; the live `design/contracts/data-model.md` must
remain PRESENT (anti-over-narrowing guard).
The helper `anchor_in_jsonc_block` does not yet exist — this test
compile-blocks the entire `design_schema_drift` file, which is the
intended contract pressure: the GREEN side must introduce the
helper for any drift test to run.
Pre-rolesplit the audit framed this as "anchors live in Decision 11
instead of §Data model"; the role-split iter (176821c) made
`data-model.md` its own file, but the per-match scope was never
narrowed — `.contains()` still cannot tell jsonc-block anchors
(load-bearing) from prose anchors (incidental). This RED pins the
remaining surface.
refs #10
This commit is contained in:
@@ -350,6 +350,82 @@ fn design_md_anchors_every_parammode_variant() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The anchor-presence check must scope its substring match to ```jsonc```
|
||||||
|
/// (and ``` / ```json) fenced code blocks. The whole-file `.contains()` is
|
||||||
|
/// fidelity-widened: a future edit can delete the canonical schema entry for
|
||||||
|
/// a variant from inside a fenced block while leaving the anchor string
|
||||||
|
/// mentioned in surrounding prose (e.g. a "design rationale" footnote, an
|
||||||
|
/// inline reference like `the "t": "lit" form`, or a historical-note
|
||||||
|
/// section). The drift test would silently pass, and downstream LLM authors
|
||||||
|
/// would lose the canonical schema for a variant the AST still produces.
|
||||||
|
///
|
||||||
|
/// This test pins the property in two directions:
|
||||||
|
/// 1. A markdown string with the anchor present ONLY in prose (no fenced
|
||||||
|
/// block) must report ABSENT under the scoped helper. The unscoped
|
||||||
|
/// `.contains()` reports PRESENT for the same input — that mismatch is
|
||||||
|
/// the bug surface.
|
||||||
|
/// 2. A markdown string with the anchor present ONLY inside a ```jsonc```
|
||||||
|
/// block must report PRESENT under the scoped helper.
|
||||||
|
///
|
||||||
|
/// Gitea issue #10. The helper `anchor_in_jsonc_block` does not yet exist —
|
||||||
|
/// this test is RED until `skills/implement` mini-mode adds it and re-routes
|
||||||
|
/// the six existing call sites onto it.
|
||||||
|
#[test]
|
||||||
|
fn anchor_presence_check_is_scoped_to_jsonc_blocks() {
|
||||||
|
// Anchor mentioned only in prose — the false-pass surface. The whole
|
||||||
|
// sentence after the heading is plain markdown body text; no fenced
|
||||||
|
// block exists in this fixture at all.
|
||||||
|
let prose_only = r#"# Data model
|
||||||
|
|
||||||
|
The `"t": "lit"` form used to be the canonical literal anchor. See
|
||||||
|
historical note below.
|
||||||
|
|
||||||
|
## Historical note
|
||||||
|
|
||||||
|
Older drafts pinned the literal schema as `"t": "lit"`; the current
|
||||||
|
schema uses a different shape (see commit log).
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// Anchor present only inside a fenced jsonc block — the true-positive
|
||||||
|
// surface. Prose outside the block does not mention the anchor.
|
||||||
|
let jsonc_only = r#"# Data model
|
||||||
|
|
||||||
|
The literal form is canonical.
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
{ "t": "lit", "lit": Literal }
|
||||||
|
```
|
||||||
|
|
||||||
|
End.
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// Unscoped substring match — what the file does today. Both inputs
|
||||||
|
// report PRESENT, and that is the bug: prose-only must not count.
|
||||||
|
assert!(prose_only.contains(r#""t": "lit""#));
|
||||||
|
assert!(jsonc_only.contains(r#""t": "lit""#));
|
||||||
|
|
||||||
|
// Scoped helper — what the file must do. Prose-only is ABSENT,
|
||||||
|
// jsonc-only is PRESENT. This call is the RED: the helper does not
|
||||||
|
// yet exist, so this test fails to compile until `implement` mini-mode
|
||||||
|
// factors it out and re-routes the six call sites onto it.
|
||||||
|
assert!(
|
||||||
|
!anchor_in_jsonc_block(prose_only, r#""t": "lit""#),
|
||||||
|
"scoped helper must NOT count an anchor that lives only in prose"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
anchor_in_jsonc_block(jsonc_only, r#""t": "lit""#),
|
||||||
|
"scoped helper MUST count an anchor that lives inside a ```jsonc``` block"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Live document: the helper must also report PRESENT for the live
|
||||||
|
// data-model.md (proves the helper does not over-narrow and break
|
||||||
|
// the existing six checks).
|
||||||
|
assert!(
|
||||||
|
anchor_in_jsonc_block(DATA_MODEL, r#""t": "lit""#),
|
||||||
|
"scoped helper must find live anchors inside data-model.md ```jsonc``` blocks"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Nested struct key anchors must be present in design/contracts/data-model.md.
|
/// Nested struct key anchors must be present in design/contracts/data-model.md.
|
||||||
/// These keys appear inside `Suppress`, `ClassMethod`, `InstanceMethod`,
|
/// These keys appear inside `Suppress`, `ClassMethod`, `InstanceMethod`,
|
||||||
/// and `Type::Forall` — they are not discriminators but they ARE part
|
/// and `Type::Forall` — they are not discriminators but they ARE part
|
||||||
|
|||||||
Reference in New Issue
Block a user