plan: phases dstamp, mailu, kuma, drone (queued after bsky) + journal
- dstamp: attribute + fix the discourse abra-stamp drift (env change 06-05→ 06-10, harness-neutral, currently pinning discourse at L1); blast-radius sweep; HC1 keeps its teeth - mailu: backupbot v2 labels recipe PR, restore proven on real seeded mail, backup rung earned instead of skipped (operator approved re-entry) - kuma: uptime-kuma first-run wizard + create-a-monitor functional test (Socket.IO or Playwright, real probe evidence, flake-checked) - drone: gitea-dep enrollment, maximal subset per Phase-2 scoping; P0 /etc/timezone host deploy is orchestrator-owned (3bde76f committed)
This commit is contained in:
@ -446,3 +446,15 @@ session cc-ci-orchestrator-stale can be killed; recipe-mirrors org still private
|
||||
in rcust M2; DEFERRED carries the re-pin follow-up. Deliverable = green recipe-mirror
|
||||
PR (operator merges) + verified screenshot on the PR runs; DEFERRED entries closed.
|
||||
- .phases-spec now rcust;shot;lvl5;bsky (idx still lvl5); watchdog bounce to load.
|
||||
|
||||
## 2026-06-11 ~12:05 — four more phases queued + DEFERRED housekeeping (operator)
|
||||
- Queue now: bsky (in progress, idx 3) → dstamp (discourse abra-stamp drift dig) →
|
||||
mailu (backupbot labels recipe PR) → kuma (uptime-kuma create-a-monitor test) →
|
||||
drone (gitea-dep enrollment; P0 host /etc/timezone deploy is MINE — nixos-rebuild
|
||||
switch on cc-ci host with committed 3bde76f, do it before/when phase drone starts or
|
||||
when STATUS-drone flags BLOCKED).
|
||||
- DEFERRED.md housekept (cc-ci 823023a): closed plausible-enrollment, discourse-bitnami,
|
||||
immich-pgdump (PR#2 merge-pending), plausible-Q4.7b (PR#3 merge-pending); re-entered
|
||||
mailu/drone/kuma/dstamp/bsky with plan pointers. Operator confirmed immich PR#2 +
|
||||
plausible PR#3 are good — merges pending on operator.
|
||||
- ORCHESTRATOR ACTION ITEM: deploy /etc/timezone host fix for phase drone P0.
|
||||
|
||||
85
cc-ci-plan/plan-phase-drone-enroll.md
Normal file
85
cc-ci-plan/plan-phase-drone-enroll.md
Normal file
@ -0,0 +1,85 @@
|
||||
# Phase `drone` — enroll the drone recipe (with gitea SCM dependency)
|
||||
|
||||
**Mission (operator-specified 2026-06-11):** enroll drone — the last §5 recipe — in
|
||||
cc-ci. Drone is a CI server that requires a git-provider SCM to boot; the viable dep is
|
||||
gitea. Ship the MAXIMAL SUBSET scoped in Phase 2 (JOURNAL-2 `f86a58a`): drone boots with
|
||||
gitea SCM — install + upgrade + health + SCM-configured — with the build-creation test
|
||||
remaining a signed-off sub-deferral.
|
||||
|
||||
State files: `STATUS-drone.md`, `BACKLOG-drone.md`, `REVIEW-drone.md`,
|
||||
`JOURNAL-drone.md`. DECISIONS.md shared.
|
||||
|
||||
## 0. P0 — HOST PREREQUISITE (orchestrator-owned; verify before any other work)
|
||||
|
||||
gitea binds `/etc/timezone:ro` from the host; NixOS `time.timeZone` creates only
|
||||
`/etc/localtime`, so the gitea container is REJECTED (`bind source path does not exist`)
|
||||
— proven on cc-ci. The Nix fix is ALREADY COMMITTED: `3bde76f`
|
||||
(`environment.etc."timezone" = "UTC\n"` in `nix/hosts/cc-ci/configuration.nix`); it
|
||||
needs the host-config deploy (sync `/root/cc-ci` + `nixos-rebuild switch
|
||||
--flake /root/cc-ci#cc-ci`), which the ORCHESTRATOR performs (operator-managed
|
||||
mechanism; do NOT attempt it from the loops).
|
||||
|
||||
**Builder's first action:** check `test -f /etc/timezone` on the cc-ci host. If absent,
|
||||
write a BLOCKED note at the top of STATUS-drone.md ("P0 host deploy needed —
|
||||
orchestrator") and work on P1 prep that needs no gitea deploy (meta scaffolding, test
|
||||
authoring) until it appears; the orchestrator reads STATUS on its hourly wakes and will
|
||||
deploy. Verify `/etc/timezone` exists (content `UTC`) before claiming anything gitea
|
||||
touches.
|
||||
|
||||
## 1. Scope (from the Phase-2 scoping, JOURNAL-2 `f86a58a`)
|
||||
|
||||
1. **gitea as a dependency recipe:** `tests/gitea/recipe_meta.py` enrolling gitea as an
|
||||
install-time DEPS provider (per the rcust install-time-deps-only system — deps are
|
||||
installed before the app, fixtures `deps`/`op_state` provide handles).
|
||||
2. **drone enrollment:** `tests/drone/recipe_meta.py` with `DEPS=["gitea"]`;
|
||||
install-time steps that create a gitea admin + token + OAuth2 application and wire
|
||||
`DRONE_GITEA_*` + client secret into drone's install; functional tests proving
|
||||
health + **SCM-configured** (drone actually talks to gitea, not just an HTTP 200).
|
||||
3. **Tiers:** install + upgrade (if a previous published version exists — justify
|
||||
either way) + functional; backup/restore per what the published recipe declares
|
||||
(structural skip is fine if the recipe has no backup config — document it); lint
|
||||
(L5) per the now-standard ladder. Screenshot per the shot-phase standard (drone has
|
||||
a real login/landing UI; default capture expected to work).
|
||||
4. **Build-creation sub-deferral STAYS deferred:** creating/listing actual CI builds
|
||||
needs an OAuth user-token + synced repo + .drone.yml + webhook trigger —
|
||||
disproportionate (the original Phase-2 assessment stands). Ship without it and get
|
||||
the Adversary's explicit §7.1-style sign-off recorded in REVIEW-drone.md; update
|
||||
the DEFERRED entry to narrow it to just this gap.
|
||||
|
||||
## 2. Gates
|
||||
|
||||
**M1 — Integration built + green locally.** P0 verified; gitea dep + drone enrollment
|
||||
implemented; full chosen tier-set green on the harness path with evidence; unit tests
|
||||
for any new harness-visible surface; no gate weakening anywhere. Adversary cold-verifies
|
||||
from a clean checkout: deps wiring per the rcust conventions, SCM-configured test has
|
||||
teeth (a drone WITHOUT gitea wiring must fail it), declared skips justified against the
|
||||
published recipe.
|
||||
|
||||
**M2 — Proven in real CI.** Full lifecycle green via the drone `!testme`/CI path
|
||||
(yes — cc-ci's own drone testing a drone recipe deploy; mind resource headroom),
|
||||
screenshot real + visually verified, level recorded under the de-capped semantics,
|
||||
canonical/warm enrollment decision documented, DEFERRED entry updated (P0+integration
|
||||
closed, build-creation gap narrowed + signed off), operator summary in STATUS-drone.md.
|
||||
Fresh Adversary PASS → `## DONE`.
|
||||
|
||||
## 3. Guardrails (binding)
|
||||
|
||||
- **Host changes are orchestrator/operator-only** (P0 above; same for anything else
|
||||
host-level you discover — file it in STATUS, don't improvise).
|
||||
- The deps system rules from rcust apply: install-time deps only, uniform HookCtx
|
||||
signatures, no new meta keys without registry + docs regeneration.
|
||||
- Two live deploys (gitea + drone) per run — count them against the ≤2-3 concurrent
|
||||
budget; coordinate so a second recipe's run isn't racing the same headroom; tear down
|
||||
BOTH on every exit path, dep included.
|
||||
- Recipe mirrors: PR only if a recipe defect is found (never push main, never merge).
|
||||
No secrets in logs/commits (gitea admin password + OAuth client secret are generated
|
||||
per-run and must stay out of artifacts; the manifest redaction rules apply).
|
||||
- Commit author `autonomic-bot <autonomic-bot@noreply.git.autonomic.zone>`; push every
|
||||
commit. CI host: no python3 on default PATH.
|
||||
|
||||
## 4. Definition of Done
|
||||
|
||||
`/etc/timezone` host fix live; gitea enrolled as a dep provider; drone enrolled and
|
||||
green (install/upgrade/health/SCM-configured + lint + screenshot) through real CI with
|
||||
the build-creation gap explicitly signed off and DEFERRED narrowed; levels + records
|
||||
reconciled; M1+M2 fresh Adversary PASSes.
|
||||
79
cc-ci-plan/plan-phase-dstamp-discourse-drift.md
Normal file
79
cc-ci-plan/plan-phase-dstamp-discourse-drift.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Phase `dstamp` — investigate & solve the discourse abra-stamp drift
|
||||
|
||||
**Mission (operator-specified):** since ~2026-06-10, discourse's upgrade tier fails its
|
||||
HC1 version-stamp check on EVERY run — on both old and new harness at the same ref, so it
|
||||
is proven harness-neutral env drift, and its mechanism is UNATTRIBUTED. Find the root
|
||||
cause, fix it properly, restore discourse to its true level in real CI, and determine
|
||||
whether the same drift silently affects any other recipe's upgrade tier.
|
||||
|
||||
State files: `STATUS-dstamp.md`, `BACKLOG-dstamp.md`, `REVIEW-dstamp.md`,
|
||||
`JOURNAL-dstamp.md`. DECISIONS.md shared.
|
||||
|
||||
## 1. Known evidence (rcust M2, 2026-06-11 — start here)
|
||||
|
||||
- Baseline: run 184 (2026-06-05) had discourse at L4 with upgrade green.
|
||||
- Since ~06-10: upgrade-HC1 at ref `7ae7b0f` stamps the **prev-base tag commit
|
||||
(eb96de94+U)** instead of the expected version — IDENTICAL on old pre-rcust harness
|
||||
and new main (A/B at same ref + invocation ⇒ rcust exonerated, branch-tip/tag/abra-pin
|
||||
drift eliminated as causes during M2; what CHANGED in the env between 06-05 and 06-10
|
||||
was never attributed).
|
||||
- Evidence artifacts: `/var/lib/cc-ci-runs/m2p-discourse/`,
|
||||
`/var/lib/cc-ci-runs/ab-discourse-7ae7b0f-oldmain/`, JOURNAL-rcust 2026-06-11 entries,
|
||||
machine-docs/DEFERRED.md note.
|
||||
- Under the new de-capped semantics a failed upgrade rung blocks at L1 — this drift is
|
||||
actively misrepresenting discourse, which makes it a live quality regression, not
|
||||
cosmetic.
|
||||
|
||||
## 2. Investigation requirements
|
||||
|
||||
1. **Attribute, don't patch.** Build a timeline of everything stamp-relevant that changed
|
||||
on the CI host between 06-05 and 06-10: abra binary version/mtime (`abra --version`,
|
||||
~/.local/bin or wherever it lives), the recipe catalogue state, `~/.abra/recipes/
|
||||
discourse` git state (tags, fetch times, what `git describe`/abra version resolution
|
||||
sees), the discourse mirror's tags/branches (was a tag re-pointed upstream or in the
|
||||
mirror?), and the harness's stash/revert dance around `abra recipe lint`/pinned deploy
|
||||
(`runner/harness/abra.py:109-114`) — plus how upgrade-HC1 derives its EXPECTED stamp.
|
||||
2. **Reproduce minimally** outside a full run if possible (the abra version-resolution
|
||||
command against the same checkout) so the Adversary can re-run the attribution cheaply.
|
||||
3. **Classify the fix target honestly:** env state (fix the host state + document how it
|
||||
drifted), harness assumption (fix run_recipe_ci/lifecycle WITHOUT weakening HC1 — the
|
||||
check itself must keep its teeth), or recipe/mirror tag problem (recipe-mirror PR,
|
||||
never merged). If the expected-stamp derivation is what is wrong, the correction must
|
||||
be justified against abra's documented behavior, not against "what makes the test
|
||||
pass".
|
||||
4. **Blast-radius sweep:** once attributed, check every enrolled recipe's most recent
|
||||
upgrade-tier evidence for the same signature (prev-base tag commit stamped where a
|
||||
version was expected). Any other affected recipe gets fixed by the same root-cause fix
|
||||
and re-proven.
|
||||
|
||||
## 3. Gates
|
||||
|
||||
**M1 — Attribution.** Root cause documented with a reproducible minimal demonstration +
|
||||
the 06-05→06-10 change identified by direct evidence (not inference alone); fix
|
||||
implemented (env/harness/recipe per §2.3); blast-radius sweep complete. Adversary
|
||||
independently reproduces the minimal demonstration and re-derives the attribution.
|
||||
|
||||
**M2 — Proven in real CI.** Discourse full lifecycle green with upgrade-HC1 stamping the
|
||||
CORRECT value at its true level (expected L4+ / L5 if lint passes); ≥1 run via the drone
|
||||
`!testme` path; any other affected recipes re-proven; HC1 demonstrably NOT weakened (the
|
||||
Adversary must show a wrong stamp still fails — synthesize one if needed). DEFERRED
|
||||
entry closed with pointers. Fresh Adversary PASS → `## DONE`.
|
||||
|
||||
## 4. Guardrails (binding)
|
||||
|
||||
- **HC1 keeps its teeth** — any change that would let a genuinely wrong version stamp
|
||||
pass is an automatic FAIL.
|
||||
- Recipe mirrors: PR only, never push main, never merge. Shared checkout race: never
|
||||
git-checkout `~/.abra/recipes/discourse` while its build runs. Real-CI etiquette:
|
||||
≤2-3 concurrent deploys, teardown on every exit path, no secrets in logs/commits.
|
||||
- Host-state changes (abra binary, catalogue) beyond reading require a DECISIONS.md
|
||||
entry; if the fix needs an abra version pin/upgrade host-wide, propose it in
|
||||
STATUS-dstamp.md for the orchestrator/operator instead of doing it unilaterally.
|
||||
- Commit author `autonomic-bot <autonomic-bot@noreply.git.autonomic.zone>`; push every
|
||||
commit. CI host has no python3 on default PATH — use shell or `cc-ci-run`.
|
||||
|
||||
## 5. Definition of Done
|
||||
|
||||
Drift mechanism attributed with reproducible evidence; fixed at the true root; discourse
|
||||
back at its real level in real CI (drone path included); no other recipe silently
|
||||
affected; HC1 unweakened and adversarially re-proven; DEFERRED closed; M1+M2 fresh PASSes.
|
||||
70
cc-ci-plan/plan-phase-kuma-monitor.md
Normal file
70
cc-ci-plan/plan-phase-kuma-monitor.md
Normal file
@ -0,0 +1,70 @@
|
||||
# Phase `kuma` — uptime-kuma create-a-monitor functional test
|
||||
|
||||
**Mission (operator-approved 2026-06-11, DEFERRED re-entry):** add the §4.3-prescribed
|
||||
functional test that completes uptime-kuma's first-run setup wizard and exercises its
|
||||
core function — create a monitor, see it actually probe a target — then check off the
|
||||
DEFERRED entry. This is a cc-ci-repo-only phase (tests/uptime-kuma/), no recipe PR.
|
||||
|
||||
State files: `STATUS-kuma.md`, `BACKLOG-kuma.md`, `REVIEW-kuma.md`, `JOURNAL-kuma.md`.
|
||||
DECISIONS.md shared.
|
||||
|
||||
## 1. Starting facts
|
||||
|
||||
- DEFERRED entry (2026-05-28): uptime-kuma's first-run setup wizard + monitor CRUD run
|
||||
over **Socket.IO** (not plain REST) — that's why it was deferred as fiddly. The
|
||||
existing coverage is install/upgrade/health (+ screenshot, fixed in the shot phase);
|
||||
the recipe currently earns its level without proving its actual function.
|
||||
- uptime-kuma has no stable public REST API for this in the pinned version; the web UI
|
||||
drives everything via socket.io events (`setup`, `login`, `add monitor`,
|
||||
`uptimeList`). Two viable approaches — pick ONE and justify in DECISIONS.md:
|
||||
(a) **python-socketio client** speaking the events directly (fast, headless, but
|
||||
couples to the event names of the pinned version); or
|
||||
(b) **Playwright through the real UI** (slower, but version-robust and reuses the
|
||||
harness browser stack like other recipes' playwright tests).
|
||||
- Wizard creates the admin credential: generated per-run, never logged (secret-safety
|
||||
rules apply; the manifest redaction conventions cover meta, your test must not print
|
||||
it either).
|
||||
|
||||
## 2. Work requirements
|
||||
|
||||
1. **Test design:** complete the first-run wizard (admin create) → create an HTTP
|
||||
monitor pointing at a target the harness controls (e.g. the app's own /; or a
|
||||
second known-up service in the deploy) → wait bounded time for ≥1 check result →
|
||||
assert the monitor reports UP with a real probe timestamp. Negative teeth: a monitor
|
||||
pointed at a dead target must go DOWN (proves the probe isn't a stub) — include it
|
||||
if it fits the runtime budget, else justify.
|
||||
2. **Placement per rcust conventions:** `tests/uptime-kuma/functional/` (or
|
||||
`playwright/` if option b), uniform fixtures (`live_app`, `meta`, ctx hooks), no new
|
||||
meta keys without registry+docs.
|
||||
3. **Runtime budget:** the whole addition stays within the recipe's normal functional
|
||||
tier budget (target ≤ ~90s added; bounded waits, no flaky sleeps — poll with
|
||||
deadline).
|
||||
4. **Prove in real CI:** full uptime-kuma lifecycle green with the new test active
|
||||
(level should hold or rise under the de-capped ladder); ≥1 drone `!testme` run.
|
||||
5. **Close records:** tick the DEFERRED entry with commit + run pointers.
|
||||
|
||||
## 3. Gates
|
||||
|
||||
**M1 — Test implemented + green.** Approach chosen and justified; test lands with
|
||||
bounded waits and real assertions; full local-path lifecycle green. Adversary
|
||||
cold-verifies: the monitor result is REAL (not asserted from config echo — there must
|
||||
be evidence a probe executed), credentials never leak into logs/artifacts, runtime
|
||||
budget held, nothing weakened.
|
||||
|
||||
**M2 — Proven in real CI.** Drone-path run green with the new test; flake check (2
|
||||
consecutive green runs); levels reconciled; DEFERRED closed. Fresh Adversary PASS →
|
||||
`## DONE`.
|
||||
|
||||
## 4. Guardrails (binding)
|
||||
|
||||
- No gate weakening; the new test only ADDS coverage. Secret-safety: generated admin
|
||||
credentials never printed/committed. Real-CI etiquette: ≤2-3 concurrent deploys,
|
||||
teardown on every exit path, never touch `~/.abra/recipes/uptime-kuma` mid-build.
|
||||
- Commit author `autonomic-bot <autonomic-bot@noreply.git.autonomic.zone>`; push every
|
||||
commit. CI host: no python3 on default PATH (use `cc-ci-run`).
|
||||
|
||||
## 5. Definition of Done
|
||||
|
||||
uptime-kuma proves its actual function in CI (wizard + created monitor genuinely
|
||||
probing), flake-checked through the drone path, budget held, DEFERRED checked off,
|
||||
M1+M2 fresh Adversary PASSes.
|
||||
73
cc-ci-plan/plan-phase-mailu-backup.md
Normal file
73
cc-ci-plan/plan-phase-mailu-backup.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Phase `mailu` — add backupbot labels to the mailu recipe (backup/restore coverage)
|
||||
|
||||
**Mission (operator-approved 2026-06-11 — the DEFERRED re-entry trigger "operator
|
||||
approves a cc-ci-authored mailu backupbot recipe-PR" has fired):** mailu ships no
|
||||
`backupbot.backup` labels, so its backup/restore rung is a structural skip. Author a
|
||||
recipe-mirror PR adding proper backupbot coverage, prove backup→wipe→restore data
|
||||
integrity green in real CI at the PR head, and flip mailu's backup rung from
|
||||
intentional-skip to genuinely earned.
|
||||
|
||||
State files: `STATUS-mailu.md`, `BACKLOG-mailu.md`, `REVIEW-mailu.md`,
|
||||
`JOURNAL-mailu.md`. DECISIONS.md shared.
|
||||
|
||||
## 1. Starting facts
|
||||
|
||||
- DEFERRED entry (2026-05-29): no `backupbot.backup` label on any service →
|
||||
`backup_capable=False`, tiers cleanly SKIP. Durable fix = recipe-PR adding labels for
|
||||
the admin DB (sqlite at /data) + the `mailu` mail volume, "mirroring the immich
|
||||
Q3.5/Q3.2b pattern".
|
||||
- mailu install + upgrade + functional (create-mailbox, IMAP login, send/receive
|
||||
mail-flow) are already covered and green — only backup/restore is missing.
|
||||
- Backupbot label syntax: use the **backupbot v2** syntax (a v1-vs-v2 syntax mistake
|
||||
burned the plausible work once — see machine-docs history; verify against the
|
||||
backupbot docs/other recipes' current labels, e.g. immich's merged pattern).
|
||||
- Under the new level semantics, mailu currently climbs past backup as an intentional
|
||||
skip; after this phase it must EARN the rung instead (and its declared-skip meta in
|
||||
tests/mailu must be updated accordingly — that change is part of this phase).
|
||||
|
||||
## 2. Work requirements
|
||||
|
||||
1. **Research the recipe's real data layout before labeling:** which services hold
|
||||
state (admin sqlite, mail store, redis?, certificates?), what must be quiesced or is
|
||||
safe to copy live, and how the published mailu recipe + upstream docs define the
|
||||
durable set. Justify every labeled path in the PR description; don't label caches.
|
||||
2. **Recipe-mirror PR** (NEVER push main, NEVER merge): backupbot v2 labels + any
|
||||
minimal compose plumbing they need + recipe version label bump per conventions.
|
||||
3. **cc-ci side:** update tests/mailu meta (backup capability declaration) and ensure
|
||||
the restore tier's data-integrity seed/verify actually exercises MAIL data (a seeded
|
||||
mailbox + message that survives backup→wipe→restore — extend the existing functional
|
||||
helpers if the current seed is too shallow; never weaken anything).
|
||||
4. **Prove at PR head via real CI:** full lifecycle green incl. the now-active
|
||||
backup/restore rung and lint (L5 expected if all rungs pass); ≥1 drone `!testme` run.
|
||||
Record the before/after level (intentional-skip climb → earned rung).
|
||||
5. **Close records:** tick the DEFERRED entry with PR + run pointers; operator handoff
|
||||
in STATUS-mailu.md (what the PR adds, what to expect post-merge).
|
||||
|
||||
## 3. Gates
|
||||
|
||||
**M1 — PR open + green.** Root data-layout research documented; mirror PR open with
|
||||
justified labels; full lifecycle green at PR head incl. restore data-integrity on real
|
||||
seeded mail data; cc-ci meta/test changes minimal and unweakened. Adversary verifies the
|
||||
labeled set against upstream docs (nothing durable missed, nothing junk included), the
|
||||
restore proof is genuine (data actually survives a wipe), and the drone path ran.
|
||||
|
||||
**M2 — Operator handoff.** Fresh Adversary cold pass (independent re-trigger at PR head,
|
||||
restore integrity re-checked); levels reconciled; DEFERRED closed; STATUS-mailu.md
|
||||
operator summary. `## DONE` with the PR left OPEN for the operator.
|
||||
|
||||
## 4. Guardrails (binding)
|
||||
|
||||
- Recipe mirrors: PR only. No gate weakening — the restore tier's assertions may only
|
||||
get STRONGER. Mail data in test fixtures must be synthetic (never real addresses
|
||||
beyond test domains; no secrets in logs/commits/PR text).
|
||||
- Real-CI etiquette: ≤2-3 concurrent deploys; teardown every dev deploy on every exit
|
||||
path; never touch `~/.abra/recipes/mailu` during its builds.
|
||||
- Commit author `autonomic-bot <autonomic-bot@noreply.git.autonomic.zone>`; push every
|
||||
commit. CI host: no python3 on default PATH.
|
||||
|
||||
## 5. Definition of Done
|
||||
|
||||
Mirror PR open with evidence-justified backupbot v2 labels; backup→wipe→restore proven
|
||||
on real seeded mail data at PR head incl. drone path; mailu's backup rung earned (not
|
||||
skipped) with levels reconciled; DEFERRED closed; M1+M2 fresh Adversary PASSes; PR
|
||||
unmerged for the operator.
|
||||
Reference in New Issue
Block a user