feat(core): doc_gate refuses the namespaced short-name alibi (GREEN)

The fieldtest's spec_gap closed per the #316 decision (tighten, not
ratify): doc_gate normalizes the doc against both the full entry name
and its bare display segment after the last :: -- an extension node
ns::Scale with doc "Scale" now refuses (RestatesName), matching the
register seam's effective bare-name behaviour. Unnamespaced entries
are unchanged (the checks coincide); genuine meaning lines containing
the name as a substring stay accepted (equality, not containment).
The C29 contract sentence carries the precision.

Gates: workspace green (98 suites, 0 failed -- incl. the C29 coverage
walk over every shipped doc under the tightened gate), clippy clean.

refs #316
This commit is contained in:
2026-07-23 21:12:39 +02:00
parent b04b56148d
commit cfc2d9f5b1
2 changed files with 5 additions and 2 deletions
+2 -1
View File
@@ -370,7 +370,8 @@ pub fn doc_gate(name: &str, doc: &str) -> Result<(), DocGateFault> {
.map(|c| c.to_ascii_lowercase())
.collect()
}
if norm(doc) == norm(name) {
let short_name = name.rsplit("::").next().unwrap_or(name);
if norm(doc) == norm(name) || norm(doc) == norm(short_name) {
return Err(DocGateFault::RestatesName);
}
Ok(())
@@ -6,7 +6,9 @@ everything entering the content-addressed store describes itself; a refusal
for a missing description names the entry, the field, and the rule. One
shared deterministic gate — `doc_gate` in aura-core, importable by every
seam per [C28](c28-stratification.md); it fails on an empty/whitespace doc
and on a doc that normalizes to the entry's own name
and on a doc that normalizes to the entry's own name — the full id or its
bare display segment after the last `::`, so a namespaced extension entry
cannot pass its short-name alibi
(`DocGateFault::{Empty, RestatesName}`) — guards three seams:
1. **Compile/unit seam (engine-shipped).** `NodeSchema.doc` is a required