---ci--- project: acdl phase: 0 milestone: v1.28 status: clarify ---/ci---
14 KiB
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)
- 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. - 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.
- 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.
- The Forge action (REQ-326) is the existing
nova cli-actionpattern, extended to both GitHub and Gitea marketplaces. The repo's current Forge/Gitea workflow conventions (.gitea/workflows/,deploy.yml@v1.25) are the baseline. - 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.