references/edit-skill.md
# Changing an existing skill
Skills predate the current standard and evolve toward it. The standard is the guide, not the text around your edit.
## Before editing
0. **State the runtime you are authoring from and what it may mask.** Run the guide's decentering step ("Your model is not a neutral author"): name the model tier and harness, then check each reaction against its bias — "this rule is redundant" (would a more literal model still hold the contract?), "this needs more steps" (protocol, or compensation for this runtime?), "it worked in my test" (which harness capability supplied that?), "this is missing X" (what observable failure does X address?). Do this before deciding anything is sediment.
1. **Read the block's goal, not just the lines you were pointed at.** What result does this block produce, for whom, and what is its done condition? If the block cannot answer that, the edit starts by restating the block; if it can, your change must keep that answer true.
2. **Search provenance for what you intend to remove or rewrite** — a test that asserts it (`rg` under `tests/`), a `docs/solutions/` learning that records it, a commit that added it to fix a named bug (`git log -S`). Then apply SKILL.md's sediment rule as written — this step does not restate it. A duplication mandate that is itself the recorded fix for a bug that regressed twice is a scar, not ceremony — keep it and cite the bug. Say which of your removals rest on absence of evidence.
3. **Audit the block with these questions** before deciding the smallest change. Ordered by expected behavior change per finding:
| Class | Diagnostic question |
|---|---|
| Protocol or judgment | If this instruction disappeared, could the workflow produce a wrong path, state, count, gate, field, boundary, coverage floor, or handoff? Yes → protocol, keep it explicit and falsifiable. No → judgment; try deleting it. A menu whose omitted item silently drops required coverage is protocol, not judgment. Decompose a mixed block before classifying it. |
| Phantom handoff | Does the party this sentence hands off to exist in this run? |
| Step machinery | Would a different order, or skipping the ceremony, produce a different artifact? |
| Capability restatement | Would the model do this if the line were deleted? |
| Filler rationale | Does the rule survive intact if the sentence after it is removed? |
| Enumerated cases | Is this list of cases a proxy for one condition it could state instead? |
| Lean-prompt regression | Does the block repeat an instruction, completion check, autonomy gate, or command skeleton that one earlier rule already decides? |
| Command freedom | Do two recipes share the same command skeleton? If yes, the command belongs once with parameters or deltas unless each full command protects a distinct fragile gate. Conversely, would a capable model with live `--help` still ship the wrong command? If yes, pin the known-good command once. |
| Per-step completion | Is a local done check protecting mutation, auth, scope expansion, irreversible external effects, a fragile transition, or a silent handoff failure? If not, the skill-level done bar decides. |
| Blanket brevity | Does a cross-model skill say "be concise", "keep it short", or paste a Fable brevity block instead of naming what the report must preserve? |
| Vendor priority | Is a Fable-only lean-prompt preference being used to delete a Sol-critical command, report field, or no-blanket-brevity rule? |
| Prescribed mechanism | Does this skill own the command/state it spells out, or does it delegate that work? |
| Vestigial mode | Is there a caller anywhere in the corpus that sets this mode, flag, or branch? |
| Cross-unit duplication | Is this near-identical elsewhere, and is factoring it out actually permitted (parity tests)? |
| Shouting | Is this ALWAYS / NEVER / MUST carrying a rule the surrounding condition does not already state? Capitals are a smell that the rule is not stated as a condition. |
## Making the change
- **Bring the touched block up to the standard as part of the change.** A block written as a procedure, a menu, or an enumeration is restated as its conditions while you are in it; matching the old shape because it is there is how procedures propagate.
- **Scope to your change plus what it makes wrong.** Reconcile blocks your change contradicts or duplicates. Leave untouched blocks alone even when short of the standard, and name them in the PR as follow-up. A repo-wide modernization is its own change, requested explicitly.
- **Repeated case-specific repair is the defect signal.** If this block has been patched before for "the case we just found" — in an earlier round of the same PR, or in git history — do not add another case. Delete the additions and restate the goal, then re-verify the restatement against every path the additions served; a restatement that no longer names a path is a new defect, not a simplification.
- **For every mandate you remove, name what now decides**, and check that decider may decide it. A required gate stays.
- **Prefer one governing sentence over behavior enumeration.** If one sentence decides the listed behaviors, keep the sentence and delete the list; if a listed item is a separate invariant, state that invariant locally.
- **Do not overcorrect away deterministic guidance.** A concrete form — a known-good fragile command, or the failing shape a rule names — may be what the most literal host actually matches on, so removing it is a behavior change whatever the block reads like afterward. Removing duplicate easy commands is right. Keep the concrete form when that host fails without it: for a command, when a capable model with live `--help` would still get the command wrong; for a rule, when that host stops instantiating the condition. Decide that by running the host, not by reading the block. When it needs the shape, keep one subordinated under the condition rather than choosing between them (`docs/solutions/skill-design/subordinate-the-failing-shape-to-the-condition.md`).
- **Resolve model conflicts by product target.** For this org's multi-model skills, keep the Sol form when Fable-optimal brevity or anti-prescription would make Sol undershoot. Sol-critical determinism beats Fable-only hygiene.
- **Control length by preserved content.** For portable skills, replace blanket brevity slogans with the fields the short output must retain and the details it may omit.
- **Keep scope beside the action it governs, and let nothing compete with an exclusion.** A quantifier, threshold, or exclusion ("for each candidate separately", "do not change files outside …") sits next to the step it bounds, not in a distant reminder — literal models lose the distant one. They also act on whatever follows an exclusion when it offers them a competing decision, so what comes after one must decide nothing: an illustration subordinated to the exclusion is fine because it rules on nothing, while a qualification goes before it and an alternative destination is delegated to the section that owns it rather than listed inline as somewhere else to land.
- **Runtime placement:** an instruction that must fire at a point stays inline at that point; do not push it into a reference the agent may not load. Where the same rule must live in two always-loaded places, protect it with a parity test.
- **Scripted replacements** across many files: assert each anchor matches exactly once before writing anything, and fail closed per file.
- **Cross-file invariants:** when a skill's contract is consumed by another skill (an envelope field, a mode token, a status enum), change both ends in the same commit and check the contract test.
## Restructuring for a size or platform constraint
A rewrite whose stated reason is a byte cap, a host's frontmatter rules, or a converter target is a different starting state from a behavior fix, and it fails in its own ways (`docs/solutions/skill-design/size-driven-skill-restructure.md`):
- **Prove the constraint applies before cutting.** Name the doc or test that pins it and say which shipping path it governs; a cap that only binds a hypothetical future package is a ratchet goal, not an outage, and the PR says so. Both are legitimate; confusing them mis-sizes the eval. A ratchet goal is still worth the work: forced onto Codex's Agent Plugins path, a 28.5K body was truncated at 8,000 bytes and silently lost steps 1-10 (#1479), so "the cap does not bite today" bounds the urgency, not the size of the body.
- **The cap is a ceiling, not the target.** A body is charged to context on every invocation on every host, so a skill that already fits gets the same pass: the smallest always-loaded body, the rest in references. When a skill genuinely resists extraction, keep the body and record in the PR what was tried and why each remaining block must fire without a read; never shrink by dropping an invariant.
- **Enumerate the pins before you rewrite.** Run the skill's contract test file first and list every phrase it asserts verbatim; those survive the restructure word-for-word or the test changes deliberately with its reason. Discovering a pin after the rewrite is what turns a plain sentence into a squeezed one.
- **A pin is a decision, not an invariant.** Enumerating the pins prevents accidental breakage; it does not make a pinned phrase permanent. Audit each by provenance: incident-backed and window-deciding stays (verbatim only where the wording itself is the contract), an invariant about the artifact rather than the body becomes a corpus grep or a semantic regex, and incidental wording with no provenance is restated as its condition or dropped, with the reason in the test comment. Authorship and age are not provenance either way: a pin a bot review or one of our own agents added days ago has provenance if its test comment or introducing commit records the failure it protects, and none if it does not. Read what a pin actually asserts before recording it as a floor — a test's 4,500-byte search ceiling was read as a section size (#1475).
- **A body that is still over after plain rewriting relocates another block; it does not compress prose.** Fused clauses and telegraphic phrasing are how nine restructures in the 2026-08-18 sweep landed within 35 bytes of the cap, and one inverted the meaning of a safety guard; the sibling PR that only compressed a shared paragraph across fifteen skills was rejected outright (#1452). Land with room to spare (about 200 bytes) so a later review fix is not forced to squeeze.
- **Relocate before you delete.** Move blocks verbatim into references first, then bring the touched block up to the standard. Every invariant in the old body must be findable in the corpus by the same words a contract test greps for; a restructure that "simplifies" a fragile command while moving it has made two changes and can defend neither.
- **The body keeps what must fire without a read**: outcome/done, boundaries, the ordering invariant, stop classes, and a pointer to each reference at the point of use. A reference the tick cannot start without is named in the body as a required read before that step; the eval below checks whether models actually load it.
- **Then delete the reference's copy of what the body owns.** Relocating verbatim leaves the same gate stated twice; that is the intended half-step, not the finished move. Before the eval, diff each reference against the body and delete **from the reference** every gate, condition, or confirmation the body still owns. The body's copy stays — it has to fire without a read — and the reference names what it supplies to the gate instead of restating it. A second copy asks the user twice, records a snapshot twice, and drifts on the next edit, when only one of the two gets fixed.
- **Place each relocated block at the step that executes it, not at the phase it came from.** The obvious landing site is the reference covering the block's old neighborhood, which is often not the file the acting step reads — a Stage 6 gate in the step-1 reference, a rubric left with no loader. Nothing catches it: the corpus greps still match and the bytes are right. Ask of each relocated block which step acts on it, and when you find one placed wrong, audit them all (#1471).
- **A hoisted rule reads against its new neighbors.** Pulling procedure out changes what sits beside what in the body, and a rule that was unambiguous mid-phase can read as license against a boundary it now borders. Re-read every rule the restructure moved next to a boundary, and state its precondition where it now sits.
- **A shortened rule comes out absolute.** A byte budget pushes each restatement toward an absolute, and an absolute forbids paths the original allowed; the tell is a sentence qualified twice, once to close a finding and once when a finding lands on that addition. On the second round against one sentence, state the condition it was a proxy for rather than shortening it again, and pay for the bytes by deleting what the restatement makes redundant elsewhere (#1456: "never re-enter an earlier phase" forbade the marker-recovery scan that the real condition — never redo a completed checkpoint — allows).
- **Tests split by load-time.** Rules that must control behavior from the window get body pins; relocated invariants get corpus greps (body + references). Do not silently convert every body pin to a corpus grep.
- **Get an adversarial cross-model read of the draft before splitting.** A second model given the old file, the draft, and the incident that motivated the change finds dropped invariants a first author cannot see; treat its list as work items, and re-verify each of its premises against the repo (it will also be wrong).
- **Eval the extraction itself, on more than one harness.** Besides the behavior scenarios, ask each run which files it read. A required-read miss fails the cell only when the always-loaded body makes the decision undefendable without that file; if the body still states the gate, omit the probe (skip allowed) and add a complementary cell on the path the reference owns. Grade surviving artifacts and the ACTIONS trailer, not whether the essay named a forbidden command. For a widely used skill, build the matrix from the skill's entry paths and modes rather than one happy path: each path pre and post on Claude, Codex, and Grok, three trials on the popular paths, and an independent grader for the most-used skills. "Unexercised" means tried and could not force, with the reason; a defect review finds on a path the matrix skipped joins the matrix before the next push. When the restructured skill's key behavior is delegation, that extraction eval also dispatches for real — a `FILES_READ` probe with dispatch forbidden cannot show that the relocated rules still govern a live delegate (`references/evaluate.md`).
## Validate
Read `references/evaluate.md`. A behavior-bearing change gets a targeted eval on the paths the change touches, on Claude and Codex; a mechanical change gets `bun run test`. A change that removes or generalizes away text still needs the eval whenever that text could have been carrying a literal reader — which is not the same as its having recorded provenance, since a line added earlier in this same PR has none and can still be what the weakest host was matching on.
## Done when
The touched block states its conditions; every removal has a provenance result; nothing your change contradicts remains; validation ran or its skip is recorded; follow-ups are named.
references/evaluate.md
# Validating a skill change
Mechanical contracts (frontmatter, paths, greppable invariants, parity, script behavior) go in `bun test` and run in CI. Prose behavior — routing judgment, restraint, cross-model outcomes — is evaluated with a model and is best-effort evidence, not a CI job. Read the guide's "Evaluate proportionally" section for sizing.
## When an eval is required
Any change to how a skill routes, what it loads and when, what it asks, when it stops, what it commits or publishes, or how it degrades — on any harness. A pure removal still needs one when a removed line had provenance you overrode. Skip for changes that cannot alter behavior (typo, path, formatting) and say so. When the eval is required but a capability it needs is unavailable — no fresh-context subagent, or one of the two hosts unreachable — record that as the exact skip reason (which capability, on which host) and finish; run the part that is available (a single-host eval is evidence, labeled as single-host). Convenience is not a capability gap.
## How
Inject the current on-disk skill (and any references the scenario needs) into a **fresh** agent, then grade what it does. Plugin skills cache at session start, so invoking the edited skill in the authoring session tests stale content — do not test through in-session Skill-tool or typed-agent dispatch, and do not edit the plugin cache.
This repository does not ship an eval skill. Anthropic's `skill-creator` and the personal `skill-eval` skill are optional installed helpers, not repo capabilities. The portable primitive is the host CLI with the current skill extracted onto disk. `bun run test:skill-eval-cell -- --skill <name> --task "…"` is the repo-owned driver (`claude -p` / `codex exec` / `grok -p`, `CLAUDECODE` unset, Codex stdin closed). Named scenarios live in `tests/skill-eval-cell/catalog.ts` and run with `bun run test:skill-eval-pack -- --skill <name> --arm ab`. `--wave1` is the cheap read-only decision set, not the whole catalog. A change whose path is already in the catalog runs those rows; a path that is not covered adds a row authored from the pre-change contract. Grade artifacts and the ACTIONS trailer, not whether the essay recites a forbidden command. A `files_read_post` entry is a required read for that scenario and a miss fails the cell — list the file only when the always-loaded body makes the decision undefendable without it. Omitting the field is the correct negative (skip allowed). Do not add a must-not-read. When a reference owns a different path, add a complementary cell that requires that file rather than dropping the extraction probe. skill-creator does not replace this cell. Do not add `evals/evals.json` — that is not this repo's suite. Do not run interview-skill evals as in-session subagents: the blocking question tool would land on the authoring user. The cell driver isolates that (stdin closed, host CLI in a throwaway workspace). When the behavior under test depends on how the user answers (an interview, a brainstorm, a clarifying-question loop), run it as a conversation with `bun run test:skill-eval-judge`: it runs the skill before and after your change on Claude and Codex, a separate simulated user answers each turn from a persona, and a blind grader scores every transcript against a rubric and totals the results. Write the scenario for the change you made rather than reaching for a stock one, and pass it with `--scenario <file.json>` (fields in `tests/skill-eval-cell/judged/scenarios.ts`). A persona is useful when it holds a goal, needs it will not volunteer that only the right question surfaces, and what it would call overkill, so one grade shows both what the skill missed and what it added. `tests/skill-eval-cell/judged/` holds a starting library of personas, rubrics and fixtures. Answering every question up front with "your call" isolates what the skill recommends, but it overstates scope growth compared with a real conversation.
**Keep the test honest.** A test subagent must not know it is testing a skill: prompt it the way a user would ("use the `<skill>` skill to do X"), pass the raw artifacts (the file, the finding, the diff), never your diagnosis, the intended fix, or the expected answer. Fresh context per pass; clean up anything a run leaves on disk before the next; if a scenario passes only when the agent can see leaked context, tighten the skill or the setup before trusting the result. Read the transcripts, not just the final outputs — a skill that reaches the right answer while spending turns on unproductive steps has a defect the output hides, and several runs independently writing the same helper is a signal to bundle a script.
Baseline, then compare: run the scenario against the pre-change skill first when a behavior is being *changed* (so you can see the failure the change fixes), then against the edited skill. Include a no-guidance control when the question is whether a line does anything at all. Read every result; do not score by keyword.
**Size the eval to the decision, not the workflow.** A routing change inside an already-active skill is one decision made early in a run — which output contract, which reviewer team, which branch — so the cell that proves it stops at that decision: prompt the skill to resolve its gate and end (announce the team, state the contract, name the route), and grade the declared result. A full-skill run per cell (a complete review, a plan written to disk) spends ten minutes of subagents to observe a line that was decided in the first thirty seconds, and that cost is what turns a proportionate eval into a matrix. The floor: one discriminating fixture per direction — the case the old prose got wrong and the new must get right, and the case both must still get right — plus one per additional leg of the condition; post arm on Claude and Codex; the pre arm only when no baseline evidence already exists (a run that already happened in the session is evidence, not something to reproduce). A cell that declares nothing fails — grade the declared line, never narration that mentions the right word. A declared line grades a decision, not an action: when the claim is that the skill invokes another skill, run the cell live with a handoff probe and grade the recorded call (`tests/skill-eval-cell/README.md`). Six to twelve cells is the ordinary size; the pack runs its rows serially, so run one pack invocation per row side by side when wall time matters. If the change seems to need more cells, suspect the condition before growing the eval. This shortcut cannot test activation — the cell tells the agent to read the skill, so a skill that would never auto-trigger still resolves its gate; a description or trigger change is evaluated in a fresh host session with no skill injected, per the activation item below.
Cover, proportionally to risk: the path the change touches on the weakest realistic model tier; strong-model regression (did prose make a capable model worse); restraint (does the skill stop where it should, and does it avoid case catalogs, repeated autonomy gates, repeated command skeletons, and blanket brevity slogans); activation (positive, adjacent-negative, explicit invoke) when the description or trigger changed — with substantive prompts, since a trivial one-step ask never triggers a skill regardless of description; and the next consumer's contract when an envelope or handoff changed. Run on Claude and Codex by default — cross-host divergence is the biggest portability risk and the one a single-host run cannot see.
**Classify the key behavior before sizing the eval, because a fake-boundary run does not validate delegation.** A run with dispatch, `git`, and `gh` forbidden grades recognition, routing, and pointer-following, and it is the right first pass for any skill (`bun run test:skill-eval-cell -- --read-only`). It cannot grade a skill whose key behavior is live: peer or subagent dispatch, an orchestrator return contract, a mutation gated on what a delegate returned. There the model's account of what it would have done is the artifact under test, so it cannot also be the evidence — whether the delegate was dispatched, what payload it got, whether attribution waited on a real receipt, and whether the reconciliation was a synthesis are all invisible. For those skills the eval dispatches for real, pre- and post-change, on Claude and Codex, graded on subprocess logs and on-disk artifacts rather than the transcript, against a throwaway subject repo rather than the checkout. Record the paths one run could not reach — reconciliation when peers concur, degradation when a peer is unavailable — as unexercised, not as passing. A `codex exec` launched from a Claude Code shell inherits `CLAUDECODE=1` and makes the peer attest the wrong host; launch it under `env -u CLAUDECODE`.
For new CLI-wrapper skills, include a restraint fixture where the tempting output is five or more near-duplicate command blocks sharing the same flags. Passing behavior is one canonical invocation with parameters or named deltas, plus late references only for demonstrated gaps or non-derivable facts.
For new model-invoked skills, include a description-restraint fixture using the contrast pairs in `references/new-skill.md` as the fixture source. Passing behavior is a context pointer: distinctive mechanism with the leading prompt word first, one trigger per genuinely distinct branch in "Use when..." or "Use for..." form as an observable work-state, and adjacent negatives only when they block real false-trigger neighbors. A category opener without the mechanism, or a quoted-utterance catalog, fails.
For cross-model output guidance, include a restraint check that the authored skill does not copy a Fable-only brevity block or use a blanket "be concise" / "keep it short" slogan. Passing behavior names the report fields that must survive shortening; for CLI wrappers: command, exit status, output path/size, and stderr or blocker.
**Read the result honestly.** If old and new prose both succeed on a strong model, that is no regression, not improvement — test the claimed insurance at the layer where it matters (the weaker tier or the other harness). Measure the outcome the skill exists to improve, not proxy volume: routing, state, authority, and completion for an orchestrator; claim support for research; clarification burden and execution errors for planning. For a side-effecting skill, grade intended and suppressed actions first, then use fake boundaries or dry-run contracts before anything live.
## Reader pass for new or rewritten prose
After any change that writes or rewrites skill prose, have a fresh reader — a subagent that did not author the change, given the new text and the pre-change text — quote every sentence it had to read twice, plus any rewritten sentence whose meaning drifted from its origin. Size the read to the change: a size or placement restructure gets the whole always-loaded body read once; a new or rewritten sentence gets that sentence read in place. If the sentence is copied into several files, read it once. The author cannot see this: an independent audit of the 2026-08-18 sweep found dense or meaning-shifted sentences in thirteen of nineteen bodies that their authors, three harness evals, and two review bots had all passed. Fix by restating plainly or relocating, never by shortening again.
## Record
In the PR: scenarios, tiers/hosts, what the pre-change run did, what the post-change run did, and anything the eval surfaced that you did not act on. Authored scenario sets over-represent the happy path; add one scenario from a real failure (a bot finding, a session that went wrong) whenever you have one. Improve from what generalizes across scenarios, not from what fixes one — a skill tuned to its handful of eval cases is overfit.
references/new-skill.md
# Creating a new skill
Read the guide's "Author in this order", "Build the skill around an outcome spine", "Make activation portable", "Separate protocol from judgment", and "Describe capabilities before tools" sections before writing.
## Before the first line
1. **Confirm the gate.** Apply the new-skill contribution gate exactly as the working agreement in the project's active instructions states it (who is exempt, and what approval must exist before work starts) — do not paraphrase it here. Confirm the skill does not already exist under another name — grep `skills/*/SKILL.md` descriptions for the same trigger.
2. **Write the outcome spine as prose, first, alone:** the result or decision this skill produces, who consumes it next, the done condition, and the non-obvious intent only if it changes the approach. If you cannot write these four in a paragraph, the skill is not ready to author.
3. **Write the activation contract:** name and description as a context pointer — the model-invoked description sits in the window every turn and is pruned harder than the body. Sentence 1 names the distinctive mechanism (what a sibling would not produce), front-loading the leading word that should fire it in prompts. Then list one positive trigger per genuinely distinct branch in "Use when..." or "Use for..." form, written as an observable work-state. Prefer "Use <sibling> for <that job>"; keep "Not for" only when the same words fire both skills. If the skill is harmful on the wrong job, put "Use only when" / "Skip when" in the description. Agents under-trigger, so state the condition broadly enough that it covers the situations a user reaches without naming the skill — as a condition ("any change to a skill file"), not as a list of phrasings. Do not open with identity boilerplate, catalog sites/synonyms/capabilities for one branch, stuff quoted utterances or slash names into a model-invoked description, dump workflow, flags, or phase lists, or spend words on content the body already carries. Distinctive how may stay. Quoted phrases and `/name` aliases belong only on a user-invoked or `disable-model-invocation` skill, after the mechanism. Name: hyphen-case, verb-led where it reads naturally, under 64 characters; public plugin skills carry the `ce-` prefix.
Contrast pairs:
- Good (shape): "Applies this repository's skill-authoring standard as a procedure. Use for any change to, or judgment about, a file under skills/** — a SKILL.md, a reference, a persona prompt, a bundled script's instructions: creating a skill, editing one, reviewing a skill change, or acting on review feedback (human or bot) about one. Not for src/, tests/, or scripts/ code."
- Bad (failure: identity boilerplate + one branch written as a site/capability catalog): "This skill should be used when a user wants media from a yt-dlp-supported URL such as YouTube, Twitter/X, TikTok, and similar sites downloaded, audio extracted, playlists archived, or 403/bot-check failures fixed."
- Good (mechanism): "Poll CI and review threads on a named PR until they settle or block. Use when merge depends on checks or feedback still in flight."
- Bad (failure: category without the distinctive mechanism): "Run metric-driven optimization loops. Use when improving a measurable outcome through experiments."
- Bad for a model-invoked skill (quoted-utterance catalog; fine after the mechanism on a user-invoked or `disable-model-invocation` skill): "Use for /ce-commit-push-pr, 'open the PR', 'land this', 'push it up'."
## Authoring
- **Layer in order:** outcome spine → hard protocol (falsifiable scope, gates, authority, failure behavior) only where omission produces a wrong path or unsafe action → load-bearing ordering only where order changes correctness → useful context → adapters. Stop at the minimal form unless evidence, risk, or a consumer contract justifies more; add a recipe only for a demonstrated agent tendency or a non-derivable fact.
- **Resolve vendor tension Sol-first.** For multi-model skills this org ships, portable means Sol-first and Fable-acceptable. If Fable-lean guidance would remove a known-good fragile command, required report content, or the no-blanket-brevity rule Sol needs, keep the Sol form. Do not use Fable's "remove old prescriptions" guidance as a license to strip Sol-critical determinism.
- **Authority proportional to risk.** Put autonomy in one envelope: name safe local actions (reading files, inspecting logs, editing in-scope files, running non-destructive validation) and let in-scope work that follows from the user's request proceed without per-action confirmation, including an external write that is the requested job or named in the skill's authority envelope. Stop for confirmation when an external write, destructive action, purchase, or material scope expansion is outside that envelope, or when only the user can supply the input. Do not repeat "ask first", "do not mutate", or "wait for approval" at each step. A read-only, single-shot, non-delegating skill carries no authorization machinery. A skill that mutates or delegates consequential work names its envelope in the guide's positive form — invoking it authorizes these in-envelope actions without per-action confirmation, and does not authorize those — and carries inherited authority as bounded data that a downstream skill may narrow, never broaden.
- **Keep scope beside the action it governs** — quantifier, threshold, or exclusion next to the step it bounds.
- **Every route ends in the skill-level done condition or an explicit blocker.** Add local done checks only around unsafe or fragile actions: mutation, auth, scope expansion, irreversible external effects, or a handoff that can silently fail. No phase hands off to a party that does not exist in the run (a reviewer, a caller, an approver); that shape teaches the model to stop and wait.
- **Match specificity to fragility.** Where several approaches are valid and context decides, write the condition and leave the how to the agent; where one pattern is preferred, use one parameterized script, command, or example; where one known-good invocation exists and agents fail if they invent it, pin the exact command once. Low freedom is right for interacting flags, brittle order, working format selectors, clip/archive/auth recipes, and facts live `--help` will not reconstruct. CLI wrappers default to one canonical invocation plus named deltas when the job is the same default with one knob changed; if two recipes share the same command skeleton, they are one recipe with a parameter, not two blocks. Delegated work states the condition, not the callee's commands; owned mechanics may be spelled out. Deterministic, cheap-but-hard-to-reason glue — quoting, combining inspection output, or a checked flag set — belongs in a bundled script invoked with the `SKILL_DIR` anchor pattern the project's active instructions define.
- **A pinned command is the default, not a suggestion.** Write ordered failure, not peer options: run the pinned command first; if it exits non-zero, returns the wrong shape, hits a bot/auth/version signal, or another named mismatch, then inspect, run live `--help`, or use the named fallback. Do not write "use this command, or compose from `--help`" — Sol may skip the pinned command.
- **State each instruction once.** If a paragraph lists behaviors a brief instruction can steer, replace the list with the sentence. Repeated "ask first", repeated completion checks, and near-identical command blocks are over-prescription unless each repetition protects a different load-bearing gate.
- **Control report length by required content.** Do not copy a Fable-only brevity paragraph, or any blanket "be concise" / "keep it short" slogan, into a skill that also runs on Sol/Codex. State what the report must preserve and what it may omit; for CLI wrappers, the report preserves command, exit status, output path/size, and stderr or blocker.
- **Extract to `references/`** when a block is conditional or late-sequence and a meaningful share of the skill (~20%+); replace it with a one-to-three-line condition and a backtick path, inline at the point where it must fire. Never `@`-include. Never inline a summary complete enough to suppress loading the reference.
- **Portability:** describe capabilities and observable behavior before naming tools; missing capabilities degrade without silent skips; no platform-only variables without a fallback; no `!` load-time pre-resolution.
- **Structure.** References are one level deep from SKILL.md and each is named there with when to read it; a reference over ~100 lines opens with a table of contents; a fact lives in SKILL.md or in a reference, not both. Beyond `scripts/`, `references/`, and `assets/`, nothing else goes in the skill directory — no README, changelog, or notes about how the skill was made. **Personas** live under `references/agents/` or `references/personas/`, without frontmatter; dispatch policy lives in SKILL.md.
## Repo inventory (all in the same change)
A user-facing skill needs: `docs/guides/<name>.md` (purpose, novel mechanics, when to use, chain position), a catalog row in `docs/guides/README.md`, a root `README.md` inventory row, a situation row in `skills/ce-help/references/skill-map.md`, and the skill-count bump in `tests/release-metadata.test.ts`. Run `bun run release:validate` and `bun run test`.
## Validate
Read `references/evaluate.md`. A new skill needs at minimum: activation fixtures (positive, adjacent-negative, explicit-invoke), one restraint case, and one run of the main path on Claude and Codex. Record the results in the PR.
## Done when
The outcome spine reads correctly before any workflow; every route completes or blocks; the description triggers on the intended situations and not on the adjacent ones; inventory is updated; the eval ran and its findings are applied or recorded, or its exact capability skip reason is recorded per `references/evaluate.md`.
references/respond-to-review.md
# Acting on review feedback for a skill
Applying review, peer, or eval feedback is a material revision under the same standard as authoring. An item is not addressed because a sentence landed; it is addressed when a demonstrated gap is closed at its owning layer by the smallest mechanism.
Skill prose is not code. A natural-language condition can always be made more specific, so a reviewer can produce a valid-looking edge case against any rule indefinitely, and patching each one dilutes the rule. "Default to fixing" is the right rule for code; on skill prose the default for a case-level finding is to point at the condition. (Measured 2026-08-15, #1397: a two-condition step absorbed 24 bot findings over nine rounds, most of them cases against text the previous round had added, before being restated as the two conditions it began as.)
## Per item, before editing
1. **Evidence** — classify Change / Verify / Consider (see `review-skill.md`). A case the stated condition already decides is Verify at most: answer with the condition — `not-addressing` quoting it, or `replied` for a question — and do not patch. Edit only when the condition itself is wrong or missing, or a mechanism sits at the wrong layer.
2. **Owning layer** — for each Change: activation contract, outcome spine or skill boundary, runtime protocol, loading or placement, deterministic enforcement, or shared authoring rule. Several fixes in #1397 belonged in the callee skills, not in the caller's prose; put the fix where the mechanic lives, and change both ends of a cross-skill contract together.
3. **Mechanism** — the smallest one at that layer. Add prose only when it is the smallest mechanism, and then only a line that earns its place.
4. **Reconcile** — reread the affected block; remove or rewrite what the change makes conflicting, duplicated, or obsolete. Resolve conflicting items rather than stacking both.
5. **Stop the accretion loop** — when a finding targets text an earlier round added, delete or restate that addition rather than qualifying it. On the **second round against the same block**, stop patching: fold every finding on the block into one restatement item, restate the block as its goal, done condition, and safe direction, and re-verify against every path the additions served, including paths this round's findings do not re-raise. This holds whether rounds arrive in one review or across a babysit loop's re-invocations — count rounds from the branch's review-fix commits, not from this invocation.
Reviewer wording is a hypothesis about mechanism, not authority over it — the reviewer's one-line prose fix is sometimes exactly right, and sometimes the right answer is to delete the mechanism the finding is about (in #1397, an auto-rename that needed cases to be safe was removed outright).
When evidence shows the same cause across skills, fix the shared guide, rule, or mechanism unless the skills' contracts materially differ.
## Record
For a multi-item round, one line per item in the PR body or work note: `item -> Change|Verify|Consider | owning layer | mechanism - why`. A single-item fix may skip the written line.
## Validate
As for an edit (`edit-skill.md`): mechanical → `bun run test`; behavior-bearing → targeted eval per `references/evaluate.md`, or the recorded skip.
## Done when
Every item has a verdict; every Change closed a gap at its owning layer; no block was patched twice without a restatement; validation ran or its skip is recorded.
references/review-skill.md
# Reviewing a skill change
A review agent is biased toward producing changes. Counter it: state the runtime you review from and what it may mask (the guide's decentering step — "this is missing X" and "this rule is redundant" are the two reactions to distrust first), then diagnose before prescribing. Read the guide's "Diagnose before prescribing" section and its "Compact review prompt"; use the prompt as your working frame.
## What a finding is, on `skills/**`
A gap in the goal, the done condition, or the safe failure direction; over-prescription that degrades the agent's degrees of freedom; under-prescription that removes a known-good fragile command; a Fable-only deletion that harms Sol; or a mechanism at the wrong owning layer — commands prescribed in a skill that delegates that work, repeated command blocks where one parameterized recipe would decide the same behavior, omitted exact commands where a capable model with live `--help` would still get the command wrong, a pinned command with no failure hatch, a hatch offered as a peer option to the pinned default, per-step done checks not protecting a fragile gate, blanket brevity slogans in cross-model skills, a rule placed where it will not fire, a Claude-only construct in a cross-host skill, a rendering that breaks on another harness, a route that hands off to a party not present in the run.
**A case a stated condition already decides is not a finding.** Before filing "what if X" against a rule, read the rule's condition and ask whether it decides X. If it does, do not file. If the condition is wrong or missing, file that — as a condition.
**State the requested fix as a condition or an owning-layer move, never as a case to add.** "This probe fails open on network error" is a correct observation; the fix to request is "state the condition (act only on positive proof)" or "delete the probe", not "also check the exit code". "Command X fails in state Y" against a delegating skill is a representation finding: propose the deletion and the condition.
**A block restated to the standard is the expected shape of an edit**, not scope creep, when the restatement covers every path the old text served. Check that coverage; that is the review.
## Classify every finding
- **Change** — demonstrated gap with a supported smallest fix. A correctness fix cites a reproduced failure or the exact path that necessarily fails. An addition names the observable consequence of its absence, the unmet consumer contract or risk, the layer, and why the mechanism is the smallest.
- **Verify** — concrete risk that still needs reproduction or implementation tracing. Return the verification task, not a prescription.
- **Consider** — plausible enhancement whose value is not demonstrated.
Do not solve a non-problem with a rewrite. Prefer an additive guard or an explicit definition over replacing something that works.
## Also check
- Description is a context pointer for a model-invoked skill: sentence 1 names the distinctive mechanism with the leading prompt word first, then one trigger per genuinely distinct branch in "Use when..." or "Use for..." form as an observable work-state. Neighbor routing prefers "Use <sibling> for <that job>". An identity-boilerplate opener, a category opener that omits the mechanism, a site/synonym/capability catalog for one branch, or a quoted-utterance catalog on a model-invoked skill, is a Change; workflow, flags, phase lists, or body-owned detail in the description is also a Change. Distinctive how may stay. Use the contrast pairs in `references/new-skill.md` when the shape needs a labeled example.
- Every route completes or blocks; no phantom handoffs.
- One skill-level done bar decides ordinary completion; local done checks appear only around mutation, auth, scope expansion, irreversible external effects, fragile transitions, or silent handoff risk.
- CLI-wrapper skills use one canonical invocation plus named deltas; five or more near-duplicate command blocks is a Change unless each block protects a distinct load-bearing gate.
- Known-good fragile commands are pinned once. Omitting the command is a Change when agents fail if they invent it: interacting flags, brittle order, working format selector, clip/archive/auth recipe, or anything live `--help` will not reconstruct.
- Pinned commands are defaults with ordered failure hatches. A pinned command with no hatch is brittle; a hatch written as a peer option ("use this command, or compose from `--help`") is a Change because Sol may take the hatch first. The safe shape is command first, then named failure signal, then fallback.
- For this org's multi-model skills, Sol-first and Fable-acceptable wins over Fable-optimal. A Fable-only deletion of a Sol-critical command, report field, or no-blanket-brevity rule is a Change, not lean-prompt hygiene.
- Autonomy policy is one envelope; in-scope work proceeds, including external writes that are the requested job or named in the authority envelope. Repeated "ask first" gates, or an absolute stop for all external writes regardless of envelope, are a Change unless each marks a different outside-envelope external/destructive/scope/user-only boundary.
- Cross-model skills do not ship blanket "be concise" / "keep it short" slogans or Fable-only brevity blocks; they name the report content to preserve. For CLI wrappers, that includes command, exit status, output path/size, and stderr or blocker.
- Always-loaded prose vs conditionally-loaded references: cost them differently, and say whether the change moved weight between them.
- Cross-skill contracts changed on both ends, with the contract test.
- Portability: capabilities before tools, fallbacks for platform variables, no `!` pre-resolution, `SKILL_DIR` anchor on executed bundled scripts.
- Ordinary code in the same PR (`src/`, `tests/`, `scripts/`) gets ordinary code review.
## Output
For each finding: file and block, class, the evidence its class requires, and the requested fix stated as a condition or a move. Lead with Change items; list Verify and Consider separately as advisory, not as findings. When the caller's transport carries only actionable findings (inline PR review comments, a bot's finding list), emit Change items there and put Verify/Consider in the summary or omit them — never post a verification task as an inline finding. The completion report's review-mode shape (SKILL.md) says what goes where.
SKILL.md
---
name: ce-skill-work
description: "Applies this repository's skill-authoring standard as a procedure. Use for any change to, or judgment about, a file under skills/** — a SKILL.md, a reference, a persona prompt, a bundled script's instructions: creating a skill, editing one, reviewing a skill change, or acting on review feedback (human or bot) about one. Not for src/, tests/, or scripts/ code."
---
# CE Skill Work
Skills in this repository are goals, not state machines. A skill hands the agent the goal, the done condition, the safe failure direction, and the facts it cannot derive from the repo in front of it, then gets out of the way. Everything this skill does — authoring, editing, reviewing, responding to review — is that one standard applied to a different starting state.
**Outcome:** the skill files you touch state their conditions rather than enumerate cases, carry nothing that does not change behavior, and put each mechanism at the layer that owns it; and the change is validated in the way its risk warrants.
**Done:** the mode's completion report is written and its validation ran (or the exact skip reason is recorded). Landing a sentence is not done; a demonstrated gap closed at its owning layer by the smallest mechanism is.
**Non-goal:** shorter files. Leanness is a side effect of stating conditions; report what changed, not word counts.
## The standard (read before any mode)
`docs/solutions/skill-design/portable-agent-skill-authoring.md` is the authority. Read the sections the mode below names; do not restate the guide in the skill you are editing. The always-loaded rules in the project's active instructions supplement it and win where more specific.
Each block starts from the same possible elements, in this order: the result and next consumer, any local done check the skill-level bar cannot protect, the safe failure direction, the non-derivable facts, and only then any protocol the outcome cannot protect on its own. If a block does not need one, it omits it. What it must not have instead is a list of cases standing in for a condition it could state, or a mechanism prescribed for work this skill delegates — that is the finding. A procedure for a mechanic this skill owns, or a menu whose omitted item would silently drop required coverage, is protocol and stays.
## Rules that hold in every mode
- **Conditions, not cases.** When you find yourself adding "and also when X" to a rule, name the condition X is a proxy for and state that. A rule that has to enumerate its cases is stated wrong.
- **Prescribe a mechanism only where this skill owns it.** Commands, exit codes, and state transitions belong to the skill that owns the mechanic (`ce-commit-push-pr` owns PR detection) or to cheap deterministic work. A delegating skill states the condition, the safe direction, and the non-derivable callee facts.
- **Sediment first.** Before adding to a block, remove what the standard says should not be there. Provenance decides how hard to look, not what stays: search for a test that asserts the line, a `docs/solutions/` learning that records it, or a commit that added it to fix a named bug. Provenance found → the line is protecting something; keep it unless its consumer is gone, and cite what it protects. None found → apply admission (does it state a falsifiable constraint, counter a demonstrated tendency, or supply a non-derivable fact?) and, when a line is plausibly insurance for a weaker model or another harness, test that before cutting rather than assuming. Say which removals rest on absence of evidence.
- **For every mandate you remove, name what now decides.** If the answer is "the model, at its discretion, whether a required step happens", that mandate is a required gate and it stays. Removing a "must" does not remove the decision.
- **A line earns its place** by stating a falsifiable constraint, countering a demonstrated default tendency, or supplying a fact the agent cannot derive. Rationale after a directive that stands alone, effort language, and capability restatement do not.
- **User-facing invocations render per harness** — the rule and its placement are in the project's active instructions ("User-Facing Skill Invocations"); apply it wherever a skill prints or copies an invocation.
- **The description is a context pointer.** For a model-invoked skill, frontmatter sits in the window every turn and is pruned harder than the body. Sentence 1 names the distinctive mechanism (what a sibling would not produce), with the leading prompt word first. Then one positive trigger per genuinely distinct branch in "Use when..." or "Use for..." form, written as an observable work-state. Prefer "Use <sibling> for <that job>"; keep "Not for" only when the same words fire both skills. If the skill is harmful on the wrong job, put "Use only when" / "Skip when" in the description. Identity boilerplate, catalogs of sites/synonyms/capabilities for one branch, quoted-utterance and slash-name stuffing on a model-invoked skill, workflow, flags, and phase lists belong out. Distinctive how may stay. Quoted phrases and `/name` aliases belong only on a user-invoked or `disable-model-invocation` skill, after the mechanism.
- **One done bar first.** Every skill needs a skill-level done condition. Add a local done check only where skipping it can produce an unsafe action, fragile transition, scope expansion, mutation, auth mistake, or silent handoff failure.
- **Lean prompts for current strong models.** State each instruction once. If a brief instruction decides a family of behaviors, use it instead of enumerating the behaviors. If two recipes share the same command skeleton, write one recipe with parameters or deltas; if the skeleton is the same, repeated full commands are a defect.
- **Plain sentences; savings come from structure, not syntax.** Write one idea per sentence in ordinary English. Name who acts, what they do, and why it matters when that information is needed. Replace invented labels and internal workflow jargon with the action or consequence they mean; keep necessary technical terms and explain unfamiliar ones where the reader needs them. A sentence a careful engineer would read twice — clauses fused with dashes, articles and connectives dropped, three rules packed into one — is a defect even when it saves bytes, and it leaks into the agent's user-facing tone. When a body must get smaller, move a coherent block to a reference named at its point of use or delete genuine redundancy; never compress wording to fit, and leave headroom so the next fix does not have to.
- **Sol-first portability for this org's multi-model skills.** When Fable guidance to strip procedure or add a brevity block conflicts with Sol guidance to preserve a known-good command, required report content, or no blanket brevity slogan, keep the Sol form. Slightly thicker but clear instructions are acceptable for Fable; omitting Sol-critical determinism is not. True noise still drops.
- **Portable length control preserves content.** Never ship a blanket "be concise" / "keep it short" slogan in a cross-model skill. State what a short report must contain and what it may omit; for CLI wrappers, preserve command, exit status, output path/size, and stderr or blocker.
- **Long-running skills state their pacing.** A skill that owns a long loop or dispatches workers instructs batching (independent calls and dispatches issued in one response; serialize only real dependencies), narration (what the user hears before, during, and at close), and completion honesty (a step is done only when actually performed; the turn does not end on described-but-undone work). A skill that runs a few calls and returns omits all three — see the guide's long-running execution section.
- **Autonomy is one compact policy.** Name safe local actions and let in-scope work that follows from the user's request proceed, including an external write that is the requested job or named in the skill's authority envelope. Confirm only when an external write, destructive action, purchase, or material scope expansion is outside that envelope, or when only the user can supply the input. Do not repeat "ask first", "do not mutate", or "wait for approval" at each step.
- **Match freedom to fragility.** High freedom for many valid approaches; medium freedom for a preferred pattern or parameterized command; low freedom when one known-good command or sequence exists and agents fail if they invent it. Write a fragile command once; collapse easy variants to one skeleton plus deltas.
- **Validate to the risk.** After any edit, `bun run test:skill-guards` runs the mechanical guards in about a second, including the 8,000-byte SKILL.md budget in `tests/codex-skill-prompt-budget.test.ts`. Mechanical contracts (frontmatter, paths, greppable invariants) go in `bun test`. Behavior-bearing prose changes get a targeted eval per `references/evaluate.md`, on Claude and Codex, or an explicit skip reason in the report. Never ship an untested behavior change as "reference".
## Modes
Pick the mode from what you were asked to do; a request can chain them (a review that becomes an edit).
| You are | Read | Done when |
|---|---|---|
| Creating a new skill | `references/new-skill.md` | The outcome spine exists before any workflow, activation cases are written, repo inventory is updated, and the eval ran or its exact skip reason is recorded |
| Changing an existing skill | `references/edit-skill.md` | The touched block meets the standard, nothing your change contradicts remains, and validation ran |
| Reviewing a skill change | `references/review-skill.md` | Every finding is Change / Verify / Consider with the evidence its class requires, and each Change names a condition or an owning-layer move |
| Acting on review feedback for a skill | `references/respond-to-review.md` | Each item has a verdict, each Change closed a gap at its owning layer, and no block was patched twice |
## Completion report
End every mode with a report shaped by what the mode does. **Mutating modes** (new, edit, respond): per touched block, the goal it now states, what was removed and its provenance result; what was intentionally left short of the standard and why it is out of scope; what validation ran and its result or the exact skip reason; any decision that would materially change the skill's contract that you did not make. **Review mode:** the findings by class with the evidence each carries, and — where the caller has a summary channel — the paths you checked that any restatement still serves and what you could not verify. The report goes to whatever channel the caller provides; when the caller accepts only a findings list, that list *is* the report and satisfies Done. Review changes nothing, so it never has changed-block entries.