From cfc2d9f5b1e4e48e2a8afcf6d39b8bf6e936d977 Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 23 Jul 2026 21:12:39 +0200 Subject: [PATCH] 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 --- crates/aura-core/src/node.rs | 3 ++- docs/design/contracts/c29-self-description.md | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/aura-core/src/node.rs b/crates/aura-core/src/node.rs index 969f792..4b7f089 100644 --- a/crates/aura-core/src/node.rs +++ b/crates/aura-core/src/node.rs @@ -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(()) diff --git a/docs/design/contracts/c29-self-description.md b/docs/design/contracts/c29-self-description.md index 19d765f..3d7db7e 100644 --- a/docs/design/contracts/c29-self-description.md +++ b/docs/design/contracts/c29-self-description.md @@ -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