Record that Procedure holds carry the fault Run holds no longer do - #616
Open
xmap wants to merge 1 commit into
Open
Record that Procedure holds carry the fault Run holds no longer do#616xmap wants to merge 1 commit into
xmap wants to merge 1 commit into
Conversation
Cause-scoped claims fixed order-dependent hold contention for Run. Procedure
was left with the same three conditions and no note saying so, which is how a
known fault becomes a rediscovered one.
1. ProcedureStatus.HELD is one bit. ProcedureHeld carries a required reason
that explains a hold without owning one, so a releaser cannot read it to
learn whether the hold is its own.
2. hold_procedure admits RUNNING only, so a second concern arriving at an
already-held Procedure cannot record its intent.
3. resume_procedure has no notion of who placed the hold; its only
cross-concern guard is the hand-patched parent_run_held flag, one bespoke
case rather than a general rule.
Two concerns can hold a Procedure, which is what makes the shape a fault: an
operator via hold_procedure, and the Conductor via conduct_or_hold, which
pauses to Held on a recoverable step failure so the conduct stays resumable.
SEVERITY IS LOWER THAN FOR RUN, and the tests say why rather than leaving the
structural similarity to imply otherwise. append_activities admits RUNNING
only, so a conduct cannot quietly carry on past a hold it did not see and
never reaches its own pause attempt; dropping the Conductor's hold silently
needs a narrow race, not the wide human-response window that made the Run
fault dangerous. What bites with no race at all is condition 3: an operator
resume clears the Conductor's pause outright, because nothing records whose
hold it is. Condition 2 holds but fails LOUDLY, with ProcedureCannotHoldError
rather than a silent drop.
These are characterization tests. They pass against today's behaviour and
document the fault rather than failing on it, so the suite stays green and a
future fix shows up as these tests changing.
The file had sat untracked because it did not typecheck: two Procedure
constructions passed a raw str where ProcedureName is required, which pyright
in the main checkout catches and a worktree without the file never saw.
Wrapped both; the ProcedureRegistered payload keeps its raw str, which is
correct for an event payload.
Verified: tests/unit/operation 1,287 passed; pyright 0 errors; ruff clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xmap
enabled auto-merge (squash)
August 6, 2026 17:20
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.
Why
Cause-scoped claims fixed order-dependent hold contention for
Run.Procedurewas left with the same three conditions and no note saying so, which is how a known fault becomes a rediscovered one.ProcedureStatus.HELDis one bit.ProcedureHeldcarries a requiredreasonthat explains a hold without owning one, so a releaser cannot read it to learn whether the hold is its own.hold_procedureadmitsRUNNINGonly, so a second concern arriving at an already-held Procedure cannot record its intent.resume_procedurehas no notion of who placed the hold; its only cross-concern guard is the hand-patchedparent_run_heldflag, one bespoke case rather than a general rule.Two concerns can hold a Procedure, which is what makes the shape a fault: an operator via
hold_procedure, and the Conductor viaconduct_or_hold, which pauses toHeldon a recoverable step failure so the conduct stays resumable.Severity is lower than for Run, and the tests say why
Rather than leaving the structural similarity to imply otherwise.
append_activitiesadmitsRUNNINGonly, so a conduct cannot quietly carry on past a hold it did not see and never reaches its own pause attempt. Dropping the Conductor's hold silently needs a narrow race, not the wide human-response window that made the Run fault dangerous.What bites with no race at all is condition 3: an operator resume clears the Conductor's pause outright, because nothing records whose hold it is. Condition 2 holds but fails loudly, with
ProcedureCannotHoldErrorrather than a silent drop.These are characterization tests
They pass against today's behaviour and document the fault rather than failing on it, so the suite stays green and a future fix shows up as these tests changing.
Why it was untracked
The file did not typecheck: two
Procedureconstructions passed a rawstrwhereProcedureNameis required. Pyright in the main checkout catches that; a worktree without the file never saw it. Both are wrapped now. TheProcedureRegisteredpayload keeps its rawstr, which is correct for an event payload.Also removes two rename-leftover directories (
set_agent_target_plan,amend_allocation_ceiling) that held nothing but__pycache__and failedtest_no_empty_feature_dirsonce anything in the main checkout was committed. Both renamed successors exist.Verification
tests/unit/operation1,287 passed;tests/architecture30,313 passed / 621 skipped🤖 Generated with Claude Code