Files
acdl/.ciagent/VERIFY.md
T
Jon Chery ed387a4f54 verify(P1): 4-layer verify PASS — engine core, 24 new tests, 0 regressions
---ci---
project: acdl
phase: 1
milestone: v1.25
status: verify
phase_role: execution
requirements:
  covered: [REQ-291, REQ-292, REQ-293, REQ-294, REQ-308, REQ-309]
  partial: []
---/ci---
2026-08-12 18:21:03 +00:00

4.0 KiB

VERIFY — P1 engine-core (v1.25)

4-layer verify gate: structural, behavioral, security, quality. Phase: P1. Requirements: REQ-291..294, 308, 309. Result: PASS.

Structural

  • core/policy_engine.py exists, implements PolicyEngine Protocol (PEP 544, @runtime_checkable), PolicyEngineRegistry with register() + get_engine(), NullEngine fallback.
  • adapters/kyverno-json/kyverno_json_engine.py exists, exports KyvernoJsonEngine with name, is_configured(), evaluate().
  • adapters/kyverno-json/__init__.py loads the engine by file path (the dir name has a hyphen — not a valid Python package name).
  • adapters/kyverno-json/policies/_smoke.json exists (trivial policy for round-trip validation).
  • scripts/install-kyverno-json.sh exists (go install kj@latest).
  • .ciagent/config.json has the policy object (engine: kyverno-json, policy_root).
  • .gitea/workflows/ci.yml + .github/workflows/ci.yml have the Go + kj install step (best-effort, tests skip when kj absent).
  • tests/test_policy_engine.py (10 tests) + tests/test_kyverno_json_engine.py (16 tests) exist.

Behavioral

  • pytest tests/test_policy_engine.py tests/test_kyverno_json_engine.py: 24 passed, 2 skipped (kj not installed — expected; pytest.skip("kj not installed")).
  • NullEngine satisfies the PolicyEngine Protocol (G-Q8a — isinstance(NullEngine(), PolicyEngine) is True). Proves the swap boundary is real without implementing OPA.
  • KyvernoJsonEngine.is_configured() returns False when which kj is absent → evaluate() returns a single KJ_ENGINE_NOT_CONFIGURED SKIPPED PCR (distinct ruleId from NullEngine's NULL_ENGINE_INACTIVE — G-Q4).
  • PCR records validate against schemas/policy_check_result.schema.json (via jsonschema.validate in tests).
  • Defensive parsing: malformed kyverno-json output → error PCR (KJ_ENGINE_ERROR), never an exception.
  • Severity annotation reading (G-Q10a): policies with nova.cloudinit.dev/severity: high produce PCRs with severity: high; policies without the annotation default to info.
  • Registry: get_engine() returns the configured engine; unknown engine name raises KeyError; policy key absent → NullEngine.
  • No regression: pytest tests/test_confidence_signal.py tests/test_adapter.py tests/test_checkov_adapter.py tests/test_kyverno_adapter.py tests/test_contract_resolver.py132 passed (unchanged).

Security

  • No new secrets, no new network calls in the engine core (the engine shells to a local binary; the binary makes no network calls for scan).
  • is_configured() guard ensures the platform runs without the binary (no hard dependency that could be exploited as a DoS vector).
  • The engine writes the payload to a temp file (tempfile.NamedTemporaryFile) and unlinks it in a finally block (no leftover payload on disk).
  • No shell=True in the subprocess.run call (command is a list — no shell injection surface).

Quality

  • python3 -m py_compile passes on all new Python files.
  • The PolicyEngine Protocol is minimal (3 members) — the swap boundary is the moat (NORTH_STAR Strategic Objective #2).
  • The NullEngine proves a second implementation exists (structural conformance) — the OPA swap is a known quantity (RESEARCH §4.2).
  • Tests use pytest.skip when which kj is absent, so the CI matrix passes with or without the binary (the suite is green in both cases).

Must-have checklist

  • PolicyEngine Protocol + PolicyEngineRegistry + NullEngine (REQ-291)
  • config.json.policy object (REQ-292)
  • KyvernoJsonEngine adapter (REQ-293)
  • __init__.py + _smoke.json + install-kyverno-json.sh + CI install (REQ-294)
  • test_policy_engine.py — protocol conformance, registry, NullEngine fallback (REQ-308)
  • test_kyverno_json_engine.py — PCR schema validity, defensive parsing, skip-without-kj (REQ-309)

Verdict: PASS — all P1 must-haves met, no regressions, 24 new tests pass (2 skip-without-kj), 132 existing tests unchanged.