Checking User-Thrown Gates
Why this skill is separate from executing-plans
User-gate enforcement is an opt-in flow. When the opt-in hook is not registered, executing-plans runs unchanged — no extra checks, no extra context, no extra questions. When the hook IS registered, it routes user-gate tasks through this skill. Keeping the decision logic in a separate skill means:
- Users who don't want the flow get zero friction.
- Users who do want it get a focused, scoped handler.
executing-plans stays short and readable.
When to invoke
Any one of:
- You are about to start a task whose
json:metadata has "userGate": true or whose tags contains "user-gate" AND the opt-in hook is active (see the README for how to detect this — if you were invoked via /gate-check, the hook is active by definition).
- A hook fired stderr telling you to run
/gate-check <task-id>.
- The user manually ran
/gate-check <task-id>.
If none of these apply, return to executing-plans without running this skill.
Announce at start: "I'm using the checking-gates skill to verify Task N's acceptance criteria."
The three-step process
Step 1 — Load and classify
TaskGet <task-id> — read the full description.
- Parse the
json:metadata fence.
- Classify:
requiresUserSpecification: true → go to Step 2 path A.
- Concrete
verifyCommand + every acceptanceCriteria names an observable (sensor, HTTP status, file, log line, entity) → go to Step 2 path B.
- Vague criteria ("it works", "is fine", "as expected", "properly") or missing
verifyCommand → go to Step 2 path A.
Step 2 — Route
Path A — HOW is ambiguous. Invoke specifying-gates (or tell the user to run /specify-gate <task-id>). Stop. Let that skill lock down the mechanics. When it returns, re-enter this skill from Step 1.
Path B — HOW is clear. Continue to Step 3.
Step 3 — Execute and post evidence
Run the verifyCommand (or dispatch the subagent with subagentBrief). Capture exact output.
Map each acceptanceCriteria entry to an observable in the output.
Post one block of text back to the user, using EXACTLY this format (the sibling hooks key off the AC: + PROVEN BY markers):
Gate: <task subject>
AC: <criterion 1> — PROVEN BY <command or excerpt of output>
AC: <criterion 2> — PROVEN BY <...>
...
If every criterion passed → TaskUpdate status=completed.
If any criterion failed → look up failurePolicy:
"stop-plan" → leave the task in_progress, surface the failure to the user, stop.
"reopen-continue" → leave the task in_progress, move to the next unblocked task.
"log-continue" → post the failure inline, mark completed anyway, continue.
Do-I-know-HOW self-check — the short version
A criterion has a clear HOW when all three hold:
- Observable named — sensor entity, HTTP endpoint, file path, log pattern, entity ID. Not "state", not "result".
- Capture method named — the command, API call, subagent, or direct read that produces the observable.
- Pass/fail rule named — an exact value, regex, or threshold. Not "reasonable" or "correct".
If any of the three is missing for any criterion, HOW is NOT clear → Path A.
Err on the side of Path A. Inventing a HOW silently is the exact failure this flow exists to prevent.
What NOT to do
- Do NOT modify executing-plans' behavior from inside this skill. This skill is a leaf — it returns control when done.
- Do NOT invoke
EnterPlanMode or ExitPlanMode.
- Do NOT substitute a cheaper verification for the one specified. If you think the spec is wrong, reopen via
/specify-gate — don't walk around it.
- This prohibition also covers re-asking a settled approach absent a changed condition — not just substituting inline. Surfacing "should we do the lesser check instead" for a verification the plan already fixed is walking around the gate unless a material condition changed (different fixture/branch, new blocker, broken plan assumption).
- Do NOT close the task if any criterion lacks concrete evidence. "Looks fine" is not evidence.
Integration
- Invoked from: the PostToolUse / PreToolUse user-gate hook; or
/gate-check slash command.
- May hand off to:
specifying-gates (Path A).
- Returns to:
executing-plans (or wherever it was invoked from) after TaskUpdate.
- References:
skills/shared/task-format-reference.md for metadata schema.
1---2name: checking-gates3description: Use when picking up a user-gate task OR when a hook demands re-validation. Runs the "do I know HOW?" self-check; if the HOW is clear, executes the verification and posts evidence; if not, hands off to specifying-gates. Kept deliberately separate from executing-plans so that without the opt-in hook, the main flow stays untouched.4---56# Checking User-Thrown Gates78## Why this skill is separate from executing-plans910User-gate enforcement is an **opt-in flow**. When the opt-in hook is not registered, executing-plans runs unchanged — no extra checks, no extra context, no extra questions. When the hook IS registered, it routes user-gate tasks through this skill. Keeping the decision logic in a separate skill means:1112- Users who don't want the flow get zero friction.13- Users who do want it get a focused, scoped handler.14- `executing-plans` stays short and readable.1516## When to invoke1718Any one of:19201. You are about to start a task whose `json:metadata` has `"userGate": true` or whose `tags` contains `"user-gate"` AND the opt-in hook is active (see the README for how to detect this — if you were invoked via `/gate-check`, the hook is active by definition).212. A hook fired stderr telling you to run `/gate-check <task-id>`.223. The user manually ran `/gate-check <task-id>`.2324If none of these apply, return to executing-plans without running this skill.2526**Announce at start:** "I'm using the checking-gates skill to verify Task N's acceptance criteria."2728## The three-step process2930### Step 1 — Load and classify31321. `TaskGet <task-id>` — read the full description.332. Parse the `json:metadata` fence.343. Classify:35 - `requiresUserSpecification: true` → go to Step 2 path A.36 - Concrete `verifyCommand` + every `acceptanceCriteria` names an observable (sensor, HTTP status, file, log line, entity) → go to Step 2 path B.37 - Vague criteria ("it works", "is fine", "as expected", "properly") or missing `verifyCommand` → go to Step 2 path A.3839### Step 2 — Route4041**Path A — HOW is ambiguous.** Invoke `specifying-gates` (or tell the user to run `/specify-gate <task-id>`). Stop. Let that skill lock down the mechanics. When it returns, re-enter this skill from Step 1.4243**Path B — HOW is clear.** Continue to Step 3.4445### Step 3 — Execute and post evidence46471. Run the `verifyCommand` (or dispatch the subagent with `subagentBrief`). Capture exact output.482. Map each `acceptanceCriteria` entry to an observable in the output.493. Post one block of text back to the user, using EXACTLY this format (the sibling hooks key off the `AC:` + `PROVEN BY` markers):5051 ```52 Gate: <task subject>53 AC: <criterion 1> — PROVEN BY <command or excerpt of output>54 AC: <criterion 2> — PROVEN BY <...>55 ...56 ```57584. If every criterion passed → `TaskUpdate status=completed`.595. If any criterion failed → look up `failurePolicy`:60 - `"stop-plan"` → leave the task `in_progress`, surface the failure to the user, stop.61 - `"reopen-continue"` → leave the task `in_progress`, move to the next unblocked task.62 - `"log-continue"` → post the failure inline, mark completed anyway, continue.6364## Do-I-know-HOW self-check — the short version6566A criterion has a clear HOW when all three hold:67681. **Observable named** — sensor entity, HTTP endpoint, file path, log pattern, entity ID. Not "state", not "result".692. **Capture method named** — the command, API call, subagent, or direct read that produces the observable.703. **Pass/fail rule named** — an exact value, regex, or threshold. Not "reasonable" or "correct".7172If any of the three is missing for any criterion, HOW is NOT clear → Path A.7374**Err on the side of Path A.** Inventing a HOW silently is the exact failure this flow exists to prevent.7576## What NOT to do7778- Do NOT modify executing-plans' behavior from inside this skill. This skill is a leaf — it returns control when done.79- Do NOT invoke `EnterPlanMode` or `ExitPlanMode`.80- Do NOT substitute a cheaper verification for the one specified. If you think the spec is wrong, reopen via `/specify-gate` — don't walk around it.81- This prohibition also covers *re-asking* a settled approach absent a changed condition — not just substituting inline. Surfacing "should we do the lesser check instead" for a verification the plan already fixed is walking around the gate unless a material condition changed (different fixture/branch, new blocker, broken plan assumption).82- Do NOT close the task if any criterion lacks concrete evidence. "Looks fine" is not evidence.8384## Integration8586- **Invoked from:** the PostToolUse / PreToolUse user-gate hook; or `/gate-check` slash command.87- **May hand off to:** `specifying-gates` (Path A).88- **Returns to:** `executing-plans` (or wherever it was invoked from) after TaskUpdate.89- **References:** `skills/shared/task-format-reference.md` for metadata schema.