review(1e): E1/HC3 FAIL — opt-out surfaces backup/restore race (F1e-1); additive+count=1 confirmed, PASS withheld
This commit is contained in:
@ -44,3 +44,31 @@ Verdict: **PASS** — default-secure, centralized gate, flips only on explicit p
|
||||
hostile repo-local code provably not executed under the shipped default. No finding.
|
||||
**Note (not a defect):** orchestrator still uses single-file override `resolve_op` (1d semantics);
|
||||
the additive generic floor (HC3) is E1 in-flight — will re-check the gate survives the HC3 refactor.
|
||||
|
||||
### E1 / HC3 — additive generic + op/assertion split — FAIL (PASS WITHHELD) @2026-05-28
|
||||
Builder claim (STATUS-1e gate, commit b7e6cbd): generic runs additively alongside overlays;
|
||||
orchestrator owns each op (once); opt-out via `CCCI_SKIP_GENERIC[_<OP>]`/`recipe_meta.SKIP_GENERIC`;
|
||||
deploy-count stays 1; two e2e (default + opt-out) "clean."
|
||||
|
||||
**Cold verification (own clone HEAD=b7e6cbd shipped to cc-ci `/tmp/adv-1e`, run via `cc-ci-run`):**
|
||||
- **Structure (PASS):** read the refactor — `run_lifecycle_tier` performs the op ONCE
|
||||
(`_perform_op`→`generic.perform_{upgrade,backup,restore}`, none call `deploy_app`), then runs generic
|
||||
(unless `_skip_generic`) + overlay as separate pytests vs the shared post-op state. Generic+overlay
|
||||
test files are assertion-only; seeding moved to `ops.py pre_<op>`. `assert_upgraded` keeps the
|
||||
non-vacuous move check (F1d-2). `_record_deploy()` lives only in `deploy_app`.
|
||||
- **Default e2e** (custom-html, all stages): EVERY tier ran BOTH `assert (generic)` AND
|
||||
`assert (cc-ci)`; pre_upgrade/backup/restore seeds fired; **deploy-count=1**; install/upgrade/backup/
|
||||
restore all PASS; custom=skip; clean teardown (no leftover stack/volume). ✓ additive confirmed.
|
||||
- **Opt-out e2e** (`CCCI_SKIP_GENERIC=1`): generic skipped on every tier (**0** `_generic/` files ran),
|
||||
overlay-only, **deploy-count=1** ✓ — **but backup=FAIL**: `test_backup_captures_state` →
|
||||
`AssertionError: '' == 'original'`. Same code/recipe; only diff is the opt-out flag.
|
||||
|
||||
**Verdict: FAIL — opt-out is not behavior-neutral.** Opting out of the generic removes an accidental
|
||||
~1s timing buffer (the generic pytest spawn) and surfaces a real race: the backup/restore overlays
|
||||
read the marker via `exec_in_app` immediately after a container-cycling op with no readiness/retry, and
|
||||
`exec_in_app` silently returns empty stdout on a failed `docker exec` (returncode ignored). A healthy
|
||||
recipe can thus be reported RED under opt-out. Filed **F1e-1 [adversary]** (BACKLOG-1e) with root cause
|
||||
+ repro + fix direction (check exec returncode + bounded readiness retry; do NOT weaken the assertion).
|
||||
Isolated (no-concurrency) reproduction in flight to rule out the parallel-Builder-run confound — which
|
||||
would itself be a concurrency-collision finding. **HC3 PASS withheld until F1e-1 is fixed + re-verified
|
||||
cold under opt-out.**
|
||||
|
||||
Reference in New Issue
Block a user