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 @@ -16,6 +16,7 @@ three commits past it), and a bug report can name a release instead of a sha nob
Sections dated before 2026-09-19 predate the cycle and stay as they are.

## Unreleased
- fix(bin/doctor.sh): **the gate self-test renamed the model in its scratch dir to `model.mpr` while copying `mprcontents/` verbatim beside it, so mxbuild bailed before writing any error file and the self-test reported `fail (unreadable error file)` — the F-042-class string that means "the gate itself is broken" — on a perfectly healthy gate.** `mprcontents/` carries an internal record of the model's real basename; the rename breaks the pair. The scratch copy now keeps the real basename (`$scratch/$(basename "$MPR")`), threaded through all four later references (baseline count, injection `exec -p`, known-bad count). **Not field-run** — reasoned and inspected only; needs one run of `doctor.sh --gate-selftest <project>` on a macOS machine with Studio Pro 11 and a real `.mpr` before the team is told to pull. Found by Yvann during Mac/sandbox onboarding — Yvann
- docs(front door): **README and `toolkit-guide.html` now count five ways in, not three.** Both already listed migration, requirements-driven, greenfield and the à-la-carte no-pipeline route; only the headlines said "three", so sessions reading the headline reported three entry modes while the runbook and `CLAUDE.md` said three plus à-la-carte. Wording now: four pipeline entry modes plus one route with no pipeline — Maurits Visser
- docs(testing): **Windows full test-run prompt.** `docs/windows-test-run.md` — a paste-able, unattended Claude Code prompt for a Git Bash machine: guards, both fixture suites, 27 Windows-relevant fixtures with their subjects, the committed inputs (`fixtures/app-analysis`, page-fidelity mocks, html-to-md capture) run directly, and a field run on a scratch copy of a real project incl. the two-tree and toolkit.env probes; one results file, facts only — Maurits Visser
- learn(eval install run, UPSTREAM-PR.md): **the "could we change the CLI?" question answered with a built, tested, field-run PR rather than an estimate** — `marketplace install --file <package.mpk>` on a shallow clone of the upstream repo, following its own CONTRIBUTING and PR checklist (test first, verify at the symptom's layer, prove by revert, record a finding). Eight unit tests with the marketplace client factory fatal-if-called, one integration test against a real package, lint and the full test tree green. The field run with real packages found a **pre-existing bug**: with a relative `-p app.mpr` the install writer refused every bundled file as path traversal after the module was already transplanted — fixed as a separate commit, test shown failing first. Two integration-test failures were my own test bugs (temp HOME hiding the mxbuild cache; return operands read before the command ran), each misread as a product failure for one round. Not submitted (repo unreachable from this session); patches, PR body and submission recipe staged in the private repo. — Maurits Visser
Expand Down
15 changes: 10 additions & 5 deletions bin/doctor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ if [ "$QUICK" != 1 ] || [ "$GATE_SELFTEST" = 1 ]; then
head_ "Gate self-test (can the mxbuild gate actually see an error?)"

gate_selftest() {
local scratch t0 t1 elapsed mdl model_dir base_count bad_count rc timeout_s
local scratch scratch_mpr t0 t1 elapsed mdl model_dir base_count bad_count rc timeout_s
timeout_s="${DOCTOR_GATE_TIMEOUT:-300}"
t0=$(date +%s)

Expand All @@ -916,7 +916,12 @@ gate_selftest() {
}
trap 'rm -rf "$scratch" 2>/dev/null' RETURN

if ! cp "$MPR" "$scratch/model.mpr" 2>/dev/null; then
# Keep the model's REAL basename in the scratch dir: mprcontents/ (copied verbatim below)
# carries an internal record of it, and a renamed copy makes mxbuild bail BEFORE it writes
# any error file — which this self-test would then report as "gate cannot read mxbuild's
# error file", a false FAIL on a healthy gate. (Reported 2026-09-22 by Yvann.)
scratch_mpr="$scratch/$(basename "$MPR")"
if ! cp "$MPR" "$scratch_mpr" 2>/dev/null; then
bad "gate self-test: could not copy the model into the scratch dir"
GATE_SELFTEST_LINE="fail (copy failed)"
return 0
Expand All @@ -926,7 +931,7 @@ gate_selftest() {

# (a) Baseline: the gate must resolve SOME integer off this model, clean or not — "?" here
# means the gate cannot read mxbuild's own output, which is the original F-042-class defect.
base_count=$(mxtk_mxbuild_error_count "$scratch/model.mpr" "$timeout_s")
base_count=$(mxtk_mxbuild_error_count "$scratch_mpr" "$timeout_s")
rc=$?
if [ "$rc" -eq 3 ]; then
bad "gate self-test: mxbuild did not return within ${timeout_s}s (baseline run)"
Expand Down Expand Up @@ -964,14 +969,14 @@ END;
MDL
# If mxcli refuses the injection (syntax rejected by a newer grammar, model locked, ...),
# the copy is still clean and a 0 below would be a FALSE "blind" verdict — say NOT RUN.
if ! "$PMXCLI_PROBE" exec "$mdl" -p "$scratch/model.mpr" >"$scratch/inject.out" 2>&1; then
if ! "$PMXCLI_PROBE" exec "$mdl" -p "$scratch_mpr" >"$scratch/inject.out" 2>&1; then
warn "gate self-test: NOT RUN — the project's mxcli refused the known-bad injection:"
sed 's/^/ /' "$scratch/inject.out" | head -5
GATE_SELFTEST_LINE="not-run (injection refused)"
return 0
fi

bad_count=$(mxtk_mxbuild_error_count "$scratch/model.mpr" "$timeout_s")
bad_count=$(mxtk_mxbuild_error_count "$scratch_mpr" "$timeout_s")
rc=$?
if [ "$rc" -eq 3 ]; then
bad "gate self-test: mxbuild did not return within ${timeout_s}s (known-bad run)"
Expand Down
Loading