Compare commits

...

2 Commits

Author SHA1 Message Date
Jon Chery adc55a17ab docs(milestone): complete v1.28 CLI Canonicalization + Identity Layer (release v1.27.6)
Nova Slides Render / render (push) Failing after 29s
---ci---
project: acdl
phase: 6
milestone: v1.28
status: complete
requirements:
  covered: [REQ-323..353]
  partial: []
---/ci---
2026-08-19 23:47:44 +00:00
Jon Chery 0d8913a299 merge(phase/05): v1.28 P5 docs-integration complete (REQ-345..351, E2E + threat model) 2026-08-19 23:34:11 +00:00
5 changed files with 132 additions and 41 deletions
+25 -8
View File
@@ -1,18 +1,35 @@
{
"phase": 5,
"phase": 6,
"stage": "complete",
"milestone": "v1.28",
"phase_role": "execution",
"phase_role": "final",
"attempts": 0,
"updated_at": "2026-08-19T23:45:00Z",
"updated_at": "2026-08-19T23:59:00Z",
"project": "acdl",
"projects": ["acdl", "nova-blockchain-exchange"],
"active_milestone": "v1.28",
"milestone_branch": "milestone/v1.28-cli-identity",
"phase_branch": "phase/05-docs-integration",
"phase_branch": "phase/06-final-review-ship",
"tag_line": "v1.27.x",
"phase_name": "docs-integration",
"reqs_covered": ["REQ-345", "REQ-346", "REQ-347", "REQ-348", "REQ-349", "REQ-350", "REQ-351"],
"tests": {"p5_specific": 17, "total_passing": 1000, "failures": 0},
"notes": "v1.28 P5 SHIP. docs-integration complete. Tag v1.27.5. 7 REQs covered (REQ-345..351). Operator guide (C-6.3), developer guide (C-7.3), threat model (C-6.2, C-9.2 INV audit), E2E test (REQ-348). 1000 tests passing. Next: P6 final-review-ship (milestone release)."
"phase_name": "final-review-ship",
"reqs_covered": ["REQ-323..353"],
"reqs_partial": [],
"caps_verified": ["CAP-033", "CAP-034", "CAP-035", "CAP-036", "CAP-037", "CAP-038"],
"invariants_added": ["INV-12", "INV-13", "INV-14", "INV-15", "INV-16", "INV-17"],
"decisions": ["D-226", "D-227", "D-228", "D-229", "D-230", "D-231"],
"milestone_complete": true,
"milestone_release": {"tag": "v1.27.6", "type": "feature"},
"tests": {"total_passing": 1000, "failures": 0, "deselected": 5},
"phases": [
{"phase": 0, "tag": "v1.27.0", "status": "complete"},
{"phase": 1, "tag": "v1.27.1", "status": "complete"},
{"phase": 2, "tag": "v1.27.2", "status": "complete"},
{"phase": 3, "tag": "v1.27.3", "status": "complete"},
{"phase": 4, "tag": "v1.27.4", "status": "complete"},
{"phase": 5, "tag": "v1.27.5", "status": "complete"},
{"phase": 6, "tag": "v1.27.6", "status": "complete"}
],
"grill": {"verdict": "PROCEED-WITH-CONDITIONS", "confidence": 0.76, "critical_resolved": 3, "tracked_resolved": 16},
"audit": {"reconstruction": "PASS", "commit_discipline": "CLEAN", "branch_hygiene": "CLEAN", "file_discipline": "CLEAN"},
"notes": "v1.28 COMPLETE. Feature milestone (CLI Canonicalization + Identity Layer). 7 phases (P0 + P1..P5 execution + P6 final). 31 REQs covered (REQ-323..353). 6 CAPs verified (CAP-033..038). 6 invariants added (INV-12..17). 6 decisions (D-226..231). Grill PROCEED 0.76 (3 critical + 16 tracked conditions resolved). 1000 tests passing, 0 failures. Audit: reconstruction PASS, commit/branch/file discipline CLEAN. Merged milestone/v1.28-cli-identity -> main. Tag v1.27.6 = milestone release. All milestone branches deleted."
}
+1 -1
View File
@@ -450,7 +450,7 @@ already exist).
> Review: 0 P0. Audit: reconstruction PASS, file/branch/commit discipline CLEAN.
> Full phase detail: `.ciagent/archive/` (v1.27 artifacts) + git history.
## v1.28 — CLI Canonicalization + Identity Layer (active)
## v1.28 — CLI Canonicalization + Identity Layer (complete, tag `v1.27.6`, merged to main 2026-08-19)
> **Feature milestone — active.** The Nova CLI becomes installable from
> internal PyPI (CodeArtifact), every `core/` module is reachable as a
+32 -32
View File
@@ -301,7 +301,7 @@ Full v1.26 requirement text:
`.ciagent/nova-blockchain-exchange/REQUIREMENTS.md`. Active phase plan:
`.ciagent/PLAN.md`.
## v1.28 — CLI Canonicalization + Identity Layer (active)
## v1.28 — CLI Canonicalization + Identity Layer (complete, tag `v1.27.6`, merged to main 2026-08-19)
> **Feature milestone — active.** The Nova CLI is installable from
> internal PyPI (CodeArtifact); every `core/` module is reachable as a
@@ -571,34 +571,34 @@ All v1.28 release-gate criteria in PLAN.md §6 met.
| REQ | Phase | Status |
|-----|-------|--------|
| REQ-323 | P1 | planned |
| REQ-324 | P1 | planned |
| REQ-325 | P1 | planned |
| REQ-326 | P1 | planned |
| REQ-327 | P1 | planned |
| REQ-328 | P1 | planned |
| REQ-329 | P2 | planned |
| REQ-330 | P2 | planned |
| REQ-331 | P2 | planned |
| REQ-332 | P2 | planned |
| REQ-333 | P3 | planned |
| REQ-334 | P3 | planned |
| REQ-335 | P3 | planned |
| REQ-336 | P4 | planned |
| REQ-337 | P4 | planned |
| REQ-338 | P4 | planned |
| REQ-339 | P4 | planned |
| REQ-340 | P4 | planned |
| REQ-341 | P4 | planned |
| REQ-342 | P4 | planned |
| REQ-343 | P4 | planned |
| REQ-344 | P4 | planned |
| REQ-345 | P5 | planned |
| REQ-346 | P5 | planned |
| REQ-347 | P5 | planned |
| REQ-348 | P5 | planned |
| REQ-349 | P5 | planned |
| REQ-350 | P5 | planned |
| REQ-351 | P5 | planned |
| REQ-352 | P6 | planned |
| REQ-353 | P6 | planned |
| REQ-323 | P1 | complete (v1.27.1) |
| REQ-324 | P1 | complete (v1.27.1) |
| REQ-325 | P1 | complete (v1.27.1) |
| REQ-326 | P1 | complete (v1.27.1) |
| REQ-327 | P1 | complete (v1.27.1) |
| REQ-328 | P1 | complete (v1.27.1) |
| REQ-329 | P2 | complete (v1.27.2) |
| REQ-330 | P2 | complete (v1.27.2) |
| REQ-331 | P2 | complete (v1.27.2) |
| REQ-332 | P2 | complete (v1.27.2) |
| REQ-333 | P3 | complete (v1.27.3) |
| REQ-334 | P3 | complete (v1.27.3) |
| REQ-335 | P3 | complete (v1.27.3) |
| REQ-336 | P4 | complete (v1.27.4) |
| REQ-337 | P4 | complete (v1.27.4) |
| REQ-338 | P4 | complete (v1.27.4) |
| REQ-339 | P4 | complete (v1.27.4) |
| REQ-340 | P4 | complete (v1.27.4) |
| REQ-341 | P4 | complete (v1.27.4) |
| REQ-342 | P4 | complete (v1.27.4) |
| REQ-343 | P4 | complete (v1.27.4) |
| REQ-344 | P4 | complete (v1.27.4) |
| REQ-345 | P5 | complete (v1.27.5) |
| REQ-346 | P5 | complete (v1.27.5) |
| REQ-347 | P5 | complete (v1.27.5) |
| REQ-348 | P5 | complete (v1.27.5) |
| REQ-349 | P5 | complete (v1.27.5) |
| REQ-350 | P5 | complete (v1.27.5) |
| REQ-351 | P5 | complete (v1.27.5) |
| REQ-352 | P6 | complete (v1.27.6) |
| REQ-353 | P6 | complete (v1.27.6) |
+26
View File
@@ -94,6 +94,32 @@
checkpoint. 3 phases (P0 pre-execution + P1 author-archive + P2
fix-stale-wire + P3 final-review-ship). No REQ-NNN (NFR).
- **v1.28:** complete (tag `v1.27.6`) — CLI Canonicalization + Identity
Layer. Feature milestone. The Nova CLI is installable from internal
PyPI (CodeArtifact); every `core/` module is reachable as a `nova
<subcommand>` (15 subcommands, argparse-only, ≤50-line thin delegates,
CAP-033/034); `nova init` scaffolds `.nova/`; `nova cli-action`
composite action published to GitHub + Gitea (byte-identical, NFR-11);
`core/mode_resolver.py` (flag → env → credential type →
`sys.stdin.isatty()`, D-226); INV-12 audit emission on every
invocation. Nova owns its identity layer end-to-end (Nova-idp):
`nova-idp-auth` Lambda (sign-up/sign-in/session, Argon2id t=3 m=65536
p=1, fail-closed D-228), `nova-idp-token-vend` Lambda (KMS-signed
OIDC tokens, ECDSA P-256 / ES256, DER→raw conversion, kyverno-json
ABAC fail-closed C-6.1), `nova-idp-jwks` Lambda (JWKS endpoint),
`nova-pats` DynamoDB (PAT lifecycle, strong-read revocation D-229,
60s SLO), `nova auth login/revoke/status`, `nova idp setup
--check/--apply/--verify` (CloudFormation, NFR-10 explicit approval).
No AWS-managed identity (INV-15). 31 requirements (REQ-323..353), 6
capabilities (CAP-033..038), 6 invariants (INV-12..17), 6 decisions
(D-226..231). 6 execution phases (P1 cli-substrate, P2
lambda-packaging, P3 idp-auth, P4 token-vend-pat + idp-setup folded
C-2.1, P5 docs-integration, P6 final-review-ship). Grill:
PROCEED-WITH-CONDITIONS (0.76), 3 critical fixes (ABAC fail-closed,
JWS KDF, traceability drift) + 16 tracked conditions applied. 1000
tests passing. Tags: `v1.27.0` (P0) → `v1.27.1..v1.27.5` (P1..P5) →
`v1.27.6` (P6 final = milestone release).
> **Full v1.0v1.24 phase detail, wave ordering, success criteria, and
> decision cross-references:** `.ciagent/archive/ROADMAP-v1.0-v1.24.md`.
+48
View File
@@ -80,6 +80,29 @@
path deferred (D-126). Multi-cloud deferred. Multi-validator BFT
deferred. The pilot runs `mode: full` for `dev` only (D-209); qa/prod/dr
stay placeholder (D-208, blocked by the pilot-readiness policy).
- **INV-12 (Mode observability, v1.28):** Every CLI invocation emits a
`cli.invocation` audit event containing `mode`, `selection_reason`,
`credential_type`, `command`, and `args`. Operators can debug mode
selection without reproducing.
- **INV-13 (Mode resolution determinism, v1.28):** Resolution priority
is flag → env (`NOVA_CLIENT_MODE`) → credential type →
`sys.stdin.isatty()`. No silent fallbacks. Invalid env values are
ignored + warned. Deviations rejected at PR time.
- **INV-14 (Credential type encodes role, v1.28):** `developer_pat` /
`nova_oidc_token` + TTY present → `interactive`; TTY absent → `agent`.
- **INV-15 (No AWS-managed identity in path, v1.28):** Nova-idp MUST
NOT depend on Cognito, IAM Identity Center, or any AWS-managed
identity service. Greenfield constraint (no Cognito existed to
"drop").
- **INV-16 (Password storage, v1.28):** Passwords hashed with Argon2id
(t=3, m=65536 KiB, p=1). Fail-closed on `ImportError` (D-228 amended
— no pure-Python fallback). Raw passwords never in logs/traces/env/
DynamoDB.
- **INV-17 (ABAC discipline, v1.28):** The token-vend Lambda evaluates
the kyverno-json ABAC policy before signing. Fail-closed on `kj`
absence or evaluation error (C-6.1 — never fail open). Allow/deny +
policy inputs emitted to the audit stream. `policy_version` (git SHA,
D-231) recorded in every event.
## Domains (capability groups)
@@ -248,6 +271,31 @@
| — | IAM policy baseline (`acdl-spike-runner-policy`) | v1.11 / `v1.11.0` | `terraform/bootstrap/spike_runner_policy.json`, `.ciagent/IAM_POLICY.md` | REQ-116, D-095 | live-aws | regression-tested by `tests/test_iam_policy_baseline.py`; OIDC role `acdl-act-runner-role` (CAP-022) |
| — | Local emulating adapters (no AWS) | v1.10 / `v1.10.0` | `core/local_lambda_stub.py`, `scripts/run_local_e2e.sh` | D-092 | local | proves runtime behavior without live AWS |
### Domain 11 — CLI + Identity Layer (v1.28)
| ID | Capability | Shipped | Files | Controlling | Tier | Notes |
|----|-----------|---------|-------|-------------|------|-------|
| CAP-033 | CLI subcommand surface exists | v1.28 / `v1.27.1` | `nova/cli.py`, `nova/<module>.py` (15 subcommands) | REQ-324 | local | `nova --help` lists a subcommand for every `core/` module; argparse-only, auto-discovered |
| CAP-034 | Subcommand delegates to `core/` | v1.28 / `v1.27.1` | `nova/<module>.py` | REQ-324 | local | ≤50 lines, ≤3 FunctionDef, all calls resolve to `core.*` imports; AST-scanned in `tests/test_cli_subcommands.py` |
| CAP-035 | Layer matches wheel | v1.28 / `v1.27.1` | `.github/workflows/publish.yml`, `.gitea/workflows/publish.yml`, SSM `/nova/layer/nova-cli/version` | REQ-323 | local | wheel + Lambda layer co-published with identical version; SSM mapping; CodeArtifact + fallback |
| CAP-036 | Nova-idp auth flow works | v1.28 / `v1.27.3` | `core/lambda/nova_idp_auth.py`, `tests/test_idp_auth.py` | REQ-333 | local | sign-up → sign-in → session E2E; Argon2id t=3 m=65536 p=1; fail-closed D-228; moto locally, real DDB in CI |
| CAP-037 | Token-vend signs via KMS | v1.28 / `v1.27.4` | `core/lambda/nova_idp_token_vend.py`, `core/kms_signing.py`, `tests/test_kms_roundtrip.py` | REQ-337 | local | ECDSA P-256 / ES256; DER→raw conversion; KMS round-trip test; mock KMS locally, real KMS in CI |
| CAP-038 | PAT issuance + revocation | v1.28 / `v1.27.4` | `core/pat_lifecycle.py`, `tests/test_pat_revocation.py` | REQ-342 | local | issue → vend → revoke → 403 within 60s P95; strong-read DDB (D-229); verified <1s locally |
| — | `nova init` scaffolds `.nova/` | v1.28 / `v1.27.1` | `nova/init.py`, `core/init_scaffold.py` | REQ-325 | local | `.nova/`, `.nova/contract.yml.attestations/`, `.gitignore` (secrets excluded) |
| — | `nova cli-action` composite action | v1.28 / `v1.27.1` | `.github/actions/nova-cli/action.yml` | REQ-326 | local | byte-identical GitHub + Gitea; Python 3.12 pinned; NFR-11 |
| — | `mode_resolver` (flag→env→cred→TTY) | v1.28 / `v1.27.1` | `core/mode_resolver.py` | REQ-327, D-226 | local | `sys.stdin.isatty()` (not stdout); hypothesis property tests |
| — | Dual-use Lambda/CLI import | v1.28 / `v1.27.2` | `core/lambda/contract_ingestor.py` | REQ-329 | local | shared `dispatch_action()`; ≥80% code share; NFR-7 |
| — | Local env synthesizer | v1.28 / `v1.27.2` | `core/env.py` (`synthesize_local_env`) | REQ-330 | local | `nova apply --local`; no cloud provisioning |
| — | JWS-from-PAT (HKDF-SHA256, HS256) | v1.28 / `v1.27.2` | `core/jws_attestation.py` | REQ-332, C-5.2 | local | symmetric; verification key derived from PAT via same KDF |
| — | JWKS endpoint (function URL) | v1.28 / `v1.27.4` | `core/lambda/nova_idp_jwks.py` | REQ-338, D-230 | local | `AuthType: NONE`; `Cache-Control: max-age=3600`; optional CloudFront/WAF |
| — | kyverno-json ABAC token-vend policy | v1.28 / `v1.27.4` | `platform/abac/token-vend.policy`, `core/abac_evaluator.py` | REQ-339, D-227 | local | fail-closed (C-6.1, 7 tests); `policy_version` git SHA (D-231) |
| — | `nova idp setup --check/--apply/--verify` | v1.28 / `v1.27.4` | `nova/idp/setup.py`, `core/lambda/nova_idp_setup.py`, `core/lambda/nova_idp_cfn.py` | REQ-340, REQ-341 | local | CloudFormation template review (NFR-10); IAM policy delta; KMS round-trip verify |
| — | `nova auth login/revoke/status` | v1.28 / `v1.27.4` | `nova/auth/{login,revoke,status}.py`, `core/auth_store.py` | REQ-344, C-7.3 | local | `~/.nova/credentials.json` 0600 stores OIDC token + metadata (NOT raw PAT) |
| — | E2E integration test | v1.28 / `v1.27.5` | `tests/test_e2e_idp.py` | REQ-348 | local | sign-up → sign-in → token-vend → apply → audit chain |
| — | Identity-layer threat model | v1.28 / `v1.27.5` | `docs/threat-model.md` | REQ-347 | local | 8 threats + C-9.2 INV-18..21 compression audit |
| — | Operator guide | v1.28 / `v1.27.5` | `docs/operator-guide-idp.md` | REQ-345 | local | `nova idp setup` + KMS rotation + layer update + PITR restore + emergency PAT revocation |
| — | Developer guide | v1.28 / `v1.27.5` | `docs/developer-guide-auth.md` | REQ-346 | local | quickstart + mode resolution + JWS KDF + service-account PATs |
## Archive pointers
- **v1.0v1.24 capability narrative + the 2026-07-27 re-verification sweep:**