feat(interns-skills-mvp): ship setup-interns + using-interns v0.1.0; project-bootstrap 1.5.0 -> 1.6.0

setup-interns (v0.1.0) — 8-phase install of the local `interns` MCP server:
detect `.common/lib/interns-mcp/` source, `pip install -e`, write
`.common/secrets/interns.env` with endpoint API keys (gitignored), register
`mcpServers.interns` in `~/.claude.json` with absolute Python interpreter
path + `cwd` so the runtime resolves config relative to project root.
Mirrors setup-projects-meta / setup-context7 confirmation-gate shape.
Description 899 chars (under the 900 budget per
feedback_skill_description_length_limit).

using-interns (v0.1.0) — runtime policy for `mcp__interns__*`. Per-session
permission grant mirrors project-discipline Rule 4: ask-mode default,
conversational grant ("разреши интернов" / "allow interns"), conversational
revoke, always-ask paths for `**/.env`, `**/secrets/**`, `**/*.key`,
`**/.ssh/**`, `**/.aws/credentials` etc with transitive rule (Claude can't
bypass by reading the file with the local Read tool and forwarding content),
cost-cap >$0.10 always asks, session-end automatic reset. Routing hints for
`bulk_text_read` (3+ files or one file >400 lines) and `transcript_distill`
(before .wiki/log.md updates / session summaries). Description 814 chars.

project-bootstrap (1.5.0 -> 1.6.0, MINOR — capability added):
* assets/CLAUDE.md.template: insert `delegate to interns when allowed`
  between `follow project discipline` and `we're on Windows`.
* SKILL.md Step 5: same insertion in inline template + new commentary
  paragraph explaining the trigger, no-op semantics, install pointer.
* SKILL.md Step 5.5: bootstrap-manifest table extended with
  `setup-interns`, `using-interns`, `project-discipline` rows.
* README.md: Workflow Step 5.5 description + See also section both pick up
  the new skills.

Root CLAUDE.md dogfood: `delegate to interns when allowed` line added.
.wiki/log.md decision entry. .tasks/STATUS.md task moved to 🟢 done.
.tasks/interns-skills-mvp.md per-task file with goal / key-files /
decisions log / open questions.

Build + install verified: `dist/{setup-interns,using-interns,
project-bootstrap}.skill` rebuilt; `bash scripts/install.sh ...` succeeded;
harness skill listing shows full descriptions for all three (no H1
fallback) — confirms the description budget held.

Versioning per project-discipline Rule 3:
* setup-interns: 0.1.0 (first edit of unversioned artifact, MAJOR=0).
* using-interns: 0.1.0 (first edit of unversioned artifact, MAJOR=0).
* project-bootstrap: 1.5.0 -> 1.6.0 (MINOR — adds capability without
  breaking existing CLAUDE.md merge or manifest consumers).

Server runtime itself (`.common/lib/interns-mcp/`) is out of scope for this
task — the skills land lifecycle, policy, and bootstrap integration so any
machine where the MCP server is later installed already has Claude's
policy in place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 17:41:11 +03:00
parent 7464ae4bc4
commit 0eb7dd1d7c
14 changed files with 632 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
# Task Board # Task Board
_Updated: 2026-05-01_ _Updated: 2026-05-05_
## 🟢 [shared-wiki-skill-catalog] — публикация каталога claude-skills в shared projects-wiki ## 🟢 [shared-wiki-skill-catalog] — публикация каталога claude-skills в shared projects-wiki
**Status:** done **Status:** done
@@ -164,12 +164,12 @@ _Updated: 2026-05-01_
--- ---
## [interns-skills-mvp] — Ship `setup-interns` + `using-interns` skills (v0.1.0) and bump `project-bootstrap` 1.5.0 → 1.6.0 with `delegate to interns when allowed` CLAUDE.md trigger, manifest entry, Step 5 commentary paragraph, idempotent merge into existing CLAUDE.md files. Two-skill pair following the setup-X / using-X prior art (setup-context7/using-context7, setup-projects-meta/using-projects-meta). Per-session permission grant policy mirroring project-discipline Rule 4 (ask-mode default, conversational grant/revoke, always-ask paths for secrets even with active grant, session-end reset). ## 🟢 [interns-skills-mvp] — Ship `setup-interns` + `using-interns` skills (v0.1.0) and bump `project-bootstrap` 1.5.0 → 1.6.0 with `delegate to interns when allowed` CLAUDE.md trigger, manifest entry, Step 5 commentary paragraph, idempotent merge into existing CLAUDE.md files. Two-skill pair following the setup-X / using-X prior art (setup-context7/using-context7, setup-projects-meta/using-projects-meta). Per-session permission grant policy mirroring project-discipline Rule 4 (ask-mode default, conversational grant/revoke, always-ask paths for secrets even with active grant, session-end reset).
**Status:** ready **Status:** done
**Where I stopped:** (not started) **Where I stopped:** `skills/setup-interns/` v0.1.0 shipped (8-phase install: detect `.common/lib/interns-mcp/` source, `pip install -e`, write `.common/secrets/interns.env` with endpoint API keys + ensure `.gitignore` covers it, register `mcpServers.interns` in `~/.claude.json` with absolute Python interpreter path + `cwd` to project root); `skills/using-interns/` v0.1.0 shipped (runtime policy mirroring project-discipline Rule 4: ask-mode default, conversational grant/revoke, always-ask paths for `.env` / `**/secrets/**` / `**/*.key` / `**/.ssh/**` / `**/.aws/credentials` etc with transitive rule + cost-cap >$0.10, session-end reset; routing hints for `bulk_text_read` + `transcript_distill`); `project-bootstrap` 1.5.0→1.6.0 with canonical CLAUDE.md trigger `delegate to interns when allowed` inserted between `follow project discipline` and `we're on Windows`, new Step 5 commentary paragraph, Step 5.5 manifest table extended with `setup-interns` + `using-interns` + `project-discipline` rows; root `CLAUDE.md` dogfood line added; both READMEs written; descriptions verified within budget (setup-interns 899 / using-interns 814 / ≤900); both archives rebuilt + installed; harness listing confirms full descriptions (no H1 fallback) for all three skills
**Next action:** Read design at `claude-skills/.wiki/concepts/interns-design.md` (just ingested) — Layer 3 section. Scaffold `skills/setup-interns/SKILL.md` and `skills/using-interns/SKILL.md` following setup-context7 / using-context7 structure. Then patch `skills/project-bootstrap/SKILL.md` Step 5 + `assets/CLAUDE.md.template` + `bootstrap-manifest.md`, bump to 1.6.0. **Next action:** (none — kept until merged)
**Branch:** n/a **Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-05T13:59:07.540Z --> <!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-05T13:59:07.540Z -->
--- ---

