@graphit/cli 0.2.206 → 0.2.236
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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/bin/graphit +1 -1
- package/bin/graphit.ps1 +1 -1
- package/dist/api/client.d.ts +36 -0
- package/dist/api/client.js +42 -0
- package/dist/api/client.js.map +1 -1
- package/dist/auth/credentials.d.ts +0 -1
- package/dist/auth/credentials.js.map +1 -1
- package/dist/auth/login.js +0 -1
- package/dist/auth/login.js.map +1 -1
- package/dist/commands/auth.js +0 -3
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/ds-poll.d.ts +2 -0
- package/dist/commands/ds-poll.js +13 -0
- package/dist/commands/ds-poll.js.map +1 -1
- package/dist/commands/ds.js +158 -19
- package/dist/commands/ds.js.map +1 -1
- package/dist/commands/status.d.ts +51 -0
- package/dist/commands/status.js +117 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/output/format.js +18 -1
- package/dist/output/format.js.map +1 -1
- package/package.json +1 -1
- package/scripts/generate-commands-doc.mjs +1 -1
- package/skills/graphit/SKILL.md +10 -5
- package/skills/graphit/VERSION.json +1 -1
- package/skills/graphit/references/data-sources.md +9 -3
- package/skills/graphit/references/governance-explained.md +1 -1
- package/skills/graphit/references/kb-actions.md +13 -2
- package/skills/graphit/references/operations.md +6 -10
package/dist/output/format.js
CHANGED
|
@@ -28,9 +28,15 @@ export function output(cmd, data, opts) {
|
|
|
28
28
|
export function note(message = "") {
|
|
29
29
|
console.error(message);
|
|
30
30
|
}
|
|
31
|
+
// Project #263: a denial reaches the caller with its machine-readable problem
|
|
32
|
+
// intact, alongside the human message. The message carries only the server's own
|
|
33
|
+
// safe `detail` and `next_step` - never a raw status code, a hidden resource
|
|
34
|
+
// name, or a locally invented explanation - and a denial always exits nonzero,
|
|
35
|
+
// so a deterministic "you cannot do this" can never read as success.
|
|
31
36
|
export function errorOutput(err) {
|
|
32
37
|
let message;
|
|
33
38
|
let retryAfter;
|
|
39
|
+
let problem;
|
|
34
40
|
if (err instanceof Error) {
|
|
35
41
|
message = err.message;
|
|
36
42
|
}
|
|
@@ -40,6 +46,9 @@ export function errorOutput(err) {
|
|
|
40
46
|
if (typeof obj.retry_after_seconds === "number") {
|
|
41
47
|
retryAfter = obj.retry_after_seconds;
|
|
42
48
|
}
|
|
49
|
+
if (obj.problem && typeof obj.problem === "object" && !Array.isArray(obj.problem)) {
|
|
50
|
+
problem = obj.problem;
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
else {
|
|
45
54
|
message = String(err);
|
|
@@ -47,7 +56,15 @@ export function errorOutput(err) {
|
|
|
47
56
|
if (retryAfter !== undefined) {
|
|
48
57
|
message = `${message} Retry in ${retryAfter}s.`;
|
|
49
58
|
}
|
|
50
|
-
|
|
59
|
+
// Read the field, never match the prose: the server owns the corrective step.
|
|
60
|
+
const nextStep = problem?.next_step;
|
|
61
|
+
if (typeof nextStep === "string" && nextStep && !message.includes(nextStep)) {
|
|
62
|
+
message = `${message} ${nextStep}`;
|
|
63
|
+
}
|
|
64
|
+
const payload = { error: message };
|
|
65
|
+
if (problem)
|
|
66
|
+
payload.problem = problem;
|
|
67
|
+
console.error(JSON.stringify(payload));
|
|
51
68
|
process.exit(1);
|
|
52
69
|
}
|
|
53
70
|
//# sourceMappingURL=format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/output/format.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoBzD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,OAAO,IAAI,CAAC,MAAM;QAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,MAAgB,CAAC;IAC5C,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACzC,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,GAAY,EACZ,IAAa,EACb,IAAiD;IAEjD,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAA+B,CAAC,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAiC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,8EAA8E;AAC9E,iFAAiF;AACjF,+EAA+E;AAC/E,MAAM,UAAU,IAAI,CAAC,OAAO,GAAG,EAAE;IAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,OAAe,CAAC;IACpB,IAAI,UAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/output/format.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -28,7 +28,7 @@ const END = "<!-- COMMANDS:END -->";
|
|
|
28
28
|
|
|
29
29
|
// Mirrors index.ts registration order; groups not listed are appended alphabetically.
|
|
30
30
|
const GROUP_ORDER = [
|
|
31
|
-
"auth", "kb", "query", "metadata", "ds", "dashboard",
|
|
31
|
+
"auth", "status", "kb", "query", "metadata", "ds", "dashboard",
|
|
32
32
|
"connector", "governance", "team", "plugin", "setup",
|
|
33
33
|
];
|
|
34
34
|
|
package/skills/graphit/SKILL.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
name: graphit
|
|
3
3
|
description: >-
|
|
4
4
|
Use Graphit for ANY question about the user's business or product data: metrics, KPIs, revenue, retention, spend, users, cohorts, funnels, trends, comparisons, "why did X change", "how are we doing on Y", analysis, reports, or dashboards. Activate even when the user does not say "Graphit" or name any tool: if someone wants to understand their numbers, this is the tool. Graphit answers through a governed semantic layer (computed the team's way, reusable and safe to share) and delivers the answer as a fast cached-data query or a hand-authored interactive HTML dashboard, and can create the metrics, dimensions, and rules an answer needs. Prefer Graphit over hand-rolled one-off analysis whenever the data is, or could be, the user's business data. Skip only for pure software tasks (code, logs, config, infra) or data with nothing to do with the user's business.
|
|
5
|
-
skill_version: "0.2.
|
|
5
|
+
skill_version: "0.2.236"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
<!-- SIZE EXEMPTION (SKILL.md): standard hard limit 12,288 chars, exempted ceiling
|
|
8
|
+
<!-- SIZE EXEMPTION (SKILL.md): standard hard limit 12,288 chars, exempted ceiling 29,696. Always-loaded: the collaboration/pace spine, hard constraints + scope gate, the loop, and the generated command table (COMMANDS markers, scripts/generate-commands-doc.mjs) - needed every turn, cannot defer to a reference. Marker sits after the frontmatter so the loader and sync-plugin-version.mjs parse it. Reviewed 2026-07-20. -->
|
|
9
9
|
|
|
10
10
|
# Graphit CLI
|
|
11
11
|
|
|
@@ -105,7 +105,7 @@ One loop serves both jobs. Each step names the reference to read when you need d
|
|
|
105
105
|
- Data source. `graphit kb explore domain <NAME>` returns that domain's data sources plus their metrics, dimensions, and rules in one traversal (`graphit ds list` for the full list); present the sources, ask which one, or offer to create one if none fits.
|
|
106
106
|
- Assets. Present the chosen source's metrics, dimensions, and rules as the working set and confirm it. If the user's wording doesn't match an asset, resolve it with `graphit kb search` (semantic, ranked by relevance) before assuming a mapping; for a cross-domain investigation, broaden across the whole KB. A 0-result search is not proof of absence (results are ranked and capped) - confirm a specific name with `kb get` first. Then proceed.
|
|
107
107
|
Ask via the structured ask-user tool above, options pre-populated from what you listed. Read references/kb-discovery.md, references/kb-traversal.md, references/data-sources.md.
|
|
108
|
-
3. KB-readiness gate (BLOCKING). Check the knowledge base has the metrics and dimensions this question needs - name them from the user's ask and the domain's real assets you just listed. If they exist, proceed. If any are missing, STOP and build the knowledge base first: identify the missing concepts, show a gap table (what is missing, the proposed definition, which rules apply), get approval, then create and verify the assets. Read references/kb-structure.md, references/kb-actions.md, and references/parameterized-metrics.md for variant axes (D7/D30, gross/net). This gate is not optional - do not reframe it as the user's choice.
|
|
108
|
+
3. KB-readiness gate (BLOCKING). Check the knowledge base has the metrics and dimensions this question needs - name them from the user's ask and the domain's real assets you just listed. If they exist, proceed. If any are missing, STOP and build the knowledge base first: identify the missing concepts, show a gap table (what is missing, the proposed definition, which rules apply), get approval, then create and verify the assets. Run `graphit status` first for the domains you can write to - advisory (the server still decides). Read references/kb-structure.md, references/kb-actions.md, and references/parameterized-metrics.md for variant axes (D7/D30, gross/net). This gate is not optional - do not reframe it as the user's choice.
|
|
109
109
|
4. Investigate. Write governed queries with `{{metric:NAME}}` / `{{dim:NAME}}` reference syntax, validate before you rely on them, show the rows, then propose the next cut or the first graph before building it. Ad-hoc only at the frontier, provenance-tagged. Read references/sql-reference.md, references/governance.md.
|
|
110
110
|
5. Deliver. A quick query result for a one-off; a designed HTML dashboard for anything recurring or shared; or a written report artifact - insight digest, analysis one-pager, postmortem - when narrative should lead. Build and show one section at a time, not one finished deliverable at the end. Pull only the reference for the move you are making:
|
|
111
111
|
- Frame and plan the dashboard (or report artifact): references/dashboard-planning.md.
|
|
@@ -154,7 +154,7 @@ Read the one that matches what you are doing now. Do not preload them. Exact com
|
|
|
154
154
|
|
|
155
155
|
## Commands
|
|
156
156
|
|
|
157
|
-
Graphit is one CLI, but how you invoke it depends on your environment. On Claude Code the plugin provides a `graphit` wrapper, so `graphit <command>` runs the current CLI. On Codex, Cursor, a terminal, or CI there is no `graphit` wrapper - invoke the CLI explicitly with `npx -y @graphit/cli@0.2.
|
|
157
|
+
Graphit is one CLI, but how you invoke it depends on your environment. On Claude Code the plugin provides a `graphit` wrapper, so `graphit <command>` runs the current CLI. On Codex, Cursor, a terminal, or CI there is no `graphit` wrapper - invoke the CLI explicitly with `npx -y @graphit/cli@0.2.236 <command>` (a stamped version, kept current by the build; pin an exact version for a reproducible run). The table below is generated from the CLI itself. For exact flags, run `graphit <command> --help` - never guess a flag.
|
|
158
158
|
|
|
159
159
|
<!-- COMMANDS:START -->
|
|
160
160
|
|
|
@@ -165,6 +165,9 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
165
165
|
- `auth status` - Show current authentication status
|
|
166
166
|
- `auth logout` - Log out and clear stored credentials
|
|
167
167
|
|
|
168
|
+
**status** - Show your effective permissions per domain (advisory; the server re-authorizes every operation)
|
|
169
|
+
- `status` - Show your effective permissions per domain (advisory; the server re-authorizes every operation)
|
|
170
|
+
|
|
168
171
|
**kb** - Knowledge Base operations
|
|
169
172
|
- `kb list <type>` - List KB entities (metric, dimension, table, rule, domain, synonym) - the inventory verb. Parameterized metrics are collapsed: each template shows a variant_count, child variants are hidden. Use --include-variants for the full flat set, kb explore metric <name> to enumerate one template's variants, kb get for the full definition. The response carries total/truncated, so fewer rows than total means raise --limit. - `--limit --verified --unverified --include-variants`
|
|
170
173
|
- `kb get <type> <name>` - Get a KB entity by name
|
|
@@ -201,10 +204,12 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
201
204
|
|
|
202
205
|
**ds** - Data source management
|
|
203
206
|
- `ds refresh-history <id>` - Show recent refresh runs for a data source with the Snowflake query id per run (status, time, rows, duration). Runs from before query-id capture - or a failure before any query ran - show 'not captured'. Read-only; no ds refresh-history delete. - `--limit`
|
|
207
|
+
- `ds delete <id>` - Delete a data source - not available on the CLI, use the Sources Hub
|
|
208
|
+
- `ds move <id>` - Move a data source between domains - not available on the CLI, use the Sources Hub
|
|
204
209
|
- `ds list` - List data sources - `--limit`
|
|
205
210
|
- `ds create` - Create a data source from a SQL query (--sql) or a local Excel/CSV file (--file) - `--sql --name --connection --schema --skip-scan --detect-tables --source-tables --file --domain --sheet`
|
|
206
211
|
- `ds refresh [ids...]` - Refresh data sources (use --all for all, or pass one or more IDs). On a breaking schema change a refresh is paused (status 'schema_changed') and the old data keeps serving; re-run with --force to accept the new schema. - `--all --no-wait --skip-empty --force`
|
|
207
|
-
- `ds verify <id>` - Scan an unverified data source's schema and review it. Warehouse/SQL sources print a verification link; add --accept-schema to accept the AI schema and activate from the CLI. File uploads activate
|
|
212
|
+
- `ds verify <id>` - Scan an unverified data source's schema and review it, and activate it. Warehouse/SQL sources print a verification link; add --accept-schema to accept the AI schema and activate from the CLI. File uploads activate on this command without --accept-schema, but NOT on create: `ds create --file` leaves them at pending_verification until you run this. Requires data_source_write in the source's domain. - `--force --accept-schema`
|
|
208
213
|
- `ds update <id>` - Update a data source row cap - `--max-rows`
|
|
209
214
|
- `ds refresh-config <id>` - Configure a data source's refresh mode (full or incremental/watermark) and settings. Sets the complete incremental config each call - omitted flags reset to server defaults (e.g. omitting --table-lookback clears existing lookback windows). - `--mode --watermark-column --watermark-type --merge-key --merge-window --table-lookback --reconciliation`
|
|
210
215
|
|
|
@@ -55,7 +55,7 @@ graphit ds create --name "MY_DS" --sql "SELECT ..." --skip-scan
|
|
|
55
55
|
|
|
56
56
|
**Warehouse connection.** `--connection` names the warehouse a `--sql` source reads from. Add BigQuery with `graphit connector add bigquery-serviceaccount --key-file <path> [--project --dataset --location]` (org admin; project defaults from the key). The pipeline routes by connection type - the same `ds create` works for either warehouse.
|
|
57
57
|
|
|
58
|
-
For existing unverified sources, `graphit ds verify <id>` scans and shows the schema; add `--accept-schema` to accept the AI schema and activate a warehouse/SQL source from the CLI
|
|
58
|
+
For existing unverified sources, `graphit ds verify <id>` scans and shows the schema; add `--accept-schema` to accept the AI schema and activate a warehouse/SQL source from the CLI. A file upload needs `ds verify` too - it activates without `--accept-schema`, but never at create time, so it stays unqueryable until you run it.
|
|
59
59
|
|
|
60
60
|
## Refreshing data sources
|
|
61
61
|
|
|
@@ -80,7 +80,7 @@ Refreshes fire in parallel; polls to completion (large sources 30-60s), or retur
|
|
|
80
80
|
|
|
81
81
|
## Incremental refresh and early-filtering (advanced)
|
|
82
82
|
|
|
83
|
-
Incremental mode fetches only rows past a watermark and merges them in. Three windows govern it: the **watermark column** (which output rows are new), the **merge window** (`--merge-window` - how far back each run re-fetches and upserts, healing late data; API responses call it `lookback_periods`), and per-table **lookback windows** (`--table-lookback` - how far back each source table is *read*). Set on a scanned source
|
|
83
|
+
Incremental mode fetches only rows past a watermark and merges them in. Three windows govern it: the **watermark column** (which output rows are new), the **merge window** (`--merge-window` - how far back each run re-fetches and upserts, healing late data; API responses call it `lookback_periods`), and per-table **lookback windows** (`--table-lookback` - how far back each source table is *read*). Set on a scanned source; each call sets the COMPLETE config - omitted flags reset to defaults (no `--table-lookback` = windows cleared).
|
|
84
84
|
|
|
85
85
|
When a source aggregates over a wide internal window (e.g. a multi-year rollup), incremental refresh is nearly as slow as full: the outer watermark filter can't prune the inner scan. Early-filtering fixes that - get the contract right first, or older periods silently corrupt on merge:
|
|
86
86
|
|
|
@@ -104,9 +104,15 @@ graphit ds refresh-config <id> --mode incremental \
|
|
|
104
104
|
|
|
105
105
|
Only early-filter when an incremental source is slow for this reason; the default refresh is correct and simpler otherwise.
|
|
106
106
|
|
|
107
|
+
## What needs write access
|
|
108
|
+
|
|
109
|
+
Querying a source, listing sources, reading schema or refresh history, and an ordinary `graphit ds refresh` are reads - any member who can read that source's domain can run them, and a source in a domain they cannot read returns the same uniform 404 as one that does not exist. These need `data_source_write` in the source's domain: `ds create`, editing its SQL, `ds refresh-config`, a `--force` refresh or accepting a schema, `ds verify`, scanning, per-source governance settings, and deletion. Moving a source to another domain needs write in both the old and the new domain, and `ds create` must name a domain the caller can write to.
|
|
110
|
+
|
|
111
|
+
Check `graphit status` for those domains before proposing a create or a config change. It is advisory - the server authorizes each operation when it runs, and a denial with `retryable: false` is a stop, not a retry (`operations.md`).
|
|
112
|
+
|
|
107
113
|
## Deleting data sources
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
`ds delete` is not available on the CLI. Deleting a data source cascades to storage and the KB table, removing all metrics, dimensions, and rules on it. Direct the user to the platform UI (Sources Hub), whose confirmation flow shows what will be affected.
|
|
110
116
|
|
|
111
117
|
## Presenting data source results
|
|
112
118
|
|
|
@@ -33,7 +33,7 @@ Enforcement is server-side and identical on every channel (agent, CLI, dashboard
|
|
|
33
33
|
| Unenforced rule | A rule that structurally cannot act on anything |
|
|
34
34
|
| Missing owner | Assets with nobody responsible for them |
|
|
35
35
|
|
|
36
|
-
Fix is a guided one-click resolution: it drafts and previews the exact change, you apply it (
|
|
36
|
+
Fix is a guided one-click resolution: it drafts and previews the exact change, you apply it (same validation as a manual edit), then Graphit re-checks and clears the card. This queue lives only in the **web app's Governance page** - the CLI cannot list or fix Insights cards (`governance status` and `governance audit` report conformance only). When a user asks about a finding, explain what it means and point them to the Governance page to Fix it.
|
|
37
37
|
|
|
38
38
|
## Relaying it
|
|
39
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# KB Actions (Execute)
|
|
2
2
|
|
|
3
|
-
The execute side of KB work: run approved create / update / delete through the `graphit kb` commands. The plan side - what a domain or topic is, why an asset sits where it does - lives in `kb-structure.md`.
|
|
3
|
+
The execute side of KB work: run approved create / update / delete through the `graphit kb` commands. The plan side - what a domain or topic is, why an asset sits where it does - lives in `kb-structure.md`.
|
|
4
4
|
|
|
5
5
|
Create only after the user approves the gap plan below. Names are stored UPPER_SNAKE_CASE. Run `graphit kb create <type> --help` for the exact flag spelling - this file teaches the recipes and policy, the CLI owns the syntax.
|
|
6
6
|
|
|
@@ -77,7 +77,18 @@ Reference a **metric or dimension** onto another table with `graphit kb update m
|
|
|
77
77
|
|
|
78
78
|
Domain is set on the TABLE, never per asset, and cascades to every asset on it (model in `kb-structure.md`). To re-home a whole table at once: `graphit kb update table NAME --domain MARKETING`. Change it once on the table, never asset by asset.
|
|
79
79
|
|
|
80
|
-
##
|
|
80
|
+
## Who can write what
|
|
81
|
+
|
|
82
|
+
Reads are open to every member; writes are scoped by the caller's data access profile. Check `graphit status` before presenting a gap plan, so the plan is one they can execute.
|
|
83
|
+
|
|
84
|
+
| Write | Needs |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Metric, dimension, rule, synonym, relationship, table | `kb_write` in the asset's domain |
|
|
87
|
+
| Moving an asset or table to another domain | `kb_write` in BOTH domains - the one it leaves and the one it enters |
|
|
88
|
+
| Domain and topic create / update / delete | Org admin; a profile never grants it |
|
|
89
|
+
| Template create / update / delete | Org admin, OR `kb_write` in any one domain - never a per-template or per-domain grant |
|
|
90
|
+
|
|
91
|
+
Every member can read and use templates. Status is advisory; a denial with `retryable: false` is a stop, not a retry (`operations.md`).
|
|
81
92
|
|
|
82
93
|
To find what exists and how it connects, use the read recipes in `kb-traversal.md`.
|
|
83
94
|
|
|
@@ -2,14 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Load this when the concern is the Graphit CLI or plugin itself, not the analysis: the session-start check, a health check, a permission error (403/404/423), the output contract, or local working artifacts. Skip it on every healthy build or query turn.
|
|
4
4
|
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- [Session start](#session-start)
|
|
8
|
-
- [Health gate](#health-gate)
|
|
9
|
-
- [Permission errors](#permission-errors)
|
|
10
|
-
- [Output contract](#output-contract)
|
|
11
|
-
- [Working artifacts](#working-artifacts)
|
|
12
|
-
|
|
13
5
|
Depth that lives elsewhere: installing, updating, or repairing Graphit -> references/install-update.md. Reporting a failure or a partial result -> references/reporting.md.
|
|
14
6
|
|
|
15
7
|
Governance itself is enforced server-side by the query gateway: a governed query is rejected by the platform, not the CLI, so never claim to have blocked a query locally. The one local guard is a session tripwire - until this skill attests at session start (below), the CLI declines commands that change org state or that assert a governance decision (`--adhoc-reason`, `--override-rules`, `--skip-conditional`). That guard is about this session, never about the query itself, and dropping those flags does not skip governance - the server still decides.
|
|
@@ -46,10 +38,14 @@ The CLI enforces the same permission model as the platform. Three codes:
|
|
|
46
38
|
|
|
47
39
|
| Code | Meaning | What to tell the user |
|
|
48
40
|
|---|---|---|
|
|
49
|
-
| 403 |
|
|
50
|
-
| 404 | Not found, or no access |
|
|
41
|
+
| 403 | Your org role or data access profile does not allow this | Every signed-in member can use the CLI. This action needs more than the caller has: connector create/delete needs org owner or admin, and data source or knowledge-base writes are limited to the domains an admin granted on their data access profile. |
|
|
42
|
+
| 404 | Not found, or no access | A permission 404 is uniform across a resource that does not exist, one the caller cannot see, and another org's id - deliberately indistinguishable, to prevent id enumeration (some older routes still name the missing entity). Never assume the thing is gone or tell the user it was deleted. |
|
|
51
43
|
| 423 | Shared dashboard needs an active editing session | Catch one from the CLI: `graphit dashboard edit <id>` acquires the session and starts a draft; make the edits, then `graphit dashboard publish <id>` to go live (or `graphit dashboard release <id> --yes` to abandon). 409 = someone else is editing; 423 = locked; 403 = view-only. Private dashboards need no session. |
|
|
52
44
|
|
|
45
|
+
A 403 body is structured: `code` (e.g. `domain.kb_write_required`), `required_capability`, `retryable`, `next_step`. Read those fields, never the prose. `retryable: false` is a decision, not a hiccup - stop, give the user the `next_step`, and never retry, route around it, or report the write as done. A 404 carries none of those by design.
|
|
46
|
+
|
|
47
|
+
`graphit status` lists the caller's writable domains and Templates result - check it before planning writes, never reuse an older answer. Advisory only: the server re-authorizes every operation, so neither a past status nor a command's existence is permission.
|
|
48
|
+
|
|
53
49
|
For the exact remediation flags on the failed command, run it with `--help`.
|
|
54
50
|
|
|
55
51
|
## Output contract
|