v0.4.8-pre.007

This commit is contained in:
2026-08-06 00:52:08 +02:00
parent 80c439c988
commit 44088c71c9
122 changed files with 8903 additions and 3914 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# file: scripts/audit_khadhroony_workspace_rules.py
# version: 14
# version: 17
"""Audit mechanically verifiable rules specific to khadhroony-bot3."""
@@ -8,6 +8,7 @@ from __future__ import annotations
import argparse
import dataclasses
import json
import pathlib
import re
import sys
@@ -100,29 +101,31 @@ def audit_kb_lib_tracing(root: pathlib.Path) -> list[Violation]:
if match.group(1).startswith("TRACING_TARGET_"):
re_exports.add(match.group(1))
target_pattern = re.compile(
r'^pub\(crate\) const (TRACING_TARGET_[A-Z0-9_]+): &str = "([^"]+)";$',
r'pub\(crate\) const (TRACING_TARGET_[A-Z0-9_]+): &str\s*=\s*"([^"]+)";',
re.MULTILINE,
)
declared_targets: dict[str, tuple[str, int]] = {}
for constants in sorted((crate / "src").rglob("constants.rs")):
text = constants.read_text(encoding="utf-8")
match = target_pattern.search(text)
if match is None:
continue
component = constants.parent.relative_to(crate / "src")
expected = "kb-lib." + ".".join(component.parts)
relative = constants.relative_to(root).as_posix()
if match.group(2) != expected:
violations.append(
Violation(
"KH_TRACE101",
relative,
text[: match.start()].count("\n") + 1,
f"`{match.group(1)}` must use hierarchical target `{expected}`",
for match in target_pattern.finditer(text):
line = text[: match.start()].count("\n") + 1
declared_targets[match.group(1)] = (relative, line)
if match.group(2) != expected:
violations.append(
Violation(
"KH_TRACE101",
relative,
line,
f"`{match.group(1)}` must use hierarchical target `{expected}`",
)
)
)
macro_pattern = re.compile(
r"tracing::(?:debug|error|info|trace|warn)!\(\s*target:\s*crate::(TRACING_TARGET_[A-Z0-9_]+)"
)
used_targets: set[str] = set()
for path in sorted((crate / "src").rglob("*.rs")):
relative = path.relative_to(root).as_posix()
text = path.read_text(encoding="utf-8")
@@ -137,6 +140,7 @@ def audit_kb_lib_tracing(root: pathlib.Path) -> list[Violation]:
)
)
for match in macro_pattern.finditer(text):
used_targets.add(match.group(1))
if match.group(1) not in re_exports:
violations.append(
Violation(
@@ -146,6 +150,16 @@ def audit_kb_lib_tracing(root: pathlib.Path) -> list[Violation]:
f"missing crate-root re-export for `{match.group(1)}`",
)
)
for target, (relative, line) in sorted(declared_targets.items()):
if target not in used_targets:
violations.append(
Violation(
"KH_TRACE104",
relative,
line,
f"declared operational tracing target `{target}` is not used by a real tracing event",
)
)
return violations
@@ -358,6 +372,326 @@ def audit_reserved_materializer_scaffolds(root: pathlib.Path) -> list[Violation]
"reserved materializer must return an ignored API result",
)
)
if "std::result::Result::Ok(std::vec::Vec::new())" not in text:
violations.append(
Violation(
"KH_MT007",
relative,
1,
"reserved materializer legacy contract must return an empty event list",
)
)
if not re.search(r"return crate::MT_[A-Z0-9_]+_ACCEPTED_FAMILIES;", text):
violations.append(
Violation(
"KH_MT008",
relative,
1,
"reserved materializer must use its exported accepted-family constant",
)
)
return violations
def iter_rust_json_object_macros(text: str) -> list[tuple[int, str]]:
"""Return balanced `serde_json::json!({ ... })` object macro bodies."""
blocks: list[tuple[int, str]] = []
needle = "serde_json::json!({"
offset = 0
while True:
start = text.find(needle, offset)
if start < 0:
break
brace = text.find("{", start)
depth = 0
in_string = False
escaped = False
end = brace
while end < len(text):
character = text[end]
if in_string:
if escaped:
escaped = False
elif character == "\\":
escaped = True
elif character == '"':
in_string = False
elif character == '"':
in_string = True
elif character == "{":
depth += 1
elif character == "}":
depth -= 1
if depth == 0:
blocks.append((start, text[start: end + 1]))
offset = end + 1
break
end += 1
else:
offset = start + len(needle)
return blocks
def audit_materializer_conventions(root: pathlib.Path) -> list[Violation]:
"""Audit materializer names, constants and component facade structure."""
violations: list[Violation] = []
materializer_root = root / "kb-lib/src/materializer"
component_pattern = re.compile(
r'pub\(crate\) const (MT_[A-Z0-9_]+)_COMPONENT_NAME: &str\s*=\s*"([^"]+)";'
)
processor_pattern = re.compile(
r'pub\(crate\) const (MT_[A-Z0-9_]+)_PROCESSOR_NAME: &str\s*=\s*"([^"]+)";'
)
component_names: dict[str, tuple[str, str, int]] = {}
processor_names: dict[str, tuple[str, str, int]] = {}
for path in sorted(materializer_root.rglob("constants.rs")):
relative = path.relative_to(root).as_posix()
text = path.read_text(encoding="utf-8")
for match in component_pattern.finditer(text):
prefix = match.group(1)
line = text[: match.start()].count("\n") + 1
component_names[prefix] = (match.group(2), relative, line)
for match in processor_pattern.finditer(text):
prefix = match.group(1)
line = text[: match.start()].count("\n") + 1
processor_names[prefix] = (match.group(2), relative, line)
for prefix, (component_name, relative, line) in sorted(component_names.items()):
processor = processor_names.get(prefix)
if processor is None:
violations.append(
Violation(
"KH_MT009",
relative,
line,
f"`{prefix}` component name requires one matching processor name",
)
)
continue
processor_name = processor[0]
if not component_name.startswith("kb-lib.materializer."):
violations.append(
Violation(
"KH_MT010",
relative,
line,
f"materializer component name `{component_name}` must start with `kb-lib.materializer.`",
)
)
expected_processor = component_name.removeprefix("kb-lib.")
if processor_name != expected_processor:
violations.append(
Violation(
"KH_MT011",
processor[1],
processor[2],
f"processor name `{processor_name}` must equal `{expected_processor}`",
)
)
for prefix, (_, relative, line) in sorted(processor_names.items()):
if prefix not in component_names:
violations.append(
Violation(
"KH_MT012",
relative,
line,
f"`{prefix}` processor name requires one matching component name",
)
)
for path in sorted(materializer_root.rglob("constants.rs")):
relative = path.relative_to(root).as_posix()
text = path.read_text(encoding="utf-8")
for match in component_pattern.finditer(text):
symbol = f"{match.group(1)}_COMPONENT_NAME"
used_by_implementation = any(
symbol in candidate.read_text(encoding="utf-8")
for candidate in path.parent.rglob("*.rs")
if candidate.name != "constants.rs"
)
if not used_by_implementation:
violations.append(
Violation(
"KH_MT025",
relative,
text[: match.start()].count("\n") + 1,
f"materializer component constant `{symbol}` is not consumed by its implementation",
)
)
component_values = {value[0] for value in component_names.values()}
processor_values = {value[0] for value in processor_names.values()}
if len(component_values) != len(component_names):
violations.append(
Violation(
"KH_MT017",
"kb-lib/src/materializer",
1,
"materializer component names must be unique",
)
)
if len(processor_values) != len(processor_names):
violations.append(
Violation(
"KH_MT018",
"kb-lib/src/materializer",
1,
"materializer processor names must be unique",
)
)
tracing_pattern = re.compile(
r'pub\(crate\) const TRACING_TARGET_MATERIALIZER_[A-Z0-9_]+: &str\s*=\s*"([^"]+)";'
)
for path in sorted(materializer_root.rglob("constants.rs")):
relative = path.relative_to(root).as_posix()
text = path.read_text(encoding="utf-8")
for match in tracing_pattern.finditer(text):
if match.group(1) not in component_values:
line = text[: match.start()].count("\n") + 1
violations.append(
Violation(
"KH_MT019",
relative,
line,
f"materializer tracing target `{match.group(1)}` must equal one component name",
)
)
config_path = root / "config/example.config.json"
if config_path.exists():
try:
config = json.loads(config_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
config = None
pending: list[object] = [config] if config is not None else []
while pending:
value = pending.pop()
if isinstance(value, dict):
targets = value.get("targets")
if isinstance(targets, list):
for target in targets:
if (
isinstance(target, str)
and target.startswith("kb-lib.materializer.")
and target not in component_values
):
violations.append(
Violation(
"KH_MT020",
"config/example.config.json",
1,
f"logging target `{target}` is not a declared materializer component",
)
)
pending.extend(value.values())
elif isinstance(value, list):
pending.extend(value)
for path in sorted(materializer_root.rglob("*.rs")):
relative = path.relative_to(root).as_posix()
text = path.read_text(encoding="utf-8")
if path.name != "constants.rs" and re.search(r'"processorName"\s*:\s*"', text):
violations.append(
Violation(
"KH_MT021",
relative,
1,
"persisted processor names must come from exported component constants",
)
)
for offset, block in iter_rust_json_object_macros(text):
if '"projectionVersion"' not in block:
continue
line = text[:offset].count("\n") + 1
if '"processorName"' not in block:
violations.append(
Violation(
"KH_MT022",
relative,
line,
"versioned materializer output must persist its processor provenance",
)
)
if re.search(
r'"projectionVersion"\s*:\s*crate::MT_[A-Z0-9_]+_PROJECTION_VERSION',
block,
) is None:
violations.append(
Violation(
"KH_MT023",
relative,
line,
"materializer projection version must come from an exported component constant",
)
)
if re.search(
r'"processorName"\s*:\s*crate::MT_[A-Z0-9_]+_PROCESSOR_NAME',
block,
) is None:
violations.append(
Violation(
"KH_MT024",
relative,
line,
"materializer processor provenance must come from an exported component constant",
)
)
if path.name != "constants.rs" and re.search(
r"^\s*(?:pub(?:\(crate\))?\s+)?const\s+[A-Z][A-Z0-9_]*\b",
text,
re.MULTILINE,
):
violations.append(
Violation(
"KH_MT013",
relative,
1,
"materializer constants must be declared in the component `constants.rs`",
)
)
if path.name == "materializer.rs" and re.search(
r"^pub struct Mt[A-Za-z0-9]+Materializer;", text, re.MULTILINE
):
constants_path = path.parent / "constants.rs"
if not constants_path.exists():
violations.append(
Violation(
"KH_MT014",
relative,
1,
"materializer implementation requires a sibling `constants.rs`",
)
)
if re.search(r'"(?:kb-lib\.)?materializer\.[^"]+"', text):
violations.append(
Violation(
"KH_MT015",
relative,
1,
"materializer identities must come from exported component constants",
)
)
module_lines = [
line
for line in text.splitlines()
if re.fullmatch(r"mod [A-Za-z_][A-Za-z0-9_]*;", line.strip()) is not None
]
if not module_lines:
continue
for index, line in enumerate(text.splitlines(), 1):
stripped = line.strip()
if not stripped or stripped.startswith("//") or stripped == "#[cfg(test)]":
continue
if re.fullmatch(r"mod [A-Za-z_][A-Za-z0-9_]*;", stripped) is not None:
continue
if stripped.startswith("pub use ") or stripped.startswith("pub(crate) use "):
continue
violations.append(
Violation(
"KH_MT016",
relative,
index,
"materializer facade may contain only submodule declarations and re-exports",
)
)
break
return violations
@@ -440,13 +774,13 @@ def audit_reserved_executor_scaffolds(root: pathlib.Path) -> list[Violation]:
"reserved executor must build only an explicit zero-instruction plan",
)
)
if reserved_count != 104:
if reserved_count != 103:
violations.append(
Violation(
"KH_EX007",
"kb-lib/src/executor",
1,
f"expected 104 reserved executor boundaries, found {reserved_count}",
f"expected 103 reserved executor boundaries, found {reserved_count}",
)
)
return violations
@@ -596,15 +930,16 @@ def main() -> int:
root = pathlib.Path(arguments.root).resolve()
violations = (
audit_tracing(root)
+ audit_kb_lib_tracing(root)
+ audit_kb_lib_symbol_prefixes(root)
+ audit_reserved_decoder_scaffolds(root)
+ audit_reserved_materializer_scaffolds(root)
+ audit_reserved_executor_scaffolds(root)
+ audit_token_2022_naming(root)
+ audit_private_kb_lib_paths_in_active_docs(root)
+ audit_solana_types(root)
+ audit_wincode_resolution(root)
+audit_kb_lib_tracing(root)
+audit_kb_lib_symbol_prefixes(root)
+audit_reserved_decoder_scaffolds(root)
+audit_reserved_materializer_scaffolds(root)
+audit_materializer_conventions(root)
+audit_reserved_executor_scaffolds(root)
+audit_token_2022_naming(root)
+audit_private_kb_lib_paths_in_active_docs(root)
+audit_solana_types(root)
+audit_wincode_resolution(root)
)
violations.sort(key=lambda item: (item.code, item.path, item.line, item.message))
if not violations: