@skhema/cli 0.4.4 → 0.4.6
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.
- package/README.md +15 -0
- package/dist/commands/import.d.ts +4 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +238 -0
- package/dist/lib/api/import-transfer.d.ts +22 -0
- package/dist/lib/api/import-transfer.d.ts.map +1 -0
- package/dist/lib/api/import-transfer.js +89 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +2 -0
- package/package.json +3 -3
- package/skills/.manifest.json +8 -10
- package/skills/skhema-calibrate/SKILL.md +90 -0
- package/skills/skhema-calibrate/references/assumptions.md +77 -0
- package/skills/skhema-calibrate/references/coherence.md +95 -0
- package/skills/skhema-calibrate/references/freshness.md +81 -0
- package/skills/skhema-calibrate/references/language.md +74 -0
- package/skills/skhema-communicate/SKILL.md +94 -0
- package/skills/skhema-communicate/references/audience-adaptation.md +103 -0
- package/skills/skhema-communicate/references/board-update.md +93 -0
- package/skills/skhema-communicate/references/decision-brief.md +93 -0
- package/skills/skhema-communicate/references/team-brief.md +91 -0
- package/skills/skhema-compose/SKILL.md +98 -0
- package/skills/skhema-compose/references/assemble.md +119 -0
- package/skills/skhema-compose/references/decompose.md +104 -0
- package/skills/skhema-compose/references/metrics-tree.md +101 -0
- package/skills/skhema-compose/references/options.md +109 -0
- package/skills/skhema-frame/SKILL.md +86 -0
- package/skills/skhema-frame/references/challenge.md +84 -0
- package/skills/skhema-frame/references/decision.md +92 -0
- package/skills/skhema-frame/references/outcome.md +82 -0
- package/skills/skhema-frame/references/policy.md +82 -0
- package/skills/skhema-frame/references/scope.md +79 -0
- package/skills/skhema-operate/SKILL.md +107 -0
- package/skills/skhema-operate/references/auth.md +110 -0
- package/skills/skhema-operate/references/author-elements.md +158 -0
- package/skills/skhema-operate/references/navigate.md +110 -0
- package/skills/skhema-operate/references/surfaces.md +67 -0
- package/skills/skhema-operate/references/validation-loop.md +84 -0
- package/skills/skhema-pressure-test/SKILL.md +107 -0
- package/skills/skhema-pressure-test/references/decision-grill.md +127 -0
- package/skills/skhema-pressure-test/references/full-grill.md +118 -0
- package/skills/skhema-pressure-test/references/pre-mortem.md +140 -0
- package/skills/skhema-challenge-framing/SKILL.md +0 -28
- package/skills/skhema-coherence-check/SKILL.md +0 -28
- package/skills/skhema-element-decomposition/SKILL.md +0 -28
- package/skills/skhema-element-writer/SKILL.md +0 -20
- package/skills/skhema-judgment-audit/SKILL.md +0 -28
- package/skills/skhema-semantic-sharpening/SKILL.md +0 -28
- package/skills/skhema-strategy-advisor/SKILL.md +0 -20
- package/skills/skhema-workspace-navigator/SKILL.md +0 -20
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Authenticate and bind the right org
|
|
2
|
+
|
|
3
|
+
Almost every command needs a credential. This is how to get one, how the
|
|
4
|
+
CLI decides which one to use, and how to read the org binding so you act on
|
|
5
|
+
the right organization.
|
|
6
|
+
|
|
7
|
+
## First, is the CLI even installed?
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
skhema --version
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
If that fails, install it:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install -g @skhema/cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Two credential lanes
|
|
20
|
+
|
|
21
|
+
**API key — for headless, CI, and agents.** A long-lived `sk_live_…` string
|
|
22
|
+
bound to one organization. No browser needed. This is the right lane for any
|
|
23
|
+
non-interactive runtime.
|
|
24
|
+
|
|
25
|
+
- Store one: `skhema auth key use sk_live_…`
|
|
26
|
+
- Or pass per-invocation: `skhema … --api-key sk_live_…`
|
|
27
|
+
- Or set the env var: `export SKHEMA_API_KEY=sk_live_…`
|
|
28
|
+
- Create a new key (needs an interactive login first):
|
|
29
|
+
`skhema auth key create --name "ci-runner" --permission read-write --scope org --use`
|
|
30
|
+
(`--permission` is `read | write | read-write`; `--scope` is `org | user`;
|
|
31
|
+
`--use` stores it as the CLI credential immediately.)
|
|
32
|
+
- List / revoke: `skhema auth key list`, `skhema auth key revoke <key-id>`
|
|
33
|
+
|
|
34
|
+
**OAuth session — for a human at a terminal.** A browser login bound to the
|
|
35
|
+
org you consent to.
|
|
36
|
+
|
|
37
|
+
- `skhema auth login` (interactive browser flow)
|
|
38
|
+
- `skhema auth login --headless` (device-code flow — no local browser; use
|
|
39
|
+
on a remote box or in a container)
|
|
40
|
+
|
|
41
|
+
## Credential precedence (highest wins)
|
|
42
|
+
|
|
43
|
+
The CLI resolves ONE credential per invocation, in this fixed order:
|
|
44
|
+
|
|
45
|
+
1. `--api-key <key>` flag
|
|
46
|
+
2. `SKHEMA_API_KEY` environment variable
|
|
47
|
+
3. stored API key (`skhema auth key use`)
|
|
48
|
+
4. OAuth session (`skhema auth login`)
|
|
49
|
+
|
|
50
|
+
Consequence: a stray `SKHEMA_API_KEY` in the environment silently overrides
|
|
51
|
+
your stored key and your OAuth session. If a command acts as the wrong
|
|
52
|
+
identity, check the env var first.
|
|
53
|
+
|
|
54
|
+
## Always know who you are
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
skhema auth status
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Prints which credential is active and which org it resolves to. Run it
|
|
61
|
+
whenever a result looks like it came from the wrong organization, or before
|
|
62
|
+
any write you can't easily undo.
|
|
63
|
+
|
|
64
|
+
## The org binding — the trap on the OAuth lane
|
|
65
|
+
|
|
66
|
+
- An **API key** is bound to its org at creation. You cannot switch it; to
|
|
67
|
+
act on a different org, use a key issued for that org.
|
|
68
|
+
- An **OAuth session** acts on the org you consented to. Change it:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
skhema auth switch <org-slug>
|
|
72
|
+
skhema auth switch # no slug: pick from consented orgs
|
|
73
|
+
skhema auth switch --headless # device-code consent fallback
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If writes land in the wrong org on the OAuth lane, you skipped
|
|
77
|
+
`auth switch`. There is no per-command org override for the OAuth session —
|
|
78
|
+
switch it, confirm with `auth status`, then act.
|
|
79
|
+
|
|
80
|
+
## Handling exit code 3
|
|
81
|
+
|
|
82
|
+
Exit **3** means no usable credential resolved. Do NOT retry the same
|
|
83
|
+
command — it will keep failing. Instead:
|
|
84
|
+
|
|
85
|
+
1. `skhema auth status` — confirm nothing is active.
|
|
86
|
+
2. Headless / CI / agent? Set an API key (lane 1). Human at a terminal?
|
|
87
|
+
`skhema auth login`.
|
|
88
|
+
3. Re-run the original command.
|
|
89
|
+
|
|
90
|
+
## The other credentialed exit codes
|
|
91
|
+
|
|
92
|
+
- **4** (permission/plan denied, 403/402): the credential is valid but not
|
|
93
|
+
allowed to do this — wrong permission on the key (`read` key attempting a
|
|
94
|
+
write), wrong role, or a plan gate. Don't re-auth; change what you're
|
|
95
|
+
asking or which key you use.
|
|
96
|
+
- **5** (rate limited, 429): back off, then retry.
|
|
97
|
+
|
|
98
|
+
## Registered-agent identity (autonomous runtimes)
|
|
99
|
+
|
|
100
|
+
If this runtime was enrolled as a registered agent, it signs its own
|
|
101
|
+
requests instead of carrying a key:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
skhema agent status --verify # show and verify this runtime's identity
|
|
105
|
+
skhema agent rotate # rotate the signing key; identity + grants unchanged
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Enrollment (`skhema agent enroll <token>`) is a one-time onboarding step —
|
|
109
|
+
see the `skhema-setup` skill. Never cache a derived agent JWT; let the CLI
|
|
110
|
+
sign per request.
|
|
@@ -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.
|