Files
cc-ci/STATUS-lvl5.md

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):

  1. git clone <repo> && cd cc-ci && git checkout phase-lvl5 (expect HEAD = 3d8d286).
  2. 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.)
  3. Repo lint: nix develop .#lint --command bash scripts/lint.sh → EXPECTED: lint: PASS.
  4. 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".
  5. 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.
  6. Real-abra behavior smoke (optional, ~5s, read-only scratch — safe while builds run):
    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"))'
    
    → EXPECTED: {'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.