Repository navigation
Conversation
- Stale-lock takeover serialised through an O_EXCL .exec.lock.takeover file; the lock is removed only if it still holds the stale line read (no mv -f restore). 12 contenders x 10 rounds: master 2/10 rounds with 2-3 holders, fixed 0/10. - --watch-compat: only ui-loop.md's watch-safe list says "watch can apply this"; other statements print "unknown — restart if behaviour looks stale". - Two-tree (.mpr under app/) cases for the lock and --commit-first. - Leading flags parsed in one loop (--commit-first --cr CR-NN works); a script name starting with -- is refused before any commit or snapshot. - ui-only test lane names the embedders of a changed snippet/layout. Refs #287 #289 #274 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
The watch paragraph listed only `restart needed` and `watch can apply this`; exec.sh now also prints `unknown — restart if behaviour looks stale` for statements on neither column. Reworded within the same paragraph to stay inside the baseline word budget. Refs #287 #289 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau
pushed a commit
that referenced
this pull request
Oct 13, 2026
…tocol (#324) test-scratch.sh shares .mpr-snapshots/.exec.lock with exec.sh, so its stale-lock takeover now mirrors exec_lock_takeover from PR #324 (fix/exec-followups @ ed4efbb): the same O_EXCL <lock>.takeover file, stale when its pid is dead or after 10 s (empty: after a minute), re-read and remove only the exact stale line, put a wrongly moved takeover file back with ln. The port lock uses the same protocol. New cross-script fixture tests/wave2/test-shared-lock-takeover.sh: 4 rounds of 5 exec.sh + 5 test-scratch contenders on one dead-holder lock never produce two holders (master's test-scratch: overlaps in 3 of 3 runs). exec.sh's block comes from the real exec.sh once it carries exec_lock_takeover, else from a verbatim copy of #324's block. Refs #244 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau
pushed a commit
that referenced
this pull request
Oct 13, 2026
…ith #324's review) `find -mmin +0` treats a fresh empty takeover file as stale at once (GNU matches 0-2 s old files, BSD rounds up), so a takeover in progress could be broken into: two holders under load. Now -mmin +1 (empty for over a minute). The takeover file is removed only when its content is what was judged stale (a moved-aside live one is put back with ln, and kept if that fails), and a finished takeover removes the file only while it still holds its own line. Fixture: a fresh empty takeover file blocks the takeover and is left alone; one over a minute old (touch -t 2000) is stale. Fails on the previous body. Keep in step with exec.sh's exec_lock_takeover (PR #324). Refs #244 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
…ith test-scratch Review of #324: `find -mmin +0` matched a takeover file created a second ago, so a live contender's fresh empty file was moved aside and a third contender got in (reviewer: 2-3 holders in 6/15 and 16/30 rounds with a 100 ms delay). Now -mmin +1; a moved-aside copy is deleted only if it is what was judged stale, else restored with ln (left on disk if ln fails); the holder removes the takeover file only while it holds its own line. Body identical to test-scratch.sh take_over() in #322. Reviewer's delayed harness against this body: 0/15 rounds with >1 holder. Also: microflow-body verbs, CREATE FOLDER and MOVE ... TO FOLDER are neutral for the watch verdict; agent-roles.md names the unknown verdict. Refs #287 #289 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau
pushed a commit
that referenced
this pull request
Oct 13, 2026
The aligned exec_lock_takeover (-mmin +1, own-file-only removal) now matches test-scratch take_over() apart from signature and parameter names (diffed). Refs #244 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
PR #312 makes lint-gate.sh print a non-blocking `note: SEC014 not configured` on stderr. run_lint_gate captured that output and showed it only on failure, so the note never appeared on a clean exec. Always echo that one line; exit code unchanged. Fixture: stub lint-gate with the note on stderr and rc 0 -> exec output shows it (fails on the prior head). Refs #287 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
MendixMau
pushed a commit
that referenced
this pull request
Oct 13, 2026
…al, shared stale-lock takeover, SEC014 note echo Conflict: skills/agent-roles.md — the Dispatching section moved to skills/dispatching.md in #320; kept integration's agent-roles.md and re-applied #324's restart-paragraph wording in dispatching.md. Review: independent joint review (agent a1e0b45) of head 90a6957 — MERGE. Contention harness 0 double holders on dead lock; follow-up owed for a takeover race after a mid-takeover crash (2/160 rounds; re-check own line before compare-and-rm). Fixtures: exec-lock-watch 84/0, exec-change-class 21/0, bug07-08 43/0, shared-lock-takeover 6/0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
3 of 4 tasks
MendixMau
added a commit
that referenced
this pull request
Oct 14, 2026
) Every constituent PR was reviewed by a fresh agent that did not write it (CLAUDE.md "Merging a PR"); only MERGE verdicts joined. CI green on each constituent head and on this head (40814fc); full suites run on the branch. Review lines (per merged PR): - #315 context trim — MERGE; 360/385 removed lines found verbatim in their new homes, rest read by hand; baseline 79,997 -> 76,259. - #316 independent-review + word-budget rules — MERGE-AFTER-FIX (3 rounds), fixes applied as specified. - #318 page-fidelity displayed text — MERGE after fix round + confirmation. - #317 interaction-model skill (#291 part 1) — MERGE after fix round + confirmation; no client names leaked. - #321 PROOF-OF-LOOK per section; final-look not due before derived Stage 6 — MERGE after fix round + confirmation. - #307 graph-sweep guard; per-BRD conformance ledgers — MERGE after two fix rounds + confirmation. - #325 extraction-quality section; token-burn fixes — MERGE after fix round + confirmation. - #310 e2e OQL by alias, negative-span liveness, APP-DOWN, #302 credential regression fix — MERGE after fix round + 3 confirmations. - #323 inbox promotions — MERGE after fix round + confirmation. - #308 lint gate BLIND on reverted stock rules — MERGE (FIRST-SEEN reverted) after two fix rounds + confirmation. - #328 pipefail + grep -q flake — MERGE; 0/30 flakes vs 15/100 on master. Follow-up: run-all resolves bin/lib/ subjects (reviewed, MERGE). - #319 test-stack-up command-line ownership proof — MERGE after fix round + 2 confirmations. - #327 change-intake core + on-demand detail; CRLF-safe change log — MERGE after fix round + confirmation. - #320 follow-ups to #290/#292; Dispatching split out — MERGE after fix round + confirmation. - #326 status delivery rounds (existing-app mode) — MERGE after fix round + confirmation. - #312 lint batch 4: SEC014, toolkit CONV009 — MERGE after review + 2 fix rounds + confirmation; field run on mxcli 0.26. - #324 exec.sh change classes, shared stale-lock takeover, SEC014 note echo — MERGE (joint review); follow-up owed for a takeover race after a mid-takeover crash. - #322 MxTest after-startup guard, mxcli-run pid check — MERGE (joint review). - #314 doctor property-set exit code; sync announces its bound — MERGE (joint review). - #330 review follow-ups (exit 4/5 docs, pipefail, NUL strip) — MERGE-AFTER-FIX, fixes applied; takeover re-check dropped. Field runs are still owed for most instruments in this batch (stated in each PR). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Owner
Author
|
Landed on master as part of the integration squash #329 (commit 31e90ae), after independent review — its Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five defects in
project-bin/exec.shthat independent reviews of the merged PRs #304, #306 and #290 found. Each fix comes with fixture cases that fail on master.1. Stale-lock takeover allowed more than one holder (#304, medium)
Problem. To take over a stale lock, a contender moved it aside. If the file it moved turned out to be a fresh lock, it put it back with
mv -f. That is check-then-act. With 3 or more contenders, B moved A's fresh lock aside, C's noclobber write landed in the gap, and B then saw a lock and deleted A's.Fix. Takeover now goes through a second O_EXCL file,
.exec.lock.takeover. While holding it, a contender re-reads the lock and removes it only if it still holds exactly the stale line it read earlier. The fresh lock is never moved aside, so there is nothing to restore.ln, which never clobbers.mvandln; no flock.Evidence. The new case in
tests/wave2/test-exec-lock-watch.shruns 10 rounds of 12 contenders started behind a barrier against a dead-pid lock. A probe in the snapshot stub counts how many runs are inside the locked section at once.Further cases: a dead contender's takeover file does not block, and an old empty takeover file does not block (CLAUDE.md instrument rule 7).
2.
--watch-compatoverclaimed "watch can apply this" (#304, low)Problem. Any statement the classifier did not recognise was reported as watch-safe.
Fix. Only the statements on
skills/ui-loop.md's watch-safe list now say "watch can apply this":ALTER PAGE,ALTER SNIPPET,CREATE [OR …] SNIPPET, andCREATE OR REPLACE|MODIFY PAGE. Read-only statements are neutral. Every other statement printsunknown — restart if behaviour looks stale: <line N: head>, both in the advisory mode and after a real run.This changes two outputs:
ALTER ENTITY … MODIFY(noADD) is nowunknown.CREATE MODULEalone is nowunknown.Golden input:
create associationtaken verbatim from a pending bug issue.CREATE ENUMERATIONfromskills/build/workflow-example.mdl.create java actionwith a$$body, verbatim from the bug87 issue.DESCRIBE NAVIGATIONfixture.ALTER ENTITY … MODIFY ATTRIBUTEorCREATE CONSTANTstatement. Those two are written from the grammar, and the fixture says so.3. Two-tree coverage (#304, low)
New case: a checkout with the
.mprunderapp/. It checks that:app/model is refused;--commit-firstcommits exactlyapp/mprcontents/*and leaves an unrelated staged file staged.These cases pass on master too. They add coverage for CLAUDE.md field-proof rule 2 rather than proving a bug.
4.
--crafter--commit-first(#306)Problem.
--crwas only read as the first argument. In the documented order,--commit-first --cr CR-07 x.mdl, the model was committed and then "--cr" was used as the script path.Fix.
--cr,--commit-firstand then--patchor an advisory mode are now parsed in one loop, in any order. An unknown flag, or a script name starting with--, exits 2 before the lock, the commit or the snapshot.Fixture. The documented order runs, and its BUILD-LOG row carries
cr: CR-07.--commit-first --bogus x.mdlis refused with no commit, no snapshot and no exec.5. ui-only test lane text (#290)
"no other module's journeys" is now "re-run the journeys of every page the change reaches (embedders of a changed snippet/layout)". A grep case for this is in
test-exec-change-class.sh.Checks
Fixtures:
test-exec-lock-watch.sh: 77/0. On master it fails 14 cases (the race, the takeover file, flag order, misplaced flag, 6 watch-compat cases).test-exec-change-class.sh: 21/0 (1 failure on master).test-bug07-08.sh project-bin/exec.sh: 43/0.test-metrics-ledger.sh: 42/0.test-change-log.sh bin/gate-check.sh: 39/0. One run showed 1 failure while two heavy fixture runs were going on in parallel; the rerun passed.test-lint-gate-accept.sh: 20/0.test-exec-approval.sh: 43/0.Repo checks:
check-scripts,check-portabilityandcheck-no-private-citationsare clean.check-pr-discipline origin/masteris clean.Not covered / follow-ups
project-bin/test-scratch.shhas the same bug. It takes the same lock with a blindmv -ftakeover (lines 81–82), so it is not mutually exclusive with exec.sh either. It should use the same.exec.lock.takeoverprotocol. That file is outside this PR's scope (another change owns it).skills/ui-loop.mdneeds a one-line update. Lines ~208–212 list two verdicts; they should mention the third (unknown — restart if behaviour looks stale). Not edited here, to stay in scope.mv,ln,find -mmin,sleep 0.01in the fixture only).Refs #287 #289 #274
🤖 Generated with Claude Code
https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw
Generated by Claude Code