Compare commits

...

4 Commits

Author SHA1 Message Date
Jon Chery 6ffcbe8283 Merge phase/03-submission-readiness — v1.17.3 (v1.18 P3 submission-readiness complete) 2026-08-06 15:09:32 +00:00
Jon Chery 5775a97388 feat(P3): submission-readiness input contract — schema + validator + docs + tests (REQ-217..220)
REQ-217: schemas/submission-readiness.schema.json (JSON Schema draft 2020-12)
defines acceptable-to-start as a superset gate above contract.schema.json:
contractId, environment, tags (5 Nova tags D-054), policyPreconditions,
profile (developer|agentic), appSource (repo+ref), per-env mandatory (W3.E:
qa→e2eSuite+loadTest, prod→runbook+dashboard+oncall, dr→drDrillRef),
agentic markers (naturalLanguageIntent+confidenceAtSubmission+agentTrace).

REQ-218: core/submission_readiness.py validator with check_readiness() +
ReadinessResult (structured pass/fail + reason codes). Wired as
contract_ingestor.py --check-readiness (D-133). Reason codes: MISSING_TAGS,
ENV_MISSING_MANDATORY, AGENTIC_MISSING_INTENT, MISSING_APP_SOURCE,
POLICY_PRECONDITION_MISSING. Never raises — all failures are reason codes.

REQ-219: docs/submission-readiness.md (good + rejected examples +
reason-code catalog + compliance-standard equivalence).

REQ-220: tests/test_submission_readiness.py — 16 tests, all pass.
Covers: good-pass, good-agentic-pass, missing-tags, empty-tag,
qa-missing-e2e, prod-missing-runbook, dr-missing-drdrill, prod-all-pass,
agentic-missing-all, agentic-missing-one, missing-appsource,
appsource-missing-ref, empty-policy, result-structure.

---ci---
project: acdl
phase: 3
milestone: v1.18
status: execute
requirements:
  covered: [REQ-217, REQ-218, REQ-219, REQ-220]
  partial: []
---/ci---
2026-08-06 15:09:29 +00:00
Jon Chery b3c75ccec1 Merge phase/02-pdlc-scope-raci — v1.17.2 (v1.18 P2 PDLC scope + RACI complete) 2026-08-06 15:07:14 +00:00
Jon Chery e891496163 docs(P2): PDLC-upstream scope + RACI matrix + 2 deck slides (REQ-215, REQ-216, REQ-228)
REQ-215: RACI matrix in PROJECT.md (§ RACI Matrix) + docs/raci.md
(citizen-dev-facing copy). 3 roles (Citizen Developer / Platform / Release
Management co-owned). 7 work categories × R/A/C/I. Compliance-standard
equivalence note: any upstream source (AI agent, SDLC, dev platform) is
subject to the same gate.

REQ-216: PDLC-upstream scope in PROJECT.md (§ Scope) + docs/scope.md.
Promotes Core Tenet #2 + Anti-Goal #1 from buried tenets to a dedicated,
unmissable scope statement.

REQ-228: 2 new deck slides (17 Scope + 18 RACI) → 20 slides. Arc preview
updated. Talking points synced. HTML + PPTX re-rendered (21 PPTX slides).

---ci---
project: acdl
phase: 2
milestone: v1.18
status: execute
requirements:
  covered: [REQ-215, REQ-216, REQ-228]
  partial: []
