Skip to content

Enforce exec director tool allowlists through tool_search and promote - #1010

Merged
TheGreatAxios merged 3 commits into
mainfrom
cl-6822-exec-director-tool-allowlist-is-advisory-tool_search-re
Sep 14, 2026
Merged

Enforce exec director tool allowlists through tool_search and promote#1010
TheGreatAxios merged 3 commits into
mainfrom
cl-6822-exec-director-tool-allowlist-is-advisory-tool_search-re

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary
Closed exec directors (explorer, critic) advertise only their package allow list, but tool_search stayed mounted and indexed the full live registry, and the promoter activated anything it returned — so a model could search up and call MCP, plugin, or proxy tools outside its allow list. This change filters the tool_search index by the overlay allow, unmounts tool_search when the overlay excludes it, and gates promoter activation through the same allow. Package deny entries are subtracted from the allow; a deny-only package is rejected loudly. Skywalker keeps the product default.

Verification

  • Red: new tests fail before the fix (tool_search returns an outside-allow MCP tool; the omitted tool_search is still mounted; promoter activates the outside-allow tool).
  • Green: targeted suites pass — src/exec/runner.test.ts, src/agent/tool-search.test.ts, src/agent/fleet-verbs-mount.test.ts (52 pass, 0 fail); directors plus session assembly (366 pass, 0 fail).
  • Lint passes; build passes. Typecheck reports only the pre-existing vendor semver error present at the base; the full suite has one worktree-environment failure (language-server presence check needs a local node_modules). No failures from this change.
  • Stacks with Wait briefly for connecting servers before answering an empty tool search #996, lands on main independently.

Fixes CL-6822

@linear-code

linear-code Bot commented Sep 13, 2026

Copy link
Copy Markdown

CL-6822

@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Critic · Approve

Closed exec directors (explorer, critic) can no longer search up or promote tools outside their package allow; skywalker keeps the product default.

Findings (all verified, none blocking)

  • src/agent/tool-search.ts:270 — index filter is the right layer: allow-undefined keeps the legacy default path, set allow closes the search hole under overlays. Temp-test verified exact-name queries (mcp__linear__create_issue) stay blocked while allowed names still surface; empty allow yields nothing without throwing.
  • src/agent/tools.ts:732 — mount gate correct: tool_search omitted unless the allow names it; undefined mounts as before. Committed default-mount/excluded-omit tests are the real regression pair.
  • src/exec/runner.ts:883 — promoter filters before activate, and the call gate (isAdvertised) refuses anything never advertised, so outside-allow names can neither activate nor dispatch. Committed promoter test covers the chain through computeAdvertised + createExecToolCallGate.
  • src/exec/runner.ts:291 — deny-without-allow throws loudly at overlay resolution (startup); deny otherwise subtracts. Read posture intact: explorer/critic still resolve to REVIEW_TOOLS-derived allows incl. read_file/run_shell, minus fleet verbs.

Should-fix (merge order, not this diff)

File-for-later

  • allow-minus-deny resolving to empty (e.g. allow ["run_shell"] + deny ["run_shell"]) locks out silently; only deny-without-allow throws. No real package hits it.

Verification (independent, worktree cl-6822-exec-director-tool-allowlist-is-advisory-tool_search-re @ 3d5b31d, after bun install)

  • bun run lint exit 0 (0 warnings/errors); bun run typecheck exit 0 — the reported vendor semver error was env-only, gone after install; bun run build exit 0; bun run test exit 0 — 7313 pass, 0 fail, 501 files; check:projects-dir-guard exit 0.
  • Targeted: tool-search + fleet-verbs-mount + exec/runner — 52 pass, 0 fail, plus 4 temp edge tests (exact-name block, empty allow, tool_search-in-allow, legacy default) all pass, temp files removed, worktree clean.

@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Critic nits addressed in 627c527 (not merging):

  • Promoter now owns the allow gate: createExecToolPromoter takes isAllowed and filters itself instead of relying on the call-site closure. Exec passes the overlay check; pinned by a test wiring activate raw so a future caller gets no bypass.
  • Allow-minus-deny collapsing to empty now throws at overlay resolution, matching the deny-without-allow loud behavior, instead of locking out silently. Test covers allow: [run_shell] + deny: [run_shell].

Kept: index filter, unmount posture, promoter gate, deny handling, skywalker/fleet unaffected, no #996 pending-wait changes.

Verification: bun run check exit 0 — lint, typecheck, build, 7315 pass / 0 fail across 501 files.

@TheGreatAxios
TheGreatAxios force-pushed the cl-6822-exec-director-tool-allowlist-is-advisory-tool_search-re branch from 627c527 to 9467d27 Compare September 14, 2026 00:49
@TheGreatAxios
TheGreatAxios changed the base branch from main to cl-7865-tool_search-answers-no-tools-matched-while-mcp-servers-are September 14, 2026 00:50
@TheGreatAxios
TheGreatAxios added this pull request to stack #1018 September 14, 2026 00:50
@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Stack-merge re-critique (d351214 + 9467d27): combined import, gated tool_search mount with awaitPendingConnections, index allow-filter, promoter isAllowed gate, and deny/empty-allow handling all intact. bun test src/agent/tool-search.test.ts + src/exec/runner.test.ts: 49 pass, 0 fail. Green — no new defects.

Base automatically changed from cl-7865-tool_search-answers-no-tools-matched-while-mcp-servers-are to main September 14, 2026 03:41
The promoter filtered outside-allow names only because its one call site pre-filtered in the activate closure; a second caller wiring activate raw would get no gate. The promoter now takes isAllowed and filters itself, with the exec call site passing the overlay check and the product-default test path passing allow-all.

An allow list that deny empties now throws at overlay resolution, matching the deny-without-allow behavior, instead of locking the director out silently.
@TheGreatAxios
TheGreatAxios force-pushed the cl-6822-exec-director-tool-allowlist-is-advisory-tool_search-re branch from 9467d27 to 3af2578 Compare September 14, 2026 04:01
@TheGreatAxios
TheGreatAxios merged commit 77838ef into main Sep 14, 2026
9 checks passed
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.

1 participant