Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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

- chore(context): **helpers read the runbook slice for their stage, and the runbook no longer carries a copy of the baseline table — mdl at Stage 5 reads 56,236 → 43,599 words; baseline 75,028 → 73,233.** `skills/conversion-runbook.md` held a fourth rendered copy of the baseline routing table (README, ROUTING.md and every project's CLAUDE.local.md carry it too); it is out of the render surfaces and replaced by a one-line pointer. New `bin/runbook-slice.sh <stage>` prints §1b plus that stage's section, using the span logic gate-check already had (now `bin/lib/runbook-span.sh`, shared). The runbook routing row is split: lead, ba and architect keep the runbook; mdl, gate, test and review get the slice, and `render-routing.sh --check` counts the slice's printed words for them, so the per-role numbers stay honest. New `tests/bench/trim-noloss.sh` checks that every removed line is found again or is a still-routed table row. Behaviour A/B (5 reps × 2 tasks + 5 probes × 3 reps, sonnet): trimmed pack no worse than master on every scored metric — planted STOP refused 10/10 each arm, mxcli-check parse failures page 2/5 vs 3/5, retrieval probes 15/15. — context-cost research (r-stub-diet, T2+T3)
- process(build): **Stage 5 drafts the ready set in parallel and applies serially.** The runbook dispatch row said "sequential within a module", which serialised drafting even for independent scripts; it now points to `iterative-build-loop.md` → Gate cost, the single statement of the rule. The unit is the build-plan row: every `BUILD` row whose "Depends on" rows are all applied, minus overlapping writers (two rows that replace, alter or drop+create the same document never share a ready set, and no row is drafted while it overlaps a queued unapplied one; `brd-to-build-plan.md` has Produces name every document a row writes), runs at once, its scripts in order, one `mdl-agent` per script. Applies stay one at a time through `bin/exec.sh`, and the ready set is recomputed after each. A queued draft made before a sibling apply landed is re-checked with `mxcli diff --format struct` (preflight STOP rule 23); any removal line (checked against `describe` per BUG-146) or STOP rule 21 target means re-draft, never patch, because a stale restatement of a shared document is exactly rule 21's silent seed-call loss and passes `check --references`. Report `ready set N, drafted N, applied k`; the `mdl-agent` template says a drafter never applies and never depends on an unapplied draft. Field evidence: none yet. — MendixMau
- fix(platform-link): **CLI commits now show their changed documents in Studio Pro History.** Studio Pro's History → Model changes pane reads a `ModelChanges` array from the commit's `refs/notes/mx_metadata` note. Trap 6c's hand-written template set it to `[]`, so every mxcli/agent commit showed "Model changes 0" (field project: 270 of 270 notes empty). New `project-bin/mx-metadata-note.py` (stdlib only) computes the array from the commit's changed `.mxunit` files, in Studio Pro's entry shape: Status, UnitID, UnitType, UnitName and Module (walked up the `.mpr` Unit tree). It has `changes` / `write` / `backfill` / `sync <remote>` subcommands. `install-project-hooks.sh` now also installs post-commit and post-rewrite hooks that write the note and never block, and `--check` covers them, so `sync-project.sh` rolls them out to wired projects. Notes are published with `mx-metadata-note.py sync <remote>` after the branch push. Push config is never touched. With mxcli v0.26+ in the project root the hooks call `mxcli git note --write` instead (mendixlabs/mxcli#1337); the Python script is the fallback for older pins, and on 160 field commits both wrote the same 3,594 entries. Trap 6c rewritten. Measured against Studio Pro's own notes, 51 commits in 5 apps: 3387/3389 entries exact on all five fields. Field run on a 357-commit Mendix 11.15.0 app: 158 notes backfilled and pushed, and Studio Pro History lists the documents per revision. Review fixes: an earlier revision added `HEAD` + the notes ref to `remote.<r>.push`. It was dropped because any push refspec replaces `push.default`. A branch tracking a differently named upstream got a new same-named branch on Team Server where `simple` refuses, a missing local notes ref failed the whole push, and nobody knows whether Studio Pro's own push reads that config. The installer now only fetches the remote's notes (non-forced). It removes that exact `HEAD` + notes pair if present, and leaves and reports any other entry. `sync` handles a remote with no notes ref (it used to exit 1) and retries a rejected push once after re-merging. A note that already lists changes (Studio Pro's) is never overwritten by `write`/`backfill` without `--force`, and `sync` keeps a colleague's non-empty note over ours. The mxcli probe greps `git note --help` for `--write`. Hooks and docs call the script through `resolve_py`. Fixture `tests/wave2/test-mx-metadata-note.sh` (40 cases, over real captured template units; single- and two-tree layouts, amend, backfill and `--force`, push exit codes identical to a no-hooks clone, leftover-refspec cleanup, sync to an empty remote and its retry, notes fetch at install, a diverged notes merge; green under `init.defaultBranch` master and main). — field project (Mendix 11.15 app), MendixMau
- learn(fixture-seeding): **explore the data structure first, choose rows by use case, scan actions for resets before any run.** Two seeding runs on public template apps: seeding raised journey passes 33 -> 58 and 20 -> 51 of the same sets (FAIL 93 -> 68, 163 -> 132; INVALID unchanged), and a "Reset all demodata" journey wiped accounts so 104 of 127 journeys reported `The username or password you entered is incorrect`, identical on empty and seeded databases. Skill gains three questions a seed must answer, a use-case checklist, a destructive-action scan, a generic traps table with symptoms, measured expectations and a denominator checklist; routing trigger now fires on seed/test/demo data and empty pages. Independent review fixes: object ids follow the Mendix bigint pattern with a business-key guard (no uuids), associations are seeded where the page's path stores them, four new traps (enum names, inheritance chain, calculated attributes, view/external entities), and the port-offset and container-label traps moved to `harness-architecture.md`. — MendixMau
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,8 @@ Then filter by Role(s). A helper dispatched with a role stub (ba, architect, mdl
| 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 |
| 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 | every role |
| 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 |
| Putting a question TO the user — any gate, any stage: ask in chat not in a file, two named options plus your recommendation, one batch per gate then end the turn | `skills/interview-protocol.md` | P,0,1,2,3,4,5,6,7 | lead, ba, architect |
| The user gives feedback or asks for a change mid-project — "change X", "it also needs Y", a remark on a screenshot or the running app, a stakeholder's ask relayed in chat: log a CR row in PROJECT.md ## Change log BEFORE any edit, size it, then edit the highest artifact it alters (BRD, decision, architecture, wireframe), never the MDL first | `skills/change-intake.md` | 2,3,4,5,6,7 | lead, ba |
Expand Down
3 changes: 2 additions & 1 deletion ROUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ picks the row up. That is the whole procedure — there is no second list to rem

| Always relevant for | Load this | Agent(s) | Stage(s) | Tier |
|---|---|---|---|---|
| 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` | all | P,0,1,2,3,4,5,6,7 | baseline |
| 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` | lead,ba,architect | P,0,1,2,3,4,5,6,7 | baseline |
| 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` | mdl,gate,test,review | P,0,1,2,3,4,5,6,7 | baseline |
| 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` | all | P,0,1,2,3,4,5,6,7 | baseline |
| Before writing any .js or .sh for a check, gate or report — and before adding a rule to an existing one: judgement goes in a skill, code only fetches facts a reader cannot | `skills/skills-over-scripts.md` | all | - | baseline |
| 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` | all | - | baseline |
Expand Down
2 changes: 1 addition & 1 deletion agents/gate-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This table is your whole list. The baseline table in the project's CLAUDE.local.

| Load this | When |
|---|---|
| `skills/conversion-runbook.md` | 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 |
| `bin/runbook-slice.sh` | 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 |
| `skills/query-the-model.md` | Any question before asking the user or writing anything — query the model, then read the source, then ask the human, in that order |
| `skills/skills-over-scripts.md` | Before writing any .js or .sh for a check, gate or report — and before adding a rule to an existing one: judgement goes in a skill, code only fetches facts a reader cannot |
| `skills/degrade-to-judgement.md` | 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 |
Expand Down
2 changes: 1 addition & 1 deletion agents/mdl-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This table is your whole list. The baseline table in the project's CLAUDE.local.

| Load this | When |
|---|---|
| `skills/conversion-runbook.md` | 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 |
| `bin/runbook-slice.sh` | 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 |
| `skills/query-the-model.md` | Any question before asking the user or writing anything — query the model, then read the source, then ask the human, in that order |
| `skills/skills-over-scripts.md` | Before writing any .js or .sh for a check, gate or report — and before adding a rule to an existing one: judgement goes in a skill, code only fetches facts a reader cannot |
| `skills/degrade-to-judgement.md` | 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 |
Expand Down
2 changes: 1 addition & 1 deletion agents/review-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This table is your whole list. The baseline table in the project's CLAUDE.local.

| Load this | When |
|---|---|
| `skills/conversion-runbook.md` | 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 |
| `bin/runbook-slice.sh` | 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 |
| `skills/query-the-model.md` | Any question before asking the user or writing anything — query the model, then read the source, then ask the human, in that order |
| `skills/skills-over-scripts.md` | Before writing any .js or .sh for a check, gate or report — and before adding a rule to an existing one: judgement goes in a skill, code only fetches facts a reader cannot |
| `skills/degrade-to-judgement.md` | 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 |
Expand Down
2 changes: 1 addition & 1 deletion agents/test-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ This table is your whole list. The baseline table in the project's CLAUDE.local.

| Load this | When |
|---|---|
| `skills/conversion-runbook.md` | 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 |
| `bin/runbook-slice.sh` | 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 |
| `skills/query-the-model.md` | Any question before asking the user or writing anything — query the model, then read the source, then ask the human, in that order |
| `skills/skills-over-scripts.md` | Before writing any .js or .sh for a check, gate or report — and before adding a rule to an existing one: judgement goes in a skill, code only fetches facts a reader cannot |
| `skills/degrade-to-judgement.md` | 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 |
Expand Down
4 changes: 2 additions & 2 deletions bin/check-skill-routing.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Proves the skill-routing table actually reaches an agent, not just that it renders.
#
# render-routing.sh --check already proves the nine in-repo surfaces match the table. What it
# render-routing.sh --check already proves the in-repo surfaces match the table. What it
# does NOT catch: two rows sharing a name (one silently shadows the other in agent:<x> views),
# a [[wikilink]] between skills pointing at a file that was never written, or — the part that
# actually matters — whether bin/lib/skill-routing.sh's routing_sync_claude_local() genuinely
Expand Down Expand Up @@ -62,7 +62,7 @@ while IFS= read -r -d '' f; do
done < <(find "$ROOT/skills" -name '*.md' -print0)
[ "$dangling" -eq 0 ] && ok "no dangling cross-references" || FAIL=1

echo "== 5. the nine in-repo surfaces match the table =="
echo "== 5. the in-repo surfaces match the table =="
if "$SCRIPT_DIR/render-routing.sh" --check >/tmp/ckroute.render 2>&1; then
ok "README/ROUTING.md/agent templates/gate-check.sh all in sync"
else
Expand Down
14 changes: 6 additions & 8 deletions bin/gate-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2379,12 +2379,10 @@ fi
# grepping the runbook's actual headings ("### Stage N — …", "## 1b. …") on every run — never
# a hard-coded number, which would be wrong after the next edit. The runbook's own "how to
# read this" paragraph states the same rule; this line is what makes it actionable.
runbook_span() { # runbook_span <file> <start-regex> <end-regex> — "A–B" (1-based, inclusive) or ""
awk -v h="$2" -v e="$3" '
!start && $0 ~ h { start = NR; next }
start && $0 ~ e { end = NR - 1; exit }
END { if (start) { if (!end) end = NR; printf "%d–%d", start, end } }' "$1" 2>/dev/null
}
# The span logic lives in lib/runbook-span.sh, shared with bin/runbook-slice.sh (which prints
# these same lines for a helper that never runs a gate) and with the per-role word count in
# lib/skill-routing.sh.
. "$TOOLKIT_DIR/bin/lib/runbook-span.sh"
if [ -n "$REQUESTED_STAGE" ]; then
RB_FILE="$TOOLKIT_DIR/skills/conversion-runbook.md"
case "$REQUESTED_STAGE" in
Expand All @@ -2395,8 +2393,8 @@ if [ -n "$REQUESTED_STAGE" ]; then
# Keyed on the " — " every stage heading carries: "### Stage 0 runs in every entry mode"
# (under Entry Modes) also starts with "### Stage 0", and matched first without it.
RB_HEAD="$(grep -m1 "^### Stage $RB_STAGE — " "$RB_FILE" | sed 's/^### //; s/[[:space:]]*$//')"
RB_SPAN="$(runbook_span "$RB_FILE" "^### Stage $RB_STAGE — " "^###? ")"
RB_1B="$(runbook_span "$RB_FILE" "^## 1b\\." "^## ")"
RB_SPAN="$(runbook_stage_span "$RB_FILE" "$RB_STAGE")"
RB_1B="$(runbook_1b_span "$RB_FILE")"
if [ -n "$RB_HEAD" ] && [ -n "$RB_SPAN" ] && [ -n "$RB_1B" ]; then
printf 'Read for this gate: skills/conversion-runbook.md §"%s" (lines %s) + §1b Live Checklist (lines %s) — not the whole file\n' \
"$RB_HEAD" "$RB_SPAN" "$RB_1B"
Expand Down
3 changes: 2 additions & 1 deletion bin/init-project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ This project uses the shared toolkit at \`$TOOLKIT_ROOT\`. For ANY pipeline work
1. **Read \`$TOOLKIT_ROOT/skills/conversion-runbook.md\` §1b plus your own stage's section FIRST —
every session; not the whole file** (\`bin/gate-check.sh <project-root> <stage>\` prints the line
spans). It is the executable spec. The toolkit README and toolkit-guide.html are orientation only; stage
summaries anywhere are routing, not deliverable lists.
summaries anywhere are routing, not deliverable lists. A helper agent (mdl, gate, test, review)
runs \`$TOOLKIT_ROOT/bin/runbook-slice.sh <stage>\` instead, which prints exactly those lines.
2. **Before producing any stage artifact, open that stage's owning skill** and follow its
full output list (e.g. Stage 3 design work = \`design-artifacts.md\`, incl. one wireframe
per screen — not just a design system).
Expand Down
Loading
Loading