@graphit/cli 0.2.355 → 0.2.357

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.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "Graphit CLI plugin for AI coding assistants",
10
- "version": "0.2.355"
10
+ "version": "0.2.357"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -16,9 +16,9 @@
16
16
  "source": {
17
17
  "source": "npm",
18
18
  "package": "@graphit/cli",
19
- "version": "0.2.355"
19
+ "version": "0.2.357"
20
20
  },
21
- "version": "0.2.355",
21
+ "version": "0.2.357",
22
22
  "category": "data-visualization",
23
23
  "tags": [
24
24
  "bi",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphit",
3
- "version": "0.2.355",
3
+ "version": "0.2.357",
4
4
  "description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
5
5
  "author": {
6
6
  "name": "Graphit",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphit",
3
- "version": "0.2.355",
3
+ "version": "0.2.357",
4
4
  "description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
5
5
  "author": {
6
6
  "name": "Graphit",
package/bin/graphit CHANGED
@@ -14,7 +14,7 @@ if [ -z "${GRAPHIT_PLUGIN_ROOT:-}" ]; then
14
14
  fi
15
15
 
16
16
  # graphit:floor (stamped by scripts/sync-plugin-version.mjs from cli/package.json)
17
- FLOOR_VERSION="0.2.355"
17
+ FLOOR_VERSION="0.2.357"
18
18
 
19
19
  PACKAGE_NAME="@graphit/cli"
20
20
  # Strict semver: anything else is rejected so a tampered cache cannot inject.
package/bin/graphit.ps1 CHANGED
@@ -7,7 +7,7 @@ if (-not $env:GRAPHIT_PLUGIN_ROOT) {
7
7
  }
8
8
 
9
9
  # graphit:floor (stamped by scripts/sync-plugin-version.mjs from cli/package.json)
10
- $FloorVersion = "0.2.355"
10
+ $FloorVersion = "0.2.357"
11
11
 
12
12
  $PackageName = "@graphit/cli"
13
13
  # Strict semver: anything else is rejected so a tampered cache cannot inject.
@@ -1,2 +1,4 @@
1
1
  import { Command } from "commander";
2
+ /** Read the bounded owner authorization body without accepting arbitrary JSON. */
3
+ export declare function parseNumericAuthorizationFile(path: string): Record<string, unknown>;
2
4
  export declare function registerGovernanceCommands(program: Command): void;
@@ -1,5 +1,36 @@
1
+ import { readFileSync, statSync } from "node:fs";
1
2
  import { apiClient } from "../api/client.js";
2
3
  import { output, errorOutput, note } from "../output/format.js";
4
+ const NUMERIC_AUTHORIZATION_MAX_FILE_KIB = 64;
5
+ const NUMERIC_AUTHORIZATION_MAX_FILE_BYTES = NUMERIC_AUTHORIZATION_MAX_FILE_KIB * 1024;
6
+ /** Read the bounded owner authorization body without accepting arbitrary JSON. */
7
+ export function parseNumericAuthorizationFile(path) {
8
+ if (statSync(path).size > NUMERIC_AUTHORIZATION_MAX_FILE_BYTES) {
9
+ throw new Error(`Numeric authorization file exceeds the ${NUMERIC_AUTHORIZATION_MAX_FILE_KIB} KiB limit`);
10
+ }
11
+ const raw = readFileSync(path, "utf-8");
12
+ let parsed;
13
+ try {
14
+ parsed = JSON.parse(raw);
15
+ }
16
+ catch {
17
+ // A malformed file is the caller's input, never a CLI defect: a raw
18
+ // SyntaxError would be framed as one by errorOutput.
19
+ throw new Error("Numeric authorization file is not valid JSON");
20
+ }
21
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22
+ throw new Error("Numeric authorization file must contain a JSON object");
23
+ }
24
+ return parsed;
25
+ }
26
+ function parseRevision(raw) {
27
+ if (!/^\d+$/.test(raw))
28
+ throw new Error("--revision must be a non-negative integer");
29
+ const revision = Number(raw);
30
+ if (!Number.isSafeInteger(revision))
31
+ throw new Error("--revision is outside the supported integer range");
32
+ return revision;
33
+ }
3
34
  export function registerGovernanceCommands(program) {
4
35
  const gov = program.command("governance").description("Query governance management");
5
36
  gov
@@ -61,5 +92,53 @@ export function registerGovernanceCommands(program) {
61
92
  errorOutput(err);
62
93
  }
63
94
  });
95
+ const numeric = gov
96
+ .command("numeric")
97
+ .description("Inspect or override the numeric rollup authorization of a data source");
98
+ numeric
99
+ .command("show")
100
+ .description("Show the numeric authorization in force for a data source (platform default or admin override)")
101
+ .requiredOption("--source <id>", "Data source id")
102
+ .action(async function () {
103
+ try {
104
+ const { source } = this.opts();
105
+ const resp = await apiClient.get(`/api/v1/cli/governance/numeric/${encodeURIComponent(source)}`);
106
+ output(this, resp, { keyValue: true });
107
+ }
108
+ catch (err) {
109
+ errorOutput(err);
110
+ }
111
+ });
112
+ numeric
113
+ .command("grant")
114
+ .description("Override the platform default numeric authorization for a data source from a JSON file")
115
+ .requiredOption("--source <id>", "Data source id")
116
+ .requiredOption("--file <path>", "JSON authorization body")
117
+ .action(async function () {
118
+ try {
119
+ const { source, file } = this.opts();
120
+ const resp = await apiClient.put(`/api/v1/cli/governance/numeric/${encodeURIComponent(source)}`, parseNumericAuthorizationFile(file));
121
+ output(this, resp, { keyValue: true });
122
+ }
123
+ catch (err) {
124
+ errorOutput(err);
125
+ }
126
+ });
127
+ numeric
128
+ .command("revoke")
129
+ .description("Switch rollup acceleration off for a data source by revoking its numeric authorization")
130
+ .requiredOption("--source <id>", "Data source id")
131
+ .requiredOption("--revision <n>", "Expected authorization revision")
132
+ .action(async function () {
133
+ try {
134
+ const { source, revision: rawRevision } = this.opts();
135
+ const revision = parseRevision(rawRevision);
136
+ const resp = await apiClient.delete(`/api/v1/cli/governance/numeric/${encodeURIComponent(source)}?expected_revision=${revision}`);
137
+ output(this, resp, { keyValue: true });
138
+ }
139
+ catch (err) {
140
+ errorOutput(err);
141
+ }
142
+ });
64
143
  }
