a63c85bc51
Relocate completed-milestone history to .ciagent/archive/ (byte-identical
snapshots of PROJECT/REQUIREMENTS/ROADMAP/ARCHITECTURE pre-compression +
verbatim moves of REVIEW/AUDIT/VERIFY/PRE_MORTEM). Slim the in-place files
to retain only active-milestone (v1.26) + immediate-predecessor (v1.25)
context + durable vision/tenets/scope/RACI/capability-status/load-bearing
decisions. REGRESSION_REPORT.{json,md} stay in place (live read/write
targets of core/metrics/collector.py + core/regression_verify.py).
Working context: 11,164 → 4,152 lines (~63% reduction). Archive preserves
8,615 lines. Lossless via relocation + git history. No test regressions
(761 passed; same 3 pre-existing failures as baseline).
---ci---
project: acdl
phase: 2
milestone: v1.26
status: execute
lessons:
- REGRESSION_REPORT.{json,md} are live operational files (read by
core/metrics/collector.py + core/regression_verify.py) — must NOT be
archived. Pre-flight grep for code references to candidate archive
paths before any move.
- test_no_purged_loaded_term scans .ciagent/PROJECT.md + CLARIFY.md +
docs/ for 'penetrat' — slimmed files must not reintroduce it. Historical
description of the purge ('removed the term ...') is safe in ROADMAP.
- Git rename detection (R) works for pure file moves; snapshot-then-slim
shows as A + M. Both preserve history.
---/ci---
1785 lines
135 KiB
Markdown
1785 lines
135 KiB
Markdown
# Nova — The New Dawn of DevSecOps
|
||
|
||
> **Rebrand complete (milestone v1.15 — Nova, tag v1.15.4).** The
|
||
> project was rebranded from **ACDL** / "Agentic Cloud Delivery
|
||
> Platform" → **Nova** / "The New Dawn of DevSecOps — security as a
|
||
> seamless enabler of fast deployments." The new tagline is added
|
||
> alongside the existing "North Star" / "consumers declare intent"
|
||
> framing. See `.ciagent/REQUIREMENTS.md` §v1.15 and
|
||
> `.ciagent/ROADMAP.md` §v1.15.
|
||
|
||
## Vision / Core Value
|
||
|
||
Consumers declare intent; the platform delivers safe production
|
||
deployment through an agentic stack. The platform absorbs two frictions:
|
||
the cognitive load of getting the infrastructure right, and the
|
||
operational work of getting the change to production safely.
|
||
|
||
Source of truth for **why**: `docs/vision.md`.
|
||
Source of truth for **how**: `docs/architecture.md` + `.ciagent/ARCHITECTURE.md`.
|
||
Where the two conflict, the vision wins.
|
||
|
||
## North Star
|
||
|
||
A merged change progresses through lower environments end-to-end without a
|
||
platform engineer joining a thread, approving a ticket, or manually
|
||
triggering a stage gate. A non-technical consumer ships a production
|
||
deployment by declaring intent — without authoring a workflow, a
|
||
configuration file, or a Terraform module. Every production change is
|
||
traceable to a human attestation and an immutable evidence stream.
|
||
|
||
## Core Tenets (from `docs/vision.md`)
|
||
|
||
1. **Operations are Declared, Not Executed.** Consumers define what they
|
||
need; the platform reconciles, provisions, and progresses.
|
||
2. **The Delivery Lifecycle is a Sovereign Boundary.** The platform
|
||
governs infra and delivery; it does not reach into upstream product/SDLC.
|
||
Integration is only through validated, published contracts.
|
||
3. **Lower Environments are Autonomous; Higher Environments are Attested.**
|
||
Dev = zero-touch agentic. QA/prod/dr = deliberate human attestation, not
|
||
rubber stamps.
|
||
4. **Safety is Computed, Not Assumed.** Every action produces a measurable,
|
||
explainable confidence signal. The signal is the platform's certified
|
||
answer to "is this safe to proceed?"
|
||
5. **Infrastructure is Consumed, Not Maintained.** Compute is abstract,
|
||
containerized, or serverless. No node/OS/bare-metal lifecycle.
|
||
6. **Two Consumer Surfaces, One Platform.** Technical developers (L3A) and
|
||
non-technical consumers (L3B) converge on the same contract schema, the
|
||
same policy envelope, and the same evidence stream.
|
||
|
||
## Domain Boundaries
|
||
|
||
- **In scope:** environment progression; cloud resource lifecycle; operational
|
||
security and observability NFRs; policy enforcement; immutable audit
|
||
lineage; confidence frameworks; two consumer surfaces (developer + agentic).
|
||
- **Out of scope:** application business logic; IDE workflows; product
|
||
backlog / sprint planning; compute requiring node-level or OS-level management.
|
||
- **Interface:** upstream systems integrate through a strict contract
|
||
boundary. The platform validates, enriches with operational standards,
|
||
and reconciles the target state.
|
||
|
||
## Scope: Nova is Downstream of PDLC
|
||
|
||
> **Promoted from Core Tenet #2 + Anti-Goal #1 (v1.18, REQ-216).** This
|
||
> is the unmissable scope statement — the PDLC is upstream, Nova is
|
||
> downstream.
|
||
|
||
The **Product Development Lifecycle (PDLC)** — product backlog, code
|
||
authorship, IDE workflows, sprint planning, application business logic —
|
||
is **upstream** of Nova. Nova never reaches into the PDLC. Nova's domain is
|
||
**infrastructure + delivery only**: environment progression, cloud
|
||
resource lifecycle, operational security/observability NFRs, policy
|
||
enforcement, immutable audit lineage, and the two consumer surfaces
|
||
(technical developer + agentic).
|
||
|
||
Integration between the PDLC and Nova is **only** through the validated,
|
||
published contract boundary (`schemas/contract.schema.json` +
|
||
`schemas/submission-readiness.schema.json`). The citizen developer's AI
|
||
coding agent, an upstream agentic SDLC platform, or any upstream
|
||
development platform may all produce submissions — the source does not
|
||
matter because all are subject to the same compliance standards (the
|
||
submission-readiness gate, D-133). Nova validates, enriches with
|
||
operational standards, and reconciles the target state. Nova never
|
||
authors application code, manages product backlogs, or provides IDE
|
||
workflows.
|
||
|
||
```
|
||
PDLC (upstream) Nova (downstream)
|
||
───────────────── ─────────────────
|
||
product backlog contract ingestion
|
||
code authorship (AI agent / IDE / SDLC) → submission-readiness gate
|
||
sprint planning → policy enforcement
|
||
application business logic → cloud resource lifecycle
|
||
→ environment progression (dev→qa→prod→dr)
|
||
→ immutable audit + attestation
|
||
```
|
||
|
||
## RACI Matrix
|
||
|
||
> **Source of truth (v1.18, REQ-215, D-139).** Three roles clarify who
|
||
> owns what across the Nova delivery lifecycle. The matrix is the
|
||
> authoritative version; `docs/raci.md` is the citizen-developer-facing
|
||
> copy.
|
||
|
||
### Roles
|
||
|
||
- **Citizen Developer (CD)** — the consumer (technical developer L3A or
|
||
non-technical L3B). Responsible for all **Functional Requirements (FRs)**
|
||
and **User Acceptance Testing (UAT)**. The FRs + UAT are produced via
|
||
the citizen developer's AI coding agent, an upstream agentic SDLC, or
|
||
an upstream development platform — **the source does not matter as all
|
||
are subject to the same compliance standards** (the submission-readiness
|
||
gate, D-133).
|
||
- **Platform** — Nova. Responsible for all **Non-Functional Requirements
|
||
(NFRs)**, **Infrastructure** (cloud resource lifecycle, state, IAM),
|
||
**QA** (the platform-side quality checks: policy, confidence, schema),
|
||
and **Production deployments to cloud** (the apply path, the pipeline,
|
||
the release).
|
||
- **Release Management (RM)** — **co-owned**. QA + SRE attestations are
|
||
required by the actual release. The attestations are performed
|
||
agentically (the platform runs the checks), but the release is
|
||
**overseen and triggered by the Citizen Developer** — the human
|
||
attestation at the stage gate (D-042, hitl_gates.py). The platform
|
||
performs; the citizen developer authorizes.
|
||
|
||
### Matrix
|
||
|
||
| Work Category | Citizen Developer | Platform | Release Management |
|
||
|---|---|---|---|
|
||
| **Functional Requirements (FRs)** | **R/A** | C | I |
|
||
| **User Acceptance Testing (UAT)** | **R/A** | C | I |
|
||
| **Non-Functional Requirements (NFRs)** | I | **R/A** | C |
|
||
| **Infrastructure (cloud, state, IAM)** | I | **R/A** | C |
|
||
| **QA (policy, confidence, schema checks)** | C | **R/A** | I |
|
||
| **Production deployment to cloud** | I | **R/A** | C |
|
||
| **Release attestation (QA + SRE sign-off)** | **A** | R | **R** |
|
||
|
||
**Key: R** = Responsible (does the work) · **A** = Accountable (owns the
|
||
outcome, sign-off) · **C** = Consulted · **I** = Informed.
|
||
|
||
**Compliance-standard equivalence note:** the citizen developer's FRs +
|
||
UAT may originate from any upstream source — an AI coding agent, an
|
||
agentic SDLC platform, or a traditional development platform. All are
|
||
subject to the same compliance standards: the submission-readiness gate
|
||
(`schemas/submission-readiness.schema.json`), the contract schema, the
|
||
policy envelope, and the immutable audit stream. The platform does not
|
||
differentiate by upstream source; it validates the submission, not the
|
||
author.
|
||
|
||
**Co-ownership of Release Management:** the release is co-owned. The
|
||
platform performs the QA + SRE attestations agentically (confidence signal,
|
||
policy checks, separation-of-duties). The citizen developer oversees and
|
||
triggers the actual release — the human attestation at the stage gate is
|
||
the citizen developer's authorization, recorded with approver identity
|
||
(D-042). The platform runs the checks; the citizen developer authorizes
|
||
the promotion. This is the "autonomy in operations, human at stage gates"
|
||
model from the NORTH_STAR.
|
||
|
||
## Capability Status (Re-Verified 2026-07-27)
|
||
|
||
> Source of truth: `.ciagent/CAPABILITY_INVENTORY.md` (Phase 54, D-093).
|
||
> Tier: **local** = runs via emulating adapters (no AWS); **live-aws** =
|
||
> runs against the live AWS account (581513795199).
|
||
|
||
**Decay disclosure.** Capabilities marked complete in v1.1–v1.8 ran
|
||
successfully at the time of tagging. As of 2026-07-27 they were **not
|
||
reproducible** — the v1.7/v1.8 platform simplification introduced 7
|
||
adapter defects that prevented `terraform init/validate/plan` from
|
||
succeeding against live AWS, and the decks (v1.9.1–v1.9.8) presented
|
||
the capability as current without disclosing the decay. The v1.10
|
||
milestone (Phases 52–55) re-verified every advertised capability and
|
||
fixed all 7 defects in-sweep (D-090: no cap). The headline E2E now
|
||
passes at both tiers.
|
||
|
||
**Auto-verified capabilities (16/16 Verified):**
|
||
|
||
| ID | Capability | Tier | Status |
|
||
|----|-----------|------|--------|
|
||
| CAP-001..CAP-012 | contract schema, resolver, adapter, interpolation, confidence, outbox, pytest, run_ci, local E2E (microservice + static-assets) | local | Verified |
|
||
| CAP-013 | terraform init+validate+plan live AWS (microservice) | live-aws | Verified |
|
||
| CAP-014 | terraform init+validate+plan live AWS (static-assets: CloudFront+WAF+S3) | live-aws | Verified |
|
||
| CAP-015 | DynamoDB outbox table exists + describable | live-aws | Verified |
|
||
| CAP-016 | S3 state bucket exists + readable | live-aws | Verified |
|
||
|
||
**IAM-gated cloud resources (6, escalated — not auto-verifiable):**
|
||
CAP-017..CAP-022 (DynamoDB contracts table, Lambda contract-ingestor,
|
||
ECS service live, CloudFront production stack, uptime-kuma, OIDC
|
||
role). The `acdl-spike-runner` IAM user lacks the permissions to
|
||
verify these (chicken-and-egg: it cannot fix its own IAM). The
|
||
terraform plan path (CAP-013, CAP-014) proves the code would deploy
|
||
them; the local emulators (Phase 53) prove the runtime behavior.
|
||
Re-bootstrap of the OIDC role + IAM re-grant requires an admin
|
||
principal — escalated, not silently skipped. See
|
||
`CAPABILITY_INVENTORY.md` §"Cloud capabilities NOT re-verified".
|
||
|
||
**Regression gate.** `bash scripts/run_regression.sh` re-runs all 16
|
||
auto-verifiable capabilities and fails closed on any non-Verified
|
||
result. The gate runs at milestone completion (D-091).
|
||
|
||
## Objective for Milestone v1.1 (prior — complete, tag `v1.2.0`)
|
||
|
||
Finalize the architecture to v1.0 (resolve all 11 open design decisions in
|
||
`docs/architecture.md` §13) and prove the locked commitments with one
|
||
end-to-end v1 implementation spike:
|
||
|
||
- **One L1 module** (`l1-s3`) — engine-agnostic, IR-typed interface.
|
||
- **One L2 thin-composition** (`l2-static-assets`) — references the L1.
|
||
- **Terraform adapter** — compiles the IR to a real `terraform plan`
|
||
against AWS via OIDC (no long-lived credentials, per §12.5).
|
||
- **One contract submission** → contract→IR resolution →
|
||
`terraform plan` → PolicyCheckResult (Checkov) → confidence signal →
|
||
evidence event to the DynamoDB outbox.
|
||
|
||
The spike validates the architecture's claim that the IR-shaped commitments
|
||
do not require a polyglot mess (`docs/architecture.md` §14, step 2).
|
||
|
||
**Status: COMPLETE — all 5 phases shipped (v1.1.1..v1.1.5) + verified; review
|
||
READY TO SHIP (0 P0); audit CLEAN; milestone tag `v1.2.0`; Gitea release
|
||
id 202 published. D-034 closed (root key deactivated by user).**
|
||
|
||
## Milestone v1.1 Phases (prior — complete)
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 06 | archive-demo-and-reorient | Move the v1.0 demo (`modules/`, `scripts/`, `evidence-ui/`, `contracts/`, demo workflows) to `demo/`; establish the new repo layout (`platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/`); rewrite README. |
|
||
| 07 | architecture-v1-finalization | Resolve the 11 open decisions → architecture v1.0. Author IR JSON Schema, PolicyCheckResult schema, contract schema, confidence-signal spec, HITL matrix, outbox/ledger design under `schemas/` + `platform/`. |
|
||
| 08 | aws-oidc-bootstrap | One-shot use of a temporary long-lived key (waiver D-034) to create an IAM role + OIDC trust policy for the act_runner, an S3 state bucket, and a DynamoDB lock table. Rotate the key. Verify the runner assumes the role via OIDC with no long-lived secret. |
|
||
| 09 | v1-spike-ir-and-l1-and-adapter | Target Stack IR; one real L1 (`l1-s3`) with IR-typed interface; L1 registry; Terraform adapter (IR → Terraform var/output + `terraform plan`) running against AWS via OIDC. |
|
||
| 10 | v1-spike-l2-and-contract-e2e | One L2 thin-composition (`l2-static-assets`) referencing `l1-s3`; contract schema + contract→IR resolution; one end-to-end contract submission → `terraform plan` → Checkov → confidence signal → evidence event to outbox. Verify the IR commitments hold. |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.2.0` (feature milestone, next
|
||
minor per ship.md) → audit. **DONE.**
|
||
|
||
## Objective for Milestone v1.2 (prior — complete)
|
||
|
||
Platform hardening + first real consumer deployment. The v1.1 spike proved
|
||
the IR commitments hold on a single dev-only `terraform plan` for one S3
|
||
bucket. v1.2 takes the spike to a real, simpler, better-documented platform
|
||
that actually delivers a microservice to AWS ECS Fargate end-to-end.
|
||
|
||
Five scope axes (user-directed, 2026-07-21):
|
||
|
||
1. **Re-evaluate the current state.** Confirm go-gitea/gitea#36988 (OIDC for
|
||
Gitea Actions) is still unmerged (re-checked 2026-07-21: **open**, last
|
||
updated 2026-05-27). Extend the D-039 per-run-rotated-key waiver for
|
||
v1.2; real OIDC is deferred to v1.3+ (D-047).
|
||
2. **NFR improvements on the existing spike.** Least-privilege IAM audit,
|
||
idempotent bootstrap, proper exit codes / error handling, rotation
|
||
hygiene, P1-1 / P1-B redaction carried forward from the v1.1 audit.
|
||
3. **Streamline / simplify the current setup.** Consolidate the
|
||
`run_spike_*.sh` scripts into one `scripts/run_platform.sh`; remove
|
||
dead code and stale paths; one command runs the whole pipeline.
|
||
4. **README.md fully up to date on how the platform works.** The current
|
||
README still says "v1.1 (active)" — it must reflect v1.1 complete, the
|
||
actual spike flow, how to run it, the real repo layout, and the v1.2
|
||
objective.
|
||
5. **Bootstrap a consumer repo with a basic microservice deployed to ECS
|
||
end-to-end.** New Gitea repo `acdl-consumer-microservice` (org
|
||
`continuous-intelligence`) holding a tiny HTTP container + Dockerfile;
|
||
new IR-typed L1s (`l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`,
|
||
`l1-iam-role`, `l1-alb`, `l1-ecr`); new `l2-microservice`
|
||
thin-composition; one contract submission → `terraform apply` (dev,
|
||
autonomous) → a live ECS Fargate service serving HTTP 200 → evidence
|
||
event to the DynamoDB outbox → acdl-evidence timeline.
|
||
|
||
The milestone proves the platform delivers real value (a running
|
||
microservice), not just a plan.
|
||
|
||
## Milestone v1.2 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 11 | v1.2-research-and-readme | Re-eval #36988 (confirm open → extend D-039 as D-047). Audit the v1.1 spike for NFR gaps (least-privilege, idempotency, error handling, rotation hygiene) + simplification opportunities. **Rewrite README.md** to reflect v1.1 complete + how the platform actually works (spike flow, how to run, repo layout, v1.2 objective). Output: RESEARCH.md v1.2 addendum; updated README. |
|
||
| 12 | nfr-harden-and-simplify | Apply Phase 11 findings: tighten `spike_runner_policy.json` (least-privilege audit); make `terraform/bootstrap/create_*.py` idempotent; consolidate `run_spike_*.sh` → one `scripts/run_platform.sh`; proper exit codes / error handling; redact P1-1 AWS key IDs in `VERIFY.md`; fix any remaining stale `platform/` paths. Spike still runs e2e after the refactor. |
|
||
| 13 | l1-catalog-for-ecs | Author IR-typed L1s for an ECS Fargate microservice: `l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`, `l1-iam-role` (task + exec role), `l1-alb`, `l1-ecr`. Register all in `modules-ir/registry.json`. Expand the Terraform adapter `TYPE_MAP`. Each L1 produces a valid `terraform plan` fragment. |
|
||
| 14 | l2-microservice-and-contract-schema | Author `l2-microservice` thin-composition (references the ECS L1s, depth ≤ 5). Extend `schemas/contract.schema.json` for microservice inputs (image, port, env, healthcheck). Verify contract→IR resolution yields a complete target stack. |
|
||
| 15 | consumer-repo-and-terraform-apply | Create consumer repo `acdl-consumer-microservice` (Gitea org) with a basic microservice (tiny HTTP container + Dockerfile + ECR push). Lift the platform from `plan` → **`apply`** (dev, autonomous per §10). Submit `contracts/microservice.yaml` → pipeline → IR → plan → apply → a real ECS Fargate service running. |
|
||
| 16 | v1.2-capstone-e2e | End-to-end verification: consumer commit → pipeline → ECS service live serving HTTP 200 → evidence event to the DynamoDB outbox → acdl-evidence timeline renders it. Verify NFR improvements hold, the setup is simpler (one `run_platform.sh`), and the README is accurate. |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.3.0` (feature milestone, next
|
||
minor per ship.md — v1.1 shipped `v1.2.0`) → audit.
|
||
|
||
## Objective for Milestone v1.4 (active)
|
||
|
||
Central pipeline contract + shell reproducibility + output streaming. The
|
||
v1.3 milestone (Phases 17–18) created identical CI/CD pipelines for Gitea
|
||
and GitHub but they were duplicated copies with no single source of truth.
|
||
v1.4 makes the pipeline a declarative contract, enables full shell
|
||
reproducibility, and streams terraform/checkov output so users can see
|
||
what the platform is doing.
|
||
|
||
Three scope axes:
|
||
|
||
1. **Central pipeline contract.** A JSON Schema
|
||
(`schemas/pipeline.schema.json`) + YAML instance (`pipelines/ci.yaml`)
|
||
declares the pipeline stages, commands, triggers, and runner. Both
|
||
`.gitea/workflows/ci.yml` (Gitea Actions, dev) and
|
||
`.github/workflows/ci.yml` (GitHub Actions, production) implement the
|
||
contract. A test validates conformance.
|
||
2. **Shell reproducibility.** `scripts/run_ci.sh` mirrors the CI pipeline
|
||
locally — runs the same 3 stages (lint, test, check-only) in sequence.
|
||
The pipeline is fully reproducible from the shell, not just in CI.
|
||
3. **Output streaming.** `scripts/run_platform.sh` streams terraform
|
||
init/validate/plan output, Checkov compliance results, and
|
||
PolicyCheckResult records to stdout by default, so the user sees what
|
||
is happening. A `--quiet` flag suppresses streaming for log-only mode.
|
||
|
||
## Milestone v1.4 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 19 | central-pipeline-contract-and-shell-reproducibility | Create the central pipeline contract (JSON Schema + YAML instance). Create `scripts/run_ci.sh` for shell reproducibility. Update `run_platform.sh` to stream terraform/checkov output. Update both workflow YAMLs with contract references (staying byte-identical). Add tests for contract validation, workflow conformance, and streaming. |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.4.1` (feature milestone, next
|
||
minor per ship.md — v1.3 shipped `v1.3.2`) → audit.
|
||
|
||
## Objective for Milestone v1.7 (complete)
|
||
|
||
Production platform + contract ingestion + pipeline maturation. The v1.6
|
||
milestone left the platform documented and environments-aware; v1.7 took it
|
||
to a production-grade platform. 12 user-directed scope axes (2026-07-22):
|
||
|
||
1. **Rename `static-assets` → `static-assets`** (D-048 — including
|
||
`.ciagent/` historical narrative, overriding the v1.6 preservation
|
||
precedent). The reconstruction test is updated to expect `static-assets`.
|
||
2. **Augment `static-assets` to a production-ready stack** by authoring a
|
||
new `cloudfront` primitive + a `waf` primitive (D-049: S3 + CloudFront
|
||
OAC + WAF; Route53/ACM are domain-dependent and deferred to documented
|
||
extension points).
|
||
3. **DX-friendly deploy outputs** (D-050): SSM Parameter Store (KMS-encrypted
|
||
`SecureString`) for runtime-injectable values + GitHub PR comment / job
|
||
summary for human-readable connection strings. No raw secrets in logs.
|
||
4. **Central deploy pipeline error reporting** via the platform Lambda
|
||
`report_error` action (D-055): the Lambda creates a GitHub issue on the
|
||
platform repo. The consumer's onboarding-granted Lambda-invoke permission
|
||
is the only grant needed — uniform pathway, no separate GitHub
|
||
`issues: write` on the consumer side. Gitea is excluded (only the CIAgent
|
||
uses it).
|
||
5. **PR comments after every successful stage** so developers always know
|
||
where they stand.
|
||
6. **Three platform pipelines**: (1) platform-test (PR, unit + integration +
|
||
schema-validation); (2) primitives-plan (PR, plan-only for all L1
|
||
primitives); (3) patterns-plan (PR, plan-only for all L2 modules).
|
||
7. **Release job** on merge to `main`: computes MAJOR.MINOR.PATCH semver,
|
||
creates the tag, then updates (force-moves) or creates the MAJOR.MINOR +
|
||
MAJOR floating tags (D-057). Consumers on `@v1` or `@v1.6` receive updates
|
||
depending on their pinned version.
|
||
8. **Platform Lambda** for one-way consumer→platform communication
|
||
(contracts). Onboarding grants the consumer repo's environment the right
|
||
to trigger the Lambda (cross-account IAM). The Lambda ingests contracts
|
||
and stores them in a DynamoDB table `acdl-contracts` (D-051) for
|
||
historical reference, impact analysis, CMDB-style application-state
|
||
queries, and pattern detection. The IAM policy reflects cross-account
|
||
invocation.
|
||
9. **Tagging standards** in policy/compliance checks (D-054): a required-tag
|
||
set (`acdl:owner`, `acdl:contract`, `acdl:environment`, `acdl:cost-center`)
|
||
enforced by a Checkov custom YAML rule. Closes the D-043 deferral (the
|
||
SKIPPED `ACDL_TAG_NAMING` placeholder becomes a real check).
|
||
10. **Wiz adapter** for security checks (D-052): a stub + schema path that
|
||
translates Wiz API issues → `PolicyCheckResult` records, degrading
|
||
gracefully when unconfigured. Matches the Checkov adapter pattern.
|
||
11. **Kyverno adapter** for compliance/security checks (D-053): a
|
||
K8s-native policy adapter that translates Kyverno `PolicyReport` results
|
||
→ `PolicyCheckResult` records. Ready but inactive for Terraform-only
|
||
stacks (the platform emits Terraform, not K8s manifests); it activates
|
||
when the GitOps reconciler (roadmap) emits K8s manifests.
|
||
12. **Remove the legacy consumer-repos directory** and add validated per-module examples
|
||
(D-058: `modules/<name>/examples/` with `simple.yaml` + `complex.yaml`
|
||
validated in CI) + a new RDS primitive demonstrating multi-engine
|
||
variation (D-059).
|
||
|
||
## Milestone v1.7 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 22 | rename-and-production-static-assets-stack | Rename `static-assets` → `static-assets` everywhere (D-048). Author `cloudfront` + `waf` primitives. Augment `static-assets` to S3 + CloudFront (OAC) + WAF (D-049). Expand adapter. Bump `uses:` to `@v1.6`; create floating `v1.6` + `v1` tags (D-057). |
|
||
| 23 | tagging-standards-and-security-adapters | Required-tag set + Checkov custom rule (D-054, D-043 closure). Wiz adapter stub (D-052). Kyverno K8s-native adapter (D-053). Schema engine enum updated. |
|
||
| 24 | platform-lambda-and-contract-ingestion | Platform Lambda + DynamoDB `acdl-contracts` table (D-051) + cross-account IAM + onboarding grant. |
|
||
| 25 | deploy-pipeline-dx-outputs-and-error-reporting | SSM SecureString + PR comment outputs (D-050). Lambda `report_error` → GitHub issue (D-055). Stage comments after each successful stage. |
|
||
| 26 | platform-pipelines-and-release-automation | 3 platform pipelines (platform-test, primitives-plan, patterns-plan). Release job with semver + MAJOR.MINOR/MAJOR tag updates (D-057). |
|
||
| 27 | remove-legacy-consumer-repos-and-module-documentation-examples | Delete the legacy consumer-repos directory. RDS primitive (D-059). Validated per-module examples (D-058). Docs updates. |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.7.0` (feature milestone, next
|
||
minor per ship.md — v1.6 shipped `v1.6.0`) → audit.
|
||
|
||
## Objective for Milestone v1.8 (active)
|
||
|
||
P1 remediation + uptime monitoring + engineering standards + encryption
|
||
and deletion-protection by default + decommission alias + documentation.
|
||
The v1.7 milestone shipped production platform + contract ingestion but
|
||
left 8 P1 issues flagged for post-hoc review. v1.8 clears all of them
|
||
AND delivers three user-directed feature/NFR tracks (2026-07-22):
|
||
|
||
**Track 1 — P1 Remediation (Phases 28–30):**
|
||
Clear all 8 pending P1 issues from v1.5/v1.6/v1.7 verify reviews:
|
||
- P1-3: SSM uses AWS-managed key silently → fail loud without CMK config
|
||
- P1-4: WAF custom rules emit invalid HCL (attribute vs block syntax)
|
||
- P1-5: WAF default_action input silently ignored
|
||
- P1-6: consumer_invoke_policy.json has placeholder account ID
|
||
- P1-7: L2 composition outputs section not implemented in resolver
|
||
- P1-8: terraform/spike/*.tf overwritten by run_platform.sh (state
|
||
contamination)
|
||
- P1-9: GitHub API URLs hardcoded in contract_ingestor.py (Gitea fails
|
||
silently)
|
||
- S1: Deploy workflow static-key override not wired (passes ACDL_AWS_*
|
||
env vars to configure-aws-credentials which reads AWS_*/its own inputs)
|
||
|
||
**Track 2 — Encryption + Deletion Protection by Default (Phases 31–32):**
|
||
All primitives encrypted by default (CMK priority + SSE, managed KMS
|
||
fallback). Per-stack CMK (one key per L2 deployment, 90-day rotation,
|
||
no shared keys). Deletion protection on by default for every primitive.
|
||
L2 modules expose a feature flag to turn off deletion protection. A
|
||
decommission alias uses a 2-step pipeline (disable deletion protection
|
||
→ zero counts → destroy) with HITL SRE gates and CMDB-validated change
|
||
request ID.
|
||
|
||
**Track 3 — Uptime + Standards + Docs (Phases 33–36):**
|
||
A new uptime-kuma primitive (ECS Fargate) deployed by default after any
|
||
L2 module deploy (separate terraform state), with a feature flag to
|
||
disable. Monitored endpoints passed from L2 outputs. Alert channels
|
||
(Teams/email/SMS/GitHub issues). The uptime URL published to consumers
|
||
via PR comments. Engineering standards for L1 + L2 module authoring
|
||
(scanned from current modules, stored in modules/). READMEs for
|
||
schemas/, adapters/, pipelines/ paths documenting how to write, wire,
|
||
and test each.
|
||
|
||
## Milestone v1.8 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 28 | adapter-waf-and-resolver-outputs | Fix WAF HCL emission (nested rules blocks + default_action input) + implement L2 composition outputs in resolver + adapter output blocks. P1-4, P1-5, P1-7. |
|
||
| 29 | ssm-kms-and-invoke-policy | SSM publisher fails loud without CMK (escape hatch for local) + Terraform-rendered consumer_invoke_policy (no placeholder account ID). P1-3, P1-6. |
|
||
| 30 | run-platform-isolation-and-api-portability | Adapter output to per-run temp dir (remove committed spike .tf) + forge-agnostic API URLs + deploy.yml static-key override wired. P1-8, P1-9, S1. |
|
||
| 31 | encryption-by-default-and-per-stack-cmk | KMS-key primitive + per-stack CMK wired in L2 modules + encryption NFRs on all primitives + managed KMS fallback. |
|
||
| 32 | deletion-protection-by-default-and-l2-feature-flag | Deletion protection NFR on all primitives (default true) + L2 feature flag + contract schema update. |
|
||
| 33 | uptime-kuma-primitive | Uptime L1 primitive (ECS Fargate, feature flag, monitored endpoints, alert channels) + deploy-uptime pipeline stage (separate state) + URL published via PR comment. |
|
||
| 34 | decommission-alias-and-cmdb-validation | Decommission mode on deploy pipeline (2-step: disable deletion protection → zero counts, HITL SRE gates) + DynamoDB CMDB validation + consumer guide docs. |
|
||
| 35 | module-engineering-standards | modules/STANDARDS.md (L1+L2 authoring + review standards scanned from current modules) + catalog index fix + template update + automated standards test. |
|
||
| 36 | schemas-adapters-pipelines-readmes | schemas/README.md + pipelines/README.md + adapters/README.md (how to write, wire, test, dependencies). |
|
||
| 37 | verify | 4-layer verification of all v1.8 phases. |
|
||
| 38 | review-audit-complete | Multi-persona review + audit + milestone completion (tag v1.8.0). |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.8.0` (feature milestone, next
|
||
minor per run.md — v1.7 shipped `v1.7.0`) → audit.
|
||
|
||
## Objective for Milestone v1.9 (complete, tag `v1.9.0`)
|
||
|
||
Production-grade progression: contract interpolation, per-environment
|
||
promotion without field editing, stub implementation, and P1-1
|
||
remediation. The v1.8 milestone shipped encryption/deletion-protection by
|
||
default, uptime, decommission, and engineering standards but left four
|
||
gaps that v1.9 closes (user-directed, 2026-07-23):
|
||
|
||
1. **Design doc refresh.** `core/hitl_matrix_design.md` and
|
||
`core/audit_ledger_design.md` are stale — both still describe the
|
||
v1.1 spike scope ("dev-only; HITL not exercised"; "spike scope =
|
||
hash chain + outbox write; Object Lock + JWS are v1.2"). v1.9 brings
|
||
them up to date with the shipped v1.8 platform and the v1.9 wiring.
|
||
2. **Contract interpolation (variable expansion).** Contracts cannot
|
||
reference environment onboarding values today — bucket names, account
|
||
IDs, regions are hardcoded literals. v1.9 adds `${env.<field>}` and
|
||
`${contract.<field>}` expansion in the resolver, sourced from the
|
||
environment onboarding JSON. Naming patterns like
|
||
`acdl-${env.environment}-${contract.module}-${env.account_id}-${env.region}`
|
||
become expressible. The S3 bucket naming-pattern requirement is the
|
||
binding example.
|
||
3. **Per-environment CI jobs (no field editing for promotion).** Today a
|
||
promotion dev → qa requires editing the `environment:` field in the
|
||
contract YAML. v1.9 ships a hybrid model: (a) per-environment contract
|
||
files (`.acdl/static-assets.dev.yaml`, `...qa.yaml`, etc.) and (b) an
|
||
`environment` `workflow_call` input on the reusable deploy workflow
|
||
that overrides the contract's environment at load time. There is one
|
||
CI job per environment, each pointing at its respective contract (or
|
||
the same contract + the env input). Promotion = running the matching
|
||
job; no field editing.
|
||
4. **Stub implementation.** Identify and implement the stubbed
|
||
functionality: `separation_of_duties.route_halt_artifact` (logs only →
|
||
real SNS + outbox event); HITL qa/prod/dr pre-execution attestation
|
||
gates (only decommission SRE gates are wired today); the full
|
||
8-concern attestation matrix (offline-testable subset implemented;
|
||
operator-supplied concerns accept signed evidence artifacts); the Wiz
|
||
adapter (stub → real API client with graceful degrade); the Kyverno
|
||
adapter (fleshed out translator, still inactive for Terraform-only
|
||
stacks). The audit-ledger S3 Object Lock + JWS + async worker + DLQ +
|
||
daily checkpoints build-out is **deferred** to a future milestone
|
||
(D-083) — it requires non-offline-testable AWS infra (Object Lock
|
||
bucket, KMS signing key, SQS DLQ, Lambda worker).
|
||
5. **Post-hoc requirement from previous milestones.** P1-1 from the v1.2
|
||
review (adapter ECS/ALB/VPC hardcoded defaults — `desired_count = 1`,
|
||
`launch_type = "FARGATE"`, `target_type = "ip"`,
|
||
`load_balancer_type = "application"`, `family = "app"`, `Name = ...`
|
||
— should be parameterized via the L1 interfaces, deferred to v1.3,
|
||
never implemented) is closed. The adapter becomes a thin translator;
|
||
the defaults move into `interface.json` inputs.
|
||
|
||
The milestone also reconstructs `.ciagent/REVIEW.md`, which still holds
|
||
v1.2 review content (v1.3–v1.8 reviews were not persisted). The v1.9
|
||
review overwrites it with current milestone content; a note records the
|
||
historical gap (no git-history rewrite).
|
||
|
||
## Milestone v1.9 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 39 | design-doc-refresh-and-p1-1-parameterization | Refresh `hitl_matrix_design.md` + `audit_ledger_design.md` to current. Move adapter ECS/ALB/VPC hardcoded defaults into L1 `interface.json` inputs (P1-1 closure). |
|
||
| 40 | contract-interpolation | `${env.<field>}` + `${contract.<field>}` resolver expansion from environment onboarding JSON. Environment JSON schema. Sample contracts use naming patterns (region + account id + environment). |
|
||
| 41 | per-environment-ci-jobs | Per-env contract files + `environment` workflow_call input on the deploy workflow. 1 CI job per environment (dev/qa/prod/dr), each pointing at its respective contract. HITL attestation gate structure wired (qa/prod/dr). |
|
||
| 42 | stub-implementation | `route_halt_artifact` real (SNS + outbox). HITL qa/prod/dr attestation gates. 8-concern attestation matrix (offline-testable subset). Wiz real client. Kyverno translator fleshed out. |
|
||
| 43 | verify-review-audit-complete | 4-layer verify. Multi-persona review. Audit. Complete v1.9 (tag `v1.9.0`, floating tags, `uses:` bump `@v1.6` → `@v1.9`). |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.9.0` (feature milestone, next
|
||
minor per run.md — v1.8 shipped `v1.8.0`) → audit.
|
||
|
||
## Patch v1.9.1 (complete, tag `v1.9.1`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Two leadership-facing presentation
|
||
decks (How the Platform Works + The Developer Experience) for senior
|
||
leadership (CTO, Head of Cloud, Head of Infrastructure, Head of DevOps).
|
||
Each deck has a full markdown source of truth (with speaker notes + mermaid
|
||
diagrams) and a lean Marp deck (no speaker notes, embedded PNG diagrams). A
|
||
README documents the 3-step slide creation process (full markdown → Marp
|
||
synthesis → PPTX export) with conventions, build commands, and maturity
|
||
framing rules. No code changes; 494 tests pass; `run_ci.sh` +
|
||
`run_platform.sh --check-only` green.
|
||
|
||
## Patch v1.9.2 (complete, tag `v1.9.2`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Applies the S&P Global Energy brand
|
||
visual identity to both Marp presentation decks. Brand colors extracted
|
||
from the live spglobal.com compiled Tailwind CSS and SVG logo: red-core
|
||
`#D6002A`, grey-90 `#1B1B1B`, grey-80 `#2E2E2E`, grey-5 `#F0F0F0`, Akkurat
|
||
Pro corporate typeface. Title headers changed to full platform name.
|
||
Footer changed from 'Confidential · For Senior Leadership' to 'Internal'.
|
||
Title slide subtitle removed. Last DX slide renamed from 'The Outcome for
|
||
Leadership' to 'The Desired Outcomes'. Marp `theme: default` kept as base.
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green.
|
||
|
||
## Patch v1.9.3 (complete, tag `v1.9.3`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Renders both Marp presentation decks
|
||
to self-contained HTML (committed to `docs/presentations/`, base64-embedded
|
||
images, full S&P Global Energy brand theme) and PPTX (uploaded to the Gitea
|
||
release as downloadable attachments). The HTML files are viewable in any
|
||
browser and on the git forge — they render the red accent bar, dark
|
||
title-slide background, red H1 headings, and Akkurat Pro font stack. README
|
||
updated to document HTML as committed artifacts (re-render when Marp source
|
||
changes) and PPTX as release attachments (binary, not committed to git).
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green.
|
||
|
||
## Patch v1.9.4 (complete, tag `v1.9.4`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Two categories of changes:
|
||
|
||
1. **Presentation slide updates** — title slide redesigned (deck title as H1
|
||
slightly bigger, 'Agentic Cloud Delivery Platform' as H3 subtitle on dark
|
||
background). DX deck: removed Local Reproducibility slide (not beneficial
|
||
for DX narrative), redesigned Safe Promotion Path with side-by-side
|
||
HTML table layout for Approaches A and B, 'an agent' → 'an AI agent' on
|
||
slides 2 and 3, What a Developer Does diagram floated to the right side.
|
||
Running header simplified to just the deck name.
|
||
|
||
2. **Complete removal of a compliance framework** — all references to a
|
||
specific healthcare compliance framework removed from 25 files
|
||
across the codebase: presentation source files (Marp + full markdown),
|
||
all module READMEs (S3, RDS, ECR, ECS, VPC, IAM, KMS, CloudFront, ALB,
|
||
uptime), top-level README, consumer guide, docs index, module standards.
|
||
Compliance milestone lists now read: GDPR, SOX, SOC2, DORA. All section
|
||
references from that framework removed from compliance annotations.
|
||
Rendered HTML decks re-generated from updated Marp source.
|
||
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green. PPTX files uploaded to Gitea release.
|
||
|
||
## Patch v1.9.5 (complete, tag `v1.9.5`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. 9 requirements implemented:
|
||
|
||
1. DX closing slide strengthened with 'Infrastructure as a utility, not a
|
||
craft' bullet — conveys the full vision (infrastructure consumed, not
|
||
maintained; platform compounds value over time).
|
||
2. PW Problem slide: 'moving a merged change' → 'promoting a change'.
|
||
3. PW Problem slide: added 'Red tape' and 'Scalability without increasing
|
||
headcount' bullets (4 frictions, not 2).
|
||
4. PW Roadmap slide: redesigned with side-by-side HTML table layout
|
||
(Testing | Planned), 16px font, no overflow.
|
||
5. PW deck: new slide 'What This Platform Is — and Isn't' after North Star
|
||
(sovereign boundary, infrastructure as utility, 4 anti-goals). PW deck
|
||
now 16 slides.
|
||
6. Maturity nomenclature: 'Available today'/'shipped' → 'Testing' across
|
||
both decks + source markdown. New .testing badge (blue/teal). The
|
||
platform has 0 consumer adoption — 'shipped' was inaccurate.
|
||
7. Global: 'substrate' → 'engine' across entire project (88 matches, 30+
|
||
files including .ciagent/, docs/, modules/, adapters/, schemas/, code).
|
||
8. Presentation files only: 'forge' → 'VCS' (6 occurrences in 4 files).
|
||
'forge' retained in all technical docs and code.
|
||
9. New .agentic badge (purple/violet) appended to agentic features in both
|
||
decks: confidence signal, autonomous dev, pattern recognition, dynamic
|
||
module creation, citizen developer surface, auto-promotion.
|
||
|
||
Also: Change Request ID format changed from 'CR-2026-001' to 'CHG0678912'
|
||
across presentation files, consumer guide, and test fixtures.
|
||
|
||
No code changes (test fixture strings only); 494 tests pass; `run_ci.sh` +
|
||
`run_platform.sh --check-only` green. PPTX files uploaded to Gitea release.
|
||
|
||
## Patch v1.9.6 (complete, tag `v1.9.6`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Both Marp presentation decks
|
||
consolidated to 10 high-impact slides each — every slide high-impact, fluff
|
||
eliminated.
|
||
|
||
**How The Platform Works (16 → 10):**
|
||
- Merged Problem + North Star + What It Is/Isn't → 1 slide (4 frictions →
|
||
North Star → 3 success criteria → 2 anti-goals)
|
||
- Merged Policy & Security + Secure by Default → 'Security by Construction'
|
||
- Merged Immutable Audit + Human-in-the-Loop → 'Accountability & Audit'
|
||
- Folded Observability, Platform-Managed Environments, Portability into
|
||
existing slides as bullets
|
||
- Added 'The Vision Realized' closing slide
|
||
|
||
**The Developer Experience (15 → 10):**
|
||
- Merged What Dev Does + Contract + No Platform Code → 'The Contract — The
|
||
Entire Consumer Surface'
|
||
- Merged Instant Feedback + Deploy Outputs → 'The Developer Feedback Loop'
|
||
- Merged Safe Promotion Path + Rising Bar → 1 slide
|
||
- Cut Citizen Developer Experience standalone (mentioned on slides 2 + 10)
|
||
- Kept Versioned Releases, Friendly Onboarding, Safe Decommission
|
||
|
||
**Also:** Removed '5-line YAML' claim from both decks (credibility — complex
|
||
stacks require more lines). Source markdown files unchanged (remain complete
|
||
reference with speaker notes for all original slides).
|
||
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green. PPTX files uploaded to Gitea release.
|
||
|
||
## Patch v1.9.7 (complete, tag `v1.9.7`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Created two talking points markdown
|
||
files — one per deck — distilling the source of truth (speaker notes +
|
||
content) into presenter-ready cues indexed by the Marp deck's 10-slide
|
||
structure. Each file has one section per Marp slide with 3-6 talking point
|
||
bullets (punchy, actionable cues) + a key takeaway per slide. The talking
|
||
points are the middle layer between the source of truth (full detail) and
|
||
the Marp deck (what the audience sees). README updated from 3-step to 4-step
|
||
process (added Step 4: talking points), with updated diagram, directory
|
||
layout, checklist, and decks table.
|
||
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green.
|
||
|
||
## Patch v1.9.8 (complete, tag `v1.9.8`)
|
||
|
||
Docs-only NFR patch on the v1.9 line. Major presentation rework based on
|
||
leadership feedback. 6 new mermaid diagrams created and rendered to PNG:
|
||
scope boundary (x2 — one per deck, showing upstream → contract → ACDL →
|
||
AWS), confidence signal (6 inputs → weighted sum → threshold gate →
|
||
proceed/halt), attestation flow (deploy → gate → approver → evidence),
|
||
promotion journey (dev → qa → prod → dr with rising thresholds), and road
|
||
to the North Star (phased timeline v1.0 → v1.9 → v1.10 → v2.0 → North Star).
|
||
|
||
Both Marp decks restructured to 10 main + 6 appendix slides (PW: 17 total,
|
||
DX: 16 total). Key changes:
|
||
|
||
1. NEW scope slide ("Where ACDL Sits in Your World") clarifying ACDL is
|
||
infrastructure only. Upstream is anything (IDE, agentic SDLC, citizen
|
||
dev vibe coding). ACDL provisions and governs AWS resources; application
|
||
deployment is upstream.
|
||
2. Contract examples fixed: `image:` field removed, replaced with
|
||
infrastructure inputs (cpu, memory, desired_count, port).
|
||
3. Story arc: every slide has an italic story beat line connecting the
|
||
narrative progression.
|
||
4. Confidence signal diagram added (slide 7) showing 6 inputs → score →
|
||
gate. Clarified: manually tuned weights, observable inputs, auditable
|
||
breakdown.
|
||
5. Attestation flow diagram added (slide 9) showing deploy → gate →
|
||
approver reviews → attestation recorded → evidence. QA clarification
|
||
added: QA attests to infrastructure readiness (contract + Terraform plan
|
||
+ evidence), not application code.
|
||
6. QA attestation reclassified: "Design tested" → "Planned". Dev autonomous
|
||
= Testing. qa/prod/dr attestation = Planned.
|
||
7. DX deck: Two Consumer Surfaces slide replaced by scope boundary slide
|
||
showing both consumer paths. Promotion journey diagram added.
|
||
8. Rising bar table annotated: dev=Testing, qa/prod/dr=Planned.
|
||
9. Appendix (6 slides per deck): TOC, detail-heavy slides moved from main
|
||
deck, Road to the North Star phased timeline (annotated "proposed
|
||
phasing, not formally planned"), full Testing vs. Planned inventory,
|
||
glossary.
|
||
10. Old two-surfaces diagram replaced by scope boundary diagram.
|
||
|
||
Source markdown, talking points, and README all updated to mirror the new
|
||
structure. Also includes scripts/sync_to_nova.sh (manual-only "2nd release"
|
||
into ~/nova — a separate GitLab consumer-facing repo with its own history;
|
||
domain-based conventional commits, never triggered by CI; REQ-229).
|
||
|
||
No code changes; 494 tests pass; `run_ci.sh` + `run_platform.sh --check-only`
|
||
green. PPTX files uploaded to Gitea release.
|
||
|
||
## Objective for Milestone v1.18 (active — Citizen Developer & Production-Grade Guidance)
|
||
|
||
v1.18 advances Nova from a platform that governs infrastructure delivery
|
||
to one that **instructs the citizen developer on production-grade
|
||
engineering** and defines a **clear, machine-checkable contract for what
|
||
is acceptable to start**. Five user-directed inputs drive the milestone:
|
||
|
||
1. **S&P Global theme restoration.** The v1.17 P5 deck rebuild consolidated
|
||
two decks into one unified narrative deck but lost the S&P Global Energy
|
||
brand visual identity (introduced v1.9.2 / P45, commit `ae0cb58`). The
|
||
Marp `style:` block (red-core `#D6002A`, grey-90 `#1B1B1B`, Akkurat Pro
|
||
font, 8px top accent bar) is restored to the unified deck. The mermaid
|
||
`sp-theme.json` survived; only the Marp CSS theme was lost.
|
||
|
||
2. **PDLC-upstream scope made explicit.** Core Tenet #2 already states the
|
||
platform "does not reach into upstream product/SDLC" and Anti-Goal #1 says
|
||
"Not an upstream development platform." v1.18 promotes this from a
|
||
buried tenet to a dedicated, unmissable scope statement in PROJECT.md +
|
||
`docs/scope.md` + a deck slide: **the PDLC (Product Development
|
||
Lifecycle — product backlog, code authorship, IDE) is upstream of Nova;
|
||
Nova governs infra + delivery only; integration is through the validated
|
||
contract boundary.**
|
||
|
||
3. **RACI matrix.** A three-role responsibility matrix clarifies who owns
|
||
what: **Citizen Developer** (Responsible for all Functional Requirements
|
||
+ User Acceptance Testing, via their AI coding agent / upstream agentic
|
||
SDLC / upstream development platform — the source does not matter as all
|
||
are subject to the same compliance standards), **Platform** (Responsible
|
||
for all NFRs + Infrastructure + QA + Production deployments to cloud),
|
||
**Release Management** (co-owned: QA + SRE attestations required by the
|
||
actual release, performed agentically but overseen & triggered by the
|
||
Citizen Developer). Source of truth in PROJECT.md + `docs/raci.md` + a
|
||
deck slide.
|
||
|
||
4. **Nova input contract — "what is acceptable to start."** A JSON Schema
|
||
(`schemas/submission-readiness.schema.json`) defines the
|
||
acceptable-to-start gate as a superset *above* contract-schema validity:
|
||
schema-valid contract + required Nova tags + per-env mandatory metadata
|
||
(per W3.E) + declared policy preconditions + (for L3B) `profile:agentic`
|
||
markers + `appSource` pointer. A validator (`core/submission_readiness.py`,
|
||
invoked as `contract_ingestor.py --check-readiness`) returns a structured
|
||
`ReadinessResult` with reason codes. On fail → citizen-developer-facing
|
||
error (not a stack trace); on pass → proceeds to existing ingestion.
|
||
|
||
5. **Atelier integration — production-grade guidance + agentic validation.**
|
||
Nova consumes `coreci/atelier` (a first-principles docs-as-code
|
||
engineering framework — 8 core principles, 19 domains, 190 P-rules) via
|
||
two surfaces: **skills** (markdown files under `skills/` keyed to Atelier
|
||
domain paths, surfaced to the citizen developer's AI agent, extending the
|
||
BA.A 5-skill catalog) and an **MCP server** (`mcp/atelier/server.py`,
|
||
plugin-registry architecture, stdio transport, vendored Atelier snapshot
|
||
for audit reproducibility) exposing tools for principle-lookup,
|
||
domain-listing, matrix-lookup, and agentic validation against the
|
||
Atelier agent-checklist — validation that goes beyond deterministic
|
||
scanners (Wiz/Checkmarx/Mend) by catching correctness/clarity/simplicity/
|
||
observability gaps.
|
||
|
||
**Deck automation (cross-cutting):** any phase modifying
|
||
`docs/presentations/*-marp.md` or `docs/presentations/assets/` MUST
|
||
re-render HTML + PPTX, **commit the PPTX to git** (binary, no LFS), and
|
||
attach it to the phase's Gitea release. New scripts:
|
||
`scripts/render_deck.sh` (HTML + PPTX render) and
|
||
`scripts/attach_release_asset.py` (Gitea release asset upload).
|
||
|
||
**Milestone type:** Feature (P1 S&P theme restoration + P3 readiness
|
||
schema/validator + P5 MCP server are new code/features). Tags run on the
|
||
**v1.17.x** patch line (previous minor per branch-strategy): `v1.17.0` (P0)
|
||
→ `v1.17.1..v1.17.6` (P1–P6) → `v1.17.7` (P7 final = milestone release).
|
||
|
||
**Phase count:** 8 (P0 pre-execution + 6 execution + 1 final).
|
||
|
||
**Hard constraints:**
|
||
- DO NOT make anything up (NORTH_STAR.md honesty model).
|
||
- The submission-readiness schema is a superset gate above
|
||
`contract.schema.json`, NOT a duplicate — it references but does not
|
||
redefine contract fields.
|
||
- The MCP server is plugin-registry extensible (future capabilities drop
|
||
in as new plugin files, no `server.py` edits).
|
||
- Atelier is vendored (pinned tag) for audit reproducibility — an agentic
|
||
validation result must be replayable against the exact principles that
|
||
produced it.
|
||
- PPTX is a first-class artifact: committed (history) + attached (download)
|
||
— both always, not optional.
|
||
|
||
## Requirements
|
||
|
||
### v1.0 (Prior milestone — the demo)
|
||
|
||
Status: complete. Tag `v1.1.0`. All REQ-01..15 satisfied by the stub-driven
|
||
executive demo. See `REQUIREMENTS.md` §v1 and the prior decisions table
|
||
appendix below. The demo is **archived** to `demo/` in Phase 06.
|
||
|
||
### v1.1 (Prior milestone — architecture finalization + v1 spike, complete)
|
||
|
||
New requirements REQ-16..REQ-28 — see `REQUIREMENTS.md` §v1.1. Summary:
|
||
|
||
- **REQ-16:** Architecture finalized to v1.0 (11 open decisions resolved).
|
||
- **REQ-17:** Target Stack IR defined as JSON Schema; engine-agnostic.
|
||
- **REQ-18:** PolicyCheckResult normalized schema defined; Checkov adapter.
|
||
- **REQ-19:** Six-input confidence signal specified with per-env thresholds
|
||
(dev 0.50 / qa 0.75 / prod 0.90 / dr 0.95) and severity→penalty mapping.
|
||
- **REQ-20:** Tiered audit ledger design (S3 Object Lock 7-yr + DynamoDB
|
||
outbox, RPO=0, JWS detached signatures, `prev_event_hash` chain).
|
||
- **REQ-21:** Full 8-concern HITL matrix + separation-of-duties design
|
||
(CODEOWNERS + DynamoDB identity-distinctness).
|
||
- **REQ-22:** Contract schema (JSON Schema draft 2020-12) with per-env
|
||
mandatory/optional inputs and `profile: agentic` marker for L3B.
|
||
- **REQ-23:** AWS OIDC bootstrap (IAM role + trust policy for act_runner);
|
||
the long-lived key is used once then rotated (waiver D-034).
|
||
- **REQ-24:** One real L1 module (`l1-s3`) with an IR-typed interface.
|
||
- **REQ-25:** One real L2 thin-composition (`l2-static-assets`) referencing
|
||
`l1-s3`.
|
||
- **REQ-26:** Terraform adapter compiles the IR to a real `terraform plan`
|
||
against AWS via OIDC; state in S3 + DynamoDB.
|
||
- **REQ-27:** One end-to-end contract submission → contract→IR resolution →
|
||
`terraform plan` → Checkov → confidence signal → evidence event to outbox.
|
||
- **REQ-28:** Spike verification proves the IR-shaped commitments hold (no
|
||
polyglot mess; the adapter is the only engine-specific code).
|
||
|
||
### v1.2 (Prior milestone — platform hardening + first real consumer deployment, complete)
|
||
|
||
New requirements REQ-29..REQ-35 — see `REQUIREMENTS.md` §v1.2. Summary:
|
||
|
||
- **REQ-29:** README.md fully documents the v1.1-complete platform: spike
|
||
flow, how to run, repo layout, v1.2 objective.
|
||
- **REQ-30:** NFR hardening — least-privilege IAM audit, idempotent
|
||
bootstrap, consolidated `run_platform.sh`, error handling, P1-1/P1-B
|
||
redaction.
|
||
- **REQ-31:** L1 catalog expanded for ECS — 6 new IR-typed L1s
|
||
(`l1-vpc`, `l1-ecs-cluster`, `l1-ecs-service`, `l1-iam-role`, `l1-alb`,
|
||
`l1-ecr`) registered and adapter-compiled.
|
||
- **REQ-32:** `l2-microservice` thin-composition + contract schema extended
|
||
for microservice inputs (image, port, env, healthcheck).
|
||
- **REQ-33:** `terraform apply` (dev, autonomous) — real provisioning, not
|
||
just `plan`.
|
||
- **REQ-34:** Consumer repo `acdl-consumer-microservice` with a basic
|
||
microservice (ECR image, Dockerfile, contract).
|
||
- **REQ-35:** End-to-end verification — consumer commit → live ECS service
|
||
(HTTP 200) → evidence event → timeline.
|
||
|
||
### v1.4 (Prior milestone — central pipeline contract + shell reproducibility + streaming)
|
||
|
||
New requirements REQ-43..REQ-45 — see `REQUIREMENTS.md` §v1.4. Summary:
|
||
|
||
- **REQ-43:** Central pipeline contract — `schemas/pipeline.schema.json` +
|
||
`pipelines/ci.yaml`. Both Gitea and GitHub workflows implement the
|
||
contract; a test validates conformance.
|
||
- **REQ-44:** `scripts/run_ci.sh` mirrors the CI pipeline locally (lint →
|
||
test → check-only), exiting 0 with "CI PIPELINE OK".
|
||
- **REQ-45:** `scripts/run_platform.sh` streams terraform/checkov output by
|
||
default (with `--quiet` for log-only mode). Both workflows byte-identical.
|
||
|
||
## Key Decisions (v1.9)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.9 decisions (numbered
|
||
D-080+ to avoid collision with v1.8 research decisions D-073..D-077):
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-080 | New milestone v1.9 (feature); ship tag `v1.9.0`. | v1.8 is complete (audit PASS, tag v1.8.0). The work (design doc updates + interpolation + per-env CI + stubs + P1-1) is a new feature milestone, not v1.8 post-hoc patching. | 5 phases (39–43) in one milestone. |
|
||
| D-081 | Interpolation syntax: `${env.<field>}` + `${contract.<field>}` (dotted paths supported, e.g. `${env.state_backend.bucket}`). Expanded by the resolver post-schema-validation, pre-IR-resolution. Fail loud on unresolved tokens (`ValueError`). | Shell-style syntax is familiar, unambiguous, and has no conflict with YAML or the contract schema. The `env` context is the loaded environment onboarding JSON; `contract` is the contract dict. | Phase 40 implements the expansion + environment JSON schema. |
|
||
| D-082 | Hybrid per-environment promotion model: (a) per-env contract files AND (b) an `environment` `workflow_call` input on the reusable deploy workflow that overrides the contract's environment at load time. One CI job per environment. | User chose to support both shapes. Per-env contracts let env-specific values differ via interpolation; the env input lets a single contract be promoted without editing. Promotion = running the matching job; no `environment:` field editing. | Phase 41 ships per-env contracts + the env input + caller-workflow docs. |
|
||
| D-083 | Audit ledger S3 Object Lock + JWS detached signatures + async worker + DLQ + daily checkpoints **deferred** to a future milestone. | Requires non-offline-testable AWS infra (Object Lock bucket, KMS signing key, SQS DLQ, Lambda worker). The hash-chain + DynamoDB-outbox path remains the v1.9 production audit record. `audit_ledger_design.md` marks this clearly. | Phase 39 updates the design doc; no build-out in v1.9. |
|
||
| D-084 | 8-concern attestation matrix: offline-testable concerns (contract NFRs, schema validity, policy pass) run for real; operator-supplied concerns (k6 load test, DR drill, FinOps forecast) accept signed evidence artifacts validated for freshness + schema, failing loud if missing/expired for prod/dr. | The platform cannot run live load tests / DR drills / FinOps forecasts inline. Accepting signed evidence artifacts with freshness + schema validation is the regulatorily-defensible middle ground. | Phase 42 implements `core/attestation_matrix.py`. |
|
||
| D-085 | P1-1 closure: adapter ECS/ALB/VPC hardcoded defaults (`desired_count = 1`, `launch_type = "FARGATE"`, `target_type = "ip"`, `load_balancer_type = "application"`, `family = "app"`, `Name = ...`) move into L1 `interface.json` inputs with defaults. The adapter reads inputs (falling back to interface defaults) and is a thin translator. | P1-1 was flagged in the v1.2 review (deferred to v1.3, never implemented). Defaults belong in the L1 interface, not the adapter. | Phase 39 closes P1-1. |
|
||
| D-086 | `.ciagent/REVIEW.md` reconstructed at v1.9 complete; v1.3–v1.8 reviews noted as not-persisted (no git-history rewrite). | REVIEW.md still holds v1.2 content — later milestone reviews were not persisted or were overwritten. The v1.9 review overwrites it with current content; a note records the historical gap. | Phase 43 reconstructs REVIEW.md. |
|
||
| D-090 | No cap on the v1.1→v1.8 capability re-verification sweep. Fix every advertised capability in-sweep; all must end Verified. | The user rejected a phase cap. Unbounded-risk trade-off accepted for full integrity: decks stay frozen until every advertised capability is Verified. Recorded as a traceable decision, not silent scope creep. | Phase 54 executes the sweep under D-090. |
|
||
| D-091 | Add a regression-class VERIFY that re-runs capability checks (not just diff checks), at minimum on milestone completion. | VERIFY is currently diff-scoped (structural defect); 8 NFR-patch phases passed while the platform decayed. Without regression memory the pipeline cannot keep the sweep honest. | Phase 52 implements the regression-class VERIFY. |
|
||
| D-092 | Build local emulating adapters (flat-file outbox, local ECS emulator, local S3 state, local Lambda stub) so the platform is fully locally testable without cloud credentials. | Required for the sweep's local tier and for durable regression testing without AWS access. Cloud interactions are emulated with flat files in temp folders + local shell. | Phase 53 builds the local emulating adapters. |
|
||
| D-093 | Re-verify every v1.1→v1.8 advertised capability. v1.0 demo excluded as archived/superseded. Headline E2E runs both live-AWS and local-emulator tiers (both must pass); all other capabilities run locally via emulating adapters. | Tiered verification: live for cloud-backed headline, local for the rest. The bar is what an exec could see demonstrated. | Phase 54 executes the re-verification sweep. |
|
||
| D-094 | Rewrite PROJECT/ROADMAP/decks to match verified reality; decks unfrozen only after this lands. | Decks were sequenced backwards for 8 phases (polish before re-verify). The honest order is re-verify → rewrite → unfreeze. | Phase 55 rewrites docs/decks to verified reality. |
|
||
|
||
### CLARIFY auto-resolved parameters (full autonomy)
|
||
|
||
| Parameter | Value | Rationale |
|
||
|---|---|---|
|
||
| Per-env `qa.json/prod.json/dr.json` account_id | `000000000000` placeholder + stderr warning at load if account_id is `000000000000` and env ≠ dev | Consistent with `dev.json`; prompts real binding without breaking offline tests. |
|
||
| SNS topic for `route_halt_artifact` | Defined in `terraform/platform/main.tf` AND code reads `ACDL_SOD_HALT_TOPIC_ARN` | Consistent with the existing Lambda/KMS/Secrets pattern (Terraform defines, code reads env). |
|
||
|
||
## Constraints
|
||
|
||
- **Forge:** Gitea at `https://git.cloudinit.dev`, org `continuous-intelligence`.
|
||
- **CI runtime:** act_runner / Gitea Actions (reuses GitHub Actions workflow YAML).
|
||
- **Cloud:** AWS via OIDC federation. **Long-lived credentials are forbidden**
|
||
(§12.5). The v1.1 spike uses a temporary long-lived key **once** to bootstrap
|
||
OIDC (waiver D-034), then rotates it.
|
||
- **Angine:** Terraform adapter in v1 (the only adapter). L1/L2 are
|
||
engine-agnostic in shape; the adapter is the only engine-specific code.
|
||
- **State:** S3 (state files) + DynamoDB (locking), single-region in v1.
|
||
- **Environments:** dev (autonomous) → qa (QA HITL) → prod (SRE HITL) → dr
|
||
(SRE HITL). **Staging does not exist** (Path A locked).
|
||
- **Compute:** abstract / containerized / serverless. No VMs, bare metal, OS
|
||
lifecycle.
|
||
- **Autonomy:** Full. Escalation hooks: deploy, delete_data, merge_to_main.
|
||
|
||
## Anti-Goals (from `docs/vision.md` §7)
|
||
|
||
- Not an upstream development platform (no product backlogs, IDE, code authorship).
|
||
- Not a general-purpose AI (autonomy is narrow, bounded by policy envelopes).
|
||
- Not a legacy infrastructure bridge (no VMs/bare metal/OS).
|
||
- Not a permissive delivery highway (no escape hatches past confidence or HITL).
|
||
- Not a mutable audit log (VCS history ≠ regulatory evidence).
|
||
|
||
## Context
|
||
|
||
- The `acdl` repo exists at the org root. `acdl-contracts` and
|
||
`acdl-evidence` exist from the v1.0 demo and continue as the developer
|
||
surface and the audit-timeline host respectively.
|
||
- `docs/vision.md` and `docs/architecture.md` (v0.2) are the upstream
|
||
vision/architecture sources, pulled from `origin/main` at the start of v1.1.
|
||
- The v1.0 demo (tag `v1.1.0`) is the reference of intent — it proved the
|
||
shape (L1/L2/contract/confidence/evidence/HITL) on stubs. v1.1 replaces the
|
||
stubs with the real platform engine.
|
||
|
||
## Key Decisions (v1.1)
|
||
|
||
Carries forward the still-valid v1.0 decisions (see appendix). New v1.1
|
||
decisions:
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-034 | Temporary long-lived AWS key (waiver) used once in Phase 08 to bootstrap the state backend + IAM user; rotated/deactivated immediately after | §12.5 forbids long-lived creds; the bootstrap needed one `aws iam` call before the spike user + rotated key could take over | Spike achieves real `terraform plan` against AWS without violating the locked target after bootstrap. **CLOSED 2026-07-21: root key `AKIA…ROOT-DEACTIVATED` deactivated by the user in the AWS IAM console (verified — `InvalidClientTokenId`); the spike uses the rotated `acdl-spike-runner` key per D-039. Key ID redacted in v1.2 Phase 12 (P1-1).** |
|
||
| D-035 | Milestone version = `v1.1` (feature), ship tag `v1.2.0` | Real platform is a breaking reframing of the demo, but treated as the next incremental milestone per user choice; ship.md: feature milestone → next minor | Tag `v1.2.0` on milestone COMPLETE |
|
||
| D-036 | Spike picks `l1-s3` + `l2-static-assets` | Simplest real AWS resource (no IAM/network deps); smallest real `terraform plan`; proves the IR + adapter end-to-end | Spike scope fixed |
|
||
| D-037 | Demo archived to `demo/` (not deleted) | Preserves the working v1.0 demo as intent reference; new platform layout under `platform/`, `schemas/`, `adapters/`, `terraform/`, `modules-ir/` | No churn on demo code; clean separation |
|
||
| D-038 | Open decisions resolved in "accept recommendations + decide rest" mode | User-locked mode: accept architecture's stated recommendations (W1.A, W1.B, W2.A, BA.A); lead-developer decides the remaining 8 (W3.D, W3.E, BA.B, BA.C, BA.D, BA.E, BA.F, OpenTofu timing) with rationale | Architecture reaches v1.0 in Phase 07 |
|
||
| D-039 | Spike-only waiver: per-run-rotated long-lived AWS key. OIDC federation deferred to v1.2, blocked on go-gitea/gitea#36988. | **RESEARCH TARGET 1 verdict (conf 0.95):** Gitea Actions does NOT support `id-token: write` / OIDC token issuance as of Gitea 1.27.x / gitea-runner v2.1.0. GitHub's OIDC pattern is not portable. The waiver satisfies §12.5's *intent* (no persistent long-lived key) for the spike: the key is rotated after each run by `scripts/rotate_spike_key.sh`. v1.2 implements real OIDC when the Gitea PR merges. | Spike achieves real `terraform plan` against AWS without a *persistently* long-lived key; real OIDC is a v1.2 deliverable |
|
||
| D-040 | The 6 confidence-signal inputs are: policy (0.30), validation (0.25), freshness (0.10), source (0.15), history (0.10), nfrs (0.10). Weights frozen for v1, tuned in v1.2 alongside thresholds (BA.B). | Architecture §8 locks "six canonical inputs" but does not enumerate them; RESEARCH TARGET 6 chose the platform-computable subset present in every environment (incl. dev). | Confidence signal (Phase 10) has a concrete input enumeration |
|
||
| D-041 | Spike audit ledger = v1.0 hash chain + DynamoDB outbox + `acdl-evidence` mirror. S3 Object Lock (compliance mode, 7-yr) + JWS (platform KMS key, quarterly rotation) + daily checkpoints are v1.2 build-out, authored as design in Phase 07. | REQ-20 is "design authored," not "implemented." The spike proves the outbox write path; the regulatory ledger is v1.2. | Spike scope stays bounded; REQ-20 satisfied by the Phase 07 design doc |
|
||
| D-042 | HITL approver identity in Gitea = `gitea.actor` of the `workflow_dispatch` run that sets `approve_qa=true`/`approve_prod=true`/`approve_dr=true`. Separation-of-duties reads `approver_qa` from the DynamoDB outbox and compares to the prod-dispatch `gitea.actor`. | Gitea has no Environments API (re-confirmed in RESEARCH); `gitea.actor` is the only approval-identity signal. | SoD design (Phase 07) is concrete for the Gitea forge |
|
||
| D-043 | Tag/naming compliance deferred for the spike: the Checkov adapter emits a single `SKIPPED` PolicyCheckResult (`ruleId: ACDL_TAG_NAMING`, `severity: info`) so the confidence policy input is non-empty. Custom Checkov YAML rule lands in v1.2. | Checkov has no built-in tag-presence check; a custom rule in the spike is scope creep. | Spike's policy input is non-empty without a custom-rule dependency |
|
||
| D-044 | DynamoDB outbox = `PAY_PER_REQUEST`; PK `contractId`, SK `eventType#eventTs`, TTL `expire_at` = now + 365d. No separate async worker/DLQ in the spike (RTO = workflow re-run); v1.2 outbox worker + DLQ is a Phase 07 design artifact. | On-demand is zero-cost-at-idle for the spike's single dev submission. | Spike outbox is minimal; v1.2 worker design authored in Phase 07 |
|
||
| D-045 | Runner tooling: `runs-on: ubuntu-latest`; install `terraform` via HashiCorp apt repo (pin `1.9.*`), `checkov` via pip (pin `>=3.2,<4`, `--break-system-packages`). Neither is pre-installed on the default runner image. | RESEARCH TARGET 2; pinning avoids mid-spike version drift. | Phase 09/10 workflows have a concrete setup step |
|
||
| D-046 | `act_runner` → `gitea-runner` rename: Phase 07 updates docs to use the current name `gitea-runner` (renamed 2026-04 in gitea/runner#850). | RESEARCH TARGET 1 + R-4: naming drift between v1.0 docs and the current runner. | Docs reflect the current binary name |
|
||
| D-047 | v1.2 carries forward the D-039 per-run-rotated-key waiver. Real OIDC federation remains deferred to v1.3+, blocked on go-gitea/gitea#36988 (re-checked 2026-07-21: still **open**, last updated 2026-05-27, not merged). | §12.5 forbids long-lived creds; the Gitea Actions OIDC provider is still not merged. The waiver continues to satisfy §12.5's *intent* (no *persistently* long-lived key) for v1.2: `scripts/rotate_spike_key.sh` rotates the key, and Phase 12 tightens the IAM scoping + rotation hygiene. | v1.2 achieves `terraform apply` against AWS without a persistently long-lived key; real OIDC is a v1.3+ deliverable. |
|
||
|
||
## Key Decisions (v1.8)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.8 decisions:
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-061 | Fold all 3 new requirements into v1.8 alongside P1 fixes. | User chose single milestone. v1.8 becomes a feature milestone (ship tag v1.8.0, minor bump). | 11 phases (28–38) in one milestone. |
|
||
| D-062 | P1-3: SSM publisher fails loud (`RuntimeError`) when `ACDL_KMS_KEY_ID` unset. `ACDL_ALLOW_DEFAULT_KMS=1` escape hatch for local testing. | User chose fail loud. Silent AWS-managed-key use is the security gap; callers must set the env. | Phase 29 implements fail-loud + escape hatch. |
|
||
| D-063 | P1-6: `consumer_invoke_policy.json` rendered via Terraform `data.aws_caller_identity` + `templatestring` at apply time. | User chose Terraform-rendered. No committed account ID; no stale placeholder. | Phase 29 converts JSON to TF-rendered template. |
|
||
| D-064 | P1-8: Remove committed `terraform/spike/*.tf` entirely; adapter emits to per-run temp dir. | User chose remove. Cleaner; no stale fixtures. | Phase 30 removes files + changes run_platform.sh target. |
|
||
| D-065 | S1: Single conditional `configure-aws-credentials` step (OIDC when no static key, access-key/secret-key inputs when static key present). | User chose single conditional step. Cleaner workflow YAML. | Phase 30 restructures the deploy workflow step. |
|
||
| D-066 | Uptime deployment target: ECS Fargate (reuse existing ecs-cluster + ecs-service + alb primitives). | User chose ECS Fargate. Most consistent with current platform; ALB gives a stable URL. | Phase 33 authors uptime primitive on ECS Fargate. |
|
||
| D-067 | Uptime trigger: new `deploy-uptime` pipeline stage after `publish-outputs`. Separate terraform state (S3 key prefix `uptime/`). | User chose pipeline stage. Most integrated with existing flow. | Phase 33 adds the pipeline stage + separate state. |
|
||
| D-068 | CMDB = DynamoDB `acdl-change-requests` table (PK changeRequestId, SK submittedAt). | User chose DynamoDB. Consistent with existing platform Lambda + DynamoDB pattern. | Phase 34 adds the table + `validate_change_request` Lambda action. |
|
||
| D-069 | Encryption key granularity: per-stack CMK (one key per L2 deployment, tagged with acdl:owner + acdl:environment). | User chose per-stack. No shared keys across stacks; 90-day rotation at creation. | Phase 31 authors kms-key primitive + L2 wiring. |
|
||
| D-070 | Decommission: new mode on the existing deploy pipeline (`mode: decommission`). 2-step with HITL SRE gates. | User chose existing pipeline with different behavior. Plan/apply to disable deletion protection (HITL SRE gate) → plan/apply with counts=0 (second HITL SRE gate). Documented in consumer guide. | Phase 34 adds decommission mode + HITL gates. |
|
||
| D-071 | `uses:`/`ref:` bump from `@v1.6` to `@v1.8` at milestone COMPLETE. | Consumer-facing version tracks the last released MAJOR.MINOR. | Phase 38 bumps references + creates floating `v1.8` + `v1` tags. |
|
||
| D-072 | Managed KMS fallback for standalone L1 deployments (no L2 CMK): adapter uses `alias/aws/<service>` with a stderr warning. `kms_key_arn` input is optional everywhere; `encryption_enabled` NFR defaults to true. | Requirement says "prioritize CMKs, fallback to managed KMS". Standalone L1s don't have a per-stack CMK. | Phase 31 implements fallback + warning. |
|
||
|
||
## Key Decisions (v1.7)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked constraints
|
||
or user-directed scope). New v1.7 decisions:
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-048 | Rename `static-assets` → `static-assets`: **rewrite all occurrences** including verbatim historical phase descriptions in `.ciagent/` (ROADMAP, REQUIREMENTS, RESEARCH, decision tables), overriding the v1.6 audit precedent that preserved some historical references. | User chose full rewrite. Maximally consistent; the reconstruction test is updated to expect `static-assets` throughout. | Phase 22 rewrites every `static-assets` string to `static-assets`; no preserved historical tokens remain. |
|
||
| D-049 | Production static-assets stack = S3 + CloudFront (OAC) + WAF. | Self-contained, domain-free production edge. Route53/ACM are domain-dependent (consumer-supplied) and deferred to documented extension points / a complex example. | Phase 22 authors `cloudfront` + `waf` primitives and augments the module. |
|
||
| D-050 | Deploy outputs: SSM Parameter Store (`SecureString`, KMS-encrypted, namespaced `/acdl/{env}/{contractId}/{output_name}`) for runtime-injectable values + GitHub PR comment / job summary for human-readable connection strings. | Two canonical mechanisms: SSM for resources that read at runtime; PR comment for developers. No raw secrets in logs. | Phase 25 implements `core/output_publisher.py` + two new pipeline stages. |
|
||
| D-051 | Contract ingestion storage = DynamoDB table `acdl-contracts` (PK `consumerRepo`, SK `contractId#submittedAt`, SSE via customer-managed CMK, point-in-time recovery). | Enables historical queries, impact analysis, CMDB-style application-state queries, and pattern detection via DynamoDB queries. S3 flat-file mirror deferred (DynamoDB is sufficient for v1.7). | Phase 24 defines the table + Lambda. |
|
||
| D-052 | Wiz adapter = stub + schema path (no live Wiz tenant in CI). | Matches the Checkov adapter pattern; typed interface, offline-testable, degrades gracefully when unconfigured (emits `WIZ_NOT_CONFIGURED` SKIPPED record). | Phase 23 authors `adapters/wiz/wiz_adapter.py`. |
|
||
| D-053 | Kyverno adapter = K8s-native policy adapter translating `PolicyReport` results → `PolicyCheckResult`. Ready but inactive for Terraform-only stacks. | The platform emits Terraform, not K8s manifests. The adapter activates when the GitOps reconciler (roadmap) emits K8s manifests. Sample policies included as documentation. | Phase 23 authors `adapters/kyverno/kyverno_adapter.py` + sample policies. |
|
||
| D-054 | Tagging standard = required-tag set (`acdl:owner`, `acdl:contract`, `acdl:environment`, `acdl:cost-center`) enforced by a Checkov custom YAML rule. | Closes the D-043 deferral (the SKIPPED `ACDL_TAG_NAMING` placeholder becomes a real check). Naming-convention regex deferred (brittle across AWS resource types). | Phase 23 authors `schemas/tagging-standard.json` + `adapters/terraform/policy/custom_rules/acdl_tagging.yaml`. |
|
||
| D-055 | Error reporting = the platform Lambda `report_error` action creates a GitHub issue on the platform repo (`acdl/acdl`). Uniform communication pathway via the Lambda; the consumer's onboarding-granted Lambda-invoke permission is the only grant needed. No separate GitHub `issues: write` on the consumer side. Gitea is excluded (only the CIAgent uses it; platform engineers and consumers use GitHub). | Unifies requirements 4 + 8 around one mechanism. The Lambda holds a GitHub token (Secrets Manager) scoped to the platform repo. Idempotent (comments on existing open issue rather than duplicating). | Phase 24 prepares the action; Phase 25 implements it + wires the `if: failure()` workflow step. |
|
||
| D-056 | Ship `v1.7.0`; bump `uses:`/`ref:` from `@v1.4` to `@v1.6`. | Consumer-facing version tracks the last released MAJOR.MINOR. Consumers on `@v1.4` stay on v1.4 behavior until they bump. | Phase 22 bumps the references. |
|
||
| D-057 | The `uses:`/`ref:` bump + floating `v1.6`/`v1` tag creation happen in Phase 22 (pointing at `v1.6.0`), so the reference never points at a non-existent tag. The release job (Phase 26) owns ongoing tag updates. | Sequencing: if Phase 22 bumps `uses:` to `@v1.6` but the tag doesn't exist, the reference is temporarily broken. Creating the tag early (pointing at the last release) fixes this. | Phase 22 creates the floating tags; Phase 26's release job maintains them. |
|
||
| D-058 | Module examples = separate validated files in `modules/<name>/examples/` (`simple.yaml` + `complex.yaml` + variation files), validated against `schemas/contract.schema.json` in the platform-test pipeline schema-validation stage. Each module's README `## Examples` section references + excerpts them. | Examples cannot drift from the schema silently. | Phase 27 authors the example files; Phase 26's platform-test pipeline validates them. |
|
||
| D-059 | Add an RDS primitive (`modules/l1/rds/`) with an `engine` input (enum: postgres, mysql, etc.) + a multi-engine example demonstrating the variation pattern. | Concrete demonstration of the multi-engine variation the requirement calls out. Adds one primitive + examples. | Phase 27 authors the primitive + adapter expansion + examples. |
|
||
| D-060 | (Consolidated into D-058.) | — | — |
|
||
|
||
### Open-decision resolutions (Phase 07 deliverable — recorded here for traceability)
|
||
|
||
| ID | Question | Resolution |
|
||
|---|---|---|
|
||
| W1.A | AI-refinement trigger | **Accept recommendation.** Joint condition: N ≥ 50 consecutive changes with zero rollbacks AND no L1/L2 incident in last 6 months AND Infra & Ops unilateral override. |
|
||
| W1.B | Multi-stack edge case rule | **Accept recommendation.** Permitted only for (a) DR-region mirror, (b) time-boxed experimental stack with TTL ≤ 30d, (c) explicit Infra & Ops approval with `multiStack.justification`. |
|
||
| W2.A | Tag mutability for prod | **Accept recommendation (Path B).** Tag for dev/qa, SHA for prod. Platform CLI resolves tag→SHA for prod-bound workflows. Justified by the "Audit truth lives outside the repository" bet. |
|
||
| BA.A | Initial L3B skill catalog | **Accept recommendation.** 5 skills: web API, worker, scheduled job, static asset, basic observability bootstrap. Addition criteria: (a) reviewable for sensitive data, (b) expressible as a single contract submission, (c) documented use case. **Extended v1.18 (REQ-221/222):** the BA.A 5-skill catalog is extended with 9 Atelier-derived production-grade engineering skills under `skills/` (api, security, data, testing, observability, errors, devops, infrastructure-as-code, compliance), indexed by `docs/skills.md`. The Atelier skills extend, not replace, the BA.A catalog. |
|
||
| W3.D | L1/L2 standard versioning | **Decided.** Semver: interface → MAJOR, behavior → MINOR, lifecycle → PATCH (same as the v1.0 demo D-rule, lifted to the real platform). Pin model: L2 contracts pin L1 by `name@semver`; the resolver picks the highest compatible. Evolution: MAJOR bumps require a new registry entry (immutable publication); old entry enters a 12-month deprecation window. |
|
||
| W3.E | Schema mandatory vs optional inputs | **Decided.** Per-env mandatory table: dev requires `stack` + `environment`; qa adds `validation.e2eSuite` + `validation.loadTest`; prod adds `runbook` + `dashboard` + `oncall`; dr adds `drDrillRef`. `inputs` map is always optional. `profile: agentic` fields (`naturalLanguageIntent`, `confidenceAtSubmission`, `agentTrace`) optional everywhere. |
|
||
| BA.B | Confidence threshold tuning | **Decided.** Starting thresholds frozen for v1. Tuning begins in v1.2: track FP/FN per environment quarterly; override authority = Infra & Ops + SRE joint sign-off; any override is itself a confidence-event in the audit stream. |
|
||
| BA.C | On-call / operational ownership | **Decided.** Platform on-call = Infra & Ops rotation. Escalation: L3A/L3B halt → platform on-call pager (Sev2); consumer-visible outage → consumer on-call (Sev1) with platform on-call support. Consumer on-call relationship is contractual, defined at onboarding (BA.E). |
|
||
| BA.D | Cost / capacity governance | **Decided.** Cloud cost owner = Infra & Ops FinOps. Per-contract consumption reported monthly. Runaway spend: hard halt at 120% of contract-declared budget envelope via the confidence signal (cost is one of the 6 inputs); override = FinOps + SRE joint sign-off. |
|
||
| BA.E | Consumer onboarding | **Decided.** Two paths: developer (L3A) — `getting-started` walks through contract schema + central pipeline template; citizen developer (L3B) — onboarding grants a scoped agent + skill catalog, no workflow authoring. Both end in a sandbox dev submission that must pass the confidence gate before the consumer is promoted. |
|
||
| BA.F | Cross-platform evolution | **Decided.** The contract schema, IR, PolicyCheckResult, confidence signal, and audit stream are portable (engine- and forge-agnostic). Forge-specific code: workflow YAML, OIDC trust, CODEOWNERS, Environments. A second forge (e.g., GitLab) requires a forge adapter + a workflow-template translator; no change to L1/L2/IR/confidence/audit. |
|
||
| Q1.3 | OpenTofu timing | **Decided (deferred).** Not in v1 or v1.1. The engine abstraction (§12) makes OpenTofu a future adapter, not an architecture change. Revisit when an OpenTofu adapter is requested; no version committed. |
|
||
|
||
## Appendix — Prior milestone (v1.0 demo) decisions
|
||
|
||
The v1.0 demo (tag `v1.1.0`) carried decisions D-001..D-033. They governed
|
||
the stub-driven executive demo and remain valid **for the archived demo
|
||
under `demo/`**. They are **superseded** by the v1.1 decisions above for the
|
||
real platform. Full text preserved in git history at tag `v1.1.0`.
|
||
|
||
## Operational parameters (CLARIFY auto-resolution, full autonomy)
|
||
|
||
Resolved at the CLARIFY stage to unblock planning. None require user
|
||
sign-off (autonomy = full; all within locked constraints).
|
||
|
||
| Parameter | Value | Rationale |
|
||
|---|---|---|
|
||
| AWS region | `us-east-1` | Default; matches v1.0 demo references; single-region in v1 (§12.3) |
|
||
| Terraform state bucket | `acdl-tfstate-<account-id>-us-east-1` | Namespaced by account id to avoid collision; region-suffixed |
|
||
| Terraform lock table | `acdl-tflock` | DynamoDB; single-region v1 |
|
||
| OIDC IAM role | `acdl-act-runner-role` | Assumed by the act_runner via web-identity |
|
||
| OIDC trust subject | `repo:continuous-intelligence/acdl:ref:refs/heads/main` (+ phase branches) | Least-privilege; refined in Phase 08 |
|
||
| Spike L1 (`l1-s3`) inputs | `bucket_name: string`, `region: string` | Minimal S3 interface per §2 |
|
||
| Spike L2 (`l2-static-assets`) | thin-composition referencing `l1-s3` only; depth 1 | Smallest real plan per D-036 |
|
||
| Spike contract | `contracts/spike.yaml`: `stack: l2-static-assets`, `environment: dev`, `inputs: { bucket_name: acdl-spike-bucket, region: us-east-1 }` | One end-to-end submission (REQ-27) |
|
||
| Spike `terraform` command | `plan` only | `apply` is out of scope (Out of Scope table); HITL-gated in v1.2 |
|
||
| Checkov ruleset (spike) | the 4 L2 checks (secrets-in-plaintext, public ingress, IAM wildcard, KMS key reference) + tag/naming | §3 + §12.4; Kyverno/OPA deferred |
|
||
| v1.0 tags preserved | `v1.0.1`..`v1.0.5`, `v1.1.0` retained | Immutability; demo archive does not rewrite history |
|
||
| Next ship tag | `v1.3.0` | Feature milestone → next minor per ship.md (v1.1 shipped `v1.2.0`; v1.2 ships `v1.3.0`) |
|
||
|
||
### Items deferred to RESEARCH (not clarifications)
|
||
|
||
- **Gitea/act_runner OIDC support** — does act_runner emit an OIDC
|
||
`id-token`? Determines whether real-AWS plan is achievable in this
|
||
environment or whether a spike-only waiver is needed. Highest-priority
|
||
research target.
|
||
- **Terraform + Checkov availability on the runner image** — install in the
|
||
workflow if missing.
|
||
- **`actions/configure-aws-credentials` action on act_runner** — if
|
||
unavailable, fall back to `aws sts assume-role-with-web-identity` from a
|
||
step.
|
||
|
||
## Objective for Milestone v1.14 (active — NFR Refinement)
|
||
|
||
Bug fixes, security posture improvements, stub/missing-functionality
|
||
identification + implementation, and documentation + NFR refinement across
|
||
the entire codebase. **No new features.** This is an NFR milestone — the
|
||
final phase's patch IS the deliverable (no separate milestone tag).
|
||
|
||
The v1.13 line shipped the presentation polish + config.json schema
|
||
migration + badge cleanup. The v1.11/v1.12 multi-persona reviews left a
|
||
backlog of P1/P2 findings (5 P1 + 4 P2 open in `REVIEW.md`), the codebase
|
||
has 6+ swallowed-error sites and 15+ hardcoded account-ID references, 7
|
||
scripts have no test coverage, the regression gate's CAP-017..022 evidence
|
||
is an offline proxy, ARCHITECTURE.md has no v1.11–v1.13 addendum, and
|
||
consumer-facing docs reference stale `@v1.6`–`@v1.9` workflow tags. v1.14
|
||
clears all of it in a 20-phase sweep.
|
||
|
||
**Scope axes (user-directed, 2026-07-29):**
|
||
1. **Bug fixes** — clear all open P1/P2 findings from the v1.11 review
|
||
(adapter dedup silent drop, static-assets unwired inputs, lifecycle
|
||
script vestigial args, regression-gate offline-proxy evidence, ALB
|
||
name_prefix, missing unit tests).
|
||
2. **Security posture** — narrow 6 swallowed-`except` sites; externalize
|
||
the hardcoded account ID; scope 6 `Resource: "*"` IAM statements to
|
||
`acdl-*` ARNs; harden contract-ingestor identity validation; add
|
||
`additionalProperties: false` + format validation to schemas; add
|
||
credential-pattern catch-all to `.gitignore`.
|
||
3. **Stub / missing functionality** — resolve the discarded
|
||
`--kube-version` flag in the Kyverno adapter; clean up orphan bytecode
|
||
+ dead config.
|
||
4. **Documentation + NFR refinement** — ARCHITECTURE.md v1.11–v1.14
|
||
addenda; bump stale `@v1.6–1.9` → `@v1.13` across 12+ sites; sync
|
||
decks/COST.md/GRILL G-005+G-008/IAM_POLICY.md; reconcile
|
||
modules/STANDARDS.md; record the D-083 audit-ledger deferral
|
||
explicitly.
|
||
5. **Test coverage** — add unit tests for 7 untested scripts + the
|
||
adapter dedup/remote-state-key behaviors.
|
||
|
||
**Out of scope (v1.14):**
|
||
- New features (feat phases). v1.14 is NFR-only.
|
||
- D-083 audit ledger build-out (S3 Object Lock + JWS + SQS DLQ + async
|
||
worker) — remains deferred; documented explicitly in ARCHITECTURE.md.
|
||
- Real OIDC federation (blocked on go-gitea/gitea#36988).
|
||
- Per-phase regression hardening (G-007, unchanged).
|
||
- Boto3 post-deploy verification probes (deferred to a future QA
|
||
milestone).
|
||
|
||
**Milestone type:** NFR (all phases are fix/test/docs/chore/refactor).
|
||
**Ship tag:** final phase patch on the v1.13.x line IS the release.
|
||
|
||
## Milestone v1.14 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 0 | pre-execution | SPECIFY → CLARIFY → RESEARCH → IDEATE → PLAN → GRILL. Establish v1.14 milestone shell; ideate finds the concrete requirements; plan decomposes into 20 execution phases. |
|
||
| 1–20 | execution | 20 phases of bug fixes, security hardening, stub resolution, test coverage, docs sync (wave-ordered). See ROADMAP.md §v1.14 for the phase list. |
|
||
| 21 | final-review-ship | Multi-persona review + audit + milestone ship (merge to main, tag final patch = release). |
|
||
|
||
## Key Decisions (v1.14)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.14 decisions (numbered
|
||
D-095+ to continue from v1.10's D-094):
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-095 | v1.14 is an NFR milestone (no feat phases); final patch IS the release. | User directed: "No new features, only bug fixes, security posture improvements, identifying stub and implement missing/lacking functionality, refine all documentation + NFRs." NFR model per branch-strategy.md:181 — progressive patches, final patch = deliverable, no separate milestone tag. | 20 execution phases (P1–P20) + 1 final (P21). Tags v1.13.3 → v1.13.24. |
|
||
| D-096 | D-083 (audit ledger JWS + S3 Object Lock + SQS DLQ + async worker) remains deferred; documented explicitly in ARCHITECTURE.md (P19), not implemented. | User chose "Skip — keep D-083 deferred." Requires non-offline-testable AWS infra (Object Lock bucket, KMS signing key, SQS). The hash-chain + DynamoDB outbox remains the v1.14 audit record. | P14 (originally JWS) replaced with orphan-artifact-and-dead-config-cleanup. D-083 deferral recorded in P19. |
|
||
| D-097 | 20 execution phases is the target (not consolidated to ~10). | User chose "20 phases as planned." Finer ship granularity; longer milestone. G-007 (per-phase regression) accepted — regression gate runs at milestone COMPLETE. | 20 phases + 1 final = 21-phase milestone. |
|
||
| D-098 | Wave ordering: W1 (P1–P6 bug fixes), W2 (P7–P12 security), W3 (P13–P17 stub/test/CI/hygiene), W4 (P18–P20 standards/docs/VPC). | Prerequisite chains: P2 depends on P1 (composition needs correct dedup); P9 depends on P8 (IAM ARNs reference externalized account ID); P15 depends on P7 (script tests benefit from hardened errors); P17 depends on P14 (both touch config.json); P19 lands last (reflects all prior phases). | 4 sequential waves; phases within a wave are independent (parallelizable when parallelization.enabled=true). |
|
||
| D-099 | `--ideate` flag: run the IDEATE stage between RESEARCH and PLAN (per ideate.md:218). The ideation tiers mine the 50 `partial:` + 16 `lessons:` + 3 `escalation:` + 16 `decisions:` git-native signals to validate/enrich the 20-phase scope. | User invoked with `--ideate`. The v1.14 scope is already user-directed (20 phases defined), so IDEATE acts as validation + enrichment, not scope discovery. Accepted ideas become IDEATE-NN IDs appended to REQUIREMENTS.md. | IDEATE stage runs; interactive validation gate (accept/skip/modify). |
|
||
| D-100 | Accept all 20 ideation findings as the v1.14 requirement set (REQ-135..REQ-154). | User accepted all 20 at the interactive validation gate. Mechanical + backend-enriched tiers confirmed the user-directed scope. | 20 REQs locked; PLAN.md formalizes the task decomposition. |
|
||
| D-101 | E-001 (P8 state-bucket continuity residual risk) auto-resolved at full autonomy: accept the residual risk. G-102's binding mitigation (fallback bound to live account ID + workflow env wiring) is the control. The lifecycle pipeline defaults to plan-only (REQ-134) — full-mode runs are workflow_dispatch only, reducing the accident surface. | Grill escalation E-001 (confidence 0.55) re-exposes the v1.11 4-VPC root cause. At full autonomy, auto-decide with assumption logging. The residual risk (misconfigured env at live-run time) is runtime-dependent, not plan-resolvable. If the user prefers zero residual risk, direct that P8 exclude the state-bucket name from externalization entirely. | E-001 resolved; G-102 binding decision enforced in PLAN.md P8. |
|
||
|
||
---
|
||
|
||
## Milestone v1.15 — Nova (Rebrand)
|
||
|
||
**Active milestone.** A full rebrand from ACDL → Nova across docs,
|
||
decks, code, configs, CI, env var prefixes, the consumer contract path,
|
||
SSM parameter paths, AWS tag keys, and AWS resource names — with a
|
||
staged infrastructure migration to avoid breakage.
|
||
|
||
**Milestone type:** Major (breaking — consumer-facing path, env var
|
||
prefixes, SSM path, AWS tag keys, and AWS resource names all change).
|
||
Tags run on the v1.15.x minor line: `v1.15.0` (P0) → `v1.15.4` (P5
|
||
final = milestone release). (G-104 binding: Major milestones tag on
|
||
their own minor line, not the previous minor's patch line.)
|
||
|
||
**In scope (v1.15):**
|
||
- Prose/decks/mermaid/pyproject/release-title rebrand (P1).
|
||
- Code identifiers, env var prefixes (`ACDL_*`→`NOVA_*` dual-read),
|
||
consumer path (`.acdl/`→`.nova/`) (P2).
|
||
- SSM path (`/acdl/`→`/nova/`) + AWS tag keys (`acdl:*`→`nova:*` ABAC)
|
||
(P3).
|
||
- AWS resource names (`acdl-*`→`nova-*`) with migration (P4).
|
||
- Final review + audit + remove dual-read fallback + milestone ship (P5).
|
||
|
||
**Out of scope (v1.15):**
|
||
- Renaming the real Gitea org/repo or GitHub org `acdl` (config stays
|
||
`acdl`; doc URLs updated to `nova` for prose only).
|
||
- Renaming the S&P Global Energy visual theme (`sp-theme.json`) —
|
||
client branding.
|
||
- Past Gitea release titles — only future releases use `Nova vX.Y.Z`.
|
||
- Git branch/tag naming — no brand name present.
|
||
|
||
**Milestone type:** Major (breaking). **Ship tag:** final phase patch
|
||
on the v1.15.x minor line IS the release (`v1.15.4`).
|
||
|
||
## Milestone v1.15 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 0 | pre-execution | SPECIFY → CLARIFY → RESEARCH → IDEATE → PLAN → GRILL. Establish v1.15-Nova milestone shell; ideation finds the 10 Nova requirements (REQ-155..164); plan decomposes into 4 execution phases. |
|
||
| 1 | docs-decks-prose | Rebrand all prose/decks/mermaid/pyproject/release-titles ACDL→Nova; add Nova tagline; ship consumer migration guide. |
|
||
| 2 | code-envvars-consumer-path | Rename acdl_tagging.py→nova_tagging.py; ACDL_*→NOVA_* dual-read; .acdl/→.nova/ contract path. |
|
||
| 3 | ssm-tagkeys | SSM /acdl/→/nova/ + AWS tag keys acdl:*→nova:* with parallel-tag ABAC migration. |
|
||
| 4 | aws-resource-migration | Rename all acdl-* AWS resources → nova-* with staged migration + runbook. |
|
||
| 5 | final-review-ship | Multi-persona review + audit + remove dual-read fallback + milestone ship (merge to main, tag final patch = release). |
|
||
|
||
## Key Decisions (v1.15)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.15 decisions (numbered
|
||
D-102+ to continue from v1.14's D-101). The high-judgment scope
|
||
decisions (D-102..D-107) were locked in by the user during the planning
|
||
conversation before execution; D-108..D-112 resolved at CLARIFY.
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-102 | AWS resource names: full rename with migration. | User chose "Full rename with migration." All `acdl-*` AWS resources → `nova-*` including state bucket migration, DynamoDB data migration, IAM re-bootstrap, ECR re-push. Accepts downtime + multi-phase migration. | P4 implements the staged migration + rollback runbook. |
|
||
| D-103 | Env var prefixes: full rename to `NOVA_*`. | User chose "Full rename to `NOVA_*`." All 21 `ACDL_*` prefixes → `NOVA_*` including `.env.secrets` (key names only, values stay) + Gitea secrets. | P2 renames + implements dual-read fallback; P5 removes fallback. |
|
||
| D-104 | Tag keys + SSM path + consumer path: full rename all three. | User chose "Full rename all three." AWS tag keys `acdl:*`→`nova:*` (ABAC re-scope), SSM path `/acdl/`→`/nova/` (param migration), consumer path `.acdl/`→`.nova/`. | P2 (consumer path) + P3 (SSM + tag keys) implement. |
|
||
| D-105 | External URLs: illustrative — update them. | User chose "URLs are illustrative — update them." Doc URLs (`github.com/acdl/...`, `git.cloudinit.dev/.../acdl*`) → `nova` for prose consistency. Real Gitea repo name (`release.gitea.repo`) stays `acdl`. | P1 updates doc URLs; config.json unchanged. |
|
||
| D-106 | Nova tagline: add alongside existing North Star. | User chose "Add Nova tagline alongside existing North Star." Tagline "The New Dawn of DevSecOps — security as a seamless enabler of fast deployments" added to README header, deck title slides, `docs/vision.md`. Existing "consumers declare intent" framing retained. | P1 adds tagline; no prose removed. |
|
||
| D-107 | S&P visual theme: leave untouched. | User chose "Leave S&P theme untouched." `sp-theme.json` (#D6002A red, Akkurat Pro) is client branding, not the Nova product brand. Only product-brand text (ACDL→Nova) changes in decks. | P1 edits deck text only; theme/CSS unchanged. |
|
||
| D-108 | Dual-read fallback centralized in a new `core/env.py` helper. | No centralized env loader exists today (env vars read via scattered `os.environ.get("ACDL_*")`). A new `core/env.py` `get_env(name)` helper reads `NOVA_X` then falls back to `ACDL_X`, returning `None` if neither. All call sites migrate to the helper in P2; P5 removes the fallback. | P2 creates `core/env.py` + migrates call sites; P5 removes fallback. |
|
||
| D-109 | Checkov custom rule `nova_tagging.py` warns during P2, hard-fails from P3. | During P2 (before tag-key migration), existing resources still carry `acdl:*` tags — a hard fail would break the regression gate. P2 rule warns on `acdl:*`; P3 (after parallel-tag + ABAC swap) hard-fails on `acdl:*` and enforces `nova:*`. | P2: warn mode; P3: hard mode. |
|
||
| D-110 | Schema `$id` URLs (`https://acdl.cloudinit.dev/schemas/...`) → `https://nova.cloudinit.dev/schemas/...`. | These are illustrative schema identifiers (no real DNS resolution required for JSON-schema validation). Renamed for brand consistency in P1. Existing `$id` values in test fixtures updated. | P1 renames schema `$id` + fixture references. |
|
||
| D-111 | Lambda env-var defaults (`CONTRACTS_TABLE` default `"acdl-contracts"`, etc.) → `nova-contracts`. | `core/lambda/contract_ingestor.py` has hardcoded `acdl-*` default table names. These become `nova-*` in P4 (resource migration). P2 changes the env-var name (`ACDL_*`→`NOVA_*`); P4 changes the default values to `nova-*`. | P4 updates Lambda defaults. |
|
||
| D-112 | `nova` slug: no `project:` prefix on branches (single-project mode). | `config.json` has `projects[]` with one entry (slug `acdl`) but `git.branching_strategy` is `flat` and the established convention since v1.0 is flat branches (no `<slug>/` prefix). Nova rebrand does NOT change the branch prefix convention. Commit `---ci---` blocks use `project: acdl` (the config slug, unchanged). | Branches stay `milestone/v1.15-nova`, `phase/NN-*`; no `acdl/` or `nova/` prefix. |
|
||
|
||
## Objective for Milestone v1.16 (complete — NFR Simplification, tag `v1.15.26`)
|
||
|
||
A 20-phase NFR sweep (no new features) themed around five axes the user
|
||
directed during ideation: **Simplify without regressions**, **Security**,
|
||
**Maintainability**, **User/Developer Experience**, and **No Humans
|
||
Onboarding Flow**. The v1.15 rebrand left a fresh layer of residual debt
|
||
(stale brand strings, a state-bucket drift, a Kyverno policy that
|
||
contradicts the Nova tagging standard, dead code) that this milestone
|
||
clears, alongside genuine simplification (dedup helpers, a workflow
|
||
generator, file splits) and the first self-service onboarding request
|
||
path (request-path only; real AWS account provisioning stays a future
|
||
feature).
|
||
|
||
**Milestone type:** NFR (all phases fix/chore/docs/refactor/test). The
|
||
final phase's patch IS the deliverable — no separate milestone tag. Tags
|
||
run on the v1.15.x line: `v1.15.5` (P0) → `v1.15.6..v1.15.25` (P1–P20) →
|
||
`v1.15.26` (P21 final = milestone release).
|
||
|
||
**Wave ordering:**
|
||
- Wave 1 (P1–P4): correctness + brand regression fixes — P1 first
|
||
(state-bucket drift + Kyverno label contradiction are the highest-
|
||
severity findings, both correctness regressions left by the rebrand).
|
||
- Wave 2 (P5–P9): simplify without regressions — P5 before P6/P9
|
||
(regression-verify dedup is independent); P8 changes the workflow test.
|
||
- Wave 3 (P10–P14): security + maintainability — P10 before P11
|
||
(identity enforcement before payload validation); P12/P13 independent
|
||
splits.
|
||
- Wave 4 (P15–P17): developer experience — independent; P17 last
|
||
(reflects the consolidated path).
|
||
- Wave 5 (P18–P20): no-humans onboarding — P18 (schema+Lambda action)
|
||
before P19 (env-file autogen consumes the schema) before P20 (cross-
|
||
account role, offline-proven).
|
||
|
||
**Verification gates:** the regression gate (D-091) runs after Wave 2
|
||
(P9) and at P21 — all 22 capabilities must stay Verified (no
|
||
regressions from simplification). A mid-milestone checkpoint runs after
|
||
Wave 3 (P14), offline.
|
||
|
||
## Milestone v1.16 Phases
|
||
|
||
| Phase | Name | Goal |
|
||
|-------|------|------|
|
||
| 01 | state-bucket-and-kyverno-rebrand-fix | `adapter.py:117` `acdl-tfstate`→`nova-tfstate`; Kyverno `require-resource-labels.yml` `acdl:*`→`nova:*` labels. Regression-risk fix. |
|
||
| 02 | user-facing-acdl-to-nova-sweep | Onboarding msg, alert title/body, PR comments, CI banner, module docstrings → Nova. |
|
||
| 03 | dead-code-and-stale-prefix-cleanup | Dead `ACDL_ENVIRONMENT_OVERRIDE` export; stale dual-read comments; `acdl_*` temp prefixes → `nova_*`. |
|
||
| 04 | migrate-ssm-except-narrowing | `migrate_ssm_paths.py` `except Exception`→`ParameterNotFound`. |
|
||
| 05 | regression-verify-dedup | Extract shared live-plan/resolver/lifecycle-resolve helpers (~70 lines saved). |
|
||
| 06 | run-platform-deadcode-and-hitl-fn | Remove dead export; extract `run_hitl_gate()` shell fn; drop hardcoded UUID/`v18` stamp. |
|
||
| 07 | contract-resolver-envloader-and-kind | Import env loader from environment_check; add `kind` field to registry; replace `is_l2` heuristic. |
|
||
| 08 | workflow-generator-dedup | `scripts/sync_workflows.py` (one source → both dirs); replace byte-identity test with generator-output test. |
|
||
| 09 | run-platform-split | Extract decommission + uptime blocks into `scripts/run_decommission.sh` + `scripts/run_uptime.sh`. |
|
||
| 10 | contract-ingestor-defense-in-depth | Fail closed on missing IAM identity; derive env enum from `core/environments/` dir. |
|
||
| 11 | contract-ingestor-payload-validation | Contract blob size cap + schema validation; consistent error/stackTrace caps. |
|
||
| 12 | split-contract-resolver | 638 lines → resolve / decommission-transform / cli modules. |
|
||
| 13 | split-regression-verify | 670 lines → capability checks / live-plan helpers / cli modules. |
|
||
| 14 | schema-driven-outputs-and-cache | `SAFE_OUTPUT_NAMES` from interface.json; cache loaded schemas in resolver. |
|
||
| 15 | run-platform-help-and-flags-doc | Real `--help`; document `--deploy-uptime`; surface `--local` in README. |
|
||
| 16 | workflows-readme-catalog | `.github/workflows/README.md` — triggers, inputs, secrets, reusable-workflow contracts. |
|
||
| 17 | getting-started-consolidation | Single getting-started section: offline happy path first, AWS path second. |
|
||
| 18 | onboarding-schema-and-lambda-action | `schemas/onboarding.schema.json` + `onboard_consumer` action → CMDB row pending grant. |
|
||
| 19 | onboarding-envfile-autogen | `core/onboarding.py` generates `<env>.json` from a request + emits a PR; rebrand onboarding message. |
|
||
| 20 | cross-account-role-automation-offline | Terraform for consumer deploy-role + `nova:owner` ABAC tag (offline-proven only). |
|
||
| 21 | final-review-ship | Review + audit + milestone ship `v1.15.26` + merge to main. |
|
||
|
||
Milestone COMPLETE gate: review → ship `v1.15.26` (NFR milestone; final
|
||
patch IS the release) → audit.
|
||
|
||
## Key Decisions (v1.16)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.16 decisions numbered D-113+
|
||
to continue from v1.15's D-112. The four high-judgment scope decisions
|
||
(D-113..D-116) were locked in by the user during the ideation planning
|
||
conversation; D-117..D-119 resolved at CLARIFY.
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-113 | Onboarding scope = request-path only (NFR-shaped). | User chose "Request-path only." Full self-service AWS account/network/state provisioning is a feature (creates real cloud resources), not an NFR. v1.16 removes the human handoff from the *request* step (schema + Lambda action + env-file autogen + ABAC grant hook); real AWS account creation stays a future feature milestone. | P18–P20 implement the request path; real provisioning deferred. |
|
||
| D-114 | Cross-account Terraform = offline-proven only. | User chose "Offline-proven only." P20 Terraform for the consumer deploy-role + ABAC tag is authored + `terraform validate` + `--check-only` only; no live apply (consistent with `NOVA_LIFECYCLE_MODE=plan` default). No new AWS resources created in this NFR milestone. | P20 validates offline; live apply deferred. |
|
||
| D-115 | Workflow dedup = generator (not status quo). | User chose "Generator." `scripts/sync_workflows.py` writes one source → both `.gitea/`+`.github/` dirs; the byte-identity test in `test_pipeline_contract.py` is replaced with a "generated outputs match committed files" test. Removes ~20 KB manual-sync risk. | P8 implements the generator + test swap. |
|
||
| D-116 | Drift fixes = P1 of v1.16 (not a hotfix to main). | User chose "P1 of v1.16." The state-bucket drift (`adapter.py:117`) and Kyverno label contradiction are correctness regressions but latent in plan-only mode (no live apply in the default path), so they are not an active outage. Fixing them as P1 keeps the milestone self-contained. | P1 fixes both; no hotfix to main. |
|
||
| D-117 | v1.14 NFR categories are NOT re-proposed. | v1.14 already swept over-broad excepts (REQ-141), hardcoded account-ID (REQ-142), IAM `Resource:"*"` scoping (REQ-143), contractId/env validation (REQ-144), `.gitignore` catch-all (REQ-146), `--kube-version` removal (REQ-147), orphan cleanup (REQ-148), `set -euo pipefail` parity (REQ-150). v1.16 finds NEW residual signals (the v1.15 rebrand left a fresh debt layer) and does not duplicate completed work. | Wave 1–5 target only fresh debt. |
|
||
| D-118 | Regression gate (D-091) gates Wave 2 completion and P21. | "Simplify without regressions" is only credible if the regression gate runs after the simplification wave. The gate runs after P9 (Wave 2 done) and at P21 (milestone complete); any non-Verified capability halts W3. Mid-milestone checkpoint after P14 (offline). | P9 + P21 run the gate; P14 checkpoint. |
|
||
| D-119 | `onboard_consumer` action stores a CMDB row pending grant (not auto-provisions). | The request-path-only scope (D-113) means the Lambda accepts an onboarding request and writes a `pending` row to `nova-contracts` (or a new `nova-onboarding` partition key); the platform automation that grants the ABAC role is the P20 Terraform (offline-proven). No AWS resources are created by the Lambda action itself. | P18 writes the pending row; P20 proves the grant Terraform offline. |
|
||
|
||
## Objective for Milestone v1.17 (active — Strategic Direction, Leadership Metrics & Unified Story)
|
||
|
||
**Milestone type:** Feature (P1–P3 feat; P4 docs; P5 docs+test; P6 test;
|
||
P7 review+audit+ship). Tags on the v1.16.x line: `v1.16.0` (P0) →
|
||
`v1.16.1..v1.16.7` (P1–P7) → `v1.16.8` (P8 final = milestone release).
|
||
|
||
**Three pillars:**
|
||
|
||
- **Pillar A — Strategic Direction.** A durable, PO-authored
|
||
`.ciagent/NORTH_STAR.md` encodes the platform's vision, 4 strategic
|
||
objectives, anti-goals, v1.17 non-goals, 12–18mo targets (with a
|
||
grounding column), and success criteria. CIAgent reads it in every
|
||
future `/ci-run` so the direction survives across milestones. The
|
||
attestation clarification is reflected: human attestation required at
|
||
stage gates (QA for production, SRE for operational readiness); autonomy
|
||
in operations, not in accountability. **v1.21 refinement:** Strategic
|
||
Objective #4 reframed from "default substrate for agentic consumption" to
|
||
integrating with externally owned PDLC/SDLC/Agentic/Citizen Developer
|
||
platforms regardless of source (Nova provides skills + MCP endpoints;
|
||
all prod intents go through the same controls). Objective #2 reworded:
|
||
trust is established by deterministic scripts that calculate a score —
|
||
the platform functions without AI. Objective #3 reworded with four
|
||
CTO-grade metrics (Lead Time PR→Prod, Infrastructure Vulnerability
|
||
Count trend, MTTR, Cloud Spend Reduction) all flowing into PowerBI.
|
||
Anti-goals #1, #4, #5 removed; replaced with "not an upstream
|
||
development platform" and "not a replacement for the PDLC".
|
||
|
||
- **Pillar B — Leadership Metrics + PowerBI.** Instrument Nova to
|
||
collect, aggregate, and surface leadership-grade metrics that prove the
|
||
"no-humans" autonomous-infrastructure value proposition (reframed in
|
||
v1.21 to "autonomous cloud delivery" — professional framing; the
|
||
platform delivers safe production deployment without an operator in
|
||
the loop of normal operations). Nova-native
|
||
minimal tech (CloudEvents 1.0 envelope, JSONL event log, SQLite cold
|
||
store, hash-chained Decision Ledger via `outbox_writer.py` extension)
|
||
+ Infracost for pre-apply cost estimates. Hybrid model: existing
|
||
file-based signals (REGRESSION_REPORT.json, pcr.json, signal.json,
|
||
junit XML) are sources the collector reads and projects into events;
|
||
new emitters emit CloudEvents directly. PowerBI export = CSV/JSON
|
||
views (fact + dimension tables + 8 empty placeholder views for
|
||
deferred metrics). **Hard constraint: DO NOT make anything up.** Every
|
||
metric is `grounded` (cites source file + schema), `derived`
|
||
(documented formula), or `deferred` (cites decision ID — D-096/D-083/
|
||
D-113/D-114/D-119). The 8 deferred metrics: drift detection, GreenOps/
|
||
carbon, predictive/reactive, live CUR reconciliation, multi-cloud,
|
||
red-team MTTR, self-healing velocity, SLA/downtime.
|
||
|
||
- **Pillar C — Unified Narrative Deck.** Merge the two existing decks
|
||
(`how-the-platform-works` + `the-developer-experience`) into one unified
|
||
narrative deck "Nova — The No-Humans Infrastructure Platform" with a
|
||
single arc: Problem → Vision/Direction (NORTH_STAR) → How it works →
|
||
Proof (metrics) → Roadmap/Ask. The "tell them x3" structure applies at
|
||
deck level AND per slide (each slide opens with what it covers,
|
||
delivers, closes with an explicit "benefit of this stage" callout).
|
||
Fluid transitions between slides. Both old decks retired.
|
||
|
||
**Key decisions resolved in the planning conversation (D-120+):**
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-120 | Tech stack = Nova-native + Infracost, drift deferred. | The PO's technical-direction document specifies Kafka/Prometheus/ClickHouse/QLDB/OTel — none exist in Nova today. Adopt the PRINCIPLES (events as source of truth, CloudEvents envelope, decision ledger, definition-of-success docs, dashboards-as-projections) but implement with Nova-native minimal tech (JSONL + SQLite + hash-chained ledger). No Kafka/Prometheus/ClickHouse/QLDB. Infracost adopted (runs offline on plan JSON). Drift detection deferred (D-096 + no scheduler). | P1–P3 use Nova-native tech; Infracost in P1; drift deferred. |
|
||
| D-121 | Decision Ledger = extend outbox_writer.py → SQLite append-only hash chain. | The direction's #1 priority is the Decision Ledger. Nova already has a hash-chained outbox (outbox_writer.py). Extend it to a SQLite append-only table with hash chain; add ai.decision.made + attestation.recorded events. Honors D-083 (no S3 Object Lock/JWS). | P1 extends outbox_writer; ledger is SQLite hash-chain. |
|
||
| D-122 | AI Planner framing = map Nova's real decision points. | The direction assumes an "AI Planner/Reasoner" (planner-v3.2). Nova's actual decision path is confidence_signal + HITL gate. Model ai.decision.made from confidence_signal (decision_id=run_id, chosen_action=band, confidence=score, alternatives=perInput, human_override=HITL block). LLM planner marked future/aspirational. | P1 emits honest decision events; no fabricated LLM. |
|
||
| D-123 | Deferred metrics = all 8 (drift, GreenOps, predictive/reactive, live CUR, multi-cloud, red-team MTTR, self-healing, SLA/downtime). | These require live AWS (D-096) or new external systems. Ship as empty PowerBI placeholder views with documented schemas. | P3 ships 8 placeholder views; METRICS.md marks them deferred. |
|
||
| D-124 | NORTH_STAR = strategy; tech direction = engineering input. | The PO's technical-direction document is engineering architecture, not strategy. NORTH_STAR.md captures strategic vision/objectives/anti-goals (PO-authored). The tech direction becomes the telemetry reference architecture section in RESEARCH.md/ARCHITECTURE.md, cited by NORTH_STAR's engineering objectives. | P0 writes NORTH_STAR; RESEARCH writes the telemetry reference. |
|
||
| D-125 | Events vs files = hybrid. | Existing file-based signals (REGRESSION_REPORT.json, pcr.json, signal.json, junit) stay as files; the collector reads them and emits normalized CloudEvents into JSONL + SQLite. New emitters emit CloudEvents directly. | P2 collector reads files + events. |
|
||
| D-126 | Hot/cold split = cold-only SQLite (hot path deferred). | Nova has no live ops dashboard (no live AWS, D-096). The SQLite store is cold-only (batch/historical). The hot path is documented as deferred. | P2 SQLite is cold-only. |
|
||
| D-127 | Definition-of-success = per-KPI docs. | The direction's §11 requires a definition-of-success doc for every executive KPI. Adopt this standard; docs live in `docs/metrics/`. | P4 writes per-KPI docs. |
|
||
| D-128 | Storage location = metrics/ at repo root. | metrics/runs/ (per-run manifests), metrics/nova_metrics.db (SQLite), metrics/events.jsonl (event log), metrics/powerbi/ (export). | P1–P3 use metrics/ at repo root. |
|
||
| D-129 | PowerBI delivery = CSV/JSON files, folder connector. | Nova is offline-first; no live connector to a running service. PowerBI ingests via the folder connector. | P3 emits CSV/JSON to metrics/powerbi/. |
|
||
| D-130 | Deck arc = Problem → Vision → How → Proof → Roadmap. | The unified narrative deck's 5-act structure. x3 arc at deck + slide level. Per-slide benefit callouts. Fluid transitions. Both old decks retired. | P5 builds the unified deck; old decks deleted. |
|
||
| D-131 | MTTR scope = platform-run MTTR. | The <60s MTTR target refers to platform-run failures (apply.failed → successful retry), not infra-incident MTTR (no incident detection system). Infra-incident MTTR deferred. | P4 grounds platform-run MTTR. |
|
||
| D-132 | Attestation instrumentation = emit attestation.recorded events. | The attestation system (hitl_gates.py + attestation_matrix.py + separation_of_duties.py) already exists. Instrument it: emit attestation.recorded events into the Decision Ledger + PowerBI. Attestation Coverage = 100% target grounded from outbox approver_* attributes. | P1 emits attestation events; P4 grounds Attestation Coverage. |
|
||
|
||
## Key Decisions (v1.18)
|
||
|
||
Resolved at the CLARIFY stage (full autonomy — all within locked
|
||
constraints or user-directed scope). New v1.18 decisions:
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-133 | Submission-readiness validator location = extend `contract_ingestor.py --check-readiness`. | Adding a new CLI binary is unnecessary; the ingestor is the existing entry point for contract submission. The validator is a subcommand that runs before ingestion proceeds. No new binary, no new entry point to maintain. | P3 implements the subcommand; no new CLI binary. |
|
||
| D-134 | Deck slide budget = 18 → 21 slides (no act restructure). | The 3 new slides (scope/RACI/atelier) are leadership-relevant and append after the existing 18. The 5-act arc (D-130) is preserved; the new slides are append-only context, not a new act. | P6 appends 3 slides → 21 total. |
|
||
| D-135 | Atelier MCP transport = stdio now; HTTP-ready (same server object). | stdio is the local-agent transport (the citizen developer's AI agent spawns the server as a subprocess). The MCP Python SDK v2 supports Streamable HTTP on the same `MCPServer` object, so adding HTTP later is a transport-only change in `server.py`, not a rewrite. | P5 ships stdio; HTTP deferred (documented in README). |
|
||
| D-136 | Atelier source = vendor pinned tag under `mcp/atelier/vendor/`. | An agentic validation result is only reproducible if the principles that produced it are pinned. Live-fetch breaks replayability (Atelier `main` drifts). Vendoring matches the v1.16 P15 offline-first precedent and the Nova thesis (provable trust). `mcp/atelier/vendor/VERSION.md` records the pinned tag; `scripts/update_atelier_vendor.sh` is the intentional upgrade path. | P5 vendors Atelier; live-fetch not implemented. |
|
||
| D-137 | MCP server language = Python (MCP Python SDK v2, `modelcontextprotocol/python-sdk`). | Nova's `core/` is Python. The MCP Python SDK v2 (23.9k stars, MIT, stable) matches the codebase; type hints become JSON Schema automatically (`@mcp.tool()` decorator). | P5 uses Python SDK v2. |
|
||
| D-138 | Skill catalog format = markdown files under `skills/` keyed to Atelier domain paths. | Markdown is the established Nova docs format (Jekyll Pages, 4-step deck process). Each skill file names the Atelier source path, distills the first-principles, links to agent-checklist triggers, and maps to the BA.A catalog. | P4 authors 9 markdown skill files. |
|
||
| D-139 | RACI role names = Citizen Developer / Platform / Release Management (co-owned). | User-specified. The 3 roles are the columns of the RACI table. Release Management is co-owned: QA + SRE attestations are required by the actual release (performed agentically, overseen & triggered by the Citizen Developer). | P2 authors the RACI with these 3 roles. |
|
||
| D-140 | MCP server extensibility = plugin-registry (`plugins/<name>.py` implementing `register(mcp)`). | Future capabilities (new scanners, policy evaluators, cost tools) drop in as new plugin files — no `server.py` edits. `server.py` scans `plugins/` and calls `register` on each. This is the extensibility insurance: plugins are decoupled from the server entrypoint. | P5 implements the plugin-registry; initial plugins are `principles.py` + `validation.py`. |
|
||
| D-141 | PPTX storage = commit binary directly to `docs/presentations/` (no LFS). | Decks are small (~1-5 MiB); git handles binary blobs. LFS requires server-side support (unverified for git.cloudinit.dev) + client config. Committing directly is simplest and works without any repo/server config. Binary diffs are not delta-friendly, but deck changes are infrequent. | P1/P2/P6 commit .pptx directly. |
|
||
| D-142 | Deck render trigger = any phase modifying `docs/presentations/*-marp.md` or `docs/presentations/assets/` must re-render HTML + PPTX, commit PPTX, and attach to the Gitea release. | PPTX was previously manual + release-only (not committed). v1.18 makes it a first-class artifact: committed (history) + attached (download), both always, not optional. Automated via `scripts/render_deck.sh` + `scripts/attach_release_asset.py`. | P1/P2/P6 run the render+commit+attach pipeline. |
|
||
## Objective for Milestone v1.19 (complete — Nova 2nd-Release Sync)
|
||
|
||
> **NFR-only chore milestone.** Ships a patch on the v1.18.x line (tag
|
||
> `v1.18.0`). Single execution phase. Establishes the manual-only "2nd
|
||
> release" pipeline from `~/acdl` (CIAgent-managed source of truth, full audit
|
||
> trail) into `~/nova` (GitLab `jonathanchery/nova` — separate repo, separate
|
||
> history, consumer / platform-team audience).
|
||
|
||
### Why
|
||
|
||
`~/acdl` is the engineering source of truth and carries the full CIAgent
|
||
audit trail (`.ciagent/`, milestone branches, `---ci---` blocks, Gitea
|
||
releases). Consumers and the platform team should consume a clean,
|
||
conventional-commit-shaped tree without the CIAgent plumbing. The old
|
||
`scripts/sync_to_gl.sh` mirrored `~/acdl → ~/gl/acdl` with a single
|
||
kitchen-sink `chore: sync from source mirror <ts>` commit — wrong audience,
|
||
wrong commit standard, wrong repo.
|
||
|
||
### What
|
||
|
||
- **`scripts/sync_to_nova.sh`** replaces `scripts/sync_to_gl.sh`.
|
||
- **Manual-only gate**: refuses without `--release` / `RELEASE_CONFIRMED=1`
|
||
(exit 2). Never triggerable by CI.
|
||
- **Consumer subset only**: excludes `.ciagent/`, `.gitea/`, `.env*`,
|
||
`terraform/`, `demo/`, runtime metrics artifacts, and internal-only scripts
|
||
(the `EXCLUDE_SCRIPTS` list — CIAgent/ops/release plumbing). Keeps
|
||
consumer-facing runbooks (`run_ci.sh`, `run_platform.sh`, etc.) and the
|
||
metrics export views (`metrics/README.md`, `powerbi/`, `TRUST_SNAPSHOT.md`).
|
||
- **Destination history protected**: rsync `--filter=P .git` ensures
|
||
`~/nova/.git` is never touched.
|
||
- **Domain-based commits**: 13 fixed-order domains (config → core → adapters
|
||
→ modules → contracts → schemas → pipelines → mcp → skills → scripts →
|
||
tests → docs → workflows). Each changed domain gets its own conventional
|
||
commit, supplied positionally via repeated `-m` flags. No kitchen-sink.
|
||
- **Conventional-commit validation**: regex-enforced
|
||
(`feat|fix|docs|chore|refactor|perf|test|build|ci|style|revert`); bypass via
|
||
`--no-verify-format`.
|
||
- **Modes**: `--list-domains` (print order), `--dry-run` (preview rsync +
|
||
messages), `--no-push` (commit without pushing), `-v` (verbose).
|
||
|
||
### Out of Scope
|
||
|
||
- **coreci / Atelier review gate on the synced tree** — deferred. A future
|
||
milestone may run a vendored-Atelier review pass before commit and block on
|
||
P0 findings.
|
||
- **Tagging releases on the `~/nova` side** — could add `--tag <semver>`
|
||
later.
|
||
- **Deleting `~/gl`** — the old mirror dir is left on disk; only the sync
|
||
script targeting it is removed.
|
||
|
||
### Requirements
|
||
|
||
- **REQ-229** — `scripts/sync_to_nova.sh` replaces `sync_to_gl.sh` with the
|
||
manual-only, consumer-subset, domain-committed 2nd-release pipeline
|
||
described above. (Phase P1)
|
||
|
||
### Phase Plan
|
||
|
||
| Phase | Name | Status |
|
||
|-------|------|--------|
|
||
| P1 | nova-sync-script | complete |
|
||
| P2 | final-review-ship | pending |
|
||
|
||
### Decisions
|
||
|
||
| ID | Decision | Rationale | Outcome |
|
||
|----|----------|-----------|---------|
|
||
| D-143 | 2nd release target = `~/nova` (separate GitLab repo), not `~/gl/acdl`. | `~/nova` is consumer/platform-team-facing with its own history; `~/gl/acdl` was an internal mirror with a kitchen-sink commit standard. Separate audience → separate repo → separate commit standard. | `sync_to_nova.sh` targets `~/nova`; `sync_to_gl.sh` removed. |
|
||
| D-144 | Commit standard for `~/nova` = real conventional commits per domain (not the `---ci---` audit blocks used in `~/acdl`). | `~/acdl` commits carry CIAgent audit metadata (`---ci---` blocks) for the ciagent auditing workflow; that's noise for platform consumers. `~/nova` gets clean `feat/fix/docs/chore(scope): subject` commits grouped by domain. | Script validates conventional format; domain-based commits via positional `-m`. |
|
||
| D-145 | Trigger = manual-only (`--release` / `RELEASE_CONFIRMED=1`). | The 2nd release is a deliberate human action, not a CI side-effect. The gate guarantees it can never fire from Gitea Actions, GitHub Actions, or accidental invocation. | Script exits 2 without `--release`. |
|
||
| D-146 | Domain grouping = 13 fixed-order domains by path prefix; messages map positionally over CHANGED domains only. | Avoids the kitchen-sink commit; gives `~/nova` a reviewable, conventional history tailored to platform consumers. Positional-over-changed mapping lets the human supply exactly the messages needed, in domain order, without padding for unchanged domains. | `--list-domains` prints order; `--dry-run` previews; count-mismatch errors clearly. |
|
||
| D-147 | coreci / Atelier review gate = deferred this milestone. | The vendored Atelier (`mcp/atelier/vendor`) could review the synced tree before commit and block on P0, but that's an additive hardening step, not part of establishing the pipeline. Deferred to a future milestone. | Sync ships consumer contents as-is; no review gate. |
|
||
|
||
### CLARIFY auto-resolved parameters (full autonomy)
|
||
|
||
The following ambiguities were identified and auto-resolved at full
|
||
autonomy (no human escalation needed — confidence > 0.6 threshold):
|
||
|
||
1. **Fix scope** — comprehensive (theme CSS + render scripts + mermaid
|
||
re-layout + deck content + tests) vs. minimal. **Resolved: comprehensive.**
|
||
The root cause spans all four layers; a theme-only fix would leave
|
||
the extreme-aspect-ratio diagrams and the stale `render_deck.sh`
|
||
unfixed. Confidence: 0.95.
|
||
|
||
2. **Pipeline depth** — full pipeline (SPECIFY→CLARIFY→RESEARCH→PLAN→
|
||
GRILL→EXECUTE→VERIFY→SHIP) vs. lighter path. **Resolved: full pipeline.**
|
||
This is a new milestone (v1.22); the full pipeline ensures the plan
|
||
is grilled and the audit trail is complete. Confidence: 0.9.
|
||
|
||
3. **Mermaid diagram fixes** — re-layout to LR + re-render vs. CSS-only
|
||
fix. **Resolved: re-layout to LR + re-render at 2x transparent.**
|
||
The `telemetry-live-ops.mmd` uses `flowchart TB` (produced a 1024×1628
|
||
PNG — aspect 0.63); the README (line 168) explicitly says to use
|
||
horizontal layouts for wide diagrams. CSS-only cannot fix the aspect
|
||
ratio. Confidence: 0.95.
|
||
|
||
4. **`render_deck.sh` disposition** — fix (add `--theme`) vs. delete.
|
||
**Resolved: delete.** The README already documents `render_slides.sh`
|
||
as canonical; `render_deck.sh` is unreferenced by the build-commands
|
||
section and is a footgun (produces unthemed output). Confidence: 0.9.
|
||
|
||
5. **Slide count change** — keep 18 main + 1 appendix vs. split
|
||
overflowing slides. **Resolved: split slides 3 and 8** (18 → 20 main
|
||
+ 1 appendix). The `test_marp_deck_slide_count` test + README
|
||
convention are updated to match. Confidence: 0.85.
|
||
|
||
No human escalation. All decisions logged with confidence scores above
|
||
the 0.6 threshold.
|
||
|
||
## Objective for Milestone v1.22 (active — Nova Deck Layout Fix)
|
||
|
||
v1.22 fixes the systemic layout/formatting problems in the Nova
|
||
presentation deck that made every slide look "out of whack" after the
|
||
v1.21 P5 re-render. A full investigation determined the root cause is
|
||
**not a P5 regression** — the `nova-sp-theme.css` has had zero `section`
|
||
padding since it was authored (it declares `/* @theme nova-sp */` as a
|
||
comment, not the `@theme` directive, and does not `@import` Marp's
|
||
default theme, so Marp's default `section { padding: 56px 64px }` never
|
||
applies). Combined with `overflow:hidden` (silent clip), a blunt
|
||
`img { max-height: 320px }` rule, header+footer chrome on every slide,
|
||
and two new P5 diagrams with extreme aspect ratios (13.52× and 0.63×),
|
||
8 of 19 slides overflow and the rest look jammed against the edges.
|
||
|
||
This milestone is a **comprehensive fix** across four layers: (1) the
|
||
theme CSS (padding, overflow handling, aspect-ratio-aware image rules,
|
||
title-slide chrome suppression, paragraph/list/table spacing); (2) the
|
||
render scripts (delete the stale unthemed `render_deck.sh`, pin
|
||
marp-cli/mermaid-cli versions, add 2x scale + transparent bg to
|
||
mermaid); (3) the two problematic mermaid diagrams (re-layout to LR +
|
||
2-row wrap); (4) the deck content (trim/split the 8 overflowing slides,
|
||
remove the redundant `header:` from frontmatter). It also adds the
|
||
**layout/aspect-ratio/theme-structural tests** that were missing — the
|
||
gap that let this regression through undetected.
|
||
|
||
**Milestone type:** NFR (all phases are fix/docs/test — no feat/breaking).
|
||
Tags run on the **v1.21.x** patch line (previous minor per
|
||
branch-strategy): `v1.21.0` (P0) → `v1.21.1..v1.21.5` (P1–P5) →
|
||
`v1.21.6` (P6 final = milestone release).
|
||
|
||
**Phase count:** 7 (P0 pre-execution + 5 execution + 1 final).
|
||
|
||
**Wave ordering:**
|
||
- Wave 1 (P1 + P2, parallel): theme CSS + render scripts — no
|
||
interdependency. P1 establishes the padding/overflow/image budget that
|
||
P4's content trimming relies on; P2 fixes the render pipeline that P3's
|
||
PNG re-render depends on.
|
||
- Wave 2 (P3 + P4, parallel): mermaid re-layout + deck content. P3
|
||
depends on P2 (2x scale flag); P4 depends on P1 (padding budget).
|
||
- Wave 3 (P5): re-render HTML + PPTX + add tests. Depends on all above.
|
||
- Wave 4 (P6): final review + audit + milestone ship.
|
||
|
||
**Hard constraints:**
|
||
- DO NOT change the deck narrative or the 4-beat arc (Problem → Solution
|
||
→ Proof → Roadmap + Ask) — only fix layout/formatting.
|
||
- DO NOT re-introduce badges, version strings, or internal citations
|
||
(D-###/REQ-###/.py paths) that v1.21 removed.
|
||
- The slide count may change from 18 main + 1 appendix to 20 main + 1
|
||
appendix (splitting slides 3 and 8 to relieve overflow). The
|
||
`test_marp_deck_slide_count` test + README "18 main + 1 appendix"
|
||
convention must be updated to match.
|
||
- PPTX remains a first-class committed artifact + release attachment.
|
||
- No code changes outside `docs/presentations/`, `scripts/render*.sh`,
|
||
and `tests/test_slides_pipeline.py`.
|
||
|
||
### Requirements
|
||
|
||
New requirements REQ-254..REQ-262 — see `REQUIREMENTS.md` §v1.22. Summary:
|
||
|
||
- **REQ-254:** Theme CSS — add `section` padding + overflow handling.
|
||
- **REQ-255:** Theme CSS — aspect-ratio-aware image rules (replace blunt
|
||
`max-height:320px`).
|
||
- **REQ-256:** Theme CSS — title-slide chrome suppression + paragraph/
|
||
list/table spacing tightening.
|
||
- **REQ-257:** Render scripts — delete `render_deck.sh` (or fix `--theme`);
|
||
pin marp-cli/mermaid-cli versions.
|
||
- **REQ-258:** `render_slides.sh` — add `-s 2 -b transparent` to mermaid-cli
|
||
(README spec).
|
||
- **REQ-259:** Re-layout `telemetry-live-ops.mmd` from `flowchart TB` →
|
||
`flowchart LR`; re-render PNG at 2x transparent.
|
||
- **REQ-260:** Re-layout `platform-pipeline.mmd` to 2-row subgraph wrap;
|
||
re-render PNG at 2x transparent.
|
||
- **REQ-261:** Trim/split 8 overflowing slides (3, 5, 6, 8, 9, 12, 15,
|
||
A1) + remove redundant `header:` from frontmatter.
|
||
- **REQ-262:** Re-render HTML + PPTX + add layout/aspect-ratio/theme-
|
||
structural tests.
|
||
|
||
## v1.23 — Nova Deck Cleanup & Python PPTX
|
||
|
||
> **Active milestone.** NFR (docs/render/test only; no features).
|
||
> Branch: `milestone/v1.23-deck-cleanup-python-pptx`. Tags run on the
|
||
> **v1.22.x** patch line: `v1.22.0` (P0) → `v1.22.1..v1.22.5` (P1–P5) →
|
||
> `v1.22.6` (P6 final = milestone release).
|
||
|
||
Driven by user feedback that the deck looked "out of whack" and the
|
||
desire to return to the clean, well-formatted style of the old
|
||
`the-developer-experience.html`. Investigation revealed the "clean"
|
||
reference was itself MARP output (using Marp's built-in `default` theme
|
||
+ an inline `style:` block); the current deck's standalone
|
||
`nova-sp-theme.css` re-derives all base spacing from scratch and had a
|
||
zero-padding bug (fixed in v1.22, but the standalone approach is
|
||
fragile). The milestone delivers:
|
||
|
||
- **Single-document consolidation** — `*-marp.md` becomes the sole
|
||
source of truth; the plain `.md` is deleted; speaker notes + talking
|
||
points are embedded as Marp HTML comments.
|
||
- **Clean style restoration** — revert to `theme: default` + inline
|
||
`style:` block (S&P palette); `nova-sp-theme.css` retained as a
|
||
reference, retired from render.
|
||
- **Self-contained HTML** — base64-inline all images for
|
||
redistribution.
|
||
- **Parallel python-pptx generator** — structured, editable, S&P-themed
|
||
PPTX alongside the MARP image-of-slide PPTX.
|
||
- **Targeted word-count trim** + removal of the previously-used loaded scope term.
|
||
|
||
**Phase count:** 7 (P0 pre-execution + 5 execution + 1 final).
|
||
|
||
**Hard constraints:**
|
||
- DO NOT change the deck narrative or the 4-beat arc (Problem → Solution
|
||
→ Proof → Roadmap + Ask) — only trim word count.
|
||
- DO NOT re-introduce badges, version strings, or internal citations.
|
||
- DO NOT remove MARP — it stays for HTML + PPTX; python-pptx runs in
|
||
parallel.
|
||
- `nova-sp-theme.css` is retained (not deleted) as a styling reference.
|
||
|
||
### Requirements
|
||
|
||
New requirements REQ-263..REQ-275 — see `REQUIREMENTS.md` §v1.23.
|
||
Summary: consolidation (REQ-263,264), style restoration (REQ-265,266,267),
|
||
image inlining (REQ-268), python-pptx generator (REQ-269,270), word-count
|
||
trim + loaded-scope-term removal (REQ-271,272), CI/tests/README (REQ-273,274,275).
|
||
|
||
## v1.25 — kyverno-json Unified Policy Engine
|
||
|
||
> **Active milestone.** Feature milestone (the primary compliance/policy
|
||
> tool becomes kyverno-json, implemented behind a swappable adapter).
|
||
> Branch: `milestone/v1.25-kyverno-json`. Tags run on the **v1.24.x**
|
||
> patch line: `v1.24.0` (P0) → `v1.24.1..v1.24.4` (P1–P4) → `v1.24.5`
|
||
> (P5 final = milestone release).
|
||
|
||
[Nova](https://github.com/kyverno/kyverno-json) `kyverno-json` is a
|
||
runtime from the Kyverno ecosystem that applies Kyverno policies to
|
||
**any JSON or YAML payload** — not just Kubernetes manifests. This
|
||
milestone makes kyverno-json the **primary tool of choice for
|
||
compliance / policy checks** in Nova, implemented as an **adapter**
|
||
(the `PolicyEngine` protocol) so the platform may one day replace it
|
||
with something else (e.g. OPA) without touching the confidence signal
|
||
or the pipeline.
|
||
|
||
### Why
|
||
|
||
Nova's policy posture today is split across three engines with three
|
||
different rule languages and three adapter shapes:
|
||
|
||
- **Checkov** (`adapters/terraform/policy/checkov_adapter.py`) — the
|
||
runtime scanner over `terraform_plan` JSON; carries the
|
||
`NOVA_TAG_NAMING` custom rule. Imperative YAML+Python rules.
|
||
- **Wiz** (`adapters/wiz/wiz_adapter.py`) — security findings from the
|
||
Wiz API; inactive unless credentials are present.
|
||
- **Kyverno (K8s)** (`adapters/kyverno/kyverno_adapter.py`) — translates
|
||
Kyverno `PolicyReport` results; **inactive for Terraform-only stacks**
|
||
(the platform emits Terraform, not K8s manifests — D-053).
|
||
|
||
All three emit the same `schemas/policy_check_result.schema.json` shape
|
||
that `core/confidence_signal.py` consumes engine-agnostically. The
|
||
*contract* is already right; the *orchestration* is fragmented. There is
|
||
no single place where "what Nova considers compliant" is declared —
|
||
tagging lives in a Checkov custom rule, public-ingress in Checkov's
|
||
`RULE_MAP`, env-transition destroy in `core/env_transition.py`
|
||
(imperative Python), and capability regression in
|
||
`core/regression_verify.py` (imperative Python). Each is a different
|
||
language, each drifts independently, and the K8s Kyverno adapter can't
|
||
help because it only speaks to K8s manifests.
|
||
|
||
`kyverno-json` fixes this: one declarative policy language (Kyverno
|
||
policies with JMESPath assertions) that applies to **any** Nova
|
||
artifact — the consumer contract, the resolved Stack IR, the
|
||
Terraform plan JSON, and even the PolicyCheckResult list itself
|
||
(meta-validation). It becomes the **unified orchestrator** of compliance
|
||
checks, while Checkov and Wiz remain as raw-finding adapters that feed
|
||
*into* kyverno-json meta-policies (so Nova-specific posture rules sit
|
||
on top of, not beside, the scanner findings).
|
||
|
||
### What the milestone delivers
|
||
|
||
- **Swappable `PolicyEngine` protocol** (`core/policy_engine.py`) — a
|
||
Python Protocol + registry selected from `config.json` (`policy.engine`,
|
||
default `"kyverno-json"`). `KyvernoJsonEngine` implements it (shells
|
||
to the `kyverno-json` CLI); a future `OpaEngine` implements the same
|
||
protocol. The confidence signal and pipeline never import the engine
|
||
directly — they go through the registry.
|
||
- **`KyvernoJsonEngine` adapter** (`adapters/kyverno-json/`) —
|
||
`evaluate(payload, policies) -> list[PolicyCheckResult]` translates
|
||
kyverno-json native output to the existing PCR schema. Mirrors the
|
||
Checkov/Wiz adapter pattern. `is_configured()` guard skips gracefully
|
||
when the `kyverno-json` binary is absent (same pattern as the Wiz
|
||
adapter — emits `SKIPPED`, never breaks the pipeline).
|
||
- **Policies over all four Nova artifacts** under
|
||
`adapters/kyverno-json/policies/`:
|
||
- `contract/` — consumer contract JSON (shape + env-promotion rules).
|
||
- `stack-ir/` — resolved Target Stack IR (tagging standard,
|
||
public-ingress, encryption-by-default — ports of the v1.0/v1.8
|
||
imperative rules into declarative policies).
|
||
- `plan-json/` — `terraform show -json` output (plaintext secrets,
|
||
IAM wildcards, KMS references — ports of Checkov's `RULE_MAP`).
|
||
- `meta/` — policies over the merged PolicyCheckResult list itself
|
||
(e.g. `block-on-any-critical` — the single declarative source of
|
||
truth for "critical = block", with the existing
|
||
`confidence_signal.py` hard-override kept as defense-in-depth).
|
||
- **`run_platform.sh` Step 5 wiring** — Checkov/Wiz still run and emit
|
||
raw PCRs; `KyvernoJsonEngine.evaluate()` runs plan-JSON policies in
|
||
parallel; both PCR lists merge into the confidence signal's `policy`
|
||
input. No change to `core/confidence_signal.py` (it already consumes
|
||
`list[PolicyCheckResult]` engine-agnostically).
|
||
- **Regression-gate-as-policy** (P4 — quality improvement from the
|
||
IDEATE pass): the capability checks in
|
||
`core/regression_verify.py` (CAP-013, CAP-023, CAP-024) become
|
||
declarative kyverno-json policies over the capability-inventory JSON
|
||
frontmatter. Capability regression becomes an audit artifact, not
|
||
imperative Python.
|
||
- **`policy-engineer` persona** (custom, added in RESEARCH) — owns the
|
||
policy territory; declarative-policies constraint; kyverno-json +
|
||
JMESPath frameworks.
|
||
|
||
**Phase count:** 6 (P0 pre-execution + 4 execution + 1 final).
|
||
|
||
**Hard constraints:**
|
||
- DO NOT change `schemas/policy_check_result.schema.json` shape in a way
|
||
that breaks existing adapters — the contract is the moat. The
|
||
`engine` enum already includes `"kyverno"` and `"opa"`; v1.25 records
|
||
carry `engine: "kyverno"` (no new enum value — decision in CLARIFY).
|
||
- DO NOT remove Checkov or Wiz adapters — they remain as raw-finding
|
||
sources feeding into kyverno-json meta-policies.
|
||
- DO NOT remove the `confidence_signal.py` `PENALTY["critical"]: None`
|
||
hard-override — it stays as defense-in-depth behind the declarative
|
||
`block-on-any-critical` meta-policy (decision in CLARIFY).
|
||
- DO NOT change `core/confidence_signal.py`'s input contract — it
|
||
already consumes `list[PolicyCheckResult]`; v1.25 only changes *who
|
||
produces* that list, not *what* the list is.
|
||
- The platform must function with `kyverno-json` absent — `is_configured()`
|
||
returns false → `SKIPPED` records → confidence signal proceeds (no
|
||
hard dependency that breaks the "platform functions without AI /
|
||
deterministic scripts" tenet — kyverno-json is deterministic, not AI).
|
||
|
||
### Requirements
|
||
|
||
New requirements REQ-291..REQ-309 — see `REQUIREMENTS.md` §v1.25.
|
||
Summary: engine protocol + registry (REQ-291,292), kyverno-json engine
|
||
impl (REQ-293,294), contract policies (REQ-295,296), stack-IR policies
|
||
(REQ-297,298,299), plan-JSON policies + pipeline wiring (REQ-300,301,302),
|
||
meta-policies (REQ-303), regression-gate policies (REQ-304,305), docs +
|
||
adapter README (REQ-306,307), tests (REQ-308,309).
|
||
|
||
## v1.26 — Live Pilot Estate Activation (active)
|
||
|
||
> **Active milestone.** Feature milestone — the first real consumer
|
||
> estate (a stock exchange on a homegrown PoA blockchain, equities
|
||
> only) is activated against live AWS account `581513795199`, lifting
|
||
> D-096. Branch: `milestone/v1.26-pilot-activation`. Tags run on the
|
||
> **v1.25.x** patch line: `v1.25.0` (P0) → `v1.25.1..v1.25.4` (P1–P4)
|
||
> → `v1.25.5` (P5 final = milestone release).
|
||
>
|
||
> **Multi-project mode:** this milestone introduces a 2nd tracked
|
||
> project — `nova-blockchain-exchange` (Gitea repo
|
||
> `continuous-intelligence/nova-blockchain-exchange`, local clone
|
||
> `/root/nova-blockchain-exchange`). The platform repo (`acdl`) remains
|
||
> the platform source; the consumer repo owns the app code +
|
||
> `contract.yaml`. Both projects share the v1.26 milestone; `.ciagent/`
|
||
> paths are per-project (`.ciagent/acdl/` for platform files — note: the
|
||
> platform's existing flat `.ciagent/` files remain the primary set for
|
||
> v1.26; the consumer's files live in `.ciagent/nova-blockchain-exchange/`).
|
||
|
||
### Why
|
||
|
||
NORTH_STAR.md has three Post-Pilot targets (Touchless Resolution ≥99%,
|
||
Human Escalation <0.1%, AI Decision Accuracy ≥99.5%) whose measurement
|
||
*pipeline* is grounded but whose *denominator* is zero — no consumer
|
||
estate has ever run. v1.25 shipped the swappable policy engine; v1.26
|
||
ships the first real consumer. The D-096 deferral (live AWS
|
||
re-provisioning) is the single blocker; the pre-run (Workstream A)
|
||
re-created the state bucket + outbox table, so the platform components
|
||
exist. The milestone grounds the metrics (outcome backfill +
|
||
escalation reason), wires the env JSON to the real account, and runs
|
||
the pilot end-to-end.
|
||
|
||
### What the milestone delivers
|
||
|
||
- **Homegrown PoA blockchain** (`nova-blockchain-exchange` repo) —
|
||
append-only blocks, single validator (pilot), deterministic block
|
||
production, T+1 settlement finality = block commit. Equities only
|
||
(bonds/derivatives/options deferred).
|
||
- **Order-matching engine** — limit order book, price-time priority.
|
||
- **Settlement service** — T+1, idempotent, finality = block commit.
|
||
- **Consumer `contract.yaml`** — declares the exchange stack; validated
|
||
against `schemas/contract.schema.json`; per-env variants.
|
||
- **Consumer deploy via `deploy.yml@v1.25`** — the reusable workflow
|
||
applies the contract, runs the policy engine, computes the
|
||
confidence signal, gates qa/prod/dr with HITL attestation, and records
|
||
every decision in the Decision Ledger.
|
||
- **3 Post-Pilot metrics grounded** — outcome backfill (AI Decision
|
||
Accuracy), `reason='confidence'` escalation tag (Human Escalation
|
||
Frequency), and the pilot run itself (Touchless Resolution Rate
|
||
denominator activates).
|
||
- **3 kyverno-json policies extending v1.25** — settlement-finality
|
||
(securities-specific), pilot-readiness (no placeholder account),
|
||
and the existing meta-policies (block-on-any-critical,
|
||
tagging-rules-agree) apply over the pilot's PCRs.
|
||
- **Env-JSON `state_backend` wiring reconciliation** — the adapter
|
||
reads `state_backend.bucket` from the env JSON (closing the wiring
|
||
gap); the env JSONs are bound to account `581513795199`.
|
||
|
||
### Requirements
|
||
|
||
New requirements REQ-310..REQ-322 — see
|
||
`.ciagent/nova-blockchain-exchange/REQUIREMENTS.md` §v1.26. Summary:
|
||
blockchain core (REQ-310), order engine (REQ-311), settlement
|
||
(REQ-312), consumer contract (REQ-313), deploy invocation (REQ-314),
|
||
settlement-finality policy (REQ-315), pilot regression CAP (REQ-316),
|
||
outcome backfill (REQ-317), escalation reason (REQ-318), env-JSON
|
||
wiring (REQ-319), pilot-readiness policy (REQ-320), docs (REQ-321),
|
||
DynamoDB L1 primitive (REQ-322 — the single platform-side module
|
||
build-out; ECS + S3 already exist).
|
||
|
||
### Hard constraints
|
||
|
||
- DO NOT lift D-083 (S3 Object Lock/JWS) — stays deferred; the SQLite
|
||
hash-chain + DynamoDB outbox is the pilot's audit record.
|
||
- DO NOT lift D-126 (hot path) — cold-only metrics are sufficient for
|
||
the pilot.
|
||
- DO NOT add multi-cloud (Azure/GCP) — Nova is AWS-only this milestone.
|
||
- DO NOT add ML forecasting — the Predictive/Reactive metric stays
|
||
deferred.
|
||
- DO NOT add bonds/derivatives/options — equities only (D-200).
|
||
- DO NOT add multi-validator BFT — single validator PoA (D-201).
|
||
- The consumer deploy MUST go through `deploy.yml@v1.25` — no direct
|
||
`terraform apply` bypassing the platform's gates.
|