---/ci---
2026-08-06 15:07:10 +00:00
12 changed files with 1134 additions and 23 deletions
+97
View File
@@ -58,6 +58,103 @@ traceable to a human attestation and an immutable evidence stream.
boundary. The platform validates, enriches with operational standards, boundary. The platform validates, enriches with operational standards,
and reconciles the target state. 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 penetrates 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) ## Capability Status (Re-Verified 2026-07-27)
> Source of truth: `.ciagent/CAPABILITY_INVENTORY.md` (Phase 54, D-093). > Source of truth: `.ciagent/CAPABILITY_INVENTORY.md` (Phase 54, D-093).
+20 -1
View File
@@ -499,4 +499,23 @@ def lambda_handler(event, context):
return {"statusCode": 401, "body": json.dumps({"error": str(e)})} return {"statusCode": 401, "body": json.dumps({"error": str(e)})}
return {"statusCode": 400, "body": json.dumps({"error": str(e)})} return {"statusCode": 400, "body": json.dumps({"error": str(e)})}
except Exception as e: # pragma: no cover - defensive top-level guard except Exception as e: # pragma: no cover - defensive top-level guard
return {"statusCode": 500, "body": json.dumps({"error": str(e)})} return {"statusCode": 500, "body": json.dumps({"error": str(e)})}
# --- CLI: --check-readiness (D-133, REQ-218) ---------------------------
# Invoked as: python3 -m core.lambda.contract_ingestor --check-readiness <submission.json>
# Delegates to core.submission_readiness.check_readiness() and prints the
# structured ReadinessResult. Exits 0 if ready, 1 if not.
if __name__ == "__main__": # pragma: no cover - CLI entry
import sys
if "--check-readiness" in sys.argv:
sys.path.insert(
0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
)
from core.submission_readiness import cli_main
# Strip the --check-readiness flag; pass the file path.
rest = [a for a in sys.argv[1:] if a != "--check-readiness"]
sys.exit(cli_main(["check-readiness"] + rest))
else:
print("Usage: python3 -m core.lambda.contract_ingestor --check-readiness <submission.json>")
+193
View File
@@ -0,0 +1,193 @@
"""core/submission_readiness.py — Nova submission-readiness validator (REQ-218).
Defines what is acceptable to start — a superset gate ABOVE
contract.schema.json validity. Invoked as
``contract_ingestor.py --check-readiness`` (D-133). Returns a structured
ReadinessResult (pass/fail per check, with reason codes). On fail → the
ingestor rejects with a citizen-developer-facing error (not a stack
trace). On pass → proceeds to existing contract ingestion.
The validator calls contract.schema.json validation first (the shape),
then the readiness checks (the gate): tags, env mandatory, policy
preconditions, profile:agentic markers, appSource.
Reason codes:
MISSING_TAGS — one or more required Nova tags are absent
ENV_MISSING_MANDATORY:<env>:<field> — a per-env mandatory field is missing
AGENTIC_MISSING_INTENT — profile=agentic but naturalLanguageIntent absent
MISSING_APP_SOURCE — appSource (repo + ref) is missing
POLICY_PRECONDITION_MISSING — a declared policy precondition is absent
"""
from __future__ import annotations
import json
import os
import sys
from dataclasses import dataclass, field
from typing import Any
_SCHEMA_DIR = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "schemas"
)
REQUIRED_TAGS = [
"nova:owner",
"nova:contract",
"nova:environment",
"nova:cost-center",
"nova:ref",
]
ENV_MANDATORY: dict[str, list[str]] = {
"dev": [], # dev requires only the base contract shape (id+environment+infrastructure)
"qa": ["validation.e2eSuite", "validation.loadTest"],
"prod": ["runbook", "dashboard", "oncall"],
"dr": ["drDrillRef"],
}
AGENTIC_REQUIRED = ["naturalLanguageIntent", "confidenceAtSubmission", "agentTrace"]
@dataclass
class ReadinessResult:
"""Structured result of the submission-readiness gate."""
ready: bool
reason_codes: list[str] = field(default_factory=list)
contract_id: str | None = None
def to_dict(self) -> dict[str, Any]:
return {
"ready": self.ready,
"reason_codes": self.reason_codes,
"contractId": self.contract_id,
}
def __str__(self) -> str:
if self.ready:
return f"READY — contract {self.contract_id} passes submission-readiness gate"
codes = "; ".join(self.reason_codes) if self.reason_codes else "unknown"
return f"NOT READY — contract {self.contract_id}: {codes}"
def _validate_contract_schema(contract: dict[str, Any]) -> list[str]:
"""Validate the contract against contract.schema.json (the shape).
Returns a list of reason codes (empty if valid). Falls back to no-op
if jsonschema or the schema file is unavailable (the contract is
validated upstream by run_platform.sh in the normal path).
"""
codes: list[str] = []
try:
import jsonschema
schema_path = os.path.join(_SCHEMA_DIR, "contract.schema.json")
with open(schema_path) as f:
schema = json.load(f)
jsonschema.validate(instance=contract, schema=schema)
except (OSError, ImportError):
pass
except jsonschema.ValidationError as e:
codes.append(f"CONTRACT_SCHEMA_INVALID:{e.message}")
return codes
def _get_nested(data: dict[str, Any], dotted_key: str) -> Any:
parts = dotted_key.split(".")
val: Any = data
for p in parts:
if not isinstance(val, dict) or p not in val:
return None
val = val[p]
return val
def check_readiness(submission: dict[str, Any]) -> ReadinessResult:
"""Run the full submission-readiness gate.
1. Validate the contract shape (contract.schema.json).
2. Validate the readiness schema (submission-readiness.schema.json).
3. Run the semantic readiness checks (tags, env mandatory, agentic, appSource, policy).
Returns a ReadinessResult. Never raises — all failures are reason codes.
"""
contract_id = submission.get("contractId") or submission.get("id", "unknown")
codes: list[str] = []
# Step 1: contract shape validation
contract_shape = {k: v for k, v in submission.items() if k in ("id", "name", "environment", "infrastructure")}
if contract_shape:
codes.extend(_validate_contract_schema(contract_shape))
# Step 2: readiness schema validation
try:
import jsonschema
schema_path = os.path.join(_SCHEMA_DIR, "submission-readiness.schema.json")
with open(schema_path) as f:
readiness_schema = json.load(f)
jsonschema.validate(instance=submission, schema=readiness_schema)
except (OSError, ImportError):
pass
except jsonschema.ValidationError as e:
codes.append(f"READINESS_SCHEMA_INVALID:{e.message}")
# Step 3: semantic checks (reason codes for citizen-developer-facing errors)
# 3a: tags
tags = submission.get("tags", {})
missing_tags = [t for t in REQUIRED_TAGS if t not in tags or not tags[t]]
if missing_tags:
codes.append(f"MISSING_TAGS:{','.join(missing_tags)}")
# 3b: env mandatory (W3.E per-env table)
env = submission.get("environment")
if env and env in ENV_MANDATORY:
for field_key in ENV_MANDATORY[env]:
val = _get_nested(submission, field_key)
if val is None:
codes.append(f"ENV_MISSING_MANDATORY:{env}:{field_key}")
# 3c: agentic profile markers
if submission.get("profile") == "agentic":
for marker in AGENTIC_REQUIRED:
if not submission.get(marker):
codes.append(f"AGENTIC_MISSING_INTENT:{marker}")
# 3d: appSource
app_source = submission.get("appSource")
if not app_source or not app_source.get("repo") or not app_source.get("ref"):
codes.append("MISSING_APP_SOURCE")
# 3e: policy preconditions (warn if declared but not enforced this milestone)
policy = submission.get("policyPreconditions", {})
if not policy:
codes.append("POLICY_PRECONDITION_MISSING")
ready = len(codes) == 0
return ReadinessResult(ready=ready, reason_codes=codes, contract_id=contract_id)
def cli_main(argv: list[str]) -> int:
"""CLI entry: python3 -m core.submission_readiness <contract.json>
Also invoked via contract_ingestor.py --check-readiness (D-133).
Prints the ReadinessResult to stdout; exits 0 if ready, 1 if not.
"""
if len(argv) < 2:
print("Usage: submission_readiness <contract.json>", file=sys.stderr)
return 2
path = argv[1]
try:
with open(path) as f:
submission = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: cannot read {path}: {e}", file=sys.stderr)
return 2
result = check_readiness(submission)
print(result)
print(json.dumps(result.to_dict(), indent=2))
return 0 if result.ready else 1
if __name__ == "__main__":
sys.exit(cli_main(sys.argv))
@@ -34,7 +34,7 @@ style: |
**Shifting from Operational Overhead to Strategic Value** **Shifting from Operational Overhead to Strategic Value**
v1.17Strategic Direction, Leadership Metrics & Unified Story v1.18Citizen Developer & Production-Grade Guidance
--- ---
@@ -49,7 +49,7 @@ v1.17 — Strategic Direction, Leadership Metrics & Unified Story
2. **Vision** — Nova's strategic direction (NORTH_STAR) 2. **Vision** — Nova's strategic direction (NORTH_STAR)
3. **How** — the pipeline, Decision Ledger, attestation gates 3. **How** — the pipeline, Decision Ledger, attestation gates
4. **Proof** — grounded metrics that make the claim defensible 4. **Proof** — grounded metrics that make the claim defensible
5. **Roadmap** — deferred metrics with unblock paths + the ask 5. **Roadmap** — deferred metrics with unblock paths + the ask + scope + RACI
**Benefit:** you leave knowing which claims are proven today, which are pipeline-ready, and which are deferred with a documented unblock path — no marketing, just grounded evidence. **Benefit:** you leave knowing which claims are proven today, which are pipeline-ready, and which are deferred with a documented unblock path — no marketing, just grounded evidence.
@@ -301,6 +301,42 @@ From `docs/METRICS_DEFERRED_ROADMAP.md`.
--- ---
## Slide 17 — Scope: Downstream of PDLC
**Nova governs infrastructure + delivery. The PDLC (product backlog, code authorship, IDE) is upstream — Nova never penetrates it.**
- **The PDLC is upstream:** product backlog, code authorship (AI agent / IDE / agentic SDLC), sprint planning, application business logic
- **Nova is downstream:** contract ingestion → submission-readiness gate → policy → cloud lifecycle → environment progression → audit + attestation
- **Integration is only through the contract boundary:** the citizen developer's AI coding agent, an upstream agentic SDLC, or any dev platform may all produce submissions — the source does not matter as all are subject to the same compliance standards
- Nova validates the submission, not the author
- Cites `docs/scope.md` + `PROJECT.md` § Scope
**Benefit:** you now know the scope boundary — Nova is purpose-built for infrastructure operations, not product development; integration is through one validated contract.
---
## Slide 18 — RACI: Who Owns What
**Three roles, one matrix — the citizen developer owns FRs + UAT, the platform owns NFRs + infra + QA + prod deploy, release management is co-owned.**
| Work Category | Citizen Dev | Platform | Release Mgmt |
|---|---|---|---|
| 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) | C | **R/A** | I |
| Production deployment to cloud | I | **R/A** | C |
| Release attestation (QA + SRE) | **A** | R | **R** |
- **Compliance-standard equivalence:** FRs + UAT may come from any upstream source (AI agent, agentic SDLC, dev platform) — all pass the same submission-readiness gate
- **Release co-ownership:** the platform runs the attestations agentically; the citizen developer oversees and triggers the actual release (human at the stage gate)
- Cites `docs/raci.md` + `PROJECT.md` § RACI Matrix
**Benefit:** you now know exactly what you bring (FRs + UAT), what Nova provides (NFRs + infra + QA + prod deploy), and what you co-own (the release attestation).
---
<!-- _class: title --> <!-- _class: title -->
<!-- _paginate: false --> <!-- _paginate: false -->
@@ -103,6 +103,20 @@
- "Pipeline-ready" → "production-proven" is the value proposition - "Pipeline-ready" → "production-proven" is the value proposition
- **Key takeaway:** approve a pilot + the ledger build-out to move from pipeline-ready to production-proven - **Key takeaway:** approve a pilot + the ledger build-out to move from pipeline-ready to production-proven
### Slide 17 — Scope: Downstream of PDLC
- Nova governs infra + delivery only; the PDLC (product backlog, code authorship, IDE) is upstream
- Integration is only through the validated contract boundary
- Any upstream source (AI agent, agentic SDLC, dev platform) may produce submissions — all subject to the same compliance standards
- Nova validates the submission, not the author
- **Key takeaway:** Nova is purpose-built for infrastructure operations, not product development; the scope boundary is clean
### Slide 18 — RACI: Who Owns What
- Citizen Developer owns FRs + UAT (via any upstream source — AI agent, SDLC, dev platform — all pass the same gate)
- Platform owns NFRs + infra + QA + prod deploy
- Release Management is co-owned: platform runs attestations agentically, citizen developer oversees + triggers the release (human at stage gate)
- The compliance-standard equivalence is the key: the source does not matter; the submission does
- **Key takeaway:** you bring FRs + UAT; Nova provides NFRs + infra + QA + prod deploy; the release is co-owned with you at the stage gate
### Appendix A1 — Metrics Glossary ### Appendix A1 — Metrics Glossary
- Reference for every metric mentioned in the deck - Reference for every metric mentioned in the deck
- Use if the audience asks "what does X mean?" - Use if the audience asks "what does X mean?"
+176 -20
View File
@@ -51,7 +51,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
<h1 id="nova--the-no-humans-infrastructure-platform">Nova — The No-Humans Infrastructure Platform</h1> <h1 id="nova--the-no-humans-infrastructure-platform">Nova — The No-Humans Infrastructure Platform</h1>
<p><strong>Shifting from Operational Overhead to Strategic Value</strong></p> <p><strong>Shifting from Operational Overhead to Strategic Value</strong></p>
<p>v1.17Strategic Direction, Leadership Metrics &amp; Unified Story</p> <p>v1.18Citizen Developer &amp; Production-Grade Guidance</p>
<footer>Act %{page}/5 — v1.17</footer> <footer>Act %{page}/5 — v1.17</footer>
</section> </section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-theme="default" data-style="section { </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-theme="default" data-style="section {
@@ -92,7 +92,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-1--arc-preview">Slide 1 — Arc Preview</h2> <h2 id="slide-1--arc-preview">Slide 1 — Arc Preview</h2>
<p><strong>This deck proves Nova is the no-humans infrastructure platform — and shows you the metrics that make the claim defensible.</strong></p> <p><strong>This deck proves Nova is the no-humans infrastructure platform — and shows you the metrics that make the claim defensible.</strong></p>
@@ -103,7 +103,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
<li><strong>Vision</strong> — Nova's strategic direction (NORTH_STAR)</li> <li><strong>Vision</strong> — Nova's strategic direction (NORTH_STAR)</li>
<li><strong>How</strong> — the pipeline, Decision Ledger, attestation gates</li> <li><strong>How</strong> — the pipeline, Decision Ledger, attestation gates</li>
<li><strong>Proof</strong> — grounded metrics that make the claim defensible</li> <li><strong>Proof</strong> — grounded metrics that make the claim defensible</li>
<li><strong>Roadmap</strong> — deferred metrics with unblock paths + the ask</li> <li><strong>Roadmap</strong> — deferred metrics with unblock paths + the ask + scope + RACI</li>
</ol> </ol>
<p><strong>Benefit:</strong> you leave knowing which claims are proven today, which are pipeline-ready, and which are deferred with a documented unblock path — no marketing, just grounded evidence.</p> <p><strong>Benefit:</strong> you leave knowing which claims are proven today, which are pipeline-ready, and which are deferred with a documented unblock path — no marketing, just grounded evidence.</p>
<footer>Act %{page}/5 — v1.17</footer> <footer>Act %{page}/5 — v1.17</footer>
@@ -146,7 +146,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-2--the-no-humans-imperative">Slide 2 — The No-Humans Imperative</h2> <h2 id="slide-2--the-no-humans-imperative">Slide 2 — The No-Humans Imperative</h2>
<p><strong>Why the operator is the bottleneck — and why removing them from operations (not accountability) is the imperative.</strong></p> <p><strong>Why the operator is the bottleneck — and why removing them from operations (not accountability) is the imperative.</strong></p>
@@ -197,7 +197,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-3--novas-vision">Slide 3 — Nova's Vision</h2> <h2 id="slide-3--novas-vision">Slide 3 — Nova's Vision</h2>
<blockquote> <blockquote>
@@ -248,7 +248,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-4--strategic-objectives--anti-goals">Slide 4 — Strategic Objectives + Anti-Goals</h2> <h2 id="slide-4--strategic-objectives--anti-goals">Slide 4 — Strategic Objectives + Anti-Goals</h2>
<p><strong>4 Strategic Objectives:</strong></p> <p><strong>4 Strategic Objectives:</strong></p>
@@ -307,7 +307,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-5--12%E2%80%9318-month-targets">Slide 5 — 1218 Month Targets</h2> <h2 id="slide-5--12%E2%80%9318-month-targets">Slide 5 — 1218 Month Targets</h2>
<p><strong>Current-milestone targets (grounded/derived):</strong></p> <p><strong>Current-milestone targets (grounded/derived):</strong></p>
@@ -421,7 +421,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-6--the-platform-pipeline">Slide 6 — The Platform Pipeline</h2> <h2 id="slide-6--the-platform-pipeline">Slide 6 — The Platform Pipeline</h2>
<p><strong>How intent becomes verified infrastructure without an operator.</strong></p> <p><strong>How intent becomes verified infrastructure without an operator.</strong></p>
@@ -472,7 +472,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-7--the-decision-ledger">Slide 7 — The Decision Ledger</h2> <h2 id="slide-7--the-decision-ledger">Slide 7 — The Decision Ledger</h2>
<p><strong>Every AI decision captured with confidence, alternatives, and outcome.</strong></p> <p><strong>Every AI decision captured with confidence, alternatives, and outcome.</strong></p>
@@ -524,7 +524,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-8--the-8-concern-attestation-matrix">Slide 8 — The 8-Concern Attestation Matrix</h2> <h2 id="slide-8--the-8-concern-attestation-matrix">Slide 8 — The 8-Concern Attestation Matrix</h2>
<p><strong>Designed controls that keep humans at stage gates.</strong></p> <p><strong>Designed controls that keep humans at stage gates.</strong></p>
@@ -634,7 +634,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-9--telemetry-architecture">Slide 9 — Telemetry Architecture</h2> <h2 id="slide-9--telemetry-architecture">Slide 9 — Telemetry Architecture</h2>
<p><strong>How Nova instruments itself — CloudEvents envelope, cold store, PowerBI export.</strong></p> <p><strong>How Nova instruments itself — CloudEvents envelope, cold store, PowerBI export.</strong></p>
@@ -684,7 +684,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-10--capability-health--confidence-distribution">Slide 10 — Capability Health + Confidence Distribution</h2> <h2 id="slide-10--capability-health--confidence-distribution">Slide 10 — Capability Health + Confidence Distribution</h2>
<p><strong>Grounded proof: capability health and confidence distribution from real runs.</strong></p> <p><strong>Grounded proof: capability health and confidence distribution from real runs.</strong></p>
@@ -759,7 +759,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-11--decision-ledger--attestation-coverage">Slide 11 — Decision Ledger + Attestation Coverage</h2> <h2 id="slide-11--decision-ledger--attestation-coverage">Slide 11 — Decision Ledger + Attestation Coverage</h2>
<p><strong>Trust metrics — both 100%.</strong></p> <p><strong>Trust metrics — both 100%.</strong></p>
@@ -811,7 +811,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-12--zero-touch-efficiency">Slide 12 — Zero-Touch Efficiency</h2> <h2 id="slide-12--zero-touch-efficiency">Slide 12 — Zero-Touch Efficiency</h2>
<p><strong>Touchless resolution, human escalation, and MTTR.</strong></p> <p><strong>Touchless resolution, human escalation, and MTTR.</strong></p>
@@ -862,7 +862,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-13--cost--roi">Slide 13 — Cost &amp; ROI</h2> <h2 id="slide-13--cost--roi">Slide 13 — Cost &amp; ROI</h2>
<p><strong>Cost estimates and the ROI formula — with honest caveats.</strong></p> <p><strong>Cost estimates and the ROI formula — with honest caveats.</strong></p>
@@ -913,7 +913,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-14--whats-deferred--and-why">Slide 14 — What's Deferred — and Why</h2> <h2 id="slide-14--whats-deferred--and-why">Slide 14 — What's Deferred — and Why</h2>
<p><strong>Honesty about what isn't measured yet.</strong></p> <p><strong>Honesty about what isn't measured yet.</strong></p>
@@ -1010,7 +1010,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-15--roadmap-to-the-north-star">Slide 15 — Roadmap to the North Star</h2> <h2 id="slide-15--roadmap-to-the-north-star">Slide 15 — Roadmap to the North Star</h2>
<p><strong>The path from v1.17's grounded metrics to the 1218 month targets.</strong></p> <p><strong>The path from v1.17's grounded metrics to the 1218 month targets.</strong></p>
@@ -1061,7 +1061,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
} }
.badge.today { background: #c6f6d5; color: #22543d; } .badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; } .badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="19"> ;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header> <header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-16--recap--ask">Slide 16 — Recap + Ask</h2> <h2 id="slide-16--recap--ask">Slide 16 — Recap + Ask</h2>
<p><strong>The 5-act recap + the business decision.</strong></p> <p><strong>The 5-act recap + the business decision.</strong></p>
@@ -1077,7 +1077,163 @@ img { display: block; margin: 0 auto; max-height: 320px; }
<p><strong>Benefit:</strong> you leave with a clear business decision to make — approve a pilot + the ledger build-out — and the confidence that every claim in this deck is grounded, derived, or honestly deferred.</p> <p><strong>Benefit:</strong> you leave with a clear business decision to make — approve a pilot + the ledger build-out — and the confidence that every claim in this deck is grounded, derived, or honestly deferred.</p>
<footer>Act %{page}/5 — v1.17</footer> <footer>Act %{page}/5 — v1.17</footer>
</section> </section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-class="title" data-theme="default" data-style="section { </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-paginate="true" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-theme="default" data-style="section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px;
color: #1B1B1B;
}
h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }
h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
section.title h1 { color: #fff; }
table { font-size: 18px; width: 100%; }
th { background: #F0F0F0; }
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }
img { display: block; margin: 0 auto; max-height: 320px; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 14px; font-weight: 600;
}
.badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; }
" lang="C" data-marpit-pagination="18" style="--paginate:true;--header:Nova — The No-Humans Infrastructure Platform;--footer:Act %{page}/5 — v1.17;--theme:default;--style:section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px;
color: #1B1B1B;
}
h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }
h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
section.title h1 { color: #fff; }
table { font-size: 18px; width: 100%; }
th { background: #F0F0F0; }
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }
img { display: block; margin: 0 auto; max-height: 320px; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 14px; font-weight: 600;
}
.badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-17--scope-downstream-of-pdlc">Slide 17 — Scope: Downstream of PDLC</h2>
<p><strong>Nova governs infrastructure + delivery. The PDLC (product backlog, code authorship, IDE) is upstream — Nova never penetrates it.</strong></p>
<ul>
<li><strong>The PDLC is upstream:</strong> product backlog, code authorship (AI agent / IDE / agentic SDLC), sprint planning, application business logic</li>
<li><strong>Nova is downstream:</strong> contract ingestion → submission-readiness gate → policy → cloud lifecycle → environment progression → audit + attestation</li>
<li><strong>Integration is only through the contract boundary:</strong> the citizen developer's AI coding agent, an upstream agentic SDLC, or any dev platform may all produce submissions — the source does not matter as all are subject to the same compliance standards</li>
<li>Nova validates the submission, not the author</li>
<li>Cites <code>docs/scope.md</code> + <code>PROJECT.md</code> § Scope</li>
</ul>
<p><strong>Benefit:</strong> you now know the scope boundary — Nova is purpose-built for infrastructure operations, not product development; integration is through one validated contract.</p>
<footer>Act %{page}/5 — v1.17</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-paginate="true" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-theme="default" data-style="section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px;
color: #1B1B1B;
}
h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }
h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
section.title h1 { color: #fff; }
table { font-size: 18px; width: 100%; }
th { background: #F0F0F0; }
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }
img { display: block; margin: 0 auto; max-height: 320px; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 14px; font-weight: 600;
}
.badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; }
" lang="C" data-marpit-pagination="19" style="--paginate:true;--header:Nova — The No-Humans Infrastructure Platform;--footer:Act %{page}/5 — v1.17;--theme:default;--style:section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px;
color: #1B1B1B;
}
h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }
h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
section.title h1 { color: #fff; }
table { font-size: 18px; width: 100%; }
th { background: #F0F0F0; }
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }
img { display: block; margin: 0 auto; max-height: 320px; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 14px; font-weight: 600;
}
.badge.today { background: #c6f6d5; color: #22543d; }
.badge.planned { background: #fef3c7; color: #78350f; }
;" data-marpit-pagination-total="21">
<header>Nova — The No-Humans Infrastructure Platform</header>
<h2 id="slide-18--raci-who-owns-what">Slide 18 — RACI: Who Owns What</h2>
<p><strong>Three roles, one matrix — the citizen developer owns FRs + UAT, the platform owns NFRs + infra + QA + prod deploy, release management is co-owned.</strong></p>
<table>
<thead>
<tr>
<th>Work Category</th>
<th>Citizen Dev</th>
<th>Platform</th>
<th>Release Mgmt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Functional Requirements (FRs)</td>
<td><strong>R/A</strong></td>
<td>C</td>
<td>I</td>
</tr>
<tr>
<td>User Acceptance Testing (UAT)</td>
<td><strong>R/A</strong></td>
<td>C</td>
<td>I</td>
</tr>
<tr>
<td>Non-Functional Requirements (NFRs)</td>
<td>I</td>
<td><strong>R/A</strong></td>
<td>C</td>
</tr>
<tr>
<td>Infrastructure (cloud, state, IAM)</td>
<td>I</td>
<td><strong>R/A</strong></td>
<td>C</td>
</tr>
<tr>
<td>QA (policy, confidence, schema)</td>
<td>C</td>
<td><strong>R/A</strong></td>
<td>I</td>
</tr>
<tr>
<td>Production deployment to cloud</td>
<td>I</td>
<td><strong>R/A</strong></td>
<td>C</td>
</tr>
<tr>
<td>Release attestation (QA + SRE)</td>
<td><strong>A</strong></td>
<td>R</td>
<td><strong>R</strong></td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Compliance-standard equivalence:</strong> FRs + UAT may come from any upstream source (AI agent, agentic SDLC, dev platform) — all pass the same submission-readiness gate</li>
<li><strong>Release co-ownership:</strong> the platform runs the attestations agentically; the citizen developer oversees and triggers the actual release (human at the stage gate)</li>
<li>Cites <code>docs/raci.md</code> + <code>PROJECT.md</code> § RACI Matrix</li>
</ul>
<p><strong>Benefit:</strong> you now know exactly what you bring (FRs + UAT), what Nova provides (NFRs + infra + QA + prod deploy), and what you co-own (the release attestation).</p>
<footer>Act %{page}/5 — v1.17</footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-class="title" data-theme="default" data-style="section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif; font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px; font-size: 22px;
color: #1B1B1B; color: #1B1B1B;
@@ -1197,7 +1353,7 @@ img { display: block; margin: 0 auto; max-height: 320px; }
</table> </table>
<footer>Act %{page}/5 — v1.17</footer> <footer>Act %{page}/5 — v1.17</footer>
</section> </section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-class="title" data-theme="default" data-style="section { </foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-header="Nova — The No-Humans Infrastructure Platform" data-footer="Act %{page}/5 — v1.17" data-class="title" data-theme="default" data-style="section {
font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif; font-family: &quot;Akkurat Pro&quot;, &quot;Helvetica Neue&quot;, &quot;Arial&quot;, sans-serif;
font-size: 22px; font-size: 22px;
color: #1B1B1B; color: #1B1B1B;
Binary file not shown.
+85
View File
@@ -0,0 +1,85 @@
# RACI — Who Owns What
> **Source of truth:** `.ciagent/PROJECT.md` § RACI Matrix (v1.18, REQ-215,
> D-139). This page is the citizen-developer-facing copy.
Nova's delivery lifecycle has three roles. This page clarifies who owns
what — so the citizen developer knows what they bring, what the platform
provides, and what is co-owned.
## The Three Roles
### Citizen Developer (CD)
That's you — the consumer (technical developer L3A or non-technical L3B).
You are **Responsible** for all **Functional Requirements (FRs)** and
**User Acceptance Testing (UAT)**. You produce the FRs + UAT via your AI
coding agent, an upstream agentic SDLC platform, or any upstream
development platform. **The source does not matter** — all are subject
to the same compliance standards (the submission-readiness gate, the
contract schema, the policy envelope, the immutable audit stream). Nova
validates the submission, not the author.
### Platform (Nova)
Nova is **Responsible** for all **Non-Functional Requirements (NFRs)**,
**Infrastructure** (cloud resource lifecycle, state, IAM), **QA** (the
platform-side quality checks: policy enforcement, confidence scoring,
schema validation), and **Production deployments to cloud** (the apply
path, the pipeline, the release mechanics).
### Release Management (RM) — co-owned
The release is **co-owned**. The platform performs the QA + SRE
attestations agentically (it runs the confidence signal, the policy
checks, the separation-of-duties). The citizen developer **oversees and
triggers** the actual release — the human attestation at the stage gate
is your authorization. The platform runs the checks; you authorize the
promotion. This is the "autonomy in operations, human at stage gates"
model.
## The 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.
## What This Means in Practice
**You (Citizen Developer) bring:**
- Your application code + a contract that declares intent.
- Your FRs (what the application does).
- Your UAT (you accept the deployment when it meets your FRs).
**Nova (Platform) provides:**
- The NFRs (security, observability, compliance — baked into the
pipeline, not your concern).
- The infrastructure (cloud resources, state management, IAM scoping).
- The QA (policy enforcement, confidence scoring, schema validation).
- The production deployment (the apply path, the pipeline, the release).
**You co-own the release:**
- Nova runs the attestations (QA confidence, SRE operational readiness).
- You authorize the promotion at the stage gate. No promotion happens
without your recorded attestation.
## Compliance Standards Apply Equally
Your FRs + UAT may come from any source — an AI coding agent, an
agentic SDLC platform, or a traditional IDE. Nova does not
differentiate. All submissions pass through the same gate
(`schemas/submission-readiness.schema.json`): tags, environment
metadata, policy preconditions, profile markers. The compliance
standards are the same regardless of how the code was authored. This
is by design: the audit trail is the same, the policy envelope is the
same, the evidence stream is the same. The source does not matter; the
submission does.
+68
View File
@@ -0,0 +1,68 @@
# Scope — Nova is Downstream of PDLC
> **Source of truth:** `.ciagent/PROJECT.md` § Scope (v1.18, REQ-216).
> This page is the citizen-developer-facing copy.
## The Boundary
The **Product Development Lifecycle (PDLC)** is **upstream** of Nova. The
PDLC includes:
- Product backlog / roadmap planning
- Code authorship (via AI coding agent, IDE, or agentic SDLC platform)
- Sprint planning / issue tracking
- Application business logic
- IDE workflows / developer experience
Nova never penetrates the PDLC. Nova's domain is **infrastructure +
delivery only**.
## What Nova Does
Nova governs the downstream half:
- **Contract ingestion** — the validated entry point
- **Submission-readiness gate** — what is acceptable to start
(`schemas/submission-readiness.schema.json`)
- **Policy enforcement** — the confidence signal, Checkov, tagging
- **Cloud resource lifecycle** — Terraform plan/apply, state, IAM
- **Environment progression** — dev (autonomous) → qa (QA attestation) →
prod (SRE attestation) → dr (SRE attestation)
- **Immutable audit + attestation** — the Decision Ledger, the evidence
stream, the HITL gates
## The Integration Point
Integration between the PDLC and Nova is **only** through the validated,
published contract boundary:
```
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
```
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** — all are subject to the
same compliance standards. Nova validates the submission, not the
author.
## What Nova is Not
- Not an upstream development platform (no product backlogs, IDE, code
authorship).
- Not a general-purpose AI agent platform (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).
These anti-goals (from `docs/vision.md` §7 and Core Tenet #2) are
promoted here from buried tenets to an unmissable scope statement.
+150
View File
@@ -0,0 +1,150 @@
# Submission Readiness — What is Acceptable to Start
> **Source of truth:** `schemas/submission-readiness.schema.json` (v1.18,
> REQ-217). The validator is `core/submission_readiness.py` (REQ-218),
> invoked as `python3 -m core.lambda.contract_ingestor --check-readiness
> <submission.json>` (D-133).
Nova's submission-readiness gate defines what is **acceptable to start**.
It is a superset gate *above* contract-schema validity: the contract schema
(`schemas/contract.schema.json`) defines the **shape** (id / name /
environment / infrastructure); the readiness schema defines the **gate**
(tags, per-env mandatory metadata, policy preconditions, profile markers,
appSource). Both must pass before ingestion proceeds.
## How It Works
```
citizen developer submits
contract.schema.json validation (shape) ← the existing check
submission-readiness.schema.json (gate) ← the new check
├── contractId present (non-empty)
├── environment valid (dev/qa/prod/dr)
├── tags: all 5 Nova tags present (D-054)
├── policyPreconditions declared
├── profile: developer or agentic
│ └── if agentic: naturalLanguageIntent + confidenceAtSubmission + agentTrace
├── appSource: repo + ref (for runtime fetch)
└── per-env mandatory (W3.E):
dev → stack + environment
qa → + validation.e2eSuite + validation.loadTest
prod → + runbook + dashboard + oncall
dr → + drDrillRef
ready → proceed to contract ingestion
not ready → reject with citizen-developer-facing error (reason code)
```
## Reason Codes
When a submission is not ready, the validator returns one or more reason
codes. These are citizen-developer-facing — no stack traces.
| Code | Meaning |
|---|---|
| `MISSING_TAGS:<tag1>,<tag2>` | One or more required Nova tags are absent |
| `ENV_MISSING_MANDATORY:<env>:<field>` | A per-env mandatory field (W3.E) is missing |
| `AGENTIC_MISSING_INTENT:<marker>` | profile=agentic but a required marker is absent |
| `MISSING_APP_SOURCE` | appSource (repo + ref) is missing |
| `POLICY_PRECONDITION_MISSING` | No policy preconditions declared |
| `CONTRACT_SCHEMA_INVALID:<detail>` | The contract shape failed contract.schema.json |
| `READINESS_SCHEMA_INVALID:<detail>` | The submission failed the readiness schema |
## Good Example
```json
{
"contractId": "uuid-1234",
"id": "webapi",
"name": "Customer Web API",
"environment": "dev",
"tags": {
"nova:owner": "consumer-repo",
"nova:contract": "uuid-1234",
"nova:environment": "dev",
"nova:cost-center": "nova-default",
"nova:ref": "CHG0678912"
},
"policyPreconditions": {
"public-ingress": false,
"encryption_enabled": true,
"deletion_protection": true
},
"profile": "developer",
"appSource": {
"repo": "consumer/web-api",
"ref": "main"
},
"infrastructure": {
"static-assets": {
"inputs": {
"bucket_name": "webapi-assets"
}
}
}
}
```
Result: **READY** — passes the shape + the gate.
## Rejected Examples
### Missing Tags
```json
{
"contractId": "uuid-1234",
"environment": "dev",
"tags": {
"nova:owner": "consumer-repo"
},
"policyPreconditions": {"public-ingress": false},
"profile": "developer",
"appSource": {"repo": "consumer/repo", "ref": "main"}
}
```
Result: `NOT READY — MISSING_TAGS:nova:contract,nova:environment,nova:cost-center,nova:ref`
### Agentic Missing Intent
```json
{
"contractId": "uuid-1234",
"environment": "qa",
"tags": { "nova:owner": "x", "nova:contract": "x", "nova:environment": "qa", "nova:cost-center": "x", "nova:ref": "x" },
"policyPreconditions": {"public-ingress": false},
"profile": "agentic",
"appSource": {"repo": "x", "ref": "x"},
"validation": {"e2eSuite": true, "loadTest": true}
}
```
Result: `NOT READY — AGENTIC_MISSING_INTENT:naturalLanguageIntent; AGENTIC_MISSING_INTENT:confidenceAtSubmission; AGENTIC_MISSING_INTENT:agentTrace`
### Env Missing Mandatory (prod without runbook)
```json
{
"contractId": "uuid-1234",
"environment": "prod",
"tags": { "nova:owner": "x", "nova:contract": "x", "nova:environment": "prod", "nova:cost-center": "x", "nova:ref": "x" },
"policyPreconditions": {"public-ingress": false},
"profile": "developer",
"appSource": {"repo": "x", "ref": "x"}
}
```
Result: `NOT READY — ENV_MISSING_MANDATORY:prod:runbook; ENV_MISSING_MANDATORY:prod:dashboard; ENV_MISSING_MANDATORY:prod:oncall`
## Compliance-Standard Equivalence
The submission-readiness gate applies **equally** to all upstream sources.
Whether the citizen developer's submission originated from an AI coding
agent, an agentic SDLC platform, or a traditional development platform —
the same tags, the same env mandatory, the same policy preconditions, the
same profile markers are required. The source does not matter; the
submission does. This is the RACI compliance-standard equivalence note
(`docs/raci.md`) made machine-checkable.
+104
View File
@@ -0,0 +1,104 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://nova.dev/schemas/submission-readiness.schema.json",
"title": "Nova Submission-Readiness Gate",
"description": "Defines what is acceptable to start — a superset gate ABOVE contract.schema.json validity. The contract schema defines the SHAPE (id/name/environment/infrastructure); this schema defines the READINESS gate: required Nova tags, per-env mandatory metadata (W3.E), declared policy preconditions, profile:agentic markers, and the appSource pointer. The validator (core/submission_readiness.py, REQ-218) calls contract.schema.json validation first, then these readiness checks. On fail → citizen-developer-facing error (not a stack trace); on pass → proceeds to existing contract ingestion.",
"type": "object",
"required": ["contractId", "environment", "tags", "policyPreconditions", "profile", "appSource"],
"properties": {
"contractId": {
"type": "string",
"minLength": 1,
"description": "The contract identifier (UUID or operational id). Non-empty."
},
"environment": {
"type": "string",
"enum": ["dev", "qa", "prod", "dr"],
"description": "Target environment. Determines the per-env mandatory fields (allOf below)."
},
"tags": {
"type": "object",
"description": "The 5 required Nova tags (D-054). References schemas/tagging-standard.json.",
"required": ["nova:owner", "nova:contract", "nova:environment", "nova:cost-center", "nova:ref"],
"properties": {
"nova:owner": {"type": "string", "minLength": 1},
"nova:contract": {"type": "string", "minLength": 1},
"nova:environment": {"type": "string", "enum": ["dev", "qa", "prod", "dr"]},
"nova:cost-center": {"type": "string", "minLength": 1},
"nova:ref": {"type": "string", "minLength": 1}
},
"additionalProperties": false
},
"policyPreconditions": {
"type": "object",
"description": "Declared policy expectations the platform will enforce. The citizen developer states what the platform should check; the platform enforces it at apply time. Missing a declared precondition is POLICY_PRECONDITION_MISSING.",
"properties": {
"public-ingress": {"type": "boolean", "default": false},
"encryption_enabled": {"type": "boolean", "default": true},
"deletion_protection": {"type": "boolean", "default": true}
},
"additionalProperties": true
},
"profile": {
"type": "string",
"enum": ["developer", "agentic"],
"description": "developer = L3A (technical); agentic = L3B (non-technical, requires naturalLanguageIntent + confidenceAtSubmission + agentTrace per REQ-22 / W3.E)."
},
"appSource": {
"type": "object",
"description": "Pointer to the consumer application code so the platform can fetch at run time.",
"required": ["repo", "ref"],
"properties": {
"repo": {"type": "string", "minLength": 1, "description": "Repository URL or owner/repo shorthand."},
"ref": {"type": "string", "minLength": 1, "description": "Git ref (branch, tag, or SHA)."}
},
"additionalProperties": false
},
"naturalLanguageIntent": {
"type": "string",
"description": "Required when profile=agentic (L3B). The citizen developer's plain-language intent."
},
"confidenceAtSubmission": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Required when profile=agentic (L3B). The submitter's self-assessed confidence."
},
"agentTrace": {
"type": "string",
"description": "Required when profile=agentic (L3B). The agent's trace/reasoning for the submission."
},
"validation": {
"type": "object",
"description": "Per-env mandatory metadata (W3.E). qa requires e2eSuite + loadTest; prod requires runbook + dashboard + oncall; dr requires drDrillRef.",
"properties": {
"e2eSuite": {"type": "boolean"},
"loadTest": {"type": "boolean"}
},
"additionalProperties": true
},
"runbook": {"type": "string", "description": "Required when environment=prod (W3.E)."},
"dashboard": {"type": "string", "description": "Required when environment=prod (W3.E)."},
"oncall": {"type": "string", "description": "Required when environment=prod (W3.E)."},
"drDrillRef": {"type": "string", "description": "Required when environment=dr (W3.E)."}
},
"allOf": [
{
"if": {"properties": {"environment": {"const": "qa"}}},
"then": {"required": ["validation"], "properties": {"validation": {"required": ["e2eSuite", "loadTest"]}}}
},
{
"if": {"properties": {"environment": {"const": "prod"}}},
"then": {"required": ["runbook", "dashboard", "oncall"]}
},
{
"if": {"properties": {"environment": {"const": "dr"}}},
"then": {"required": ["drDrillRef"]}
},
{
"if": {"properties": {"profile": {"const": "agentic"}}},
"then": {"required": ["naturalLanguageIntent", "confidenceAtSubmission", "agentTrace"]}
}
],
"additionalProperties": true
}
+189
View File
@@ -0,0 +1,189 @@
"""tests/test_submission_readiness.py — REQ-220.
Covers: good contract passes; missing tags fail with MISSING_TAGS;
env-missing-mandatory fails with ENV_MISSING_MANDATORY:<env>:<field>;
agentic profile missing intent fails with AGENTIC_MISSING_INTENT;
missing appSource fails with MISSING_APP_SOURCE.
"""
import json
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from core.submission_readiness import check_readiness, ReadinessResult
GOOD_TAGS = {
"nova:owner": "consumer-repo",
"nova:contract": "uuid-1234",
"nova:environment": "dev",
"nova:cost-center": "nova-default",
"nova:ref": "CHG0678912",
}
def _base(**overrides):
submission = {
"contractId": "uuid-1234",
"id": "webapi",
"name": "Customer Web API",
"environment": "dev",
"tags": dict(GOOD_TAGS),
"policyPreconditions": {"public-ingress": False, "encryption_enabled": True},
"profile": "developer",
"appSource": {"repo": "consumer/repo", "ref": "main"},
"infrastructure": {
"static-assets": {"inputs": {"bucket_name": "webapi-assets"}}
},
}
submission.update(overrides)
return submission
class TestGoodContract(unittest.TestCase):
def test_good_contract_passes(self):
result = check_readiness(_base())
self.assertTrue(result.ready, f"Expected ready, got: {result.reason_codes}")
self.assertEqual(result.contract_id, "uuid-1234")
def test_good_agentic_contract_passes(self):
submission = _base(
profile="agentic",
naturalLanguageIntent="A web API for customer data",
confidenceAtSubmission=0.85,
agentTrace="LLM generated contract from issue #42",
)
result = check_readiness(submission)
self.assertTrue(result.ready, f"Expected ready, got: {result.reason_codes}")
class TestMissingTags(unittest.TestCase):
def test_missing_tags_fail(self):
submission = _base()
submission["tags"] = {"nova:owner": "consumer-repo"}
result = check_readiness(submission)
self.assertFalse(result.ready)
codes = " ".join(result.reason_codes)
self.assertIn("MISSING_TAGS", codes)
self.assertIn("nova:contract", codes)
self.assertIn("nova:environment", codes)
self.assertIn("nova:cost-center", codes)
self.assertIn("nova:ref", codes)
def test_empty_tag_value_fails(self):
submission = _base()
submission["tags"]["nova:owner"] = ""
result = check_readiness(submission)
self.assertFalse(result.ready)
self.assertTrue(any("MISSING_TAGS" in c for c in result.reason_codes))
class TestEnvMissingMandatory(unittest.TestCase):
def test_qa_missing_e2e_suite_fails(self):
submission = _base(environment="qa")
submission["tags"]["nova:environment"] = "qa"
# No validation.e2eSuite
result = check_readiness(submission)
self.assertFalse(result.ready)
codes = " ".join(result.reason_codes)
self.assertIn("ENV_MISSING_MANDATORY:qa:validation.e2eSuite", codes)
def test_prod_missing_runbook_fails(self):
submission = _base(environment="prod")
submission["tags"]["nova:environment"] = "prod"
# No runbook/dashboard/oncall
result = check_readiness(submission)
self.assertFalse(result.ready)
codes = " ".join(result.reason_codes)
self.assertIn("ENV_MISSING_MANDATORY:prod:runbook", codes)
self.assertIn("ENV_MISSING_MANDATORY:prod:dashboard", codes)
self.assertIn("ENV_MISSING_MANDATORY:prod:oncall", codes)
def test_dr_missing_drdrillref_fails(self):
submission = _base(environment="dr")
submission["tags"]["nova:environment"] = "dr"
result = check_readiness(submission)
self.assertFalse(result.ready)
codes = " ".join(result.reason_codes)
self.assertIn("ENV_MISSING_MANDATORY:dr:drDrillRef", codes)
def test_prod_with_all_mandatory_passes(self):
submission = _base(
environment="prod",
runbook="docs/runbooks/webapi.md",
dashboard="https://grafana/nova/webapi",
oncall="oncall@company.com",
)
submission["tags"]["nova:environment"] = "prod"
result = check_readiness(submission)
self.assertTrue(result.ready, f"Expected ready, got: {result.reason_codes}")
class TestAgenticMissingIntent(unittest.TestCase):
def test_agentic_missing_all_markers_fails(self):
submission = _base(profile="agentic")
result = check_readiness(submission)
self.assertFalse(result.ready)
codes = " ".join(result.reason_codes)
self.assertIn("AGENTIC_MISSING_INTENT:naturalLanguageIntent", codes)
self.assertIn("AGENTIC_MISSING_INTENT:confidenceAtSubmission", codes)
self.assertIn("AGENTIC_MISSING_INTENT:agentTrace", codes)
def test_agentic_missing_one_marker_fails(self):
submission = _base(
profile="agentic",
naturalLanguageIntent="A web API",
confidenceAtSubmission=0.85,
# agentTrace missing
)
result = check_readiness(submission)
self.assertFalse(result.ready)
self.assertTrue(any("agentTrace" in c for c in result.reason_codes))
class TestMissingAppSource(unittest.TestCase):
def test_missing_appsource_fails(self):
submission = _base()
del submission["appSource"]
result = check_readiness(submission)
self.assertFalse(result.ready)
self.assertTrue(any("MISSING_APP_SOURCE" in c for c in result.reason_codes))
def test_appsource_missing_ref_fails(self):
submission = _base()
submission["appSource"] = {"repo": "consumer/repo"}
result = check_readiness(submission)
self.assertFalse(result.ready)
self.assertTrue(any("MISSING_APP_SOURCE" in c for c in result.reason_codes))
class TestPolicyPreconditionMissing(unittest.TestCase):
def test_empty_policy_fails(self):
submission = _base()
submission["policyPreconditions"] = {}
result = check_readiness(submission)
self.assertFalse(result.ready)
self.assertTrue(any("POLICY_PRECONDITION_MISSING" in c for c in result.reason_codes))
class TestReadinessResultStructure(unittest.TestCase):
def test_result_to_dict(self):
result = check_readiness(_base())
d = result.to_dict()
self.assertIn("ready", d)
self.assertIn("reason_codes", d)
self.assertIn("contractId", d)
def test_result_str_ready(self):
result = check_readiness(_base())
self.assertIn("READY", str(result))
def test_result_str_not_ready(self):
submission = _base()
del submission["appSource"]
result = check_readiness(submission)
self.assertIn("NOT READY", str(result))
if __name__ == "__main__":
unittest.main()