fix(OperationsCenter): widen executor-backend self-heal to critique_executor - #491
Merged
Conversation
…xecutor
`ensure_executor_backends()` in scripts/operations-center.sh reinstalls dropped
executor sibling checkouts at every fleet launch, but covered only two of the
three backends OC imports: it probed `import team_executor, dag_executor` and
looped over `TeamExecutor DAGExecutor`.
`critique_executor` — imported as a library by
backends/critique_executor/adapter.py, backed by the sibling checkout
../CritiqueExecutor — was in neither list. A `uv sync` or venv-recreate that
dropped it was therefore NOT auto-repaired, so every critique-topology task
failed at execute with `No module named 'critique_executor'` until a human
noticed: the exact failure mode the self-heal exists to prevent for the other
two.
The drift was structural — the probe and the install loop were two separate
hardcoded lists inside one function, so widening one without the other was easy
and silent. Collapsed them into a single EXECUTOR_BACKENDS array of
`<import name>:<sibling checkout dir>` pairs; both the probe's import statement
and the install loop derive from it. Behavior is otherwise unchanged (still
all-or-nothing: any missing module reinstalls all siblings; missing `uv` or a
missing checkout still degrades to a WARNING rather than aborting launch).
Not sourced from Python, deliberately. The nearest real Python lists are
BackendName / EXECUTOR_LANE_NAMES (contracts/enums.py) and the
backends/factory.py registry, but neither carries the checkout-dir half of each
pair and it is not derivable (`dag_executor` -> `DAGExecutor`, not
`DagExecutor`). More fundamentally, this self-heal has to run precisely when the
venv is too broken to import operations_center. Cross-reference comments added
in both scripts/operations-center.sh and backends/factory.py, each naming the
other, so adding a backend updates both.
Verified against the live stack (siblings at
~/GitHub/{TeamExecutor,DAGExecutor,CritiqueExecutor}): `bash -n` clean; the
probe builds exactly `import team_executor, dag_executor, critique_executor`;
silent no-op with rc=0 against the real fleet venv; against a throwaway empty
venv the real `uv` path installed all three (+ critique-executor==0.1.0 from
file:///home/diane/GitHub/CritiqueExecutor), all three then imported, and a
second call was a silent no-op. Fleet venv untouched.
tests/unit/backends/test_factory.py + test_critique_executor_adapter.py:
5 passed. ruff check + format clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…po_root/..
`.hooks/pre-push` finds the boundary disclosure artifact by globbing sibling
checkouts of the main clone:
workspace_root="$(cd "$repo_root/.." && pwd)"
"$workspace_root"/*/dist/boundary_disclosure_artifact.json
That assumes $repo_root is the main clone. Inside a git worktree it is not:
repo_root is .../OperationsCenter/.claude/worktrees/<name>, so workspace_root
resolved to .../.claude/worktrees — a directory with no siblings. The glob
matched nothing and every push from a worktree failed closed with
"missing REPOGRAPH_BOUNDARY_ARTIFACT_FILE", pointing the operator at a
generation step they had already done one directory over.
`git rev-parse --git-common-dir` is shared by the main clone and all of its
worktrees, so its parent is always the main clone root and that clone's parent
is the real workspace root. In a worktree it returns an absolute
.../OperationsCenter/.git; in the main clone a bare ".git" — hence resolving it
relative to $repo_root and taking the realpath via cd.
Verified from both: the worktree now auto-discovers
PrivateManifest/dist/boundary_disclosure_artifact.json, and the main clone
resolves to the identical path it did before, so there is no behaviour change
anywhere the old code already worked. `bash -n` clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ProtocolWarden
added a commit
that referenced
this pull request
Aug 4, 2026
main already carries an equivalent workspace_root fix via #491, which bundled the same worktree discovery bug. Resolved in favour of main's version (git_common_dir/main_clone_root) — no reason to prefer my phrasing of an identical fix. What survives from this branch is the part main does NOT have: the custodian-multi candidate list still omits the main clone's venv, so a worktree push on a box whose only custodian-multi lives at <clone>/.venv/bin — no PATH entry, no sibling Custodian checkout, which is the fleet's layout — still fails "custodian-multi not found". Added main_clone_root/{.venv,.warehouse-venv} using main's variable name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 4, 2026
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.
Two fixes, both path/list assumptions that silently covered less than they claimed.
1.
ensure_executor_backends()covered two of three backendsscripts/operations-center.shreinstalls dropped executor sibling checkouts at every fleet launch, but it probedimport team_executor, dag_executorand looped overTeamExecutor DAGExecutor.critique_executor— imported as a library bybackends/critique_executor/adapter.py, backed by the sibling checkout../CritiqueExecutor— was in neither list. Auv syncor venv-recreate that dropped it was therefore not auto-repaired, so every critique-topology task failed at execute withNo module named 'critique_executor'until a human noticed. That is the exact failure mode this self-heal exists to prevent for the other two.The drift was structural: the probe and the install loop were two separate hardcoded lists inside one function, so widening one without the other was easy and silent. They are now a single
EXECUTOR_BACKENDSarray of<import name>:<sibling checkout dir>pairs, and both the probe's import statement and the install loop derive from it. Behaviour is otherwise unchanged — still all-or-nothing, and a missinguvor a missing checkout still degrades to a WARNING rather than aborting launch.Not sourced from Python, deliberately. The nearest real Python lists are
BackendName/EXECUTOR_LANE_NAMES(contracts/enums.py) and thebackends/factory.pyregistry, but neither carries the checkout-dir half of each pair, and it is not derivable (dag_executor→DAGExecutor, notDagExecutor). More fundamentally this self-heal has to run precisely when the venv is too broken to importoperations_center. Cross-reference comments now sit in bothscripts/operations-center.shandbackends/factory.py, each naming the other.2.
.hooks/pre-pushresolved the wrong workspace root inside a worktreeThe hook globs sibling checkouts for the boundary disclosure artifact using
workspace_root="$(cd "$repo_root/.." && pwd)". That assumes$repo_rootis the main clone. In a git worktree it is.../OperationsCenter/.claude/worktrees/<name>, soworkspace_rootbecame.../.claude/worktrees— a directory with no siblings. The glob matched nothing and every push from a worktree failed closed on a missingREPOGRAPH_BOUNDARY_ARTIFACT_FILEit had no way to find.Now derived from
git rev-parse --git-common-dir, which the main clone and all its worktrees share.Verification
Against the live stack (
~/GitHub/{TeamExecutor,DAGExecutor,CritiqueExecutor}):bash -nclean; the probe builds exactlyimport team_executor, dag_executor, critique_executor.uvpath installed all three (+ critique-executor==0.1.0 from file:///home/diane/GitHub/CritiqueExecutor), all three then imported, and a second call was a silent no-op. Fleet venv untouched.tests/unit/backends/test_factory.py+test_critique_executor_adapter.py: 5 passed.ruff check+ruff format --checkclean.Context: the gate was blocking every push
Getting here surfaced two faults outside this repo, both now fixed:
~/GitHub, so its own pre-push failed atB2before Custodian ran. PrivateManifest was not checked out there at all; it now is, and the artifact is generated from it.find_tool()preferred its own venv over the audited repo's, so a globally-installedcustodian-multiaudited OC (pinnedruff==0.15.13) with a system-wide ruff 0.16.1 and reported 1222 phantom findings against a clean tree. Fixed upstream in fix(adapters): find_tool must prefer the AUDITED repo's venv, not Custodian's Custodian#72.The OC baseline was never dirty.
🤖 Generated with Claude Code