@meetless/mla 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +81 -0
  3. package/dist/build-info.json +9 -0
  4. package/dist/bundles/ask-core.js +396 -0
  5. package/dist/bundles/mcp.js +16592 -0
  6. package/dist/bundles/trace-core.js +263 -0
  7. package/dist/cli.js +828 -0
  8. package/dist/commands/activate.js +781 -0
  9. package/dist/commands/adoption.js +130 -0
  10. package/dist/commands/ask.js +290 -0
  11. package/dist/commands/context.js +114 -0
  12. package/dist/commands/debug.js +313 -0
  13. package/dist/commands/doctor.js +1021 -0
  14. package/dist/commands/enrich.js +427 -0
  15. package/dist/commands/evidence.js +229 -0
  16. package/dist/commands/flush.js +184 -0
  17. package/dist/commands/graph.js +104 -0
  18. package/dist/commands/init.js +272 -0
  19. package/dist/commands/internal-active-review.js +322 -0
  20. package/dist/commands/internal-auto-index.js +188 -0
  21. package/dist/commands/internal-capture-decisions.js +320 -0
  22. package/dist/commands/internal-evidence-correlate.js +239 -0
  23. package/dist/commands/internal-evidence-hooks.js +240 -0
  24. package/dist/commands/internal-evidence-inject.js +231 -0
  25. package/dist/commands/internal-finalize.js +221 -0
  26. package/dist/commands/internal-pretool-observe.js +225 -0
  27. package/dist/commands/internal-refresh.js +136 -0
  28. package/dist/commands/internal-session-nudge.js +120 -0
  29. package/dist/commands/internal-steer-sync.js +117 -0
  30. package/dist/commands/internal-turn-recap.js +140 -0
  31. package/dist/commands/kb.js +375 -0
  32. package/dist/commands/kb_add.js +681 -0
  33. package/dist/commands/kb_forget.js +283 -0
  34. package/dist/commands/kb_move.js +45 -0
  35. package/dist/commands/kb_pending.js +410 -0
  36. package/dist/commands/kb_personal.js +149 -0
  37. package/dist/commands/kb_promote.js +188 -0
  38. package/dist/commands/kb_purge.js +168 -0
  39. package/dist/commands/kb_reingest.js +335 -0
  40. package/dist/commands/kb_retime.js +170 -0
  41. package/dist/commands/kb_review.js +391 -0
  42. package/dist/commands/kb_revision.js +179 -0
  43. package/dist/commands/kb_show.js +385 -0
  44. package/dist/commands/label.js +226 -0
  45. package/dist/commands/login.js +295 -0
  46. package/dist/commands/logout.js +108 -0
  47. package/dist/commands/mcp-supervisor.js +93 -0
  48. package/dist/commands/mcp.js +227 -0
  49. package/dist/commands/queue-prune.js +98 -0
  50. package/dist/commands/review.js +358 -0
  51. package/dist/commands/rewire.js +124 -0
  52. package/dist/commands/rules.js +728 -0
  53. package/dist/commands/scan-context.js +67 -0
  54. package/dist/commands/session.js +347 -0
  55. package/dist/commands/stats.js +479 -0
  56. package/dist/commands/status.js +61 -0
  57. package/dist/commands/summary.js +250 -0
  58. package/dist/commands/turn.js +114 -0
  59. package/dist/commands/uninstall.js +222 -0
  60. package/dist/commands/whoami.js +102 -0
  61. package/dist/commands/workspace.js +130 -0
  62. package/dist/hooks-template/ce0-post-tool-use.sh +34 -0
  63. package/dist/hooks-template/ce0-session-start.sh +49 -0
  64. package/dist/hooks-template/ce0-stop.sh +29 -0
  65. package/dist/hooks-template/ce0-user-prompt-submit.sh +38 -0
  66. package/dist/hooks-template/common.sh +934 -0
  67. package/dist/hooks-template/event-batch-filter.jq +67 -0
  68. package/dist/hooks-template/flush.sh +503 -0
  69. package/dist/hooks-template/post-tool-use.sh +423 -0
  70. package/dist/hooks-template/pre-tool-use.sh +69 -0
  71. package/dist/hooks-template/session-start.sh +140 -0
  72. package/dist/hooks-template/stop.sh +308 -0
  73. package/dist/hooks-template/user-prompt-submit.sh +1162 -0
  74. package/dist/lib/activation.js +79 -0
  75. package/dist/lib/active-conflict-cache.js +141 -0
  76. package/dist/lib/active-memory.js +59 -0
  77. package/dist/lib/active-review-runner.js +26 -0
  78. package/dist/lib/agent-decision/index.js +25 -0
  79. package/dist/lib/agent-decision/keys.js +49 -0
  80. package/dist/lib/agent-decision/normalize-claude.js +183 -0
  81. package/dist/lib/agent-decision/types.js +21 -0
  82. package/dist/lib/agent-decision/validate.js +216 -0
  83. package/dist/lib/analytics/capture.js +96 -0
  84. package/dist/lib/analytics/command-event.js +267 -0
  85. package/dist/lib/analytics/consent.js +58 -0
  86. package/dist/lib/analytics/coverage-gap.js +96 -0
  87. package/dist/lib/analytics/envelope.js +236 -0
  88. package/dist/lib/analytics/event-id.js +86 -0
  89. package/dist/lib/analytics/evidence.js +150 -0
  90. package/dist/lib/analytics/followthrough.js +194 -0
  91. package/dist/lib/analytics/forwarder.js +109 -0
  92. package/dist/lib/analytics/logs.js +78 -0
  93. package/dist/lib/analytics/metrics.js +78 -0
  94. package/dist/lib/analytics/recorder.js +92 -0
  95. package/dist/lib/analytics/review-analytics.js +75 -0
  96. package/dist/lib/analytics/sequence.js +77 -0
  97. package/dist/lib/analytics/store.js +131 -0
  98. package/dist/lib/analytics/turn-recap.js +279 -0
  99. package/dist/lib/artifact_id.js +108 -0
  100. package/dist/lib/auth-breaker.js +161 -0
  101. package/dist/lib/auto-index.js +112 -0
  102. package/dist/lib/classifier.js +88 -0
  103. package/dist/lib/config.js +298 -0
  104. package/dist/lib/conflict-advisory.js +64 -0
  105. package/dist/lib/debug-bundle.js +520 -0
  106. package/dist/lib/enrichment/ingest.js +301 -0
  107. package/dist/lib/enrichment/plan.js +253 -0
  108. package/dist/lib/enrichment/protocol.js +359 -0
  109. package/dist/lib/enrichment/scout-brief.js +176 -0
  110. package/dist/lib/failure-telemetry.js +444 -0
  111. package/dist/lib/git.js +200 -0
  112. package/dist/lib/governance-cache.js +77 -0
  113. package/dist/lib/governed-path-cache.js +76 -0
  114. package/dist/lib/http.js +677 -0
  115. package/dist/lib/identity-envelope.js +23 -0
  116. package/dist/lib/kb-candidate.js +65 -0
  117. package/dist/lib/kb_acl.js +98 -0
  118. package/dist/lib/login.js +353 -0
  119. package/dist/lib/mcp-fetchers.js +130 -0
  120. package/dist/lib/mcp-restart.js +47 -0
  121. package/dist/lib/observability.js +805 -0
  122. package/dist/lib/open-url.js +33 -0
  123. package/dist/lib/orphan-guard.js +70 -0
  124. package/dist/lib/packaged.js +21 -0
  125. package/dist/lib/reconcile-sessions.js +171 -0
  126. package/dist/lib/redactor.js +89 -0
  127. package/dist/lib/relationship-candidate-query.js +27 -0
  128. package/dist/lib/render.js +611 -0
  129. package/dist/lib/rules/applicability.js +64 -0
  130. package/dist/lib/rules/attest-code-rule-version.js +47 -0
  131. package/dist/lib/rules/attest-notes-location.js +217 -0
  132. package/dist/lib/rules/attest-rule-version.js +69 -0
  133. package/dist/lib/rules/canonical-json.js +97 -0
  134. package/dist/lib/rules/ce0-emit.js +64 -0
  135. package/dist/lib/rules/ce0-evidence.js +281 -0
  136. package/dist/lib/rules/ce0-recall-sample.js +82 -0
  137. package/dist/lib/rules/ce0-rule.js +55 -0
  138. package/dist/lib/rules/ce0-sampling-bucket.js +15 -0
  139. package/dist/lib/rules/ce0-store.js +683 -0
  140. package/dist/lib/rules/ce0-telemetry-project.js +93 -0
  141. package/dist/lib/rules/ce0-telemetry.js +158 -0
  142. package/dist/lib/rules/code-rule-registry.js +17 -0
  143. package/dist/lib/rules/command-match.js +185 -0
  144. package/dist/lib/rules/consult-evidence-binding.js +27 -0
  145. package/dist/lib/rules/consultation-capture-adapter.js +193 -0
  146. package/dist/lib/rules/content-match.js +56 -0
  147. package/dist/lib/rules/deny-admission.js +99 -0
  148. package/dist/lib/rules/durable-observation.js +190 -0
  149. package/dist/lib/rules/enforce-notes-version.js +421 -0
  150. package/dist/lib/rules/evaluation-input-hash.js +126 -0
  151. package/dist/lib/rules/evaluator.js +108 -0
  152. package/dist/lib/rules/inert-rule-families.js +51 -0
  153. package/dist/lib/rules/input-authority-resolver.js +241 -0
  154. package/dist/lib/rules/interception-schema.js +170 -0
  155. package/dist/lib/rules/interception-store.js +267 -0
  156. package/dist/lib/rules/live-input-authority.js +66 -0
  157. package/dist/lib/rules/local-matcher.js +108 -0
  158. package/dist/lib/rules/local-observe.js +79 -0
  159. package/dist/lib/rules/local-rule-version-repo.js +214 -0
  160. package/dist/lib/rules/memory-requirement.js +109 -0
  161. package/dist/lib/rules/notes-observe.js +39 -0
  162. package/dist/lib/rules/notes-path.js +261 -0
  163. package/dist/lib/rules/notes-rule.js +75 -0
  164. package/dist/lib/rules/observe-adapter.js +114 -0
  165. package/dist/lib/rules/observed-rule-hash.js +119 -0
  166. package/dist/lib/rules/prompt-submit-adapter.js +132 -0
  167. package/dist/lib/rules/requirement-subject.js +240 -0
  168. package/dist/lib/rules/rule-activity.js +67 -0
  169. package/dist/lib/rules/rule-version-hash.js +151 -0
  170. package/dist/lib/rules/runtime-scope.js +55 -0
  171. package/dist/lib/rules/stop-adapter.js +116 -0
  172. package/dist/lib/rules/stop-response-snapshot.js +174 -0
  173. package/dist/lib/rules/types.js +10 -0
  174. package/dist/lib/rules/ulid.js +46 -0
  175. package/dist/lib/rules/version-evaluation.js +156 -0
  176. package/dist/lib/scanner/agent-memory.js +99 -0
  177. package/dist/lib/scanner/bootstrap-summary.js +87 -0
  178. package/dist/lib/scanner/cache.js +59 -0
  179. package/dist/lib/scanner/frontmatter.js +42 -0
  180. package/dist/lib/scanner/parse-directives.js +69 -0
  181. package/dist/lib/scanner/parse-structured.js +72 -0
  182. package/dist/lib/scanner/render.js +73 -0
  183. package/dist/lib/scanner/scan.js +132 -0
  184. package/dist/lib/scanner/score.js +38 -0
  185. package/dist/lib/scanner/scout-mission.js +126 -0
  186. package/dist/lib/scanner/types.js +7 -0
  187. package/dist/lib/session-scope.js +195 -0
  188. package/dist/lib/spool.js +355 -0
  189. package/dist/lib/staleness.js +100 -0
  190. package/dist/lib/steer-cache.js +87 -0
  191. package/dist/lib/tagged-reference.js +20 -0
  192. package/dist/lib/temporal.js +109 -0
  193. package/dist/lib/turn-recap-emit.js +67 -0
  194. package/dist/lib/unwire.js +253 -0
  195. package/dist/lib/update-check.js +469 -0
  196. package/dist/lib/update-notifier.js +217 -0
  197. package/dist/lib/upgrade-apply.js +643 -0
  198. package/dist/lib/wire.js +1087 -0
  199. package/dist/lib/workspace.js +96 -0
  200. package/dist/lib/zip.js +154 -0
  201. package/dist/pretool-entry.js +37 -0
  202. package/package.json +75 -0
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseArgs = parseArgs;
4
+ exports.isReviewListInvocation = isReviewListInvocation;
5
+ exports.pendingAliasArgs = pendingAliasArgs;
6
+ exports.runKb = runKb;
7
+ const config_1 = require("../lib/config");
8
+ const http_1 = require("../lib/http");
9
+ const kb_add_1 = require("./kb_add");
10
+ const kb_show_1 = require("./kb_show");
11
+ const kb_reingest_1 = require("./kb_reingest");
12
+ const kb_forget_1 = require("./kb_forget");
13
+ const kb_purge_1 = require("./kb_purge");
14
+ const kb_move_1 = require("./kb_move");
15
+ const kb_pending_1 = require("./kb_pending");
16
+ const kb_review_1 = require("./kb_review");
17
+ const kb_personal_1 = require("./kb_personal");
18
+ const kb_promote_1 = require("./kb_promote");
19
+ const kb_retime_1 = require("./kb_retime");
20
+ const kb_revision_1 = require("./kb_revision");
21
+ // Legacy inspect parser. Only handles `mla kb summary` and `mla kb dump`; the
22
+ // six curation subcommands (add/show/reingest/forget/purge/move) are routed by
23
+ // `runKb` BEFORE this is called and each owns its own arg parser inside its own
24
+ // commands/kb_*.ts module.
25
+ function parseArgs(argv) {
26
+ const sub = argv[0];
27
+ if (sub !== "summary" && sub !== "dump") {
28
+ throw new Error(`Usage: mla kb summary [--json] | mla kb dump [--markdown] [--json]`);
29
+ }
30
+ const out = { sub, json: false, markdown: false };
31
+ for (let i = 1; i < argv.length; i++) {
32
+ const a = argv[i];
33
+ if (a === "--json")
34
+ out.json = true;
35
+ else if (a === "--markdown")
36
+ out.markdown = true;
37
+ else
38
+ throw new Error(`Unknown flag for \`mla kb ${sub}\`: ${a}`);
39
+ }
40
+ return out;
41
+ }
42
+ function n(v) {
43
+ return typeof v === "number" && Number.isFinite(v) ? v : 0;
44
+ }
45
+ // The three buckets of §5.1, plus the Control read-projection mirror. Labels are
46
+ // deliberately honest about provenance: the notes/LDM ingest writes ONLY the
47
+ // Sources layer (chunks + chunk_fts). The graph layer (entities /
48
+ // knowledge_relations / claim-kind entities) is written by the claims extractor
49
+ // (`--pipeline=claims`) and the relationship-promotion loop, NOT by notes
50
+ // ingest, so it reads 0 for a notes-only workspace by design. Conflating the two
51
+ // under an "accepted/live, promoted from sources" label is what made the old
52
+ // output look broken.
53
+ function bucketLines(c) {
54
+ return {
55
+ sources: [
56
+ `chunks (Weaviate): ${n(c.chunks)}`,
57
+ `chunk_fts (lexical): ${n(c.chunk_fts)}`,
58
+ ],
59
+ graph: [
60
+ `entities (nodes): ${n(c.graph_nodes)}`,
61
+ `knowledge_relations: ${n(c.graph_edges)}`,
62
+ `claim-kind entities: ${n(c.claims)}`,
63
+ ],
64
+ ops: [
65
+ `decision diffs: ${n(c.ops_decision_diffs)}`,
66
+ `coordination cases: ${n(c.ops_coordination_cases)}`,
67
+ `relationship candidates: ${n(c.ops_relationship_candidates)}`,
68
+ `workflow audit: ${n(c.ops_workflow_audit)}`,
69
+ `outbox pending: ${n(c.outbox_pending)}`,
70
+ ],
71
+ };
72
+ }
73
+ const SOURCES_LABEL = "Sources (ingested via notes/LDM pipeline):";
74
+ const GRAPH_LABEL = "Internalized graph (claims + relationship pipeline; not written by notes ingest):";
75
+ const OPS_LABEL = "Control read projection:";
76
+ // withDumpPointer is true only for the standalone `summary` view, where the
77
+ // closing line nudges the reader toward `dump`. In `dump` the per-source
78
+ // listing follows immediately below, so repeating "run dump" there would tell
79
+ // the reader to run the command they are already looking at.
80
+ function renderSummary(c, withDumpPointer = true) {
81
+ const b = bucketLines(c);
82
+ const out = [];
83
+ out.push(`Knowledge base summary (workspace: ${c.workspaceId})`);
84
+ out.push("");
85
+ out.push(SOURCES_LABEL);
86
+ b.sources.forEach((l) => out.push(` ${l}`));
87
+ out.push(GRAPH_LABEL);
88
+ b.graph.forEach((l) => out.push(` ${l}`));
89
+ out.push(OPS_LABEL);
90
+ b.ops.forEach((l) => out.push(` ${l}`));
91
+ if (withDumpPointer) {
92
+ out.push("");
93
+ out.push("Counts only. Run `mla kb dump` to list the ingested sources (note paths + chunk counts).");
94
+ }
95
+ return out.join("\n");
96
+ }
97
+ function renderSourcesPlain(s) {
98
+ const out = [];
99
+ out.push(`Ingested sources (${s.total}):`);
100
+ if (s.total === 0) {
101
+ out.push(" none yet (nothing ingested into chunk_fts for this workspace).");
102
+ return out.join("\n");
103
+ }
104
+ for (const src of s.sources) {
105
+ const when = src.lastIngestedAt ?? "unknown";
106
+ out.push(` ${src.documentId}`);
107
+ out.push(` ${src.parentKind}, ${n(src.chunkCount)} chunks, last ingested ${when}`);
108
+ }
109
+ return out.join("\n");
110
+ }
111
+ function renderDumpPlain(c, s) {
112
+ return [renderSummary(c, false), "", renderSourcesPlain(s)].join("\n");
113
+ }
114
+ function mdRow(l) {
115
+ const idx = l.lastIndexOf(":");
116
+ const label = l.slice(0, idx).trim();
117
+ const val = l.slice(idx + 1).trim();
118
+ return `| ${label} | ${val} |`;
119
+ }
120
+ function mdSection(title, lines) {
121
+ return [`### ${title}`, "", "| substrate | count |", "| --- | --- |", ...lines.map(mdRow), ""].join("\n");
122
+ }
123
+ function mdSources(s) {
124
+ const head = [`### Ingested sources (${s.total})`, ""];
125
+ if (s.total === 0) {
126
+ return [...head, "_none yet (nothing ingested into chunk_fts for this workspace)._", ""].join("\n");
127
+ }
128
+ const rows = s.sources.map((src) => `| ${src.documentId} | ${src.parentKind} | ${n(src.chunkCount)} | ${src.lastIngestedAt ?? "unknown"} |`);
129
+ return [
130
+ ...head,
131
+ "| source | kind | chunks | last ingested |",
132
+ "| --- | --- | --- | --- |",
133
+ ...rows,
134
+ "",
135
+ ].join("\n");
136
+ }
137
+ function renderDumpMarkdown(c, s) {
138
+ const b = bucketLines(c);
139
+ const ts = new Date().toISOString();
140
+ return [
141
+ `# Meetless knowledge base snapshot`,
142
+ "",
143
+ `- workspace: \`${c.workspaceId}\``,
144
+ `- generated: ${ts}`,
145
+ "",
146
+ mdSection("Sources (ingested via notes/LDM pipeline)", b.sources),
147
+ mdSection("Internalized graph (claims + relationship pipeline, not notes ingest)", b.graph),
148
+ mdSection("Control read projection", b.ops),
149
+ mdSources(s),
150
+ `> Sources are listed per-document from chunk_fts. The graph + control`,
151
+ `> projection layers expose counts only (their per-item read endpoints`,
152
+ `> remain deferred). Counts wrap \`/v1/debug/substrate_counts\`; the source`,
153
+ `> list wraps \`/v1/debug/ingested_sources\`.`,
154
+ "",
155
+ ].join("\n");
156
+ }
157
+ function explainIntelError(err, intelUrl) {
158
+ if (err.status === 404) {
159
+ return (`intel returned 404 for a /v1/debug route. Those routes are mounted ` +
160
+ `only when intel runs with SERVER_ENV != production; the KB inspector ` +
161
+ `needs a non-production intel.`);
162
+ }
163
+ if (err.status === 401 || err.status === 403) {
164
+ return `intel rejected the token (HTTP ${err.status}). Check controlToken in cli-config.json.`;
165
+ }
166
+ if (err.status === undefined) {
167
+ return `intel not reachable at ${intelUrl}. Is it running? Try \`mla doctor\`.`;
168
+ }
169
+ return err.message;
170
+ }
171
+ // The user-facing `mla kb` catalog. This is the help surface an operator (or
172
+ // an agent) reads to decide WHICH kb subcommand to run, so it has to teach the
173
+ // one fact that gets the commands confused: posture (grounding) and
174
+ // relationships (coherence) are two independent axes, and `kb promote` only
175
+ // touches the first. The accurate model used to live ONLY in a code comment
176
+ // above; surfacing it here is the root-cause fix for "add/promote/review get
177
+ // mixed up". Keep the word "Usage" present: the bad-subcommand error path
178
+ // re-emits this block and a test locks that contract.
179
+ const KB_USAGE = `mla kb: Knowledge Base curation, grounding, and relationship review.
180
+
181
+ Two independent axes govern every KB doc. Do not conflate them:
182
+
183
+ posture (grounding): does the agent retrieve + cite this doc?
184
+ LIVE = grounded, agent-visible. SHADOW = stored, NOT grounded.
185
+ Posture defaults BY provenance at ingest:
186
+ human_authored -> LIVE (grounded immediately; no extra step)
187
+ agent_distilled, tool_emitted, external_imported,
188
+ external_scraped -> SHADOW (promote later with \`mla kb promote\`)
189
+ So \`mla kb add --provenance human_authored\` already remembers a
190
+ decision: it lands LIVE. \`kb promote\` ONLY flips a SHADOW Personal-KB
191
+ doc to LIVE; it is NOT how a human-authored doc becomes grounded.
192
+
193
+ relationships (coherence): how does this doc relate to existing docs?
194
+ Edges (SUPERSEDES / CONTRADICTS / REFINES / REFERENCES) are proposed as
195
+ candidates and decided via \`kb review\` (list, then verdict). Reviewing an
196
+ edge records how docs relate; it does NOT change grounding (posture).
197
+
198
+ Relations also carry TIME. Two temporal axes, never conflated:
199
+
200
+ valid-time: when a relation is TRUE in the world (its valid-from / valid-until
201
+ window). \`mla kb show --as-of <date>\` and \`mla ask --as-of <date>\` answer
202
+ point-in-time: relations not yet valid at that instant, or carried on an
203
+ untrusted clock, are excluded. Validity is SEPARATE from posture and from
204
+ relationship review.
205
+
206
+ observation-time: when Meetless recorded the relation. A trusted clock means
207
+ valid-time came from an author stamp or document date; an approximate clock
208
+ means we only know when we observed it, not when it became true. \`kb show\`
209
+ prints each relation's window plus this trust so observation never reads as
210
+ validity.
211
+
212
+ Usage:
213
+ ingest + curation
214
+ mla kb add <path> --mode file|corpus --provenance <kind>
215
+ [--workspace <id>] [--vault-root <dir>]
216
+ [--profile <p>] [--glob <g>] [--ingest-run-id <id>]
217
+ [--queue] [--open]
218
+ (born PENDING; --provenance is advisory, server derives trust)
219
+ mla kb show <kbdoc:<id>|note:<path>|<path>>
220
+ [--posture both|LIVE|SHADOW] [--as-of <date>]
221
+ [--all] [--json] [--open]
222
+ mla kb reingest <kbdoc:<id>|note:<path>|<path>> [--path <new-path>] [--reason <s>]
223
+ mla kb accept <kbdoc:<id>|<doc-id>> [--reason <s>] [--json]
224
+ mla kb reject <kbdoc:<id>|<doc-id>> [--reason <s>] [--json]
225
+ (resolve a revision a reingest parked at SHADOW_PENDING_REVIEW
226
+ because the doc has promoted edges. accept makes the pending
227
+ revision live (it starts grounding answers, the old one is
228
+ superseded); reject discards it and keeps the old revision
229
+ serving. Acts on the doc's single pending revision: this is the
230
+ grounding-BYTES axis, separate from \`kb promote\` (posture) and
231
+ from \`kb review\` (which decides relationship edges, NOT
232
+ revisions, despite also taking --accept / --reject).)
233
+ mla kb forget <kbdoc:<id>|note:<path>|<path>> [--reason <s>]
234
+ mla kb purge <kbdoc:<id>|note:<path>|<path>> --reason <s> [--force]
235
+ mla kb move <kbdoc:<id>|note:<path>|<path>> <new-path> [--reason <s>]
236
+ mla kb retime <source-item-id> --effective-date <date>
237
+ [--reason <s>] [--anchor-type <t>] [--json]
238
+ (correct the source item's effective date; regenerates its
239
+ derived relations through the correction path. Edits the
240
+ SOURCE ITEM, not a relation: an accepted relation is never
241
+ edited in place nor deleted.)
242
+
243
+ grounding (posture)
244
+ mla kb promote <doc-id> promote a SHADOW Personal-KB doc to LIVE
245
+ mla kb promote --reject <doc-id> decline the promotion; leaves it SHADOW, untouched
246
+ mla kb personal list this actor's own SHADOW Personal-KB docs
247
+ mla kb personal show <id> inspect one (reuses \`mla kb show\`)
248
+
249
+ relationship review
250
+ mla kb review list the queue (defaults to your current session)
251
+ mla kb review --all list the full workspace queue
252
+ mla kb review --session <sid|current|latest> list a specific session's candidates
253
+ mla kb review [scope] --json structured output (with agent policy + scope)
254
+ mla kb review <candidate-id> --accept | --reject [--note <text>] [--agent]
255
+ record a verdict (--accept is human-only)
256
+
257
+ inspect
258
+ mla kb summary [--json] substrate counts for this workspace
259
+ mla kb dump [--markdown] [--json] counts + one row per ingested source`;
260
+ // Overload boundary for the `review` verb: a leading candidate id means "record a
261
+ // verdict on this one"; anything else (no args, or a leading flag) means "list the
262
+ // review queue". Candidate ids are CUIDs (no leading dash) and are passed first in
263
+ // every documented usage.
264
+ function isReviewListInvocation(argv) {
265
+ return argv.length === 0 || argv[0].startsWith("-");
266
+ }
267
+ // `pending` is the deprecated alias for the listing. Historically it was
268
+ // workspace-wide, so inject --all to keep that default, but ONLY when the caller
269
+ // passed no explicit scope (so old `pending --doc x` / `pending --session y` keep
270
+ // working instead of tripping the mutual-exclusivity guard).
271
+ function pendingAliasArgs(argv) {
272
+ const hasScope = argv.includes("--all") || argv.includes("--session") || argv.includes("--doc");
273
+ return hasScope ? argv : ["--all", ...argv];
274
+ }
275
+ // Curation subcommand router (kb v2.3). Each subcommand owns its own arg
276
+ // parser + exit codes inside commands/kb_*.ts. summary/dump fall through to
277
+ // the legacy inspect handler below.
278
+ async function runKb(argv) {
279
+ const sub = argv[0];
280
+ const rest = argv.slice(1);
281
+ // Help is workspace-free: print the full catalog to stdout, exit 0. This is
282
+ // reached by `mla kb`, `mla kb help`, and `mla kb --help/-h`.
283
+ if (sub === undefined || sub === "help" || sub === "--help" || sub === "-h") {
284
+ console.log(KB_USAGE);
285
+ return 0;
286
+ }
287
+ switch (sub) {
288
+ case "add":
289
+ return (0, kb_add_1.runKbAdd)(rest);
290
+ case "show":
291
+ return (0, kb_show_1.runKbShow)(rest);
292
+ case "reingest":
293
+ return (0, kb_reingest_1.runKbReingest)(rest);
294
+ case "forget":
295
+ return (0, kb_forget_1.runKbForget)(rest);
296
+ case "purge":
297
+ return (0, kb_purge_1.runKbPurge)(rest);
298
+ case "move":
299
+ return (0, kb_move_1.runKbMove)(rest);
300
+ case "review":
301
+ return isReviewListInvocation(rest) ? (0, kb_pending_1.runKbReviewList)(rest) : (0, kb_review_1.runKbReview)(rest);
302
+ case "pending":
303
+ return (0, kb_pending_1.runKbReviewList)(pendingAliasArgs(rest));
304
+ case "personal":
305
+ return (0, kb_personal_1.runKbPersonal)(rest);
306
+ case "promote":
307
+ // `share` is the deprecated alias for `promote` (renamed because "share"
308
+ // read as "invite a teammate"; the verb only flips SHADOW -> LIVE posture).
309
+ // Kept routing so existing hooks/scripts/muscle-memory keep working; it is
310
+ // intentionally NOT advertised in the catalog, exactly like `pending`.
311
+ case "share":
312
+ return (await (0, kb_promote_1.runKbPromote)(rest)).code;
313
+ case "retime":
314
+ return (0, kb_retime_1.runKbRetime)(rest);
315
+ case "accept":
316
+ return (0, kb_revision_1.runKbAccept)(rest);
317
+ case "reject":
318
+ return (0, kb_revision_1.runKbReject)(rest);
319
+ }
320
+ // Anything that is not a routed subcommand and not summary/dump is unknown.
321
+ // Emit the full catalog (not the old summary|dump-only line, which hid every
322
+ // curation command) on stderr, and do it WITHOUT requiring a workspace so the
323
+ // error is the same whether or not the folder is activated.
324
+ if (sub !== "summary" && sub !== "dump") {
325
+ console.error(`unknown \`mla kb\` subcommand: ${sub}\n`);
326
+ console.error(KB_USAGE);
327
+ return 2;
328
+ }
329
+ const cfg = (0, config_1.loadWorkspaceConfig)();
330
+ let args;
331
+ try {
332
+ args = parseArgs(argv);
333
+ }
334
+ catch (e) {
335
+ console.error(e.message);
336
+ return 2;
337
+ }
338
+ const intelUrl = cfg.intelUrl || http_1.DEFAULT_INTEL_URL;
339
+ const qs = new URLSearchParams({ workspaceId: cfg.workspaceId }).toString();
340
+ let counts;
341
+ try {
342
+ counts = await (0, http_1.intelGet)(cfg, `/v1/debug/substrate_counts?${qs}`, 10000);
343
+ }
344
+ catch (e) {
345
+ console.error(explainIntelError(e, intelUrl));
346
+ return 1;
347
+ }
348
+ if (args.sub === "summary") {
349
+ if (args.json) {
350
+ console.log(JSON.stringify(counts, null, 2));
351
+ return 0;
352
+ }
353
+ console.log(renderSummary(counts));
354
+ return 0;
355
+ }
356
+ // dump: fetch the per-source listing too.
357
+ let sources;
358
+ try {
359
+ sources = await (0, http_1.intelGet)(cfg, `/v1/debug/ingested_sources?${qs}`, 10000);
360
+ }
361
+ catch (e) {
362
+ console.error(explainIntelError(e, intelUrl));
363
+ return 1;
364
+ }
365
+ if (args.json) {
366
+ console.log(JSON.stringify({ counts, sources }, null, 2));
367
+ return 0;
368
+ }
369
+ if (args.markdown) {
370
+ console.log(renderDumpMarkdown(counts, sources));
371
+ return 0;
372
+ }
373
+ console.log(renderDumpPlain(counts, sources));
374
+ return 0;
375
+ }