View File

@@ -0,0 +1,38 @@
# interns-skills-mvp
## Goal
Ship the first version of the `setup-interns` + `using-interns` skill pair (v0.1.0 each) and roll the canonical `delegate to interns when allowed` CLAUDE.md trigger into `project-bootstrap` (1.5.0 → 1.6.0). The pair exposes the local `interns` MCP server (Layer 2 of `.wiki/concepts/interns-design.md`) to Claude Code under a per-session permission grant that mirrors `project-discipline` Rule 4 — ask-mode by default, conversational grant/revoke, always-ask paths for secrets even with an active grant, session-end reset. The runtime server itself is out of scope for this task; the skills land their full lifecycle (install procedure, runtime policy, bootstrap integration) so that on every machine where the MCP server is later installed, Claude already knows the policy.
## Key files
- `.wiki/concepts/interns-design.md` — Layer 3 Skills section is the primary spec
- `skills/setup-interns/SKILL.md` — to be created (mirror `skills/setup-projects-meta/SKILL.md` 8-phase shape)
- `skills/setup-interns/README.md` — to be created (mirror `skills/setup-projects-meta/README.md`)
- `skills/using-interns/SKILL.md` — to be created (mirror `skills/using-projects-meta/SKILL.md` two-class shape; grant mechanism mirrors `skills/project-discipline/SKILL.md` Rule 4)
- `skills/using-interns/README.md` — to be created
- `skills/project-bootstrap/SKILL.md` — Step 5 commentary + Step 5.5 manifest table; bump `version:` 1.5.0 → 1.6.0
- `skills/project-bootstrap/assets/CLAUDE.md.template` — append `delegate to interns when allowed` between `follow project discipline` and `we're on Windows`
- `CLAUDE.md` (root, dogfood) — same line addition
- `.wiki/log.md``## [2026-05-05] decision | interns-skills-mvp shipped` entry
- `dist/setup-interns.skill`, `dist/using-interns.skill`, `dist/project-bootstrap.skill` — rebuilt archives
## Decisions log
- 2026-05-05: ship as a pair (setup-X + using-X) following the validated prior-art pattern — same shape as setup-context7/using-context7 and setup-projects-meta/using-projects-meta. Rationale: clean separation of one-time install (mutates user-level config; needs confirmation gates) from runtime policy (read every session; no mutations). Cross-reference between the two via the `Prerequisites` section.
- 2026-05-05: setup-interns assumes inline `.common/lib/interns-mcp/` layout per design's "current склонение". Open question (Gitea repo + subtree) deferred — v0.1.0 documents the inline path; if a separate repo lands later, a 0.2.0 minor adds the alternate clone branch.
- 2026-05-05: grant mechanism mirrors project-discipline Rule 4 verbatim — ask-mode default per session, conversational grant ("разреши интернов" / "allow interns"), conversational revoke, always-ask paths even under an active grant, session-end automatic reset. Rationale: same security posture, same UX vocabulary the user already trained on.
- 2026-05-05: always-ask path list copied from design Layer 3 verbatim plus the transitive rule (Claude reading a matched file and forwarding content also triggers the gate). Plus cost-based ask: any call with estimated cost > $0.10 (sanity bound).
- 2026-05-05: `description:` budget — keep ≤ 900 chars per `feedback_skill_description_length_limit` memory. Verify char count before shipping; if over, trim trigger phrases first, never the policy summary.
## Open questions
- [ ] How does the user's actual `.common/` layout look on disk? Setup skill currently assumes `<project-root>/.common/lib/interns-mcp/` and `<project-root>/.common/secrets/interns.env`. If the convention is `~/projects/.common/`, the discovery phase needs to widen.
- [ ] Should `setup-interns` ship a scaffolding sub-step that writes a placeholder `.common/lib/interns-mcp/` from a template if the source isn't there? Probably not — kicks the can to a separate "build the runtime" task.
## Completed steps
- [x] Read design `.wiki/concepts/interns-design.md` Layer 3 section
- [x] Survey prior art: setup-context7, setup-projects-meta, using-context7, using-projects-meta, project-bootstrap@1.5.0, project-discipline (Rule 4 grant mechanism)
- [x] Mark 🔴 active in `.tasks/STATUS.md`, create this file
## Notes
- Char-count check after writing each `description:` — paste into a quick `wc -c` PowerShell snippet (or count manually). 1024 is the hard ceiling, 900 is the safety margin.
- Restart-Claude-Code caveat goes in setup-interns Phase 8, identical to setup-projects-meta and setup-context7.
- `using-interns` does NOT mention restart — it's a policy skill, no MCP install side.
- Bootstrap-manifest table gets `setup-interns` and `using-interns` rows.

