Skip to content

P1a.5: the four skills - #9

Merged
kurowski merged 4 commits into
mainfrom
p1a.5/skills
Sep 19, 2026
Merged

kurowski merged 4 commits into
mainfrom
p1a.5/skills

Conversation

@kurowski

Copy link
Copy Markdown
Owner

Checkpoint P1a, sub-scope 1a.5, the four skills. Stacked on #8, whose toolkit additions these skills call; merge #8 first, then this.

  • start, next, lesson, done under plugins/rolling/skills/, holding the loop of docs/plan.md § 5 and the spike's coaching rules with its fourth-wall slips corrected.
  • Grants are the rolling-* commands each needs and read-only git; no map command, no package manager, no tree-changing git. lesson is the one model-invocable skill; next hands off to it through the Skill tool under its own narrow grant.
  • Every file of the tutor's goes through the pen; the skills forbid what the first runs caught the tutor doing (reading toolkit source, --help, listing the state directory, code in heredocs, parking files in the repo).
  • The mechanism rows for 1a.5 are recorded: Skill-from-skill works under the caller's own grant; a slash command in print mode runs the skill; grants hold only for the invoking turn; the data directory is a protected path.
  • One write lesson ran end to end on the Rallly clone twice; the 1a.5 paragraph has the transcript read and the warts left for 1a.6, 1a.7, and P1b. Prose is reviewed by running it, per CLAUDE.md; that run is the review.

Gate: claude plugin validate --strict on the plugin and the marketplace; the toolkit suite unchanged from #8.

🤖 Generated with Claude Code

https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki

kurowski and others added 3 commits September 16, 2026 18:42
`start`, `next`, `lesson`, and `done` as `rolling`'s skills: the loop
of docs/plan.md § 5 and the coaching rules the spike settled, with the
spike's fourth-wall slips corrected, calling the toolkit by name.

What each skill may do is its `allowed-tools` line, and nothing wider:
the `rolling-*` commands it needs, read-only git, and for `next` the
Edit and Write tools, which it uses only before a task exists, to
prepare a test and try its solution. No skill grants a map command, a
package manager, or git that changes the tree; the checks a lesson
asks of the learner are the map's own commands, verbatim, run by the
tutor only when asked and through the permission prompt. `lesson` is
the one skill the model may invoke, since it only re-presents the
open task; `next` hands off to it through the Skill tool, which its
own `Skill(rolling:lesson)` grant covers with no session-level grant.

Every file of the tutor's goes through the pen: `rolling-write` for
the task, the profile, the reference, and the patch; `rolling-note`
for evidence, whose kind the script requires; `rolling-keep-task` for
a proved task. The skills say why, once: the data directory is a
protected path, and the Write tool would prompt there on every call.
They also say what the first runs found the tutor doing unbidden and
forbid it: reading the toolkit's source, running its commands with
--help, listing the state directory, pasting code into a heredoc, and
parking a file in the repository to get round the Bash tool's
refusal. A seam task's solution is tried in the tree and taken out
with `rolling-write patch --from-tree`; the proof is two commands,
`rolling-verify --on-base` and `--on-reference`, and `next` runs no
git that changes the tree at all.

A skill's grants hold for the turn it was invoked in. In the learner's
next plain turn the same commands prompt, once each; `done` and
`lesson` say so the first time and carry on, because the rubric's
"the learner can explain…" bullets are answered in that later turn
and the record of the outcome is written then.

One `write` lesson ran end to end on the Rallly clone, twice, in print
mode with the session resumed turn by turn: route chosen and noted,
a seam task built and proven both ways, the brief given with the mode
first and the map's command as what done means, the diff read against
the rubric with a path, a line, and a provenance per point, the
identical-to-reference change noticed and said, the explain-it
bullets left to the learner, and an unearned "I agree" recorded as a
disagreement with the lesson left open. The checkpoint plan's 1a.5
paragraph has the run and the warts it left for the next slices.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki
The sub-scope records its own PR number, the way the earlier ones do.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki
Markdown reads a text line followed by --- as a setext heading, so the
whole paragraph rendered as one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki
@kurowski
kurowski changed the base branch from p1a.5a/toolkit-writes to main September 19, 2026 01:05
@kurowski

Copy link
Copy Markdown
Owner Author

@claude review this

@claude

claude Bot commented Sep 19, 2026

Copy link
Copy Markdown

Claude finished @kurowski's task in 7m 4s —— View job