65
144
  //# sourceMappingURL=governance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"governance.js","sourceRoot":"","sources":["../../src/commands/governance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhE,MAAM,UAAU,0BAA0B,CAAC,OAAgB;IACzD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,6BAA6B,CAAC,CAAC;IAErF,GAAG;SACA,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,KAAK;QACX,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAC9B,+BAA+B,CAChC,CAAC;YACF,wEAAwE;YACxE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,IAAI,IAAI,CAAC,gBAAgB;gBAAE,IAAI,CAAC,qBAAqB,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,cAAyC,CAAC;YAC5D,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,sBAAsB,CAAC,CAAC;gBAC7B,IAAI,CAAC,eAAe,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,eAAe,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC,eAAe,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxC,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,eAAe,EAAE,mDAAmD,EAAE,GAAG,CAAC;SACjF,MAAM,CAAC,eAAe,EAAE,0CAA0C,CAAC;SACnE,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;SAC9C,MAAM,CAAC,qBAAqB,EAAE,sDAAsD,CAAC;SACrF,MAAM,CAAC,aAAa,EAAE,0CAA0C,EAAE,IAAI,CAAC;SACvE,MAAM,CAAC,KAAK;QACX,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,IAAI;gBAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAEtD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAC9B,gCAAgC,MAAM,EAAE,CACzC,CAAC;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAmC,CAAC;YACxD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACjB,IAAI,CAAC,4BAA4B,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE;gBACnB,OAAO,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"governance.js","sourceRoot":"","sources":["../../src/commands/governance.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphit/cli",
3
- "version": "0.2.355",
3
+ "version": "0.2.357",
4
4
  "description": "Graphit CLI - Build custom dashboards from any AI coding assistant",