View File

@@ -42,3 +42,4 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`.
## [2026-05-01] ingest | shared-wiki packages/claude-skills — каталог всех 20 скиллов опубликован в projects-wiki (3 commits: page + index + log on Gitea, ae2cc9a..001cdd0); группировка bootstrap / wiki+tasks / MCP / caveman / discovery+platform; cross-link с concepts/setup-using-skill-pair и packages/projects-meta-mcp ## [2026-05-01] ingest | shared-wiki packages/claude-skills — каталог всех 20 скиллов опубликован в projects-wiki (3 commits: page + index + log on Gitea, ae2cc9a..001cdd0); группировка bootstrap / wiki+tasks / MCP / caveman / discovery+platform; cross-link с concepts/setup-using-skill-pair и packages/projects-meta-mcp
## [2026-05-05] ingest | concepts/interns-design ## [2026-05-05] ingest | concepts/interns-design
## [2026-05-05] decision | interns-skills-mvp — shipped `setup-interns` v0.1.0 (8-phase install: detect `.common/lib/interns-mcp/`, `pip install -e`, `.common/secrets/interns.env` write, `mcpServers.interns` registration with absolute Python interpreter + `cwd`) and `using-interns` v0.1.0 (runtime policy mirroring project-discipline Rule 4: ask-mode default, conversational grant/revoke, always-ask paths for `.env`/secrets/keys/SSH/credentials with transitive rule, cost-cap >$0.10, session-end reset; routing hints for `bulk_text_read` + `transcript_distill`); `project-bootstrap` 1.5.0→1.6.0 with canonical CLAUDE.md trigger `delegate to interns when allowed` between `follow project discipline` and `we're on Windows`, Step 5 commentary paragraph, manifest table extended with both new skills + `project-discipline` row; root `CLAUDE.md` dogfood updated; both READMEs written; descriptions verified (setup-interns 899 chars, using-interns 814 chars, both under 900 budget); all three rebuilt + installed + listed by harness with full descriptions (no H1 fallback)

View File

@@ -8,4 +8,5 @@ use task management system
check across all projects check across all projects
pull remote before work pull remote before work
follow project discipline follow project discipline
delegate to interns when allowed
we're on Windows we're on Windows

Binary file not shown.

BIN
dist/setup-interns.skill vendored Normal file

Binary file not shown.

BIN
dist/using-interns.skill vendored Normal file

Binary file not shown.

View File

@@ -57,7 +57,8 @@ projects bootstrapped at different times debuggable.
3. **Steps 15.** Create or skip each piece in order — git, README, `.wiki/`, 3. **Steps 15.** Create or skip each piece in order — git, README, `.wiki/`,
`.tasks/`, `CLAUDE.md`. Steps 3 and 4 delegate to the setup-skills. `.tasks/`, `CLAUDE.md`. Steps 3 and 4 delegate to the setup-skills.
4. **Step 5.5.** Write `bootstrap-manifest.md` recording the versions of 4. **Step 5.5.** Write `bootstrap-manifest.md` recording the versions of
`project-bootstrap`, `setup-wiki`, and `setup-tasks` used. `project-bootstrap`, `setup-wiki`, `setup-tasks`, `project-discipline`,
`setup-interns`, and `using-interns` used.
5. **Step 5.6.** Detect the official `superpowers@claude-plugins-official` 5. **Step 5.6.** Detect the official `superpowers@claude-plugins-official`
plugin via `~/.claude/plugins/installed_plugins.json`. If absent, print plugin via `~/.claude/plugins/installed_plugins.json`. If absent, print
a one-time chat recommendation with the install command and upstream a one-time chat recommendation with the install command and upstream
@@ -104,5 +105,10 @@ target with `CLAUDE_SKILLS_DIR=/path bash scripts/install.sh …`.
- [`setup-tasks`](../setup-tasks/) — companion, owns `.tasks/` layout. - [`setup-tasks`](../setup-tasks/) — companion, owns `.tasks/` layout.
- [`using-wiki`](../using-wiki/) — runtime policy for working with `.wiki/`. - [`using-wiki`](../using-wiki/) — runtime policy for working with `.wiki/`.
- [`using-tasks`](../using-tasks/) — runtime policy for working with `.tasks/`. - [`using-tasks`](../using-tasks/) — runtime policy for working with `.tasks/`.
- [`project-discipline`](../project-discipline/) — cross-project rules
activated by the `follow project discipline` trigger.
- [`setup-interns`](../setup-interns/), [`using-interns`](../using-interns/) —
pair behind the `delegate to interns when allowed` trigger; cheap-LLM
delegation under a per-session permission grant.
- Karpathy's LLM Wiki gist: - Karpathy's LLM Wiki gist:
<https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f> <https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f>

