0.5.1-pre.005

This commit is contained in:
2026-08-10 01:36:42 +02:00
parent ec07ddbd80
commit b6a286a4df
54 changed files with 6236 additions and 5569 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# file: scripts/audit_khadhroony_workspace_rules.py
# version: 20
# version: 21
"""Audit mechanically verifiable rules specific to khadhroony-bot3."""
@@ -562,7 +562,7 @@ def audit_materializer_conventions(root: pathlib.Path) -> list[Violation]:
f"materializer tracing target `{match.group(1)}` must equal one component name",
)
)
config_path = root / "config/example.config.json"
config_path = root / "config/logging.config.json"
if config_path.exists():
try:
config = json.loads(config_path.read_text(encoding="utf-8"))
@@ -583,7 +583,7 @@ def audit_materializer_conventions(root: pathlib.Path) -> list[Violation]:
violations.append(
Violation(
"KH_MT020",
"config/example.config.json",
"config/logging.config.json",
1,
f"logging target `{target}` is not a declared materializer component",
)
@@ -906,10 +906,17 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
f"workspace environment example `{match.group(1)}` must use a `KS_*` or `KB_*` namespace",
)
)
config = root / "config/example.config.json"
if config.is_file():
placeholder = re.compile(r"\$\{([A-Z][A-Z0-9_]*)")
for relative in [
"config/app.config.json",
"config/logging.config.json",
"config/example.app.config.json",
"config/example.logging.config.json",
]:
config = root / relative
if not config.is_file():
continue
text = config.read_text(encoding="utf-8")
placeholder = re.compile(r"\$\{([A-Z][A-Z0-9_]*)")
for match in placeholder.finditer(text):
name = match.group(1)
if name.startswith(("KS_", "KB_")):
@@ -917,7 +924,7 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
violations.append(
Violation(
"KH_ENV003",
"config/example.config.json",
relative,
text[: match.start()].count("\n") + 1,
f"configuration placeholder `{name}` must use a `KS_*` or `KB_*` namespace",
)
@@ -941,6 +948,86 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
return violations
def audit_configuration_split(root: pathlib.Path) -> list[Violation]:
"""Require the independent application and logging configuration contract."""
violations: list[Violation] = []
required_files = [
"config/app.config.json",
"config/logging.config.json",
"config/example.app.config.json",
"config/example.logging.config.json",
"config/schemas/app.config.schema.json",
"config/schemas/logging.config.schema.json",
]
for relative in required_files:
if (root / relative).is_file():
continue
violations.append(
Violation(
"KH_CFG001",
relative,
1,
"required split configuration file is missing",
)
)
app_path = root / "config/app.config.json"
if app_path.is_file():
try:
app = json.loads(app_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
app = None
if isinstance(app, dict):
for index, profile in enumerate(app.get("profiles", []), 1):
if isinstance(profile, dict) and "logging" in profile:
violations.append(
Violation(
"KH_CFG002",
"config/app.config.json",
index,
"application profiles must not embed logging configuration",
)
)
logging_path = root / "config/logging.config.json"
if logging_path.is_file():
try:
logging = json.loads(logging_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
logging = None
if isinstance(logging, dict):
if not isinstance(logging.get("active_profile"), str):
violations.append(
Violation(
"KH_CFG003",
"config/logging.config.json",
1,
"logging configuration must define its own active_profile",
)
)
if not isinstance(logging.get("profiles"), list) or not logging.get("profiles"):
violations.append(
Violation(
"KH_CFG004",
"config/logging.config.json",
1,
"logging configuration must define independent named profiles",
)
)
legacy = ["config/example.config.json", "config/schema.config.json"]
for relative in legacy:
if not (root / relative).exists():
continue
violations.append(
Violation(
"KH_CFG005",
relative,
1,
"legacy combined configuration file must be removed after the split",
)
)
return violations
def audit_wincode_resolution(root: pathlib.Path) -> list[Violation]:
"""Require the currently compatible Solana wincode dependency family."""
@@ -1024,6 +1111,7 @@ def main() -> int:
+audit_private_ks_lib_paths_in_active_docs(root)
+audit_solana_types(root)
+audit_environment_namespaces(root)
+audit_configuration_split(root)
+audit_wincode_resolution(root)
)
violations.sort(key=lambda item: (item.code, item.path, item.line, item.message))