Diagrams now show relationships + stack positioning, not just restating slide text: - slide 1: the widening gap (velocity vs coordination surface) → Nova absorbs - slide 2: Nova's position in the stack (SDLC/PDLC → contract → Nova → prod) - slide 3: inheritance tree (two tenets → 6 architectural elements they shape) - slide 4: confidence-threshold ladder (dev 0.50 → qa 0.75 → prod 0.90 → dr 0.95 + escalation) - slide 5: stack layers with the contract as the dividing line (above/below) - slide 6: the arc with what each milestone unlocks + the constant contract surface - slide 7: proven foundation → runway arc → ask → structural risk if not Fixed: slide 4 node/subgraph naming collision (DR → DRENV); slides 2 + 5 reworked to horizontal layout (were too tall for slides). ---ci--- project: acdl phase: 5 milestone: v1.30 status: execute ---/ci---
Nova
Nova — The New Dawn of DevSecOps. Security as a seamless enabler of fast deployments — not a bottleneck, not a "no" department.
Consumers declare intent; the platform delivers safe production deployment through an agentic stack — automatically, safely, and with a complete audit trail. A merged change progresses through lower environments end-to-end without a platform engineer joining a thread; a non-technical consumer ships a production deployment by declaring intent, without authoring a workflow, a configuration file, or an infrastructure module.
- Consumer guide:
docs/consumer-guide.md - Modules:
docs/modules/ - Contracts:
docs/contracts/ - Pipeline:
docs/pipeline/ - Versioning:
docs/pipeline/versioning.md - Environments:
docs/environments/ - Architecture:
docs/architecture.md - Vision:
docs/vision.md
Repository roles
There are two kinds of repository in the Nova model:
-
Platform repo (this one). This is the source code of the platform. It owns
modules/,adapters/,core/,schemas/,pipelines/,scripts/, and the reusable workflow files. Platform engineers work here. A consumer never clones it. -
Consumer repo (yours). A consumer repo contains only:
- Its application code — the service or site being deployed.
- One or more contracts — small YAML files at
.nova/contract.ymlthat declare infrastructure (one or more modules by name + version), select an environment, and supply module-specific inputs. - One or more CI definitions — thin
.github/workflows/*.ymlfiles thatuses:the central reusable deploy workflow, pointing at the appropriate environment + contract.
The consumer does not write infrastructure modules, workflow YAML beyond the thin
uses:wrapper, or adapter code — they write a contract YAML file and the platform does the rest.
The rest of this README describes the platform repo (how the platform works, how to run it locally, how it's laid out). If you are a consumer, jump to the Consumer guide.
Features
A referenceable list of what the platform provides today, for consumers and platform engineers alike:
- Contract-driven deploys — a consumer writes a YAML contract; the platform resolves it to a stack, compiles it, and deploys it.
- Reusable versioned deploy workflow — consumer repos
uses:a versioned central workflow; no platform code is cloned by the consumer. - Module catalog — primitives (single resources) and modules (patterns of primitives) with self-documented inputs/outputs. See docs/modules/.
- Zero-trust credentials — OIDC federation + attribute-based authorization (ABAC) by default; no long-lived keys in consumer repos.
- Security + policy checks — a security-check stage and a policy-check stage run before any infrastructure is created.
- Confidence signal — a computed, explainable score gates promotion.
- Evidence outbox — every deployment writes a hash-chained evidence event to an audit outbox.
- Shell reproducibility —
scripts/run_ci.shmirrors the CI pipeline locally;scripts/run_platform.sh --check-onlyruns offline. - Platform-managed environments — consumers provide no AWS account, VPC, subnet, or state bucket; the platform manages environments. See docs/environments/.
- Central pipeline contract — a declarative YAML instance is the single source of truth for both the CI and deploy workflows.
Roadmap
Planned future features (no dates; tracked in the internal roadmap):
- Dynamic module creation from a contract — an agentic flow where a consumer creates a module directly from the contract file (the "composition" mechanism, redesigned).
- Compliance milestone — per-module compliance extension points (GDPR, SOX, SOC2, DORA) wired into the pipeline.
- Additional engine adapters — beyond the Terraform adapter.
- Environment self-service — a consumer-facing flow to request and provision a new platform-managed environment (today it is a platform-team action).
- HITL gates for qa / prod / dr — human attestation + higher confidence thresholds for higher environments.
- OIDC for all platform runners — zero-trust credentials everywhere.
How the platform works
The platform is four layers + six cross-cutting concerns, bound by the vision's "Two Consumer Surfaces, One Platform" tenet: consumers declare intent via a contract; the platform delivers the deployment through the same contract schema, the same policy envelope, and the same evidence stream.
Consumers have their own repos and consume Nova by writing a contract that declares infrastructure. A consumer declares a contract (id + name + environment + infrastructure); the platform resolves it to a stack instance, compiles it, runs security + policy checks, computes a confidence signal, writes an evidence event to the audit outbox, and applies the infrastructure.
The platform flow (end-to-end)
flowchart TD
A["consumer contract<br/>(id + name + environment + infrastructure)"] --> B
B["schema validation<br/>(contract schema)"] --> C
C["resolve to Target Stack<br/>(contract resolver)"] --> D
D["security checks<br/>(adapter)"] --> E
E["infrastructure plan<br/>(adapter compiles the stack)"] --> F
F["policy checks<br/>(adapter -> PolicyCheckResult records)"] --> G
G["confidence signal<br/>(6 inputs: policy, validation,<br/>freshness, source, history, NFRs)"] --> H
H["evidence event<br/>(hash-chained, to the audit outbox)"] --> I
I["infrastructure apply<br/>(dev only, autonomous)"]
The platform validates the architecture's claim that the stack
commitments do not require a polyglot mess: the adapter is the only
engine-specific code. modules/, schemas/, contracts/,
core/confidence_signal.py, core/contract_resolver.py, and
core/outbox_writer.py are all engine-agnostic (no aws_s3_bucket /
aws_ infrastructure terms).
How to run
Quick start (offline, no AWS required)
The fastest way to verify the platform works — no AWS credentials, no bootstrap, no cost. See the Consumer guide for the consumer happy path (a consumer owns only a contract + app code).
# Install test dependencies
pip install -r requirements-test.txt
# 1. Run the test suite (all offline — uses moto for DynamoDB mocking)
python3 -m pytest tests/ -v
# 2. Run the platform in check-only mode (offline — contract -> resolver ->
# adapter -> structure validation). Uses the default sample contract
# (contracts/static-assets.yaml) + sample dev environment.
bash scripts/run_platform.sh --check-only
# Expected: "=== PLATFORM CHECK OK ==="
# 3. Run the headline E2E against the local emulating tier (emulates ECS,
# outbox, S3 state, Lambda in-process; D-092).
bash scripts/run_platform.sh --local
# Expected: "=== LOCAL E2E OK ==="
# 4. Reproduce the full CI pipeline locally (lint -> test -> check-only)
bash scripts/run_ci.sh
# Expected: "=== CI PIPELINE OK ==="
# Show all run_platform.sh flags:
bash scripts/run_platform.sh --help
Run against live AWS (requires credentials + bootstrap)
Prerequisites: a platform-managed environment (see docs/environments/;
core/environments/dev.jsonis the sample), AWS credentials for dev (in.env.secrets, gitignored; see Credentials & zero-trust),terraform(pin1.9.*),checkov(pin>=3.2,<4),python3+boto3+jsonschema.
# 1. Bootstrap the AWS state backend + runner IAM user (one-time, idempotent)
# (requires the bootstrap root key in env — skip if the state bucket +
# nova-spike-runner already exist)
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
python3 terraform/bootstrap/create_state_backend.py
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
python3 terraform/bootstrap/create_iam_user.py # prints the initial key
# 2. Rotate the runner key (writes .env.secrets, gitignored)
ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID=... ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY=... \
bash scripts/rotate_spike_key.sh
# 3. Run the full platform pipeline (contract -> environment check -> stack ->
# adapter -> security checks -> infrastructure plan -> policy checks ->
# confidence -> evidence event -> apply). Output is streamed to stdout.
bash scripts/run_platform.sh contracts/static-assets.yml
# Expected: "=== PLATFORM E2E OK ==="
# Or plan-only (contract -> stack -> adapter -> infrastructure plan; no
# policy checks / outbox):
bash scripts/run_platform.sh --plan-only contracts/static-assets.yaml
# Add --quiet to suppress streaming (output to log files only):
bash scripts/run_platform.sh --quiet contracts/static-assets.yaml
CI/CD pipelines
The CI/CD pipeline is defined by a central pipeline contract — a
declarative YAML instance (pipelines/ci.yml) validated against a JSON
Schema (schemas/pipeline.schema.json). Both platform-runner workflows
implement the same contract:
.github/workflows/ci.yml— GitHub Actions (production)
Both run three stages: lint (py_compile), test (pytest), and
check-only (run_platform.sh --check-only). Both trigger on push to
main and on pull requests. A test (tests/test_pipeline_contract.py)
validates that the workflow conforms to the contract.
scripts/run_ci.sh mirrors the CI pipeline locally — running the same
three stages in sequence. This makes the pipeline fully reproducible from
the shell, not just in CI:
bash scripts/run_ci.sh # run all 3 stages (lint, test, check-only)
bash scripts/run_ci.sh --quiet # suppress per-stage banners
Reusable deploy workflow
Consumer repos invoke the deploy pipeline via .github/workflows/deploy.yml
(a reusable GitHub Actions workflow, versioned tag nova/.github/workflows/deploy.yml@v1.19).
See the Consumer guide for the end-to-end happy path.
Output streaming (run_platform.sh)
scripts/run_platform.sh streams output by default so the user can see
what the platform is doing:
--check-only: streams the emitted infrastructure file content to stdout.--plan-onlyand full mode: streams the infrastructure plan output viatee(visible and logged).- Full mode: prints policy-check results and each
PolicyCheckResultrecord with severity, rule ID, and pass/fail status.
A --quiet flag suppresses streaming (output to log files only) for
backwards-compatible log-only mode.
Consumer guide
A step-by-step guide for a consumer to create their pipeline and define a
contract that deploys any Nova module to AWS is at
docs/consumer-guide.md. The guide is generic
across all modules; static-assets is the worked example.
Repository layout
| Path | Purpose | Status |
|---|---|---|
core/ |
Platform code: contract resolver, confidence signal, outbox writer, environment check, environments, separation of duties, HITL/ledger designs | active |
schemas/ |
JSON Schemas: stack, contract, PolicyCheckResult, pipeline contract, deploy pipeline contract (draft 2020-12) | active |
pipelines/ |
Central pipeline contracts: ci.yml (CI), contract.yml (deployment) |
active |
adapters/ |
Angine adapters — the engine adapter (the only engine-specific code per §12) + the policy adapter | active |
terraform/ |
State backend (S3 + DynamoDB) + platform TF (terraform/spike/) + bootstrap scripts (terraform/bootstrap/) |
active |
modules/ |
Primitives + modules + registry.json. Primitives: s3, vpc, ecs-cluster, ecs-service, iam-role, alb, ecr, cloudfront, waf, rds. Modules: microservice, static-assets. Each module has a examples/ directory with validated contract examples |
active |
contracts/ |
Sample consumer contracts (static-assets.yaml, microservice.yaml) |
active |
scripts/ |
Platform run script (run_platform.sh with --check-only/--plan-only/--quiet), CI pipeline script (run_ci.sh), key rotation |
active |
tests/ |
Pytest suite (all offline — adapter, confidence signal, policy adapter, outbox writer, pipeline contract, contract resolver, streaming, environment check) | active |
.github/workflows/ |
GitHub Actions workflows: ci.yml (CI), deploy.yml (reusable deploy, invoked by consumer repos) |
active |
docs/ |
GitHub Pages documentation site: consumer guide, modules, contracts, pipeline, versioning, environments, architecture, vision | active |
Credentials & zero-trust
Default — zero-trust OIDC + attribute-based authorization
Consumer repos are zero-trust: they hold no long-lived AWS keys and no static credentials in repo secrets.
-
Authentication is OIDC federation between the platform runners (GitHub Actions) and AWS. Each job mints a short-lived STS token; no credential is ever stored in the consumer repo or in a runner secret.
-
Authorization is attribute-based (ABAC), not role-based (RBAC). AWS IAM roles and session policies are scoped by two attribute classes:
- Repository identity — the runner claim (e.g.
repo:org/consumer-repo:ref:refs/heads/main) binds the role's trust policy to the exact consumer repo + branch that invoked the workflow. - Resource-creation attributes — every resource the pipeline creates
is tagged with
nova:owner=<consumer-repo>andnova:contract=<contract-id>. The session policy grants view/update/delete only on resources whose tags match the calling repo.
The effect: a consumer's pipeline can only view and update the resources it created. Blast radius is contained to that consumer's own stack instances — one consumer can never touch another consumer's resources, and the consumer cannot escape its own scope.
- Repository identity — the runner claim (e.g.
Alternative — static AWS key
Where OIDC is not yet available, a static AWS key may be used as a documented alternative:
- The key is stored in GitHub Secrets (consumer repo) for platform-runner
runs, or in
.env.secrets(gitignored, chmod 600) for local testing. - The platform rotates platform-runner keys on a daily cadence — rotation is not the consumer's burden in the platform-runner path. No long-lived credential is permitted persistently — the platform-runner key's useful lifetime is one workflow run, and the local alternative is rotated at least daily (platform-runner) or out of band (local).