5
5
  "repository": {
6
6
  "type": "git",
@@ -686,6 +686,30 @@
686
686
  "requires_approval": false,
687
687
  "silent_retry_exempt": false
688
688
  },
689
+ "governance numeric show": {
690
+ "surface": "cli_only",
691
+ "is_read_only": true,
692
+ "mutation_class": "none",
693
+ "requires_approval": false,
694
+ "silent_retry_exempt": true,
695
+ "reason": "Operator read for the admin who overrides a source's numeric rollup contract: it shows the authorization in force (the platform default or their override) plus the exact query-family and schema/runtime identities an override file must name. Those identities only mean something next to the override file on the admin's disk. An in-app turn has no such file and never explains why a graph was or was not accelerated through this surface - acceleration is silent and the ordinary path always answers."
696
+ },
697
+ "governance numeric grant": {
698
+ "surface": "cli_only",
699
+ "is_read_only": false,
700
+ "mutation_class": "governance",
701
+ "requires_approval": true,
702
+ "silent_retry_exempt": true,
703
+ "reason": "Replaces the platform default numeric contract for one data source with the org admin's own (tighter error limits, fewer finalizers or families, an expiry). Nobody needs this to get acceleration. The body is a reviewed JSON file on the admin's disk, and the override is the admin's own decision, not something an in-app agent turn should draft or submit on their behalf."
704
+ },
705
+ "governance numeric revoke": {
706
+ "surface": "cli_only",
707
+ "is_read_only": false,
708
+ "mutation_class": "governance",
709
+ "requires_approval": true,
710
+ "silent_retry_exempt": true,
711
+ "reason": "The off switch for one source's rollup acceleration: compare-and-set on the revision the admin read with show (0 for the platform default). It stays on the surface that installs overrides so switching acceleration off is never an in-app side effect of a data question."
712
+ },
689
713
  "team list": {
690
714
  "surface": "cli_only",
691
715
  "is_read_only": true,
@@ -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.355"
5
+ skill_version: "0.2.357"
6
6
  ---
7
7
 
8
- <!-- SIZE EXEMPTION (SKILL.md): hard limit 12,288 chars, exempted ceiling 34,048. Reviewed 2026-09-10. Always-loaded: the collaboration/pace spine, hard constraints + scope gate, the loop, and the generated command table (COMMANDS markers; cli/scripts/generate-commands-doc.mjs) - needed every turn, not deferrable. Marker sits after the frontmatter so the loader and sync-plugin-version.mjs parse it. Raises pay only for command-table growth; each is recorded in docs/knowledge/prompt-engineering/sizing/SIZING.md, prose changes in docs/workflow/prompt-changes/INDEX.md. -->
8
+ <!-- SIZE EXEMPTION (SKILL.md): hard limit 12,288 chars, exempted ceiling 34,560. Reviewed 2026-09-17. Always-loaded: the collaboration/pace spine, hard constraints + scope gate, the loop, and the generated command table (COMMANDS markers; cli/scripts/generate-commands-doc.mjs) - needed every turn, not deferrable. Marker sits after the frontmatter so the loader and sync-plugin-version.mjs parse it. Raises pay only for command-table growth; each is recorded in docs/knowledge/prompt-engineering/sizing/SIZING.md, prose changes in docs/workflow/prompt-changes/INDEX.md. -->
9
9
 
10
10
  # Graphit CLI
11
11
 
@@ -92,7 +92,7 @@ Soft narration is what "just build it" drops. These hard stops hold even then: c
92
92
  ### Handoffs, failure, truthful reporting
93
93
 
94
94
  - Name the handoffs. Some actions live on the platform, not the CLI: visiting a data source's verification link, deleting a source from the Sources Hub. Say when a step hands control back to the user, and move between building the dashboard and building the knowledge base through the gate.
95
- - Keep scratch files together. In repository-owned workflows, `.graphit/` holds durable KB definitions: never ignore or delete it as scratch. Read repo-preparation.md before authoring those files; other local artifacts follow operations.md.
95
+ - Keep scratch files together. In repository-owned workflows `.graphit/` is durable source, never scratch: read repo-preparation.md before authoring it; other local artifacts follow operations.md.
96
96
  - On failure: retry once if it looks transient (timeout, rate limit); on a real error (missing column, permission, validation) stop, say what failed and the next step, never a bare "something went wrong".
97
97
  - Report truthfully: what worked, what did not, what you are unsure of. If only part succeeded, say which part and why the rest did not. Done means the answer is delivered and every dashboard element resolves on real data with no entity_sql_warnings.
98
98
 
@@ -145,11 +145,13 @@ Load only the relevant reference. Check `graphit <command> --help` for flags.
145
145
  | preparing a repository-owned KB from repository docs | repo-preparation.md |
146
146
  | a brand-new or empty workspace, nothing connected yet | onboarding.md |
147
147
  | scoping to a domain, data source, and assets | kb-discovery.md, kb-traversal.md, data-sources.md |
148
- | a repository-owned (`manual`) org: verify, CI tokens, Data Sources via PR | references/repo-kb.md |
148
+ | connecting a repository as KB owner: bind, PR, identities, CI tokens | references/repo-setup.md |
149
+ | a bound repository-owned (`manual`) org: verify, refusals, Data Sources via PR | references/repo-kb.md |
149
150
  | building or curating semantic assets (the gate) | kb-structure.md, kb-scope.md, kb-actions.md, semantic-authoring.md, metric-families.md |
150
151
  | a business-knowledge, schema, ERD, or data-dictionary document should inform semantic definitions | attached-docs.md |
151
152
  | data-source refresh modes, incremental settings, or reconciliation | data-source-refresh.md |
152
153
  | writing or validating a query | sql-reference.md, governance.md |
154
+ | rollup acceleration for a data source: inspect, switch off, override | governance.md |
153
155
  | a user is confused about governance itself - what governed means, why a query was blocked, how it works | governance-explained.md |
154
156
  | creating, designing and rendering a dashboard | dashboard-create.md, dashboard-planning.md, chart-selection.md, chart-patterns.md, graphit-style.md, runtime.md, kpi.md, table.md |
155
157
  | adding interactivity (filters, parameters, saved views) | filters.md, filters-advanced.md, state-contract.md |
@@ -164,7 +166,7 @@ Load only the relevant reference. Check `graphit <command> --help` for flags.
164
166
 
165
167
  ## Commands
166
168
 
167
- Claude Code supplies the `graphit` wrapper. On Codex, Cursor, terminals and CI, use `npx -y @graphit/cli@0.2.355 <command>`; pin a version for reproducibility. The table is generated from the CLI; check command help for exact flags.
169
+ Claude Code supplies the `graphit` wrapper. On Codex, Cursor, terminals and CI, use `npx -y @graphit/cli@0.2.357 <command>`; pin a version for reproducibility. The table is generated from the CLI; check command help for exact flags.
168
170
 
169
171
  <!-- COMMANDS:START -->
170
172
 
@@ -270,6 +272,9 @@ _Generated by `npm run gen:commands`; do not hand-edit between the markers._
270
272
  **governance** - Query governance management
271
273
  - `governance status` - Show governance conformance summary
272
274
  - `governance audit` - Query the governance audit log - `--last --tier --user --channel --limit`
275
+ - `governance numeric show` - Show the numeric authorization in force for a data source (platform default or admin override) - `--source`
276
+ - `governance numeric grant` - Override the platform default numeric authorization for a data source from a JSON file - `--source --file`
277
+ - `governance numeric revoke` - Switch rollup acceleration off for a data source by revoking its numeric authorization - `--source --revision`
273
278
 
274
279
  **team** - Team management
275
280
  - `team list` - List teams you belong to (org admins see all teams)
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@graphit/cli",
3
- "version": "0.2.355",
3
+ "version": "0.2.357",
4
4
  "source": "cli/package.json"
5
5
  }
