docs(P00): revise plan — add P3 W0 (Gitea adapter) + W0.5 (kj substrate) + W6 (drift) + W7 (rotation) per SPEC-aws-deploy-platform-gaps
Folds SPEC §5.1/§5.2/§5.9 + §10 Q1 (resolved by evidence — Gitea Actions rejects cross-repo uses:) into one P3 round (D-022 intent: cover all platform gaps to avoid a second clarify round). W0 is the highest- priority gap; W0.5 (already done) fixes the v1.25 skip-masked kj bug; W6 fixes deploy.yml drifts (AWS_DEFAULT_REGION, ref v1.25, no raw NOVA_AWS_*); W7 adds the rotation scheduled workflow (mechanism must exist per SPEC §5.9). Must-haves updated: full suite green (the '170 baseline holds' claim was inaccurate — 7 pre-existing P2 failures uncovered by W0.5, all fixed). ---ci--- project: acdl phase: 0 milestone: v1.26 status: plan ---
This commit is contained in:
+125
-25
@@ -142,24 +142,77 @@ wiring reconciliation, + the pilot regression CAP. The Post-Pilot
|
||||
metrics are grounded (outcome backfill + escalation reason); the pilot-
|
||||
readiness + settlement-finality policies are in place.
|
||||
|
||||
**Project:** `acdl` (platform repo).
|
||||
**Project:** `acdl` (platform repo) + `nova-blockchain-exchange`
|
||||
(consumer repo — the Gitea adapter rewrites the consumer's `deploy.yml`).
|
||||
**Branch:** `acdl/phase/03-pilot-metrics-and-policies` (platform branch).
|
||||
**Personas:** backend-engineer (emitters + adapter + regression),
|
||||
data-engineer (DynamoDB primitive + env JSON + collector),
|
||||
policy-engineer (kyverno-json policies).
|
||||
policy-engineer (kyverno-json policies), lead-developer (Gitea adapter
|
||||
+ deploy.yml drift + rotation workflow).
|
||||
|
||||
### Wave 1 — DynamoDB primitive (REQ-322) — data-engineer
|
||||
- **Task 1.1** (data-engineer): `modules/l1/dynamodb/interface.json` —
|
||||
stack type `aws:dynamodb:table`, inputs (table_name, region, pk, sk,
|
||||
billing_mode), outputs (table_arn, table_name).
|
||||
- **Task 1.2** (data-engineer): `modules/l1/dynamodb/terraform/main.tf`
|
||||
— `resource "aws_dynamodb_table" "this"` (PK + optional SK,
|
||||
`PAY_PER_REQUEST` default, encryption + PITR enabled per v1.8 NFR).
|
||||
- **Task 1.3** (data-engineer): `modules/l1/dynamodb/README.md` +
|
||||
`instance.json`.
|
||||
- **Task 1.4** (data-engineer): `modules/registry.json` — `dynamodb`
|
||||
entry (kind `l1`, `terraform_dir`).
|
||||
- **Task 1.5** (data-engineer): `modules/README.md` — catalog index.
|
||||
### Wave 0 — Gitea reusable-workflow adapter (SPEC §10 Q1, resolved by evidence) — lead-developer + blockchain-engineer
|
||||
> **Highest-priority gap.** The v0.2 P3 `workflow_dispatch` (Gitea
|
||||
> Actions run id=6199) failed: Gitea Actions rejects cross-repo `uses:`
|
||||
> (`acdl/.github/workflows/deploy.yml@v1.25`) with `expected format
|
||||
> {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}`. The
|
||||
> consumer's `deploy.yml` is frozen at the v0.1 byte-identical mirror;
|
||||
> the platform adapts (option c — inline checkout-then-call), not
|
||||
> vice-versa.
|
||||
- **Task 0.1** (lead-developer): rewrite
|
||||
`nova-blockchain-exchange/.gitea/workflows/deploy.yml` + byte-identical
|
||||
`.github/workflows/deploy.yml` — drop the `uses:` indirection; single
|
||||
`deploy` job on `ubuntu-latest` that `actions/checkout@v4` the consumer,
|
||||
`actions/checkout@v4` `acdl/acdl` @ `ref: v1.25` into `platform/`,
|
||||
setup-python 3.12, install deps (jsonschema/pyyaml/boto3 + checkov),
|
||||
install Terraform 1.9.*, configure AWS (static-key path:
|
||||
`aws-region: ${{ secrets.AWS_DEFAULT_REGION }}`, `access-key-id` +
|
||||
`secret-access-key` from `NOVA_AWS_*` secrets; no OIDC token minted),
|
||||
run `bash platform/scripts/run_platform.sh $MODE_FLAG $ENV_FLAG
|
||||
contract.yaml`. Preserve `on: workflow_dispatch` inputs (mode choice
|
||||
default full; environment choice default "") + `permissions: {id-token:
|
||||
write, contents: read}` + `secrets: inherit`.
|
||||
- **Task 0.2** (blockchain-engineer): update
|
||||
`nova-blockchain-exchange/tests/test_deploy_workflow_invocation.py` +
|
||||
`test_deploy_gitea_invocation.py` — assert no cross-repo `uses:`,
|
||||
assert `ref: v1.25`, assert `secrets: inherit`, assert
|
||||
`run_platform.sh` invoked, assert `AWS_DEFAULT_REGION` wired.
|
||||
- **Task 0.3** (lead-developer): `acdl/.github/workflows/deploy.yml`
|
||||
stays as the GitHub Actions reference impl (the `workflow_call`
|
||||
reusable workflow — used by GitHub-hosted consumers); document in
|
||||
`adapters/README.md` that Gitea consumers use the inline adapter, not
|
||||
the reusable `uses:`.
|
||||
|
||||
### Wave 0.5 — kyverno-json substrate fix (v1.25 skip-masked bug) — backend-engineer
|
||||
> The v1.25 kyverno-json engine + policies were never validated
|
||||
> against the real `kj` binary (tests `pytest.skip("kj not installed")`
|
||||
> when absent). With `kj` now installed (v0.0.3), 3 policy tests
|
||||
> failed. Root cause: (a) `kj` v0.0.3 does not load `.json` policy
|
||||
> files (only `.yaml`/`.yml`) — the engine now materializes `.yaml`
|
||||
> twins at runtime; (b) the `validate` wrapper is not supported —
|
||||
> `assert` goes directly under the rule; (c) the check syntax was
|
||||
> inverted (`expression: expected_value`, not `key: expression`);
|
||||
> (d) the engine `_translate` expected `{"results": [...]}` but `kj`
|
||||
> returns a bare list with `results[].policy.metadata.name` +
|
||||
> `results[].rules[].violations[]`. DONE (committed 59d837f). Also
|
||||
> fixed `scripts/install-kyverno-json.sh` (the `cmd/kj@latest` path
|
||||
> fails — the real binary is `kyverno-json`, symlinked as `kj`).
|
||||
- **Task 0.5.1** (backend-engineer): rewrite
|
||||
`adapters/kyverno-json/kyverno_json_engine.py` `_translate` for the
|
||||
bare-list output format + add `_materialize_yaml_policy_dir` (DONE).
|
||||
- **Task 0.5.2** (backend-engineer): remove the `validate` wrapper +
|
||||
fix check syntax across all 16 existing policies (DONE).
|
||||
- **Task 0.5.3** (backend-engineer): fix
|
||||
`scripts/install-kyverno-json.sh` (DONE).
|
||||
- **Task 0.5.4** (backend-engineer): resolve pre-existing P2 drift
|
||||
uncovered by the full-suite run — dynamodb `examples/simple.yml` +
|
||||
`complex.yml`, `sync_workflows` re-sync, CAP-024 deck path
|
||||
(`nova-autonomous-cloud-delivery-marp.md`) + slide-count bound +
|
||||
`class="benefit"` div count (DONE, committed 3735330).
|
||||
|
||||
### Wave 1 — DynamoDB primitive (REQ-322) — data-engineer — verify-only (done in P2 W0)
|
||||
- **Task 1.1** (data-engineer): verify `modules/l1/dynamodb/` resolves
|
||||
+ emits valid Terraform via `tests/test_adapter.py` (the primitive
|
||||
shipped in P2 W0; this wave is a re-verify, not re-authoring).
|
||||
|
||||
### Wave 2 — metric grounding (REQ-317, REQ-318) — backend-engineer + data-engineer — parallel
|
||||
- **Task 2.1** (backend-engineer): `core/metrics/outcome_backfill.py` —
|
||||
@@ -204,26 +257,73 @@ policy-engineer (kyverno-json policies).
|
||||
— kyverno-json policy over env JSON (asserts
|
||||
`account_id != "000000000000"`).
|
||||
- **Task 4.3** (policy-engineer): `tests/test_settlement_finality_policy.py`
|
||||
— passing + failing fixtures; skip when `kj` absent.
|
||||
— passing + failing fixtures; **runs against real `kj`** (not skipped
|
||||
— `kj` is installed via `scripts/install-kyverno-json.sh`).
|
||||
- **Task 4.4** (policy-engineer): `tests/test_pilot_readiness_policy.py`
|
||||
— passing (real account) + failing (placeholder) fixtures; skip when
|
||||
`kj` absent.
|
||||
— passing (real account) + failing (placeholder) fixtures; **runs
|
||||
against real `kj`** (not skipped).
|
||||
|
||||
### Wave 5 — regression CAP (REQ-316) — backend-engineer
|
||||
- **Task 5.1** (backend-engineer): `core/regression_verify.py` —
|
||||
CAP-025 (live-pilot-apply): the round-trip assertion.
|
||||
- **Task 5.2** (backend-engineer): `tests/test_regression_pilot.py`.
|
||||
|
||||
### Wave 6 — deploy.yml drift fixes (SPEC §5.1/§5.2) — lead-developer + backend-engineer
|
||||
> The platform reference `workflows-src/deploy.yml` (synced to
|
||||
> `.github`+`.gitea`) has three drifts vs the SPEC: (a) `aws-region`
|
||||
> hardcoded `us-east-1` (SPEC wants `NOVA_AWS_REGION`/`AWS_DEFAULT_REGION`
|
||||
> from secret); (b) platform checkout `ref: v1.9` (SPEC wants `v1.25`);
|
||||
> (c) the local `scripts/run_platform.sh` fallback exports raw
|
||||
> `NOVA_AWS_*` names into shell env (SPEC §5.2 constraint: consume as
|
||||
> workflow secrets, not shell env — `blocked_env_vars`).
|
||||
- **Task 6.1** (lead-developer): `workflows-src/deploy.yml` —
|
||||
`aws-region: ${{ secrets.AWS_DEFAULT_REGION || 'us-east-1' }}`;
|
||||
platform checkout `ref: v1.25`; re-sync to `.github`+`.gitea`.
|
||||
- **Task 6.2** (backend-engineer): `scripts/run_platform.sh` — source
|
||||
`AWS_DEFAULT_REGION` from `.env.secrets` for the local fallback (not
|
||||
raw `NOVA_AWS_*`); the CI path already consumes secrets via the
|
||||
`configure-aws-credentials` action.
|
||||
- **Task 6.3** (backend-engineer): `tests/test_deploy_workflow_env_input.py`
|
||||
— assert `AWS_DEFAULT_REGION` wired + `ref: v1.25` + no raw
|
||||
`NOVA_AWS_*` in shell env.
|
||||
|
||||
### Wave 7 — secret rotation scheduled workflow (SPEC §5.9) — lead-developer
|
||||
> SPEC §5.9: "the rotation mechanism must *exist* (not have run)."
|
||||
> A platform-managed scheduled workflow wraps the existing
|
||||
> `scripts/rotate_spike_key.sh` (manual today) on a daily cron.
|
||||
- **Task 7.1** (lead-developer): `workflows-src/rotate-aws-key.yml` —
|
||||
`on: { schedule: [{cron: "0 0 * * *"}], workflow_dispatch:}`,
|
||||
single job that checks out the platform repo + runs
|
||||
`bash scripts/rotate_spike_key.sh` with `NOVA_AWS_*` bootstrap
|
||||
secrets; sync to `.github`+`.gitea`.
|
||||
- **Task 7.2** (lead-developer): verify `scripts/rotate_spike_key.sh`
|
||||
is idempotent (deactivates old key only after the new key propagates
|
||||
to the Gitea Actions secret store).
|
||||
- **Task 7.3** (lead-developer): `tests/test_rotate_key_workflow.py` —
|
||||
structural test (the workflow file declares `schedule` + invokes
|
||||
`rotate_spike_key.sh`); document in `.ciagent/ARCHITECTURE.md` §12.8
|
||||
that the mechanism exists (v0.2 scope: exists-not-ran per SPEC §5.9).
|
||||
|
||||
**Must-haves (verify before ship):**
|
||||
- `pytest tests/` in the platform repo passes (170 existing + new tests).
|
||||
- The DynamoDB primitive resolves + emits valid Terraform.
|
||||
- The outcome backfill updates `fact_decision.outcome` (not `pending`).
|
||||
- The `escalation_reason` field is emitted on `block` band.
|
||||
- The adapter reads `env.state_backend.bucket` from the env JSON.
|
||||
- `pytest tests/` in the platform repo passes (the 170 baseline held
|
||||
inaccurately — the real P2 baseline had 7 pre-existing failures
|
||||
uncovered by W0.5; all now fixed). Full suite green.
|
||||
- `pytest tests/` in the consumer repo passes (deploy invocation tests
|
||||
updated for the inline adapter).
|
||||
- The kyverno-json substrate works against real `kj` (W0.5 — DONE).
|
||||
- The Gitea adapter: consumer `deploy.yml` has no cross-repo `uses:`;
|
||||
inline checkout `acdl@v1.25` + `run_platform.sh` (W0).
|
||||
- The DynamoDB primitive resolves + emits valid Terraform (W1 verify).
|
||||
- The outcome backfill updates `fact_decision.outcome` (not `pending`)
|
||||
(W2).
|
||||
- The `escalation_reason` field is emitted on `block` band (W2).
|
||||
- The adapter reads `env.state_backend.bucket` from the env JSON (W3).
|
||||
- The 2 new kyverno-json policies pass on valid fixtures + fail on
|
||||
invalid fixtures (skip when `kj` absent).
|
||||
- CAP-025 is in the regression gate.
|
||||
- No existing tests regress (170 baseline holds).
|
||||
invalid fixtures, against real `kj` (W4 — not skipped).
|
||||
- CAP-025 is in the regression gate (W5).
|
||||
- The deploy.yml drifts fixed: `AWS_DEFAULT_REGION` wired, `ref:
|
||||
v1.25`, no raw `NOVA_AWS_*` in shell env (W6).
|
||||
- The rotation scheduled workflow exists (W7).
|
||||
|
||||
**Ship:** tag `v1.25.3`, merge `phase/03` → milestone, Gitea release.
|
||||
Delete `phase/03`.
|
||||
|
||||
Reference in New Issue
Block a user