Turns the M137 inline recipes into a data-driven primitive. 3 items+3 hooks+1 skill
1. /goal convergence telemetry (G3)
user: /goal until findings.critical == 0
prompt/goal-tracker:
→ appends to .claude/state/goal-history.jsonl
→ { session_id, condition, started_at, started_token_estimate }
... 8 turns later ...
stop/goal-tracker:
→ matches open record by session_id
→ appends close: status=converged
turn_count=8 tokens_estimate=42100
Two hooks (UserPromptSubmit + Stop), one append-only JSONL ledger. The first read-consumer of /goal in OrchestKit.
2. Monitor surfaces convergence rate
statusline: last 10 /goal: 8✓ 1↻ 1✗ avg 6t
✓ = converged (model self-stopped, condition met)
↻ = spun (high turn count, no natural stop)
✗ = aborted (user Esc / Ctrl+F)
Aggregated from .claude/state/goal-history.jsonl
src/monitors/goal-convergence.json
Surfaced in the OrchestKit statusline so you see /goal health at-a-glance, not just per-run.
3. Cost circuit-breaker (G5)
SessionEnd:
Σ(this session's /goal turns) = 34 ⚠ over 30
Σ(this session's /goal tokens) = 287k ⚠ over 250k
→ write .claude/state/goal-budget-tripped.json
{ tripped_at, reason: "turns_cap", turns, tokens }
next session:
user: /goal until ...
prompt/goal-tracker (continueOnBlock: true):
⛔ previous session burned 34 turns / 287k tokens on /goal.
Cool-down active. Delete .claude/state/goal-budget-tripped.json
to override.
Soft cap — refuses NEW /goal, doesn't interrupt in-flight. Env: ORK_GOAL_MAX_TURNS_PER_SESSION (30), ORK_GOAL_MAX_TOKENS_PER_SESSION (250k).
4. prd-to-goal skill (G2)
$ /ork:prd-to-goal "fix login fails on email with +"
decomposed:
✓ failing test passes
✓ no regressions in suite
✓ commit + PR opened
output:
/goal until test_passes("test_login_email_plus")
AND ci.failures == 0
AND gh.pr.exists("fix/login-email-plus")
/goal abort-if turns > 15
OR tokens > 100000
OR no_progress_for_3_turns
3 worked examples in the skill body: bug fix, feature, refactor. Each shows acceptance criteria → boolean assertions over observable state.
5. closes "emit-only" gap
M137 (#1773): /goal recipes in 4 SKILL.md files
emit-only — nothing reads what happens
M139 #1784: PR template "Consumer" checkbox
cultural fix — surface the question
M140 Bundle B: /goal gets 3 consumers
G3 logs every run
G3 stop closes with status
G5 caps cumulative session cost
→ /goal is now load-bearing instead of decorative
First cohort that ships explicitly with the M139 Consumer answer wired in.
6. counts + verification
| Metric | Before | After |
| hooks (global) | 123 | 126 +3 |
| hooks (total) | 191 | 194 |
| async hooks | 81 | 83 |
| skills | 108 | 109 +1 |
✓ vitest: 8158 passed, 2 skipped (290 files) ·
✓ npm run build: clean ·
✓ validate-counts.sh: PASS