Review of PR #9 — the four skills

  • Read CLAUDE.md and repo conventions
  • Read the diff (this PR's own commits: df5d7ef..HEAD, matching the stated 609/−12 across the 6 listed files)
  • Read the four new SKILL.md files in full
  • Check against CLAUDE.md rules and the toolkit they call (plugins/rolling/lib/rolling/cli.py, writes.py, tasks.py)
  • Post review

Overall this holds the rules well: no skill names a script/task/profile file to the learner, next's grants are read-only git plus the rolling-* pen, lesson is the one model-invocable skill, and the pen (rolling-write/rolling-note) is used everywhere instead of Write/Edit for the tutor's own state. One correctness bug, and one open question.

1. next's inline map check aborts the skill exactly when it's supposed to report a fault

plugins/rolling/skills/next/SKILL.md:212-214:

## Map check

!`rolling-check-map`

and the "Choosing" section says: "If the map check below reports faults, tell the learner the map has a problem the author needs to fix, quote the faults, and stop." (lines 78-79)

But rolling-check-map is registered under ACTIONS, not INLINE, in plugins/rolling/lib/rolling/cli.py:461-469, and cmd_check_map (cli.py:414-429) return 1s when the map has faults — the same exit-1 behavior plugins/rolling/tests/test_cli.py's test_check_exit_codes and test_an_unreadable_lessons_directory assert on directly. cli.py's own module docstring is explicit about why the split exists: "an inline command... always exits 0, because a non-zero inline exit aborts the skill." CLAUDE.md states the same rule for skills generally: "A non-zero exit from a !`command` aborts the skill."

So on an actually broken map, the inline rolling-check-map call aborts next before the model's turn even begins — the graceful "tell the learner, quote the faults, stop" branch the skill describes can never execute. It'd likely surface as a raw tool failure instead of the tutor's voice, which is also in tension with "no fourth wall." The two demo runs recorded in docs/plans/p1a-write-mode.md didn't exercise this because the map validated cleanly both times (the healthy path returns 0 and is invisible).

Fix: give next an inline-safe way to see map faults — e.g. add a variant to cli.py's INLINE dispatch (alongside show/claim-session/session-start/diff/verify/report) that always exits 0 and reports faults in words, while keeping rolling-check-map's existing exit-1 contract for its other callers (the eventual CI gate / rolling-author verify, and the existing tests).

Fix this →

2. Open question: how does "try your own solution until the test passes" run, before a task exists?

next/SKILL.md's seam-task path (## Building the task, option 3) has the tutor write a test and "try your own solution in the tree beside it until the test passes," then call rolling-begin-task <lesson> --here <the test's path>. But at that point no task.md exists yet, and rolling-verify (cli.py's _verify) refuses with "no open task" until one does; next's allowed-tools also grants no map-declared test/build command directly (by design — no package manager grant). So it's not obvious what actually runs the test during that "try until it passes" step. The two recorded demo runs did build a seam task successfully (docs/plans/p1a-write-mode.md's 1a.5 write-up), so either this resolves in a way I'm not seeing from the skill text alone, or the demo runs used elevated permissions not representative of the shipped grants. Worth a sentence in the skill (or the plan doc) clarifying the mechanism, since it's the one step in the loop that looks like it needs a capability the skill isn't granted.

Minor

  • plugins/rolling/README.md and the PR body describe next's grants as "the rolling-* commands each needs and read-only git," but next also carries full Edit/Write (needed for option 3's test-in-tree authoring). Intentional per the design (the tree is the tutor's to prepare before a task exists), just broader than that one-line summary suggests — worth a reader's note, not a change.
    · Branch: p1a.5/skills

The GitHub review of PR #9 read the next skill's inline
`rolling-check-map` against the dispatch table and was right: it is
an action that exits 1 on a fault, and a non-zero inline exit aborts
the skill before any model turn (a probe confirmed it: zero turns, an
empty result, the output in a stderr block). The skill's own
instruction to tell the learner the map has a problem could never run.
`rolling-show map-check` reports the same faults in words at exit 0;
the skill reads that, and `rolling-check-map` keeps its exit-1
contract for authors and CI. Run against a map with `mode: sideways`,
the tutor now explains the fault in one turn.

Also from that review: no skill grants a map command, so the checks
and setup operations the tutor runs while building a seam task ask
the learner each time; the skill now says so and says to keep them
few, and the plan says the recorded runs pre-approved them. The
README said next's grants were toolkit commands and read-only git; it
also has Edit and Write, for the test it prepares before a task
exists, and says so now. Two stale "run by" cells in the toolkit
table corrected while there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki
@kurowski
kurowski merged commit 8497202 into main Sep 19, 2026
5 checks passed
kurowski added a commit that referenced this pull request Sep 19, 2026
The review workflow ran on every push to #9 and #11, finished
successfully, and posted nothing, with one denied tool call each time.
The code-review plugin's own command says why: with --comment and no
issues found, it posts a summary with `gh pr comment`, and its skill
declares that under its allowed-tools; the generated workflow allowed
only the inline-comment tool, so a clean review was a denied call and
silence, indistinguishable from a broken run. The allowed tools are
now the ones the skill declares, exactly: inline comments for
findings, `gh pr comment` for the summary, and the `gh` reads it uses
to look at the pull request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X6P54zABxhBhazCERoY1ki
kurowski added a commit that referenced this pull request Sep 19, 2026
P1a review round: what the local reviews of #8 and #9 found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant