Skip to content
Back to skills

Grask

ASecurity

Serve the next pending grask probe — a multiple-choice question about code the developer recently shipped — using the native question UI. Use when the user types /grask.

  • 7 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
developmentgoshelldatabase

Works with

  • terminal

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add imkp1/grask --skill grask --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Grask?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Grask
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/imkp1-grask/badge)](https://www.skillsdirectory.com/skills/imkp1-grask)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: grask
description: Serve the next pending grask probe — a multiple-choice question about code the developer recently shipped — using the native question UI. Use when the user types /grask.
---

# Serving a grask probe

Grask quizzes the developer on mechanisms they shipped without fully
understanding. You are the delivery surface only: you serve the question and
relay the answer. You never grade, never guess, and never see the answer key.

## Hard rules

- Never open or query grask's database directly. The two subcommands below are
  the entire interface.
- Never speculate about which option is correct — not in text, not in labels,
  not in previews, not before the pick and not after it. Grading happens in
  `grask record`, and the only true thing you ever learn about the key is the
  `display` string it hands back. Relay that; never reason past it.
- One native question, one round. No confidence round, no follow-ups.

## Running grask

Do not assume a bare `grask` is on PATH — the plugin install deliberately does
not put one there. Call the shim the SessionStart hook writes, by its literal
path:

```
~/.claude/grask/grask
```

Keep it literal, and keep the arguments to the shapes below. grask ships a
`PreToolUse` hook that pre-approves exactly `serve` and `record` spelled this
way; anything else — a `${...}` expansion, an extra flag, a second command
joined on — falls through to a permission prompt, on every single call. On a
first `/grask` that is an opaque shell one-liner shoved in front of someone who
has not seen a probe yet.

Only if that path does not exist or will not run — a standalone install, or a
`GRASK_HOME` pointing elsewhere — fall back to the resolver, once:

```
GRASK="${GRASK_HOME:-$HOME/.claude/grask}/grask"; [ -x "$GRASK" ] || GRASK=grask; "$GRASK" <args>
```

Where a step below writes `grask …`, run `~/.claude/grask/grask …`, or the
resolved `"$GRASK" …` if you had to fall back.

## Flow

1. Run:

   ```
   ~/.claude/grask/grask serve --json
   ```

   `pending` is `true` when a probe is waiting and `null` when none is. Both
   arms carry the key, so branch on it rather than on which other fields
   happen to be present.

   If `pending` is null, the queue is empty: relay the `note` field from that
   same JSON and stop. Do not shorten it to "nothing pending" and do not
   generalise across the `reason` codes — `note` already says *why* it is empty,
   and the six reasons (`never`, `caught_up`, `capturing`, `unverified`,
   `expired`, `over_cap`) mean different things. `over_cap` especially: those
   probes are still waiting, they just do not fit this UI, so the note sends the
   developer to the terminal. `capturing` is the other one worth getting right: a
   session just ended and its question is still being written, so the queue is
   not empty but early — relay the note and do not suggest ending another
   session. `unverified` is the opposite case and must not be softened into
   "caught up": grask wrote a question, could not confirm its answer key, and
   threw it away rather than grade the developer against a key that might be
   wrong.
   If `grask` cannot be found or run either way, grask is not installed here —
   say so and stop rather than hunting for a checkout to `cd` into.

2. Ask ONE native question, preview-style (like plan-mode option picks), built
   entirely from the served JSON:

   - `question`: a neutral provenance line from `created_at` alone, then the
     full question text — e.g. `from 2026-07-21 · What would happen if …?`.
     The question text carries any file names it needs. The question must be
     readable inside the picker itself; do not rely on markdown printed before
     it. There is nothing else in the payload to add: `serve` deliberately does
     not send the probe's topic, because the topic states *why* the probe was
     raised and that rationale is the bridge to the graded answer. It arrives
     in step 3's `display`, once the answer is settled and it can no longer
     leak the mechanism under test.
   - `header`: a short constant chip — use `Probe`.
   - One option per stored option, in stored order. Every option needs all
     three fields below; `label` and `description` are required by the question
     tool's schema, and omitting `description` fails the call outright:
     - `label`: the letter plus the first few distinguishing words of the
       option (e.g. `a) dedup to a no-op`). Keep labels short; they are not the
       full text.
     - `description`: the next clause or so of the same stored option text,
       carrying on from where the label stopped, then cut off. It is a longer
       mechanical excerpt and nothing else — never a gloss, a summary, or a
       hint about whether the option holds.
     - `preview`: the full stored option text, verbatim and unabridged. The
       side-by-side preview pane is where the developer reads the option.
   - In exactly one option's preview (or the question text), append a footer
     note: "Other" accepts `skip`, or `wrong: <what's off>` if the question
     misreads what happened.

3. Record the result (through whichever path worked in step 1):
   - Picked letter L: `~/.claude/grask/grask record <probe_id> --pick L`
   - Skipped: `~/.claude/grask/grask record <probe_id> --skip`
   - Premise rejected: `~/.claude/grask/grask record <probe_id> --wrong
     --objection "<their words>"` (omit `--objection` if they gave no reason).

   Print the `display` field verbatim, as markdown. It is already the whole
   result — verdict, the correct option where there is one, the explanation,
   and the withheld provenance, now that the answer is settled and the topic can
   no longer leak it. Do not restate it, summarise it, add a verdict of your
   own, or comment on how the answer went. You did not grade it and you still
   have not seen the key except in that string.

   If the command prints `{"error": ...}`, show the error and stop — do not
   retry with different flags.

4. In that **same reply**, without waiting for a turn of your own, read the
   `next` field of the `record` output you just used. Do NOT run `serve` again
   — `next` already holds exactly what `serve` would have printed.

   Everything in a `/grask` round that is not the developer reading or tapping
   is you taking a turn, and a turn is seconds against 60ms of actual work.
   Printing the result and offering the next probe are one reply, not two.

   - `next.pending` is null: relay its `note`, exactly as in step 1, and end.
   - Otherwise a probe is waiting. Ask a native yes/no question — `Serve the
     next probe?` with options `Yes` and `Stop` — rather than a prose offer, so
     the continue step matches the probe's own picker affordance and per-probe
     consent stays an explicit tap. Do not auto-serve, and do not show any part
     of the next probe inside that yes/no question. On `Yes`, go to step 2
     building the picker from `next` (it is the served payload — no further
     command needed); on `Stop`, end.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…