# 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.