Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m

## Unreleased

- process(routing, mdl-agent): **the mdl helper no longer preloads the kind-specific MDL skills at Stage 5; it loads them per script through `bin/mdl-rules.sh`** — lazy-load PR 2b. `learned-microflow-patterns.md`, `microflow-preflight.md` and `ui-preflight-pages.md` move to on-demand; `learned-mdl-preflight.md`, `design-spacing.md`, `learned-detection-gaps.md`, `security-is-not-a-later-script.md` and `retesting-learned-rules.md` become on-demand for mdl only (`mdl?`), unchanged for every other role; a new baseline `mdl-rules` row (Stages 5 and 6, so a Stage 6 mdl pack keeps the detection-gaps and retesting rules; mdl Stage 6 preload 9,476 words) replaces them. Baseline 72,891 → 63,877 words; mdl Stage 5 preload 29,388 → 14,600 (per script, after reading the `mdl-rules` output, the helper reads ≈21.4k words for page only, ≈22.5k for microflow+access, ≈28.1k for page+microflow, ≈29.5k for all kinds: ≈0–8k saved by kind; the A/B covered rule sufficiency with kinds pre-selected, not step 4a) (the 3,347-word core of `bin/mdl-rules.sh` counted, like the runbook slice). The mdl stub's workflow step 4a and report line ask for "STOP rows for kinds K: n/n checked". `context-pack.sh`'s "Rules" list names `<toolkit>/bin/mdl-rules.sh <kinds>` with the step's kinds (page / microflow / entity) — after this change the only route `microflow-preflight`, `security-is-not-a-later-script`, `design-spacing`, `learned-detection-gaps` and `retesting-learned-rules` have to a pack-fed helper (fixture: a page step and a logic step). `gate-check.sh` build-ready item 2 accepts `bin/mdl-rules.sh` as well as `ui-preflight-pages`, so a project synced after this change does not flip to FAIL (fixture: both layouts). No skill text changed — lazy-load plan, option C (maintainer)
- new(mdl-rules): **`bin/mdl-rules.sh <kind...> | --for <script.mdl>` prints the MDL rules one script needs, by the kinds of statement it writes** — lazy-load PR 2a. `bin/lib/mdl-rule-kinds.tsv` maps page / microflow / access / workflow / entity / any to sections located by file and heading text (never line numbers): the STOP rows by their `Kind` column, the kind-specific gotchas, `learned-microflow-patterns.md`, `microflow-preflight.md`, `ui-preflight-pages.md`, `design-spacing.md` §1–3, the detection-gaps register rows by construct, `security-is-not-a-later-script.md` and `retesting-learned-rules.md`. Output is the core (Step 0, the `any` STOP rows, gotchas, final self-check: 3,347 words) plus the kind sections, closed by "Rules for kinds K: STOP rows n/n listed" (page 10,223 words, microflow 10,186, access 4,730, entity 5,183, workflow 3,732), against the 29,388 words the mdl helper preloads at Stage 5 today. `--for` reuses exec.sh's statement classifier (`exec.sh --subjects`; Java actions and mappings count as microflow, demo users as access) and exits 1 if it fails; a heading that is gone fails loudly, never prints empty. `skills/generated/rules-<kind>.md` are the same output for harnesses that read files (Copilot, Cursor, Windsurf); `--check` (CI) fails on drift, on any STOP row, gotcha, register row or `##` section that reaches no kind (a section left out on purpose needs an `exclude` row with its reason), and on any register ERE that matches no row by itself, and on an unclosed code fence in a file it reads. No routing change yet: PR 2b demotes the preloads. Behaviour suite: `build-packs.sh --rules "<kinds>"` expands the script in a pack. Fixture `tests/wave2/test-mdl-rules.sh` — lazy-load plan, option C (maintainer)
- process(preflight): **`learned-mdl-preflight.md` moves its STOP-row narrative out of the baseline and gains a `Kind` column (page / microflow / access / workflow / any)** — lazy-load PR 1. The 15 retired rows collapse to one line listing their numbers, the version notes move, and each live row keeps its If/Then text plus one failure clause; the full rows, retired rows and version notes are in `process/baseline-incident-history.md` § PF1, verbatim (`check-moved-text.sh`: 43 of 43 removed lines found). The workflow `DECISION` STOP and the #879 read-first pointer stay in the skill. `Kind` sits at the end of each row so `mdl-scan`'s `| <n> 🔎` markers still match. Baseline 73,946 → 72,891 words (−1,055). — maintainer (Option C lazy-loading plan)
- fix(progress-report): **`progress-report.py` no longer crashes with `TypeError: '<' not supported between instances of 'dict' and 'dict'` when two exec'd scripts share a leading number** (#513). `script_phases()` sorted `(number, phase dict)` pairs, so `10-data.mdl` and `10b-data-flows.mdl` (or one script logged under two paths), both matched to a plan phase, compared the dicts and every `exec.sh` run ended with `WARN: progress-report.html not updated`. It now sorts on (number, script name) only; an unmatched numbered script still takes the phase of the nearest lower-numbered matched one, ties broken by name. Fixture: `test-progress-report.sh` T17 (fails 3/3 on master). — jopterhorst (#513)
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ All gate decisions land in the consuming project's `PROJECT.md`, marked `CONFIRM

