Files
cc-ci/JOURNAL-lvl5.md
autonomic-bot e219a7891d
All checks were successful
continuous-integration/drone/push Build is passing
feat(lvl5): P1 — 5-rung ladder (L5=abra recipe lint) + de-capped level semantics
level.py: RUNGS += lint; statuses {pass,fail,skip,unver}; compute_level = max passed
rung with all below pass-or-skip (fail/unver block); cap_reason/capped DELETED.
harness/lint.py: lint executor — pristine scratch clone of the per-run tree at the
exact tested ref (mirror-origin + untracked-overlay pollution solved by context, no
rule filtered), PTY via script -qec, 60s hard budget, lint.txt artifact, table-parse
classifier (rc only signals FATA), unver on any non-run (never silent pass).
results.py: derive_rungs classifies every N/A source (structural/declared → skip,
else unver), lint rung + synthetic lint stage + lint block in results.json, schema 2,
cap fields removed. run_recipe_ci.py: lint call before tiers (double-wrapped,
verdict-neutral), badge = level only. card/dashboard: 0-5 ramp, cap line → 'level N
of {4|5}', unverified rows, badge number+colour only, lint.txt servable, old schema-1
artifacts render untouched. Unit suite rewritten: 245 passed on cc-ci venv.
2026-06-11 07:42:30 +00:00

4.2 KiB
Raw Blame History

JOURNAL — Phase lvl5

2026-06-11 bootstrap

  • Read plan-phase-lvl5-lint-rung.md in full + plan.md §6/§6.1/§7/§9. Phase files created.
  • Orientation reads: level.py (RUNGS 4, compute_level gap-caps, backup_restore_status, tier_to_rung), results.py derive_rungs/build_results (cap fields at :215-229), card.py (LEVEL_COLOR 0-6!, cap line :246, level_badge_svg cap_skip third segment), dashboard.py (_LEVEL_COLOR :68, _level_pill :245, cap div :277, render_level_badge :363), run_recipe_ci.py build_results call :1248 + badge wiring :1296-1320, bridge.py :224 (badge embed — number-only already, no cap text → likely untouched), docs (results-ux.md has cap language; recipe-customization.md EXPECTED_NA row).
  • Notable: card.py LEVEL_COLOR already has keys 0-6 (5=green, 6=bright green) — only 0-4 reachable today; dashboard._LEVEL_COLOR needs checking for the same.
  • Lint context: abra.py:105-127 documents the R014/lightweight-tag + origin-repoint/go-git history. Per-run recipe tree = $ABRA_DIR/recipes/, origin = private mirror (SRC) on PR runs, upstream tags fetched in by fetch_recipe. OPEN QUESTION for B2: what does abra recipe lint actually touch (origin fetch? auth? R014 against which tags?) — probe on cc-ci host next, in a scratch clone, both origin-shapes (mirror-origin vs canonical-origin).
  • Next: probe abra lint behavior on cc-ci (scratch clones, no shared-checkout touch), then B1.

2026-06-11 abra lint probe (B2 design input) — all on cc-ci, scratch ABRA_DIR=/tmp/lvl5-lint-probe/abra

  • abra recipe lint hedgedoc (fresh canonical clone): FATA "inappropriate ioctl for device" rc=1 — needs a PTY even with -n. Under script -qec "abra recipe lint -n hedgedoc" /dev/null: rc=0, 21-line unicode table R001R016 (cols: ref|rule|severity|satisfied /|skipped|how-to-fix), maxlen 146 no wrapping, wall time 0.7s.
  • rc SEMANTICS: rc≠0 ONLY on FATA (cannot lint). Probes:
    • rm .env.sample + commit → rc=1 FATA "unable to validate recipe: .env.sample ... no such file" (content-attributable FATA).
    • lightweight tag added → table renders R014 error , final line WARN critical errors present in <recipe> config, rc=0. So pass/fail MUST be parsed from the table (error-severity rows), sentinel line as cross-check. Baseline warn-only (R015) → NO sentinel, rc=0 → pass.
    • untracked compose.ccci.yml (CI overlay) in tree → FATA "version mismatched between two composefiles" rc=1 — abra lint globs compose*.yml INCLUDING untracked harness overlays ⇒ lint MUST run on a pristine clone of the exact ref, not the deploy tree.
    • origin repointed to auth-required mirror URL → rc=1 FATA "unable to fetch tags in ...: repository not found" — lint force-fetches tags from origin ⇒ scratch clone's origin must be fetchable without auth. Cloning FROM the per-run tree (local path origin) satisfies this offline and preserves the run's true tag set (fetch_recipe pulls upstream tags into the per-run tree).
  • run_quick emits no results.json/card (build_results only at run_recipe_ci.py:1248, cold path) → lint rung wiring is full-path only.
  • Executor design settled (DECISIONS.md entry to come with B2): scratch ABRA_DIR (recipes/ = git clone <per-run-tree> + checkout -f <exact tested sha>; catalogue/servers symlinks to canonical), script -qec "abra recipe lint -n <r>", hard 60s timeout, full output → lint.txt artifact, parse table rows; status = fail iff any error-severity row (not skipped) or content-attributable FATA ("unable to validate recipe"); pass iff table rendered & no error-row ; anything else (timeout, abra missing, fetch FATA, unparseable) → unver + loud log. No rule filtering needed (mirror pollution solved by context, not by ignoring rules).
  • Tier-skip sources mapped for derive_rungs classification (run_recipe_ci.py:1040-1131): upgrade skip ⟺ prev falsy ("only one published version", structural-intentional) given install passed; backup/restore skip ⟺ not backup_cap (structural-intentional); install-fail → downstream tiers skip (unintentional); custom skip ⟺ no custom tests (unintentional unless EXPECTED_NA declares functional); tier absent from stages (CCCI_STAGES dev escape) → missing key (unintentional).