@@ -35,3 +35,13 @@ Search the KB genuinely, explain why visible definitions do not fit, and prefer
35
35
  ## Reporting
36
36
 
37
37
  Report tier, semantic references, row cap, visible rules that changed the query, and any refusal or override. Read the receipt rather than inferring. A blocked or partial result is not success.
38
+
39
+ ## Numeric rollup authorization
40
+
41
+ Org admins only, and never required. Every prepared data source carries the platform default numeric contract, so prepared rollups may answer governed queries with nothing installed. The server measures each exact query against the source before serving it, renews that evidence on its own after data refreshes and expiry, and sends anything outside the contract down the ordinary path. Acceleration is silent; never claim a result came from a rollup.
42
+
43
+ - `governance numeric show --source <id>` - the contract in force plus the query families, schema fingerprint and compiler/runtime versions an override must name. Acceleration is on only while `status` is `active`; a revoked record still says `platform_default: true`, so read `status` and `revision`, never that flag.
44
+ - `governance numeric revoke --source <id> --revision <n>` - switch acceleration off for one source; `n` is the revision `show` returned (0 for the platform default). Serving stops at the next request. There is no un-revoke: only a later `grant` quoting the revoked revision turns acceleration back on, so confirm with the admin before running it.
45
+ - `governance numeric grant --source <id> --file override.json` - replace the default for one source with tighter bounds. Body: `expected_revision`, `schema_fingerprint`, `compiler_version`, `runtime_version`, `query_families` (only families listed by `show`), `mode` (`exact` or `scoped_float`), `allowed_finalizers`, `absolute_error_limit` and `relative_error_limit` (required for `scoped_float`; both caps are enforced independently), `evidence_ttl_seconds`, `expires_at`, `reason`.
46
+
47
+ Never invent error limits for the admin: report what `show` returns and let them decide whether an override is wanted at all.
@@ -1,6 +1,6 @@
1
1
  # First Run: From an Empty Workspace to a First Dashboard
