eb7634da28
v1.15-Nova rebrand doc verification (phase/05-final-review-ship) found stale ACDL references where the code/terraform already uses Nova names. Critical drift fixed (doc said old name; code uses new): - README.md: `.acdl/contract.yml` -> `.nova/contract.yml`; `acdl-spike-runner` -> `nova-spike-runner`; ABAC tag keys `acdl:owner|contract` -> `nova:owner|contract`. - docs/environments/index.md: `acdl-contract-ingestor` -> `nova-contract-ingestor`; `aws:PrincipalTag/acdl:owner` -> `nova:owner`; `acdl-contracts` -> `nova-contracts`. - docs/consumer-guide.md: `acdl-change-requests` -> `nova-change-requests`; state bucket example `acdl-qa-state` -> `nova-qa-state`. - docs/presentations/* (4 decks + 2 HTML + talking-points): `acdl:owner|contract| environment|cost-center` -> `nova:*`; `ACDL_LIFECYCLE_MODE` -> `NOVA_LIFECYCLE_MODE`. - pipelines/modules-lifecycle.yml comments: `ACDL_LIFECYCLE_MODE` -> `NOVA_LIFECYCLE_MODE` (workflows already use NOVA_; the contract comments were stale). - docs/NOVA_MIGRATION.md: status banner -> COMPLETE (P5 cutoff passed). - .ciagent/ARCHITECTURE.md: header `ACDL` -> `Nova`; NOVA_LIFECYCLE_MODE rename noted in the live lifecycle-mode section (v1.15 addendum already correct). - .ciagent/ROADMAP.md: v1.15 phase statuses P1-P4 pending -> complete (v1.15.1..v1.15.4); P5 -> in progress (phase/05-final-review-ship). Verification: - grep for `acdl:*` tag keys / `.acdl/contract` / `acdl-contract-ingestor` / `acdl-contracts` / `ACDL_LIFECYCLE_MODE` in README/docs/pipelines -> 0 hits (excluding explicitly-unchanged repo path `acdl/.github/...`, `continuous-intelligence/acdl`, and historical narrative). - core/output_publisher.py uses `/nova`; schemas/tagging-standard.json uses `nova:*`; terraform uses `nova-*` (0 `acdl-` in *.tf) — docs now match. - git tag v1.15.0..v1.15.4 exist. - pytest tests/test_lifecycle_mode_flag.py tests/test_pipeline_contract.py -> 111 passed. ---ci--- project: acdl
321 lines
14 KiB
Markdown
321 lines
14 KiB
Markdown
---
|
|
marp: true
|
|
theme: default
|
|
paginate: true
|
|
size: 16x9
|
|
header: "The Developer Experience"
|
|
footer: "Internal"
|
|
style: |
|
|
section {
|
|
font-family: "Akkurat Pro", "Helvetica Neue", "Arial", sans-serif;
|
|
font-size: 26px;
|
|
color: #1B1B1B;
|
|
}
|
|
h1 { color: #D6002A; font-size: 40px; margin-bottom: 0.3em; }
|
|
h2 { color: #D6002A; font-size: 32px; margin-bottom: 0.2em; }
|
|
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
|
|
section.title h1 { color: #fff; }
|
|
table { font-size: 22px; width: 100%; }
|
|
th { background: #F0F0F0; }
|
|
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 24px; }
|
|
pre { font-size: 16px; line-height: 1.3; }
|
|
code { font-size: 16px; }
|
|
img { display: block; margin: 0 auto; max-height: 280px; }
|
|
.badge {
|
|
display: inline-block; padding: 2px 8px; border-radius: 4px;
|
|
font-size: 16px; font-weight: 600;
|
|
}
|
|
.planned { background: #fef3c7; color: #78350f; }
|
|
---
|
|
|
|
<!-- _class: title -->
|
|
<!-- _paginate: false -->
|
|
|
|
# The Developer Experience
|
|
|
|
### Nova — The New Dawn of DevSecOps
|
|
|
|
<style>
|
|
section.title h1 { font-size: 44px; margin-bottom: 0.1em; }
|
|
section.title h3 { color: #F0F0F0; font-weight: 400; font-size: 22px; margin-top: 0; }
|
|
</style>
|
|
|
|
---
|
|
|
|
# Two consumer paths, one safety envelope
|
|
|
|

|
|
|
|
- **Technical developer** — owns app code + a contract + a thin CI definition
|
|
- **Citizen developer** — declares intent; an AI agent produces a contract that passes the **same** safety envelope
|
|
- **Upstream is anything** — IDE, agentic SDLC, or vibe coding. Nova doesn't care how the contract was produced
|
|
- **Nova is infrastructure only** — provisions and governs AWS resources. Application deployment is upstream
|
|
|
|
---
|
|
|
|
# The platform at a glance
|
|
|
|

|
|
|
|
- **You own the left edge** — app code and a contract. That is the entire consumer surface
|
|
- **The platform owns the middle** — pipeline, catalog, adapter, environments, gates, evidence
|
|
- **Two surfaces, one pipeline, one evidence stream** — senior engineer and citizen dev converge on the same safety envelope
|
|
- **The bar rises automatically** — confidence signal + HITL gates scale with the target environment, not a ticket
|
|
|
|
---
|
|
|
|
# Three things. The entire consumer surface.
|
|
|
|
<img src="assets/png/developer-experience-02-what-dev-does.png" style="float: right; width: 38%; margin-left: 20px; margin-bottom: 10px;" />
|
|
|
|
- **1. App code** — the consumer's service, at the top level of the repo
|
|
- **2. A contract** — a single YAML file: id, name, environment, infrastructure
|
|
|
|
```yaml
|
|
id: msvc
|
|
name: microservice
|
|
environment: dev
|
|
infrastructure:
|
|
microservice:
|
|
version: "1.0.0"
|
|
inputs:
|
|
cpu: 256
|
|
memory: 512
|
|
desired_count: 2
|
|
port: 8080
|
|
```
|
|
|
|
- **3. A one-line CI definition** — a thin `uses:` wrapper pointing at a versioned platform workflow
|
|
- The developer does **not**: write modules, clone the platform repo, hold cloud credentials, or maintain a state backend
|
|
|
|
---
|
|
|
|
# See what the platform does, in real time
|
|
|
|
- **Streamed output by default** — the plan, policy results, and each check record flow to stdout
|
|
- **PR comments after every successful pipeline stage** — always know where you stand
|
|
- **Clear, explainable halt reasons** — a policy violation, an insufficient signal, or a missing attestation. **Never opaque.**
|
|
- **Connection strings posted as PR comments** — human-readable, no hunting. Runtime secrets go to encrypted Parameter Store, never to logs
|
|
- **Errors become GitHub issues, automatically** — a failed deploy opens an issue on the platform repo
|
|
|
|
---
|
|
|
|
# Pick from pre-built, security-reviewed blocks
|
|
|
|

|
|
|
|
- **Primitives** — single-purpose resources (S3, VPC, ECS, IAM, ALB, ECR, CloudFront, WAF, RDS)
|
|
- **Modules** — composed patterns (static site with CDN + WAF; microservice with VPC + ECS + ALB + ECR)
|
|
- **Validated examples per module** — `simple.yaml` + `complex.yaml`, validated against the contract schema in CI
|
|
- **Auto-promotion of patterns** — after 3 observed usages <span class="badge planned">Planned</span>
|
|
|
|
---
|
|
|
|
# The bar rises automatically with sensitivity
|
|
|
|

|
|
|
|
| Environment | What the platform adds | Maturity |
|
|
|---|---|---|
|
|
| dev | Confidence ≥ 0.50, fully autonomous | — |
|
|
| qa | QA human attestation + confidence ≥ 0.75 | <span class="badge planned">Planned</span> |
|
|
| prod | SRE human attestation + confidence ≥ 0.90 | <span class="badge planned">Planned</span> |
|
|
| dr | SRE human attestation + confidence ≥ 0.95 + DR drill | <span class="badge planned">Planned</span> |
|
|
|
|
- **No staging environment** — dev is the only autonomous environment
|
|
- **Separation of duties** — the QA approver cannot be the prod approver
|
|
|
|
---
|
|
|
|
# Tearing down is as gated as deploying
|
|
|
|

|
|
|
|
<style>
|
|
section { font-size: 22px; }
|
|
pre { font-size: 13px; line-height: 1.2; }
|
|
code { font-size: 13px; }
|
|
</style>
|
|
|
|
```yaml
|
|
uses: acdl/.github/workflows/deploy.yml@v1.12
|
|
with:
|
|
contract: .nova/contract.yml
|
|
mode: decommission
|
|
changeRequestId: "CHG0678912"
|
|
```
|
|
|
|
- **Validate the change request** — platform queries the CMDB; CR must be `approved` and match the consumer repo
|
|
- **Two SRE human-attestation gates** — disable protection → SRE approves → zero counts + destroy → second SRE approves
|
|
- **Per-stack encryption key enters a grace window** (default 30 days) so encrypted data remains recoverable
|
|
|
|
---
|
|
|
|
# You control when you absorb improvements
|
|
|
|

|
|
|
|
- **Floating MAJOR + MINOR tags** (e.g. `@v1.12`) — automatically receive patch updates within the line
|
|
- **Semantic versioning with a clear contract:** interface → MAJOR, behavior → MINOR, lifecycle → PATCH
|
|
- **Pin to an exact version** for stability, or float on MAJOR only (`@v1`) to absorb new features on your own cadence
|
|
- **Unversioned references (`@main`, bare) are discouraged** — the versioned tag is the only immutability lever
|
|
- **Automated release job** computes the next semver on merge to main, creates the tag, and updates floating tags
|
|
|
|
---
|
|
|
|
# Fails gracefully, not opaquely
|
|
|
|
First impressions of a platform are made **when it fails for the first time.** The platform fails gracefully.
|
|
|
|
When no environment is bound, the platform emits a **user-friendly onboarding prompt** instead of failing opaquely:
|
|
|
|
1. That no environment is bound to their repo yet
|
|
2. What the platform will provision on their behalf (account, network, state, role)
|
|
3. The expected turnaround for the platform team to grant the environment
|
|
4. How to request an environment
|
|
|
|
The pipeline then **exits without attempting a deployment** — no partial state, no confusing errors.
|
|
|
|
<span class="badge planned">Citizen developer onboarding path: planned</span>
|
|
|
|
---
|
|
|
|
<!-- _class: title -->
|
|
<!-- _paginate: false -->
|
|
|
|
# The desired outcomes
|
|
|
|
- **Velocity without sacrificing safety** — speed in ergonomics, safety in unbypassable gates
|
|
- **Security, observability, compliance as platform defaults** — not per-team effort, not post-hoc remediation
|
|
- **Auditability as a byproduct, not a project** — every change traceable to a human attestation and a tamper-evident evidence event
|
|
- **Blast radius contained by design** — OIDC + ABAC, only your own tagged resources
|
|
- **The bottleneck moves off the platform team's ticket queue** — a merged change progresses without a platform engineer joining a thread
|
|
- **Infrastructure as a utility, not a craft** — consume, don't maintain
|
|
- **A path to the citizen developer** — same envelope, senior engineer or non-technical
|
|
|
|
---
|
|
|
|
<!-- _class: title -->
|
|
<!-- _paginate: false -->
|
|
|
|
# Appendix
|
|
|
|
**Contents:**
|
|
|
|
1. The Citizen Developer Experience (full)
|
|
2. No Platform Code, No Cloning (detail)
|
|
3. Local Reproducibility (detail)
|
|
4. The Road to the North Star (phased roadmap)
|
|
5. Glossary
|
|
6. Operating Model & Cost
|
|
7. Verified by Construction
|
|
|
|
---
|
|
|
|
# A1 — The Citizen Developer Experience
|
|
|
|
A non-technical consumer ships a production deployment **by declaring intent** — without authoring a workflow, a configuration file, or an infrastructure module.
|
|
|
|
- The consumer opens an issue describing what they need (e.g. "a web API for the pricing service")
|
|
- An AI agent maps the intent to a contract referencing a module from the **reviewed skill catalog**
|
|
- The contract enters the **same pipeline** and must clear the **same confidence gate** before promotion
|
|
|
|
**Guardrails that make this safe:**
|
|
|
|
- Skills are **versioned, signed, and reviewed for sensitive data before release** (Infra & Ops owns the review)
|
|
- Agents are **stateless** — all state lives in the platform; the platform trusts and **always verifies**
|
|
- The agent's trace and submission confidence are captured in the contract for review
|
|
|
|
<span class="badge planned">Skill catalog + real agent runtime: planned</span>
|
|
|
|
---
|
|
|
|
# A2 — No Platform Code, No Cloning
|
|
|
|
Consumers `uses:` a **versioned** central workflow. The platform fetches itself at run time. The consumer **never touches platform internals.**
|
|
|
|

|
|
|
|
- The consumer's CI definition is a thin wrapper — one `uses:` line
|
|
- The runner checks out the consumer repo, then checks out the platform repo into the workspace
|
|
- The platform installs its own runtime dependencies — the consumer installs nothing
|
|
- When the platform ships a fix, every consumer on a floating tag gets it on their next run
|
|
|
|
---
|
|
|
|
# A3 — Local Reproducibility
|
|
|
|
The entire CI pipeline runs **from the shell**, not just in CI.
|
|
|
|
- `scripts/run_ci.sh` mirrors the CI pipeline locally — the same three stages (lint → test → check-only) in sequence
|
|
- `scripts/run_platform.sh --check-only` runs the platform **offline** — no AWS, no policy engine, no outbox required. Validates a contract end-to-end before pushing
|
|
- `--plan-only` runs through the infrastructure plan without applying
|
|
- The CI and deploy pipelines are defined by **declarative contracts** (YAML instances validated against JSON Schemas) — a single source of truth that both workflows implement
|
|
|
|
---
|
|
|
|
<!-- _class: title -->
|
|
<!-- _paginate: false -->
|
|
|
|
# A4 — The Road to the North Star
|
|
|
|
*Proposed phasing — not formally planned.*
|
|
|
|

|
|
|
|
---
|
|
|
|
# A5 — Glossary
|
|
|
|
| Term | Meaning |
|
|
|---|---|
|
|
| **OIDC** | OpenID Connect — federation protocol for short-lived tokens, no long-lived credentials |
|
|
| **ABAC** | Attribute-Based Access Control — access scoped by resource tags + repo identity, not roles |
|
|
| **CMK** | Customer-Managed Key — per-stack encryption key, 90-day rotation, no shared keys |
|
|
| **CMDB** | Configuration Management Database — validates change requests for decommission |
|
|
| **RPO** | Recovery Point Objective — RPO = 0 means evidence is written synchronously, no data loss |
|
|
| **HITL** | Human-in-the-Loop — deliberate human attestation required for qa/prod/dr environments |
|
|
| **VCS** | Version Control System — the git hosting platform (GitHub, Gitea, GitLab) |
|
|
| **NFR** | Non-Functional Requirement — encryption, tagging, observability standards |
|
|
|
|
---
|
|
|
|
# A6 — Operating Model & Cost
|
|
|
|
<style>
|
|
section { font-size: 20px; }
|
|
table { font-size: 18px; }
|
|
</style>
|
|
|
|
Nova runs at **zero cloud cost** for day-to-day development. AWS spend was measured via Cost Explorer (`COST.md`, 2026-07-28):
|
|
|
|
| Metric | Value |
|
|
|--------|-------|
|
|
| Total spend (8 days) | **$0.001883** |
|
|
| Daily average | $0.000235 |
|
|
| Projected monthly | ~$0.007 |
|
|
| Peak day | 2026-07-27 ($0.000867) |
|
|
|
|
- **Local emulators are the primary tier** — the full pipeline runs in-process, no AWS credentials
|
|
- **Live-AWS verification is milestone-scoped, then torn down.** The pipeline now **defaults to plan-only** on every PR; `NOVA_LIFECYCLE_MODE=full` overrides to apply→destroy for milestone verification (REQ-134, v1.12).
|
|
- **Cost drivers** are spike-scoped: Terraform plan reads (free), S3 state storage (cents), DynamoDB outbox (cents). No running infrastructure between milestones.
|
|
|
|
**Pre-mortem (`PRE_MORTEM.md`):** the v1.10 decay incident (diff-scoped VERIFY missed 7 adapter defects) is the root pattern: *a claim outruns the verification that backs it.* Four forward failure modes + structural mitigations (regression-tested IAM baseline, mandatory teardown, verified-only deck claims, honest scope).
|
|
|
|
---
|
|
|
|
<!-- _class: title -->
|
|
<!-- _paginate: false -->
|
|
|
|
# A7 — Verified by Construction
|
|
|
|
<style>
|
|
section { font-size: 20px; }
|
|
</style>
|
|
|
|
Two architectural pillars make "Verified" a structural property, not a claim:
|
|
|
|
- **The stateless adapter (918 → ~80 lines).** The Terraform adapter was a 918-line monolith with 3 constant tables and 39 type-specific branches. It is now a ~80-line **stateless assembler**: it owns no module content — no resource shape, no nested HCL blocks, no defaults. Each L1 module ships a real `terraform/` module dir owning its shape, nested blocks, and defaults. The adapter reads the registry and emits `module "x" { source = ... }` blocks. A new module is a new terraform dir, not a code change. *(The v1.12 P67 fix closed a dedup defect for multi-resource L1s — ecs-service, alb; CAP-013 now Verified.)*
|
|
- **Pipeline-driven lifecycle testing.** A `modules-lifecycle` pipeline matrix-runs each L1 and L2 module's contracts through apply→modify→destroy against live AWS. **The "test" = the pipeline cell going green.** Defaults to **plan-only** on every PR (fast, no AWS mutation, no cost); `NOVA_LIFECYCLE_MODE=full` overrides to the real apply→destroy for milestone verification (REQ-134, v1.12). The regression gate (D-091) re-runs all 22 capabilities at milestone completion — **22/22 Verified** as of v1.12.
|
|
|
|
The v1.10 lesson is the negative space: a 918-line adapter with type-specific branches decayed silently. The ~80-line stateless adapter + the milestone regression gate are the structural fix. |