Skip to content

debugging: probe disallowed-tools MCP pattern and large-heap converter #7593

Closed

Description

@kyle-sexton

Parent

Refs #7580 (Tool per job). Source: PLAN Phase 1, topic poteto-review.

Depends on

  • none: on the frontier now

Outcome

Two recorded observations that gate the tool-per-job setting slice: whether a skill's
disallowed-tools entry naming an MCP server-wide pattern denies that server's tools, and how long
analyze-profile's SQLite converter takes, and how much memory it peaks at, on a heap near its 512 MiB
cap.

Decisions

  • Q561 (owner: follow Lauren or better): one named tool per job; the skill names the command, checks
    it resolves and stops if missing. Origin: Lauren's (Playwright plus CDP; SQLite dump and diff).
  • The converter must handle a large heap before CI use is promised (Q561 research tag).
  • No product code; probe artifacts stay out of tracked plugin files.

Key interfaces

Variation verdicts: "Browser driver and profiling tools: abstract now; tool-per-job setting read
through the adapter; one named tool, no MCP handoff (Q561, Q569)."

Done when

  • A Probe result: comment records the throwaway skill's disallowed-tools pattern, whether the
    server's tools were denied, and a control (a tool outside the pattern stays allowed), with the
    Claude Code version and date.
  • A Probe result: comment records the converter's run on a heap near 512 MiB: input size, wall
    time, peak memory, command, date.
  • git status --porcelain plugins/ is empty after the probe.

Out of scope

  • Changing the converter or any skill; the setting slice acts on the result.

Activity

  1. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 16, 2026
  2. added theissue type on Oct 16, 2026
  3. github-actions commented on Oct 16, 2026

    @github-actions
    Contributor

    Thanks for the report. Automated triage handed this issue to a maintainer.

    Proposed work class: work-class: read-only
    Basis: automated intake triage; a maintainer confirms or changes it.

    Automated triage. A maintainer reviews it.

  4. kyle-sexton commented on Oct 16, 2026

    @kyle-sexton
    MemberAuthor

    Probe result: a skill's disallowed-tools entry naming an MCP server-wide pattern removes that server's tools. A tool from another server stays allowed.

    • Claude Code 2.1.301, 2026-10-16, headless claude -p --plugin-dir <throwaway plugin> --output-format stream-json --verbose --model sonnet.
    • Docs read: Skills: frontmatter reference says disallowed-tools removes the listed tools from Claude's pool while the skill is active, and the restriction clears on the next message. Permissions: MCP says mcp__<server> and mcp__<server>__* both match every tool from that server. The skills page does not say that disallowed-tools accepts this rule syntax. This probe checks that.
    • Server under test: context7, which is user-scoped and showed connected in every run. Control tool: mcp__ref__ref_search_documentation.
    • All three runs passed the same --allowedTools covering both tools and ToolSearch. Each prompt asked for one mcp__context7__resolve-library-id call and one ref call.
    Run Skill disallowed-tools context7 tools in init tool list context7 call ref call (control)
    Baseline (no skill) none both present ran, returned results ran
    block-star mcp__context7__* none not attempted: ToolSearch select: returned only the ref tool ran
    block-bare mcp__context7 none denied: <tool_use_error>Error: No such tool available: mcp__context7__resolve-library-id</tool_use_error> ran

    permission_denials was empty in every run. The tools were removed from the pool, so no permission rule was involved. The model was told the context7 server had "disconnected", but the init event still showed the server connected.

    Caveat: stream-json does not echo the slash-command expansion. The evidence that the skill took effect is the difference between runs: the only change from the baseline is the /probe7593:block-* prefix, and only those runs lose the context7 tools.

    Probe artifacts stay untracked under .work/poteto-review/probes/7593/: the plugin, the three run-*.jsonl streams and summarize.jq. git status --porcelain plugins/ is empty.

  5. kyle-sexton commented on Oct 16, 2026

    @kyle-sexton
    MemberAuthor

    Probe result: analyze-profile's trace_to_sqlite.py converted a 510.9 MiB heap snapshot (cap: 512 MiB) in 59 s wall time with a peak RSS of 3.73 GiB.

    • Date: 2026-10-16. Host: WSL2 Linux, 24 CPUs, 39 GiB RAM, Python 3.14.8, Node v24.21.0.

    • Input: a V8 .heapsnapshot written by v8.writeHeapSnapshot() after allocating 2,000,000 linked objects. Size: 535,749,748 bytes (510.9 MiB). The converter's MAX_INPUT_BYTES is 536,870,912.

    • Command, with paths relative to the repo root:

      /usr/bin/time -v python3 plugins/debugging/skills/analyze-profile/scripts/trace_to_sqlite.py \
        --in .work/poteto-review/probes/7593/big.heapsnapshot \
        --out .work/poteto-review/probes/7593/big.sqlite
    • Result: exit 0, {"format": "heapsnapshot", "tables": {"nodes": 8057330, "edges": 22246947, ...}}. The SQLite output was 1,292,222,464 bytes (1.2 GiB).

    • /usr/bin/time -v: elapsed 0:59.10, user 54.10 s, system 4.69 s, maximum resident set size 3,911,012 kB (3.73 GiB, about 7.3x the input size).

    The peak memory comes from read_json, which reads the whole file into memory and then calls json.loads, so the full Python object graph is in memory at once. A CI runner needs about 4 GiB free for a heap at the cap.

    The heap and SQLite files were deleted after the run. git status --porcelain plugins/ is empty.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.needs-specNeeds a Brief or plan before anyone can build it.

    Type

    Fields

    Work status

    needs-spec

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions