@skhema/cli 0.4.4 → 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 (41) hide show
  1. package/package.json +1 -1
  2. package/skills/.manifest.json +8 -10
  3. package/skills/skhema-calibrate/SKILL.md +90 -0
  4. package/skills/skhema-calibrate/references/assumptions.md +77 -0
  5. package/skills/skhema-calibrate/references/coherence.md +95 -0
  6. package/skills/skhema-calibrate/references/freshness.md +81 -0
  7. package/skills/skhema-calibrate/references/language.md +74 -0
  8. package/skills/skhema-communicate/SKILL.md +94 -0
  9. package/skills/skhema-communicate/references/audience-adaptation.md +103 -0
  10. package/skills/skhema-communicate/references/board-update.md +93 -0
  11. package/skills/skhema-communicate/references/decision-brief.md +93 -0
  12. package/skills/skhema-communicate/references/team-brief.md +91 -0
  13. package/skills/skhema-compose/SKILL.md +98 -0
  14. package/skills/skhema-compose/references/assemble.md +119 -0
  15. package/skills/skhema-compose/references/decompose.md +104 -0
  16. package/skills/skhema-compose/references/metrics-tree.md +101 -0
  17. package/skills/skhema-compose/references/options.md +109 -0
  18. package/skills/skhema-frame/SKILL.md +86 -0
  19. package/skills/skhema-frame/references/challenge.md +84 -0
  20. package/skills/skhema-frame/references/decision.md +92 -0
  21. package/skills/skhema-frame/references/outcome.md +82 -0
  22. package/skills/skhema-frame/references/policy.md +82 -0
  23. package/skills/skhema-frame/references/scope.md +79 -0
  24. package/skills/skhema-operate/SKILL.md +107 -0
  25. package/skills/skhema-operate/references/auth.md +110 -0
  26. package/skills/skhema-operate/references/author-elements.md +158 -0
  27. package/skills/skhema-operate/references/navigate.md +110 -0
  28. package/skills/skhema-operate/references/surfaces.md +67 -0
  29. package/skills/skhema-operate/references/validation-loop.md +84 -0
  30. package/skills/skhema-pressure-test/SKILL.md +107 -0
  31. package/skills/skhema-pressure-test/references/decision-grill.md +127 -0
  32. package/skills/skhema-pressure-test/references/full-grill.md +118 -0
  33. package/skills/skhema-pressure-test/references/pre-mortem.md +140 -0
  34. package/skills/skhema-challenge-framing/SKILL.md +0 -28
  35. package/skills/skhema-coherence-check/SKILL.md +0 -28
  36. package/skills/skhema-element-decomposition/SKILL.md +0 -28
  37. package/skills/skhema-element-writer/SKILL.md +0 -20
  38. package/skills/skhema-judgment-audit/SKILL.md +0 -28
  39. package/skills/skhema-semantic-sharpening/SKILL.md +0 -28
  40. package/skills/skhema-strategy-advisor/SKILL.md +0 -20
  41. package/skills/skhema-workspace-navigator/SKILL.md +0 -20
