Phase 2b confirm-and-document outcome: per-recipe test-sequence deploy budget is already minimal — `deploys == 1 (base, shared by all 5 tiers) + N_cold_deps` — and tighter than plan B1's nominal `1+1(upgrade)+N` because the upgrade is an in-place chaos redeploy of the prev-version base, not a separate deploy. Enforced as a hard failure by DG4.1 (expected = 1 + deps_deployed_count, run_recipe_ci.py:1005-1010). No redundant deploy found; none removed (none existed). - docs/perf/deploys.md: the budget record (B4), names the out-of-budget WC5 reseed - STATUS-2b.md: B1-B4 claim with WHAT/HOW/EXPECTED/WHERE for cold verify - JOURNAL-2b.md / BACKLOG-2b.md / DECISIONS.md: reasoning + settled note - consume machine-docs/BUILDER-INBOX.md (Adversary heads-up processed) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.2 KiB
JOURNAL — Phase 2b (reasoning; WHY) — confirm minimal deploy budget
2026-05-31 — Bootstrap + analysis (Builder)
Operator manually kicked off Phase 2b (narrowed scope, plan §0): the ONLY task is to confirm the
per-recipe test sequence uses the minimum number of deploys, and fix it if not, without weakening any
test. Broad empirical-perf work is parked in IDEAS. Phase 2 is not yet ## DONE (plausible/drone/Q5
remain), but B1–B4 are a property of the already-existing harness, so the analysis is independent of
Phase-2 completion.
Method
Traced every abra app deploy/upgrade/new path through the harness. Key realization: the only
thing that increments the DG4.1 deploy counter is lifecycle._record_deploy(), and it is called from
exactly one place — inside lifecycle.deploy_app (:211). So "deploy count" == number of deploy_app
calls in a run. Enumerated all deploy_app callers: base deploy (run_recipe_ci.py:819), per-dep
(deps.py:100), and WC5 promote (:699, which pops the countfile first so it's outside the budget).
Why the budget is minimal (and tighter than plan B1's nominal text)
Plan B1 frames the minimum as 1 base + 1 upgrade + N_deps, assuming the upgrade tier needs its own
prior-version deploy. The cc-ci design avoids that: when the upgrade tier runs, the base deploy is
done at the previous published version (base = prev or target, :746-754), and the upgrade is an
in-place chaos redeploy of PR-head onto that same app (perform_upgrade → chaos_redeploy, which
does NOT call deploy_app). So the prior-version deploy and the base deploy are the SAME deploy — the
upgrade tier adds zero deploys. backup/restore also operate on the same app. Net: 1 + N_cold_deps.
This is the deploy-sharing the operator expected; nothing to remove because nothing is redundant.
Why I trust the enforcement (B2 is real, not vacuous)
run_recipe_ci.py:1005-1010 turns deploy_count != expected_deploy_count into a non-zero exit. So
every GREEN run is itself a proof the recipe stayed within 1 + N_cold_deps — a redundant redeploy
would push the count over and fail the run red. The historical Phase-2 runs (recorded in
STATUS-2/REVIEW-2) corroborate: every recipe ran at deploy-count = 1, or 2 (expect 2) for the one
cold-dep recipe (lasuite-docs + cold keycloak). Warm keycloak (lasuite-meet) → 0 dep deploys → expect 1.
Why B3 holds
Sharing one deploy does not skip assertions: all five tiers still run their generic+overlay assertions
against the shared app; upgrade is a real prev→PR-head crossover verified by assert_upgraded; P4
backup→restore is real data-integrity; per-run isolation/teardown is unchanged. Only the deploy COUNT
is constrained, never the coverage.
Cross-loop note
The Adversary's independent pre-claim cold trace (REVIEW-2b @05:33Z) reached the identical conclusion
and flagged exactly one completeness item: the B1/B4 doc must NAME the WC5 green-cold reseed
(run_recipe_ci.py:699) — one additional uncounted abra app new for canonical warm-cache
maintenance, outside the test-sequence budget. docs/perf/deploys.md addresses this in its
"Out of scope of the budget (intentionally)" section, and STATUS-2b names it in verify-step (a).
Claimed B1–B4 accordingly.