MIP-0011 tasks¶
Ordered delivery of MIP-0011 as stacked PRs
(.claude/skills/mip-tasks/SKILL.md, scripts/stack.sh). Branch mip-0011/<k>-<slug>; merge
bottom-up, scripts/stack.sh restack after each squash-merge.
MIP §5 already gives one bullet per task in delivery order; this file keeps that order and adds
the test each task must have before its PR, per §7's verification plan. All eleven tasks are one
chain (k based on k-1): nothing here is genuinely parallel the way MIP-0010's three lanes
were, since later tasks read files earlier ones create (AGENTS.md's trimmed body, the hooks
directory, the settings.json permissions block).
| # | slug | delivers | tests (must exist before the PR) | depends on |
|---|---|---|---|---|
| 1 | permissions-allowlist | .claude/settings.json permissions.allow (just build\|test\|quality\|fmt*, sbt *, git status\|diff\|log*, Read/Grep/Glob) and permissions.deny (Read(.env), Read(**/*.pem), Read(**/*.key)), on top of the existing gh/stack.sh allow entries, derived from real transcripts via the fewer-permission-prompts skill, not guessed |
fewer-permission-prompts run recorded in the PR body; a fresh session shows no prompt for just test; existing entries untouched (diff-reviewed) |
– |
| 2 | hook-cost-gate | A PreToolUse(Bash) hook that blocked cloud deploy commands with the AGENTS.md cost sentence (since removed) |
its --self-test, wired into just quality |
1 |
| 3 | hook-format-on-write | PostToolUse(Edit\|Write) on *.scala → native scalafmt (resolve OQ1 first: does the flake already provide one); *.py → ruff format when present; 30s timeout, single file only |
format.sh --self-test: an already-formatted file comes out byte-equal; OQ1's answer recorded in the PR body |
2 |
| 4 | hook-stop-gate | Stop hook .claude/hooks/stop-gate.sh: if .scala files changed since HEAD and no just test marker exists this session, block once with "run just test or say why", write the marker, allow the next stop |
stop-gate.sh --self-test: first call blocks, second call (marker present) allows; never a second block in the same session |
3 |
| 5 | hook-session-start | SessionStart hook prints branch, one-line gh auth status, uncommitted count, and FABLE_REVIEW.md §3's two jail caveats; deletes the two auto-memory notes it replaces |
Manual: just jcf transcript matches MIP §3's example line-for-line; the two auto-memory files are gone |
4 |
| 6 | claude-rules-split | .claude/rules/scala.md and docs.md with paths: frontmatter carrying the path-specific halves of AGENTS.md; AGENTS.md trimmed to ≤150 lines, linking to both (resolves OQ2 as excerpt-with-link-back, not move-only, per the MIP's stated default) |
wc -l AGENTS.md ≤ 150; /context shows rules/scala.md loaded only after a .scala file is read in the same session |
5 |
| 7 | subagents-reviewer-verifier | .claude/agents/mip-reviewer.md (Read, Grep, Glob, Bash; model: fable; memory: project): DEV-FLOW.md §5's review prompt, as a file; .claude/agents/jar-verifier.md (Bash; model: sonnet): javap a pinned Kyo class and report its real signature |
Manual: mip-reviewer run against a real task branch reports only correctness/requirement gaps (no style noise); jar-verifier run against one pinned Kyo class matches javap ground truth |
6 |
| 8 | skills-hardening | disable-model-invocation: true added to mip-tasks' frontmatter (it creates branches and PRs, MIP §2); one AGENT-SKILLS.md §3 candidate skill (cheapest first, decide which at task time) shipped with its own evals/evals.json |
/skill-doctor run before and after, both attached to the PR; skill-creator's eval run green for the new skill |
7 |
| 9 | mcp-registration | .mcp.json: marola → just mcp-server (stdio) |
Manual: a fresh session's /mcp lists find_nearby_beaches/get_swim_recommendation as available tools |
8 |
| 10 | claude-md-additions | CLAUDE.md additions under the @AGENTS.md import: plan-mode note, /clear + /rename-to-branch restatement, a compaction instruction ("preserve modified files, test commands run, and the Cost figure"), a CLAUDE.local.md mention plus its .gitignore entry |
Manual: forcing a compaction mid-session (/compact) and reading the result shows the modified-files/test-commands/Cost figure preserved |
9 |
| 11 | overnight-run-guardrail | Spike + guardrail for MIP §5 item 11: (a) verify the heavy-usage plugin's "stop before the wall" claim against its actual source before recommending it (OQ8) and record the finding in the MIP; (b) a short recipe (in docs/3-Working-on-the-repo/DEV-FLOW.md or a new short doc) for running a MIP-NNNN.tasks.md row-by-row unattended via /goal+/loop locally or a cloud routine (OQ7's spike, pick one, don't build both) with a stated stop condition; (c) permissions.deny gains Bash(gh pr merge*) and Bash(gh pr close*) at the project level, so an overnight session can never merge or close a PR itself: the same boundary voice-to-feature's disallowed-tools already gives that one skill, made a repo-wide hook-level guarantee instead of a per-skill opt-in |
Manual: a scripted gh pr merge attempt is denied under the new project settings, with no override (merge stays humans-only, no bypass flag); OQ7/OQ8 answers recorded in the MIP with a routines-vs-/goal+/loop recommendation |
– (independent spike + a settings addition; can be built any time relative to 1-10, but numbered last since it depends on nothing they produce) |
Decisions taken so the tasks above are unambiguous:
- Task 8 ships one skill candidate, not four (MIP §5 item 8 lists four). The remaining three
(
fixture-refresh,benchmark-compare,corpus-doc,water-provider, minus whichever ships in task 8) are follow-up tasks/PRs offmainonce this stack merges, not bundled here; each needs its ownevals/evals.jsonand review, and cramming four into one PR would blow past the ~400-line guideline. - Task 11's
gh pr merge/gh pr closedeny is project-wide, not scoped to background runs only: there is no daytime workflow inDEV-FLOW.md§6 that has Claude itself rungh pr merge(a human merges, per that doc), so a project-level deny costs nothing during normal sessions and closes the gap for unattended ones. If a future workflow needs Claude to merge under human instruction, that is a new MIP, not a quiet exception carved into this one. - Order 1→11 matches MIP §5's own bullet order: the MIP already sequenced these by what
later tasks read (task 6 trims
AGENTS.mdafter tasks 2-5 exist to point rules at; task 8 disables auto-invocation onmip-tasks, which this very tasks.md was produced by, so task 8 should not land before this file is committed). No task reorders the MIP's own sequence.
Restack notes: task 6 is the only one that touches AGENTS.md itself (trimming it); every task
before it only adds new files. Nothing else rewrites a file an earlier task created, so restacks
after each merge should be mechanical (scripts/stack.sh restack, no manual conflict resolution
expected).