9.6 KiB
9.6 KiB
STATUS — phase cfold (custom-folder collapse)
Phase: cfold — collapse functional/+playwright/ into custom/
Builder: autonomic-bot
Updated: 2026-06-13
M1 — PASS
Gate result: REVIEW-cfold.md 2026-06-12T16:20Z -> M1 PASS
Inputs for verification:
- Implementation commit:
44e0242(feat(cfold): canonicalize custom test layout)
Completed in this checkpoint:
- discovery.py:
custom/canonical + deprecated aliases with warnings git mvall 64 custom tests (60 functional + 4 playwright) across 20 recipes- helper modules moved alongside their tests into
custom/ - sys.path refs updated in mailu lifecycle overlays
- docs updated (
README.md,recipe-customization.md,testing.md,enroll-recipe.md) - unit tests updated (
test_discovery.py,test_discovery_phase2.py,test_manifest.py) - manifest.py now reports canonical
customcounts
WHAT:
- M1 implementation is complete: custom-test discovery is canonicalized to
custom/, deprecated aliases warn loudly instead of silently dropping coverage, all cc-ci custom tests/helpers moved totests/<recipe>/custom/, manifest counts are canonicalized, and the placement-rule docs/unit tests were updated.
HOW:
git ls-files "tests/*/custom/test_*.py" | wc -lgit ls-files "tests/*/functional/*" "tests/*/playwright/*"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"; donenix shell nixpkgs#python311Packages.pytest -c pytest tests/unit/test_discovery.py tests/unit/test_discovery_phase2.py tests/unit/test_manifest.py -q
EXPECTED:
- Total canonical custom tests:
64 - Old tracked trees: no output for
functional/*orplaywright/* - Per-recipe counts exactly match the baseline table below
- Focused unit suite:
18 passed
WHERE:
- Discovery + alias warnings:
runner/harness/discovery.py - Canonical manifest counts:
runner/harness/manifest.py - Migrated custom tests/helpers:
tests/*/custom/ - Focused unit coverage:
tests/unit/test_discovery.py,tests/unit/test_discovery_phase2.py,tests/unit/test_manifest.py - Placement-rule docs:
docs/recipe-customization.md,docs/testing.md,docs/enroll-recipe.md,README.md
Adversary verdict:
machine-docs/REVIEW-cfold.mdlines 52-77- PASS facts include: 64 canonical custom tests, zero old tracked custom trees, focused unit suite
18 passed, deprecated-alias warning probe green, normalized(recipe, filename)coverage set preserved exactly (missing [],extra []).
DONE
Phase result: REVIEW-cfold.md 2026-06-13T04:11:00Z -> M2 PASS
Done criteria satisfied:
- M1 PASS at
REVIEW-cfold.md2026-06-12T16:20Z - M2 PASS at
REVIEW-cfold.md2026-06-13T04:11:00Z - Full real-CI
!testmesweep green across all 20 enrolled recipes with canonicalcustom/coverage intact - Zero leaked live
-prstacks after the sweep
Final proof points:
- Ghost blocker closure: build
585on PR #5 refd42d0f7c7cf9->level 5, all stages pass, custom JUnit4, upgrade JUnit2 - Same-code-path Ghost repro after the fix:
/var/lib/cc-ci-runs/ghost-repro-cfold-3/results.json->install=pass,upgrade=pass - cfold implementation commit:
44e0242 - Ghost closure fix commit:
d44f799
M2 — PASS
Gate: M2 — CLAIMED, awaiting Adversary
Current work item:
- full real-CI
!testmesweep is now green across the enrolled recipe set, including the formerly-blocking Ghost PR head - Ghost's upgrade blocker was fixed in cc-ci via the
tests/ghost/compose.ccci.ymloverlay: the app now waits in its entrypoint for the replacement DB socket before starting during the base->head crossover, while preserving Ghost's normal/abra-entrypoint.sh node current/index.jsboot path - bridge replay-guard fix remains live on
cc-ci(image tageb32876581d9); the Ghost duplicate-trigger side issue is separately closed and no longer affects the cfold sweep result
M2 baseline matrix (built from live PR heads + fresh post-cfold evidence)
| Recipe | PR / ref | Expected level | Custom tests | Fresh evidence |
|---|---|---|---|---|
| bluesky-pds | PR #2 f7b6c8df |
5 | 4 | build 556 -> L5 |
| cryptpad | PR #5 9c18c176 |
5 | 4 | build 554 -> L5 |
| custom-html | PR #2 db9a9502 |
5 | 4 | build 541 -> L5 |
| custom-html-tiny | PR #7 526502ba |
5 | 1 | build 510 -> L5 |
| discourse | PR #2 b7d8a244 |
5 | 3 | build 521 -> L5 |
| drone | PR #1 049438e1 |
5 | 1 | build 506 -> L5 |
| ghost | PR #5 d42d0f7c |
5 | 4 | build 585 -> L5 |
| hedgedoc | PR #1 441c411c |
5 | 2 | build 555 -> L5 |
| immich | PR #2 17f1649c |
5 | 3 | build 522 -> L5 |
| keycloak | PR #3 bfe0d16f |
5 | 3 | build 553 -> L5 |
| lasuite-docs | PR #5 8a06cfc2 |
5 | 5 | build 523 -> L5 |
| lasuite-drive | PR #2 6771622b |
5 | 3 | build 524 -> L5 |
| lasuite-meet | PR #6 05cdafb5 |
5 | 3 | build 525 -> L5 |
| mailu | PR #4 682ccaaa |
5 | 3 | build 526 -> L5 |
| matrix-synapse | PR #2 72f0176a |
5 | 3 | build 527 -> L5 |
| mattermost-lts | PR #2 966c6d61 |
5 | 3 | build 529 -> L5 |
| mumble | PR #1 2b50b2f7 |
5 | 5 | build 558 -> L5 |
| n8n | PR #5 989c44b3 |
5 | 4 | build 528 -> L5 |
| plausible | PR #3 709a294d |
5 | 2 | build 530 -> L5 |
| uptime-kuma | PR #3 b0ce7942 |
5 | 4 | build 531 -> L5 |
Ghost closure
ghost was the final M2 blocker and is now green on the real !testme path.
- Historical failing same-ref comparison remains the strongest pre-fix proof:
- build
559ond42d0f7c7cf9-> L1; install/backup/restore/custom/lint pass, upgrade fail - build
585ond42d0f7c7cf9-> L5; install/upgrade/backup/restore/custom/lint pass
- build
- Root cause of the upgrade failure: during the base->head crossover, Ghost's app task started before the
replacement DB service was accepting connections, so the new task exited on
ENOTFOUND/ECONNREFUSEDagainst${STACK_NAME}_dband swarm paused the update before the head spec could settle. - Fix landed in
cc-cicommitd44f799(fix(cfold): wait for ghost db in entrypoint):tests/ghost/compose.ccci.ymlnow keeps the existing 15m app/db healthcheck grace and wraps the appentrypointwith a tiny TCP wait that execs the normal/abra-entrypoint.sh node current/index.jspath only after the DB socket is reachable. - Focused same-code-path repro after the fix:
/var/lib/cc-ci-runs/ghost-repro-cfold-3/results.json->install=pass,upgrade=pass- log
/root/ghost-repro-cfold-3.logincludesupgrade-converged: ghos-ce3c44_ci_commoninternet_net_app swarm UpdateStatus=completedandupgrade->PR-head: head_ref=d42d0f7c chaos-version=d42d0f7c+U version=1.2.0+6.21.2-alpine->1.4.0+6.44.0-alpine
Fresh Adversary state
REVIEW-cfold.md2026-06-12T23:45:11Z: cold Ghost follow-up audit only, no new finding, no M2 claim pending.REVIEW-cfold.md2026-06-13T00:23:55Z: cold M2 artifact/teardown audit only, no new finding, no M2 claim pending; zero leaked live-prstacks confirmed.
WHAT:
- M2 is now met: the full real-CI
!testmerecipe sweep is green, the formerly-blocking Ghost recipe is green again on the same PR head that previously failed, custom-tier coverage remains intact, and there are zero leaked live-prstacks.
HOW:
ssh cc-ci 'tok=$(cat /run/secrets/bridge_drone_token); curl -fsS -H "Authorization: Bearer $tok" https://drone.ci.commoninternet.net/api/repos/recipe-maintainers/cc-ci/builds/585 | jq -r "[.number,.status,.after,.params.RECIPE,.params.PR,.params.REF] | @tsv"'ssh cc-ci 'jq -r "{level,recipe,ref,results,stages:(.stages|map({name,status}))}" /var/lib/cc-ci-runs/585/results.json'ssh cc-ci 'printf "ghost custom junit="; ls /var/lib/cc-ci-runs/585/junit/custom__cc-ci__*.xml | wc -l; printf " ghost upgrade junit="; ls /var/lib/cc-ci-runs/585/junit/upgrade*.xml | wc -l'ssh cc-ci 'printf "live_pr_apps="; docker stack ls --format "{{.Name}}" | grep -c -- "-pr" || true'ssh cc-ci 'jq -r ".results, .stages" /var/lib/cc-ci-runs/ghost-repro-cfold-3/results.json'
EXPECTED:
- Drone build query returns build
585, statussuccess,after=d44f799de945d0775933aad58726d46509154a64, recipeghost, PR5, refd42d0f7c7cf9946077a583ffa3f7c96abfe94a77 results.jsonfor build585showslevel: 5andresults.install=pass,results.upgrade=pass,results.backup=pass,results.restore=pass,results.custom=pass; stages includeinstall,upgrade,backup,restore,custom,lintallpass- JUnit counts for build
585:ghost custom junit=4,ghost upgrade junit=2 - Teardown check returns
live_pr_apps=0 - Focused repro
ghost-repro-cfold-3showsinstall=pass,upgrade=pass
WHERE:
- Fix commit:
d44f799(fix(cfold): wait for ghost db in entrypoint) - Ghost overlay:
tests/ghost/compose.ccci.yml - Real CI proof:
/var/lib/cc-ci-runs/585/results.json,/var/lib/cc-ci-runs/585/junit/ - Focused repro proof:
/var/lib/cc-ci-runs/ghost-repro-cfold-3/results.json,/root/ghost-repro-cfold-3.log
Baseline (pre-cfold) — custom test count per recipe
| Recipe | Count |
|---|---|
| bluesky-pds | 4 |
| cryptpad | 4 |
| custom-html | 4 |
| custom-html-tiny | 1 |
| discourse | 3 |
| drone | 1 |
| ghost | 4 |
| hedgedoc | 2 |
| immich | 3 |
| keycloak | 3 |
| lasuite-docs | 5 |
| lasuite-drive | 3 |
| lasuite-meet | 3 |
| mailu | 3 |
| matrix-synapse | 3 |
| mattermost-lts | 3 |
| mumble | 5 |
| n8n | 4 |
| plausible | 2 |
| uptime-kuma | 4 |
| TOTAL | 64 |