@@ -0,0 +1,79 @@
1
+ # Frame the scope
2
+
3
+ Scope is the boundary line: what this piece of work covers and what it
4
+ deliberately does not. Mood: **command**. Scope is a decision, stated as an
5
+ instruction — "include this, exclude that" — not a description of
6
+ everything that might be relevant. Open-ended scope is the most common way
7
+ strategy work quietly dies, because a thing with no edge can never be
8
+ finished. Your job is to force explicit in/out calls and refuse the
9
+ "everything, eventually" answer.
10
+
11
+ ## The moves
12
+
13
+ 1. **Get the sprawl on the table.** Ask: "list everything this could
14
+ possibly touch." Let them dump. You need the full candidate set before
15
+ you can cut it.
16
+
17
+ 2. **Draw two columns: IN and OUT.** Take each item and ask "in for this
18
+ round, or out?" Force every item into one column. "Maybe" is not a
19
+ column. If they can't decide, park it in a third list called LATER — but
20
+ LATER is a form of OUT for now, and say so.
21
+
22
+ 3. **Make OUT explicit, not implied.** The out-list is the valuable half.
23
+ Anything not consciously ruled out will creep back in. Ask "if someone
24
+ started working on [out item] next week, would that be wrong?" If yes,
25
+ it belongs in OUT in writing.
26
+
27
+ 4. **Name the edges.** For each boundary, get a crisp criterion, not a
28
+ vibe. Not "small customers are out" but "accounts under 50 seats are out
29
+ of scope for this round." A boundary you can't test at the edge will be
30
+ argued at the edge.
31
+
32
+ 5. **Pressure the in-list for feasibility.** Ask "with the time and people
33
+ we have, can we actually finish everything in IN?" If not, more items
34
+ move to OUT now. Scope you can't complete isn't scope, it's a wish.
35
+
36
+ 6. **Read it back as one instruction.** "This work covers X and Y. It does
37
+ not cover Z or W, and we're not deciding those here." Get a clean yes.
38
+
39
+ ## What good looks like
40
+
41
+ - **Two-sided** — states what's out as clearly as what's in. An in-list
42
+ alone is not a scope.
43
+ - **Testable at the edge** — for any borderline item, the boundary decides
44
+ it without a new debate.
45
+ - **Finishable** — the in-list fits the resources and time available.
46
+ - **Time-boxed** — scoped to "this round / this quarter", not forever.
47
+ Excluding something now doesn't mean never.
48
+ - **Stated as a decision** — reads as a call someone made, which means
49
+ someone can be asked to change it. "We're not touching billing this
50
+ round" beats "billing is complicated."
51
+
52
+ Worked example. A team wants to "fix the customer experience." Framed
53
+ scope: *"In: the signup-to-first-value flow for self-serve accounts. Out:
54
+ enterprise onboarding, the mobile app, and anything post-purchase — those
55
+ are separate work. Not deciding pricing changes here."* Now the work has an
56
+ edge, and a stray "but what about the mobile app?" has an answer.
57
+
58
+ ## Failure modes to catch
59
+
60
+ - **In-list only.** No out-list means no scope. Push until they'll name
61
+ what they're NOT doing.
62
+ - **"Everything, eventually."** The refusal to exclude. Reframe: "not
63
+ never — not this round. What's this round?"
64
+ - **Fuzzy edges.** "Big accounts" / "the core flows" — no test at the
65
+ boundary. Replace with a criterion someone can apply cold.
66
+ - **Scope that can't be finished.** An in-list bigger than the team can
67
+ ship. Cut it now, on purpose, rather than discovering it in week six.
68
+ - **Scope creep pre-loaded.** "In: the signup flow, and maybe also…" — the
69
+ "maybe also" is creep before you've started. Kill it or commit it.
70
+ - **Confusing scope with the challenge.** Scope bounds the WORK; the
71
+ challenge is the PROBLEM. If they're really unsure what problem they're
72
+ solving, go to `challenge.md` first — you can't scope work whose purpose
73
+ is undefined.
74
+
75
+ ## When they're really framing something else
76
+
77
+ - If the reason scope keeps sprawling is that they haven't chosen a
78
+ direction — every option stays open because no approach is committed —
79
+ they need `policy.md`, not a wider in-list.
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: skhema-operate
3
+ description: "Use when working with a Skhema workspace, the skhema CLI, the Skhema Public API, or Skhema MCP tools — creating or editing elements, searching and navigating a workspace, running validation, or any job that touches the live Skhema environment. Picks the right surface, gets you authenticated, and drives the work."
4
+ ---
5
+
6
+ # Operate
7
+
8
+ This skill is how an agent gets a job done inside the Skhema environment.
9
+ Unlike the practice skills, it assumes the product: a real workspace, a
10
+ credential, and one of three surfaces to act through. Its job is to route
11
+ you to the right surface, get you authenticated cleanly, and run the
12
+ concrete loop — author, navigate, validate — without fumbling.
13
+
14
+ Everything here is grounded in the real CLI. When in doubt about a flag or
15
+ command, run `skhema --help`, `skhema <command> --help`, or read the
16
+ generated reference at the docs site (`/docs/api/cli`). Do not guess flags.
17
+
18
+ ## Two things every command depends on
19
+
20
+ **The credential.** Almost nothing works without one. The CLI resolves
21
+ credentials in a fixed precedence — highest wins:
22
+
23
+ 1. `--api-key <key>` flag on the invocation
24
+ 2. `SKHEMA_API_KEY` environment variable
25
+ 3. a stored API key (`skhema auth key use`)
26
+ 4. an interactive OAuth session (`skhema auth login`)
27
+
28
+ If none resolves, the command exits **3** ("no usable credential"). That is
29
+ your signal to authenticate, not to retry.
30
+
31
+ **The org.** An API key is already bound to one organization. An OAuth
32
+ session is bound to whatever org you consented to; switch it with
33
+ `skhema auth switch <org-slug>`. Run `skhema auth status` any time to see
34
+ which credential is active and for which org.
35
+
36
+ ## The output contract
37
+
38
+ Pass `--json` on any command and you get a stable envelope:
39
+
40
+ ```json
41
+ { "ok": true, "command": "element.create", "data": { ... } }
42
+ { "ok": false, "command": "element.create", "error": { "message": "…" } }
43
+ ```
44
+
45
+ Branch on `ok`, read `data` or `error`. For scripts and agents, `--json` is
46
+ the default posture — parse the envelope instead of scraping human text.
47
+
48
+ **Exit codes are a stable contract.** Branch on them:
49
+
50
+ | Code | Meaning | What to do |
51
+ |---|---|---|
52
+ | 0 | success | continue |
53
+ | 1 | generic / API error | read the error, likely transient or a bad payload |
54
+ | 2 | usage error (bad args, caught before any API call) | fix the command |
55
+ | 3 | no usable credential | authenticate — see `references/auth.md` |
56
+ | 4 | permission or plan denied (403/402) | the credential can't do this; wrong scope, role, or plan |
57
+ | 5 | rate limited (429) | back off and retry |
58
+
59
+ ## Capability map
60
+
61
+ | You need to… | Route to |
62
+ |---|---|
63
+ | Decide CLI vs Public API vs MCP for this job | `references/surfaces.md` |
64
+ | Authenticate, fix an exit-3, or bind the right org | `references/auth.md` |
65
+ | Create or edit elements well in the environment | `references/author-elements.md` |
66
+ | Find things — workspaces, elements, strategies | `references/navigate.md` |
67
+ | Drive validate → fix → re-validate until it holds | `references/validation-loop.md` |
68
+
69
+ ## Routing
70
+
71
+ - **First job in a fresh runtime, or exit code 3?** Start at
72
+ `references/auth.md`. Nothing else works until a credential resolves.
73
+ - **Not sure whether to shell out, hit the API, or use MCP tools?** Read
74
+ `references/surfaces.md` first — the choice shapes everything after.
75
+ - **Writing strategy content** (challenges, policies, measures as elements)
76
+ → `references/author-elements.md`. Compose the strategy first with the
77
+ practice skills; this capability is about getting it INTO the workspace
78
+ correctly.
79
+ - **Reading the workspace** — what's here, where does X live, what does this
80
+ strategy contain → `references/navigate.md`.
81
+ - **You've authored something and want it to be sound** →
82
+ `references/validation-loop.md`. Note that `validate` and `rephrase` are
83
+ AI actions and cost budget; the reference tells you how to spend it well.
84
+
85
+ ## Set a default workspace once
86
+
87
+ Most commands take `--workspace <id>` but fall back to a stored default.
88
+ Set it once with `skhema workspace use <workspace-id>` and drop the flag
89
+ everywhere after. `skhema workspace use --clear` unsets it. If a command
90
+ errors asking for a workspace, you never set the default — set it or pass
91
+ the flag.
92
+
93
+ ## Without a live respondent
94
+
95
+ Run headless, with no one to answer? Don't invent their answers. Make the
96
+ minimal reasonable assumption, mark it in the output as yours ("assumed: …"),
97
+ and list the questions only the owner can settle — what's in scope, what a word
98
+ means, whose dissent to record — at the end instead of papering over them. A
99
+ marked assumption is honest work; a silent one is a guess you built on.
100
+
101
+ ## Sharpen with Skhema
102
+
103
+ This whole skill IS the Skhema environment — there is no product-absent
104
+ mode. If the CLI isn't present, `references/auth.md` starts with installing
105
+ it (`npm install -g @skhema/cli`). If you only need to onboard the runtime
106
+ (credential + skills + MCP server), that is the `skhema-setup` skill, not
107
+ this one.
@@ -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.