Files
vitya 0accdccaac feat(using-interns): add grep_audit routing [v0.3.0]
Add 3 routing-table rows for the new deterministic `grep_audit` intern
per .wiki/concepts/interns-grep-audit-design.md §Layer 3:

  - grep_audit row — deterministic, no LLM call, zero cost
  - bulk_text_read vs grep_audit boundary — Q&A vs contains-check
  - always-ask uniform reminder — server opens file even sans LLM

Consistency adds: new Overview catalog row, Tool quick reference row,
prose note marking grep_audit as the catalog's first LLM-free intern.

Version 0.2.2 -> 0.3.0 (MINOR — new routing capability).

Closes [interns-grep-audit-skill-updates] on the .tasks board.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 08:02:57 +03:00

16 KiB
Raw Permalink Blame History

name: using-interns version: 0.3.0 description: Use when delegating predictable bulk reads or summarization to cheap intern LLMs via the local interns MCP server (mcp__interns__bulk_text_read, mcp__interns__transcript_distill, etc.) so Claude saves Anthropic quota. Activated by delegate to interns when allowed in CLAUDE.md or explicit phrases like "use interns", "delegate to an intern", "разреши интернов", "allow interns". Also activates proactively when Claude is about to read 3+ files for context, read a single file >400 lines for non-edit purposes, or distill a long transcript — surface the offer "знаю, что есть интерны — заюзать?" before proceeding, even without an explicit user phrase. Per-session permission grant mirrors project-discipline Rule 4: ask-mode default, conversational grant / revoke, always-ask paths for .env / secrets / keys / SSH / credentials even with active grant, transitive rule (Claude can't bypass by reading the file itself and forwarding content), session-end reset. Skip for architecture, debugging, auth / payments, final commit messages, or final user-facing text.

Using the interns MCP server

Overview

interns is a local stdio MCP server that exposes a catalog of cheap-LLM "interns" — DeepSeek, Kimi, Ollama-hosted models, etc. — so Claude can delegate predictable bulk I/O and summarization tasks instead of paying Anthropic quota for them. The pattern (~23× cheaper end-to-end on summarization, ~125× per-call on bulk reads) is sourced from a Reddit thread + Medium follow-up; see .wiki/concepts/interns-design.md for the full design and the cost numbers.

The catalog:

Tool What it does When to call
mcp__interns__bulk_text_read Reads N files end-to-end and answers a focused question with file:line citations. Claude was about to read 3+ files or one file > 400 lines just to extract context.
mcp__interns__transcript_distill Compresses a session transcript / log into a structured action list (decisions / open questions / next steps). Before updating .wiki/log.md or producing a session summary.
mcp__interns__repo_read Packs a directory/repo via repomix and answers a focused question about the codebase. Whole-repo or whole-directory questions — architecture, "where is X used", "what does module Y do". See Routing hints for repo_read vs bulk_text_read.
mcp__interns__grep_audit Deterministic grep matrix over N paths × M patterns. No LLM call, no endpoint cost. Returns //⚠️ table or JSON. Contains/not-contains audits — checking a set of CLAUDE.md / SKILL.md / frontmatter files for canonical strings. See Routing hints for grep_audit vs bulk_text_read.

LLM-backed interns currently run on Ollama Cloud (deepseek-v4-flash, ~$0.002 / call). grep_audit is the catalog's first LLM-free intern — zero cost, zero hallucination boundary. Adding a new intern is a config-only change — see .wiki/concepts/interns-design.md § "Как добавить нового интерна".

Prerequisites

This skill assumes mcp__interns__* tools are available. If they aren't (tools missing from the session, or calls fail with a connection error), the server isn't running for this session. Trigger the setup-interns skill to pip install -e the runtime, write ~/.config/projects-secrets/interns.env, and register mcpServers.interns in ~/.claude.json. It's a one-time procedure with confirmation gates.

When to use

  • A read that's bulky and not central to editing: scanning long config files, log dumps, transcript files, generated docs — anything where Claude would burn input tokens summarizing for itself.
  • A read across 3+ files to assemble context.
  • A read of one file > 400 lines that won't be edited.
  • Transcript / session distillation before writing a wiki log entry, summary, or post-mortem.
  • Any future intern documented in .common/config/interns/config.yaml (PDF extraction via Marker, repo packaging via Repomix, JS-rendered web fetches via Firecrawl, etc.) — same trigger / grant rules apply.

Offer proactively — don't wait to be asked

When any of the conditions above match a task you're about to perform, the offer is your first action, not a reaction to the user mentioning interns. The user shouldn't have to remember the catalog exists — that's your job.

  • Ask-mode (default) — surface a short offer in the user's language before proceeding:

    Знаю, что есть интерны — могу заюзать <intern> для <task>?

    English equivalent:

    Interns can handle this — want me to delegate <task> to <intern>?

    Keep it short. Don't pre-quote cost / model / tool name in the offer — those are in the catalog, the user can ask if curious. Verbose ask = friction = user defaults to "just do it yourself" even when delegation was the better move.

  • Grant active — skip the offer entirely. Delegate with a one-line FYI:

    Делегирую <intern> для <task> (<N> файлов / <N> строк).

  • Recognition heuristics for "I'm about to do an intern-shaped task": mid-task, before issuing N Reads in a batch, ask yourself: would this become 3+ Read calls? Is the file I'm about to open >400 lines and I won't edit it? Am I reading a transcript to summarize, not to navigate? Any yes → offer.

This is the change that actually delivers the savings — the catalog is useless if Claude only remembers it when prompted.

When NOT to use

  • Architecture / design decisions. Cheap models miss subtle trade-offs.
  • Debugging. Cheap models hallucinate in ways that turn a 5-minute fix into a 1-hour wild goose chase.
  • Auth / payments / PII / production data / deletion. Recommendation, not enforced — but obvious.
  • Final commit messages, PR descriptions, user-facing answers. The task explicitly delegated to Claude. Don't sub-delegate the deliverable.
  • Anything that fits into Claude's own working context cheaply. A 50-line file to skim is not a delegation candidate; it's just a Read.

Per-session permission grant (mirrors project-discipline Rule 4)

The grant mechanism is identical in shape to the push-grant in project-discipline. Reuse the same vocabulary so the user doesn't have to learn two policies.

Default — ask-mode

Every session starts in ask-mode. Before the first mcp__interns__* call, ask:

Я бы делегировал чтение <files> интерну bulk_text_read (DeepSeek Flash via Ollama Cloud, ~$0.002 за вызов). Ок?

(or its English equivalent if the user is communicating in English) and wait for explicit yes / да / go / поехали. Without confirmation — don't call.

Conversational grant

When the user says any of:

  • "разреши интернов" / "разреши интерна" / "разреши делегировать"
  • "allow interns" / "use interns freely" / "go ahead with interns"

— grant the right to call mcp__interns__* without further confirmation for the rest of the session, subject to always-ask paths below. Acknowledge the grant in one short line ("ок, делегирую интернам без подтверждения, кроме secrets-путей" / "got it, free delegation except secrets").

Conversational revoke

When the user says any of:

  • "отзови интернов" / "снова спрашивай" / "делай сам"
  • "revoke interns" / "stop using interns" / "ask me again every time"

— return to ask-mode for the rest of the session. Acknowledge in one short line.

Session-end reset

The next session starts in ask-mode regardless of prior grants. Same reasoning as project-discipline Rule 4: a grant is given for the current context (user nearby, attention available), and should not survive a context switch.

Always-ask paths (even with active grant)

These never go to an intern silently, even when delegation is granted:

  • **/.env, **/.env.*
  • **/secrets/**, **/projects-secrets/** (including ~/.config/projects-secrets/, ~/.config/projects-mcp/)
  • **/credentials*, **/credentials.json
  • **/*.key, **/*.pem
  • **/.ssh/**
  • **/.aws/credentials, **/.aws/config
  • **/.netrc, **/.npmrc, **/.pypirc

The interns MCP server enforces this server-side: matched paths return BlockedByPolicy{path, pattern, reason} instead of going out to the endpoint. Claude's job: don't try to bypass by reading the file with the local Read tool and forwarding the content as a string argument. The transitive rule applies — once a file matched, its content stays out of every intern call for the rest of the session unless the user explicitly grants per-path.

When a path is blocked, ask the user explicitly:

Файл <path> matched always-ask pattern <pattern> (reason: <reason>). Передавать интерну на endpoint <endpoint> несмотря на это?

Wait for an explicit per-path "yes". Don't generalize the answer to other paths in the same call.

Cost-based always-ask

Any call with estimated cost > $0.10 (per the tokens × price_per_M config in .common/config/interns/config.yaml) goes to ask-mode regardless of grant state. Sanity bound — catches a misrouted huge-payload request before it bills.

Routing hints (when to pick which intern)

Situation Intern
File > 400 lines, not editing it bulk_text_read
Need to read 3+ files for context bulk_text_read
Whole-repo or whole-directory question (architecture, "where is X used", "what does module Y do") repo_read
bulk_text_read vs repo_read Use bulk_text_read when file paths are known and explicit. Use repo_read when you need a whole directory without cherry-picking files — repomix packs everything under the given paths.
Don't delegate editing or debugging a specific file to repo_read Read the file yourself. repo_read is for comprehension, not modification.
Updating .wiki/log.md or session-summary doc transcript_distill
Compressing a long brainstorm transcript before quoting in a design doc transcript_distill
Audit N paths × M patterns (contains/not-contains matrix — checking CLAUDE.md / SKILL.md / frontmatter for canonical strings) grep_audit — deterministic, no LLM call, zero cost, zero hallucination boundary
bulk_text_read vs grep_audit bulk_text_read is Q&A with an LLM over files; grep_audit is deterministic contains/not-contains. Semantic match (paraphrase, intent) → bulk_text_read with a question, not grep_audit.
Always-ask paths apply uniformly to grep_audit The server still opens the file even without an LLM call — no special "safe intern" carve-out. Same .env / secrets / keys / SSH gate as the LLM-backed interns.
(Future interns in config.yaml) per the description in the catalog

Workflow

1. Identify the candidate task (read-heavy, bulk, predictable).
2. Pick the intern from the routing table.
3. Check grant state:
     • ask-mode → ask before calling
     • granted   → check always-ask paths; if any matched, ask per-path
4. Call the intern with `paths` (list of file paths — the server reads them)
   and `question` (focused, specific).
5. Cite the response (file:line refs come from the intern's reply).

Don't pass file contents as arguments — only paths. The MCP server reads and applies the always-ask matcher before any path content reaches an endpoint. If you forward content yourself, the gate is bypassed and the user can't trust the policy.

Tool quick reference

Tool Required args Optional Purpose
mcp__interns__bulk_text_read paths: list[str], question: str max_tokens: int Read N files end-to-end, answer the question with citations.
mcp__interns__repo_read paths: list[str], question: str compress: bool, max_tokens: int Pack directory/repo via repomix, answer the question. Use compress=True for large codebases (lossy: strips comments/whitespace).
mcp__interns__transcript_distill paths: list[str], question: str max_tokens: int Distill transcript / log into structured action list.
mcp__interns__grep_audit paths: list[str], patterns: list[str | dict] output: "table" | "json" (default "table"), case_sensitive: bool (default True) Deterministic grep matrix over N paths × M patterns. No LLM call. Returns //⚠️ table or JSON. patterns are substring by default; pass {pattern, name, regex: true} for named regex columns.

(Future interns expose tools at mcp__interns__<intern_id> as the catalog grows.)

Examples

Read-bulk delegation

User: "summarize what these four config files do for the build pipeline."

1. Routing → bulk_text_read (4 files, context only).
2. Grant state → ask-mode (session start).
3. Ask: "Bulk-read these 4 files via bulk_text_read (~$0.002)? Ок?"
4. User: "ok"
5. Call mcp__interns__bulk_text_read
   paths: ["build/config.ts", "build/plugins.ts", "build/env.ts", "build/output.ts"]
   question: "What does each file contribute to the build pipeline? Cite file:line."
6. Cite the response. Done.

Always-ask path triggered

User: "scan all .env* files in the repo and tell me which keys are duplicated."

1. Routing → bulk_text_read.
2. Grant state → granted (user said "allow interns" earlier).
3. Path matcher → every input matches `**/.env`. Server returns BlockedByPolicy.
4. Ask user: "These are .env files (always-ask). Pass them to bulk_text_read despite the secrets exposure?"
5. Wait for explicit per-path yes/no.

Transcript distill

User: "compress this brainstorm transcript into action items before I ingest it into the wiki."

1. Routing → transcript_distill.
2. Call mcp__interns__transcript_distill
   paths: [".meeting-room/.brainstorm/foo.md"]
   question: "Extract decisions, open questions, and next steps. Output structured markdown."
3. Quote the result in the wiki ingest commit.

Common mistakes

Mistake Fix
Calling an intern in ask-mode without asking first Ask before the first call every session, even for trivial reads.
Forwarding file content instead of path Pass paths. The server reads. The matcher only sees paths.
Trying to bypass always-ask by reading the file with Read and pasting content Transitive rule — that path stays out of intern calls for the session unless user says otherwise per-path.
Sub-delegating final deliverables (commit messages, user-facing answers) Those are Claude's job. Interns are for predictable bulk I/O, not for the answer that ships.
Using an intern for debugging Cheap models miss subtle bugs. Pay the Anthropic call for debugging — the savings aren't worth a wrong fix.
Persistent grant across sessions The next session resets to ask-mode. By design — same as project-discipline Rule 4.

Red flags

  • "I'll just paste the content as a string arg" → no. The matcher only sees paths. If you're tempted to bypass it, you're about to leak a secret.
  • "This grant should survive the session" → no. The next session asks again. The grant is bound to the current context where the user is paying attention.
  • "It's just a small file, why ask?" → small files don't need an intern. Read them yourself. The ask is because the call goes to a third-party endpoint, not because of size.
  • "Estimated cost is fine, $0.08 < $0.10" → still ask if the call is novel or the file set is unfamiliar. The cost gate is a hard ceiling, not the only signal.