Skip to content

learn(parallel-builds): worktrees and branches on one app — never a plain git merge of the model; post-merge orphan check (#741) - #742

Merged
MendixMau merged 9 commits into
masterfrom
claude/loving-gates-hauc1n-worktree
Nov 12, 2026
Merged

MendixMau merged 9 commits into
masterfrom
claude/loving-gates-hauc1n-worktree

Conversation

@MendixMau

@MendixMau MendixMau commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

Direct lane (changes to skills/, bug-logs/, bin/, project-bin/, project-tests/, pipelines)

What changed and why (one paragraph): Refs #741 and #744 (a field run, 2026-11, where a plain git merge took the model's unit index from one side and a module of 63 units vanished without any gate failing). New skills/parallel-builds.md (about 1,560 words), an optional, opt-in reference outside the pipeline (maintainer decision: available for people who want it, not part of the process). It is routed in the experimental tier with stage - and role lead: listed in README's "Under trial" table and ROUTING.md, but in no stage map, no gate-check.sh stage list and no agent stub; its trigger fires only when the user explicitly asks to build in parallel worktrees or merge model branches. The skill's first line says the default stays one writer per .mpr (dispatching.md) and the pipeline does not call it. Content: set up (one worktree and branch per builder, ports and own database, rewired local-URL constants, a script number block per branch, owners for shared parts and cross-page flows), build (rerun marks, explicit-path commits), review before merge (written Decision), merge (never a plain git merge of the model; on every merge a rollback tag first, recovery per path), post-merge check in a fixed order because the build gate alone is blind to orphaned units, and a Never list. Text plus one captured fixture; no script changes (bin/gate-check.sh is untouched).

Two evidence tiers. Tier A, reproduced here (mxcli v0.28, Mendix 11.13, 2026-11-11, recaptured 2026-11-12 with neutral module names): the plain-merge failure, script replay, check order, ports and disk. Tier B, field-tested by the maintainer with mxcli v0.30+ and not reproduced here (the CLI tested in this PR is v0.28, which has only mxcli git note): the mxcli git merge path and the outcomes of the maintainer's wrapper around it, rerun marks, review file, isolation rewiring, commit discipline, the same-name CE0081 trap. Each rule in the skill carries its tier. The merge-command path is the first choice when mxcli git --help lists merge; the script-replay path stays as the second choice for v0.28, limited to branches whose scripts are all marked rerun-safe.

Impact

Row Answer
Process — human steps or gates added/removed; does anything new block; new stage artifacts None. The skill is an optional reference outside the pipeline: experimental tier, stage -, so it is in no stage map and no agent stub, and nothing blocks or gates on it. No new stage artifact.
Dependencies — shared files touched; order vs other open PRs; new tools/platform assumptions; new artifact reads + their producer bin/lib/skill-routing.tsv (one experimental row, stage -, role lead, trigger "the user explicitly asks") and its renders (README.md "Under trial" table, ROUTING.md). bin/gate-check.sh is not touched. Points to project-bin/idempotence-check.sh for the rerun check. Relies on mxcli fix hashes and show modules (v0.28); the merge path relies on mxcli git merge (v0.30+) and is gated on mxcli git --help listing it.
Context cost — always-loaded words, base → head, baseline total vs 80,000 Baseline 66,014 → 66,014 (0 added) of 80,000, from bin/render-routing.sh --check. The skill is read only on the user's ask (about 1,560 words).
Behaviour — A/B result for agent-read text, or "NOT RUN: " NOT RUN as an A/B. Tier A rules come from one measured field test; Tier B rules from the maintainer's field use. The skill text has not yet driven a fresh agent through a merge.
Runtime — seconds/resources added or saved n/a: no check or gate added. Measured for the Tier A path: script replay of three scripts 58 s plus a 14 s gate; about 0.5 GB memory and 28 s boot per extra running app; about 400 MB disk per worktree after a build.

Field evidence (Tier A) — LoanDesk (fictional test app, Mendix 11.13.0, mxcli v0.28.0), two worktrees on two branches from one base, each adding a module (Planner and Tickets in the committed capture; first run 2026-11-11, recaptured 2026-11-12 with the same counts) and both changing the menu and a role:

  • exec.sh ran unchanged inside a worktree; two apps ran side by side on their own ports and databases. The untracked mxcli binary had to be copied into the fresh worktree.
  • Plain git merge: conflict on the .mpr unit index and on the Navigation and ProjectSecurity units. Taking one side's index left 7 units of the other module on disk and unregistered (396 indexed, 403 files). mx check and the exec.sh mxbuild gate both reported 0 errors. mxcli fix hashes exited 1 and named all 7; show modules lacked the module. Verbatim capture committed at tests/wave2/fixtures/worktree-merge/.
  • Mendix's mx merge: merged the units changed on one side, left CE0137 on the units changed on both; clearing it needs Studio Pro.
  • Script replay: three scripts applied first time, 0 errors, 0 orphans, both modules present, both pages rendered. Trap found: a script that replaced the whole menu silently dropped the other branch's item with the gate green. alter navigation insert was not rerun-safe.
  • Parallel page authors on private copies (same app, 4 pages): replay took 2 min, quality equal to the serial build, but 25 min against 16 serial end to end; what fell between authors was a cross-page refresh nobody owned.
  • Unproven, stated in the skill: more than two branches; the merge command on a model with orphans; break-even size for parallel page authoring; a Team Server push after such a merge.

Not in this PR (follow-ups from #741, #744): the wrapper that automates these rules (later, its own PR); a guard that runs fix hashes and the module count after a merge; a replay-in-number-order helper for merge scripts; a lint delta during merges; a fixture that asserts on the committed capture; the Team Server push note (the ContentsHash step), which teamserver-alignment.md does not cover yet.

  • No client data anywhere in the diff
  • Size cap: one new skill, one routing row and its renders, one capture, one changelog line
  • Test tier reached: static checks (render-routing.sh --check, check-scripts.sh, check-no-private-citations.sh, mdl-rules.sh --check) plus the field test above
  • For a new/changed instrument: n/a, no instrument; the capture is verbatim tool output, not hand-written
  • For a new skill: routing row added (bin/lib/skill-routing.tsv + bin/render-routing.sh)
  • CHANGELOG.md line appended in this PR, crediting the source
  • New bug entries: n/a

Generated by Claude Code

…del-branch merges (#741)

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
…before the merge, forbid diag --fix on ORPHAN lines, spell out the tested script-replay merge, clarify the two timing figures (#742 review)

Review: MERGE-AFTER-FIX applied

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
…-readable rollback, ff-only refusal path, restore field-test cut lines (#742 round 2)

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
…gested diag --fix, and why (#741)

Review finding: at the moment fix hashes prints ORPHAN lines its own output
suggests the command that deletes the lost module; the step only pointed to
section 6.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau

Copy link
Copy Markdown
Owner Author

Review: MERGE-AFTER-FIX: a sound skill backed by a field run. But its Team Server pointer (skills/parallel-builds.md:63) sends readers to a file that does not cover the ContentsHash step #741 asked for, and nothing lists that ask as deferred.

Value: it covers #741's first ask: the parallel-build rules, including never a plain git merge of the .mpr. It also covers part of the second: the post-merge orphan and module check (parallel-builds.md:48-57) runs before the build gate, which is the core lesson.

Regression risk: low.

  • The on-demand row is at bin/lib/skill-routing.tsv:325, and the renders are in sync (render-routing.sh --check rc 0 on base and head).
  • The gate-check.sh:2790-2791 stage-map entries only feed the sync-note relevance check (:2822). No verdict, exit code or parsed output changes.
  • No script changes, so the layouts, bash 3.2 and Git Bash are unaffected.
  • The fixture directory has no consumer (CAPTURE.txt:11), so it cannot FAIL.
  • No conflict with origin/master.

Correctness: the capture looks verbatim, not hand-written. The cited flags exist: exec.sh --commit-first (:15), project-bin/idempotence-check.sh, and --serve-port / --db-type (test-stack-up.sh:816-820). Problems:

  • :10: "only 5 integration defects against 7" doesn't say which arm had which count.
  • :16: requires --db-type hsqldb for every worktree, but the issue's field run gave each worktree its own Postgres database. The rule should be "own database per worktree".
  • The "never diag --check-units --fix" rule is stated three times (:43, :50, :61), which dilutes it slightly.
  • The bundled teamserver-git skill (:30) could not be verified from this repo.

Context cost: 66,014 → 66,014 of 80,000 (measured on base 03ab940 and head). The skill is on demand, 939 words.

Time cost: none.

Exact fixes required:

  1. skills/parallel-builds.md:63: say that the ContentsHash step (Parallel worktree builds: plain git merge of App.mpr dropped a module (NCS field run), promote parallel-builds rules + guards #741 item 7) is not yet covered in teamserver-alignment.md, and add it to "Not in this PR".
  2. :10: say which arm had 5 defects and which had 7.
  3. :16: replace the mandatory --db-type hsqldb with "own database per worktree (--db-type hsqldb or a separate Postgres database)", matching the Done-when at :20.

Generated by Claude Code

…unts per arm, own database per worktree)

Review: applying MERGE-AFTER-FIX findings on #742.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau

Copy link
Copy Markdown
Owner Author

All three fixes from the review above are in e6cf1323:

  1. The Team Server paragraph now says the ContentsHash step (Parallel worktree builds: plain git merge of App.mpr dropped a module (NCS field run), promote parallel-builds rules + guards #741 item 7) is not covered by teamserver-alignment.md, was not tested here, and that this skill is not to be relied on for the push. The PR body lists it under "Not in this PR".
  2. "5 with a private copy per author, 7 without".
  3. "its own database per worktree (--db-type hsqldb, or a separate Postgres database; only hsqldb was run in our test)".

Also: the never-diag --check-units --fix rule is now stated in full twice (at the orphan-check step and in "Never"); the merge section points to both. fix hashes only runs in the post-merge check, so an agent reaches the full rule before it can see ORPHAN lines.

Re-review at e6cf1323: MERGE, no findings. Baseline 66,014 → 66,014.


Generated by Claude Code

…d rules from #744 (merge command path, rerun marks, review before merge, isolation, commit discipline)

Refs #744

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
…ath safety, evidence labels, review fixes

Review: MERGE-AFTER-FIX items a-i applied.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
…tant values; say the line keeps a bad merge (#741 #744)

Review finding: the constants gap line recommended 'mxcli constant list',
which prints resolved values and masks only machine-store ones, so it can
print the same secrets 'show constants' does. Point to the audit script,
which classifies without printing values, and say to run neither listing on
a model whose constants may hold a credential. On the merge-command path the
line keeps the bad merge until the maintainer decides; nothing is reset. Two
restatements shortened.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau

Copy link
Copy Markdown
Owner Author

Updated for #744 (head 8f09e23c). The skill is rewritten around the rules in that issue, with two labelled evidence tiers:

  • Reproduced here (mxcli v0.28): the plain-merge failure, the post-merge check order, the ban on diag --check-units --fix, ports and own database, script replay as the fallback path.
  • Field-tested by the maintainer with v0.30+, not reproduced here: mxcli git merge as first choice, rerun marks, one branch per worktree cut from the line, rewiring local-URL constants, explicit-path commits, a written Decision before merge, the CE0081 duplicate-name trap.

What changed beyond that:

  • One rule governs every merge by either path: commit, tag the line, merge, post-merge check, model check, full gates. Recovery never resets the line.
  • The outcome table is attributed to the wrapper around the command; the bare command's exit codes are not in Bug: parallel worktree builds have no toolkit guidance; plain git merge of the .mpr silently drops units (skill + field log attached) #744.
  • Script replay starts with a hard stop on its preconditions, with the field failure as its warning.
  • Finding local-URL constants is marked as a gap. The skill points to the audit script that classifies constants without printing values, not to listings that print them.
  • The capture was re-run with neutral module names (Planner, Tickets): same result, 396 indexed, 403 files, 7 orphans, exit 1, both build gates at 0 errors.

Not in this PR: the wrapper that automates these rules, the post-merge guard, a replay helper, a lint delta, the Team Server push note.

Review at 8f09e23c: MERGE, no findings. Baseline 66,014 → 66,014.


Generated by Claude Code

…mental tier, no stage map, no stub)

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau

Copy link
Copy Markdown
Owner Author

Maintainer decision applied in 995e29b3: the skill stays in the toolkit as an optional reference and is not part of the pipeline.

  • Routing row moved to the experimental tier with no stage: it is listed in ROUTING.md only, in no stage map and no agent stub. bin/gate-check.sh is identical to master again.
  • The row fires only when the user explicitly asks to build in parallel git worktrees or to merge model branches.
  • The skill opens with one line saying it is optional, the default stays one writer per .mpr, and the pipeline does not call it. Its rules are unchanged.

Known gap: README.md no longer mentions the skill, so it is findable through ROUTING.md and the changelog only.

Review at 995e29b3: MERGE. Baseline 66,014 → 66,014.


Generated by Claude Code

@MendixMau
MendixMau merged commit 4ae2529 into master Nov 12, 2026
2 checks passed
MendixMau pushed a commit that referenced this pull request Nov 12, 2026
CHANGELOG.md, ROUTING.md and bin/lib/skill-routing.tsv: both rows kept; routing re-rendered.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
MendixMau added a commit that referenced this pull request Nov 12, 2026
… must-have list (#743)

New on-demand skill skills/poc-build.md. A POC build is a build type (`Build type: full | poc` in PROJECT.md), chosen by the kickoff interview's first question (intake Q16) and independent of entry mode and Pipeline mode. No line means full; `Interview mode: auto` never picks poc; a project already past kickoff is not asked. Flow: design artifacts first, one human stop on the prototype, then model work, a journey covering the happy path and every refusal, a 12-row must-have list and a markdown hand-over. Size is warn-only. Touches bin/lib/intake-template.sh (Q16), bin/init-project.sh (scaffold line), bin/lib/resume-template.sh (starter text), the Stage P row of skills/conversion-runbook.md, one routing row and its renders. No gate logic changed. Baseline words 66,014 -> 66,025.

Refs #729.

Review: MERGE — no findings; composition check with #742 MERGE (branch equals master plus exactly this PR's changes).
CI: green on ac79eef (checks, authoring-audit).

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants