Skip to content
Merged
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 @@ -22,6 +22,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m
- fix(brd-report, gate-check): **Stage 2 no longer trusts a self-declared "Clean" on requirements-driven BRDs** — `bin/brd-report.sh` now runs brd-validation.md's mechanical subset over every non-code-extracted BRD (complete use cases, entity references that resolve, one owner per entity and business-rule id, rule ids — read from `{id}` or a leading token of a string rule (`BR001: …`), tracked open questions; each with its denominator; reserved names as warnings) and Stage 2 FAILs a Clean report it contradicts (`--waive artifact/brd-validation --reason`) (#622) — a requirements-driven field run (Path B, 9 hand-written BRDs)
- fix(gate-check, interview-protocol): **Stage 3/4 can pass an unattended run, and nothing ships on it** (#624): under `Interview mode: auto` (alias `unattended`, as `bin/interview-mode.sh` resolves it) a Stage 3/4 Decisions row recorded `ASSUMED` with `consentBy: auto-mode` and a `consentAt` satisfies the ✋ gate; in every other mode the gate is `CONFIRMED`-only as before (its FAIL line now says when an auto-mode row is the reason), and Stage 7 cutover stays `CONFIRMED`-only. Every run, any mode, prints `N ✋ decision(s) assumed by auto-mode — confirm before release: <ids>` (Stage 0/3/4/7 rows still stamped auto-mode, plus a triage.md signed by auto mode), and Stage 6 FAILs while one remains — a stage-6 waiver does not excuse it. A person confirms or overturns each: any status, `consentBy` naming them. Protected-rule change ("✋ gates never resolve to ASSUMED"), maintainer decision 2026-11-05; rule in `interview-protocol.md` §"What `auto` obliges you to do", one-line pointers in the runbook, ba/architect stubs, `agents/README.md`, `architecture-blueprint.md`, `checkpoint-template.md`, `CONVERSION-RUNBOOK.md` (baseline 64,891 → 65,053 words). New fixture `tests/wave2/test-auto-mode-hand-gates.sh`. Field run: a copy of a real unattended Stage-4 purchasing-app project that had waived Stages 3/4 to get past the gate — waivers removed, 3/4 FAIL → PASS, 11 auto-mode ✋ decisions listed, Stage 6 FAIL with test surfaces present, PASS once confirmed. — Mijn Roostercommissie field run (#624)

- new(gate-check, interaction-model): **Stage 3 now fails on an interaction model that leaves out a user task or a wireframe's page parameter, and asks about BRD actors with no home** ([#291](https://github.com/MendixMau/mxcli-project-toolkit/issues/291), part 2). Once `design/interaction-model.md` exists, `bin/lib/interaction-model-check.sh` (called by `gate-check.sh`) lists one FAIL per BRD approval/review/sign-off/user-task use case not named on any line (row or bullet) under an Inbox heading, and per `design/wireframes/*.html` without a `Page parameter:` line (`Module.Entity`, a trailing `(note)` allowed, or `none — <reason>`) in its `wf-contract` block; any of them fails Stage 3. A BRD actor with no "Role homes" row is MANUAL (confirm it is a user role, or add a `none — <reason>` row), never FAIL. Findings are waived by hand in the register (`Waived artifact interaction-model/<unit>: reason`); a project adopted above stage 3 reports ADOPTED. A new `artifact-manifest.tsv` row reports the artifact PENDING when it is absent, which does not block. `checkpoint-design.md` asks "who lands where, and how does each role find its work" next to the layout question; `brd-to-build-plan.md` Step 7 reads wire points from the artifact. Fixture `tests/wave2/test-interaction-model-gate.sh` (synthetic trees only). Brought up to date with master 2026-11-03; run against six Stage-3 worker outputs, which found two defects, both fixed: a MANUAL role finding no longer hides the "no Stage-3 CONFIRMED decision" FAIL (it was reported MANUAL, exit 2), and a role cell with a trailing note in parentheses (`Owner (signed-in …)`) now names the role. After review: a "Homes and inboxes" heading with a `Home` column reads as the Role homes table. Fixture cases T13–T18. A field run on a client project is still owed — field retro (#291)
- fix(gate-check): **Stage 0 no longer passes a `_pending_` sign-off (#620)**: the triage `Confirmed by:` check rejected only a `[`, so `_pending_`, `TBD`, `n/a`, `—` or `?` signed a human gate off. A whole-value "not yet" (markdown emphasis stripped, case ignored) now FAILs and says to ask the user; "confirmed in chat, pending legal review" still passes — Mijn Roostercommissie field run
- fix(obligations): **`design-reaches-app` is owed from Stage 5, not 3 (#627)**: its only producer (check-design-reaches-app.sh against the BUILT stylesheet, ui-preflight-pages.md B0) runs at the first build, so every Stage 3/4 summary carried a PENDING nothing honest could clear. The routing row stays at 3,5 — Mijn Roostercommissie field run
- fix(gate-check, render-routing): **the obligations reverse check stops printing in consumer projects (#623)**: "give it an obligation row in obligations.tsv" is a message to the toolkit maintainer and appeared in every project's gate output from Stage 2 on. It now runs in `render-routing.sh --check` (CI) and in gate-check only against the toolkit itself or under `MXTK_AUTHORING=1` — Mijn Roostercommissie field run
Expand Down
31 changes: 31 additions & 0 deletions bin/gate-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1641,10 +1641,21 @@ check_stage_3() {
fi
done
fi
# The interaction-model facts (#291), computed once before the stage loop and printed under
# "Interaction model (stage 3 facts)". PENDING (no artifact yet — the Artifacts block reports
# that) and ADOPTED/WAIVED leave this verdict alone; a finding is something examined and wrong.
# A FAIL returns here; a MANUAL only replaces a PASS, so it never hides the register FAIL below.
if [ "${MXTK_IM_STATUS:-}" = "FAIL" ]; then
local im_also=""
if ! reg_unavailable && ! has_confirmed_decision 3 && ! { interview_mode_is_auto && has_auto_assumed_decision 3; }; then im_also="; also: no Stage-3 CONFIRMED decision"; fi
echo "FAIL|interaction model: ${MXTK_IM_NOTE} — each finding is listed under 'Interaction model (stage 3 facts)' (skills/interaction-model.md)${im_also}"; return
fi
if reg_unavailable; then reg_unavailable_note; return; fi
if has_confirmed_decision 3; then
if [ "${MXTK_IM_STATUS:-}" = "MANUAL" ]; then echo "MANUAL|interaction model: ${MXTK_IM_NOTE}$wf_note"; return; fi
echo "PASS|fit-gap, blueprint render, design system, wireframes present and a Stage-3 CONFIRMED decision is in $REGISTER$wf_note"
elif interview_mode_is_auto && has_auto_assumed_decision 3; then
if [ "${MXTK_IM_STATUS:-}" = "MANUAL" ]; then echo "MANUAL|interaction model: ${MXTK_IM_NOTE}$wf_note"; return; fi
echo "PASS|fit-gap, blueprint render, design system, wireframes present and a Stage-3 decision is ASSUMED by auto-mode in $REGISTER (Interview mode: auto) — a human confirms it before release$wf_note"
else
echo "FAIL|artifacts exist but ${REGISTER:-PROJECT.md} has no Stage-3 CONFIRMED decision — ✋ gate: artifacts without an interview don't pass$(auto_assumed_hint 3)"
Expand Down Expand Up @@ -3316,6 +3327,26 @@ else
printf 'Artifacts: FAULT — bin/lib/artifact-check.sh missing from %s; no artifact was checked\n' "$TOOLKIT_DIR"
fi

# ---------------------------------------------------------------------------
# Interaction model — the Stage-3 facts over design/interaction-model.md (#291).
#
# The artifact check above only notices the file is absent. Once it exists, three facts are
# read from it: every BRD role has a home row, every BRD approval/user-task use case has an
# inbox row (or a stated reason), every wireframe carries its `Page parameter:` line. Each
# finding prints here; check_stage_3() turns any un-waived one into a Stage-3 FAIL. Judgement
# (is that the right home?) stays in skills/interaction-model.md. Waivers and adoption: see the
# header of bin/lib/interaction-model-check.sh.
MXTK_IM_STATUS=""; MXTK_IM_NOTE=""
if [ -r "$TOOLKIT_DIR/bin/lib/interaction-model-check.sh" ] && [ -r "$TOOLKIT_DIR/bin/lib/artifact-check.sh" ]; then
# shellcheck source=lib/interaction-model-check.sh
. "$TOOLKIT_DIR/bin/lib/interaction-model-check.sh"
mxtk_interaction_model_check "$PROJECT_DIR" "$REGISTER" "$ANALYSIS_BASE"
else
MXTK_IM_STATUS="MANUAL"
MXTK_IM_NOTE="bin/lib/interaction-model-check.sh missing from $TOOLKIT_DIR — cannot evaluate, which is not a pass"
printf 'Interaction model (stage 3 facts): MANUAL — %s\n' "$MXTK_IM_NOTE"
fi

# ---------------------------------------------------------------------------
# Source sufficiency — was the source actually characterised, or did Stage 0
# pass on nobody having looked?
Expand Down
1 change: 1 addition & 0 deletions bin/lib/artifact-manifest.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ blueprint-html 3 architecture/blueprint.html skills/architecture-blueprint.md St
design-system 3 design/design-system.html skills/design-artifacts.md:79 (annotated showcase linking ds.css) bin/gate-check.sh:913 (check_stage_3), bin/gate-check.sh:1135 (build-ready) migration,requirements,existing-app-change gate
ds-css 3 design/ds.css skills/design-artifacts.md:75 (the physical token/component source) skills/design-artifacts.md:68 (two-files rule — every wireframe links it), bin/gate-check.sh:1135 (build-ready accepts either file) migration,requirements,existing-app-change report
wireframes 3 design/wireframes/*.html skills/design-artifacts.md Step 3, one per screen bin/gate-check.sh:923 (check_stage_3), bin/gate-check.sh:1129 (build-ready), skills/ui-preflight-pages.md (mdl-agent pre-flight input) migration,requirements,existing-app-change gate
interaction-model 3 design/interaction-model.md skills/interaction-model.md (Stage 3, after the role model is CONFIRMED and before the first wireframe — design-artifacts.md Step 2b) skills/design-artifacts.md Step 3 (every wireframe's wf-contract block is copied from its row), skills/brd-to-build-plan.md Step 7 Navigation Wiring (home per role, wire points, page parameters), bin/lib/interaction-model-check.sh (the Stage-3 facts check_stage_3 fails on) migration,requirements,existing-app-change report
module-definition 3 architecture/modules/*/definition.md skills/architecture-blueprint.md Step 1 (:60 — the directory shape, one doc per module) THIS ROW IS ITS FIRST MECHANICAL CONSUMER — as of 2026-08-22 nothing executable read definition.md (improvement-plan P7 residue, the newest instance of the pattern this table exists to stop); prose consumers: skills/architecture-blueprint.md:43, skills/coverage-ledger.md:27 migration,requirements,existing-app-change report
build-plan 4 architecture/build-plan.md skills/brd-to-build-plan.md bin/gate-check.sh:955 (check_stage_4), project-bin/build-plan-status.sh (progress board), project-bin/coverage-preflight.sh:238 (the claims join) migration,requirements,existing-app-change gate
build-plan-html 4 architecture/progress-report.html project-bin/build-plan-status.sh --html (skills/brd-to-build-plan.md:47 — derived view, never hand-edited; refreshed by exec.sh and full gate-check.sh runs via --refresh) conversion-runbook.md §2 Stage-4 Surface row, parsed at bin/gate-check.sh:1284 migration,requirements,existing-app-change report
Expand Down
Loading
Loading