0.5.1-pre.006
This commit is contained in:
125
scripts/audit_khadhroony_workspace_rules.py
Executable file → Normal file
125
scripts/audit_khadhroony_workspace_rules.py
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# file: scripts/audit_khadhroony_workspace_rules.py
|
||||
# version: 21
|
||||
# version: 22
|
||||
|
||||
"""Audit mechanically verifiable rules specific to khadhroony-bot3."""
|
||||
|
||||
@@ -908,10 +908,15 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
|
||||
)
|
||||
placeholder = re.compile(r"\$\{([A-Z][A-Z0-9_]*)")
|
||||
for relative in [
|
||||
"config/app.config.json",
|
||||
"config/kb-app-demo-desktop.default.config.json",
|
||||
"config/ks-pipeline-demo-scenarios.default.config.json",
|
||||
"config/logging.config.json",
|
||||
"config/example.app.config.json",
|
||||
"config/transport.config.json",
|
||||
"config/listeners.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 = root / relative
|
||||
if not config.is_file():
|
||||
@@ -949,16 +954,24 @@ def audit_environment_namespaces(root: pathlib.Path) -> list[Violation]:
|
||||
|
||||
|
||||
def audit_configuration_split(root: pathlib.Path) -> list[Violation]:
|
||||
"""Require the independent application and logging configuration contract."""
|
||||
"""Require binary composition plus independent shared configuration documents."""
|
||||
|
||||
violations: list[Violation] = []
|
||||
required_files = [
|
||||
"config/app.config.json",
|
||||
"config/kb-app-demo-desktop.default.config.json",
|
||||
"config/ks-pipeline-demo-scenarios.default.config.json",
|
||||
"config/logging.config.json",
|
||||
"config/example.app.config.json",
|
||||
"config/transport.config.json",
|
||||
"config/listeners.config.json",
|
||||
"config/example.kb-app-demo-desktop.default.config.json",
|
||||
"config/example.logging.config.json",
|
||||
"config/schemas/app.config.schema.json",
|
||||
"config/example.transport.config.json",
|
||||
"config/example.listeners.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/resolved.app.config.schema.json",
|
||||
]
|
||||
for relative in required_files:
|
||||
if (root / relative).is_file():
|
||||
@@ -971,58 +984,82 @@ def audit_configuration_split(root: pathlib.Path) -> list[Violation]:
|
||||
"required split configuration file is missing",
|
||||
)
|
||||
)
|
||||
app_path = root / "config/app.config.json"
|
||||
if app_path.is_file():
|
||||
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
|
||||
try:
|
||||
app = json.loads(app_path.read_text(encoding="utf-8"))
|
||||
composition = json.loads(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):
|
||||
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",
|
||||
"config/logging.config.json",
|
||||
1,
|
||||
"logging configuration must define its own active_profile",
|
||||
relative,
|
||||
index,
|
||||
"composition profiles must reference transport/listener/logging profiles instead of embedding them",
|
||||
)
|
||||
)
|
||||
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",
|
||||
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}`",
|
||||
)
|
||||
)
|
||||
)
|
||||
legacy = ["config/example.config.json", "config/schema.config.json"]
|
||||
for relative in ["config/logging.config.json", "config/transport.config.json", "config/listeners.config.json"]:
|
||||
path = root / relative
|
||||
if not path.is_file():
|
||||
continue
|
||||
try:
|
||||
document = json.loads(path.read_text(encoding="utf-8"))
|
||||
except json.JSONDecodeError:
|
||||
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("profiles"), list) or not document.get("profiles"):
|
||||
violations.append(Violation("KH_CFG006", relative, 1, "shared configuration document must define named profiles"))
|
||||
legacy = [
|
||||
"config/app.config.json",
|
||||
"config/example.app.config.json",
|
||||
"config/schemas/app.config.schema.json",
|
||||
"config/example.config.json",
|
||||
"config/schema.config.json",
|
||||
]
|
||||
for relative in legacy:
|
||||
if not (root / relative).exists():
|
||||
continue
|
||||
violations.append(
|
||||
Violation(
|
||||
"KH_CFG005",
|
||||
"KH_CFG007",
|
||||
relative,
|
||||
1,
|
||||
"legacy combined configuration file must be removed after the split",
|
||||
"legacy monolithic application configuration file must be removed",
|
||||
)
|
||||
)
|
||||
return violations
|
||||
|
||||
Reference in New Issue
Block a user