Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/planning/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "planning",
"version": "0.26.3",
"version": "0.27.0",
"userConfig": {
"use_ask_user_question": {
"type": "boolean",
Expand Down
29 changes: 29 additions & 0 deletions plugins/planning/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,35 @@
All notable changes to the `planning` plugin are documented here. Format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this plugin uses semantic versioning.

## [0.27.0]

### Added

- **`draft-goal-condition` drafts conditions for goals no metric can measure (#1652).** Step 2
assumed a checkable condition already existed, so an intent with no honest metric either got a
manufactured one or nothing. A new branch builds the condition from three moves instead — a
structural constraint, enumerated required contents, and a self-verification sub-step that
requires the verifying work rather than its verdict. The branch states why the third move must be
worded that way: the evaluator calls no tools, so it can only credit verification Claude performed
in the transcript, and an assertion that checking happened is indistinguishable from the checking.
Co-drafting a still-vague intent points at `/planning:interview` rather than restating it.
- **`draft-goal-condition`'s Step 0 router gains the dynamic-workflows lever (#1654).** The router
offered `/loop`, routines and `/schedule`, a Stop hook, and a one-shot prompt as alternatives to
`/goal`, leaving work that needs more agents than one conversation can coordinate with nowhere to
route. Two caveats ship with the row, each because it turns a plausible recommendation into a dead
one. The `ultracode` keyword runs one task as a workflow, changes nothing else, and is honored
only from a human-typed prompt, whereas `/effort ultracode` is the standing session setting
(`xhigh` effort plus per-task workflow planning) and needs a model offering `xhigh` — so the two
are not interchangeable. And the `Workflow` tool is filtered out of every non-fork subagent, so a
lever whose work lands in dispatched non-fork subagents — the loop lanes' item-workers, for
instance — cannot be this one however well it otherwise fits. The row also carries the
availability fact that keeps it from being skipped as
preview-gated: all paid plans, switched on from the `/config` **Dynamic workflows** row on Pro.
Alone among the router's rows, this one is not exclusive of `/goal`: a workflow decides how a
single task fans out and the goal decides when to stop turning, so it routes away from drafting
only when the intent wants the fan-out and no across-turn completion condition — an intent
wanting both drafts the condition here and runs the workflow alongside it.

## [0.26.3]

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion plugins/planning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ where artifacts land in the consuming repo.
| `/planning:interview` | Engineering contract | Locks a task contract (goal, constraints, acceptance criteria, named assumptions) into a PLAN.md Brief — synthesizing when intent is clear, running frontier-rounds Q&A when it isn't, or interviewing relentlessly on request. |
| `/planning:audit-answers` | Contract validation | Independent adversarial validation of a completed `/planning:interview`'s answers — over any filled ledger, hand-answered or auto-accepted: fresh-context validators re-examine each answer (rationale withheld) and return a per-answer confirmed / challenged / reclassified verdict, so only the challenged or reclassified answers, and every user-reserved decision, return as real human questions (open branches are accept-filled first, holding the never-auto floor). |
| `/planning:questionnaire` | Person hand-off | Turns a decision another person holds into a discovery questionnaire delivered async — interviews the user about the send only (recipient, what's needed back), writes the document to the topic's memory slice, and leaves delivery out-of-band. |
| `/planning:draft-goal-condition` | Goal authoring | Crafts a paste-ready `/goal` completion condition from a stated intent — reads the current official `/goal` docs live for the condition shape and character limit (nothing hardcoded), drafts a transcript-demonstrable condition, and proves it fits the limit with a deterministic character counter instead of model guesswork; a lever-fit gate routes interval-shaped or cloud/sessionless work elsewhere. Standalone. |
| `/planning:draft-goal-condition` | Goal authoring | Crafts a paste-ready `/goal` completion condition from a stated intent — reads the current official `/goal` docs live for the condition shape and character limit (nothing hardcoded), drafts a transcript-demonstrable condition, and proves it fits the limit with a deterministic character counter instead of model guesswork, with a branch that builds a checkable condition for goals no metric can measure; a lever-fit gate routes interval-shaped, cloud/sessionless, and orchestration-only work elsewhere. Standalone. |
| `/planning:design` | Design space | Explores types, contracts, module boundaries, and package topology through collaborative discussion rounds, producing capability-matrix / type-inventory / design-threads / topology artifacts; its `handoff` action delegates to `/planning:design-handoff`. |
| `/planning:design-handoff` | Design→plan gate | Gates a finished design for `/planning:plan` — a binary check that every `design-threads.md` thread is RESOLVED, directional, or TAGGED-DEFERRED — then packages the plan-ready summary and resume prompt, or FAILs and routes back to `/planning:design`. |
| `/planning:devils-advocate` | Adversarial review | Stress-tests plans via assumption extraction, evidence checks, failure scenarios, and operational-gotcha sweeps — every finding evidence-backed, never generic warnings. An `incumbent` mode turns the same lens on the status quo: an Alternatives Sweep that stress-tests keeping an incumbent tool/approach against alternatives (native > official > vetted ladder, coupling priced, KEEP / MIGRATE / RESEARCH verdict), exploring the incumbent first-hand in a fresh sub-agent. |
Expand Down
28 changes: 24 additions & 4 deletions plugins/planning/skills/draft-goal-condition/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: draft-goal-condition
description: "Routes the repetition-lever choice across /goal, /loop, routines and /schedule, a Stop hook, and a one-shot prompt, then crafts a paste-ready /goal completion condition when /goal is the fit — the autonomous-goal / keep-working-toward-a-goal field Claude Code evaluates after every turn. Reads the current official docs live for the condition shape and character limit (never hardcodes either), drafts a transcript-demonstrable condition, and proves it fits the limit with a deterministic character counter instead of model guesswork. Use when: 'which loop should I use', '/goal or /loop', 'should this be a routine', 'pick the right autonomy lever', 'what kind of loop is this', 'craft a /goal', 'write a goal condition', 'set up an autonomous goal', 'make Claude keep working until X', 'my /goal is too long / over the limit', 'turn this into a completion condition'."
description: "Routes the repetition-lever choice across /goal, /loop, routines and /schedule, a dynamic workflow, a Stop hook, and a one-shot prompt, then crafts a paste-ready /goal completion condition when /goal is the fit — the autonomous-goal / keep-working-toward-a-goal field Claude Code evaluates after every turn. Reads the current official docs live for the condition shape and character limit (never hardcodes either), drafts a transcript-demonstrable condition, and proves it fits the limit with a deterministic character counter instead of model guesswork, including a branch for goals no metric can measure. Use when: 'which loop should I use', '/goal or /loop', 'should this be a routine', 'should this be a workflow', 'pick the right autonomy lever', 'what kind of loop is this', 'craft a /goal', 'write a goal condition', 'set up an autonomous goal', 'make Claude keep working until X', 'my goal is not measurable', 'my /goal is too long / over the limit', 'turn this into a completion condition'."
argument-hint: "[intent]"
user-invocable: true
disable-model-invocation: false
Expand All @@ -24,11 +24,17 @@ The `/goal` contract — its condition shape and its character limit — can cha
`/goal` starts the next turn when the previous one finishes and stops when a fresh evaluator model confirms a completion condition holds. Before authoring, confirm that fits the intent. If it does not, route instead of drafting:

- **Interval-driven** ("every 5 minutes", "poll until") → `/loop` (a time interval starts each turn), not `/goal`.
- **Cloud / sessionless / scheduled** ("nightly", "each morning", runs with no session open) → routines / `/schedule`.
- **Cloud / sessionless / scheduled** ("nightly", "each morning", runs with no session open) → routines / `/schedule` (labelled research preview at the time of writing — check before recommending it).
- **Custom per-turn logic across all sessions** (deterministic script check, settings-scoped) → a prompt-based Stop hook.
- **More agents than one conversation can coordinate** (or the orchestration is worth codifying as a rerunnable script) → a dynamic workflow. Unlike the rows above, this one is not exclusive of `/goal`: a workflow decides how a single task fans out, `/goal` decides when to stop turning, and the two compose — the goal sets the hard completion requirement while the workflow performs the parallel work. Route away from drafting only when the intent wants the fan-out and *no* across-turn completion condition; when it wants both, draft the condition here and say the workflow rides alongside it.
- **One-shot** (a single prompt with no across-turn continuation) → just prompt; no goal.

Confirm the current comparison semantics against the live docs (below) rather than this summary — the routing table can drift. Only proceed when the intent genuinely wants "keep working until this condition is met."
Two caveats belong to the workflow row, because each turns a plausible recommendation into a dead one:

- **Route to the right ultracode form.** The `ultracode` keyword in a prompt runs **one** task as a workflow and changes nothing else — not the session's effort level — and is honored only from a prompt a human types (not `-p`, not an Agent SDK prompt that never stamps its origin as human input, not a scheduled-task prompt, not a webhook or relayed PR comment); asking in plain words — `use a workflow` — is the same opt-in. `/effort ultracode` is the separate standing setting: `xhigh` effort plus a workflow planned for each substantive task, for the rest of the session. Availability differs too — the workflow lever itself reaches all paid plans (on Pro it is switched on from the **Dynamic workflows** row in `/config`), while the standing setting needs a model that offers `xhigh` effort.
- **The lever is unreachable from an ordinary subagent.** The `Workflow` tool is filtered out of every non-fork subagent (`/discovery:research-deep` (if installed) exists because of this and documents it; the filter itself is on `https://code.claude.com/docs/en/sub-agents`). So a lever whose work lands in dispatched non-fork subagents — the loop lanes' dispatched workers, for instance — cannot be the workflow row however well it otherwise fits; recommend it only where the orchestrating context is the main thread or a fork.

Confirm the current comparison semantics against the live docs (below) rather than this summary — the routing table can drift, and the workflow row's availability and keyword specifics have each moved within recent releases. Only proceed when the intent genuinely wants "keep working until this condition is met."

## Step 1 — Read the live contract

Expand All @@ -37,7 +43,7 @@ Fetch the current official `/goal` documentation and extract, from the page itse
1. the **effective-condition shape** it prescribes, and
2. the **maximum character limit** for a condition.

Primary source: `https://code.claude.com/docs/en/goal`. Cross-check the scheduling comparison via the pages that doc links (`/en/scheduled-tasks`, routines) if Step 0 routing is in question.
Primary source: `https://code.claude.com/docs/en/goal`. If Step 0 routing is in question, cross-check the scheduling comparison via the pages that doc links (`/en/scheduled-tasks`, routines) and the workflow row against `https://code.claude.com/docs/en/workflows`.

**Doc-fetch failure is not silent and never guessed.** If the page cannot be fetched or its structure has shifted so the limit or shape cannot be located, stop and tell the user exactly that, citing the URL. Do not fall back to a remembered number or shape — a stale limit or condition shape baked in here is precisely the drift this skill exists to avoid. Offer the user two ways forward: paste the current condition shape and character limit from that page — the shape drives the Step 2 draft, the limit drives the Step 3 counter — or defer until the docs are reachable. Never finalize a draft on a shape or limit that was not sourced live.

Expand All @@ -49,6 +55,20 @@ Structure the draft to the shape Step 1 read off the live page — that page is

Avoid conditions the transcript cannot show (subjective quality, external state Claude never surfaces).

### When the outcome is not quantifiable

Most goals are not `npm test`. When the intent has no honest metric, do **not** manufacture one — a made-up number aims the evaluator at the wrong thing and lets a run pass on the wrong evidence. Three moves give the shape Step 1 read off the live page something demonstrable to be built out of; they feed that shape rather than replace it:

1. **A structural constraint** — something countable about the artifact: a length, a section count, one entry per input item.
2. **Enumerated required contents** — name the parts that must be present, so the evaluator decides "is it there" rather than "is it good".
3. **A self-verification sub-step that is itself checkable** — require the verifying *work*, not its verdict. "…a report where you have verified every citation by fetching it and confirming the page supports the claim" is checkable; "…a report whose citations are correct" is not.

Move 3 is what makes this branch work, and the no-tools constraint at the top of this step is why it has to be worded that way. The judgment is not self-review — it is delegated to a fresh-context evaluator model that receives only the condition and the conversation so far, and calls nothing — so the sub-step is credited only by verification Claude **performed in the transcript**. A claim that the checking happened reads identically to the checking having happened. Word it so the doing leaves visible output — the fetches, the diffs, the command runs — and the evaluator judges evidence rather than a promise.

Subjective quality still stays out of the condition. It re-enters only as whatever moves 1–3 made observable.

If the intent itself is still too vague to name a structure or a content list, settle it with `/planning:interview` before drafting — that skill owns the questioning; this one owns the condition.

## Step 3 — Mechanical length check

Validate the draft's character count against the **live limit from Step 1** with the deterministic counter (no model estimation). Write the draft to a temp file and pass `--file` — this is the robust path, immune to a condition that contains a single quote, backtick, or `$` that would otherwise mangle a piped string:
Expand Down