0.5.1-pre.007

This commit is contained in:
2026-08-10 09:28:57 +02:00
parent 34a670eaec
commit a2820062eb
81 changed files with 3357 additions and 2381 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# file: scripts/audit_khadhroony_workspace_rules.py
# version: 22
# version: 23
"""Audit mechanically verifiable rules specific to khadhroony-bot3."""
@@ -909,14 +909,19 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
placeholder = re.compile(r"\$\{([A-Z][A-Z0-9_]*)")
for relative in [
"config/kb-app-demo-desktop.default.config.json",
"config/ks-pipeline-demo-scenarios.default.config.json",
"config/logging.config.json",
"config/transport.config.json",
"config/listeners.config.json",
"config/store.config.json",
"config/wallet.config.json",
"config/execution.config.json",
"config/example.kb-app-demo-desktop.default.config.json",
"config/example.logging.config.json",
"config/example.transport.config.json",
"config/example.listeners.config.json",
"config/example.store.config.json",
"config/example.wallet.config.json",
"config/example.execution.config.json",
]:
config = root / relative
if not config.is_file():
@@ -954,83 +959,66 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
def audit_configuration_split(root: pathlib.Path) -> list[Violation]:
"""Require binary composition plus independent shared configuration documents."""
"""Require one binary composition plus independent shared configuration documents."""
violations: list[Violation] = []
required_files = [
"config/kb-app-demo-desktop.default.config.json",
"config/ks-pipeline-demo-scenarios.default.config.json",
"config/logging.config.json",
"config/transport.config.json",
"config/listeners.config.json",
"config/store.config.json",
"config/wallet.config.json",
"config/execution.config.json",
"config/example.kb-app-demo-desktop.default.config.json",
"config/example.logging.config.json",
"config/example.transport.config.json",
"config/example.listeners.config.json",
"config/example.store.config.json",
"config/example.wallet.config.json",
"config/example.execution.config.json",
"config/schemas/composition.config.schema.json",
"config/schemas/logging.config.schema.json",
"config/schemas/transport.config.schema.json",
"config/schemas/listeners.config.schema.json",
"config/schemas/store.config.schema.json",
"config/schemas/wallet.config.schema.json",
"config/schemas/execution.config.schema.json",
"config/schemas/resolved.app.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",
)
)
composition_paths = [
"config/kb-app-demo-desktop.default.config.json",
"config/ks-pipeline-demo-scenarios.default.config.json",
]
for relative in composition_paths:
path = root / relative
if not path.is_file():
continue
violations.append(Violation("KH_CFG001", relative, 1, "required split configuration file is missing"))
composition_path = root / "config/kb-app-demo-desktop.default.config.json"
if composition_path.is_file():
try:
composition = json.loads(path.read_text(encoding="utf-8"))
composition = json.loads(composition_path.read_text(encoding="utf-8"))
except json.JSONDecodeError:
composition = None
if not isinstance(composition, dict):
continue
sources = composition.get("sources")
if not isinstance(sources, dict) or set(sources) != {"logging", "transport", "listeners"}:
violations.append(
Violation(
"KH_CFG002",
relative,
1,
"binary composition must reference logging, transport and listeners sources",
)
)
for index, profile in enumerate(composition.get("profiles", []), 1):
if not isinstance(profile, dict):
continue
if "solana" in profile or "logging" in profile:
violations.append(
Violation(
"KH_CFG003",
relative,
index,
"composition profiles must reference transport/listener/logging profiles instead of embedding them",
)
)
for key in ["logging_profile", "transport_profile", "listeners_profile"]:
if not isinstance(profile.get(key), str) or not profile.get(key, "").strip():
violations.append(
Violation(
"KH_CFG004",
relative,
index,
f"composition profile must define non-empty `{key}`",
)
)
for relative in ["config/logging.config.json", "config/transport.config.json", "config/listeners.config.json"]:
if isinstance(composition, dict):
sources = composition.get("sources")
expected_sources = {"logging", "transport", "listeners", "store", "wallet", "execution"}
if not isinstance(sources, dict) or set(sources) != expected_sources:
violations.append(Violation("KH_CFG002", composition_path.relative_to(root).as_posix(), 1, "binary composition must reference all six shared configuration sources"))
for index, profile in enumerate(composition.get("profiles", []), 1):
if not isinstance(profile, dict):
continue
forbidden = {"solana", "logging", "database", "data", "wallet", "execution"}
if forbidden.intersection(profile):
violations.append(Violation("KH_CFG003", composition_path.relative_to(root).as_posix(), index, "composition profiles must reference shared profiles instead of embedding shared configuration"))
for key in ["logging_profile", "transport_profile", "listeners_profile", "store_profile", "wallet_profile", "execution_profile"]:
if key in profile and (not isinstance(profile.get(key), str) or not profile.get(key, "").strip()):
violations.append(Violation("KH_CFG004", composition_path.relative_to(root).as_posix(), index, f"optional composition override `{key}` must be non-empty when present"))
shared = [
"config/logging.config.json",
"config/transport.config.json",
"config/listeners.config.json",
"config/store.config.json",
"config/wallet.config.json",
"config/execution.config.json",
]
for relative in shared:
path = root / relative
if not path.is_file():
continue
@@ -1040,28 +1028,47 @@ def audit_configuration_split(root: pathlib.Path) -> list[Violation]:
document = None
if not isinstance(document, dict):
continue
if not isinstance(document.get("active_profile"), str):
violations.append(Violation("KH_CFG005", relative, 1, "shared configuration document must define active_profile"))
if not isinstance(document.get("default_profile"), str) or not document.get("default_profile", "").strip():
violations.append(Violation("KH_CFG005", relative, 1, "shared configuration document must define a non-empty default_profile"))
if not isinstance(document.get("profiles"), list) or not document.get("profiles"):
violations.append(Violation("KH_CFG006", relative, 1, "shared configuration document must define named profiles"))
logging = root / "config/logging.config.json"
if logging.is_file():
document = json.loads(logging.read_text(encoding="utf-8"))
if not isinstance(document.get("logs_directory"), str) or not document.get("logs_directory", "").strip():
violations.append(Violation("KH_CFG008", "config/logging.config.json", 1, "logging root directory must be global and non-empty"))
wallet = root / "config/wallet.config.json"
if wallet.is_file():
document = json.loads(wallet.read_text(encoding="utf-8"))
if not isinstance(document.get("wallets_directory"), str) or not document.get("wallets_directory", "").strip():
violations.append(Violation("KH_CFG009", "config/wallet.config.json", 1, "wallet root directory must be global and non-empty"))
for index, profile in enumerate(document.get("profiles", []), 1):
if isinstance(profile, dict) and any(key.endswith("_send_enabled") for key in profile):
violations.append(Violation("KH_CFG010", "config/wallet.config.json", index, "send authorization belongs to execution configuration, not wallet profiles"))
transport = root / "config/transport.config.json"
if transport.is_file():
document = json.loads(transport.read_text(encoding="utf-8"))
defaults = document.get("ws_endpoint_defaults")
if not isinstance(defaults, list) or not defaults:
violations.append(Violation("KH_CFG011", "config/transport.config.json", 1, "transport configuration must define named WebSocket endpoint defaults"))
for pindex, profile in enumerate(document.get("profiles", []), 1):
if not isinstance(profile, dict):
continue
for endpoint in profile.get("ws_endpoints", []):
if isinstance(endpoint, dict) and (not isinstance(endpoint.get("defaults"), str) or not endpoint.get("defaults", "").strip()):
violations.append(Violation("KH_CFG012", "config/transport.config.json", pindex, "each WebSocket endpoint must select one named defaults class"))
legacy = [
"config/app.config.json",
"config/example.app.config.json",
"config/schemas/app.config.schema.json",
"config/example.config.json",
"config/schema.config.json",
"config/ks-pipeline-demo-scenarios.default.config.json",
]
for relative in legacy:
if not (root / relative).exists():
continue
violations.append(
Violation(
"KH_CFG007",
relative,
1,
"legacy monolithic application configuration file must be removed",
)
)
violations.append(Violation("KH_CFG007", relative, 1, "legacy or unnecessary configuration composition file must be removed"))
return violations