2"""Enforce capability parity across the full source chain and Tier-2 documentation coverage."""
4from __future__
import annotations
10from pathlib
import Path
13REPO_ROOT = Path(__file__).resolve().parents[2]
14REGISTRY_PATH = REPO_ROOT /
"tests" /
"tooling" /
"capability_families.json"
15INVENTORY_PATH = REPO_ROOT /
"docs" /
"generated" /
"capability_inventory.json"
16GENERATOR = REPO_ROOT /
"tests" /
"tooling" /
"generate_capability_inventory.py"
28ALIAS_FIELDS = (
"Identity",
"Status",
"Migration")
31def slug(value: str) -> str:
33 @brief Convert a selector value into the anchor slug its entry must use.
34 @param[in] value Public selector value.
35 @return Lowercase underscore slug.
37 return re.sub(
r"[^a-z0-9]+",
"_", value.lower()).strip(
"_")
42 @brief Remove fenced code blocks and HTML comments so anchors inside examples do not count.
43 @param[in] text Raw page text.
44 @return Page text with code fences and comments blanked out.
46 text = re.sub(
r"<!--.*?-->",
"", text, flags=re.S)
47 text = re.sub(
r"^```.*?^```",
"", text, flags=re.S | re.M)
53 @brief Verify the committed inventory matches what the sources currently produce.
54 @return Violation lines.
56 result = subprocess.run(
57 [sys.executable, str(GENERATOR),
"--check"], capture_output=
True, text=
True, check=
False
59 if result.returncode != 0:
60 detail = result.stderr.strip().replace(
"\n",
"\n ")
61 return [f
"generated capability inventory is stale or invalid; run 'make docs-inventory'\n {detail}"]
67 @brief Index a family's parity records by source kind.
68 @param[in] family Inventory record for one family.
69 @return Mapping of source kind to its parity record.
71 return {record[
"source"][
"kind"]: record
for record
in family[
"parity"]}
76 @brief Verify the public selector set agrees with every declared parity source.
78 Every declared source kind is handled explicitly; an unrecognized kind is a
79 violation rather than a silent pass, because a source that is registered but
80 never compared produces a false assurance of parity.
81 @param[in] family Inventory record for one family.
82 @return Violation lines.
84 violations: list[str] = []
85 public = set(family[
"public_values"])
87 known = {
"c_string_map",
"c_token_map",
"c_switch",
"c_dispatch",
"c_enum"}
89 for record
in family[
"parity"]:
90 kind = record[
"source"][
"kind"]
93 f
"{family['id']}: parity source kind '{kind}' is registered but not verified by this audit"
97 accepted: dict[str, str] = {}
98 for kind
in (
"c_string_map",
"c_token_map"):
99 record = records.get(kind)
102 accepted = record.get(
"mapping", {})
103 path = record[
"source"][
"path"]
104 if kind ==
"c_string_map":
107 expected = {spec.get(
"maps_to")
for spec
in family[
"public_values"].values()}
108 for missing
in sorted(expected - set(accepted)):
110 f
"{family['id']}: '{missing}' is produced by the validator but the C parser "
111 f
"({path}) does not accept it"
113 legacy = set(record[
"source"].get(
"legacy_tokens", {}))
114 for token
in sorted(legacy - set(accepted)):
116 f
"{family['id']}: '{token}' is declared a legacy token but the C parser ({path}) "
117 f
"no longer accepts it; remove the declaration"
119 for extra
in sorted(set(accepted) - expected - legacy):
121 f
"{family['id']}: the C parser ({path}) accepts '{extra}' but the validator "
122 f
"never produces it; either expose it or remove it"
126 for kind, label
in ((
"c_switch",
"factory"), (
"c_dispatch",
"runtime dispatch")):
127 record = records.get(kind)
130 handled = set(record[
"values"])
131 path = record[
"source"][
"path"]
132 for token, enum
in sorted(accepted.items()):
133 if enum
not in handled:
135 f
"{family['id']}: token '{token}' resolves to {enum}, which the {label} in "
136 f
"{path} does not handle; selecting it would fail at runtime"
140 record = records.get(
"c_enum")
142 declared = set(record[
"values"])
143 path = record[
"source"][
"path"]
144 for token, enum
in sorted(accepted.items()):
145 if enum
not in declared:
147 f
"{family['id']}: token '{token}' resolves to {enum}, which is not a member of "
148 f
"the enum declared in {path}"
155 @brief Verify declared value metadata is complete, well-typed, and matches the sources.
157 @details Fails closed on the status field. A canonical value with no status, or with
158 a typo such as "suported", previously passed every check while generation
159 quietly defaulted it to supported - so a defective capability could read as
160 production-ready through an omission.
161 @param[in] family Inventory record for one family.
162 @param[in] registry_entry Registry entry carrying value metadata.
163 @return Violation lines.
167 metadata = registry_entry.get(
"value_metadata", {})
168 public = set(family[
"public_values"])
170 for stale
in sorted(set(metadata) - public):
172 f
"{family['id']}: metadata declares '{stale}', which is no longer a public value; "
173 f
"remove it from capability_families.json"
175 for undeclared
in sorted(public - set(metadata)):
177 f
"{family['id']}: public value '{undeclared}' has no metadata entry; "
178 f
"declare its status and whether it is canonical"
180 for name, spec
in sorted(metadata.items()):
181 target = spec.get(
"alias_of")
or spec.get(
"spelling_of")
182 if spec.get(
"canonical")
is False and not target:
184 f
"{family['id']}: '{name}' is marked non-canonical but names no alias_of or "
185 f
"spelling_of target"
187 if target
and target
not in metadata:
188 violations.append(f
"{family['id']}: '{name}' aliases '{target}', which is not a declared value")
190 if spec.get(
"spelling_of"):
194 f
"{family['id']}: '{name}' is a spelling of '{spec['spelling_of']}' and must not "
195 f
"declare its own status; it inherits one"
199 status = spec.get(
"status")
202 f
"{family['id']}: '{name}' declares no status; every canonical value and "
203 f
"deprecated alias must declare one of {list(VALID_STATUSES)}"
206 if status
not in VALID_STATUSES:
208 f
"{family['id']}: '{name}' has status '{status}', which is not in the closed "
209 f
"vocabulary {list(VALID_STATUSES)}"
212 if spec.get(
"alias_of")
and status !=
"deprecated":
214 f
"{family['id']}: '{name}' declares alias_of '{spec['alias_of']}' but status "
215 f
"'{status}'; an alias is by definition deprecated"
217 if status
in NON_SELECTABLE_STATUSES:
222 reachable = family[
"public_values"].get(name, {}).get(
"reachable",
True)
225 f
"{family['id']}: '{name}' has status '{status}' but is publicly selectable; "
226 f
"a {status} capability must not be reachable"
231def check_coverage(family: dict, registry_entry: dict, all_entries: list =
None) -> tuple:
233 @brief Verify every public value has a Tier-2 entry carrying its required fields.
234 @param[in] family Inventory record for one family.
235 @param[in] registry_entry Registry entry carrying anchor prefix and enforcement flag.
236 @param[in] all_entries Every registry entry, so anchors owned by a sibling family on
237 the same page are not misreported as stale.
238 @return Blocking violations and advisory notes.
240 all_entries = all_entries
or [registry_entry]
241 page = REPO_ROOT /
"docs" /
"pages" / f
"{registry_entry['family_page']}.md"
242 if not page.is_file():
243 return ([f
"{family['id']}: family page {page.name} does not exist"], [])
245 anchors = set(re.findall(
r"^@anchor\s+([A-Za-z0-9_]+)\s*$", prose, re.M))
246 prefix = registry_entry[
"entry_anchor_prefix"]
247 metadata = registry_entry.get(
"value_metadata", {})
250 seen: dict[str, str] = {}
251 problems: list[str] = []
252 for value
in sorted(family[
"public_values"]):
256 f
"{family['id']}: '{value}' and '{seen[key]}' produce the same anchor slug "
257 f
"'{prefix}{key}'; entries would collide"
266 for name, spec
in family[
"public_values"].items()
267 if spec.get(
"reachability") !=
"latent" and not spec.get(
"spelling_of")
269 expected = {f
"{prefix}{slug(v)}": v
for v
in selectable}
270 for anchor, value
in sorted(expected.items()):
271 if anchor
not in anchors:
273 f
"{family['id']}: no Tier-2 entry for '{value}' (expected `@anchor {anchor}` in {page.name})"
277 spec = metadata.get(value, {})
278 required = ALIAS_FIELDS
if spec.get(
"alias_of")
else CANONICAL_FIELDS
279 for field
in required:
280 if not re.search(rf
"\*\*{re.escape(field)}", body):
282 f
"{family['id']}: entry for '{value}' is missing the **{field}** part"
290 other[
"entry_anchor_prefix"]
291 for other
in all_entries
292 if other
is not registry_entry
293 and other[
"family_page"] == registry_entry[
"family_page"]
294 and other[
"entry_anchor_prefix"].startswith(prefix)
295 and other[
"entry_anchor_prefix"] != prefix
297 for anchor
in sorted(a
for a
in anchors
if a.startswith(prefix)):
298 if any(anchor.startswith(other)
for other
in others):
300 if anchor
not in expected:
302 f
"{family['id']}: {page.name} carries a stale entry `@anchor {anchor}` that no "
303 f
"current public value claims; remove it or restore the capability"
306 if registry_entry.get(
"coverage_enforced"):
307 return (problems, [])
308 return ([], problems)
313 @brief Return the text of one capability entry, from its anchor to the next entry.
314 @param[in] prose Page text with code fences removed.
315 @param[in] anchor Entry anchor name.
316 @return Entry body text.
318 match = re.search(rf
"^@anchor\s+{re.escape(anchor)}\s*$", prose, re.M)
321 rest = prose[match.end() :]
322 nxt = re.search(
r"^@(?:subsection|section)\s", rest, re.M)
323 return rest[: nxt.start()]
if nxt
else rest
326SCOPE_RECORDS_PATH = REPO_ROOT /
"tests" /
"tooling" /
"capability_scope_records.json"
327MEASUREMENTS_PATH = REPO_ROOT /
"tests" /
"tooling" /
"measurement_records.json"
332 @brief Check that one evidence source identifier names something that exists.
333 @param[in] identifier Source identifier such as `make:unit-boundaries`.
334 @return True when the named artifact exists.
336 kind, _, value = identifier.partition(
":")
338 makefile = (REPO_ROOT /
"Makefile").read_text(encoding=
"utf-8")
339 return re.search(rf
"^{re.escape(value)}\s*:", makefile, re.M)
is not None
340 if kind
in {
"example",
"file"}:
341 return (REPO_ROOT / value).exists()
342 if kind ==
"measurement":
349 @brief Every recorded measurement available as an evidence source.
350 @return List of measurement records.
352 if not MEASUREMENTS_PATH.is_file():
354 return json.loads(MEASUREMENTS_PATH.read_text(encoding=
"utf-8")).get(
"records", [])
359 @brief Verify every recorded measurement carries what a reader needs to judge it.
361 @details A measurement is cited in place of a re-runnable artifact, so the record
362 has to stand on its own: what was asked, at what revision, on what
363 machine and configuration, what the verdict was, and what it does not
364 establish. A verdict of `not-met` or `inconclusive` is a legitimate
365 record; an absent or empty field is not.
366 @return Violation lines.
368 violations: list = []
369 required = (
"id",
"question",
"date",
"commit",
"environment",
"configuration",
370 "result",
"limitations")
373 label = record.get(
"id")
or f
"record #{index + 1}"
374 for field
in required:
375 value = record.get(field)
376 if value
is None or (isinstance(value, str)
and not value.strip()):
377 violations.append(f
"measurement {label}: '{field}' is required and must not be empty")
378 if record.get(
"id")
in seen:
379 violations.append(f
"measurement {label}: duplicate id")
380 seen.add(record.get(
"id"))
381 stated = str(record.get(
"limitations",
"")).strip().lower()
382 if stated
in {
"none",
"n/a",
"na",
"-"}:
384 f
"measurement {label}: 'limitations' must say what the measurement does not "
385 "establish; 'none' is not an acceptable answer"
387 verdict = (record.get(
"result")
or {}).get(
"verdict")
if isinstance(record.get(
"result"), dict)
else None
388 if verdict
is not None and verdict
not in {
"met",
"not-met",
"inconclusive"}:
390 f
"measurement {label}: result verdict '{verdict}' is not one of "
391 "met, not-met, inconclusive"
398 @brief The human-readable token a capability entry must cite for a declared source.
399 @param[in] identifier Source identifier such as `make:unit-boundaries`.
400 @return The bare target, example directory, or file path.
402 _, _, value = identifier.partition(
":")
406def check_evidence(family: dict, registry_entry: dict, facets: dict) -> list[str]:
408 @brief Verify declared evidence sources exist and are cited by the capability entry.
410 This checks *correspondence*, not scientific validity. It establishes that a
411 declared source names something real and that the entry a reader sees cites the
412 same source the registry does. It cannot establish that the source actually
413 demonstrates the claimed result - that remains a human review judgement, which is
414 why these are described as declared evidence sources rather than verified evidence.
415 @param[in] family Inventory record for one family.
416 @param[in] registry_entry Registry entry carrying value metadata.
417 @param[in] facets The project-wide facet vocabulary.
418 @return Violation lines.
420 page = REPO_ROOT /
"docs" /
"pages" / f
"{registry_entry['family_page']}.md"
421 prose =
strip_non_prose(page.read_text(encoding=
"utf-8"))
if page.is_file()
else ""
422 violations: list[str] = []
423 for name, meta
in sorted(registry_entry.get(
"value_metadata", {}).items()):
424 if meta.get(
"spelling_of")
or meta.get(
"alias_of"):
425 if "evidence" in meta:
427 f
"{family['id']}: '{name}' is a spelling/alias and must not carry its own evidence"
430 evidence = meta.get(
"evidence")
432 violations.append(f
"{family['id']}: '{name}' declares no evidence mapping (use {{}} for none)")
434 for facet, sources
in sorted(evidence.items()):
435 if facet
not in facets:
437 f
"{family['id']}: '{name}' claims unknown evidence facet '{facet}'; "
438 f
"vocabulary is {sorted(facets)}"
442 violations.append(f
"{family['id']}: '{name}' claims '{facet}' with no source identifier")
443 for source
in sources:
446 f
"{family['id']}: '{name}' cites '{source}' for '{facet}', which does not exist"
451 anchor = registry_entry[
"entry_anchor_prefix"] +
slug(name)
454 section = body.split(
"**Evidence.**", 1)
455 evidence_text = section[1]
if len(section) > 1
else ""
456 for facet, sources
in sorted(evidence.items()):
457 for source
in sources:
459 if token
not in evidence_text:
461 f
"{family['id']}: '{name}' declares '{source}' for '{facet}', "
462 f
"but its entry's Evidence part does not cite '{token}'"
464 if meta.get(
"status") ==
"supported" and not evidence:
466 f
"{family['id']}: '{name}' is marked supported but claims no evidence; "
467 f
"either record a facet or lower the status"
474 @brief Verify every known-defective scope record is disclosed where it claims to be.
476 A safety valve that nothing reads is not a safety valve. This makes the scope
477 records load-bearing: a record marked known-defective must either name the pages
478 that disclose it and have them actually say so, or be resolved.
479 @return Violation lines.
481 if not SCOPE_RECORDS_PATH.is_file():
483 records = json.loads(SCOPE_RECORDS_PATH.read_text(encoding=
"utf-8")).get(
"records", [])
484 violations: list[str] = []
485 for record
in records:
486 if record.get(
"status") !=
"known-defective":
488 policy = record.get(
"publication_policy")
489 if policy ==
"disclose-now":
490 surfaces = record.get(
"disclosed_at", [])
493 f
"scope record '{record['id']}' is known-defective with policy disclose-now "
494 f
"but names no disclosure surfaces"
496 for surface
in surfaces:
497 path = REPO_ROOT / surface.split(
" ")[0]
498 if not path.is_file():
499 violations.append(f
"scope record '{record['id']}' names missing surface {path.name}")
500 elif "known-defective" not in path.read_text(encoding=
"utf-8"):
502 f
"scope record '{record['id']}' claims disclosure in {path.name}, "
503 f
"but that page contains no known-defective disclosure"
505 elif policy ==
"scope-only":
506 condition = record.get(
"activation_condition", {})
507 if not condition.get(
"surfaces"):
509 f
"scope record '{record['id']}' is scope-only but names no activation surfaces"
513 f
"scope record '{record['id']}' has unknown publication_policy '{policy}'"
521 "supported",
"experimental",
"known-defective",
"deprecated",
522 "planned",
"internal",
"removed",
527NON_SELECTABLE_STATUSES = (
"planned",
"internal",
"removed")
529LIFECYCLE_REQUIREMENTS = {
530 "supported": (
"Evidence",),
531 "experimental": (
"Limitations",),
532 "known-defective": (
"Limitations",),
533 "deprecated": (
"Migration",),
539 @brief Enforce the documentation each lifecycle status owes.
541 @details Requirements grow with the status a capability claims: `supported` owes
542 evidence, `experimental` and `known-defective` owe stated limitations, and
543 `deprecated` owes migration guidance. The gate fires when a value claims a
544 status, which is the moment the claim becomes readable.
545 @param[in] family Inventory record for one family.
546 @param[in] registry_entry Registry entry carrying value metadata and the page.
547 @return Violation lines.
549 page = REPO_ROOT /
"docs" /
"pages" / f
"{registry_entry['family_page']}.md"
550 if not page.is_file():
553 prefix = registry_entry[
"entry_anchor_prefix"]
554 violations: list = []
555 for name, meta
in sorted(registry_entry.get(
"value_metadata", {}).items()):
556 if meta.get(
"spelling_of"):
560 effective = family[
"public_values"].get(name, {}).get(
"status")
or meta.get(
"status")
561 required = LIFECYCLE_REQUIREMENTS.get(effective)
567 for field
in required:
568 if not re.search(rf
"\*\*{re.escape(field)}", body):
570 f
"{family['id']}: '{name}' is {effective} but its entry has no "
571 f
"**{field}** part; that status owes it"
578 @brief Fail on capability parity breaks, metadata drift, or missing entries.
579 @return Process status code.
581 registry_doc = json.loads(REGISTRY_PATH.read_text(encoding=
"utf-8"))
582 registry = {f[
"id"]: f
for f
in registry_doc[
"families"]}
583 facets = registry_doc[
"evidence_facets"]
584 if not INVENTORY_PATH.is_file():
585 print(
"Capability inventory has not been generated; run 'make docs-inventory'.", file=sys.stderr)
587 inventory = json.loads(INVENTORY_PATH.read_text(encoding=
"utf-8"))
590 advisory: list[str] = []
591 for family
in inventory:
592 entry = registry[family[
"id"]]
597 family_blocking, family_advisory =
check_coverage(family, entry,
list(registry.values()))
598 blocking += family_blocking
599 advisory += family_advisory
602 print(
"Capability documentation coverage (advisory, backfill pending):")
603 for note
in advisory:
608 print(
"Capability parity/coverage violations:", file=sys.stderr)
609 for violation
in blocking:
610 print(f
" {violation}", file=sys.stderr)
613 enforced = sorted(f[
"id"]
for f
in registry.values()
if f.get(
"coverage_enforced"))
614 pending = sorted(f[
"id"]
for f
in registry.values()
if not f.get(
"coverage_enforced"))
615 selectable = alias = spelling = latent = 0
616 for family
in inventory:
617 for spec
in family[
"public_values"].values():
618 if spec.get(
"reachability") ==
"latent":
620 elif spec.get(
"alias_of"):
622 elif spec.get(
"spelling_of"):
627 f
"Capability audit passed: {len(inventory)} families; "
628 f
"{selectable} canonical values, {spelling} accepted spelling, "
629 f
"{alias} deprecated alias, {latent} latent; "
630 f
"full-chain parity verified."
632 print(f
" coverage enforced: {', '.join(enforced) or 'none'}")
634 print(f
" coverage advisory (backfill pending): {', '.join(pending)}")
638if __name__ ==
"__main__":
639 raise SystemExit(
main())
list check_lifecycle_requirements(dict family, dict registry_entry)
Enforce the documentation each lifecycle status owes.
int main()
Fail on capability parity breaks, metadata drift, or missing entries.
list[str] check_scope_records()
Verify every known-defective scope record is disclosed where it claims to be.
list measurement_records()
Every recorded measurement available as an evidence source.
str strip_non_prose(str text)
Remove fenced code blocks and HTML comments so anchors inside examples do not count.
list[str] check_parity(dict family)
Verify the public selector set agrees with every declared parity source.
dict[str, dict] parity_by_kind(dict family)
Index a family's parity records by source kind.
str source_token(str identifier)
The human-readable token a capability entry must cite for a declared source.
list check_metadata(dict family, dict registry_entry)
Verify declared value metadata is complete, well-typed, and matches the sources.
list check_measurement_records()
Verify every recorded measurement carries what a reader needs to judge it.
list[str] check_generated_current()
Verify the committed inventory matches what the sources currently produce.
tuple check_coverage(dict family, dict registry_entry, list all_entries=None)
Verify every public value has a Tier-2 entry carrying its required fields.
list[str] check_evidence(dict family, dict registry_entry, dict facets)
Verify declared evidence sources exist and are cited by the capability entry.
bool source_exists(str identifier)
Check that one evidence source identifier names something that exists.
str slug(str value)
Convert a selector value into the anchor slug its entry must use.
str entry_body(str prose, str anchor)
Return the text of one capability entry, from its anchor to the next entry.
Head of a generic C-style linked list.