2
2
 
3
- Load this when the user is signed in but visible groups/models and `graphit ds list` are empty. Onboarding is the job, not a blocker: walk through it one step at a time and surface each result. Once a source and semantic assets exist, return to the normal loop.
3
+ Load this when the user is signed in but visible groups/models and `graphit ds list` are empty. If a repository is to own the Knowledge Base instead, that first run is `repo-setup.md`. Onboarding is the job, not a blocker: walk through it one step at a time and surface each result. Once a source and semantic assets exist, return to the normal loop.
4
4
 
5
5
  ## The arc
6
6
 
@@ -2,7 +2,9 @@
2
2
 
3
3
  Load when: `graphit kb repo show` reports `ownership_mode: manual` or `migrating`, a
4
4
  `.graphit/` tree exists, a shared KB or Data Source change was refused as repository-owned,
5
- or the user asks to set up, verify or sync the repository. A `managed` org never loads this.
5
+ or the user asks to verify or sync the repository. Connecting a repository for the first
6
+ time (no binding, no PR, no CI tokens, no import yet) is `repo-setup.md`, step by step;
7
+ this reference is the contract once it is bound. A `managed` org never loads this.
6
8
 
7
9
  ## Contract
8
10
 
@@ -18,14 +20,11 @@ Run `graphit kb repo show` first.
18
20
 
19
21
  - `managed`: this reference does not apply. Use the ordinary KB and Data Source verbs.
20
22
  - `manual` with a bound repository: the procedures below.
21
- - `manual` with no binding: initialize. Scaffold `.graphit/` per `repo-preparation.md`,
22
- run `graphit kb repo verify --path . --allow-dirty` (a `local_only` plan, never
23
- applyable; an uncommitted `.graphit/` is refused without the flag), fix findings until
24
- the verdict passes, commit on a branch, open the PR with the user's own tooling. Then tell an org admin to bind (`graphit kb repo bind --repo <owner/name> --branch main`;
25
- the connection resolves from the repository; on `connection_ambiguous` pass
26
- `--connection <id>` from `graphit connector list`'s `id` column, never the card's token
27
- fingerprint), link reviewers (`kb repo link-identity`) and mint the CI tokens
28
- (below). Those are admin actions you never run yourself.
23
+ - `manual` with no binding, or bound with `last_imported_sha` null: follow `repo-setup.md`
24
+ state by state. It scaffolds per `repo-preparation.md`, verifies with
25
+ `graphit kb repo verify --path . --allow-dirty`, and hands each admin step over one at a
26
+ time (`graphit kb repo bind`, `kb repo link-identity`, `kb repo token mint`); you never
27
+ run those yourself.
29
28
 
