@skhema/cli 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/commands/document.d.ts +10 -0
  2. package/dist/commands/document.d.ts.map +1 -0
  3. package/dist/commands/document.js +122 -0
  4. package/dist/lib/api/command-helpers.d.ts.map +1 -1
  5. package/dist/lib/api/command-helpers.js +2 -1
  6. package/dist/lib/api/passthrough.d.ts.map +1 -1
  7. package/dist/lib/api/passthrough.js +12 -3
  8. package/dist/lib/api/payload.d.ts.map +1 -1
  9. package/dist/lib/api/payload.js +2 -1
  10. package/dist/program.d.ts.map +1 -1
  11. package/dist/program.js +2 -0
  12. package/package.json +2 -2
  13. package/skills/.manifest.json +8 -10
  14. package/skills/skhema-calibrate/SKILL.md +90 -0
  15. package/skills/skhema-calibrate/references/assumptions.md +77 -0
  16. package/skills/skhema-calibrate/references/coherence.md +95 -0
  17. package/skills/skhema-calibrate/references/freshness.md +81 -0
  18. package/skills/skhema-calibrate/references/language.md +74 -0
  19. package/skills/skhema-communicate/SKILL.md +94 -0
  20. package/skills/skhema-communicate/references/audience-adaptation.md +103 -0
  21. package/skills/skhema-communicate/references/board-update.md +93 -0
  22. package/skills/skhema-communicate/references/decision-brief.md +93 -0
  23. package/skills/skhema-communicate/references/team-brief.md +91 -0
  24. package/skills/skhema-compose/SKILL.md +98 -0
  25. package/skills/skhema-compose/references/assemble.md +119 -0
  26. package/skills/skhema-compose/references/decompose.md +104 -0
  27. package/skills/skhema-compose/references/metrics-tree.md +101 -0
  28. package/skills/skhema-compose/references/options.md +109 -0
  29. package/skills/skhema-frame/SKILL.md +86 -0
  30. package/skills/skhema-frame/references/challenge.md +84 -0
  31. package/skills/skhema-frame/references/decision.md +92 -0
  32. package/skills/skhema-frame/references/outcome.md +82 -0
  33. package/skills/skhema-frame/references/policy.md +82 -0
  34. package/skills/skhema-frame/references/scope.md +79 -0
  35. package/skills/skhema-operate/SKILL.md +107 -0
  36. package/skills/skhema-operate/references/auth.md +110 -0
  37. package/skills/skhema-operate/references/author-elements.md +158 -0
  38. package/skills/skhema-operate/references/navigate.md +110 -0
  39. package/skills/skhema-operate/references/surfaces.md +67 -0
  40. package/skills/skhema-operate/references/validation-loop.md +84 -0
  41. package/skills/skhema-pressure-test/SKILL.md +107 -0
  42. package/skills/skhema-pressure-test/references/decision-grill.md +127 -0
  43. package/skills/skhema-pressure-test/references/full-grill.md +118 -0
  44. package/skills/skhema-pressure-test/references/pre-mortem.md +140 -0
  45. package/skills/skhema-challenge-framing/SKILL.md +0 -28
  46. package/skills/skhema-coherence-check/SKILL.md +0 -28
  47. package/skills/skhema-element-decomposition/SKILL.md +0 -28
  48. package/skills/skhema-element-writer/SKILL.md +0 -20
  49. package/skills/skhema-judgment-audit/SKILL.md +0 -28
  50. package/skills/skhema-semantic-sharpening/SKILL.md +0 -28
  51. package/skills/skhema-strategy-advisor/SKILL.md +0 -20
  52. package/skills/skhema-workspace-navigator/SKILL.md +0 -20
