# STATUS — phase cf55 **Phase:** cf55 — GPT-5.5 post-cfold coverage-loss review **Builder:** autonomic-bot **Model:** `claude-sonnet-4-6` (orchestrator-invoked via Claude Code; plan specified `openai/gpt-5.5`, but prior GPT-5.4 loops stopped on model mismatch — orchestrator relaunched on Claude) **Updated:** 2026-06-13T05:18Z --- ## DONE Phase result: `REVIEW-cf55.md` 2026-06-13T05:13:45Z → **M1 PASS + M2 NO COVERAGE LOST** Done criteria satisfied: - M1 PASS at `REVIEW-cf55.md` 2026-06-13T05:13:45Z (combined M1+M2 Adversary verdict) - M2 PASS / NO COVERAGE LOST confirmed independently by Adversary - All 7 review categories passed: diff review, discovery parity, assertion preservation, old-folder behavior, lifecycle-overlay separation, evidence audit, cleanliness - No blocking findings --- ## M1 — PASS Gate result: `REVIEW-cf55.md` 2026-06-13T05:13:45Z → **M1 PASS** WHAT: - cf55 review matrix complete; covering all 7 required review categories across 20 enrolled recipes - Implementation commit under review: `44e0242` (`feat(cfold): canonicalize custom test layout`) - cfold phase M1 PASS (2026-06-12T16:20Z) + M2 PASS (2026-06-13T04:11:00Z) reviewed HOW (Adversary can verify these from a fresh clone): 1. `git ls-files "tests/*/custom/test_*.py" | wc -l` → `64` 2. `git ls-files "tests/*/functional/*" "tests/*/playwright/*" | grep test_ | wc -l` → `0` 3. Per-recipe count check (exact match vs pre-cfold baseline): ``` for recipe in bluesky-pds cryptpad custom-html custom-html-tiny discourse drone ghost hedgedoc immich keycloak lasuite-docs lasuite-drive lasuite-meet mailu matrix-synapse mattermost-lts mumble n8n plausible uptime-kuma; do count=$(git ls-files "tests/$recipe/custom/test_*.py" | wc -l); printf "%s %s\n" "$recipe" "$count"; done ``` 4. `nix shell nixpkgs#python311Packages.pytest -c pytest tests/unit/test_discovery.py tests/unit/test_discovery_phase2.py tests/unit/test_manifest.py -q` → `18 passed` 5. Lifecycle-overlay check: `git ls-files "tests/*/custom/test_install.py" "tests/*/custom/test_upgrade.py" "tests/*/custom/test_backup.py" "tests/*/custom/test_restore.py"` → empty 6. Deprecated-alias warning probe: ```python # Run from repo root: python3 -c " import sys,os,tempfile,unittest.mock as mock sys.path.insert(0,'runner') from harness import discovery with tempfile.TemporaryDirectory() as tmp: d=os.path.join(tmp,'tests','probe') os.makedirs(os.path.join(d,'functional')) os.makedirs(os.path.join(d,'playwright')) open(os.path.join(d,'functional','test_old.py'),'w').write('#x') open(os.path.join(d,'playwright','test_ui.py'),'w').write('#x') with mock.patch.object(discovery,'cc_ci_dir',lambda r: os.path.join(tmp,'tests',r)): result=discovery.custom_tests('probe',None) print('found:',[os.path.basename(p) for _,p in result]) " 2>&1 ``` Expected: 2 `WARNING [cfold]: test found in deprecated folder` lines + `found: ['test_old.py', 'test_ui.py']` 7. RUNG name preserved: `grep 'functional' runner/harness/level.py` → `RUNGS = (..., "functional", ...)` still present 8. `git status` → clean working tree EXPECTED: - Command 1: `64` - Command 2: `0` - Command 3: matches pre-cfold baseline exactly (see table below) - Command 4: `18 passed` - Command 5: empty (no lifecycle overlays in custom/) - Command 6: 2 deprecation warnings, both test files found - Command 7: "functional" still in RUNGS - Command 8: `nothing to commit, working tree clean` WHERE: - Implementation commit: `44e0242` - Discovery: `runner/harness/discovery.py` - Manifest: `runner/harness/manifest.py` - Unit tests: `tests/unit/test_discovery.py`, `tests/unit/test_discovery_phase2.py`, `tests/unit/test_manifest.py` - Migrated custom tests: `tests/*/custom/` - Lifecycle overlays: `tests/*/test_install.py`, `tests/*/test_upgrade.py`, etc. (top-level only) - Level/RUNG names: `runner/harness/level.py` --- ## Review Matrix ### Pre-cfold baseline (from cfold STATUS-cfold.md) | Recipe | Pre-cfold count | Post-cfold count | Match | |---|---:|---:|---| | bluesky-pds | 4 | 4 | ✓ | | cryptpad | 4 | 4 | ✓ | | custom-html | 4 | 4 | ✓ | | custom-html-tiny | 1 | 1 | ✓ | | discourse | 3 | 3 | ✓ | | drone | 1 | 1 | ✓ | | ghost | 4 | 4 | ✓ | | hedgedoc | 2 | 2 | ✓ | | immich | 3 | 3 | ✓ | | keycloak | 3 | 3 | ✓ | | lasuite-docs | 5 | 5 | ✓ | | lasuite-drive | 3 | 3 | ✓ | | lasuite-meet | 3 | 3 | ✓ | | mailu | 3 | 3 | ✓ | | matrix-synapse | 3 | 3 | ✓ | | mattermost-lts | 3 | 3 | ✓ | | mumble | 5 | 5 | ✓ | | n8n | 4 | 4 | ✓ | | plausible | 2 | 2 | ✓ | | uptime-kuma | 4 | 4 | ✓ | | **TOTAL** | **64** | **64** | **MATCH** | ### Category review results **1. Diff review** (`44e0242`): - `discovery.py`: added `custom/` as canonical; `functional/`+`playwright/` become deprecated aliases with loud `WARNING [cfold]` on stderr. Still discovers from all 3 subdirs — no coverage loss. - `manifest.py`: normalizes `sub` key to `"custom"` always for clean output. Correct. - `tests/mailu/ops.py`, `test_backup.py`, `test_restore.py`: `sys.path.insert` updated from `functional` → `custom` to match helper `_mailu.py` new location. Correct — these are lifecycle overlays importing a helper. - `tests/ghost/recipe_meta.py`: comment-only change (`functional/_ghost.py` → `custom/_ghost.py`). No coverage loss. - `tests/drone/install_steps.sh`: comment-only change. No coverage loss. - Keycloak custom test files: `sys.path.insert` depth adjusted (`../..` → `../../..`) due to moving from `functional/` to `custom/` — same directory depth. Correct. - All 60 functional + 4 playwright test files: pure `git mv` (0 insertions/deletions in stat for most; path-comment updates only for a few). No assertion changes. - Unit tests: fixtures updated from `functional/`+`playwright/` to `custom/`; new test `test_custom_tests_prefers_custom_and_warns_on_deprecated_aliases` added. No coverage removed; one test renamed (`test_custom_tests_placement_rule_functional_playwright_only` → `test_custom_tests_placement_rule_custom_only`) but same assertions preserved. **2. Discovery parity**: PASS — 64 custom tests in `tests/*/custom/test_*.py`, zero in `tests/*/functional/` or `tests/*/playwright/`. Per-recipe counts match pre-cfold baseline exactly. **3. Assertion preservation**: PASS — All 64 test files contain unmodified assertion bodies. Changes were: `git mv`, path-comment updates, `sys.path.insert` depth adjustments. Zero assertions removed, zero tests skipped, zero waits relaxed. **4. Old-folder behavior**: PASS — Deprecated `functional/`+`playwright/` subdirs are still in `subdirs` tuple in `discovery.py`, still discovered, with `WARNING [cfold]` emitted per deprecated file found. Tests still run (no silent drop). Probe confirms: both deprecated dirs emit warnings AND return the test files. **5. Lifecycle-overlay separation**: PASS — Lifecycle overlays (`test_install.py`, `test_upgrade.py`, `test_backup.py`, `test_restore.py`) remain at `tests//` top-level. Zero lifecycle files in `custom/`. The RUNG name `"functional"` (L4) is unchanged in `runner/harness/level.py:44` — only the *folder* name changed, not the tier name. **6. Evidence audit**: PASS — cfold M1 PASS (2026-06-12T16:20Z): 64 canonical tests, zero old-tracked trees, `18 passed`, deprecated-alias probe green, exact `(recipe, filename)` coverage set preserved. M2 PASS (2026-06-13T04:11:00Z): full real-CI `!testme` sweep green across all 20 enrolled recipes at L5 with expected custom junit counts; build 585 (ghost) passes at L5 with `custom=4`, `upgrade=2`; zero leaked live `-pr` stacks. **7. Cleanliness**: PASS — Working tree clean (`git status`: nothing to commit). No root-level coordination files. No stale temporary scripts. No uncommitted implementation files. `machine-docs/` contains only expected phase-namespaced state files. --- ## Final Verdict **NO COVERAGE LOST.** The cfold phase (`44e0242`) preserved the full pre-cfold custom-test set. All 64 custom tests are in canonical `tests//custom/` directories with per-recipe counts matching the pre-cfold baseline exactly. No assertions were weakened during the move. Deprecated `functional/`/`playwright/` aliases continue to discover and warn. Lifecycle overlays remain at top-level. The RUNG name `"functional"` is unchanged. The full real-CI sweep is green at L5 across all 20 enrolled recipes.