@ritualai/cli 0.4.0 → 0.5.0

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.
@@ -6,6 +6,7 @@ const node_os_1 = require("node:os");
6
6
  const config_1 = require("../lib/config");
7
7
  const detector_1 = require("../lib/agents/detector");
8
8
  const api_client_1 = require("../lib/api-client");
9
+ const project_config_1 = require("../lib/project-config");
9
10
  /**
10
11
  * `ritual doctor` — sanity check the CLI's environment.
11
12
  *
@@ -80,6 +81,38 @@ async function doctorCommand() {
80
81
  }
81
82
  console.log('');
82
83
  }
84
+ // --- Knowledge-graph reachability (PR 107c) ------------------
85
+ // Lightweight verify: if a workspace is bound to this project,
86
+ // fetch its KG summary. Proves auth → API → DB round-trip works
87
+ // AND shows the user where the workspace's KG currently stands.
88
+ // Skip silently when not signed in (covered above) or when no
89
+ // project workspace is bound (not a misconfiguration; the user
90
+ // just hasn't run `ritual init` in this repo yet).
91
+ if (tokenStatus.kind === 'signed-in') {
92
+ const project = (0, project_config_1.loadProjectConfig)(process.cwd());
93
+ if (project) {
94
+ console.log(' Knowledge graph (this project\'s workspace):');
95
+ console.log(` workspace ${project.workspaceName} (${project.workspaceId})`);
96
+ try {
97
+ const api = new api_client_1.ApiClient({
98
+ issuer: tokenStatus.creds.issuer,
99
+ accessToken: tokenStatus.accessToken,
100
+ });
101
+ const summary = await api.get(`/workspaces/${encodeURIComponent(project.workspaceId)}/knowledge-graph/summary`);
102
+ console.log(` counts ${summary.counts.implementations} implementation(s), ${summary.counts.decisions} decision(s), ${summary.counts.deferrals} deferral(s)`);
103
+ if (summary.counts.implementations === 0) {
104
+ console.log(' note cold-start KG — fills as agents call `mcp__ritual__sync_implementation`');
105
+ }
106
+ console.log('');
107
+ }
108
+ catch (err) {
109
+ console.log(` reachable ✗ (${err.message})`);
110
+ console.log(' note cluster/API reachability issue — `ritual graph status` will fail too');
111
+ problems++;
112
+ console.log('');
113
+ }
114
+ }
115
+ }
83
116
  if (problems > 0) {
84
117
  process.exitCode = 1;
85
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.graphStatusCommand = graphStatusCommand;
4
+ const config_1 = require("../lib/config");
5
+ const api_client_1 = require("../lib/api-client");
6
+ const project_config_1 = require("../lib/project-config");
7
+ async function graphStatusCommand(opts = {}) {
8
+ console.log('');
9
+ console.log(' Ritual — knowledge-graph status');
10
+ console.log('');
11
+ // 1. Auth check (uses the same lazy-OAuth flow as the rest of the CLI).
12
+ const tokenStatus = await (0, config_1.getValidAccessToken)();
13
+ if (tokenStatus.kind !== 'signed-in') {
14
+ console.error(' ✗ Not signed in. Run `ritual login` first, then `ritual graph status`.');
15
+ console.error('');
16
+ process.exitCode = 1;
17
+ return;
18
+ }
19
+ // 2. Resolve workspace id.
20
+ let workspaceId = opts.workspace;
21
+ let workspaceSource = '--workspace flag';
22
+ if (!workspaceId) {
23
+ const project = (0, project_config_1.loadProjectConfig)(opts.cwd ?? process.cwd());
24
+ if (project) {
25
+ workspaceId = project.workspaceId;
26
+ workspaceSource = `.ritual/config.json (${project.workspaceName})`;
27
+ }
28
+ }
29
+ if (!workspaceId) {
30
+ console.error(' ✗ No workspace specified.');
31
+ console.error(' Run `ritual init` in your repo to bind one, OR pass `--workspace <id>` explicitly.');
32
+ console.error('');
33
+ process.exitCode = 1;
34
+ return;
35
+ }
36
+ console.log(` Workspace: ${workspaceId} (from ${workspaceSource})`);
37
+ console.log('');
38
+ // 3. Hit the API.
39
+ const issuer = tokenStatus.creds.issuer;
40
+ const api = new api_client_1.ApiClient({
41
+ issuer,
42
+ accessToken: tokenStatus.accessToken,
43
+ });
44
+ const limit = opts.limit ? parseInt(opts.limit, 10) : undefined;
45
+ const queryString = limit ? `?recentLimit=${limit}` : '';
46
+ let summary;
47
+ try {
48
+ summary = await api.get(`/workspaces/${encodeURIComponent(workspaceId)}/knowledge-graph/summary${queryString}`);
49
+ }
50
+ catch (err) {
51
+ console.error(` ✗ Could not fetch graph summary: ${err.message}`);
52
+ console.error('');
53
+ process.exitCode = 1;
54
+ return;
55
+ }
56
+ // 4. Render.
57
+ console.log(` Workspace name: ${summary.workspaceName}`);
58
+ console.log('');
59
+ console.log(' Counts:');
60
+ console.log(` Implementations: ${pad(summary.counts.implementations)}`);
61
+ console.log(` Decisions: ${pad(summary.counts.decisions)}`);
62
+ console.log(` Deferrals: ${pad(summary.counts.deferrals)}`);
63
+ console.log('');
64
+ if (summary.recent.length === 0) {
65
+ // Cold-start KG — no implementations synced yet. Tell the user
66
+ // what to do about it, not just "0 records found."
67
+ console.log(' No implementations have been synced for this workspace yet.');
68
+ console.log('');
69
+ console.log(' The KG fills in when you complete an exploration and your');
70
+ console.log(' AI coding agent calls `mcp__ritual__sync_implementation`');
71
+ console.log(' after landing the work. Until then, /ritual build calls won\'t');
72
+ console.log(' have any prior-implementation context to draw from.');
73
+ console.log('');
74
+ return;
75
+ }
76
+ console.log(` Recent implementations (${summary.recent.length} shown):`);
77
+ console.log('');
78
+ for (const r of summary.recent) {
79
+ const name = r.explorationName ?? '(unnamed)';
80
+ const subtitle = `${r.repo}@${r.branch} · ${r.commitsCount} commit${r.commitsCount === 1 ? '' : 's'} · ${r.decisions} decision${r.decisions === 1 ? '' : 's'} · ${r.deferrals} deferral${r.deferrals === 1 ? '' : 's'}`;
81
+ console.log(` ${shortDate(r.implementedAt)} ${name}`);
82
+ console.log(` ${subtitle}`);
83
+ if (r.prUrl) {
84
+ console.log(` ${r.prUrl}`);
85
+ }
86
+ }
87
+ console.log('');
88
+ }
89
+ /** Right-pad a count for visual alignment in the summary block. */
90
+ function pad(n) {
91
+ return String(n).padStart(3, ' ');
92
+ }
93
+ /** Render an ISO timestamp as YYYY-MM-DD for the recent-list. */
94
+ function shortDate(iso) {
95
+ try {
96
+ return iso.slice(0, 10);
97
+ }
98
+ catch {
99
+ return iso;
100
+ }
101
+ }
102
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/commands/graph.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,12 +8,13 @@ const whoami_1 = require("./commands/whoami");
8
8
  const refresh_1 = require("./commands/refresh");
