Let Him Grill
Extend grilling and domain-modeling; do not modify them. Preserve their
evidence-first behavior and documentation rules while batching decisions that do
not need human judgment.
Mode
Honor an explicitly requested mode. Otherwise choose compact for short or
linear discussions and visual when decisions branch, depend on one another, or
the user wants to revisit them. State the selected mode once.
compact/kompakt: Work text-first. Do not create state for a single linear decision. At the human gate, show the resolved path, recommendation, 2–4 real options, and material consequences as concise text. Create state or render a tree only when branching, revisiting, or the user requests it.visual/visuell: Preserve the full current behavior. Create.grill/decisions.json, persist every decision, render the interactive tree at each human gate and after every change, and allow earlier choices to invalidate their dependent subtree.
The decision logic and human-gate rules are identical in both modes. Users may
switch modes at any time. Switching to visual materializes known decisions;
switching to compact keeps existing state but stops automatic rendering.
Backend
Compact mode needs no runtime. For visual mode, honor an explicitly requested
backend. Otherwise run python3 --version once and select:
python: Usedecision_state.pywhen Python 3 is available.native: Use Codex file and visualization tools when Python 3 is unavailable.
State the selection once as Visual mode · Python backend or
Visual mode · Native Codex fallback. If the user explicitly requires Python
and it is unavailable, stop instead of silently changing backends. Never install
Python or another runtime without permission.
Workflow
-
Read relevant project docs, code,
CONTEXT.md, and ADRs. Resolve discoverable facts with tools instead of asking. -
Select the mode and backend. In
visual, create.grill/decisions.jsonwith the selected backend if no active state exists. Incompact, keep the path in the conversation until persistence is useful. -
Build the next decision and 2–4 real options. Assess every option as
recommended,solid-alternative,situational,not-recommended, orexcluded. Record a short reason, confidence, reversibility, effort, risk, downstream impact, and when the option becomes preferable. -
Classify it:
auto: one option follows from evidence, is low-risk, and is cheap to reverse. Choose it and continue.review: a strong reversible default exists, but preference may matter. Choose it provisionally and continue.human: choice changes goals, architecture, security, privacy, external cost, provider lock-in, operations, or another hard-to-reverse outcome. Stop before choosing.derived: choice is forced by an earlier confirmed decision.blocked: required evidence is missing and guessing could materially change the result. Stop and request only that evidence. Usehumanwhen similarly strong options carry a meaningful trade-off.
-
Continue across
auto,review, andderivednodes until reachinghuman,blocked, or shared understanding. Forauto, allow the script to choose only when exactly onerecommendedoption is low-risk and reversible. Invisual, add each decision withdecision_state.py addwith the Python backend or update the state directly with the native backend. -
In
compact, present the human gate as concise text. Invisual, render the state into the exact visualization directory assigned to the current Codex task withdecision_state.py render. Never reuse a visualization directory from another task or infer it from an earlier artifact. Confirm the rendered file exists in the current task's directory, then embed it using:::codex-inline-vis{file="<rendered-filename>.html"} -
When a follow-up applies an earlier persisted option, use
decision_state.py chooseor the native invalidation procedure below. It invalidates all transitive dependants. Re-research and rebuild only those nodes; render again only invisual. -
Update domain terminology inline through
domain-modeling. Create an ADR only when that skill's three ADR conditions all hold. -
Do not implement the discussed plan until the user confirms shared understanding.
Human gate
Stop when any answer is yes:
- Would changing this later require migration, broad rework, or coordination?
- Does it change product intent, audience, scope, or user-visible trade-offs?
- Does it authorize spend, external actions, data exposure, or security risk?
- Are multiple options reasonable because of personal or business preference?
- Is evidence missing and guessing could materially change the result?
Confidence alone never authorizes an automatic choice. Risk and reversibility
take priority.
Never select an excluded option. Reassess it only after its conflicting
requirement changes.
Commands
Run the bundled script with Python 3 and no third-party dependencies. It needs
no virtual environment, package install, or lockfile. Check python3 --version
before the first command. If Python 3 is unavailable, do not install it without
permission; update .grill/decisions.json with file tools, apply the same
transitive invalidation rules, and populate the bundled visual template.
Resolve <skill-dir> to the directory containing this SKILL.md.
python3 <skill-dir>/scripts/decision_state.py init \
.grill/decisions.json --title "Decision title"
python3 <skill-dir>/scripts/decision_state.py add \
.grill/decisions.json --id storage --question "How store state?" \
--type auto \
--option local-json="Local JSON::Portable and easy to inspect" \
--option sqlite="SQLite::Useful for larger queryable state" \
--assessment 'local-json={"triage":"recommended","reason":"No service required","confidence":0.94,"reversible":true,"effort":"low","risk":"low","impact":"Keeps state local","preferredWhen":"One workspace owns the plan"}' \
--assessment 'sqlite={"triage":"situational","reason":"Adds query support","confidence":0.86,"reversible":true,"effort":"medium","risk":"low","impact":"Adds schema maintenance","preferredWhen":"The tree needs complex queries"}'
python3 <skill-dir>/scripts/decision_state.py choose \
.grill/decisions.json storage sqlite --actor human
python3 <skill-dir>/scripts/decision_state.py render \
.grill/decisions.json /absolute/thread-visualization/decision-tree.html
python3 <skill-dir>/scripts/decision_state.py export \
.grill/decisions.json docs/decision-path.md
Use --depends-on <id> once per dependency. Use --replace when rebuilding an
invalidated node with refreshed options or reasoning.
Native backend
Do not call python3, Node.js, a shell renderer, or another runtime. Use Codex
file tools for all operations:
- Create version 2 state as
{"version":2,"title":"...","nodes":[]}. Use only these exact schema values; never invent synonyms:type:auto,review,human,derived, orblockedstatus:recommended,confirmed,pending,derived, orinvalidatedactor:ai,human, ornull- option assessment
status: absent, orinvalidated
- Before every write, read the complete current state and validate those exact
value sets, unique node IDs, known dependencies, valid option IDs, one
assessment per option, and no selected
excludedor invalidated option. Useexamples/decisions.jsonas the schema example. Stop instead of writing when any field uses an unknown value. - For an
autonode, select only when exactly one option isrecommended, low-risk, and reversible. Otherwise promote the node to a human gate. - When a choice changes, compute the full transitive descendant set from
dependsOn. Set every descendant'schoiceandactortonull, status toinvalidated, reason toEarlier dependency changed; reassessment required., confidence tonull, and every option assessment status toinvalidated. - Apply the complete JSON update in one file edit. Never partially update state.
- Read
<skill-dir>/assets/decision-tree.htmlcompletely. It is the canonical visual source; never recreate or restyle its HTML, CSS, or JavaScript. - Serialize the complete validated state as JSON and escape every
<as\u003c. Replace the template's single__LET_HIM_GRILL_STATE_JSON__placeholder with that JSON object. - Encode the absolute state-file path as a JSON string, escape every
<as\u003c, and replace the single__LET_HIM_GRILL_STATE_PATH_JSON__placeholder with that string. - Write the resulting self-contained fragment to the exact visualization
directory assigned to the current Codex task. Never reuse a directory from
another task or an earlier artifact. Confirm neither
__LET_HIM_GRILL_placeholder remains; otherwise stop instead of presenting a broken view. - Confirm the HTML file exists in the current task's visualization directory,
embed it with
::codex-inline-vis{file="<rendered-filename>.html"}, and inspect the result before presenting it. If inline visualization tools are unavailable, show the same decision content as compact text.
State rules
- Treat
.grill/decisions.jsonas source of truth; the visualization is a view. - Never silently overwrite a confirmed human choice.
- Reusing an invalidated recommendation requires fresh evidence.
- Replace invalidated nodes with fresh option assessments; do not reuse stale option triage.
- Keep reasons factual and short. Record uncertainty explicitly.
- In
visual, render a new visualization after every persisted change; old responses remain historical snapshots.