f753353ad4
RESEARCH.md: kyverno-json CLI (kj scan), ValidatingPolicy structure, assertion trees + ~ modifier + JMESPath, output shape, severity-via- annotation convention, 4 policy targets (contract/stack-IR/plan-JSON/ meta), PolicyEngine protocol + OPA-equivalent swap surface, latency <1s (parallel with checkov), deterministic-not-AI tenet, ECS catalog prior art, 5 logged assumptions (A1..A5). PERSONAS.md: 4 active personas (lead-developer, backend-engineer, new policy-engineer, data-engineer); frontend-engineer deactivated. policy-engineer owns kyverno-json policies + engine translation + STANDARDS.md policy-authoring section. ARCHITECTURE.md §12.7: Policy Engine Registry — protocol, registry, NullEngine fallback, engine enum reuse (D-116), defense-in-depth critical-override (D-119), graceful degradation (D-120). ---ci--- project: acdl phase: 0 milestone: v1.25 status: research ---/ci---
132 lines
7.7 KiB
Markdown
132 lines
7.7 KiB
Markdown
---
|
|
project: acdl
|
|
milestone: v1.25
|
|
generated_at: 2026-08-12
|
|
generator: lead-developer
|
|
verification_toolchain:
|
|
typecheck: "python3 -m py_compile core/policy_engine.py adapters/kyverno-json/kyverno_json_engine.py tests/test_policy_engine.py tests/test_kyverno_json_engine.py"
|
|
test: "pytest tests/test_policy_engine.py tests/test_kyverno_json_engine.py tests/test_adapter.py tests/test_contract_resolver.py tests/test_confidence_signal.py tests/test_checkov_adapter.py tests/test_kyverno_adapter.py tests/test_pipeline.py -v"
|
|
lint: "ruff check core/policy_engine.py adapters/kyverno-json/ 2>/dev/null || python3 -m py_compile core/policy_engine.py"
|
|
note: |
|
|
v1.25 is the kyverno-json Unified Policy Engine milestone — a feat
|
|
milestone. Four active personas: lead-developer (coordination +
|
|
docs + ARCHITECTURE.md §12.7), backend-engineer (core/policy_engine.py
|
|
protocol + registry + contract_resolver.py wiring + run_platform.sh
|
|
Step 5 + pipeline tests), policy-engineer (adapters/kyverno-json/
|
|
engine + policies across all 4 target dirs + meta-policies + policy
|
|
tests + adapter README + STANDARDS.md policy-authoring section),
|
|
data-engineer (config.json policy object + schemas/README.md note +
|
|
capability-inventory JSON fixture for regression policies).
|
|
frontend-engineer stays deactivated (no UI). The policy-engineer is a
|
|
new custom persona created for this milestone's policy domain (see
|
|
RESEARCH.md §4 — kyverno-json + JMESPath is a distinct framework from
|
|
backend-engineer's fastify/hono).
|
|
---
|
|
|
|
# ACDL — Persona Roster (v1.25 kyverno-json Unified Policy Engine)
|
|
|
|
> v1.25 roster. Four active personas + one deactivated. This is a feat
|
|
> milestone: the work is a swappable policy-engine protocol + a new
|
|
> adapter + policies across 4 Nova artifacts + pipeline wiring + docs.
|
|
> The policy-engineer is a new custom persona — kyverno-json + JMESPath
|
|
> is a specialized domain that doesn't fit backend-engineer's
|
|
> fastify/hono frameworks or data-engineer's drizzle/postgresql.
|
|
|
|
## Active personas
|
|
|
|
### lead-developer
|
|
- **Domain:** coordination + docs
|
|
- **Frameworks:** []
|
|
- **Constraints:** ["pragmatic", "battle-tested defaults", "docs match code", "swap boundary is the moat"]
|
|
- **Territory:**
|
|
- `.ciagent/ARCHITECTURE.md` (§12.7 Policy Engine Registry — NEW)
|
|
- `.ciagent/PROJECT.md` (v1.25 section)
|
|
- `.ciagent/REQUIREMENTS.md` (v1.25 section)
|
|
- `.ciagent/ROADMAP.md` (v1.25 section)
|
|
- `.ciagent/PLAN.md`, `.ciagent/RESEARCH.md`, `.ciagent/CLARIFY.md`,
|
|
`.ciagent/GRILL.md`, `.ciagent/PERSONAS.md`
|
|
- `docs/METRICS.md` (swappable engine narrative — REQ-307)
|
|
- **Reason:** Owns the milestone coordination + the architecture
|
|
narrative. The swap boundary (PolicyEngine protocol) is the moat per
|
|
Strategic Objective #2 — the lead-developer owns the boundary
|
|
description in ARCHITECTURE.md §12.7 and the docs/METRICS.md note.
|
|
No Python policy code (backend-engineer + policy-engineer territory).
|
|
No UI (frontend-engineer deactivated).
|
|
|
|
### backend-engineer
|
|
- **Domain:** backend (Python + bash + pipeline wiring)
|
|
- **Frameworks:** ["boto3", "terraform"]
|
|
- **Constraints:** ["api-first", "strict-typing", "engine-agnostic confidence signal", "fail-soft when kj absent"]
|
|
- **Territory:**
|
|
- `core/policy_engine.py` (NEW — PolicyEngine Protocol + PolicyEngineRegistry + NullEngine)
|
|
- `core/contract_resolver.py` (MODIFIED — invoke registry pre/post resolve)
|
|
- `scripts/run_platform.sh` (MODIFIED — Step 5 kyverno-json parallel pass)
|
|
- `scripts/install-kyverno-json.sh` (NEW)
|
|
- `tests/test_policy_engine.py` (NEW — protocol conformance, registry, NullEngine)
|
|
- `tests/test_run_platform_plan_json_policies.py` (NEW — script-substring assertion)
|
|
- `.github/workflows/ci.yml` + `.gitea/workflows/ci.yml` (MODIFIED — Go + kj install)
|
|
- **Reason:** Owns the Python protocol layer + the pipeline wiring. The
|
|
`PolicyEngine` Protocol + `PolicyEngineRegistry` are Python structural-
|
|
typing constructs (PEP 544) — backend-engineer's strict-typing
|
|
constraint. The `contract_resolver.py` wiring + `run_platform.sh`
|
|
Step 5 are backend territory. Does NOT write kyverno-json policy
|
|
files (policy-engineer territory) — only the Python that *invokes* the
|
|
engine. Does NOT modify the confidence signal (it already consumes
|
|
`list[PolicyCheckResult]` engine-agnostically — PROJECT.md hard-
|
|
constraint).
|
|
|
|
### policy-engineer
|
|
- **Domain:** policy (declarative compliance rules)
|
|
- **Frameworks:** ["kyverno-json", "jmespath", "kyverno ValidatingPolicy"]
|
|
- **Constraints:** ["declarative-policies", "no-imperative-rules", "schema-validated", "severity-via-annotation", "assertion-trees-not-foreach"]
|
|
- **Territory:**
|
|
- `adapters/kyverno-json/` (NEW — engine impl + __init__.py + README)
|
|
- `adapters/kyverno-json/kyverno_json_engine.py` (NEW — KyvernoJsonEngine)
|
|
- `adapters/kyverno-json/policies/` (NEW — all 4 target dirs: contract/, stack-ir/, plan-json/, meta/, regression/)
|
|
- `adapters/kyverno-json/policies/_smoke.json` (NEW)
|
|
- `adapters/README.md` (MODIFIED — new adapter row + PolicyEngine Protocol section)
|
|
- `tests/test_kyverno_json_engine.py` (NEW — PCR schema validity, defensive parsing)
|
|
- `tests/test_stack_ir_policies.py` (NEW)
|
|
- `tests/test_plan_json_policies.py` (NEW)
|
|
- `tests/test_meta_policies.py` (NEW)
|
|
- `tests/test_regression_policies.py` (NEW)
|
|
- `tests/fixtures/stack_ir/`, `tests/fixtures/plan_json/`, `tests/fixtures/capability_inventory.json` (NEW)
|
|
- `modules/STANDARDS.md` (MODIFIED — Policy authoring standard section — REQ-307)
|
|
- **Reason:** The policy-engineer owns the declarative policy artifacts.
|
|
kyverno-json's `ValidatingPolicy` + assertion trees + JMESPath is a
|
|
distinct framework from backend-engineer's fastify/hono and requires
|
|
its own constraints: no imperative rules (everything is an assertion
|
|
tree), severity via the `nova.cloudinit.dev/severity` annotation (not
|
|
in the engine adapter), no `forEach` (use the `~` modifier). The
|
|
adapter pattern (engine ↔ protocol ↔ registry) is backend-engineer
|
|
territory, but the policy *content* and the engine *translation*
|
|
(`_to_pcr()`) are policy-engineer territory because they require
|
|
kyverno-json output-shape knowledge. Created per RESEARCH.md §4 — this
|
|
is a phase-spanning persona (active for P1..P4), not phase-specific.
|
|
|
|
### data-engineer
|
|
- **Domain:** data (config schema + structured fixtures)
|
|
- **Frameworks:** ["jsonschema", "yaml"]
|
|
- **Constraints:** ["schema-first", "type-safe config", "backward-compatible additions"]
|
|
- **Territory:**
|
|
- `.ciagent/config.json` (MODIFIED — new `policy` object: engine + policy_root)
|
|
- `schemas/policy_check_result.schema.json` (READ-ONLY — no change per D-116)
|
|
- `schemas/README.md` (MODIFIED — note engine: "kyverno" shared by K8s adapter + kj)
|
|
- `tests/fixtures/capability_inventory.json` (NEW — clean + drifted inventory fixtures for regression policies)
|
|
- **Reason:** The `config.json.policy` object is a schema-first addition
|
|
(new top-level key with `engine` + `policy_root` fields). The
|
|
capability-inventory JSON fixtures for the regression-gate policies
|
|
(REQ-304) are structured data — the data-engineer owns the fixture
|
|
shape. The `policy_check_result.schema.json` is read-only (D-116 — no
|
|
enum change); the data-engineer documents the `engine: "kyverno"`
|
|
sharing in `schemas/README.md`. No migrations (no database). No Python
|
|
(backend-engineer + policy-engineer territory).
|
|
|
|
## Deactivated personas
|
|
|
|
### frontend-engineer
|
|
- **active:** false
|
|
- **Reason:** ACDL has no frontend (no package.json — confirmed in
|
|
config.json personas.personas[frontend-engineer].reason). v1.25 adds
|
|
no UI work — the policy engine is backend + policy artifacts only.
|
|
Deactivated per the v1.15+ convention. |