9
9
  const init_1 = require("./commands/init");
10
10
  const doctor_1 = require("./commands/doctor");
11
+ const graph_1 = require("./commands/graph");
11
12
  const program = new commander_1.Command();
12
13
  program
13
14
  .name('ritual')
14
15
  .description('Ritual CLI — connect AI coding agents to Ritual Cloud. ' +
15
16
  'Scaffold skills, register MCP servers, manage sessions.')
16
- .version('0.4.0');
17
+ .version('0.5.0');
17
18
  // `init` is the headline command: scaffold + register against every
18
19
  // detected agent. Listed first so `ritual --help` surfaces it.
19
20
  program
@@ -49,6 +50,18 @@ program
49
50
  .command('doctor')
50
51
  .description('Sanity check the CLI environment: credentials, endpoints, detected agents')
51
52
  .action(doctor_1.doctorCommand);
53
+ // `graph` is the workspace-KG visibility surface. Today only one
54
+ // subcommand (`status`) but reserved as a noun so future verbs
55
+ // (`verify`, `seed`, `export`) compose naturally.
56
+ const graph = program
57
+ .command('graph')
58
+ .description('Inspect the workspace knowledge graph (PR 107c — visibility layer)');
59
+ graph
60
+ .command('status')
61
+ .description('Show counts + recent implementations for the project\'s workspace')
62
+ .option('--workspace <id>', 'Override the workspaceId. Default reads from .ritual/config.json (set by `ritual init`).')
63
+ .option('--limit <n>', 'Number of recent implementations to show (default 5, max 25)')
64
+ .action(graph_1.graphStatusCommand);
52
65
  program.parseAsync(process.argv).catch((err) => {
53
66
  console.error(`\n ✗ ${err.message}\n`);
54
67
  process.exit(1);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAElD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CACN,gBAAgB,EAChB,kFAAkF,CAClF;KACA,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;KACvE,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAChD,8CAAkD;AAClD,8CAAkD;AAClD,gDAAoD;AACpD,0CAA8C;AAC9C,8CAAkD;AAClD,4CAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACL,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CACX,yDAAyD;IACxD,yDAAyD,CAC1D;KACA,OAAO,CAAC,OAAO,CAAC,CAAC;AAEnB,oEAAoE;AACpE,+DAA+D;AAC/D,OAAO;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kFAAkF,CAAC;KAC/F,MAAM,CAAC,cAAc,EAAE,wDAAwD,CAAC;KAChF,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;KAC9C,MAAM,CACN,gBAAgB,EAChB,kFAAkF,CAClF;KACA,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;KACvE,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CACN,gBAAgB,EAChB,wHAAwH,CACxH;KACA,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEtB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CACN,gBAAgB,EAChB,iGAAiG,CACjG;KACA,MAAM,CACN,kBAAkB,EAClB,4EAA4E,CAC5E;KACA,MAAM,CAAC,OAAO,EAAE,iFAAiF,CAAC;KAClG,MAAM,CAAC,oBAAY,CAAC,CAAC;AAEvB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,wBAAc,CAAC,CAAC;AAEzB,OAAO;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2EAA2E,CAAC;KACxF,MAAM,CAAC,sBAAa,CAAC,CAAC;AAExB,iEAAiE;AACjE,+DAA+D;AAC/D,kDAAkD;AAClD,MAAM,KAAK,GAAG,OAAO;KACnB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oEAAoE,CAAC,CAAC;AAEpF,KAAK;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CACN,kBAAkB,EAClB,0FAA0F,CAC1F;KACA,MAAM,CAAC,aAAa,EAAE,8DAA8D,CAAC;KACrF,MAAM,CAAC,0BAAkB,CAAC,CAAC;AAE7B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACrD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ritualai/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Ritual CLI — scaffold AI coding agent skills + register MCP servers. Connects Claude Code, Cursor, Windsurf, Kiro, Gemini CLI, VS Code/Copilot, and Codex to Ritual Cloud.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",
@@ -24,6 +24,7 @@
24
24
  "prepublishOnly": "pnpm run clean && pnpm run build"
25
25
  },
26
26
  "dependencies": {
27
+ "@ritual/shared-types": "workspace:^",
27
28
  "commander": "^14.0.3",
28
29
  "open": "^10.1.0"
29
30
  },
@@ -53,7 +54,12 @@
53
54
  "jest": {
54
55
  "preset": "ts-jest",
55
56
  "testEnvironment": "node",
56
- "roots": ["<rootDir>/src", "<rootDir>/test"],
57
- "testMatch": ["**/?(*.)+(spec|test).ts"]
57
+ "roots": [
58
+ "<rootDir>/src",
59
+ "<rootDir>/test"
60
+ ],
61
+ "testMatch": [
62
+ "**/?(*.)+(spec|test).ts"
63
+ ]
58
64
  }
59
65
  }
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?
@@ -51,7 +51,7 @@ When **not** to use:
51
51
  - An exploration already exists with recommendations — fetch directly via `get_exploration` + `get_recommendations`