View File

@@ -1,6 +1,6 @@
--- ---
name: project-bootstrap name: project-bootstrap
version: 1.5.0 version: 1.6.0
description: > description: >
Initializes or upgrades a project in the current folder: git, .gitignore, README.md, Initializes or upgrades a project in the current folder: git, .gitignore, README.md,
.wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers. .wiki/ using Karpathy's method, .tasks/ for task tracking, CLAUDE.md with skill triggers.
@@ -265,6 +265,7 @@ use task management system
check across all projects check across all projects
pull remote before work pull remote before work
follow project discipline follow project discipline
delegate to interns when allowed
we're on Windows we're on Windows
``` ```
@@ -291,6 +292,19 @@ push only after explicit per-session approval. Install the skill on the host
if `project-discipline` is not in `~/.claude/skills/`; otherwise the trigger is if `project-discipline` is not in `~/.claude/skills/`; otherwise the trigger is
silently dead like any other absent skill. silently dead like any other absent skill.
The `delegate to interns when allowed` line activates the `using-interns` skill,
which lets Claude offload predictable bulk I/O and summarization tasks
(reading 3+ files, distilling long transcripts) to cheap intern LLMs via the
local `interns` MCP server (`mcp__interns__bulk_text_read`,
`mcp__interns__transcript_distill`, etc.) — saves Anthropic quota at ~125× the
per-call cost reduction on bulk reads. 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 an
active grant, session-end reset. The skill is a no-op until the `interns` MCP
server is registered — install via `setup-interns` on a fresh machine if
`mcp__interns__*` tools are missing. Full design at
`.wiki/concepts/interns-design.md` in the `claude-skills` repo.
The `we're on Windows` line activates the `active-platform` skill and pins the The `we're on Windows` line activates the `active-platform` skill and pins the
project's default platform to Windows / PowerShell — so generated commands and project's default platform to Windows / PowerShell — so generated commands and
README quick-starts use PS-native syntax. Bootstrapping on a Linux or macOS README quick-starts use PS-native syntax. Bootstrapping on a Linux or macOS
@@ -322,6 +336,8 @@ Skills used to initialize this project's `.wiki/` and `.tasks/` layout, with the
| `setup-wiki` | <version> | wiki canonical layout | | `setup-wiki` | <version> | wiki canonical layout |
| `setup-tasks` | <version> | tasks canonical layout | | `setup-tasks` | <version> | tasks canonical layout |
| `project-discipline` | <version> | cross-project policy | | `project-discipline` | <version> | cross-project policy |
| `setup-interns` | <version> | interns MCP server install (one-time, per machine) |
| `using-interns` | <version> | interns runtime policy + per-session permission grant |
This file is overwritten if `project-bootstrap` is re-run on the same project. For history, use `git log .wiki/concepts/bootstrap-manifest.md`. This file is overwritten if `project-bootstrap` is re-run on the same project. For history, use `git log .wiki/concepts/bootstrap-manifest.md`.
``` ```

View File

@@ -8,4 +8,5 @@ use task management system
check across all projects check across all projects
pull remote before work pull remote before work
follow project discipline follow project discipline
delegate to interns when allowed
we're on Windows we're on Windows

View File

