diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index c71591e..a8beb0b 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,5 +1,5 @@ # Task Board -_Updated: 2026-05-01_ +_Updated: 2026-05-05_ ## 🟢 [shared-wiki-skill-catalog] — публикация каталога claude-skills в shared projects-wiki **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 -**Where I stopped:** (not started) -**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. -**Branch:** n/a +**Status:** done +**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:** (none — kept until merged) +**Branch:** master --- diff --git a/.tasks/interns-skills-mvp.md b/.tasks/interns-skills-mvp.md new file mode 100644 index 0000000..0c130de --- /dev/null +++ b/.tasks/interns-skills-mvp.md @@ -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 `/.common/lib/interns-mcp/` and `/.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. diff --git a/.wiki/log.md b/.wiki/log.md index 9a266e6..b00be12 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -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-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) diff --git a/CLAUDE.md b/CLAUDE.md index 8e9866d..dd42cb0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,4 +8,5 @@ use task management system check across all projects pull remote before work follow project discipline +delegate to interns when allowed we're on Windows diff --git a/dist/project-bootstrap.skill b/dist/project-bootstrap.skill index 4692735..bc0187b 100644 Binary files a/dist/project-bootstrap.skill and b/dist/project-bootstrap.skill differ diff --git a/dist/setup-interns.skill b/dist/setup-interns.skill new file mode 100644 index 0000000..a5efedc Binary files /dev/null and b/dist/setup-interns.skill differ diff --git a/dist/using-interns.skill b/dist/using-interns.skill new file mode 100644 index 0000000..eec6d16 Binary files /dev/null and b/dist/using-interns.skill differ diff --git a/skills/project-bootstrap/README.md b/skills/project-bootstrap/README.md index c75caeb..f2ce38a 100644 --- a/skills/project-bootstrap/README.md +++ b/skills/project-bootstrap/README.md @@ -57,7 +57,8 @@ projects bootstrapped at different times debuggable. 3. **Steps 1–5.** Create or skip each piece in order — git, README, `.wiki/`, `.tasks/`, `CLAUDE.md`. Steps 3 and 4 delegate to the setup-skills. 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` plugin via `~/.claude/plugins/installed_plugins.json`. If absent, print 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. - [`using-wiki`](../using-wiki/) — runtime policy for working with `.wiki/`. - [`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: diff --git a/skills/project-bootstrap/SKILL.md b/skills/project-bootstrap/SKILL.md index 3a46c3d..f925d68 100644 --- a/skills/project-bootstrap/SKILL.md +++ b/skills/project-bootstrap/SKILL.md @@ -1,6 +1,6 @@ --- name: project-bootstrap -version: 1.5.0 +version: 1.6.0 description: > 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. @@ -265,6 +265,7 @@ use task management system check across all projects pull remote before work follow project discipline +delegate to interns when allowed 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 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 project's default platform to Windows / PowerShell — so generated commands and 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` | | wiki canonical layout | | `setup-tasks` | | tasks canonical layout | | `project-discipline` | | cross-project policy | +| `setup-interns` | | interns MCP server install (one-time, per machine) | +| `using-interns` | | 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`. ``` diff --git a/skills/project-bootstrap/assets/CLAUDE.md.template b/skills/project-bootstrap/assets/CLAUDE.md.template index 8e9866d..dd42cb0 100644 --- a/skills/project-bootstrap/assets/CLAUDE.md.template +++ b/skills/project-bootstrap/assets/CLAUDE.md.template @@ -8,4 +8,5 @@ use task management system check across all projects pull remote before work follow project discipline +delegate to interns when allowed we're on Windows diff --git a/skills/setup-interns/README.md b/skills/setup-interns/README.md new file mode 100644 index 0000000..a5e06e1 --- /dev/null +++ b/skills/setup-interns/README.md @@ -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 `/.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 | +|---|---| +| `/.common/lib/interns-mcp/` | server source (must already exist; not created here) | +| `/.common/config/interns/config.yaml` | catalog of interns + endpoints (read-only here) | +| `/.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 .bak- ` 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. diff --git a/skills/setup-interns/SKILL.md b/skills/setup-interns/SKILL.md new file mode 100644 index 0000000..8395564 --- /dev/null +++ b/skills/setup-interns/SKILL.md @@ -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 `/.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: `/.common/lib/interns-mcp/` (source), `/.common/config/interns/config.yaml` (catalog), `/.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 ", never echo key values. + +**Server source.** Check whether `/.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 `/.common/config/interns/config.yaml`. Extract the unique set of `endpoints..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. `/.common/secrets/interns.env` (`=...` lines). +2. Process env (`os.environ[]`). +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: +Module: +Config: — endpoints: +Missing keys: not yet present in interns.env | none> +Gitignore: +MCP entry: +Backups: ~/.claude.json.bak-, .common/secrets/interns.env.bak- (if exists) +``` + +Wait for explicit confirmation ("ok", "go", "поехали"). Anything else → stop. + +For each missing key, ask: "Paste a value for `` (endpoint: `` — provider settings page: ``), 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 `.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 `=` if the user pasted one, or `=` (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": "", + "args": ["-m", "interns_mcp.server"], + "cwd": "" + } + } +} +``` + +`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 '' -Raw | ConvertFrom-Json | Out-Null" +# Linux / macOS +jq empty +# fallback +python -c "import json; json.load(open(''))" +``` + +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 -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- (and interns.env.bak- + 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 .bak- ` 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 '' -Raw \| ConvertFrom-Json \| Out-Null"` | `cp` | per-user ACL by default | +| Linux | `jq empty ` (or `python -c "import json; json.load(open(''))"`) | `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 ``.** 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. diff --git a/skills/using-interns/README.md b/skills/using-interns/README.md new file mode 100644 index 0000000..c68eb2b --- /dev/null +++ b/skills/using-interns/README.md @@ -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. diff --git a/skills/using-interns/SKILL.md b/skills/using-interns/SKILL.md new file mode 100644 index 0000000..198aa80 --- /dev/null +++ b/skills/using-interns/SKILL.md @@ -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: + +> Я бы делегировал чтение `` интерну `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: + +> Файл `` matched always-ask pattern `` (reason: ``). Передавать интерну на 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__` 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.