d8240588c9
---ci--- project: acdl phase: 0 milestone: v1.24 status: plan ---/ci---
180 lines
8.7 KiB
Markdown
180 lines
8.7 KiB
Markdown
# PLAN — v1.24 (Consumer Guide Accuracy & Env-Promotion Lifecycle Enforcement)
|
|
|
|
> Feature milestone (one `feat` phase: env-transition destroy enforcement;
|
|
> the rest are `fix`/`docs`/`test`). Tags on the **v1.23.x** line:
|
|
> v1.23.0 (P0) → v1.23.1 (P1) → v1.23.2 (P2) → v1.23.3 (P3) → v1.23.4 (P4
|
|
> final = milestone release). 15 requirements (REQ-276..290), 4 phases +
|
|
> P0 pre-execution.
|
|
|
|
## Phase breakdown
|
|
|
|
### Phase P1 — consumer-guide-fixes (Wave 1, lead-developer)
|
|
|
|
**Type:** `docs` + `fix` + `test` (consumer guide accuracy + guide test updates)
|
|
|
|
**Requirements:** REQ-276, REQ-277, REQ-278, REQ-279, REQ-280, REQ-281, REQ-290
|
|
|
|
**Must-haves:**
|
|
- `docs/consumer-guide.md` Step 3 contract fields table corrected (REQ-276)
|
|
- `docs/consumer-guide.md` Step 4 caller consistent with Step 2 (REQ-277)
|
|
- `docs/consumer-guide.md` Step 5 stage 8 "(dev only)" → "(autonomous in dev; higher environments apply after HITL attestation)" (REQ-278)
|
|
- `docs/consumer-guide.md` Step 8 rewritten with destroy-then-rebuild semantics + cross-ref to Shape B (REQ-279)
|
|
- `docs/consumer-guide.md` Per-env section gains Shape B lead sentence (REQ-280)
|
|
- `docs/consumer-guide.md` Reference table `@v1.19` wording corrected (REQ-281)
|
|
- `tests/test_consumer_guide_per_env_section.py` updated: rename `test_consumer_guide_states_no_field_editing` → `test_consumer_guide_documents_both_promotion_shapes`; add `test_consumer_guide_documents_destroy_on_env_change` (REQ-290)
|
|
|
|
**Vertical slice:** A reader of `docs/consumer-guide.md` can promote via
|
|
either shape (A: edit environment + platform destroys prior; B: per-env
|
|
caller workflow) without contradiction. The guide's field table, caller
|
|
examples, and stage descriptions match the actual schema and platform
|
|
behavior. All consumer-guide tests pass.
|
|
|
|
**Files touched:**
|
|
- `docs/consumer-guide.md`
|
|
- `tests/test_consumer_guide_per_env_section.py`
|
|
|
|
**Verification:** `pytest tests/test_consumer_guide_per_env_section.py -v`
|
|
(all 7 tests pass). Manual read of `docs/consumer-guide.md` end-to-end
|
|
for internal consistency.
|
|
|
|
---
|
|
|
|
### Phase P2 — env-transition-detect-and-destroy (Wave 2, backend-engineer)
|
|
|
|
**Type:** `feat` (new platform feature: env-transition detect-and-destroy)
|
|
|
|
**Requirements:** REQ-282, REQ-283, REQ-284, REQ-285, REQ-286, REQ-287
|
|
|
|
**Must-haves:**
|
|
- `core/env_transition.py` new module: `detect_prior_env()` + `record_applied_env()` with boto3 DynamoDB queries (REQ-282, REQ-283)
|
|
- `scripts/run_platform.sh` Step 0b: environment-transition check — detect prior env, re-resolve with `environment_override=prior_env` + `deletion_protection=false`, `terraform init -reconfigure` + `terraform destroy -auto-approve` against prior state key, emit `nova.env.destroyed` evidence event, fail closed on destroy failure (REQ-284)
|
|
- `scripts/run_platform.sh` records applied env after successful apply (REQ-285)
|
|
- `.github/workflows/deploy.yml` passes `NOVA_CONSUMER_REPO=${{ github.repository }}` to `run_platform.sh` (REQ-286)
|
|
- `adapters/terraform/adapter.py` state-key block gains doc comment (REQ-287)
|
|
|
|
**Vertical slice:** When a consumer changes `environment:` on a stable
|
|
`contract.id`, the pipeline detects the prior env from DynamoDB, destroys
|
|
the prior env's Terraform state (with `deletion_protection=false`), emits
|
|
an evidence event, and only then applies the new env. If the destroy
|
|
fails, the pipeline exits non-zero (no orphan path). If no prior env
|
|
exists (first deploy or Shape B), the pipeline proceeds normally.
|
|
|
|
**Files touched:**
|
|
- `core/env_transition.py` (NEW)
|
|
- `scripts/run_platform.sh`
|
|
- `.github/workflows/deploy.yml`
|
|
- `adapters/terraform/adapter.py` (doc comment only)
|
|
|
|
**Verification:** `python3 -m py_compile core/env_transition.py`.
|
|
`pytest tests/test_pipeline.py tests/test_deploy_workflow_env_input.py -v`
|
|
(existing tests still pass). The new tests in P3 validate the behavior.
|
|
|
|
**Key implementation notes (from RESEARCH §5 pitfalls):**
|
|
1. The destroy step must re-resolve with `environment_override=prior_env`
|
|
so the emitted TF matches the prior env's resources.
|
|
2. `terraform init -reconfigure` is required when switching state backends.
|
|
3. `deletion_protection: false` must be injected (same as decommission
|
|
Step 2 in `scripts/run_decommission.sh:34-37`) or `prevent_destroy`
|
|
blocks the destroy.
|
|
4. DynamoDB unreachable in local/CI → log warning + return `None`
|
|
(conservative, no prior env assumed).
|
|
5. The state key `spike/{id}/{env}/terraform.tfstate` stays as-is — the
|
|
env segment is what lets the destroy target the prior env.
|
|
|
|
---
|
|
|
|
### Phase P3 — env-transition-tests (Wave 3, backend-engineer + lead-developer)
|
|
|
|
**Type:** `test` (new test coverage for env-transition + pipeline integration)
|
|
|
|
**Requirements:** REQ-288, REQ-289
|
|
|
|
**Must-haves:**
|
|
- `tests/test_env_transition.py` (NEW): `detect_prior_env` returns `None` when no record; returns prior env when record differs; returns `None` when record matches; `record_applied_env` writes record. Uses moto for DynamoDB (REQ-288)
|
|
- `tests/test_run_platform_env_transition.py` (NEW): asserts `run_platform.sh` has Step 0b; calls `env_transition.py detect`; calls `terraform destroy` on prior env; fails closed on destroy failure; records applied env after success (REQ-289)
|
|
|
|
**Vertical slice:** The env-transition detect-and-destroy behavior is
|
|
fully covered by automated tests. The DynamoDB query logic is unit-tested
|
|
with moto. The pipeline orchestration is tested via shell-text assertions
|
|
(pattern from `tests/test_pipeline.py:79-95`).
|
|
|
|
**Files touched:**
|
|
- `tests/test_env_transition.py` (NEW)
|
|
- `tests/test_run_platform_env_transition.py` (NEW)
|
|
|
|
**Verification:** `pytest tests/test_env_transition.py tests/test_run_platform_env_transition.py -v` (all new tests pass). Full suite: `pytest tests/ -k "env_transition or consumer_guide or pipeline or adapter or deploy_workflow" -v`.
|
|
|
|
---
|
|
|
|
### Phase P4 — final-review-ship (Wave 4, lead-developer)
|
|
|
|
**Type:** `docs` (review + audit + milestone ship)
|
|
|
|
**Requirements:** (none new — milestone completion)
|
|
|
|
**Must-haves:**
|
|
- Multi-persona code review across P1-P3 changes (ci-code-reviewer)
|
|
- Project health audit (ci-doc-verifier + ci-audit)
|
|
- Milestone ship: tag v1.23.4 (final phase patch = milestone release), merge to main, Gitea release
|
|
- Update REQUIREMENTS.md traceability (all REQ-276..290 → complete)
|
|
- Update ROADMAP.md (v1.24 → complete)
|
|
|
|
---
|
|
|
|
## Wave ordering
|
|
|
|
```
|
|
Wave 1 (P1): consumer-guide-fixes [lead-developer]
|
|
↓
|
|
Wave 2 (P2): env-transition-detect-and-destroy [backend-engineer]
|
|
↓
|
|
Wave 3 (P3): env-transition-tests [backend-engineer + lead-developer]
|
|
↓
|
|
Wave 4 (P4): final-review-ship [lead-developer]
|
|
```
|
|
|
|
**Dependencies:**
|
|
- P2 depends on P1: the Step 8 rewrite in P1 documents the destroy
|
|
semantics that P2 implements. Doing P1 first ensures the docs and code
|
|
land in the right order (docs describe the intended behavior, then code
|
|
implements it).
|
|
- P3 depends on P2: the tests validate the env-transition module and
|
|
pipeline Step 0b that P2 creates.
|
|
- P4 depends on P1+P2+P3: the final review covers all changes.
|
|
|
|
**Parallelization:** P1 and P2 could run in parallel (different
|
|
territories: docs vs code), but the wave ordering is sequential for
|
|
safety — if P1's Step 8 rewrite reveals a design issue, P2's
|
|
implementation should follow the corrected design. With
|
|
`parallelization.enabled=true` and `min_plans_for_parallel=2`, the
|
|
orchestrator *could* run them concurrently; however, the dependency
|
|
(P2 follows P1's design) makes sequential the safer choice. P3 must
|
|
follow P2 (tests validate the code). P4 must follow all.
|
|
|
|
## Requirement → Phase mapping
|
|
|
|
| REQ | Phase | Type | Description |
|
|
|-----|-------|------|-------------|
|
|
| REQ-276 | P1 | docs | Contract fields table corrected |
|
|
| REQ-277 | P1 | docs | Step 4 caller consistent with Step 2 |
|
|
| REQ-278 | P1 | docs | Step 5 stage 8 "dev only" corrected |
|
|
| REQ-279 | P1 | docs | Step 8 rewritten with destroy semantics |
|
|
| REQ-280 | P1 | docs | Per-env section Shape B lead sentence |
|
|
| REQ-281 | P1 | docs | Reference table @v1.19 wording corrected |
|
|
| REQ-282 | P2 | feat | env_transition.py detect_prior_env() |
|
|
| REQ-283 | P2 | feat | env_transition.py record_applied_env() |
|
|
| REQ-284 | P2 | feat | run_platform.sh Step 0b detect-and-destroy |
|
|
| REQ-285 | P2 | feat | run_platform.sh records applied env |
|
|
| REQ-286 | P2 | feat | deploy.yml passes NOVA_CONSUMER_REPO |
|
|
| REQ-287 | P2 | docs | adapter.py state-key doc comment |
|
|
| REQ-288 | P3 | test | test_env_transition.py |
|
|
| REQ-289 | P3 | test | test_run_platform_env_transition.py |
|
|
| REQ-290 | P1 | test | consumer guide test updates |
|
|
|
|
## Tag plan
|
|
|
|
- P0 (this phase): `v1.23.0` — pre-execution patch
|
|
- P1: `v1.23.1` — consumer guide fixes
|
|
- P2: `v1.23.2` — env-transition detect-and-destroy
|
|
- P3: `v1.23.3` — env-transition tests
|
|
- P4: `v1.23.4` — final review + ship = **milestone release** |