Conversation
#751 moved the per-tool index out of tools/CLAUDE.md into the generated tools/INDEX.md, because the inline list was the top merge-queue conflict surface. The sync gate still recognised only CLAUDE.md as a domain's documentation surface, so every post-#751 PR that touches a tool and regenerates tools/INDEX.md was reported as "code changes without CLAUDE.md update" and blocked at pre-push and in CI. Recognise CLAUDE.md and INDEX.md as documentation surfaces (basename match, so a lookalike like MY_INDEX.md is still code). The gate is not weakened: a tool change with no documentation change is still drift, and INDEX.md only moves when the tool's own INDEX: line moves. Tests: 4 regression cases covering both directions, including the fail-closed case for an undocumented tool change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rd test, make epoch fencing real
Deep-scan findings B1/B2/B3 in the multibox coordination layer.
B1 (split-brain): LeaseStore derived claim keys with case_policy="platform",
which case-folds when os.name == 'nt' and preserves case otherwise. Two
instances sharing one coordination db therefore derived DIFFERENT keys for the
same file ('tools/Runner.py' -> 'tools/runner.py' on Windows, 'tools/Runner.py'
on Linux), so _check_conflicts (exact match) missed and BOTH were granted the
claim. Case policy is now configuration, not a property of the host OS, resolved
explicit-arg > multibox.case_policy > $AESOP_CLAIM_CASE_POLICY > "insensitive".
An unrecognized policy raises ValueError (fail-closed).
B2 (vacuous guard): the heterogeneity guard called canonical_claim_path directly
with case_policy="insensitive" -- a value production never passed -- and never
touched _normalize_path, so it stayed green while B1 was live and survived
mutating _normalize_path to the identity function. Rewritten to exercise the real
production entry point, plus an end-to-end LeaseStore split-brain reproducer.
B3 (inert epoch): nothing in the repo ever incremented the persisted epoch, so
get_identity_with_epoch returned 1 forever and could not distinguish a pre- from
a post-crash instance, while the module documented it as a monotonic boot
counter. Acquisition now increments and durably persists the epoch (temp file +
fsync + os.replace), fail-closed on persist failure (EpochPersistError, a
subclass of IdentityCorruptionError) and on a non-integer epoch. Existing
corrupt-file fail-closed hardening and fresh-box epoch=1 are preserved.
release_own_stale() now raises NotImplementedError instead of returning an
unconditional True while doing nothing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Dissolving merge-queue batch: required check(s) absent from rollup: windows |
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.
Merge-queue batch built by tools/merge_queue.py.
Members: #752, #754
Members are closed only after
git merge-base --is-ancestorproves their content landed on main.