Use when a request is vague, broad or ad hoc and has no Jira ticket. "figure out X and do it", "sort out this mess", "look into Y and fix whatever's wrong". Turns the prompt into a Task/Scope/Constraints/Outcome brief, gets approval once, then holds the session to the Outcome with a Stop hook until the evidence exists. Use work-on when a ticket exists.
Resources
1Install
npx skillscat add yunidbauza/the-hive/goal-on Install via the SkillsCat registry.
Goal on
A vague prompt cannot be verified, so it cannot be finished. This skill fixes
that in two moves: it interrogates the prompt into a brief with a checkable
Outcome, then holds the session to that Outcome with a Stop hook that refuses
to end the turn until the evidence exists.
Phase 1 is interactive. Phase 2 is not. Once Phase 2 starts the hook
blocks turn-end, so every question is asked in Phase 1.
The brief
~/.hive/goals/<session-id>.md, named exactly that, with the id repeated in
the header's session: field. The verifier tries the filename first and falls
back to the header; a brief it cannot find reads as "no goal here".
---
status: PENDING-APPROVAL # PENDING-APPROVAL | ACTIVE | NEEDS-DECISION | DONE | FAILED | CLEARED
route: code # artifact | code
turns_used: 0
turn_budget: 8
created: 2026-09-11T14:30:00Z
session: <session id>
last_verified: # written by the verifier, never by you
done_at: # written by the verifier with DONE, never by you
branch: goal/<slug> # code route
workspace: current # code route: current | worktree
repo: /abs/path # code route, REQUIRED when the work is not in this cwd
worktree: /abs/path # code route, when workspace is worktree
plan: /abs/path # code route: the plan file; every step must be ticked for DONE
---
## Task
One sentence. The objective, not the symptom.
## Scope
Files, migrations, dependencies, sibling repos. From the code, not the prompt.
## Constraints
What must not change; what must be preserved.
## Outcome
- [ ] Checkable item, naming the command or artifact that proves it.
## Stop Rules
Stop and report if verification fails after 8 turns, or on an unresolvable conflict.
## Verification evidence
(none yet)A line that is only a parenthetical is a placeholder to the verifier, never
evidence. Replace it with command output as work proceeds.
turn_budget stays at 8: CLAUDE_CODE_STOP_HOOK_BLOCK_CAP defaults to 8
consecutive blocks and the harness abandons the loop above it.
Phase 1 (interactive)
- Gates. Hooks permitted (
disableAllHooks,allowManagedHooksOnlynot
set),nodeon PATH. Say "the hooks are configured", never "the goal is
enforced": these checks prove a hook may run, not that one did. - Task, one sentence, the objective. Several readings → a question.
- Scope, from looking at the code: paths, not categories.
- Constraints and Outcome. Every Outcome item is checkable by someone
else: the command, the artifact. - One batched
AskUserQuestion, four questions at most, recommended
option first. The last chance; an unasked question is a guess that burns
budget. - Route.
artifactfor research, documents, Jira updates, throwaway
scripts;codefor changes meant to merge. Mixed iscode. Code decidesworkspace: current(an interactive foreground session) orworktree
(background,claude agents, or an isolation guard; when unsure,worktree). - Write the brief with
status: PENDING-APPROVAL, present the five
sections, END TURN.PENDING-APPROVALis what lets the gate exist: anACTIVEbrief with an unmet Outcome is what "keep working" looks like to
the verifier.
Phase 2 (autonomous)
First act: flip to ACTIVE and confirm last_verified is present. Phase
1 ended on a turn boundary, so the floor has run once and stamped it. Missing
means nothing is enforcing: say so plainly, then continue in degraded mode,
holding yourself to the brief and setting the terminal status yourself at the
end. Check the filename first; it is the one cause you can fix.
Record evidence as you go under ## Verification evidence. Absent evidence is
unmet.
Route artifact. Do the work, verify it (open the file, run the script,
read the ticket back), append the evidence, tick the items. The verifier
writes DONE.
Route code.
git fetch origin.workspace: currentneeds a clean tree; dirty →status: NEEDS-DECISION, ask.hive:worktree(or, forcurrent,git checkout -b goal/<slug> origin/<default>). Recordbranch:,repo:andworktree:as absolute
paths: the verifier's PR check runsghfromworktree:orrepo:.- Plan, always: the plan file is what the Hive's plan panel reads, and a
terminal session has no task tools to fall back on. Big enough to plan?hive:planstraight from the brief (no brainstorm: the brief is the
design, and every question was asked in Phase 1), thenhive:execute
inline. Otherwise write a short one yourself, a## Task N: <name>per
Outcome item with its- [ ]steps, and tick each step as it lands.
Either way it goes in.hive/plans/YYYY-MM-DD-goal-<slug>.mdunder the
directory you are working in (the worktree, when there is one): the Hive
reads a plan file only from under the session's own cwd. Record its
absolute path as the brief'splan:: the verifier holdsDONEuntil
every step in it is ticked, so a finished goal never leaves the panel at 0/N. hive:verify: the repository's gates, a browser drive for any UI surface.- Append the output. Push.
gh pr create --draft. Record the PR URL in
the evidence and tick both files now: the brief's Outcome items and
any plan step still open.ledger_askends the turn, so anything written
after it waits for the next one, and the Stop hook would block on the
unticked boxes in between. Do not writestatus: DONEyourself. The
verifier writes it once the boxes in both files, the evidence and a real
PR onbranch:agree. mcp__hive__agentslistsshipper:ledger_ask to: shipperwith the
intake shape fromship,reply-to: $HIVE_SESSION_ID(this session'ssess-…party name, never the brief'ssession:UUID, which no party
answers to),ticket: none. It
does not: say the draft PR is ready and stop; the tail is the person's.
The goal is met at draft PR raised, plus the shipper woken when there is one.
A goal/<slug> branch carries no key, and the shipper's Jira steps skip;
that is correct.
The ledger receipt
scripts/verify-goal.mjs posts one event entry to the Hive on every status
it writes (ACTIVE turns, DONE, FAILED), through $HIVE_RECEIVER_URL
with the session's own token, meta.goal naming the session andmeta.status, meta.turns_used, meta.turn_budget. The overmind sees the
goal move without opening the file. The receipt never blocks: a receiver that
is not there costs nothing.
Terminal states
| Status | When | Then |
|---|---|---|
PENDING-APPROVAL |
Phase 1 wrote the brief | verifier releases; flip to ACTIVE on approval |
ACTIVE |
Phase 2 | verifier enforces |
DONE |
verifier confirmed the Outcome | report what was produced |
FAILED |
budget spent, or an unresolvable conflict | report what was achieved and the gap |
NEEDS-DECISION |
a decision blocks progress | verifier releases; ask, set ACTIVE, continue |
CLEARED |
the goal is abandoned | hive:goal-on clear |
Clearing a goal
hive:goal-on clear sets status: CLEARED on this session's brief and
reports it; the same happens when the person says the goal is off. The hook
stays registered for the rest of the session and short-circuits on the
terminal status, one cheap read per turn end. A new session starts clean.
Red flags
ACTIVEbefore approval. A question in Phase 2. An Outcome nobody else
could check. Done claimed without evidence appended.DONEwritten by hand.- The brief ticked and the plan not: the panel shows 0/N on finished work.
plan:omitted from the header is the same miss, with nothing to catch it. repo:omitted on a code-route goal outside this cwd: the PR check runs in
the wrong repository and blocks every turn until the budget is spent.- A brief under any other name than
<session-id>.md. turn_budgetabove 8 without raising the harness cap.- Waiting for the merge. The shipper owns it.
- Re-invoking
goal-onwhile a goal is active: each invocation registers
another verifier. Amend the brief instead.