scripts.factory_c4
Reference › scripts › factory_c4
The command-line interface for the SPEC-033 C4 declared-formalization detectors (B26, REQ-033-C4). It builds on c4 and the bridge in dor_bridge; the factory narrative describes the subsystem. No module or test imports it.
Invocation: main has two subcommands. template prints a skeleton formalization for a requirement id (_skeleton_formalization, _cmd_template). check runs the C4 detectors on a formalization and prints a C4Report, converted to a dictionary by _report_to_dict (_cmd_check). With no subcommand it prints help and exits 1, and an exception prints an error and exits 1.
At a glance
| Source | scripts/factory_c4.py |
| Lines of code | 188 |
| Classes | 0 |
| Functions | 6 |
| Imports (internal) | orchestrata_ultimate.factory.formalization.c4, orchestrata_ultimate.factory.formalization.dor_bridge, orchestrata_ultimate.factory.formalization.models |
| Imported by | none |
| Tests that import it | none |
Class diagram
No classes; see Functions.
Dependency diagram
API
Functions
| Function | Signature | Summary |
|---|---|---|
_skeleton_formalization |
_skeleton_formalization(requirement_id: str) -> Formalization |
Build a fresh skeleton: one observable variable, zero constraints. |
_cmd_template |
_cmd_template(args: argparse.Namespace) -> int |
|
_report_to_dict |
_report_to_dict(report: C4Report) -> dict[str, Any] |
|
_cmd_check |
_cmd_check(args: argparse.Namespace) -> int |
|
_build_parser |
_build_parser() -> argparse.ArgumentParser |
|
main |
main(argv: list[str] | None = None) -> None |
Parse argv, dispatch to the matching subcommand, and sys.exit. |
Source
Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/scripts/factory_c4.py
#!/usr/bin/env python3
"""CLI for the SPEC-033 C4 declared-formalization detectors (B26, REQ-033-C4).
Subcommands
-----------
template Emit a skeleton :class:`Formalization` JSON for a requirement --
one example observable variable with two domain values and ZERO
constraints, so the skeleton honestly reports under-constrained
(0 constraints on 2 observable values admits both) until it is
actually authored.
check Load a formalization, run both C4 detectors, print the findings
(witnesses/cores, never a bare boolean -- ADR-0026), and exit 1 if
either detector fired.
Examples
--------
python scripts/factory_c4.py template --requirement REQ-033-C4 \\
--out formalization.json
python scripts/factory_c4.py check formalization.json
python scripts/factory_c4.py check formalization.json --json
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Any
# Ensure repo src is on path when run directly (mirrors factory_dor_procedure.py
# / kg_schema.py; also lets static analysis resolve the import without the
# editable-install .pth machinery).
_repo_src = Path(__file__).resolve().parent.parent / "src"
if str(_repo_src) not in sys.path:
sys.path.insert(0, str(_repo_src))
from orchestrata_ultimate.factory.formalization.c4 import ( # noqa: E402
C4Report,
run_c4,
)
from orchestrata_ultimate.factory.formalization.dor_bridge import ( # noqa: E402
c4_blocking_findings,
)
from orchestrata_ultimate.factory.formalization.models import ( # noqa: E402
Domain,
Formalization,
Variable,
load_formalization,
save_formalization,
)
def _skeleton_formalization(requirement_id: str) -> Formalization:
"""Build a fresh skeleton: one observable variable, zero constraints.
Two domain values and no constraints admits both -- honestly
under-constrained until real variables/constraints are authored, the
same "present-but-empty" discipline as ``factory_dor_procedure.py
template``.
"""
example_variable = Variable(
name="example_var",
domain=Domain(values=("value_a", "value_b")),
observable=True,
)
return Formalization(
requirement_id=requirement_id,
variables=(example_variable,),
constraints=(),
)
def _cmd_template(args: argparse.Namespace) -> int:
formalization = _skeleton_formalization(args.requirement)
save_formalization(formalization, Path(args.out), overwrite=args.overwrite)
print(
f"Wrote skeleton C4 formalization for {args.requirement} to {args.out} "
f"(0 constraints on 2 observable values -- honestly under-constrained "
f"until authored; see the Constraint docstring for REQUIRE/FORBID/IMPLIES "
f"shapes)"
)
return 0
def _report_to_dict(report: C4Report) -> dict[str, Any]:
contradiction = report.contradiction
under_constraint = report.under_constraint
return {
"requirement_id": report.requirement_id,
"contradiction": (
None
if contradiction is None
else {
"conflicting_constraint_ids": list(
contradiction.conflicting_constraint_ids
),
"conflicting_sources": list(contradiction.conflicting_sources),
}
),
"under_constraint": (
None
if under_constraint is None
else {
"differing_observable_vars": list(
under_constraint.differing_observable_vars
),
"witness_a": under_constraint.witness_a,
"witness_b": under_constraint.witness_b,
}
),
"solution_count_observable": report.solution_count_observable,
}
def _cmd_check(args: argparse.Namespace) -> int:
formalization = load_formalization(Path(args.file))
report = run_c4(formalization)
findings = c4_blocking_findings(report)
if args.json:
print(json.dumps(_report_to_dict(report), indent=2))
return 1 if findings else 0
if not findings:
print(
f"requirement={report.requirement_id}: no C4 finding "
f"(solution_count_observable={report.solution_count_observable})"
)
return 0
for line in findings:
print(line)
return 1
def _build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="factory_c4",
description="SPEC-033 C4 declared-formalization detectors (B26, REQ-033-C4).",
)
sub = parser.add_subparsers(dest="command", required=True)
template_p = sub.add_parser(
"template", help="Emit a skeleton formalization JSON for a requirement."
)
template_p.add_argument("--requirement", required=True, help="Requirement id.")
template_p.add_argument("--out", required=True, help="Output JSON path.")
template_p.add_argument(
"--overwrite",
action="store_true",
help="Allow overwriting an existing file at --out.",
)
check_p = sub.add_parser(
"check", help="Run both C4 detectors and print findings; exit 1 if any fired."
)
check_p.add_argument("file", help="Formalization JSON path.")
check_p.add_argument("--json", action="store_true", help="Print findings as JSON.")
return parser
def main(argv: list[str] | None = None) -> None:
"""Parse ``argv``, dispatch to the matching subcommand, and ``sys.exit``."""
parser = _build_parser()
args = parser.parse_args(argv)
dispatch = {
"template": _cmd_template,
"check": _cmd_check,
}
handler = dispatch.get(args.command)
if handler is None:
parser.print_help()
sys.exit(1)
try:
exit_code = handler(args)
except Exception as exc: # noqa: BLE001
print(f"ERROR: {exc}", file=sys.stderr)
sys.exit(1)
sys.exit(exit_code)
if __name__ == "__main__":
main()