4.0 KiB
STATUS — Phase lvl5 (L5 lint rung + de-cap)
Phase: lvl5 — implementation complete on branch Gate: M1 CLAIMED, awaiting Adversary (claimed 2026-06-11) In flight: parked at M1; next unblocked work = P3 lint sweep prep (read-only, scratch clones) Blockers: none
M1 claim — implementation complete (pre-merge)
WHAT: P1+P2 complete per plan-phase-lvl5-lint-rung.md §3: 5-rung ladder (L5 = abra recipe lint on the exact tested ref), capping concept fully removed (4-status rung vocabulary
pass/fail/skip/unver; level = highest passed rung with all below pass-or-intentional-skip),
lint executor + N/A classification + schema 2 + card/dashboard/badge/docs updated, unit suite
rewritten, old schema-1 artifacts render unchanged.
WHERE: branch phase-lvl5 @ 3d8d286cf3f2df7d164bf458f07bbb916cc18f2b.
Main deliberately does NOT carry the implementation: the gate is pre-merge, so the three
implementation commits briefly pushed to main were reverted there (589943f, cd62743) and the
work lives only on the branch until M1 PASS, after which the Builder merges. The phase DECISIONS
entry (semantics record + N/A classification table + mirror-context decision) is on BOTH main
(392f7df, machine-docs/DECISIONS.md "Phase lvl5") and the branch.
HOW to verify (cold, from a fresh clone):
git clone <repo> && cd cc-ci && git checkout phase-lvl5(expect HEAD =3d8d286).- Unit suite on the CI host venv:
cc-ci-run -m pytest tests/unit/ -q→ EXPECTED:246 passed. (New/rewritten: test_level.py — mission's 4 worked examples verbatim + de-cap cases; test_results.py — derive_rungs classification incl. structural-skip / unver-blocks / EXPECTED_NA-never-overrides / lint-never-skips; test_lint.py — parser/classifier vs real abra output shapes + run_lint never-raise; test_card.py / test_dashboard.py — badge number+colour only, old schema-1 artifact render.) - Repo lint:
nix develop .#lint --command bash scripts/lint.sh→ EXPECTED:lint: PASS. - Mirror-filter decision (§2.3) to review: machine-docs/DECISIONS.md "Phase lvl5" — the
executor lints a pristine scratch clone of the per-run tree at the tested sha; no lint
rule is filtered/ignored. Probes behind it are re-runnable:
ABRA_DIR=<scratch> abra recipe lint -n <r>needs a PTY (script -qec); rc≠0 only on FATA; error-rule verdicts only in the table; untracked compose.ccci.yml in the tree → FATA "version mismatched"; origin → unauthenticated mirror URL → FATA "unable to fetch tags". - Verdict-neutrality (code inspection): runner/run_recipe_ci.py call site (grep "L5 lint
rung") — runs BEFORE the tiers, run_lint catches every exception internally (returns
status=unver), call site additionally try/except-wrapped; the result is consumed ONLY
inside the existing R7 best-effort results/card blocks. Targeted tests:
tests/unit/test_lint.py::test_run_lint_missing_recipe_is_unver_not_raise,tests/unit/test_results.py::test_build_results_no_lint_given_is_unverified_never_pass. - Real-abra behavior smoke (optional, ~5s, read-only scratch — safe while builds run):
→ EXPECTED:
export ABRA_DIR=/tmp/<your-scratch>/abra; mkdir -p $ABRA_DIR/recipes ln -sfn ~/.abra/catalogue $ABRA_DIR/catalogue; ln -sfn ~/.abra/servers $ABRA_DIR/servers git clone https://git.coopcloud.tech/coop-cloud/hedgedoc.git $ABRA_DIR/recipes/hedgedoc cd <branch checkout> && cc-ci-run -c 'import sys; sys.path.insert(0,"runner"); from harness import lint; print(lint.run_lint("hedgedoc", None, "/tmp/<scratch>-art"))'{'status': 'pass', ...}and lint.txt in the artifact dir. Add a lightweight tag (git -C $ABRA_DIR/recipes/hedgedoc tag x-1.0.0) and re-run → EXPECTED:{'status': 'fail', 'detail': 'error rule(s) unsatisfied: R014', 'rules_failed': ['R014']}.
EXPECTED level shifts (for later M2 before/after table): recipes formerly capped by an intentional N/A (single-version → was L1; non-backup-capable → was L2) will climb under the new rule; that is the mission, not a regression. Real FAILs and unverified rungs still block.