52
52
  - The user wants to *implement* a feature from existing recommendations — use `/ritual-builder-spec` (from `@ritual-ai/cli`)
53
53
 
54
- ### Workflow — 8 phases
54
+ ### Workflow — 9 phases (Phase 8 happens after the engineer ships the work)
55
55
 
56
56
  Each phase has explicit **[USER PAUSE]** points — never skip them.
57
57
 
@@ -319,6 +319,32 @@ Show the final state:
319
319
  >
320
320
  > View at: https://dev.ritualapp.cloud/e/{exploration_id}
321
321
 
322
+ #### Phase 8 — After shipping: close the loop with `sync_implementation`
323
+
324
+ This phase happens *outside* the `/ritual build` chat — after the engineer has taken the accepted recommendations into their coding work and the implementation has actually landed (PR merged, etc.). The agent in that follow-up session should call `mcp__ritual__sync_implementation` to register what shipped, which decisions were made, and what was deliberately deferred.
325
+
326
+ When sync_implementation succeeds, the response now includes:
327
+
328
+ - `decisions: [{ decisionId, area, choice }, ...]` — IDs of every architectural decision logged
329
+ - `deferrals: [{ deferralId, rbId, severity }, ...]` — IDs of every deferral
330
+ - `decisionsCount`, `deferralsCount` — totals for the summary line
331
+ - `webUrl` — clickable link to the exploration's implementation record in the web UI
332
+
333
+ **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
334
+
335
+ > ✓ Logged implementation for **{exploration name}**
336
+ > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
337
+ > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
338
+ > - View: {webUrl}
339
+ >
340
+ > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
341
+
342
+ The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
343
+
344
+ If they want to check the state at any time, point them at:
345
+
346
+ > `ritual graph status` (in their CLI) — shows the workspace's current KG counts + recent implementations.
347
+
322
348
  ### Failure modes & recovery
323
349
 
324
350
  **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Phase 6 without picked questions)?