@graphit/cli 0.2.113 → 0.2.136
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/README.md +2 -0
- package/bin/graphit +1 -1
- package/bin/graphit.ps1 +1 -1
- package/dist/commands/connector.js +66 -2
- package/dist/commands/connector.js.map +1 -1
- package/dist/commands/ds-config.d.ts +45 -0
- package/dist/commands/ds-config.js +122 -0
- package/dist/commands/ds-config.js.map +1 -0
- package/dist/commands/ds.d.ts +0 -45
- package/dist/commands/ds.js +4 -128
- package/dist/commands/ds.js.map +1 -1
- package/dist/commands/governance.js +1 -17
- package/dist/commands/governance.js.map +1 -1
- package/dist/commands/kb-create.js +2 -2
- package/dist/commands/kb-create.js.map +1 -1
- package/dist/commands/kb-update.js +2 -2
- package/dist/commands/kb-update.js.map +1 -1
- package/dist/commands/query.d.ts +38 -0
- package/dist/commands/query.js +145 -18
- package/dist/commands/query.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/skill-guard.d.ts +4 -0
- package/dist/skill-guard.js +75 -0
- package/dist/skill-guard.js.map +1 -0
- package/package.json +1 -1
- package/scripts/plugin-status.mjs +48 -0
- package/skills/graphit/SKILL.md +15 -14
- package/skills/graphit/VERSION.json +1 -1
- package/skills/graphit/cursor/graphit-sql-reference.mdc +2 -2
- package/skills/graphit/graphit.mdc +6 -9
- package/skills/graphit/references/data-sources.md +7 -3
- package/skills/graphit/references/governance-explained.md +2 -2
- package/skills/graphit/references/governance.md +22 -17
- package/skills/graphit/references/kb-actions.md +2 -3
- package/skills/graphit/references/kb-traversal.md +1 -1
- package/skills/graphit/references/runtime.md +5 -1
- package/skills/graphit/references/sql-reference.md +15 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { registerGovernanceCommands } from "./commands/governance.js";
|
|
|
15
15
|
import { registerTeamCommands } from "./commands/team.js";
|
|
16
16
|
import { registerPluginCommands } from "./commands/plugin.js";
|
|
17
17
|
import { getCurrentVersion, printUpdateBanner, printMigrationNoticeIfGlobal, printPluginHealthPreflight, fireBackgroundCheck, } from "./update-check.js";
|
|
18
|
+
import { printSkillNotLoadedWarning } from "./skill-guard.js";
|
|
18
19
|
const program = new Command();
|
|
19
20
|
const args = process.argv.slice(2);
|
|
20
21
|
const pluginArgIndex = args.indexOf("plugin");
|
|
@@ -39,6 +40,7 @@ if (!isPluginStatusCommand) {
|
|
|
39
40
|
printMigrationNoticeIfGlobal();
|
|
40
41
|
printUpdateBanner();
|
|
41
42
|
printPluginHealthPreflight();
|
|
43
|
+
printSkillNotLoadedWarning();
|
|
42
44
|
}
|
|
43
45
|
program.parse();
|
|
44
46
|
fireBackgroundCheck();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,iFAAiF;AACjF,oFAAoF;AACpF,oEAAoE;AACpE,OAAO,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,iFAAiF;AACjF,oFAAoF;AACpF,oEAAoE;AACpE,OAAO,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9C,MAAM,qBAAqB,GAAG,cAAc,IAAI,CAAC,IAAI,cAAc,KAAK,cAAc,GAAG,CAAC,CAAC;AAE3F,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,oEAAoE,CAAC;KACjF,OAAO,CAAC,iBAAiB,EAAE,CAAC;KAC5B,MAAM,CAAC,mBAAmB,EAAE,iDAAiD,EAAE,MAAM,CAAC,CAAC;AAE1F,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACpC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAE9B,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC3B,4BAA4B,EAAE,CAAC;IAC/B,iBAAiB,EAAE,CAAC;IACpB,0BAA0B,EAAE,CAAC;IAC7B,0BAA0B,EAAE,CAAC;AAC/B,CAAC;AACD,OAAO,CAAC,KAAK,EAAE,CAAC;AAChB,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function isPluginInstalledButNotLoaded(env?: NodeJS.ProcessEnv): boolean;
|
|
2
|
+
export declare const SKILL_NOT_LOADED_MESSAGE: string;
|
|
3
|
+
/** Print the not-loaded warning to stderr (decoration channel). No-op otherwise. */
|
|
4
|
+
export declare function printSkillNotLoadedWarning(env?: NodeJS.ProcessEnv): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
// Feature #743: warn when the Graphit plugin is installed but its SKILL did not load
|
|
5
|
+
// in THIS session (a mid-session plugin install). Claude Code loads plugin skills,
|
|
6
|
+
// slash commands, hooks, and the `graphit` PATH entry at SESSION START; the skill
|
|
7
|
+
// cannot load into a running session, so the only remedy is a new session. Without a
|
|
8
|
+
// signal the agent silently improvises off the raw CLI (observed in a real first-time
|
|
9
|
+
// demo). We warn loudly on every command rather than block, so a false positive can
|
|
10
|
+
// never break a working session.
|
|
11
|
+
//
|
|
12
|
+
// Primary signal (best CLI-side proxy): the plugin's SessionStart hook runs ONLY when
|
|
13
|
+
// Claude Code loaded the plugin at this session's start, and it stamps a marker keyed
|
|
14
|
+
// by the session id (`~/.graphit/sessions/<id>`). The CLI checks for a marker matching
|
|
15
|
+
// CLAUDE_CODE_SESSION_ID - the Bash tool and the hook receive the SAME id (both from
|
|
16
|
+
// Claude Code's getSessionId()). Marker present => the plugin's machinery loaded this
|
|
17
|
+
// exact session - a better proxy than PATH, which only proves the bin is reachable and
|
|
18
|
+
// is shared across all installed plugins.
|
|
19
|
+
//
|
|
20
|
+
// Honest limit: neither the marker nor PATH can see the agent's skill REGISTRY (that
|
|
21
|
+
// lives in the agent's context, not visible to a CLI subprocess). Both prove "the
|
|
22
|
+
// plugin loaded this session," not "the skill is invocable" - so this cannot catch the
|
|
23
|
+
// rarer case where hooks load but the skill silently does not (a Claude Code bug,
|
|
24
|
+
// anthropics/claude-code#42471). It DOES reliably catch the target case - a genuine
|
|
25
|
+
// mid-session install, where nothing loaded (no marker, bin not on PATH). Warn-only,
|
|
26
|
+
// so any miss/false-positive costs at most one harmless stderr line.
|
|
27
|
+
//
|
|
28
|
+
// Legacy fallback (rollout window): sessions that loaded an older, pre-marker plugin
|
|
29
|
+
// build have no marker. So the plugin bin being on PATH still counts as loaded - a
|
|
30
|
+
// suppress-only signal that can never *cause* a warning, only prevent a false one.
|
|
31
|
+
function pluginDataDir(env) {
|
|
32
|
+
return env.GRAPHIT_PLUGIN_DATA ?? join(homedir(), ".graphit");
|
|
33
|
+
}
|
|
34
|
+
function loadedThisSession(env) {
|
|
35
|
+
// Reliable: the SessionStart hook stamped a marker for this exact session id.
|
|
36
|
+
const sid = env.CLAUDE_CODE_SESSION_ID;
|
|
37
|
+
if (sid && existsSync(join(pluginDataDir(env), "sessions", sid)))
|
|
38
|
+
return true;
|
|
39
|
+
// Fallback (suppress-only): the plugin bin on PATH means Claude Code injected it at
|
|
40
|
+
// session start - covers sessions still on a pre-marker plugin build.
|
|
41
|
+
return /graphit-plugin/.test(env.PATH ?? "");
|
|
42
|
+
}
|
|
43
|
+
function pluginInstalledOnDisk(env) {
|
|
44
|
+
const pluginsRoot = env.CLAUDE_PLUGINS_ROOT ?? join(homedir(), ".claude", "plugins");
|
|
45
|
+
return (existsSync(join(pluginsRoot, "marketplaces", "graphit-plugin")) ||
|
|
46
|
+
existsSync(join(pluginsRoot, "cache", "graphit-plugin")));
|
|
47
|
+
}
|
|
48
|
+
export function isPluginInstalledButNotLoaded(env = process.env) {
|
|
49
|
+
// Scope to Claude Code. Other surfaces (Codex, a plain terminal, CI) load skills
|
|
50
|
+
// differently or legitimately have none, so the "restart Claude Code" remedy does
|
|
51
|
+
// not apply and could mislead.
|
|
52
|
+
if (!env.CLAUDE_CODE_ENTRYPOINT)
|
|
53
|
+
return false;
|
|
54
|
+
if (loadedThisSession(env))
|
|
55
|
+
return false;
|
|
56
|
+
// Not loaded this session: warn only if the plugin is actually installed on disk
|
|
57
|
+
// (else this is a genuine no-plugin surface, where the CLI itself is the interface).
|
|
58
|
+
return pluginInstalledOnDisk(env);
|
|
59
|
+
}
|
|
60
|
+
export const SKILL_NOT_LOADED_MESSAGE = [
|
|
61
|
+
"The Graphit skill is NOT loaded in this session.",
|
|
62
|
+
"The plugin is installed, but Claude Code loads plugin skills and commands only at",
|
|
63
|
+
"session start - so a mid-session install leaves this session without the Graphit",
|
|
64
|
+
"skill, /graphit, or the guided workflow (scope gates, KB governance, quality).",
|
|
65
|
+
"Tell the user to start a NEW session, then continue there. Do not build dashboards,",
|
|
66
|
+
"create KB assets, or run analysis without the skill - the CLI runs, but the",
|
|
67
|
+
"workflow that makes the output correct and governed lives in the skill.",
|
|
68
|
+
].join("\n");
|
|
69
|
+
/** Print the not-loaded warning to stderr (decoration channel). No-op otherwise. */
|
|
70
|
+
export function printSkillNotLoadedWarning(env = process.env) {
|
|
71
|
+
if (isPluginInstalledButNotLoaded(env)) {
|
|
72
|
+
console.error(SKILL_NOT_LOADED_MESSAGE);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=skill-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-guard.js","sourceRoot":"","sources":["../src/skill-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,qFAAqF;AACrF,mFAAmF;AACnF,kFAAkF;AAClF,qFAAqF;AACrF,sFAAsF;AACtF,oFAAoF;AACpF,iCAAiC;AACjC,EAAE;AACF,sFAAsF;AACtF,sFAAsF;AACtF,uFAAuF;AACvF,qFAAqF;AACrF,sFAAsF;AACtF,uFAAuF;AACvF,0CAA0C;AAC1C,EAAE;AACF,qFAAqF;AACrF,kFAAkF;AAClF,uFAAuF;AACvF,kFAAkF;AAClF,oFAAoF;AACpF,qFAAqF;AACrF,qEAAqE;AACrE,EAAE;AACF,qFAAqF;AACrF,mFAAmF;AACnF,mFAAmF;AAEnF,SAAS,aAAa,CAAC,GAAsB;IAC3C,OAAO,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAsB;IAC/C,8EAA8E;IAC9E,MAAM,GAAG,GAAG,GAAG,CAAC,sBAAsB,CAAC;IACvC,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,oFAAoF;IACpF,sEAAsE;IACtE,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAsB;IACnD,MAAM,WAAW,GACf,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACnE,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;QAC/D,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,MAAyB,OAAO,CAAC,GAAG;IAEpC,iFAAiF;IACjF,kFAAkF;IAClF,+BAA+B;IAC/B,IAAI,CAAC,GAAG,CAAC,sBAAsB;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,iBAAiB,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,iFAAiF;IACjF,qFAAqF;IACrF,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,kDAAkD;IAClD,mFAAmF;IACnF,kFAAkF;IAClF,gFAAgF;IAChF,qFAAqF;IACrF,6EAA6E;IAC7E,yEAAyE;CAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,oFAAoF;AACpF,MAAM,UAAU,0BAA0B,CACxC,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,6BAA6B,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,10 +5,13 @@ import {
|
|
|
5
5
|
cpSync,
|
|
6
6
|
existsSync,
|
|
7
7
|
mkdirSync,
|
|
8
|
+
readdirSync,
|
|
8
9
|
readFileSync,
|
|
9
10
|
realpathSync,
|
|
10
11
|
renameSync,
|
|
11
12
|
rmSync,
|
|
13
|
+
statSync,
|
|
14
|
+
unlinkSync,
|
|
12
15
|
writeFileSync,
|
|
13
16
|
} from "node:fs";
|
|
14
17
|
import { homedir } from "node:os";
|
|
@@ -513,6 +516,47 @@ function tryParseJson(value) {
|
|
|
513
516
|
}
|
|
514
517
|
}
|
|
515
518
|
|
|
519
|
+
// Feature #743: stamp a per-session marker so the CLI can tell whether the plugin
|
|
520
|
+
// actually loaded THIS session. This SessionStart hook only runs when Claude Code
|
|
521
|
+
// loaded the plugin at session start - a mid-session install never runs it, so the
|
|
522
|
+
// marker is absent and the CLI can warn. The SessionStart payload carries session_id
|
|
523
|
+
// (the same value as the Bash tool's CLAUDE_CODE_SESSION_ID - both from getSessionId()),
|
|
524
|
+
// and the marker is keyed by it so concurrent sessions never clobber each other.
|
|
525
|
+
function stampSessionMarker() {
|
|
526
|
+
if (hookEvent !== "SessionStart") return;
|
|
527
|
+
let sessionId = "";
|
|
528
|
+
try {
|
|
529
|
+
sessionId = String(tryParseJson(readFileSync(0, "utf-8"))?.session_id ?? "").trim();
|
|
530
|
+
} catch {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
// The id becomes a filename, so accept only an id-shaped token (path-safety).
|
|
534
|
+
if (!/^[A-Za-z0-9._-]{1,128}$/.test(sessionId)) return;
|
|
535
|
+
const dir = join(cacheRoot, "sessions");
|
|
536
|
+
try {
|
|
537
|
+
mkdirSync(dir, { recursive: true });
|
|
538
|
+
writeFileSync(join(dir, sessionId), String(Date.now()), "utf-8");
|
|
539
|
+
pruneOldSessionMarkers(dir);
|
|
540
|
+
} catch {
|
|
541
|
+
// Best-effort: a missing marker only costs an extra (harmless) CLI warning.
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function pruneOldSessionMarkers(dir) {
|
|
546
|
+
const cutoff = Date.now() - 48 * 60 * 60 * 1000;
|
|
547
|
+
try {
|
|
548
|
+
for (const name of readdirSync(dir)) {
|
|
549
|
+
try {
|
|
550
|
+
if (statSync(join(dir, name)).mtimeMs < cutoff) unlinkSync(join(dir, name));
|
|
551
|
+
} catch {
|
|
552
|
+
/* skip an unreadable entry */
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
} catch {
|
|
556
|
+
/* dir missing or unreadable - nothing to prune */
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
516
560
|
// Feature #675: read session liveness locally (zero network) so the single
|
|
517
561
|
// startup check covers version AND auth. logged_in = a credentials file holding
|
|
518
562
|
// a refresh_token is present; email powers the greeting. The real token refresh
|
|
@@ -730,6 +774,10 @@ if (isMainModule()) {
|
|
|
730
774
|
process.exit(0);
|
|
731
775
|
}
|
|
732
776
|
|
|
777
|
+
// Feature #743: record that the plugin loaded this session (SessionStart only;
|
|
778
|
+
// reads stdin before anything else would consume it).
|
|
779
|
+
stampSessionMarker();
|
|
780
|
+
|
|
733
781
|
const status = await collectStatus();
|
|
734
782
|
|
|
735
783
|
if (args.has("--json")) {
|
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.136"
|
|
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 27,648. This router always-loads the collaboration/pace spine (brainstorm, ask-user, present-result, plan-next), the hard constraints + scope gate, the investigation loop, and the generated command table (between the COMMANDS markers, written by scripts/generate-commands-doc.mjs) - all needed every turn, so they cannot defer to a reference. The marker sits after the YAML frontmatter so the loader and sync-plugin-version.mjs still parse it. Reviewed 2026-07-11. -->
|
|
9
9
|
|
|
10
10
|
# Graphit CLI
|
|
11
11
|
|
|
@@ -33,6 +33,7 @@ Two interlocking jobs: use the knowledge base (investigate, then build the dashb
|
|
|
33
33
|
|
|
34
34
|
- Never hardcode or invent numbers. Live data comes from graphit.resolve against governed SQL.
|
|
35
35
|
- Never silently substitute ad-hoc SQL for a measure that should be a governed metric. Ad-hoc is the frontier: fine for genuine new questions, always provenance-tagged.
|
|
36
|
+
- Never render business-data charts inline in chat; deliver dashboards in Graphit.
|
|
36
37
|
|
|
37
38
|
### MUST
|
|
38
39
|
|
|
@@ -143,7 +144,7 @@ Read the one that matches what you are doing now. Do not preload them. Exact com
|
|
|
143
144
|
|
|
144
145
|
## Commands
|
|
145
146
|
|
|
146
|
-
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.
|
|
147
|
+
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.136 <command>` (a stamped version, kept current automatically by the build), or pin an exact one - `npx -y @graphit/cli@<exact> <command>` - for a reproducible run. The table below is the always-loaded command map, generated from the CLI itself, so it is the source of truth for which commands, subcommands, and flags exist. For exact flag values and full descriptions, run `graphit <command> --help` - never guess a flag.
|
|
147
148
|
|
|
148
149
|
<!-- COMMANDS:START -->
|
|
149
150
|
|
|
@@ -164,7 +165,7 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
164
165
|
- `kb unverify <type> <name>` - Unverify a KB asset (mark as draft); cascades to metric variants
|
|
165
166
|
- `kb create metric` - Create a new metric - `--name --sql --table --description --topics --default-dimensions --parameters --parameters-file --skip-validate --unverified`
|
|
166
167
|
- `kb create dimension` - Create a new dimension - `--name --expr --table --type --output-type --description --topics --skip-validate --unverified`
|
|
167
|
-
- `kb create rule` - Create a new rule. Without --apply-on the rule governs the whole --table, which cascades to every metric and dimension on it. Use --apply-on metric:NAME / dimension:NAME to govern only specific assets instead. A rule must apply to at least one asset (targetless rules are rejected). - `--name --sql --table --description --topics --constraint --
|
|
168
|
+
- `kb create rule` - Create a new rule. Without --apply-on the rule governs the whole --table, which cascades to every metric and dimension on it. Use --apply-on metric:NAME / dimension:NAME to govern only specific assets instead. A rule must apply to at least one asset (targetless rules are rejected). - `--name --sql --table --description --topics --constraint --enforcement-mode --apply-on --skip-validate --unverified`
|
|
168
169
|
- `kb create domain` - Create a new domain - `--name --description --color`
|
|
169
170
|
- `kb create synonym` - Create a new synonym - `--term --canonical --type --description --unverified`
|
|
170
171
|
- `kb create relationship` - Create a new relationship (JOIN between tables) - `--name --primary-table --primary-column --related-table --related-column --description`
|
|
@@ -172,7 +173,7 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
172
173
|
- `kb create template` - Create a reusable template (chart, KPI, or filter control) - `--name --render-code --file --description --chart-types`
|
|
173
174
|
- `kb update metric <name>` - Update a metric. - `--sql --table --description --topics --default-dimensions --secondary-tables --parameters --parameters-file`
|
|
174
175
|
- `kb update dimension <name>` - Update a dimension. - `--expr --table --description --topics --secondary-tables`
|
|
175
|
-
- `kb update rule <name>` - Update a rule. Broadening a verified rule's targeting requires org admin. - `--sql --description --topics --constraint --
|
|
176
|
+
- `kb update rule <name>` - Update a rule. Broadening a verified rule's targeting requires org admin. - `--sql --description --topics --constraint --enforcement-mode --apply-on`
|
|
176
177
|
- `kb update template <name>` - Update a template - `--render-code --file --description`
|
|
177
178
|
- `kb update table <name>` - Update a table's description or domain - `--description --domain`
|
|
178
179
|
- `kb update domain <name>` - Update a domain. --owner sets the governance owner (the person accountable for the domain and the fallback owner for its assets); pass an empty string to clear it. - `--description --color --owner`
|
|
@@ -181,12 +182,12 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
181
182
|
- `kb update topic <name>` - Update a topic - `--description`
|
|
182
183
|
- `kb delete <type> <name>` - Delete a KB entity (requires --yes flag) - `--yes`
|
|
183
184
|
|
|
184
|
-
**query** - Run SQL against a cached data source or live Snowflake
|
|
185
|
-
- `query <sql>` - Run SQL against a cached data source or live Snowflake - `--ds --warehouse --connection --limit --override-rules --verbose --adhoc-reason --timeout`
|
|
185
|
+
**query** - Run SQL against a cached data source or a live warehouse (Snowflake / BigQuery)
|
|
186
|
+
- `query <sql>` - Run SQL against a cached data source or a live warehouse (Snowflake / BigQuery) - `--ds --warehouse --connection --limit --override-rules --verbose --adhoc-reason --apply-conditional --skip-conditional --timeout`
|
|
186
187
|
|
|
187
|
-
**metadata** - Snowflake
|
|
188
|
-
- `metadata schemas` - List Snowflake
|
|
189
|
-
- `metadata tables` - List tables in a Snowflake
|
|
188
|
+
**metadata** - Warehouse metadata (Snowflake schemas / BigQuery datasets)
|
|
189
|
+
- `metadata schemas` - List schemas (Snowflake) or datasets (BigQuery) - `--connection`
|
|
190
|
+
- `metadata tables` - List tables in a schema (Snowflake) or dataset (BigQuery) - `--connection --schema`
|
|
190
191
|
|
|
191
192
|
**ds** - Data source management
|
|
192
193
|
- `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`
|
|
@@ -194,7 +195,7 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
194
195
|
- `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`
|
|
195
196
|
- `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`
|
|
196
197
|
- `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 automatically. - `--force --accept-schema`
|
|
197
|
-
- `ds update <id>` - Update data source
|
|
198
|
+
- `ds update <id>` - Update a data source row cap - `--max-rows`
|
|
198
199
|
- `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`
|
|
199
200
|
|
|
200
201
|
**dashboard** - Custom dashboard management
|
|
@@ -210,14 +211,14 @@ _Generated from the CLI by `npm run gen:commands` - do not hand-edit between the
|
|
|
210
211
|
- `dashboard delete <id>` - Delete a custom dashboard (requires --yes) - `--yes`
|
|
211
212
|
|
|
212
213
|
**connector** - Connection management. OAuth and GitHub connections are set up in the Graphit web app.
|
|
213
|
-
- `connector list` - List active connections
|
|
214
|
+
- `connector list` - List active connections (Snowflake + BigQuery)
|
|
214
215
|
- `connector add snowflake-keypair` - Add Snowflake via keypair auth - `--account --user --key --name --warehouse --role --database`
|
|
216
|
+
- `connector add bigquery-serviceaccount` - Add BigQuery via a service-account key (org admin only) - `--key-file --project --dataset --location --name --max-bytes-billed`
|
|
215
217
|
- `connector test <id>` - Test a connection
|
|
216
218
|
- `connector remove <id>` - Remove a connection (requires --yes) - `--yes`
|
|
217
219
|
|
|
218
220
|
**governance** - Query governance management
|
|
219
|
-
- `governance status` - Show governance
|
|
220
|
-
- `governance set` - Set governance mode - `--mode`
|
|
221
|
+
- `governance status` - Show governance conformance summary
|
|
221
222
|
- `governance audit` - Query the governance audit log - `--last --tier --user --channel --limit`
|
|
222
223
|
|
|
223
224
|
**team** - Team management
|
|
@@ -157,8 +157,8 @@ Ground every query in the KB. When using `{{metric:X}}`/`{{dim:X}}` references,
|
|
|
157
157
|
|
|
158
158
|
For inline SQL (no KB refs): show query + results + governance, and suggest the KB reference equivalent to nudge toward governed tier.
|
|
159
159
|
|
|
160
|
-
On a
|
|
160
|
+
On the CLI, every ad-hoc query needs a substantive `--adhoc-reason` when no KB definition fits. An ad-hoc **business measure** (aggregate / `GROUP BY` without `{{metric:X}}`) is hard-blocked when the caller lacks EXPLORE access to any queried scope; a reason never bypasses that access denial.
|
|
161
161
|
|
|
162
162
|
## Presenting Data Source Results
|
|
163
163
|
|
|
164
|
-
After `graphit ds list`: table with **bold Name**, ID, Rows (right-aligned), Status,
|
|
164
|
+
After `graphit ds list`: table with **bold Name**, ID, Rows (right-aligned), Status, Row cap. End with DS recommendation for current task.
|
|
@@ -221,15 +221,13 @@ You are the rendering layer - format and present every CLI result using markdown
|
|
|
221
221
|
| `graphit ds refresh --all --skip-empty` | Refresh non-empty data sources only |
|
|
222
222
|
| `graphit ds refresh --all --no-wait` | Trigger all refreshes without waiting |
|
|
223
223
|
| `graphit ds refresh <id> [id2...]` | Refresh one or more data sources by ID |
|
|
224
|
-
| `graphit ds update <id> --
|
|
225
|
-
| `graphit ds update <id> --max-rows N` | Set max rows cap on a data source |
|
|
224
|
+
| `graphit ds update <id> --max-rows N` | Set or clear a data-source row cap |
|
|
226
225
|
| `graphit query "<sql>" --ds <id>` | Query cached data source (~100ms) |
|
|
227
226
|
| `graphit query "<sql>" --ds <id> --override-rules RULE1 RULE2` | Query with governance rule overrides |
|
|
228
227
|
| `graphit query "<sql>" --ds <id> --verbose` | Show expanded SQL and trust tier |
|
|
229
|
-
| `graphit query "<sql>" --ds <id> --
|
|
228
|
+
| `graphit query "<sql>" --ds <id> --adhoc-reason "<reason>"` | Justify an ad-hoc query when no KB definition fits |
|
|
230
229
|
| `graphit query "<sql>" --warehouse --connection <id>` | Query live Snowflake (~10s) |
|
|
231
|
-
| `graphit governance status` | Show governance
|
|
232
|
-
| `graphit governance set <mode>` | Set governance mode (observe/warn/strict) |
|
|
230
|
+
| `graphit governance status` | Show governance conformance stats |
|
|
233
231
|
| `graphit governance audit` | View recent governance audit events |
|
|
234
232
|
| `graphit dashboard create --name "..."` | Create dashboard (returns ID) |
|
|
235
233
|
| `graphit dashboard get-html <id>` | Get current HTML content of a dashboard |
|
|
@@ -264,12 +262,11 @@ Use KB references for governed queries:
|
|
|
264
262
|
graphit query "SELECT {{dim:INSTALL_MONTH}}, {{metric:CPI}} as cpi FROM MARKETING_UA_DS GROUP BY 1" --ds ds_abc123
|
|
265
263
|
graphit query "SELECT {{metric:ARPU(DAY=7)}} as arpu FROM MARKETING_UA_DS" --ds ds_abc123 # parameterized
|
|
266
264
|
graphit query "SELECT * FROM events" --ds ds_123 --override-rules EXCLUDE_RETARGETING # bypass rule
|
|
267
|
-
graphit governance status # view
|
|
268
|
-
graphit
|
|
269
|
-
graphit ds update <id> --governed-mode on # enable governance on DS
|
|
265
|
+
graphit governance status # view conformance
|
|
266
|
+
graphit ds update <id> --max-rows 10000 # cap result size
|
|
270
267
|
```
|
|
271
268
|
|
|
272
|
-
Reference syntax in `graphit.resolve()` calls works the same way - server expands at query time. Trust tiers: **governed** (KB refs), **verified** (matches KB), **ad-hoc** (inline). On
|
|
269
|
+
Reference syntax in `graphit.resolve()` calls works the same way - server expands at query time. Trust tiers: **governed** (KB refs), **verified** (matches KB), **ad-hoc** (inline). On the CLI, an ad-hoc query needs a substantive `--adhoc-reason` when no KB definition fits. An ad-hoc **business measure** (aggregate / `GROUP BY` without `{{metric:X}}`) is hard-blocked when the caller lacks EXPLORE access to any queried scope; a reason never bypasses that access denial.
|
|
273
270
|
|
|
274
271
|
---
|
|
275
272
|
|
|
@@ -9,11 +9,11 @@ Always prefer a cached data source over the live warehouse. Check what exists wi
|
|
|
9
9
|
| Situation | Command | Speed |
|
|
10
10
|
|---|---|---|
|
|
11
11
|
| The table has a cached data source | `graphit query "SQL" --ds <NAME>` | roughly 100ms, DuckDB |
|
|
12
|
-
| No data source covers the table | `graphit query "SQL" --warehouse --connection <id>` | roughly 10s,
|
|
12
|
+
| No data source covers the table | `graphit query "SQL" --warehouse --connection <id>` | roughly 10s, the connected warehouse |
|
|
13
13
|
|
|
14
14
|
`--ds` takes the data source **name** (the same name you SELECT FROM, e.g. `... FROM MARKETING_UA_DS ... --ds MARKETING_UA_DS`); a full id or unique id-prefix also resolves.
|
|
15
15
|
|
|
16
|
-
If no data source covers the table the user needs, propose creating one for future speed rather than defaulting to repeated warehouse queries. Dialect differs by route
|
|
16
|
+
If no data source covers the table the user needs, propose creating one for future speed rather than defaulting to repeated warehouse queries. Dialect differs by route: DuckDB for `--ds`, and the connected warehouse's own dialect (Snowflake or BigQuery) for `--warehouse`; see `sql-reference.md`.
|
|
17
17
|
|
|
18
18
|
## Build it right (in the source SQL)
|
|
19
19
|
|
|
@@ -53,11 +53,15 @@ graphit ds create --name "MY_DS" --sql "SELECT ..." --skip-scan
|
|
|
53
53
|
|
|
54
54
|
**From a local file (Excel/CSV):** `graphit ds create --file <path>` uploads the file and creates one data source. Optional: `--name` (defaults to the file name), `--sheet <name>` (multi-sheet workbooks), `--domain <NAME>` (attach to an existing KB domain - create it first if needed). `--file` and `--sql` are mutually exclusive; same auto-scan + verification flow as above.
|
|
55
55
|
|
|
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
|
+
|
|
56
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 (file uploads activate automatically).
|
|
57
59
|
|
|
58
60
|
## Refreshing data sources
|
|
59
61
|
|
|
60
|
-
Data sources cache a snapshot of the
|
|
62
|
+
Data sources cache a snapshot of the warehouse query result. Refresh when you need current data. **File-upload sources can't be refreshed (no query to re-run) - update them by re-uploading with `graphit ds create --file <path>`.**
|
|
63
|
+
|
|
64
|
+
On BigQuery a refresh scans billed bytes, so keep the source shape tight and prefer incremental/partition-pruned refresh over full re-scans to control cost; a per-connection scan cap (max bytes billed) fails an oversized query fast rather than running up a bill.
|
|
61
65
|
|
|
62
66
|
```bash
|
|
63
67
|
# Refresh all data sources and wait for completion (live status table)
|
|
@@ -16,7 +16,7 @@ Governance means every number is computed the team's agreed way and carries an h
|
|
|
16
16
|
| verified | Raw SQL whose math matches a KB definition | Amber |
|
|
17
17
|
| ad_hoc | Inline formula with no KB match | Gray |
|
|
18
18
|
|
|
19
|
-
Enforcement is server-side and identical on every channel (agent, CLI, dashboard, warehouse); it cannot be weakened from the CLI.
|
|
19
|
+
Enforcement is server-side and identical on every channel (agent, CLI, dashboard, warehouse); it cannot be weakened from the CLI. An ad-hoc business measure requires EXPLORE access across every table it touches. A rule override additionally requires EXPLORE, the rule policy, and the user's role to allow it. If a query was blocked or asked for a justification, that is the ad-hoc gate: it used no KB reference and matched no definition, so Graphit wants you to either rewrite it with a metric or dimension (creating one if it is missing) or state honestly why a raw run is warranted. The reason is recorded in the audit log; it never bypasses missing access or a disallowed rule override.
|
|
20
20
|
|
|
21
21
|
**2. Auditing, after the fact (Proactive Insights).** Separately, Graphit continuously scans everything the team built - KB definitions, dashboard graphs, the queries that actually ran - and turns each governance gap into a ranked Fix card routed to an owner. Three principles: a card shows only when Graphit is confident it is real (right or silent), one root cause is one card even if it spans many surfaces, and each is routed to an owner (the resource's owner, else its domain owner, else org admins). The ten card types:
|
|
22
22
|
|
|
@@ -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 (analyst seat, 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
|
|
36
|
+
Fix is a guided one-click resolution: it drafts and previews the exact change, you apply it (analyst seat, 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,8 +1,8 @@
|
|
|
1
1
|
# Query Governance
|
|
2
2
|
|
|
3
|
-
Load this when writing or validating a governed query, working trust tiers,
|
|
3
|
+
Load this when writing or validating a governed query, working trust tiers, declaring a conditionally-enforced rule, or working the ad-hoc frontier.
|
|
4
4
|
|
|
5
|
-
Governance is enforced server-side in the QueryGateway, the same across every channel. You CANNOT weaken it from the CLI
|
|
5
|
+
Governance is enforced server-side in the QueryGateway, the same across every channel. You CANNOT weaken it from the CLI: an ad-hoc business measure requires EXPLORE access across every queried scope, and rule overrides must also satisfy EXPLORE.
|
|
6
6
|
|
|
7
7
|
## Reference syntax
|
|
8
8
|
|
|
@@ -27,7 +27,7 @@ Some metrics (for example ARPU, ROAS, RETENTION) carry required parameters and c
|
|
|
27
27
|
|
|
28
28
|
## Trust tiers
|
|
29
29
|
|
|
30
|
-
Every result is stamped with a tier
|
|
30
|
+
Every result is stamped with a tier, shown to the user as a badge on graphs and canvas entities - your honest signal of how trustworthy the number is.
|
|
31
31
|
|
|
32
32
|
| Tier | Meaning | Badge |
|
|
33
33
|
|------|---------|-------|
|
|
@@ -39,12 +39,12 @@ Prefer the governed tier. The server may upgrade matching raw SQL to verified, b
|
|
|
39
39
|
|
|
40
40
|
## The ad-hoc gate
|
|
41
41
|
|
|
42
|
-
This is the hard frontier
|
|
42
|
+
This is the hard frontier - the rules below are what the QueryGateway does.
|
|
43
43
|
|
|
44
|
-
A query lands at the `ad_hoc` tier when it uses no `{{metric:NAME}}` / `{{dim:NAME}}` reference and its raw expressions match no KB definition. On the CLI (`graphit query`, cached `--ds` or `--warehouse`), **every** ad-hoc query must be justified - business measures (an aggregate or `GROUP BY`)
|
|
44
|
+
A query lands at the `ad_hoc` tier when it uses no `{{metric:NAME}}` / `{{dim:NAME}}` reference and its raw expressions match no KB definition. On the CLI (`graphit query`, cached `--ds` or `--warehouse`), **every** ad-hoc query must be justified - business measures (an aggregate or `GROUP BY`) and plain exploration alike (`SELECT *`, `COUNT(*)`, `DISTINCT` peeks). Governed and verified results are exempt.
|
|
45
45
|
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
46
|
+
- **EXPLORE access is a hard prerequisite for ad-hoc business measures.** If the user lacks EXPLORE access to any queried table scope, the server blocks that measure. An ad-hoc reason cannot bypass that denial.
|
|
47
|
+
- **Justification floor.** The ad-hoc query is withheld and asks for a justification. Preferred path first: rewrite with `{{metric:NAME}}` / `{{dim:NAME}}` references - genuinely search the KB (`graphit kb explore`, `graphit kb list metric`, `graphit kb list dimension`), and if the metric or dimension you need does not exist, CREATE it first. A filter's value list belongs in a `{{dim:NAME}}`, not a raw `SELECT DISTINCT` peek. Only if nothing fits and the user needs the raw run, pass `--adhoc-reason "<text>"` stating what you searched, what you found, and why it does not fit - pass it on the first call when you already know the query is ad-hoc. A trivial or empty reason is rejected server-side and recorded in the audit log, so it must be honest.
|
|
48
48
|
|
|
49
49
|
When the gate fires, do not narrate around it or pretend the query ran. Report truthfully: it was blocked or needs approval, name the governed rewrite, and let the user decide.
|
|
50
50
|
|
|
@@ -60,36 +60,41 @@ Rules with typed constraints are enforced automatically, rewriting the SQL befor
|
|
|
60
60
|
| `required_filter` | Validates a column appears in WHERE |
|
|
61
61
|
| `required_aggregation` | Validates GROUP BY includes a column |
|
|
62
62
|
|
|
63
|
-
User-context variables (`${user.team_id}`, `${user.email}`) resolve server-side for row-level security. Override a rule only when the user explicitly asks
|
|
63
|
+
User-context variables (`${user.team_id}`, `${user.email}`) resolve server-side for row-level security. Override a rule only when the user explicitly asks; the server honors it only if the user holds EXPLORE on every queried scope. A rule that masks a column (a `forbidden_column` constraint) can never be overridden. Every override is logged. Pass several names to override more than one.
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
66
|
graphit query "SELECT * FROM EVENTS" --ds EVENTS --override-rules EXCLUDE_RETARGETING
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
##
|
|
69
|
+
## Conditionally-enforced rules
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
A rule's mode is Advisory (guidance), Always (every query), or **Conditional** - fires only when its plain-language body (the condition) holds for the query you wrote. No server classifier decides that; you do. Read a table's rules first (`graphit kb explore table <name>`), judge your query against each conditional rule's body, and declare it up front:
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
- `--apply-conditional RULE` - enforce it for this query.
|
|
74
|
+
- `--skip-conditional RULE:"reason"` - skip it; a reason is required and audit-logged.
|
|
75
|
+
|
|
76
|
+
Declare up front so a clean query never stalls. An undeclared conditional returns a retryable prompt naming each unresolved rule and its condition - read it, decide, re-run. A saved tile stores your decision and replays it every refresh.
|
|
77
|
+
|
|
78
|
+
## Data-source row caps
|
|
79
|
+
|
|
80
|
+
An admin can set a `max_rows` cap per data source. A cap limits the result set; it does not change authorization, trust-tier classification, or the ad-hoc justification floor.
|
|
76
81
|
|
|
77
82
|
## Presenting governance results
|
|
78
83
|
|
|
79
84
|
The user CANNOT see raw CLI output. Render every result as markdown.
|
|
80
85
|
|
|
81
|
-
**After a governed query**, append a provenance footer so the trust signal travels with the number: tier,
|
|
86
|
+
**After a governed query**, append a provenance footer so the trust signal travels with the number: tier, KB references used, row cap if applied. Because a governed query may be rewritten before it runs, read `provenance.injection_summary` and report which rules changed it and how (each rule, its outcome, and why), not just a count. An ungoverned query reports no rules applied. For an ad-hoc result, state the tier honestly and offer the governed `{{metric:NAME}}` / `{{dim:NAME}}` rewrite.
|
|
82
87
|
|
|
83
88
|
~~~
|
|
84
|
-
**Trust tier:** governed -
|
|
89
|
+
**Trust tier:** governed - 2 KB refs, 1 rule enforced (**EXCLUDE_INTERNAL**), max rows 10000
|
|
85
90
|
~~~
|
|
86
91
|
|
|
87
|
-
**After `graphit governance status`**, show the
|
|
92
|
+
**After `graphit governance status`**, show the 7-day conformance counts (governed / verified / ad-hoc / total) as a small markdown table.
|
|
88
93
|
|
|
89
94
|
**When a gate or rule blocks a query**, explain it and the path forward, no raw dump:
|
|
90
95
|
|
|
91
96
|
~~~
|
|
92
97
|
**Blocked by governance.**
|
|
93
98
|
|
|
94
|
-
Rule **EXCLUDE_ORGANIC**
|
|
99
|
+
Rule **EXCLUDE_ORGANIC** is enforced; overriding it requires EXPLORE access on every queried scope. Rewrite the query to include the required filter, or ask an admin for EXPLORE access.
|
|
95
100
|
~~~
|
|
@@ -29,7 +29,7 @@ Present the plan, then stop. Do not create until the user approves.
|
|
|
29
29
|
|---|---|
|
|
30
30
|
| Metric | `graphit kb create metric --name X --sql "<expr>" --table T` (optional `--topics "A,B"`, `--default-dimensions "D1,D2"`, `--parameters`/`--parameters-file` for templates, `--skip-validate`) |
|
|
31
31
|
| Dimension | `graphit kb create dimension --name X --expr "<expr>" --table T` (type auto-inferred; override with `--type` / `--output-type`; `--skip-validate`) |
|
|
32
|
-
| Rule | `graphit kb create rule --name X --sql "<text>" --table T` (optional `--constraint`, `--
|
|
32
|
+
| Rule | `graphit kb create rule --name X --sql "<text>" --table T` (optional `--constraint`, `--apply-on`, `--topics`, `--skip-validate`) |
|
|
33
33
|
| Synonym | `graphit kb create synonym --term X --canonical Y --type metric` |
|
|
34
34
|
| Domain | `graphit kb create domain --name X` (optional `--color "#4DB6AC"`) |
|
|
35
35
|
| Topic | `graphit kb create topic --name X` |
|
|
@@ -40,12 +40,11 @@ Present the plan, then stop. Do not create until the user approves.
|
|
|
40
40
|
A plain rule is documentation. To make it enforced server-side at query time, pass typed constraints on `graphit kb create rule` / `graphit kb update rule`:
|
|
41
41
|
|
|
42
42
|
- `--constraint <spec...>` - one or more typed constraints, each written `type:value`. Types: `required_where:"<predicate>"`, `forbidden_column:<col>`, `required_filter:<col>`, `required_aggregation:<col>`, `value_restriction:<col>:<in|not_in>:<v1,v2>`. On update the supplied list REPLACES the rule's existing constraints.
|
|
43
|
-
- `--override-policy <policy>` - who may bypass the rule with `--override-rules`: `anyone`, `analyst_only`, `admin_only`, or `never`. Create defaults to `anyone`.
|
|
44
43
|
|
|
45
44
|
What each constraint type does at query time, plus the override flow, lives in `governance.md`. Example: a rule that always scopes verified purchases -
|
|
46
45
|
|
|
47
46
|
```bash
|
|
48
|
-
graphit kb create rule --name FILTER_VERIFIED_PURCHASES --sql "Only count verified purchases" --table ORDERS --constraint required_where:"is_verified = true"
|
|
47
|
+
graphit kb create rule --name FILTER_VERIFIED_PURCHASES --sql "Only count verified purchases" --table ORDERS --constraint required_where:"is_verified = true"
|
|
49
48
|
```
|
|
50
49
|
|
|
51
50
|
## Rule Targeting - what a rule governs
|
|
@@ -79,7 +79,7 @@ Adapt columns per type: dimensions include semantic type, rules include constrai
|
|
|
79
79
|
| **Default dims** | MEDIA_SOURCE, CAMPAIGN_NAME |
|
|
80
80
|
~~~
|
|
81
81
|
|
|
82
|
-
Adapt fields per type. Rules: content, constraints, apply-on,
|
|
82
|
+
Adapt fields per type. Rules: content, constraints, apply-on, plus `enforced` (Enforced = has constraints / applied to every query; Suggested = body-only / guides the AI) and `governs` (the tables it covers whole + any narrowed metric/dimension targets). Metrics and dimensions carry `governed_by` - the rules governing that asset, each tagged `enforced` and a `scope_tag` (`whole table` vs `this metric`/`this dimension`) - so reading a metric also shows what rules apply to it. Dimensions also: expression, semantic type, output type.
|
|
83
83
|
|
|
84
84
|
**After `graphit kb search`** - result count + table with type column:
|
|
85
85
|
|