Files
acdl/.ciagent/CLARIFY.md
T
CIAgent Orchestrator 0789c27ca2
Nova Slides Render / render (push) Failing after 14m27s
docs(P00): complete v1.29 pre-execution — SPECIFY+CLARIFY+RESEARCH+PLAN+GRILL+MVP/UX
---ci---
project: acdl
phase: 0
milestone: v1.29
status: complete
---/ci---
2026-08-20 05:00:35 +00:00

24 KiB
Raw Blame History

CLARIFY — v1.28 CLI Canonicalization + Identity Layer

Autonomy: full. Auto-resolution with assumption logging per config.autonomy.level: "full". No human escalation unless confidence < 0.60. The user-approved re-mapping plan (v1.18 spec → v1.28) resolved the headline discrepancy. This file records the remaining ambiguities and the grounding gaps surfaced in pre-flight.


Method

The clarify stage identifies ambiguities in the v1.28 specification and resolves them at full autonomy. The v1.28 spec is the user-provided "Universal Feature Specification — v1.18 CLI Canonicalization + Identity Layer," re-mapped to v1.28 (milestone number, tag line, and all ID namespaces) per the user-approved plan. Each ambiguity gets a decision ID (D-226+, continuing from v1.27's D-214..D-225), a resolution, a confidence score, and a rationale.


Prior-conversation resolutions (already locked, restated for the record)

These were resolved by the user-approved re-mapping plan in the conversation that spawned v1.28. They are load-bearing for v1.28 execution.

Q-P1 — The source spec is titled "v1.18" but v1.18 already shipped. What milestone is this?

Resolution: Re-map the spec's content (CLI Canonicalization + Identity Layer) to v1.28, the next milestone after v1.27 (complete). Tags run on the v1.27.x line (P0 = v1.27.0). Milestone branch: milestone/v1.28-cli-identity. Confidence: 1.0 (user-confirmed — "Re-map to v1.28"). Decision: n/a (milestone identity, not a D-ID).

Q-P2 — The spec's "locked inputs" (D-NEW-26, kj engine, Nova-idp, INV-63/64/65, CAP-025..030, REQ-001..031) don't exist in the repo. How to handle?

Resolution: Author them fresh in this milestone's CLARIFY/RESEARCH as D-226..D-231, INV-12..17, CAP-033..038, REQ-323..353. The kj engine is mapped to the existing kyverno-json engine (INV-4 swappable) — no new engine is built. CAP/INV/REQ IDs are re-allocated to avoid collisions with shipped history (CAP-025..032 and INV-1..11 are blockchain/pilot). Confidence: 1.0 (user-confirmed — "Re-map to v1.28"). Decision: D-227 (kj→kyverno-json), plus the ID-allocation block in REQUIREMENTS.md.

Q-P3 — The spec claims a "Cognito drop." No Cognito exists in the repo. What does NFR-5 mean?

Resolution: NFR-5 (no AWS-managed identity in the path) is a greenfield constraint, not a migration. Nova-idp is built fresh; no Cognito/IAM Identity Center is introduced. The "drop" framing is aspirational language from the source spec, not a literal removal. Confidence: 1.0. Decision: D-226 (recorded below; NFR-5 restated as a greenfield constraint in INV-15).


Open questions from the spec's §7 (auto-resolved at full autonomy)

Q1 — Argon2 native dependency in Lambda runtime

argon2-cffi has a C extension that may not build cleanly in the Lambda Python 3.12 runtime.

Resolution (D-228): Use argon2-cffi with bundled wheels; if the extension fails to load, fall back to the pure-Python implementation. If both fail, document the Fargate migration path for the auth Lambda. CAP-036 covers end-to-end verification. Confidence: 0.85. Rationale: Bundled wheels are the standard workaround for Lambda native deps; the pure-Python fallback is a safe degradation. Fargate is the escape hatch if Lambda's runtime is fundamentally incompatible. RESEARCH will validate wheel availability for Python 3.12 + the Lambda execution environment. Impact if wrong: Auth Lambda migrates to Fargate, adding ~1 week to P2.

Q2 — PAT revocation propagation latency

The 60-second SLO (NFR-4) depends on whether the token-vend Lambda reads PAT revocation state from DynamoDB on every request (eventually consistent reads) or via a cached/denylist mechanism.

Resolution (D-229): Read-on-every-request with strongly consistent reads on the PAT hash table. Cost is acceptable given expected request volume (token vending is not a hot path — it precedes a deploy, not every request). REV-351 verifies the SLO in CI. Confidence: 0.90. Rationale: Strongly consistent DynamoDB reads have single-digit-ms latency at expected volume; the 60s SLO has >10x headroom. A cache layer adds invalidation complexity that the SLO does not require. Impact if wrong: If read latency exceeds 60s under load, introduce a DynamoDB TTL + cache layer; SLO must be re-verified.

Q3 — JWKS endpoint: Lambda function URL vs. API Gateway

A function URL is simpler and cheaper but lacks throttling, WAF, and custom domains out of the box.

Resolution (D-230): Start with a Lambda function URL behind a custom domain; rate limiting configured at the DNS/CDN layer. API Gateway migration deferred to v1.19+ if throttling requirements grow. Confidence: 0.80. Rationale: The JWKS endpoint is public-key only (no secrets); the threat surface is low. Function URL + CDN rate- limiting covers the v1.28 volume. API Gateway is over-engineering until traffic patterns are known. Impact if wrong: If throttling becomes a requirement, API Gateway migration adds ~3-5 days.

Q4 — Mode resolver precedence with invalid NOVA_CLIENT_MODE value

What happens if the env var is set to something other than agent or interactive (e.g., NOVA_CLIENT_MODE=auto)?

Resolution (D-226): Invalid env var values are ignored, falling through to credential type. A warning is logged. Behavior is documented in the nova-cli README. This is a sub-clause of the mode-resolution priority decision. Confidence: 0.90. Rationale: Ignoring + warning is the least surprising behavior for an operator debugging mode issues. Failing hard would block legitimate workflows that set a stale/typo'd env var. Impact if wrong: Operators debugging mode issues may be confused; non-blocking.

Q5 — Service-account PAT vs. developer PAT in the same session

What if both credential types are available (e.g., a developer explicitly exports a service-account PAT)?

Resolution (D-226): The most recently acquired credential wins. Documented in nova auth login output. The credential type is what drives mode resolution (INV-14), so the operator sees which mode was selected and why. Confidence: 0.85. Rationale: "Most recent wins" is the simplest deterministic rule that matches operator mental models of "I just logged in as X." The audit event records the winning credential type, so the selection is traceable. Impact if wrong: Mode selection may surprise the operator; non- blocking, but nova auth status must make the active credential explicit.

Q6 — ABAC policy ownership and versioning

platform/abac/token-vend.policy is referenced, but who owns changes? How are policy versions tracked in audit?

Resolution (D-231): Policy changes require PR review; the policy version (git SHA) is recorded in every token-vend audit event. Owner: Platform Security. The policy file lives in the platform repo at platform/abac/token-vend.policy and is reviewed like any other production config. Confidence: 0.90. Rationale: Git SHA is the natural version identifier for a repo-resident policy; recording it in the audit event makes every allow/deny decision reconstructable to the exact policy text. Impact if wrong: Untracked policy changes could lead to unexpected allow/deny decisions in production, undermining audit defensibility.


Grounding gaps surfaced in pre-flight (auto-resolved)

G1 — The kj engine does not exist; the spec treats it as locked.

Resolution (D-227): The token-vend Lambda uses the existing kyverno-json engine (INV-4 swappable) as the ABAC evaluator. The policy at platform/abac/token-vend.policy is a kyverno-json policy. No new kj engine is built in v1.28. If a distinct kj engine is desired later, it is a separate research spike (not this milestone). Confidence: 0.95. Rationale: The repo already has a swappable policy engine (INV-4) implemented as kyverno-json. Building a second engine to do the same job violates the swappable-engine invariant's spirit. kyverno-json's evaluate semantics cover the spec's ABAC needs (subject, claims, resource, environment → allow/deny). Impact if wrong: If the user actually wants a new kj engine, v1.28 scope expands significantly (engine design + implementation + migration). This was flagged as caveat #3 in the approved plan; the recommended path (kyverno-json) is locked here.

G2 — The spec's INV-18..21, INV-34, INV-63/64/65 don't exist.

Resolution: Re-allocated as INV-12..INV-17 (see REQUIREMENTS.md §v1.28 Invariants). The 1:1 mapping:

  • INV-63 (mode observability) → INV-12
  • INV-64 (mode determinism) → INV-13
  • INV-65 (credential type encodes role) → INV-14
  • INV-18..21 (attestation invariants) → INV-15 (no AWS-managed identity), INV-16 (password storage), INV-17 (ABAC discipline). The spec's attestation invariants INV-18..21 are partially covered by existing invariants (INV-6 immutable audit) + INV-17; the JWS-from-PAT behavior (REQ-332) is a requirement, not a separate invariant, in this mapping.
  • INV-34 (MFA enforcement) → deferred to v1.21+ (out of scope per §2.2); no INV allocated in v1.28. Confidence: 0.85. Rationale: The mapping preserves the spec's intent without colliding with the repo's INV-1..11. INV-34 (MFA) is explicitly deferred per the spec's own §2.2 out-of-scope table. Impact if wrong: If the user wants the exact INV-18..21 semantics as separate invariants, INV-12..17 can be re-numbered; non-blocking.

G3 — The spec's CAP-025..030 collide with blockchain/pilot CAPs.

Resolution: Re-allocated as CAP-033..CAP-038 (see REQUIREMENTS.md §v1.28 + REQ-352). The 1:1 mapping:

  • CAP-025 (CLI subcommand surface) → CAP-033
  • CAP-026 (subcommand delegates to core/) → CAP-034
  • CAP-027 (layer matches wheel) → CAP-035
  • CAP-028 (Nova-idp auth flow) → CAP-036
  • CAP-029 (token-vend signs via KMS) → CAP-037
  • CAP-030 (PAT issuance + revocation) → CAP-038 Confidence: 1.0. Rationale: Existing CAP-025..032 are blockchain/pilot capabilities (STATE.md); re-use would corrupt the capability registry. The re-allocated IDs are the next available. Impact if wrong: None — this is a numbering decision, not a semantic one.

G4 — The spec's REQ-001..031 collide / don't exist.

Resolution: Re-allocated as REQ-323..REQ-353 (1:1 with the spec's REQ-001..031). Full text in REQUIREMENTS.md §v1.28. Max existing REQ = REQ-322. Confidence: 1.0. Rationale: Same as G3 — avoid collision, use next available range.

G5 — platform/abac/, nova/ subcommand dir, nova-idp-* Lambdas don't exist.

Resolution: These are greenfield deliverables of v1.28 execution phases, not pre-existing "locked architectures." RESEARCH will design them; PLAN will sequence them; EXECUTE will build them. The spec's "Operating Principle 1" (incremental delivery) is honored — v1.28 is net-new work. Confidence: 1.0. Rationale: The spec itself describes these as new ("introducing Nova-idp"). The mis-framing was in calling them "locked" — they are locked in scope, not in prior existence. Impact if wrong: None — this is a framing correction.


Decision ledger (v1.28 — D-226..D-231)

ID Title Confidence Load-bearing for
D-226 Mode resolution priority + invalid-env + dual-credential 0.90 REQ-327, INV-12, INV-13, INV-14
D-227 ABAC engine = kyverno-json (no kj engine built) 0.95 REQ-336, REQ-339, INV-17, NFR-9
D-228 Argon2id in Lambda: bundled wheels + pure-Python fallback + Fargate path 0.85 REQ-333, REQ-334, INV-16, NFR-8
D-229 PAT revocation: strongly-consistent DDB read-on-every-request, 60s SLO 0.90 REQ-342, REQ-343, REQ-351, NFR-4
D-230 JWKS endpoint: Lambda function URL + custom domain + CDN rate-limit 0.80 REQ-338, NFR-5
D-231 ABAC policy ownership: Platform Security, git SHA in audit 0.90 REQ-339, NFR-9

Assumptions logged (full autonomy, no human escalation)

  1. CodeArtifact is provisionable in AWS account 581513795199 (the pilot account). RESEARCH will confirm IAM permissions + repository creation. If not, v1.28 falls back to a private PyPI server or a Gitea-hosted wheel index; the CLI subcommand surface (REQ-324) and identity layer (REQ-333+) are unaffected.
  2. Python 3.12 is the target runtime for both the CLI wheel and the Lambda functions (spec §4 REQ-004.3). The repo's current Python version will be confirmed in RESEARCH; if it differs, the CLI pins 3.12 and Lambda uses the 3.12 runtime regardless.
  3. KMS asymmetric signing (RSA-2048 or ECDSA P-256) is available in the target account. RESEARCH will confirm. If only symmetric KMS is available, the token-vend Lambda uses symmetric signing + a public-key publication step (less ideal, but functional); INV-15 is unaffected.
  4. The Forge action (REQ-326) is the existing nova cli-action pattern, extended to both GitHub and Gitea marketplaces. The repo's current Forge/Gitea workflow conventions (.gitea/workflows/, deploy.yml@v1.25) are the baseline.
  5. MFA/TOTP code path ships in v1.28 (per spec §2.2) but enforcement for prod/dr is deferred to v1.21+. This is a doc/test-only path in v1.28 — no enforcement gate.

CLARIFY complete

All material ambiguities resolved at full autonomy (6 open questions + 5 grounding gaps → D-226..D-231, confidence ≥ 0.80). No human escalation triggered (all confidences ≥ 0.60 threshold). REQUIREMENTS.md updated with the decision ledger + invariants. Next: RESEARCH.


CLARIFY — v1.29 Reposplit + Identity Layer Bring-Live

Autonomy: full. Auto-resolution with assumption logging per config.autonomy.level: "full". No human escalation unless confidence < 0.60. The v1.29 spec is v1.1 (highly detailed — §7 resolves Q1-6, Q7 carried forward as a verification-gate dependency). This file records the v1.29 ambiguities and the scope-split grounding.


Method

The v1.29 spec ("Universal Feature Specification — Reposplit + Identity Layer Bring-Live", v1.1) is the most detailed spec the project has received: it includes BDD acceptance criteria, an 8-item M1.5 spike checklist, 7 decisions pre-drafted (D-232..238), 14 NFRs, and an explicit §7 resolving Q1-6. Clarify work focuses on (a) the scope split between acdl (CIAgent) and nova-platform-ops (out-of-band), (b) the kj identity (Go binary vs. the v1.28 kyverno-json re-mapping), and (c) the carried-forward Q7. Each ambiguity gets a decision ID (D-232+, continuing from v1.28's D-226..D-231), a resolution, a confidence score, and a rationale.


Prior-conversation resolutions (already locked, restated for the record)

These were resolved by the user-approved execution plan in the conversation that spawned v1.29.

Q-P1 — The spec creates a separate repo nova-platform-ops. CIAgent runs inside acdl. Where does the Terraform code land?

Resolution: Terraform modules (networking/kms/identity/contract-ingest/bootstrap/edge) are authored out-of-band in nova-platform-ops (operator-owned). CIAgent in acdl delivers only the acdl-side work (publish.yml, Gitea scrub, CFN archive, operator guide, consumer bump) and tracks the ops-side REQs as covered-reference (verification surface = the M1/M1.5/M2 cutover gates documented in the operator guide). Confidence: 1.0 (user-confirmed — "Author out-of-band in nova-platform-ops"). Decision: scope split documented in PROJECT.md §v1.29 + REQUIREMENTS.md §v1.29.

Q-P2 — The run scope. How far does this /ci-run go?

Resolution: Full milestone through the final phase (P0 → P1..P5 → P6 final review + audit + milestone ship, tag v1.28.6). Confidence: 1.0 (user-confirmed — "Full milestone through final phase"). Decision: n/a (execution scope, not a D-ID).

Q-P3 — Edge 8 / REQ-354 footnote: pilot consumer deploy bump. Handle how?

Resolution: Include a cross-project phase (P5) in this CIAgent run (multi-project mode is active). Bump nova-blockchain-exchange deploy.yml @v1.25@v1.29 + smoke test. Confidence: 1.0 (user-confirmed — "Cross-project phase in this run"). Decision: n/a (execution scope).


Spec-grounded resolutions (from §7 + §5)

Q1 — State bucket bootstrap on day-0 (resolved per spec §7.1)

Resolution: Manual one-time at the operator's secure scratch; Terraform then adopts it via terraform import. Avoids bootstrapping the bootstrapper. Confidence: 1.0 (spec §7.1 explicit). Decision: D-235 (tag-pin handoff) — the state bucket is one of the imported resources.

Q2 — pyproject.toml version bump (resolved per spec §7.2)

Resolution: Bump to 1.29.0 in M1 (P2 — Gitea scrub phase) of v1.29 alongside the Gitea scrub. Confidence: 1.0 (spec §7.2 explicit). Decision: n/a (implementation detail, tracked in PLAN.md P2).

Q3 — WAF cost (resolved per spec §7.3)

Resolution: Acceptable for the JWKS public surface; documented in operator-guide cost section (~$510/month per WebACL + per-request). Confidence: 1.0 (spec §7.3 explicit). Decision: documented in REQ-OPS-GUIDE AC.

Q4 — Coverage 73.8% — does this milestone drive it down further? (resolved per spec §7.4)

Resolution: Accept any further debt as carry-forward to the separate NFR milestone. New modules have ≥80% coverage; older code paths are unchanged. YELLOW carried without scope expansion. Confidence: 1.0 (spec §7.4 explicit). Decision: n/a (NFR carry-forward, not a v1.29 D-ID).

Q5 — CFN code deletion timing (resolved per spec §7.5)

Resolution: Archive to docs/archive/nova-idp-cfn-v1.28.md; deletion is a follow-up after the next pilot run verifies Terraform parity. Confidence: 1.0 (spec §7.5 explicit). Decision: REQ-369 AC (3).

Q6 — acdl-act-runner-role reuse (resolved per spec §7.6)

Resolution: Reuse the existing role for v1.29 to minimize IAM surface changes; scope narrow per REQ-360. Confidence: 1.0 (spec §7.6 explicit). Decision: covered by REQ-360 (IAM-NARROW).

Q7 — kj image verification dependency (CARRY-FORWARD per spec §7.7)

Resolution (carry-forward): M1 cutover is conditional on the M1.5 verification gate. Recommendation: Block M1 cutover until M1.5 passes. If M1.5 fails three consecutive rebuilds, defer to M2a and ship Nova-idp in read-only partial mode (no token issuance) until kj is verified. Impact if wrong: A live token-vend that signs with a broken ABAC path would let through a denied claim — fails closed only if ImageUri is verified pre-apply. Confidence: 0.92 (spec §7.7 explicit + D-236 cutover shape). Decision: D-236 (cutover shape + rollback procedure). This is the only outstanding carry-forward; CIAgent in acdl builds + publishes the image + the gate tests (P1), but the live 3-rebuild verification happens in nova-platform-ops CI (out-of-band). CIAgent does not block on it.


Grounding-gap resolutions (surfaced in pre-flight)

G1 — The spec's kj vs. v1.28's kj re-mapping

Ambiguity: v1.28 (D-227) re-mapped the spec's kj engine → kyverno-json (INV-4 swappable), explicitly stating "no new kj engine is built." v1.29 reintroduces kj as a compiled Go binary (platform/abac/kj-version.txt, pinned v0.0.3) embedded in an ECR container image. Is this a contradiction?

Resolution: No contradiction. v1.28's kj was a policy engine reference; v1.29's kj is a compiled Go binary (a distinct artifact). The kyverno-json engine remains the policy engine (INV-4). The v1.29 kj binary is invoked via subprocess.run(['/opt/kj/kj', 'apply', ...]) by the Lambda handler — it is a substrate binary, not a policy engine. The two coexist: kyverno-json evaluates ABAC policy; kj is the container image's static binary that the Lambda runtime executes. No collision. Confidence: 0.95 (spec §3.3 Edge 5 item 4 explicit + v1.28 D-227 scope). Decision: documented in PROJECT.md §v1.29 ID allocations + KJ-STATIC NFR.

G2 — REQ-363b sub-requirement numbering

Ambiguity: The spec uses REQ-363b for the Fargate defensive fallback. The repo's REQ namespace is REQ-NNN (numeric). How to record 363b?

Resolution: Keep REQ-363b as-is (sub-requirement of REQ-363). It is a distinct requirement (Fargate fallback, KJ-LOCKSTEP) but logically paired with REQ-363 (production substrate). The b suffix is unambiguous and matches the spec. No collision with any existing REQ. Confidence: 0.98 (spec explicit + no collision). Decision: n/a (naming convention).

G3 — REQ-370 gap

Ambiguity: The spec jumps from REQ-369 to REQ-371. Is REQ-370 missing or intentionally unused?

Resolution: Intentionally unused per the source spec. REQ-370 is a gap in the spec's numbering (likely a deleted/renumbered item during spec v1.0 → v1.1). v1.29 does not allocate REQ-370; it remains a reserved gap. Confidence: 0.90 (spec explicit gap, no content). Decision: n/a (spec fidelity).

G4 — Covered-reference REQs and CIAgent verification

Ambiguity: REQ-355, 356, 357, 358, 359, 360, 361, 362, 363, 363b, 364, 365, 366, 371 are authored in nova-platform-ops (out-of-band). How does CIAgent verify them? Are they human_needed?

Resolution: They are covered-reference, NOT human_needed. The verification surface is the M1/M1.5/M2 cutover gates documented in the operator guide (docs/operator-guide-platform-ops.md). The operator guide lists each covered-reference REQ with its cutover gate entry (M1/M1.5/M2). CIAgent verify marks them covered-reference and the final-phase audit confirms the operator guide documents all gates. Confidence: 0.94 (scope-split decision + spec §2.3 milestone gates). Decision: documented in REQUIREMENTS.md §v1.29 + REQ-OPS- GUIDE AC.


Assumptions (logged, not escalated — confidence ≥ 0.80)

  1. kj v0.0.3 is available at the pinned SHA in platform/abac/kj-version.txt and compiles with CGO_ENABLED=0 GOOS=linux GOARCH=amd64. RESEARCH will confirm the source repository
    • build commands. If the binary is not available, P1 (publish pipeline) cannot produce the ECR image; M1.5 gate fails by construction → M2a (Fargate toggle, same image) also fails → escalate (but this is a spec dependency, not a CIAgent ambiguity).
  2. ECR repository exists or is creatable in account 581513795199 for the kj image. RESEARCH will confirm. The repo name is not specified in the spec; the operator guide will document it.
  3. GitHub Releases is the artifact distribution channel (per REQ-354). The acdl/acdl repo is already on GitHub (the Gitea scrub in REQ-367 standardizes on GitHub). NOVA_FORGE_TOKEN (Gitea) is retained for nova-platform-ops releases only.
  4. The nova idp setup --apply terraform-delegation (REQ-369 AC 2) requires terraform to be on the operator's PATH. The CLI detects terraform via which terraform; if absent, it falls back to the CFN path with a deprecation warning (the CFN archive remains read-only reference, but the delegation is the preferred path).
  5. The M1.5 8-item spike (spec §3.3 Edge 5) is the verification gate. CIAgent in acdl authors the tests (test_idp_auth, test_kms_roundtrip, ABAC E2E) in P1; the live 3-rebuild run happens in nova-platform-ops CI. This is the Q7 carry-forward surface.

CLARIFY complete

All material ambiguities resolved at full autonomy (3 prior-conversation

  • 7 spec-grounded + 4 grounding-gap → D-232..D-238, confidence ≥ 0.80). Q7 is the only carry-forward (verification-gate dependency, not a blocking ambiguity). No human escalation triggered (all confidences ≥ 0.60 threshold). REQUIREMENTS.md updated with the decision ledger + invariants + NFR constraints. Next: RESEARCH.