Run the per-round tension check that makes /grill's steelman push-back discipline real. Reads the epic cut on the live model (the `epic.md` grounding docs, written in place per ADR 026 — there is no draft tree) and everything the slice declared — its functionalities' grounding docs `functionality.md` (the hub), all SEVEN lens grounding docs, and the profile bars — and produces a structured tension report, one entry per real contradiction, each citing the specific declared item it defends (sou...
Scanned 9/10/2026
Install to Claude Code
npx -y skills add kapilvirenahuja/garura --skill check-cut-tensions --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Check Cut Tensions?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/kapilvirenahuja-check-cut-tensions)More formats (shields.io, HTML) on the badges page.
---
name: check-cut-tensions
description: Run the per-round tension check that makes /grill's steelman push-back discipline real. Reads the epic cut on the live model (the `epic.md` grounding docs, written in place per ADR 026 — there is no draft tree) and everything the slice declared — its functionalities' grounding docs `functionality.md` (the hub), all SEVEN lens grounding docs, and the profile bars — and produces a structured tension report, one entry per real contradiction, each citing the specific declared item it defends (source file + verbatim quote). Detects untestable increments, acceptance thinner than a declared bar, cut/lens contradictions, and material omissions — and, separately, unresolved DELIVERY-METHOD choices: when an epic's user check depends on a method the lenses never decided, it emits a cited decision_questions entry for the play to put to the human. Emits live tensions and open questions only; the push-back/human-response evidence fields are the play's to fill from the actual conversation, never this skill's. Returns an empty report when the cut is consistent with the declared design. Used only by the /grill play, once per grilling round, between draft (or revision) and push-back.
version: 0.2.0
user-invocable: false
model: sonnet
allowed-tools: Read, Glob
---
# check-cut-tensions
Detects tensions between a drafted epic cut and what the slice **declared**: the
functionality grounding docs (`functionality.md` — what each does, its rules, its
acceptance), the seven lens grounding docs (the solved design), and the profile bars. The
output is a structured report /grill uses to author its cited push-backs — the play quotes
the citations; this skill produces them.
This skill is the enforcement point for /grill's two hardest constraints:
- **every push-back cites a specific declared item.** This skill produces the citations; an
uncited entry must not be emitted.
- **the cut is reconciled against all seven lenses before writing.** This skill IS that
reconciliation check; a grilling round that does not invoke it is malformed.
Structured analysis, not free reasoning. Each tension entry names a specific declared item
(source file + verbatim quote) AND describes the specific contradiction. Generic critique
without a cited anchor is not a tension and must not be emitted.
## Input
| Field | Required | Description |
|-------|----------|-------------|
| `epics_home` | yes | The slice's live `epics/` home holding the epics' `epic.md` docs + `deferrals.yaml` (written in place on the live model per ADR 026 — read-only here). |
| `slice_file` | yes | The slice record (read-only). |
| `functionality_groundings` | yes | The resolved hub `functionality.md` paths, from the readiness gate. |
| `lens_dir` | yes | The slice's lens folder — all SEVEN lens grounding docs (read-only). |
| `spine` | yes | The live `_spine.yaml` (read-only) — the profile bars. |
| `round_id` | yes | Round identifier (e.g. `R3`) — written into the report. |
| `prior_rounds_dir` | no | Folder of previous round reports; entries already `resolved`/`accepted` are suppressed unless the current cut re-introduces the contradiction (then re-emitted with `reopened: true`). |
| `output_path` | yes | Where to write the report — `{working}/rounds/{round_id}-tensions.yaml`. |
## Process
1. **Build the defended set.** From each functionality's `functionality.md`: its behavior,
its rules, and its acceptance criteria. From each of the seven lens docs: its declared
content and decisions. From the spine profile: each bar (level + gate). Each defended item
carries its source file and the verbatim text.
2. **Interrogate the cut against it.** Read every epic's `epic.md` and the cut as a whole;
for each defended item ask: does the cut **contradict** it, **render it incoherent**, or
**materially omit** it?
- **Contradicts** — an epic's scope or acceptance violates a declared item (a quality gate
the acceptance undercuts, an architecture boundary an epic crosses, a profile bar the
User check ignores).
- **Renders incoherent** — the cut makes a declared item unsatisfiable (a dependency order
that defeats the run lens's rollout, two epics splitting what a lens treats as one).
- **Material omission** — a declared item demands something the cut is silent on, where
silence means it goes unmet (a failure no epic's acceptance guards, an untestable
increment hiding behind a vague User check).
3. **Emit one structured entry per real tension:**
- `tension_id` — `{round_id}-T{n}`.
- `epic_id` — the epic it concerns, or `cut` for whole-cut tensions.
- `cites` — `kind` (functionality_behavior | functionality_rule | functionality_acceptance |
lens_quality | lens_ux | lens_agentic | lens_marketing | lens_architecture | lens_run |
lens_measure | profile_bar), `source` (the file path), `quote` (the verbatim declared text).
- `contradiction_kind` — `contradicts` | `renders_incoherent` | `material_omission`.
- `summary` — one or two plain-language sentences, specific to THIS cut — what the play
will phrase the push-back from. Product language, no machine jargon.
- `status` — always `live` on a fresh entry. The play (never this skill) later flips it to
`resolved` (the cut changed) or `accepted` (with a `resolution_reason`).
- `reopened` — true only when re-emitting a previously closed tension.
4. **Detect unresolved delivery-method choices.** For each epic, ask: does its `User check`
or acceptance depend on a delivery method the lenses never decided — an ingestion route,
a surface, a data path? If the architecture/run lens decides it, cite that and move on. If
no declared item decides it, emit a **`decision_questions` entry** — NOT a tension:
- `question_id` — `{round_id}-Q{n}`.
- `epic_id` — the epic whose shape depends on the answer.
- `cites` — the declared item that makes the question necessary (the User check or
acceptance line, the lens gap), same kind/source/quote shape as tensions.
- `question` — one plain question, simply stated. No recommendation, no option menu, no
advocacy — the play asks it verbatim, one at a time.
- `human_response` — ALWAYS absent from this skill's output; the play records the human's
answer there. Never invent or pre-fill an answer.
5. **Suppress closed tensions and answered questions.** Any contradiction already
`resolved`/`accepted`, or any decision question already answered, in `prior_rounds_dir` is
skipped unless the current cut re-introduces it.
6. **Write the report** to `output_path` and return the path + counts.
## What counts as a tension — and what doesn't
A valid entry satisfies BOTH: it cites a specific declared item (source + verbatim quote),
and its summary describes a contradiction specific to the current cut — not stylistic
critique, not "this seems vague", not "have you considered X" where X is not anchored in a
declared item. If either fails, do not emit — an uncited tension becomes an uncited
push-back, which the play forbids.
## Output
```yaml
round_id: R1
epics_home: <path>
tensions:
- tension_id: R1-T1
epic_id: e-2-team-rollups
cites:
kind: lens_quality
source: product-os/ai-usage/slices/slice-team-usage/lens/quality.md
quote: "attribution totals reconcile to source totals within 1%"
contradiction_kind: material_omission
summary: >
The epic's acceptance checks that roll-ups render, but nothing verifies the declared
reconciliation gate — delivered as cut, the dashboard could show numbers the source
data contradicts.
status: live
reopened: false
decision_questions:
- question_id: R1-Q1
epic_id: e-1-token-spine
cites:
kind: lens_run
source: product-os/.../lens/run.md
quote: "Environments: one environment — a developer laptop"
question: >
Should v1 token ingestion be file/log import, provider API, manual upload, or a hybrid?
# human_response is the PLAY's field — recorded from the human's typed answer;
# this skill never fills it.
counts:
total: 1
by_kind: {contradicts: 0, renders_incoherent: 0, material_omission: 1}
decision_questions: 1
```
The play later augments each entry from the actual conversation: `pushback` (`shown_to_human`,
`text`, `asked_at`), `human_response` (`text`, `answered_at`), the disposition (`resolved` +
`resolution_directive`, or `accepted` + `resolution_reason`), and the answer on each decision
question. Those fields are evidence of the human loop — this skill emits entries WITHOUT them,
always.
**Return value:** `{status: checked, report_path, tension_count, question_count, breakdown}`.
## Failure modes
| What failed | Return |
|-------------|--------|
| epics_home empty / unreadable | `status: failed, reason: missing_cut` |
| a functionality grounding or lens doc unreadable | `status: failed, reason: missing_declared_source` |
| output path unwritable | `status: failed, reason: output_write_error` |
## Boundaries
- Reads only the cut (`epic.md` docs), the slice record, the functionality groundings, the
seven lenses, the profile, and prior round reports; writes only `output_path`.
- Does not issue push-backs, does not edit the cut, does not set `resolved`/`accepted` (the
play does, after the human answers), does not interview the human, does not call other skills.
- NEVER fills `pushback`, `human_response`, `resolution_directive`, or `resolution_reason`, and
never answers its own decision questions — those fields are the play's evidence that a real
human answered; pre-filling any of them forges the grilling.
- Empty report is a valid output — a cut consistent with everything declared returns
`tension_count: 0`; the play uses that to advance to the checkpoint.
- One entry per defended item per epic per round; two breaks of the same item by the same epic
combine into one entry.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!