## Key skills and when to load them

Load skill files **on demand when the task calls for it** — not all upfront. Full routing table: `README.md` → "When to use which skill". The always-on set (`README.md` → "Baseline routing"): `query-the-model.md`, `learned-mdl-preflight.md`, `learned-microflow-patterns.md`, and `bin/bug-lookup.sh` (a CE code, BUG-n, keyword or the whole pasted error message → the matching ledger entries; `bug-logs/mxcli-bugs.md` itself is read on demand — it outgrew the always-on budget).
Load skill files **on demand when the task calls for it** — not all upfront. Full routing table: `README.md` → "When to use which skill". The always-on set (`README.md` → "Baseline routing"): `query-the-model.md`, `learned-mdl-preflight.md` (the mdl helper instead runs `bin/mdl-rules.sh` for the statement kinds it writes; `learned-microflow-patterns.md` is on demand), and `bin/bug-lookup.sh` (a CE code, BUG-n, keyword or the whole pasted error message → the matching ledger entries; `bug-logs/mxcli-bugs.md` itself is read on demand — it outgrew the always-on budget).

| Task | Read this file |
|------|---------------|
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ Every mxcli project has a `.ai-context/skills/` directory (bundled by `mxcli ini

| Task | Skill to load |
|---|---|
| Building any page or snippet — before the first widget. Wireframe, tokens, gallery reuse, cross-check; no wireframe means STOP | `skills/ui-preflight-pages.md` |
| Building or using the in-app design gallery | `skills/learned-stylegallery.md` |
| Before porting ds.css into SCSS, and at the Stage-3 gate — greps the stylesheet for rules that cannot match the HTML Mendix emits (rem against the real root, table/th/td selectors, positional row selectors). mx check, mxcli check and mxcli lint are all blind to CSS | `project-bin/check-design-portability.sh` |
| After every wireframe edit: assembles design/wireframes/*.html into design/prototype.html, one hash-routed page a stakeholder can click through instead of twenty separate files. Generated, never edited (design-artifacts.md Step 3) | `project-bin/assemble-prototype.js` |
Expand Down Expand Up @@ -684,6 +685,8 @@ Every mxcli project has a `.ai-context/skills/` directory (bundled by `mxcli ini

| Task | Skill to load |
|---|---|
| Writing or fixing any microflow — MDL gotchas plus annotation discipline | `skills/learned-microflow-patterns.md` |
| Writing a microflow with any loop, a retrieve/commit/call inside a loop, nested or multiple loops, >20 activities counting loop bodies, or a list built from a list — post the checklist before the first MDL line | `skills/microflow-preflight.md` |
| Reading what loop bodies do (LOOP_TQ, deferred commit, nested loop, REST in loop, transaction control per item, scheduled-event reachability) from described MDL; the catalog holds top-level activities only and cannot see inside a loop | `skills/microflow-loop-antipatterns.md` |
| Writing MDL microflow scripts — worked recipes | `skills/mdl-cookbook-microflows.md` |
| Writing a single MDL script that takes a project from nothing to a working vertical slice — execution order, why it is deliberately non-idempotent, the instrument hierarchy, and the silent failures that pass every check | `skills/build/mdl/oneshot-mdl-method.md` |
Expand Down Expand Up @@ -850,7 +853,7 @@ Then filter by Role(s). A helper dispatched with a role stub (ba, architect, mdl
| Script or skill? Before writing any .js or bash/.sh for a check, checker, linter, gate or report, or adding a rule or regex to an existing one — judgement goes in a skill, code only fetches facts a reader cannot | `skills/skills-over-scripts.md` | every stage | every role except mdl, review (on demand for those) |
| Any pass whose input is missing, stale or unresolvable — before recording UNMEASURED, N/A or a silent skip: name what was missing, say what you assessed against instead, still deliver a verdict | `skills/degrade-to-judgement.md` | every stage | every role |
| Any time an exit code, a tool's output or a subagent's report is about to become a stated finding — verify before you conclude | `skills/tool-output-is-not-ground-truth.md` | every stage | every role |
| Before obeying any learned-* STOP or workaround that costs a detour — probe the binary you actually have, then stamp the verdict back into the rule | `skills/retesting-learned-rules.md` | every stage | every role |
| Before obeying any learned-* STOP or workaround that costs a detour — probe the binary you actually have, then stamp the verdict back into the rule | `skills/retesting-learned-rules.md` | every stage | every role except mdl (on demand for those) |
| Any pipeline work at all — every session, before producing any stage artifact: read §1b plus your own stage's section, not the whole file (gate-check.sh prints the line spans); READMEs and the guide are orientation only | `skills/conversion-runbook.md` | P,0,1,2,3,4,5,6,7 | lead, ba, architect |
| Any pipeline work at all, as a helper — every dispatch, before producing anything: run the toolkit's bin/runbook-slice.sh <stage>, which prints §1b plus your stage's section of the conversion runbook; never open skills/conversion-runbook.md whole | `bin/runbook-slice.sh` | P,0,1,2,3,4,5,6,7 | mdl, gate, test, review |
| Any question before asking the user or writing anything — query the model, then read the source, then ask the human, in that order | `skills/query-the-model.md` | P,0,1,2,3,4,5,6,7 | every role |
Expand All @@ -867,12 +870,10 @@ Then filter by Role(s). A helper dispatched with a role stub (ba, architect, mdl
| Deciding who answers a question — before putting any batch to the user. gap/conflict/choice/user-only is what keeps a gate batch at four questions instead of 127 | `bin/question-kinds.sh` | 1,2,3 | ba |
| Writing BRDs, especially several in parallel — "build" before the fan-out, "check" before any BRD is called done | `bin/facts-lock.sh` | 2 | ba |
| Building any module — before the first script. The mdl-agent's single per-module input | `skills/module-brief.md` | 4,5 | ba, mdl |
| Writing ANY MDL script — before the first line. Step 0 picks the write mode, then the STOP table overrides it for corrupting operations | `skills/learned-mdl-preflight.md` | 5 | mdl |
| Writing ANY MDL script — before the first line. Step 0 picks the write mode, then the STOP table overrides it for corrupting operations | `skills/learned-mdl-preflight.md` | 5 | (mdl: on demand) |
| Writing ANY MDL script — before the first line: run bin/mdl-rules.sh <kinds> (page, microflow, access, workflow, entity) or --for <draft.mdl>, or read skills/generated/rules-<kind>.md, and read ALL of it — the STOP rows, gotchas and preflight sections for the statement kinds the script writes; your PREFLIGHT reports "STOP rows for kinds K: n/n checked" | `bin/mdl-rules.sh` | 5,6 | mdl |
| Placing any document in a module — before the first `create`. Feature group, then Pages/Microflows/Services/Resources; the path comes from the brief's folder plan, and the table says which types mxcli can actually place | `skills/module-folder-convention.md` | 4,5 | architect, mdl |
| Writing or fixing any microflow — MDL gotchas plus annotation discipline | `skills/learned-microflow-patterns.md` | 5 | mdl |
| Writing a microflow with any loop, a retrieve/commit/call inside a loop, nested or multiple loops, >20 activities counting loop bodies, or a list built from a list — post the checklist before the first MDL line | `skills/microflow-preflight.md` | 5 | mdl |
| Building any page or snippet — before the first widget. Wireframe, tokens, gallery reuse, cross-check; no wireframe means STOP | `skills/ui-preflight-pages.md` | 5 | mdl |
| Writing or reviewing any page or snippet — the spacing scale (8/16/24/32/48), section rhythm, and the page-header scaffold every full page starts with; sections at 0px apart and pages with no H1 are the defects it retires | `skills/design-spacing.md` | 5 | mdl, review |
| Writing or reviewing any page or snippet — the spacing scale (8/16/24/32/48), section rhythm, and the page-header scaffold every full page starts with; sections at 0px apart and pages with no H1 are the defects it retires | `skills/design-spacing.md` | 5 | review (mdl: on demand) |
| After every page-building script, and any time the UI looks wrong — the cheap repeatable look during the build: one page, one screenshot, four questions, scored when a wireframe exists. Feeds Gate: UI, never replaces it | `skills/ui-loop.md` | 5 | review (mdl: on demand) |
| After the FIRST build that follows any design-system port, and before any page is built on it — reads the BUILT stylesheet and reports how many framework knobs point at a design token, how many tokens arrived, how many component classes arrived, each with its denominator. Measured on a real run: 55 tokens ported correctly into the right file, 0 of 35 knobs bound and 0 of 20 classes present, two build phases shipped in the framework's default blue with mx check, mxcli lint, the MDL suite and two e2e journeys all green | `project-bin/check-design-reaches-app.sh` | 3,5 | architect, mdl, gate, review |
| Before exec'ing ANY page script — compares the drafted MDL's shell against the wireframe's: page column, layout/nav shell, one H1. Measured 0/10 pages on a real first build, repaired wholesale 47 scripts later | `project-bin/check-page-shell.sh` | 5 | mdl, gate, review |
Expand All @@ -882,8 +883,8 @@ Then filter by Role(s). A helper dispatched with a role stub (ba, architect, mdl
| Before calling any module tested, or before re-running tests after a change — what testing a module means, which re-runs a change owes (UI-only vs logic lane), and the false-green register of confirmed ways a test reports green over a broken feature | `skills/testing-shape.md` | 5,6 | test, gate, review |
| Finishing any module — before calling it done. One command that runs every instrument and keeps "instrument faulted" apart from "feature failed"; in a wired project run the installed copy at bin/verify-module.sh | `project-bin/verify-module.sh` | 5,6 | mdl, gate, test, review |
| A CSS/SCSS or style change that appears to have done nothing (a colour or class that won't show), a focus ring or outline that paints on every page landing or load, or an app still grey after a design port every instrument called green — the three ways a correct rule paints nothing (matches nothing / matches chrome / loses the cascade), the two reads that tell them apart, and the class that arrived in the stylesheet and is bound to no widget | `skills/learned-css-that-never-applied.md` | 5,6 | review, gate (mdl: on demand) |
| Before trusting a green check/exec/DESCRIBE result as proof, or when a runtime symptom appears over a fully green model — the register of constructs that pass early rungs and fail later ones | `skills/learned-detection-gaps.md` | 5,6 | mdl, gate, review |
| Creating any entity, or calling a module security-ready — entity and grants land in one script, and ready means SHOW SECURITY MATRIX proves it | `skills/security-is-not-a-later-script.md` | 5 | mdl, gate, review |
| Before trusting a green check/exec/DESCRIBE result as proof, or when a runtime symptom appears over a fully green model — the register of constructs that pass early rungs and fail later ones | `skills/learned-detection-gaps.md` | 5,6 | gate, review (mdl: on demand) |
| Creating any entity, or calling a module security-ready — entity and grants land in one script, and ready means SHOW SECURITY MATRIX proves it | `skills/security-is-not-a-later-script.md` | 5 | gate, review (mdl: on demand) |
| A CE error (mx check or mxbuild: CE0066, CE0117…), a cited BUG-n, or behavior that looks like a known mxcli quirk rather than a modeling mistake — `bin/bug-lookup.sh CE0117` / `BUG-102` / "keyword" / the whole pasted error message (ranked top 3) prints the matching ledger entries, so the session reads one entry, not the whole ledger | `bin/bug-lookup.sh` | 5,6 | mdl, gate |
| You hit, or worked around, a bug in mxcli or the toolkit — `bin/file-bugs.sh` (the `--add` line is in learned-detection-gaps.md) keeps docs/bugs.jsonl, redacts, shows duplicates, is filed only by a human with `!` (`--file PBUG-NN`, y/N, denied to agents), or prints new-issue links (`--links`, `--json`) | `bin/file-bugs.sh` | 5,6 | mdl, gate |
| The first command of every session, and any time someone asks "where are we" or "what next" — one screen: stage, done/overdue, the ONE next action, from the instruments, never from memory | `bin/status.sh` | P,0,1,2,3,4,5,6,7 | every role |
Expand Down
Loading
Loading