30
29
  ## A Data Source through a PR
31
30
 
@@ -68,11 +67,14 @@ Typed `{code, message}`; read the code, never the prose.
68
67
  | `apply_in_progress`, `migration_in_progress` | an apply or a migration holds the lease: wait, never cancel |
69
68
  | `not_on_base_branch`, `not_descendant_of_last_import`, `pr_head_mismatch`, `pull_request_not_merged`, `merged_commit_mismatch`, `pr_base_branch_mismatch` | verify the PR head; apply only its merged commit on the bound branch |
70
69
  | `pull_request_not_found`, `pull_request_list_unavailable` | no PR resolved for that commit, or the index is still warming: pass `--pr <id>` naming the merged PR; if unavailable, retry later |
71
- | `approvals_unavailable`, `no_head_bound_approvals`, `approval_head_binding_unprovable`, `identity_unlinked`, `identity_unverified`, `member_removed`, `approver_closure_uncovered`, `write_closure_uncovered` | check native PR approval, reviewer linkage and current Graphit permissions; incomplete or moved provider evidence refuses. Fix the cause, then verify again |
70
+ | `identity_unlinked`, `member_removed`, `pr_author_unavailable`, `provider_identity_mismatch`, `author_closure_uncovered`, `write_closure_uncovered` | the PR author must be a linked, current member whose KB write covers every touched group; reviewers are the provider's process. Fix the link or the permission, then verify again |
71
+ | `premerge_verification_required`, `pr_base_moved`, `pr_base_stale`, `pr_target_mismatch`, `pr_source_repository_unproven` | the PR must be open, from a branch in the bound repository, targeting the bound branch, its destination unchanged since verify; update it and verify again |
72
+ | `migration_required` | routine sync on a `managed` org: switch to `manual` first (repo-setup.md, state 0) |
72
73
  | `certificate_not_applyable`, `migration_requires_plan`, `migration_requires_commit`, `migration_mode_invalid`, `approved_sha_missing`, `approved_sha_mismatch` | migration only: the pre-delete `--kind migration` verify is a certificate; after the delete a fresh `--kind migration` verify yields the plan for `apply --plan <id>`; the SHA must match `bind --approved-sha` |
73
74
  | `token_invalid`, `token_revoked`, `token_scope`, `token_repo_mismatch` | CI token: mint a fresh one, use the right scope, mint for this repository |
74
75
 
75
- Operation status `failed_retryable`: retry once, then report. `refused` or a `fail`
76
+ Operation status `failed_retryable`: retry once, then report. `component_rejected`: the
77
+ write contract refused one asset; fix its file and verify again. `refused` or a `fail`
76
78
  verdict: never retry unchanged or route around it.
77
79
 
78
80
  ## Refusals inside the app
@@ -90,15 +92,12 @@ Report drafted, verified (local-only or provider), PR opened, merged and applied
90
92
  distinct states. Claim an apply only when you saw the operation reach terminal `succeeded`;
91
93
  quote the operation id, the plan id and the verdict. Queued or timed out is not done.
92
94
 