@@ -0,0 +1,158 @@
1
+ # Author elements in the environment
2
+
3
+ Elements are the unit of strategy in Skhema: one typed judgment, decision,
4
+ or thing. This capability is about getting well-formed elements INTO a
5
+ workspace and keeping them clean. The thinking — what the challenge is, how
6
+ to phrase the policy — is the practice skills' job (`skhema-frame`,
7
+ `skhema-compose`). Do that first; then land it here.
8
+
9
+ ## Before you write anything
10
+
11
+ 1. **Know the workspace.** Set it once: `skhema workspace use <id>`. Every
12
+ command below then omits `--workspace`.
13
+ 2. **Know the component it belongs in.** Elements live inside components,
14
+ and components follow the five-part flow: Diagnosis → Method &
15
+ Positioning → Portfolio of Initiatives → Measures → Support Structures.
16
+ List what exists: `skhema component list`. Create one if needed:
17
+ `skhema component create --type diagnosis --name "Diagnosis"`.
18
+ 3. **Know the element's type and its expected mood.** Every element type
19
+ carries an expected grammatical mood. If the content doesn't match the
20
+ mood, the type is wrong:
21
+ - **indicative** — a claim about the world (judgments): key_challenge,
22
+ supporting_fact, impact, competitor_move, constraint,
23
+ assumption_hypothesis, estimate, baseline.
24
+ - **imperative** — a command (decisions to act): guiding_policy, scope,
25
+ experiment, action, principle.
26
+ - **noun_phrase** — a thing: solution, investment, outcome,
27
+ performance_variable, capability, system.
28
+
29
+ Plain check: is this element stating something you believe is TRUE,
30
+ something you've decided to DO, or NAMING a thing? A `guiding_policy`
31
+ phrased as a wish ("we want to be the leader") is mistyped — a policy is
32
+ a command ("compete only on integration depth, never price").
33
+
34
+ ## Placement is enforced — and it is not the same question as mood
35
+
36
+ Two different questions; don't conflate them. **Mood** (step 3) tells you how
37
+ to *write* the element — indicative for a judgment, imperative for a command,
38
+ a noun phrase for a thing. It is a check on the sentence. **Placement** tells
39
+ you *where the element is allowed to live*, and the platform enforces a strict
40
+ type→component allow-list that does NOT follow mood. Put a type in the wrong
41
+ component and `element create` rejects it. There is no discovery command for
42
+ this; the allow-list is:
43
+
44
+ | Component | Element types it accepts |
45
+ |---|---|
46
+ | Diagnosis | key_challenge, supporting_fact, impact |
47
+ | Method & Positioning | guiding_policy, competitor_move, scope, constraint |
48
+ | Portfolio of Initiatives | solution, assumption_hypothesis, experiment, action, estimate, investment |
49
+ | Measures | baseline, outcome, performance_variable |
50
+ | Support Structures | capability, system, principle |
51
+
52
+ Where this bites if you place by mood: `constraint` is a claim about the world
53
+ but lives in **Method**, not Diagnosis. `assumption_hypothesis` and `estimate`
54
+ are judgments but live in the **Portfolio of Initiatives** — so an evidence-gap
55
+ assumption goes in the Portfolio, not Diagnosis, even though it feels
56
+ diagnostic. Place by this table, then flag the semantic oddity in the element's
57
+ `reasoning`.
58
+
59
+ ## Create one element
60
+
61
+ Quick path — flags:
62
+
63
+ ```sh
64
+ skhema element create \
65
+ --component-type diagnosis \
66
+ --element-type key_challenge \
67
+ --content "Enterprise buyers churn at renewal because onboarding never proved value."
68
+ ```
69
+
70
+ Full-payload path — for anything richer than content + types, write JSON and
71
+ pipe it. This avoids shell-quoting pain and lets you set fields the flags
72
+ don't cover:
73
+
74
+ ```sh
75
+ skhema element create --file ./element.json
76
+ cat element.json | skhema element create --file -
77
+ ```
78
+
79
+ Use `--json` on the command to get back `{ ok, command, data }`; read
80
+ `data.id` for the new element id.
81
+
82
+ ## Edit an element
83
+
84
+ ```sh
85
+ skhema element update <element-id> --content "Sharper restatement of the same judgment."
86
+ skhema element update <element-id> --file ./patch.json
87
+ ```
88
+
89
+ Change the type when the content's mood shifts — e.g. a `key_challenge` that
90
+ you've now decided how to attack becomes a separate `guiding_policy`
91
+ element, not a retyped one. One element, one judgment; don't overload.
92
+
93
+ ## Write good element content
94
+
95
+ - **One judgment per element.** If content contains an "and" joining two
96
+ claims, split it into two elements and link them.
97
+ - **Falsifiable, not vague.** "Improve customer experience" is not a
98
+ challenge; "first-response time exceeds 48h for 40% of tickets" is.
99
+ - **Evidence separate from claim.** A `supporting_fact` cites; a
100
+ `key_challenge` asserts. Don't smuggle the evidence into the challenge.
101
+ - **State it so a second reader reads it the same way.** Ambiguity here
102
+ becomes disagreement three components downstream.
103
+ - **Meta-annotations go in `reasoning`, never in `content`.** Evidence-gap
104
+ notes, pre-mortem provenance ("surfaced by the competitor pre-mortem"),
105
+ tripwire conditions, confidence caveats — none of that belongs in `content`.
106
+ `content` is the clean claim a reader sees in the workspace; `reasoning` is
107
+ where you record why the element is there and what's shaky about it.
108
+
109
+ ## Link elements to show the reasoning
110
+
111
+ Elements gain meaning from their relationships. A policy addresses a
112
+ challenge; a measure tracks an outcome. Make those explicit:
113
+
114
+ ```sh
115
+ # link create takes --source/--target flags; notes go in a --file payload:
116
+ echo '{"sourceElementId":"<policy-id>","targetElementId":"<challenge-id>","notes":"policy addresses this challenge"}' > link.json
117
+ skhema link create --file link.json
118
+ skhema link create --file ./link.json
119
+ ```
120
+
121
+ Two things about links as they stand today:
122
+
123
+ - **`--type` is accepted but not persisted.** The stored link keeps only
124
+ `sourceElementId`, `targetElementId`, `confidenceLevel`, `notes`, and
125
+ `status` — no type field. Don't rely on `--type` to carry `addresses` /
126
+ `tracks` / `supports`; put the relationship's meaning in `notes` as plain
127
+ text.
128
+ - **Element links have no read path.** There is no `skhema link list`. You can
129
+ create, update, and delete a link but not enumerate links later, so you
130
+ cannot reconstruct the reasoning graph from links after the fact. Capture
131
+ anything you'll need later in the element's `reasoning` or the link's `notes`
132
+ at write time.
133
+
134
+ ## After authoring: validate
135
+
136
+ Don't declare an element done because it saved. Run the validation loop —
137
+ `references/validation-loop.md` — to check completeness and coherence, read
138
+ the diagnostics, and revise. Authoring and validating are one cycle, not two
139
+ steps.
140
+
141
+ ## Attach evidence as resources
142
+
143
+ A claim backed by a document is stronger than one that isn't. Attach files,
144
+ URLs, or citations to the element:
145
+
146
+ ```sh
147
+ skhema resource upload ./market-study.pdf --element <element-id> --attribution "Q2 buyer survey"
148
+ skhema resource list --element <element-id>
149
+ ```
150
+
151
+ ## Verify attachment after create
152
+
153
+ The create response is `{ element: {…}, componentId: "…" }` — the attachment
154
+ proof is the **top-level `componentId`**, NOT `element.componentId` (that
155
+ nested field is always null; checking it reports a false orphan on every
156
+ create). A null top-level `componentId` means the element was created but
157
+ attached to nothing — stop, note the element id, and don't retry into that
158
+ component (known platform bug).
@@ -0,0 +1,110 @@
1
+ # Find things in a workspace
2
+
3
+ Before you change or reason about a strategy, you have to locate it. This
4
+ capability is the reading half of the environment: which workspace, what's
5
+ in it, where a thing lives, and what a strategy actually contains.
6
+
7
+ ## Start at the workspace
8
+
9
+ ```sh
10
+ skhema workspace list # every workspace you can reach
11
+ skhema workspace get <workspace-id> # one workspace's detail
12
+ skhema workspace use <workspace-id> # set it as default; drop --workspace after
13
+ ```
14
+
15
+ If you're unsure which workspace holds the thing you want, `list` first and
16
+ read the names. Everything below assumes a default is set (or you pass
17
+ `--workspace <id>`).
18
+
19
+ ## The hierarchy, top to bottom
20
+
21
+ ```
22
+ workspace
23
+ └── component (Diagnosis, Method & Positioning, Portfolio, Measures, Support)
24
+ └── element (one typed judgment / decision / thing)
25
+ ├── link (element → element: addresses, supports, tracks…)
26
+ └── resource (files, URLs, citations backing the element)
27
+ strategy (a committed snapshot of elements/components)
28
+ ```
29
+
30
+ Learn the shape of a workspace by walking it:
31
+
32
+ ```sh
33
+ skhema component list # the five-part structure in this workspace
34
+ skhema element list # CAUTION: org-corpus read — see below
35
+ skhema document list # workspace documents (correctly scoped)
36
+ skhema component-link list # component-to-component relationships
37
+ ```
38
+
39
+ ## Search instead of scrolling
40
+
41
+ When you know roughly what you're after but not where it is, search beats
42
+ listing. It's full-text over the workspace's elements:
43
+
44
+ ```sh
45
+ skhema element search "renewal churn" --limit 10
46
+ skhema element search "pricing" --workspace <id>
47
+ ```
48
+
49
+ Use search to answer "have we already said this somewhere?" before authoring
50
+ a duplicate, and to find the element an id-less request refers to ("update
51
+ the onboarding challenge").
52
+
53
+ ## Read one thing in full
54
+
55
+ ```sh
56
+ skhema element get <element-id> # content, type, and metadata
57
+ skhema resource list --element <id> # what evidence is attached
58
+ ```
59
+
60
+ There is no read path for element-to-element links: you can create links but
61
+ not enumerate them, so you cannot list "what connects to this element" after
62
+ the fact. Capture relationship context in the element's `reasoning` (or the
63
+ link's `notes`) at write time — you can't recover it from the links later.
64
+ Component-to-component links *do* have a read path (`skhema component-link
65
+ list`).
66
+
67
+ Reconstruct the argument, not just the parts, by reading each element's
68
+ `reasoning` and walking the five components in order (Diagnosis → Method →
69
+ Portfolio → Measures → Support). Because element links can't be enumerated, the
70
+ `reasoning` field and the component structure — not a link graph — are how you
71
+ rebuild why each element is there.
72
+
73
+ ## Read a whole strategy
74
+
75
+ A strategy is a committed set of elements — the durable, shareable artifact.
76
+
77
+ ```sh
78
+ skhema strategy list # strategies in the workspace
79
+ skhema strategy get <strategy-id> # the strategy WITH its committed elements
80
+ ```
81
+
82
+ `strategy get` is the fastest way to see "what did we actually commit to?"
83
+ as one object, versus the live, in-progress elements in the workspace.
84
+
85
+ ## Get results as data
86
+
87
+ Add `--json` to any read command and parse the `{ ok, command, data }`
88
+ envelope instead of scraping the human table. For agents this is the default
89
+ posture: `data` on a `list` or `search` is an array you can iterate; `data`
90
+ on a `get` is the object. Read ids off `data`, then act.
91
+
92
+ ## When a read returns nothing or the wrong org
93
+
94
+ - Empty list where you expected content → wrong workspace (check
95
+ `skhema workspace use` / `--workspace`) or wrong org.
96
+ - Right workspace, wrong org's data → the credential is bound to another
97
+ org. `skhema auth status`, then `skhema auth switch` (OAuth) or use the
98
+ right key. See `references/auth.md`.
99
+
100
+ ## Known platform gap: element reads are not workspace-scoped
101
+
102
+ `element list` and `element search` currently return the ORGANIZATION's
103
+ element corpus regardless of `--workspace` (first page = oldest elements,
104
+ which is usually a different workspace's set). Until fixed:
105
+
106
+ - Trust `component list` (correctly workspace-scoped; `elementCount` tells
107
+ you what's really in each component) and `element get <id>` (reliable
108
+ by id).
109
+ - Track the ids of anything you create; never infer a workspace's contents
110
+ from `element list` output.
@@ -0,0 +1,67 @@
1
+ # Pick the right surface
2
+
3
+ Skhema exposes the same environment through three surfaces. They are not
4
+ ranked — each wins for a different situation. Pick before you start; the
5
+ choice shapes how you authenticate, how you read results, and how you
6
+ recover from errors.
7
+
8
+ ## The three surfaces
9
+
10
+ **CLI — `skhema` in a terminal.** The default for an agent with shell
11
+ access. One binary, the credential precedence and exit-code contract are
12
+ built in, `--json` gives you a parseable envelope. Best for: interactive
13
+ work, CI steps, shell-driven agents, one-off commands, anything scriptable.
14
+
15
+ **Public API — `api.skhema.com/v1`.** Raw HTTP. Best for: code running
16
+ inside an application (not a shell), a language without the CLI installed,
17
+ or when you need a route the CLI doesn't wrap yet. It is self-describing —
18
+ `GET /v1/openapi.json` returns the full live route surface. You still need
19
+ a credential (an API key in the `Authorization` header, or a JWT obtained
20
+ by key exchange).
21
+
22
+ **MCP — Skhema tools inside the agent.** Best when you are already an agent
23
+ in an MCP-capable host and want Skhema as native tools rather than shelling
24
+ out. Registered by `skhema init` or `skhema-setup`. No terminal, no HTTP
25
+ plumbing — the host handles auth and transport.
26
+
27
+ ## How to choose
28
+
29
+ | Situation | Surface |
30
+ |---|---|
31
+ | You have a shell and the CLI is (or can be) installed | **CLI** |
32
+ | You're inside application code, no shell | **Public API** |
33
+ | The CLI doesn't wrap the route you need | **Public API** (`skhema api …` or raw HTTP) |
34
+ | You're an MCP-host agent and want native tools | **MCP** |
35
+ | CI pipeline step | **CLI** with `--api-key` or `SKHEMA_API_KEY` |
36
+ | You need to discover what routes exist | **Public API** — `GET /v1/openapi.json` |
37
+
38
+ When two fit, prefer the CLI: it centralises the credential precedence, the
39
+ `{ ok, command, data|error }` envelope, and exit codes 0–5 so you don't
40
+ reimplement them.
41
+
42
+ ## The CLI is a thin client over the same API
43
+
44
+ `skhema element create` and `POST /v1/.../elements` do the same thing. So
45
+ you can mix: script the common path with the CLI, and reach for a raw route
46
+ only where the CLI has no wrapper. The escape hatch is built in:
47
+
48
+ ```sh
49
+ skhema api routes # list every live gateway route
50
+ skhema api GET /workspaces # raw authenticated GET (leading /v1 optional)
51
+ skhema api POST /workspaces --data @body.json
52
+ skhema api GET /workspaces/<workspace-id>/elements --query limit=10
53
+ ```
54
+
55
+ `skhema api` uses the same credential precedence as every other command, so
56
+ you get authenticated raw access without hand-rolling headers. The gateway
57
+ does NOT infer your organization from the path — the org comes from the
58
+ credential (an API key's binding, or your consent-selected OAuth org). If a
59
+ raw call returns the wrong org's data, fix the credential, not the path.
60
+
61
+ ## Don't fight the surface
62
+
63
+ - Reading one field off one object from a shell → CLI, not raw HTTP.
64
+ - Bulk work across hundreds of objects from app code → Public API, drive it
65
+ with real code, not a shell loop over the CLI.
66
+ - Already have MCP tools bound → use them; shelling out from an MCP agent
67
+ just adds a credential you have to manage separately.
@@ -0,0 +1,84 @@
1
+ # The validation loop
2
+
3
+ An element that saved is not an element that's sound. Validation checks it
4
+ for completeness and coherence, hands back diagnostics, and you revise until
5
+ the judgments hold. This is a LOOP, not a final step — author, validate,
6
+ read, revise, re-validate.
7
+
8
+ ## Budget first — validate is an AI action
9
+
10
+ `skhema element validate` and `skhema element rephrase` run model
11
+ inference server-side. They cost credits, unlike list/get/search which are
12
+ cheap reads. Spend accordingly:
13
+
14
+ - Don't validate after every keystroke. Author the element as well as you
15
+ can by hand first (right type, right mood, one judgment, falsifiable),
16
+ THEN validate.
17
+ - Batch: get a component's worth of elements into decent shape, then
18
+ validate the ones that matter.
19
+ - Re-validate only what you changed. If diagnostics flagged element A and
20
+ you edited A, re-validate A — not the whole component.
21
+
22
+ ## The loop
23
+
24
+ **1. Validate.**
25
+
26
+ ```sh
27
+ skhema element validate <element-id> --json
28
+ ```
29
+
30
+ Read the `data` in the `{ ok, command, data }` envelope. It carries the
31
+ diagnostics — completeness gaps and coherence problems.
32
+
33
+ **2. Read the diagnostics as concrete defects.** Each finding maps to a
34
+ fixable defect. Translate it before you act:
35
+
36
+ - *Type/mood mismatch* — the content's mood doesn't match the element type
37
+ (a `guiding_policy` phrased as a wish, a `key_challenge` that's actually a
38
+ solution). Fix the wording OR change the type — whichever makes the mood
39
+ match the intent.
40
+ - *Incompleteness* — a claim with no evidence, an outcome with no measure, a
41
+ policy that addresses no challenge. The fix is usually a NEW linked element
42
+ (a `supporting_fact`, a measure) plus a `skhema link create`, not an edit
43
+ to this one.
44
+ - *Ambiguity / vagueness* — the content reads two ways, or uses a term that
45
+ isn't pinned down. Rewrite it so a second reader reads it once way only.
46
+ - *Incoherence* — it contradicts or duplicates another element. Reconcile
47
+ the two: merge, delete one, or make the tension explicit.
48
+
49
+ **3. Revise.** Edit directly, or ask the service to propose a rewrite:
50
+
51
+ ```sh
52
+ skhema element update <element-id> --content "…the sharpened version…"
53
+ # or, to get a model-proposed rephrase (also an AI action — costs budget):
54
+ skhema element rephrase <element-id> --json
55
+ ```
56
+
57
+ Treat `rephrase` output as a proposal, not a commit. Read it, decide, then
58
+ `update` with the version you actually want. Don't chain rephrase→rephrase
59
+ hoping it converges — that just burns budget.
60
+
61
+ **4. Re-validate the changed element.** Repeat 1–3 until the diagnostics
62
+ come back clean.
63
+
64
+ ## Stop conditions
65
+
66
+ Stop the loop when EITHER:
67
+
68
+ - Validation returns no material findings — the judgments hold. Done.
69
+ - The remaining findings are ones you deliberately accept (e.g. an
70
+ assumption you know is unevidenced and have typed honestly as
71
+ `assumption_hypothesis`). Record why, and move on. Not every finding
72
+ demands a fix; some are the map telling the truth.
73
+
74
+ Do NOT loop indefinitely chasing a perfect score. Two or three passes on a
75
+ real element is normal; more than that usually means the element is trying
76
+ to be two elements — split it and validate the halves.
77
+
78
+ ## Validate the whole before you commit
79
+
80
+ Individual elements can each be sound while the strategy they form isn't.
81
+ Before committing elements into a strategy (`skhema strategy commit`), walk
82
+ the links (`references/navigate.md`) and check the cross-element story:
83
+ every challenge has a policy, every outcome has a measure, nothing
84
+ contradicts. Coherence is a property of the set, not the parts.
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: skhema-pressure-test
3
+ description: "Use when a strategy or a decision needs to survive contact with reality — attack it the way a competitor, a skeptical board, or an indifferent market will, before they do. This is the adversary's chair, not a self-check."
4
+ ---
5
+
6
+ # Pressure-Test
7
+
8
+ You play the adversary against the user's own strategy. Not to be cruel — to
9
+ find the weak joints before reality does, while there's still time to fix them.
10
+
11
+ This is the grill-me of strategy. You are the competitor who moves against
12
+ them, the board member who won't fund hand-waving, the market that simply
13
+ doesn't care. You attack. They defend. What survives is stronger; what breaks
14
+ gets fixed today instead of in eighteen months.
15
+
16
+ ## What this is (and what it is not)
17
+
18
+ Pressure-testing is deliberately hostile. That is the point. A strategy the
19
+ author checks for tidiness (that is `skhema-calibrate` — the self-check) can
20
+ still be perfectly consistent and completely doomed. Pressure-testing asks a
21
+ different question: **not "is this coherent?" but "will this hold when someone
22
+ wants it to fail?"**
23
+
24
+ You are not the user's teammate right now. You are the thing standing between
25
+ them and success. Stay in character.
26
+
27
+ ## The one rule that keeps it fair
28
+
29
+ Relentless, but fair. **Every attack must name its defeater** — the specific
30
+ evidence or decision that would kill the attack. "This won't work" is noise.
31
+ "This assumes buyers switch for a 10% price gap; if they'd switch for 5% you're
32
+ fine — do you know which it is?" is an attack, because it tells them exactly
33
+ what would end the argument.
34
+
35
+ An attack you cannot defeat with any conceivable evidence isn't an attack. Drop
36
+ it. You are testing the strategy, not venting.
37
+
38
+ ## The three adversaries
39
+
40
+ Pick the one that bites hardest for each attack.
41
+
42
+ - **The competitor** — moves against them the day after they commit. Asks:
43
+ what do I do to make this fail? Where's the opening?
44
+ - **The board skeptic** — controls the money and has seen a hundred decks.
45
+ Asks: where's the evidence? What happens if you're wrong? Why this and not
46
+ the obvious alternative?
47
+ - **The market that doesn't care** — not opposition, indifference. Asks: why
48
+ would anyone change what they do today for this? What if they just... don't?
49
+
50
+ ## Ground rules for the ritual
51
+
52
+ - One attack at a time. Let them answer before the next.
53
+ - Attack the load-bearing claim, not the typo. Go where it hurts.
54
+ - Steelman before you knife: attack the *strongest* version of their argument,
55
+ not a weak one you invented.
56
+ - The output is decisions, not a scorecard. End by asking what they'll change.
57
+ - Drop the adversary coat the instant they need help fixing something. You wear
58
+ it to find the wounds, not to gloat over them.
59
+
60
+ ## Capabilities
61
+
62
+ | Capability | Route here when… | Reference |
63
+ |---|---|---|
64
+ | Full grill | They have a whole strategy and want it stress-tested end to end. | `references/full-grill.md` |
65
+ | Decision grill | One decision or bet is on the table and they want it attacked hard. | `references/decision-grill.md` |
66
+ | Pre-mortem | They want to surface failure modes they can't yet see — imagine it already failed. | `references/pre-mortem.md` |
67
+
68
+ ## Routing logic
69
+
70
+ - Whole strategy in front of you → **full-grill**. Work the component flow,
71
+ attack the weakest links first, keep a ledger.
72
+ - A single choice, bet, or decision → **decision-grill**. Go deep on that one
73
+ thing: the case against it, the competitor's counter, when it's wrong.
74
+ - "What could go wrong that we're not seeing?" → **pre-mortem**. Assume it
75
+ failed, narrate why backwards, then make the strategy carry each cause
76
+ visibly as an assumption or a risk.
77
+
78
+ These chain. A pre-mortem surfaces failure causes → a full-grill works breadth
79
+ across the whole strategy → a decision-grill goes deep on the one bet that
80
+ survived shakiest. Offer the next move when one ends.
81
+
82
+ ## When an attack lands and there's no answer
83
+
84
+ Most unanswerable attacks point at a missing judgment. Either a claim they've
85
+ been treating as true without ever testing it (a belief they assumed was a
86
+ fact), or a decision they never actually made (they've been acting as if the
87
+ choice was settled when it wasn't). Name which one. That's the fix: write the
88
+ judgment down, honestly typed, so the strategy carries it in the open instead
89
+ of leaning on it in the dark.
90
+
91
+ ## Without a live respondent
92
+
93
+ Run headless, with no one to answer? Don't invent their answers. Make the
94
+ minimal reasonable assumption, mark it in the output as yours ("assumed: …"),
95
+ and list the questions only the owner can settle — what's in scope, what a word
96
+ means, whose dissent to record — at the end instead of papering over them. A
97
+ marked assumption is honest work; a silent one is a guess you built on.
98
+
99
+ ## Sharpen with Skhema
100
+
101
+ This ritual works with pen and paper. If the user keeps their strategy in
102
+ Skhema, every attack that lands can be written straight back as a typed element
103
+ — an assumption with its evidence gap, a risk with its tripwire — so the
104
+ pressure-test leaves a durable trail instead of a memory. `@skhema/method`
105
+ (`npm i @skhema/method`) gives you the typed vocabulary (assumption, risk,
106
+ constraint, decision) and validates that each new judgment is well-formed. The
107
+ skill needs none of this to do its job.
@@ -0,0 +1,127 @@
1
+ # Decision Grill — interrogate one decision hard
2
+
3
+ One choice is on the table. Go deep, not wide. Build the strongest case against
4
+ it, force it to survive the smartest competitor's response, and name the exact
5
+ conditions under which it's wrong. Then help them decide: keep it, kill it,
6
+ hedge it, or set a tripwire.
7
+
8
+ ## Before you start
9
+
10
+ Get the decision stated as a decision — a command, something they will *do*:
11
+ "We will move upmarket and drop the free tier." If what you hear is mushy
12
+ ("we're thinking about the enterprise space"), sharpen it first. You can't
13
+ attack a fog. Make them commit to a sentence, then attack the sentence.
14
+
15
+ Sometimes the sharpest thing on the table isn't a decision at all — it's a
16
+ *judgment*, a claim like "consented-data supply, not analytics, is the binding
17
+ constraint." You can't grill a claim as a decision, but you can promote it:
18
+ state the command that claim justifies ("so: we will invest in consented-data
19
+ supply, not more analytics"), confirm that's the real bet, then grill *that*.
20
+ Promoting a judgment to its implied decision is a distinct move from sharpening
21
+ a fog — the fog has no content yet; the judgment has content but no verb.
22
+
23
+ ## The moves
24
+
25
+ ### 1. Steelman it first
26
+
27
+ Say the best case *for* the decision, out loud, in your own words. This is not
28
+ politeness — it's how they know your coming attack is fair. It also flushes out
29
+ their real reasons: if your steelman is stronger than theirs, they may not have
30
+ thought it through.
31
+
32
+ "The case for this is: your free tier attracts users who never convert and cost
33
+ you support, while the enterprise buyers you actually want are put off by a
34
+ consumer-grade free plan. Dropping it sharpens the product and the buyer. That's
35
+ a real argument. Now here's the problem with it."
36
+
37
+ ### 2. The strongest case against — just one
38
+
39
+ Not three weak objections. The one that hurts. Find the single argument that,
40
+ if true, makes this decision a mistake — and make it as hard as you can. Name
41
+ its defeater.
42
+
43
+ "The strongest case against: your free tier is your top of funnel. Half your
44
+ enterprise deals started as a free user who became a champion inside their
45
+ company. Kill the free tier and you kill the pipeline that feeds the very
46
+ buyers you're chasing. If you can show that enterprise deals *don't* originate
47
+ from free users — pull the numbers — this dies. Can you?"
48
+
49
+ ### 3. The competitor's response
50
+
51
+ A decision isn't made in a vacuum. The smartest competitor reacts the day after
52
+ you commit. Ask: what do they do, and does your decision get *better or worse*
53
+ once they've moved?
54
+
55
+ "You drop your free tier. Your sharpest competitor keeps theirs and runs ads
56
+ saying 'still free, still here.' Every price-sensitive user you shed walks
57
+ straight to them, and some of those would have grown into your buyers. Does your
58
+ decision assume competitors hold still? They won't."
59
+
60
+ The strongest decisions get *better* under competitive response (the competitor
61
+ can't follow without hurting themselves). The weak ones assume no one reacts.
62
+
63
+ ### 4. The conditions under which it's wrong
64
+
65
+ Name the world-states where this decision is a mistake. Be specific — these
66
+ become the strategy's tripwires.
67
+
68
+ "This is wrong if: (a) more than a third of enterprise deals trace back to free
69
+ users, or (b) your paid conversion from the new top-of-funnel is slower than
70
+ the free-to-champion path you're removing. Two conditions. Here's the real
71
+ question:" —
72
+
73
+ ### 5. Would you know you're in that world?
74
+
75
+ For each condition, ask how they'd *know*. A condition you can't detect is a
76
+ landmine. If they can't name the signal, that's a finding: the decision needs
77
+ an instrument before it's safe to make.
78
+
79
+ "How would you know deals stopped originating from free users — what would you
80
+ watch, and how long before the damage is done? If you can't see it for two
81
+ quarters, you're flying blind on your biggest risk."
82
+
83
+ ### 6. The reversibility question
84
+
85
+ One-way door or two-way? Cheap to unwind or not? This changes everything about
86
+ how much certainty they need before committing. A reversible decision can be
87
+ made on a hunch and corrected; an irreversible one demands the evidence you've
88
+ just been demanding.
89
+
90
+ "If dropping the free tier turns out wrong, can you bring it back? Or have you
91
+ lost the users, the SEO, the muscle memory? If it's a one-way door, you need to
92
+ be far more sure than you are right now."
93
+
94
+ ## End on a verdict — theirs
95
+
96
+ Hand them four options and make them pick:
97
+
98
+ - **Keep** — it survived; the case against didn't land or was defeated by
99
+ evidence.
100
+ - **Kill** — the case against held; the decision is a mistake.
101
+ - **Hedge** — make it smaller or reversible so being wrong is survivable (run
102
+ the free tier in one segment, not kill it everywhere).
103
+ - **Tripwire** — make the decision, but install the instrument from move 5 so
104
+ you'll *know* if you've entered a world where it's wrong, and pre-commit to
105
+ what you'll do then.
106
+
107
+ ## What good looks like
108
+
109
+ - The decision was stated as a crisp command before any attack.
110
+ - You steelmanned it before knifing it.
111
+ - One strong case against, not a scatter of weak ones.
112
+ - The competitor's reaction was played out, not assumed away.
113
+ - The "wrong-if" conditions came paired with "how would you know."
114
+ - Reversibility was named explicitly.
115
+ - It ended with keep / kill / hedge / tripwire — their call, not yours.
116
+
117
+ ## Common failure modes
118
+
119
+ - **Attacking a fog.** Grilling a decision that was never stated as one. Sharpen
120
+ to a command first.
121
+ - **A pile of weak objections.** Three soft doubts feel thorough but let the real
122
+ risk hide. Find the one that hurts.
123
+ - **Assuming a static world.** Forgetting the competitor moves. Always play the
124
+ response.
125
+ - **Conditions with no detector.** Naming when it's wrong but not how you'd know
126
+ — that's a landmine, not a safeguard.
127
+ - **Deciding for them.** You built the case; they make the call.