@@ -0,0 +1,74 @@
# setup-interns
One-time skill that brings up the local `interns` MCP server on a new (or freshly broken) machine. Detects the runtime source at `<project-root>/.common/lib/interns-mcp/`, runs `pip install -e`, writes `.common/secrets/interns.env` with the endpoint API keys, and registers `mcpServers.interns` in `~/.claude.json`.
The runtime policy for *using* the resulting tools lives in [`using-interns`](../using-interns/) — `setup-interns` is the only place that touches user-level config or the project's secrets directory.
Full design (Layer 1 / 2 / 3, MVP catalog, always-ask paths, routing hints):
`.wiki/concepts/interns-design.md` (in this repo).
## When it triggers
- User says: "install interns", "set up interns", "configure interns",
"настрой интернов", "установи интернов", "interns не работает",
"interns isn't working".
- [`using-interns`](../using-interns/) detects missing `mcp__interns__*` tools and delegates here via its Prerequisites section.
- A new machine in the multi-machine fleet — install once per machine that wants delegation.
## What it touches
| Path | Role |
|---|---|
| `<project-root>/.common/lib/interns-mcp/` | server source (must already exist; not created here) |
| `<project-root>/.common/config/interns/config.yaml` | catalog of interns + endpoints (read-only here) |
| `<project-root>/.common/secrets/interns.env` | endpoint API keys (gitignored) |
| `~/.claude.json` (`mcpServers.interns`) | MCP registration |
| `pip` site-packages | editable install of `interns_mcp` |
## Hard rules
- **Never auto-mutate.** Phase 1 (discovery) and Phase 2 (plan) always pause for explicit confirmation. A trigger phrase grants permission to inspect, not to run `pip install` or write secrets.
- **Never echo endpoint API keys in chat.** Edit / Write tool calls inevitably contain them (that's how they land in `.env`); chat output must not.
- **Never run on absent source.** If `.common/lib/interns-mcp/pyproject.toml` is missing, stop and tell the user — initializing a fresh runtime is a separate task.
- **Always `chmod 600` `.env` on Linux / macOS.** Token leak otherwise.
- **Pin the absolute Python interpreter path** in `mcpServers.interns.command`. A bare `python` resolves to whatever shadows it on `PATH` at session start.
## Procedure (high-level)
1. **Phase 0** — environment sanity (`python` ≥ 3.11, `pip`, network to endpoints).
2. **Phase 1** — discovery (source / module / config / keys / MCP registration / `.gitignore`).
3. **Phase 2** — plan + confirm. Wait for explicit "ok" / "go" / "поехали".
4. **Phase 3** — backup (`~/.claude.json`, existing `.common/secrets/interns.env`).
5. **Phase 4**`pip install -e .common/lib/interns-mcp/`.
6. **Phase 5** — write `.common/secrets/interns.env` (per-key, missing-only) + ensure `.gitignore` rule.
7. **Phase 6** — register `mcpServers.interns` in `~/.claude.json` with absolute interpreter path + `cwd`.
8. **Phase 7** — best-effort smoke test (in-session caveat: real verification is after restart).
9. **Phase 8** — restart guidance + final report.
Full procedure with shell snippets and templates lives in [`SKILL.md`](SKILL.md).
## Rollback
1. Stop. Don't fix forward.
2. `cp <file>.bak-<ts> <file>` for `~/.claude.json` and `.common/secrets/interns.env`.
3. Optional: `pip uninstall interns-mcp` to undo the editable install.
4. Restart Claude Code.
5. Confirm `mcp__interns__*` tools are gone (or back to the prior version).
## Install
From the repo root:
```bash
bash scripts/install.sh setup-interns
```
Works on Windows under git-bash, Linux, macOS.
## See also
- [`using-interns`](../using-interns/) — runtime policy + per-session permission grant for the `mcp__interns__*` tools.
- [`setup-projects-meta`](../setup-projects-meta/) — companion pattern, similar 8-phase shape.
- [`setup-context7`](../setup-context7/) — sister setup-skill for the context7 MCP plugin.
- [`project-discipline`](../project-discipline/) — Rule 4 (per-session push grant) is the prior art for the grant mechanism in `using-interns`.
- `.wiki/concepts/interns-design.md` — full architecture spec.

View File

@@ -0,0 +1,228 @@
---
name: setup-interns
version: 0.1.0
description: Installs and configures the local `interns` MCP server — a FastMCP stdio app at `<project-root>/.common/lib/interns-mcp/` that delegates bulk reads, transcript distillation, and other predictable I/O to cheap intern LLMs (DeepSeek / Kimi / Ollama) so Claude saves Anthropic quota. Procedure: detect the server source, `pip install -e` it, write `.common/secrets/interns.env` with the endpoint API keys, register `mcpServers.interns` in `~/.claude.json`. Use this skill when the user says "install interns", "set up interns", "configure interns", "настрой интернов", "установи интернов", "interns не работает", "interns isn't working", or whenever the `mcp__interns__*` tools are missing in a session that needs delegation. Cross-platform — Windows / Linux / macOS. Mutates user-level config and writes secrets; pauses for confirmation before every write.
---
# setup-interns
> One-time skill that gets the local `interns` MCP server running with the user's endpoint API keys and a registered `mcpServers.interns` entry in `~/.claude.json`. Stops at confirmation gates because the procedure runs `pip install`, writes a secret-bearing `.env` file, and edits user-level config.
Reference: full design lives in this repo at `.wiki/concepts/interns-design.md` (Layer 1/2/3 architecture, MVP catalog, always-ask paths, routing hints).
## When to use
- User explicitly asks: install / set up / configure interns.
- A `using-interns`-driven task fails because `mcp__interns__*` tools aren't available in the session.
- New machine in the user's multi-machine fleet — install once per machine that wants delegation.
- Migrating a stale install (endpoint key rotated, server source moved, broken `dist/` artifact) — same procedure, Phase 1 detects what's already in place.
## Out of scope
- Building or scaffolding the `.common/lib/interns-mcp/` source tree itself. The skill expects the source already in place per the inline `.common/` convention from the design (or a future Gitea repo when that branch lands). If the source is absent, Phase 1 stops with a clear message — initializing a fresh runtime is a separate task.
- Issuing or rotating endpoint API keys (Ollama Cloud, OpenRouter, etc.). The skill *uses* keys the user already has; if there is none, it points at the provider's settings page and stops.
- Running `interns-mcp` itself — the Claude Code harness spawns it on session start.
- Authoring new interns or editing `.common/config/interns/config.yaml` — that's a content task, not a setup task.
- Any other MCP server.
## Hard rule: don't auto-mutate config
The procedure runs `pip install`, writes `.common/secrets/interns.env` (carries endpoint API keys), and edits `~/.claude.json`. **Always pause for explicit confirmation between Phase 1 (discovery, read-only) and Phase 2 (plan), and again before Phase 3 (backup + writes).** A trigger phrase grants permission to inspect, not to install or write secrets.
## Procedure
### Phase 0 — Environment sanity
- Confirm Claude Code is the current harness (need `mcpServers` registration in `~/.claude.json`).
- Confirm `python` ≥ 3.11 and `pip` are on `PATH`. Report the resolved interpreter path (`python -c "import sys; print(sys.executable)"`); the skill will pin this exact path in the MCP registration so a later `python` shadowed by another env doesn't silently take over.
- Confirm network reachability to the configured endpoints (default: `https://ollama.com/v1`). On HTTP 401 / 403 later, the API key is dead — stop and ask for a new one.
- Pick paths: `<project-root>/.common/lib/interns-mcp/` (source), `<project-root>/.common/config/interns/config.yaml` (catalog), `<project-root>/.common/secrets/interns.env` (keys, gitignored), `~/.claude.json` (MCP registration). POSIX-style paths resolve correctly under git-bash on Windows.
### Phase 1 — Discovery (read-only)
Search, in order. Report only "found at <path>", never echo key values.
**Server source.** Check whether `<project-root>/.common/lib/interns-mcp/pyproject.toml` exists. If absent, **stop** — the runtime source must be in place before this skill runs. Report:
```
.common/lib/interns-mcp/ not found.
This skill expects the inline interns-mcp source per the
.common/ layout (see .wiki/concepts/interns-design.md). Initialize
the runtime first, then re-run setup-interns.
```
**Build artifact.** Run `python -c "import interns_mcp" 2>&1` against the candidate interpreter. If it fails with `ModuleNotFoundError`, Phase 4 will run `pip install -e .common/lib/interns-mcp/`. If it succeeds, capture the installed location and skip the install in Phase 4.
**Config catalog.** Read `<project-root>/.common/config/interns/config.yaml`. Extract the unique set of `endpoints.<name>.api_key_env` values — these are the env var names the runtime expects to find. Capture for Phase 2.
**Existing endpoint keys.** Look in priority order, per `api_key_env` name from the config:
1. `<project-root>/.common/secrets/interns.env` (`<NAME>=...` lines).
2. Process env (`os.environ[<NAME>]`).
3. `~/.config/projects-mcp/auth.toml` — only if the user has explicitly noted the key is shared with another local MCP server (rare).
The first hit wins per key. **Never echo key values in chat.**
**MCP registration.** Read `~/.claude.json` and check `mcpServers.interns`. Note the `command` and `args`. If args point at a stale interpreter, Phase 6 will fix it.
**Gitignore sanity.** Check `.gitignore` (project root). If `.common/secrets/` (or `.common/secrets/*.env`) is not listed, flag for Phase 2 — the skill will offer to add it before writing the file.
### Phase 2 — Plan + confirm
Present a single-block plan to the user:
```
Source: <found at .common/lib/interns-mcp/ | NOT FOUND — STOP>
Module: <interns_mcp importable | will pip install -e>
Config: <found at .common/config/interns/config.yaml> — endpoints: <names>
Missing keys: <list of <NAME> not yet present in interns.env | none>
Gitignore: <covers .common/secrets/ | will add ".common/secrets/*.env">
MCP entry: <present in ~/.claude.json | will add | will fix interpreter path>
Backups: ~/.claude.json.bak-<ts>, .common/secrets/interns.env.bak-<ts> (if exists)
```
Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop.
For each missing key, ask: "Paste a value for `<NAME>` (endpoint: `<endpoint_name>` — provider settings page: `<url-from-config-or-known-list>`), or skip and we'll leave the entry blank for you to fill later." Don't proceed past Phase 2 without resolving every required key — the runtime won't start with a missing API key.
### Phase 3 — Backup
Copy each file we will modify to `<file>.bak-YYYYMMDD-HHMMSS`:
```bash
TS=$(date +%Y%m%d-%H%M%S)
[ -f ~/.claude.json ] && cp ~/.claude.json ~/.claude.json.bak-$TS
[ -f .common/secrets/interns.env ] && cp .common/secrets/interns.env .common/secrets/interns.env.bak-$TS
```
Confirm both backups exist (when their source existed) before any further edit.
### Phase 4 — Install Python module
```bash
# from project root
python -m pip install -e .common/lib/interns-mcp/
```
Capture the resolved `python` from Phase 0; use the same interpreter for both `pip install` and the later MCP `command:` field. Verify post-install:
```bash
python -c "import interns_mcp; print(interns_mcp.__file__)"
```
If import fails — abort. Ask the user to paste the `pip install` output so the failure mode is visible.
### Phase 5 — Write `interns.env` + gitignore
If Phase 1 flagged a missing `.gitignore` rule, append it first:
```
# interns endpoint API keys
.common/secrets/*.env
```
Then write `.common/secrets/interns.env`. Per-key behavior:
- Existing key in the file with a non-empty value — leave it alone.
- Missing key — append `<NAME>=<value-from-Phase-2>` if the user pasted one, or `<NAME>=` (blank) if the user skipped. A blank entry will fail at runtime with a clear `KeyError`; that's acceptable for the "I'll fill it later" path.
Permissions: on Linux / macOS run `chmod 600 .common/secrets/interns.env`. On Windows the default ACL is per-user, no extra step.
### Phase 6 — Register in `~/.claude.json`
Edit `~/.claude.json`. Add or update the `mcpServers.interns` block:
```json
{
"mcpServers": {
"interns": {
"command": "<ABSOLUTE_PATH_TO_PYTHON>",
"args": ["-m", "interns_mcp.server"],
"cwd": "<ABSOLUTE_PATH_TO_PROJECT_ROOT>"
}
}
}
```
`cwd` is set so the runtime resolves `.common/config/interns/config.yaml` and `.common/secrets/interns.env` relative to project root regardless of where Claude Code was launched.
Absolute interpreter path comes from Phase 0 (`sys.executable`). Forward slashes work in JSON on Windows without escaping.
After each edit, validate JSON:
```bash
# Windows (git-bash)
powershell.exe -NoProfile -c "Get-Content '<file>' -Raw | ConvertFrom-Json | Out-Null"
# Linux / macOS
jq empty <file>
# fallback
python -c "import json; json.load(open('<file>'))"
```
If validation fails → restore from `.bak-*` and abort.
### Phase 7 — Smoke test (best-effort)
Best-effort: ask the user to call `mcp__interns__bulk_text_read` against a tiny benign input (e.g. read this file's `Phase 7` section, ask "what is this section about?"). A response that is structurally valid (text + usage) means the server is reachable.
**Important caveat to relay to the user:** in the *same* session that just ran setup, the active MCP connection was bound at session start. So a passing in-session smoke test only proves "an interns server is alive" — not "the registration we just wrote is what's serving it". The real test is after Claude Code restart.
If `mcp__interns__*` tools aren't registered in this session at all, skip the smoke test and rely on Phase 8.
### Phase 8 — Restart guidance + final report
Tell the user:
```
✅ Setup complete. Restart Claude Code so the new mcpServers.interns
registration binds to a fresh stdio session.
After restart:
• mcp__interns__* tools serve from <python> -m interns_mcp.server
• Endpoint keys live in .common/secrets/interns.env (gitignored)
• Config catalog at .common/config/interns/config.yaml
• Backups saved at ~/.claude.json.bak-<ts> (and interns.env.bak-<ts>
if it existed before)
Runtime policy lives in `using-interns`. CLAUDE.md trigger:
delegate to interns when allowed
project-bootstrap 1.6.0+ adds it to new projects automatically.
If something breaks after restart:
• Restore from .bak-* and tell me — we'll roll back together.
```
## Rollback procedure
If a problem surfaces (now or after restart):
1. Stop. Don't try to fix forward.
2. Find the most recent `.bak-YYYYMMDD-HHMMSS` next to `~/.claude.json` and `.common/secrets/interns.env`.
3. `cp <file>.bak-<ts> <file>` for each.
4. Optional: `pip uninstall interns-mcp` if you want to remove the editable install.
5. Restart Claude Code.
6. Confirm `mcp__interns__*` is gone (or back to its pre-existing version).
7. Report what went wrong so we can fix the procedure.
## Cross-platform notes
The procedure is platform-agnostic. Only auxiliary tooling differs:
| | JSON validate | Backup | Permissions on `.env` |
|---|---|---|---|
| Windows (git-bash) | `powershell.exe -NoProfile -c "Get-Content '<f>' -Raw \| ConvertFrom-Json \| Out-Null"` | `cp` | per-user ACL by default |
| Linux | `jq empty <f>` (or `python -c "import json; json.load(open('<f>'))"`) | `cp` | `chmod 600` |
| macOS | same as Linux | `cp` | `chmod 600` |
POSIX-style paths (`.common/...`, `~/.claude.json`) work on all three.
## Common mistakes
- **Skipping Phase 1.** "User just said 'install interns' — let's go." No — find existing source / module / keys first; clobbering an existing `.env` over a working one loses keys you can't recover.
- **Echoing endpoint keys.** They're secrets. Edit / Write tool calls inevitably contain them (that's how they land in `.env`), but no chat output should.
- **Pinning `python` instead of `<sys.executable>`.** A bare `python` in the MCP `command:` resolves to whatever interpreter is first on `PATH` at session start — often a different env without the `interns_mcp` module. Always use the absolute interpreter path captured in Phase 0.
- **Forgetting `cwd:`.** Without it the runtime can't find `.common/config/interns/config.yaml` and bombs at startup with a config-not-found error that looks like a Claude Code bug.
- **Writing `.env` with `0644` perms on Linux/macOS.** Token leak. Always `chmod 600` after write.
- **Missing the gitignore rule.** Tokens commit to the repo on the next `git add .`. Always check `.gitignore` covers `.common/secrets/*.env` before writing — Phase 5 does it but it's worth double-checking.
- **Treating in-session smoke test as proof.** Same as the context7 / projects-meta caveat — the active MCP connection was bound at session start. Real verification happens after restart.
- **Auto-running on every "use interns".** This skill is intrusive. Trigger only on explicit "install / set up / configure interns", or when MCP tools are missing and the user is blocked.

View File

@@ -0,0 +1,68 @@
# using-interns
Runtime policy for the local `interns` MCP server. Delegates predictable bulk I/O and summarization tasks to cheap intern LLMs (DeepSeek / Kimi / Ollama-hosted) so Claude saves Anthropic quota.
`using-interns` governs *usage* of an installed server. Initial setup (`pip install`, `.env` write, MCP registration) is owned by [`setup-interns`](../setup-interns/).
Full design: `.wiki/concepts/interns-design.md` (in this repo) — Layer 1 / 2 / 3 architecture, MVP catalog, always-ask paths, routing hints.
## When it triggers
- CLAUDE.md contains `delegate to interns when allowed` (added by `project-bootstrap` 1.6.0+).
- User says: "use interns", "delegate to an intern", "разреши интернов", "allow interns", "go ahead with interns".
- Claude is about to read 3+ files, or one file > 400 lines, just to build context.
- Claude is about to update `.wiki/log.md` or write a session summary from a long transcript.
- If `mcp__interns__*` tools are missing, this skill delegates to [`setup-interns`](../setup-interns/) before doing anything else.
## What it does
- **Picks the right intern** for the task from a routing table (`bulk_text_read` for reads, `transcript_distill` for summaries; future interns added in `.common/config/interns/config.yaml`).
- **Guards every call** with a per-session permission grant that mirrors `project-discipline` Rule 4 — ask-mode default, conversational grant / revoke, session-end reset.
- **Enforces always-ask paths** — `.env`, `**/secrets/**`, `**/*.key`, `**/*.pem`, `**/.ssh/**`, `**/.aws/credentials`, `**/.netrc` etc. — even when delegation is granted. Server-side enforcement plus a transitive rule: Claude can't bypass by reading the file with the local `Read` tool and forwarding the content.
- **Caps cost** — calls with estimated cost > $0.10 always go to ask-mode regardless of grant.
- **Tells Claude what NOT to delegate** — architecture, debugging, auth / payments, final commit messages, final user-facing answers.
## Permission grant cheat-sheet
| Phrase | Effect |
|---|---|
| (default) | Ask before every `mcp__interns__*` call. |
| "разреши интернов" / "allow interns" | Free delegation until session end (subject to always-ask paths + cost cap). |
| "отзови интернов" / "revoke interns" | Back to ask-mode. |
| (session ends) | Reset to ask-mode. The next session asks again. |
## Tool quick reference
| Tool | Required args | Optional | Purpose |
|---|---|---|---|
| `mcp__interns__bulk_text_read` | `paths: list[str]`, `question: str` | `max_tokens: int` | Read N files, answer with file:line citations. |
| `mcp__interns__transcript_distill` | `paths: list[str]`, `question: str` | `max_tokens: int` | Distill transcript / log into structured action list. |
Pass **paths**, not file contents. The MCP server reads and applies the always-ask matcher server-side; forwarding content as a string arg bypasses the gate.
## When NOT to use
- Architecture / design decisions — Claude's job.
- Debugging — cheap models miss subtle bugs.
- Auth / payments / PII / production data — recommendation, not enforced, but obvious.
- Final commit messages, PR descriptions, user-facing answers — don't sub-delegate the deliverable.
- A single 50-line file you can read yourself for free.
Full policy and examples in [`SKILL.md`](SKILL.md).
## Install
From the repo root:
```bash
bash scripts/install.sh using-interns
```
Works on Windows under git-bash, Linux, macOS.
## See also
- [`setup-interns`](../setup-interns/) — companion, owns the server install + `mcpServers.interns` registration.
- [`project-discipline`](../project-discipline/) — Rule 4 (per-session push grant) is the prior art for the grant mechanism here.
- [`using-projects-meta`](../using-projects-meta/), [`using-context7`](../using-context7/) — sister `using-X` skills for other MCP servers (same shape).
- `.wiki/concepts/interns-design.md` — full architecture spec.

View File

@@ -0,0 +1,191 @@
---
name: using-interns
version: 0.1.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". 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.
Two MVP interns:
| 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. |
Both currently run on Ollama Cloud (`deepseek-v4-flash`, ~$0.002 / call). 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 `.common/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.
## 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/**` (including `.common/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` |
| Updating `.wiki/log.md` or session-summary doc | `transcript_distill` |
| Compressing a long brainstorm transcript before quoting in a design doc | `transcript_distill` |
| (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__transcript_distill` | `paths: list[str]`, `question: str` | `max_tokens: int` | Distill transcript / log into structured action list. |
(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.