93
- ## CI in one paragraph
94
-
95
- Two jobs, two tokens, one pinned CLI version. Export `GRAPHIT_TOKEN` in the job
96
- environment, never as `--token` in argv or shell traces. The required PR check uses
97
- `kb:verify`: `graphit kb repo verify --sha $HEAD --pr $PR` (verify/status only).
98
- After the customer merges, the protected `kb:apply` job runs
99
- `graphit kb repo apply --sha $MERGED_SHA`. Both check native reviewers' current
100
- Graphit permissions; the merger is audit context. Apply revalidates the actual
101
- merged commit, including squash merges. CI always passes `--sha`; flagless
102
- interactive verify resolves and reports the bound branch head. Admin commands:
103
- `graphit kb repo token mint --scope kb:verify|kb:apply` (shown once, `gkb.` prefix),
104
- `token list`, `token revoke <id>`. Tokens authorize calls, never replace reviewers.
95
+ ## CI
96
+
97
+ The two jobs, the token recipe and the provider differences live in `repo-setup.md`. Both
98
+ jobs authorize on the PR author alone: a linked, current member whose KB write covers every
99
+ touched group; reviewers and the merger are the provider's process.
100
+ Apply revalidates the actual merged commit, including squash merges. CI always passes
101
+ `--sha`; flagless interactive verify resolves and reports the bound branch head. Tokens
102
+ (`graphit kb repo token mint`, `token list`, `token revoke <id>`) authorize calls, never
103
+ replace reviewers.
@@ -0,0 +1,103 @@
1
+ # Connect a Repository as the Knowledge Base Owner
2
+
3
+ Load when: the user wants a repository to own the shared Knowledge Base, or
4
+ `graphit kb repo show` reports `ownership_mode: manual` with `repo: null`, or a
5
+ binding exists and `last_imported_sha` is null. Skip it once `last_imported_sha`
6
+ is set: routine work follows repo-kb.md. Git providers: `github`, `bitbucket`;
7
+ the procedure is the same, the differences are in the last table.
8
+
9
+ ## How to guide
10
+
11
+ One step at a time. Name the state the user is in, say in one or two plain
12
+ sentences what the step does and why it exists, say who runs it, do your part,
13
+ show the result, then the next step. For an admin step hand over exactly one
14
+ command and wait; never run `mode`, `bind`, `link-identity` or `token mint`
15
+ yourself, never touch a key or a token value, never merge or apply.
16
+
17
+ The split, when the user asks why so much is manual: an org admin's own login
18
+ establishes trust once (who owns the KB, which accounts count, which tokens may
19
+ act). CI then repeats the mechanical part forever: verify every pull request
20
+ head, apply every merged commit. CI cannot bind because its tokens are minted
21
+ for the binding, and a token authorizes calls, it never replaces a reviewer.
22
+
23
+ ## Find the state
24
+
25
+ Read `graphit kb repo show`, `graphit connector list`, `graphit kb repo
26
+ identities`, `graphit kb repo token list` and the branch, then match the first
27
+ row that fits.
28
+
29
+ | State | You see | Next step | Who |
30
+ |---|---|---|---|
31
+ | 0 managed | `show`: `ownership_mode: managed` | empty shared KB: `graphit kb repo export-datasources --out .graphit/datasources`, commit, then `graphit kb repo mode manual`; `shared_kb_not_empty` means the protected migration: ask the Graphit team, never route around it | admin |
32
+ | 1 no warehouse | `connector list` has no warehouse entry | add it in the Sources Hub or `graphit connector add`; the key never passes through you | admin |
33
+ | 2 no definitions | `.graphit/` missing or empty | author it (repo-preparation.md), then `graphit kb repo verify --path . --allow-dirty` until it passes | you |
34
+ | 3 not bound | `show`: `repo: null` | `graphit kb repo bind --repo <owner/name> --branch <base>` | admin |
35
+ | 4 no pull request | tree committed, no PR | commit on a branch, push, open the PR with the user's tooling; ask for its number | you, user |
36
+ | 5 author unlinked | `verify --sha <head> --pr <n>` refuses `identity_unlinked`; `identities` shows `seen` | `graphit kb repo link-identity <provider> <account_id> <member-email>` | admin |
37
+ | 6 no CI tokens | `token list` empty, or CI says the token is not recognized | mint and store both tokens (below) | admin |
38
+ | 7 verified | provider verify: `pass`, `applyable: true` | approve and merge | user |
39
+ | 8 merged | the merge job runs `apply` | wait for it; `show` reports the merged sha as `last_imported_sha` | CI |
40
+
41
+ ## What to say at each step
42
+
43
+ - State 2: with no warehouse connection a local verify passes without compiling
44
+ the metrics. Report it as "pass, not compiled" and expect compile findings
45
+ once state 1 is done. A local plan is never applyable; that is by design.
46
+ - State 2: a provenance shard's `content_hash` must equal the cited document's
47
+ bytes at that commit, or verify refuses `source_drift`: fix the shard, never
48
+ the document. `derived_without_source` cannot fire before the first import;
49
+ there is no earlier apply to differ from.
50
+ - State 3: the connection resolves from the repository. On
51
+ `connection_ambiguous` add `--connection <id>` from the `id` column of
52
+ `graphit connector list`, never the token fingerprint on the Sources Hub card.
53
+ - State 5: the first provider verify refuses here on purpose: an account
54
+ becomes linkable only after a verify has seen it. Any member may plan, so run
55
+ `graphit kb repo verify --sha <head> --pr <n>` with the user's login before CI
56
+ has tokens; `identities` then shows the author as `seen`. Use `account_id`
57
+ from it (logins may contain spaces). `unlinked` means an admin unlinked that
58
+ account; relink it by id. The linked author with KB write on every touched
59
+ group is the whole authority; reviewers are the provider's own process.
60
+ - State 6: mint to the clipboard, never to the screen. Wrapped or quoted
61
+ terminal output is why CI reports "the machine token is not recognized".
62
+
63
+ ```bash
64
+ graphit kb repo token mint --scope kb:verify | python3 -c "import sys,json; print(json.load(sys.stdin)['token'], end='')" | pbcopy
65
+ ```
66
+
67
+ `pbcopy` is macOS: `xclip -selection clipboard` on Linux, `clip` on Windows.
68
+ Paste it as `GRAPHIT_VERIFY_TOKEN`, repeat with `kb:apply` for
69
+ `GRAPHIT_APPLY_TOKEN`. Tokens never expire: one that reached a chat, a log or
70
+ a wrapped paste is revoked (`graphit kb repo token revoke <id>`) and minted
71
+ again. After the next run `token list` shows `last_used_at`; that is the
72
+ proof CI used it. "must be a machine token" with an empty value means the
73
+ variable is not visible to that job (see the provider table).
74
+ - Token refusals: `token_invalid`, `token_revoked`, `token_scope`,
75
+ `token_repo_mismatch`: mint a fresh one, with the right scope, for this
76
+ repository.
77
+ - State 7: Graphit checks the PR author, never the approvals; approving and
78
+ merging follow the provider's own rules.
79
+
80
+ ## CI: two jobs, two tokens, one pinned CLI
81
+
82
+ Export `GRAPHIT_TOKEN` from the secret in the job environment, never as
83
+ `--token` or in a shell trace. Run every job command through the pinned CLI,
84
+ `npx -y @graphit/cli@<version> kb repo ...` (or `npm install -g` that version once
85
+ per job). The PR job runs `kb repo verify --sha <head> --pr <number>` with the
86
+ `kb:verify` token and is the required check; the merge job on the base branch
87
+ runs `kb repo apply --sha <merged sha>` with `kb:apply` and re-verifies the
88
+ merged commit itself. Exit codes: 0 pass, 1 failed, 2 refused or failing
89
+ verdict, 3 stopped waiting (poll the operation id, do not resubmit).
90
+
91
+ | | github | bitbucket |
92
+ |---|---|---|
93
+ | pipeline file | `.github/workflows/*.yml`, jobs on `pull_request` and `push` to the base branch | `bitbucket-pipelines.yml`, `pull-requests:` and `branches: <base>:` steps |
94
+ | head, PR id, merged sha | `github.event.pull_request.head.sha`, `github.event.pull_request.number`, `github.sha` | `$BITBUCKET_COMMIT`, `$BITBUCKET_PR_ID`, `$BITBUCKET_COMMIT` on the base branch |
95
+ | where both secrets live | Settings > Secrets and variables > Actions, repository secrets | Repository settings > Pipelines > Repository variables, Secured; a deployment-environment variable reaches only a step that declares `deployment:` |
96
+ | approval | a review with Approve on the head commit | Approve on the PR page; self-approval is allowed |
97
+
98
+ ## Receipts
99
+
100
+ Drafted, verified (local-only or provider), PR opened, merged and applied are
101
+ five different states; say which one is true. Applied means `graphit kb repo
102
+ show` reports the merged sha as `last_imported_sha`; a green pipeline is not
103
+ that. From then on repo-kb.md is the reference.