# JOURNAL — phase cf48 (Opus 4.8 post-cfold coverage-loss review)

## 2026-06-13T05:30Z — Independent cold review complete, M1 claimed

**Model check:** session reports `claude-opus-4-8`, override files
`/srv/cc-ci/.cc-ci-logs/.loop-model-cf48 = claude-opus-4-8` and `.loop-backend = claude`. Matches the
phase Model Requirement — proceeded.

**Approach.** Reviewed independently first (formed my own verdict from the diff, the code, and live
probes), THEN read cf55 to reconcile. The plan named GPT-5.5 for cf55 but cf55 actually ran on
claude-sonnet-4-6 (launcher mismatch, orchestrator relaunch — documented in its own state files), so the
"two different models" cross-validation is Sonnet 4.6 vs Opus 4.8. Recorded honestly in STATUS rather
than pretending it was GPT vs Claude.

**Why I'm confident it's a pure relocation.** The cfold safety argument (discovery globs both old subdirs
with no branching, both map to the L4 `functional` rung, identical fixtures/failure semantics) was already
established in the cfold plan §1. My job was to confirm the *execution* matched. Three things made it
provable rather than "looks right":
1. The cardinal coverage diff (cmd 6) compares the actual git trees at `44e0242^` and HEAD by
   `(recipe, filename)`, stripping the folder component — a byte-identical sorted diff means no file was
   added, dropped, or renamed-away, only re-parented. This is stronger than a count match (counts can
   coincide while a file is swapped).
2. `git show --find-renames` collapses the 100%-identical moves so only the 5 content-touched test files
   surface — and each of those is a docstring/comment/sys.path line, never an assertion. Small surface to
   eyeball exhaustively.
3. The whole-repo grep for `functional/`/`playwright/` literals outside the alias handling, plus the
   `== "functional"` value-branch grep, proves no consumer (manifest, screenshot, dashboard, drone, bridge)
   silently keys off the old folder name. Only `discovery.py`'s intentional alias lines remain.

**Discrepancy I caught vs cf55.** cf55's narrative claims keycloak's custom tests had a `sys.path` depth
adjustment `../..` → `../../..`. The diff shows those lines unchanged (only the comment moved). Harmless —
functional/ and custom/ are equal depth so no adjustment was needed — but it's a factual slip in cf55's
write-up. Surfaced in the agreement note per the phase's "note where the two disagree" instruction. cf48
found it; cf55 missed it. No coverage consequence either way.

**Evidence audit stance.** Did NOT rerun the full fleet sweep (guardrail: don't re-sweep unless cfold
evidence is incomplete — it isn't). Relied on cfold's cold-verified M2 PASS (REVIEW-cfold.md 04:11:00Z):
all 20 recipes L5, custom-junit counts = baseline per recipe, ghost upgrade junit=2, live_pr_apps=0. That
is sufficient and independently re-runnable evidence; re-sweeping would be churn.

**Commands run (all green):** unit suite `18 passed`; per-recipe counts all match; cardinal diff
`IDENTICAL SET`; alias probe `found: ['test_new.py','test_old.py','test_ui.py']` + 2 warnings; stale-
consumer grep clean; `git status` clean; RUNG name `"functional"` intact.

**Next:** parked at M1 CLAIMED gate awaiting Adversary M1 + M2 PASS in REVIEW-cf48.md. No other unblocked
cf48 work (review-only phase). Will self-poll with a fallback while the watchdog edge-pings on the
Adversary's `review(...)` commit.

## 2026-06-13T06:32Z — Resumed to close cf48; M2 claimed

Re-invoked on cf48. Found M1 PASS already recorded (REVIEW-cf48.md @05:29Z, commit `836ab13`) but the
loop had advanced through pvfix/pvcheck/ghost (all DONE) without an explicit **M2** PASS or a `## DONE`
here — cf48 was left dangling at M1. The M2 gate (no-loss verdict) was never separately handshaken even
though the M1 review text already establishes the full no-loss evidence.

Action: re-verified the cheap structural checks (1–6) to confirm no test-tree drift since M1 — canonical=64,
stale=0, lifecycle_in_custom=0, lifecycle_top=64, cardinal diff still IDENTICAL SET. Then updated STATUS
to mark M1 PASS received + claim M2, and pushed `claim(cf48-M2)` (commit `61ad356`) to ping the Adversary.
M2 reuses M1's already-cold-verified evidence — no new build/sweep (review-only phase, cfold evidence
complete per guardrail; re-sweeping would be churn). Parked awaiting Adversary M2 PASS in REVIEW-cf48.md,
after which I write `## DONE`.
