Files
cc-ci-orchestrator/cc-ci-plan/plan-phase-bsky-fix.md
autonomic-bot c89cd6366b plan: phase 'bsky' — fix bluesky-pds recipe + its screenshot (queued after lvl5)
Root-cause the upstream image breakage (Cannot find module /app/index.js,
Node v24 under the pinned tag — proven harness/ref-neutral in rcust M2),
research upstream releases (persist to cc-ci-plan/upstream/bluesky-pds.md),
fix via recipe-mirror PR (NEVER merge — operator does), prove full lifecycle
green incl. the new L5 lint rung via !testme at PR head, then verify a real
credential-free screenshot on those runs (hook only if needed). Close both
DEFERRED bluesky entries; crisp operator handoff in STATUS-bsky.md.
2026-06-11 11:30:49 +00:00

7.1 KiB

Phase bsky — fix the bluesky-pds recipe (and then its screenshot)

Mission (operator-specified): bluesky-pds is the one enrolled recipe that cannot deploy at all. Diagnose and FIX whatever is wrong with the recipe, prove the fix green in real CI on a recipe-mirror PR, and then make its CI screenshot work like every other recipe's. The recipe-mirror PR is the deliverable — the operator merges it (you NEVER do).

State files (phase-namespaced): STATUS-bsky.md, BACKLOG-bsky.md, REVIEW-bsky.md, JOURNAL-bsky.md. DECISIONS.md shared (append).


1. What is already known (rcust/shot phase evidence, 2026-06-11)

  • Symptom: the app container crash-loops Error: Cannot find module '/app/index.js' (MODULE_NOT_FOUND) under Node v24.15.0, at the recipe's pinned tag, on EVERY current run. Proven harness-neutral and ref-neutral during rcust M2: identical failure on old pre-rcust harness and new main, at mirror head and old default head (runs m2r-bluesky-pds, m2rr-bluesky-pds, ab-bluesky-pds-oldmain).
  • Conclusion already on record (machine-docs/DEFERRED.md): upstream re-published or moved the image under the recipe's pinned tag — the historical baseline ("full lifecycle green", Phase-2 e45e0ee) is unreproducible for reasons outside the cc-ci repo. Node v24 in the traceback is itself a smell: the PDS image historically shipped an older Node — the tag now likely resolves to something rebuilt/different.
  • Screenshot: classified deploy-gated N/A in the shot phase — never capturable because the app never comes up. Once deploy works, the default landing-page capture (a PDS serves a minimal HTTP landing page) is expected to work; verify, and add a SCREENSHOT(page, ctx) hook only if genuinely needed.
  • DEFERRED.md carries the explicit follow-up: "file/propose a re-pin PR against the bluesky-pds recipe mirror" — this phase executes it (and closes both bluesky entries).

2. Diagnosis & fix requirements

  1. Root-cause first, properly. Inspect the recipe's compose: which image+tag is pinned, any entrypoint/command overrides (a stale command: node /app/index.js against a restructured upstream image is a prime suspect alongside a moved tag). Inspect the actual image on the CI host (docker run --rm --entrypoint sh <image> -c 'ls /app; node --version' or crane/skopeo inspect) to see what the tag REALLY contains now vs what the recipe assumes.
  2. Research upstream before pinning. Check bluesky-social/pds releases/changelog for the current recommended version, breaking changes, and required env/config migrations. Persist findings to cc-ci-plan/upstream/bluesky-pds.md (the per-recipe upstream registry convention — create it if absent). Prefer upgrading to a current stable, digest-pinned or exact-version tag over re-pinning to an old image, unless the research says otherwise — justify the choice in DECISIONS.md.
  3. Fix in the RECIPE (mirror PR), not the harness. The recipe change (image re-pin/upgrade + any required compose/env/entrypoint/config migrations + recipe version label bump per recipe conventions) goes on a branch in the bluesky-pds recipe mirror → open a PR (like immich PR#2 / plausible PR#3). NEVER push the mirror's main, NEVER merge. Harness/tests changes belong in the cc-ci repo only if something there is genuinely stale (and never weakened).
  4. Verify on the PR via real CI: !testme on the mirror PR (the drone path) until the full lifecycle is green — install/health, upgrade (if a previous published version exists for the path: justify status either way), backup/restore, functional, lint (the new L5). Record the achieved level under the new de-capped semantics and reconcile the recipe's expected baseline.
  5. Then the screenshot: on the green PR runs, verify screenshot.png exists and is a real, representative, credential-free view (Read the PNG). If the default capture is inadequate for PDS (bare JSON/empty page), add a SCREENSHOT hook in tests/bluesky-pds/recipe_meta.py (cc-ci repo) honoring the secret-safety rule. Card + dashboard must show it.
  6. Close the loop on records: check the two bluesky entries in DEFERRED.md (re-pin follow-up; M2 exclusion note) with pointers to the PR + green runs; update the shot phase's N/A disposition for bluesky in a JOURNAL-bsky note. If upgrade-path or canonical/warm enrollment state for bluesky-pds needs reseeding after the fix, document what the operator should expect post-merge.

3. Gates

M1 — Root cause + green fix PR. Root cause documented with evidence (image inspection output, upstream changelog refs); recipe-mirror PR open with the fix; !testme on the PR green through the full lifecycle; screenshot captured on a PR run and visually verified by the Builder. Adversary verifies: root-cause evidence reproduces, the PR diff is minimal + justified line-by-line against upstream docs, no test/gate weakening anywhere, the green run is genuinely the PR head via the drone path.

M2 — Operator handoff complete. Fresh Adversary cold pass: independent re-run (or re-trigger) confirming green at PR head; PNG independently Read (real, credential-free); level under new semantics recorded and baseline reconciled; DEFERRED entries closed with pointers; STATUS-bsky.md contains a crisp operator summary (what was wrong, what the PR changes, what to do post-merge). ## DONE only after fresh M2 PASS. The phase is DONE with the PR OPEN — merging is the operator's, and post-merge canonical reseeding is documented, not performed.

4. Guardrails (binding)

  • Recipe mirrors: PR only. NEVER push main, NEVER merge (operator decides; immich PR#2 and plausible PR#3 are the standing precedent and also remain unmerged).
  • No gate weakening: recipe tests in cc-ci may not be loosened to make bluesky green; if a test is genuinely stale vs the new upstream version, the change must be evidence-backed, minimal, and Adversary-verified against upstream docs.
  • Shared checkout race: NEVER git-checkout ~/.abra/recipes/bluesky-pds on cc-ci while its CI build runs; abra app new moves the checkout to a release tag — check out the PR branch afterward when chaos-deploying, or you deploy the wrong tree.
  • Real-CI etiquette: ≤2-3 concurrent live deploys; tear down every dev deploy on every exit path; no secrets in logs/commits/PR text.
  • Screenshot rules from the shot phase remain law: capture is best-effort and can never affect a verdict; never capture a page showing generated credentials.
  • Commit author autonomic-bot <autonomic-bot@noreply.git.autonomic.zone>; push every commit immediately. CI host has no python3 on default PATH — use shell or cc-ci-run.

5. Definition of Done

bluesky-pds root cause proven; a minimal, upstream-justified fix PR open on the recipe mirror and verified fully green (all rungs incl. lint) at its head via real drone CI; its screenshot real and visually verified on those runs (hook added only if needed); DEFERRED entries closed; operator handoff written; M1 + M2 fresh Adversary PASSes — with the PR left unmerged for the operator.