memorix 1.2.1 → 1.2.2

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 (199) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +14 -2
  3. package/README.zh-CN.md +14 -2
  4. package/TEAM.md +86 -86
  5. package/dist/cli/index.js +15407 -13779
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/index.js +1321 -529
  8. package/dist/index.js.map +1 -1
  9. package/dist/maintenance-runner.d.ts +1 -1
  10. package/dist/maintenance-runner.js +8458 -8087
  11. package/dist/maintenance-runner.js.map +1 -1
  12. package/dist/memcode-runtime/CHANGELOG.md +16 -0
  13. package/dist/sdk.d.ts +7 -2
  14. package/dist/sdk.js +1349 -535
  15. package/dist/sdk.js.map +1 -1
  16. package/dist/types.d.ts +49 -1
  17. package/dist/types.js.map +1 -1
  18. package/docs/1.2.2-MEMORY-CONTROL-PLANE.md +434 -0
  19. package/docs/AGENT_OPERATOR_PLAYBOOK.md +4 -0
  20. package/docs/API_REFERENCE.md +24 -4
  21. package/docs/DESIGN_DECISIONS.md +357 -357
  22. package/docs/README.md +1 -1
  23. package/docs/dev-log/progress.txt +91 -11
  24. package/package.json +1 -1
  25. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  26. package/src/audit/index.ts +156 -156
  27. package/src/cli/command-guide.ts +192 -0
  28. package/src/cli/commands/audit-list.ts +89 -89
  29. package/src/cli/commands/audit.ts +9 -4
  30. package/src/cli/commands/background.ts +659 -659
  31. package/src/cli/commands/cleanup.ts +5 -1
  32. package/src/cli/commands/codegraph.ts +15 -5
  33. package/src/cli/commands/context.ts +3 -2
  34. package/src/cli/commands/doctor.ts +4 -2
  35. package/src/cli/commands/explain.ts +9 -3
  36. package/src/cli/commands/formation.ts +48 -48
  37. package/src/cli/commands/git-hook-install.ts +111 -111
  38. package/src/cli/commands/handoff.ts +75 -61
  39. package/src/cli/commands/hooks-status.ts +63 -63
  40. package/src/cli/commands/identity.ts +116 -0
  41. package/src/cli/commands/ingest-commit.ts +153 -153
  42. package/src/cli/commands/ingest-image.ts +71 -69
  43. package/src/cli/commands/ingest-log.ts +180 -180
  44. package/src/cli/commands/ingest.ts +44 -44
  45. package/src/cli/commands/integrate-shared.ts +15 -15
  46. package/src/cli/commands/lock.ts +93 -92
  47. package/src/cli/commands/memory.ts +58 -21
  48. package/src/cli/commands/message.ts +123 -118
  49. package/src/cli/commands/operator-shared.ts +98 -3
  50. package/src/cli/commands/poll.ts +74 -64
  51. package/src/cli/commands/purge-all-memory.ts +85 -85
  52. package/src/cli/commands/purge-project-memory.ts +83 -83
  53. package/src/cli/commands/reasoning.ts +135 -121
  54. package/src/cli/commands/retention.ts +9 -4
  55. package/src/cli/commands/serve-http.ts +8 -2
  56. package/src/cli/commands/serve-shared.ts +118 -118
  57. package/src/cli/commands/session.ts +29 -3
  58. package/src/cli/commands/skills.ts +124 -119
  59. package/src/cli/commands/status.ts +4 -3
  60. package/src/cli/commands/task.ts +193 -184
  61. package/src/cli/commands/team.ts +14 -10
  62. package/src/cli/commands/transfer.ts +108 -55
  63. package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
  64. package/src/cli/identity.ts +89 -0
  65. package/src/cli/index.ts +96 -19
  66. package/src/cli/invocation.ts +115 -0
  67. package/src/cli/tui/ChatView.tsx +234 -234
  68. package/src/cli/tui/CommandBar.tsx +312 -312
  69. package/src/cli/tui/ContextRail.tsx +118 -118
  70. package/src/cli/tui/HeaderBar.tsx +72 -72
  71. package/src/cli/tui/LogoBanner.tsx +51 -51
  72. package/src/cli/tui/Sidebar.tsx +179 -179
  73. package/src/cli/tui/chat-service.ts +41 -18
  74. package/src/cli/tui/data.ts +23 -44
  75. package/src/cli/tui/index.ts +41 -41
  76. package/src/cli/tui/markdown-render.tsx +371 -371
  77. package/src/cli/tui/operator-context.ts +60 -0
  78. package/src/cli/tui/use-mouse.ts +157 -157
  79. package/src/cli/tui/useNavigation.ts +56 -56
  80. package/src/cli/tui/views/MemoryView.tsx +10 -8
  81. package/src/cli/update-checker.ts +211 -211
  82. package/src/cli/version.ts +7 -7
  83. package/src/cli/workbench.ts +1 -1
  84. package/src/codegraph/auto-context.ts +31 -2
  85. package/src/codegraph/context-pack.ts +1 -0
  86. package/src/codegraph/project-context.ts +2 -0
  87. package/src/compact/engine.ts +26 -10
  88. package/src/compact/index-format.ts +25 -2
  89. package/src/compact/token-budget.ts +74 -74
  90. package/src/dashboard/project-classification.ts +64 -64
  91. package/src/dashboard/server.ts +46 -9
  92. package/src/embedding/fastembed-provider.ts +142 -142
  93. package/src/embedding/transformers-provider.ts +111 -111
  94. package/src/git/extractor.ts +209 -209
  95. package/src/git/hooks-path.ts +85 -85
  96. package/src/hooks/admission.ts +117 -0
  97. package/src/hooks/handler.ts +98 -91
  98. package/src/hooks/pattern-detector.ts +173 -173
  99. package/src/hooks/significance-filter.ts +250 -250
  100. package/src/knowledge/context-assembly.ts +97 -0
  101. package/src/knowledge/workset.ts +179 -10
  102. package/src/llm/memory-manager.ts +328 -328
  103. package/src/llm/provider.ts +885 -885
  104. package/src/llm/quality.ts +248 -248
  105. package/src/memory/admission.ts +57 -0
  106. package/src/memory/attribution-guard.ts +249 -249
  107. package/src/memory/consolidation.ts +13 -2
  108. package/src/memory/disclosure-policy.ts +140 -135
  109. package/src/memory/entity-extractor.ts +197 -197
  110. package/src/memory/export-import.ts +11 -3
  111. package/src/memory/formation/evaluate.ts +217 -217
  112. package/src/memory/formation/extract.ts +361 -361
  113. package/src/memory/formation/index.ts +417 -417
  114. package/src/memory/formation/resolve.ts +344 -344
  115. package/src/memory/formation/types.ts +315 -315
  116. package/src/memory/freshness.ts +122 -122
  117. package/src/memory/graph-context.ts +8 -2
  118. package/src/memory/graph.ts +197 -197
  119. package/src/memory/observations.ts +162 -4
  120. package/src/memory/quality-audit.ts +2 -0
  121. package/src/memory/refs.ts +94 -94
  122. package/src/memory/retention.ts +22 -2
  123. package/src/memory/secret-filter.ts +79 -79
  124. package/src/memory/session.ts +5 -2
  125. package/src/memory/visibility.ts +80 -0
  126. package/src/multimodal/image-loader.ts +143 -143
  127. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  128. package/src/orchestrate/adapters/claude.ts +111 -111
  129. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  130. package/src/orchestrate/adapters/codex.ts +41 -41
  131. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  132. package/src/orchestrate/adapters/gemini.ts +42 -42
  133. package/src/orchestrate/adapters/index.ts +73 -73
  134. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  135. package/src/orchestrate/adapters/opencode.ts +47 -47
  136. package/src/orchestrate/adapters/spawn-helper.ts +286 -286
  137. package/src/orchestrate/adapters/types.ts +77 -77
  138. package/src/orchestrate/capability-router.ts +284 -284
  139. package/src/orchestrate/context-compact.ts +188 -188
  140. package/src/orchestrate/cost-tracker.ts +219 -219
  141. package/src/orchestrate/error-recovery.ts +191 -191
  142. package/src/orchestrate/evidence.ts +140 -140
  143. package/src/orchestrate/ledger.ts +110 -110
  144. package/src/orchestrate/memorix-bridge.ts +378 -340
  145. package/src/orchestrate/output-budget.ts +80 -80
  146. package/src/orchestrate/permission.ts +152 -152
  147. package/src/orchestrate/pipeline-trace.ts +131 -131
  148. package/src/orchestrate/prompt-builder.ts +155 -155
  149. package/src/orchestrate/ring-buffer.ts +37 -37
  150. package/src/orchestrate/task-graph.ts +389 -389
  151. package/src/orchestrate/worktree.ts +232 -232
  152. package/src/project/aliases.ts +374 -374
  153. package/src/project/detector.ts +268 -268
  154. package/src/rules/adapters/claude-code.ts +99 -99
  155. package/src/rules/adapters/codex.ts +97 -97
  156. package/src/rules/adapters/copilot.ts +124 -124
  157. package/src/rules/adapters/cursor.ts +114 -114
  158. package/src/rules/adapters/kiro.ts +126 -126
  159. package/src/rules/adapters/trae.ts +56 -56
  160. package/src/rules/adapters/windsurf.ts +83 -83
  161. package/src/rules/syncer.ts +235 -235
  162. package/src/runtime/control-plane-maintenance.ts +1 -0
  163. package/src/runtime/isolated-maintenance.ts +1 -0
  164. package/src/runtime/lifecycle.ts +18 -0
  165. package/src/runtime/maintenance-jobs.ts +1 -0
  166. package/src/runtime/maintenance-runner.ts +2 -0
  167. package/src/runtime/project-maintenance.ts +89 -0
  168. package/src/sdk.ts +334 -304
  169. package/src/search/intent-detector.ts +289 -289
  170. package/src/search/query-expansion.ts +52 -52
  171. package/src/server/formation-timeout.ts +27 -27
  172. package/src/server.ts +260 -81
  173. package/src/skills/mini-skills.ts +386 -386
  174. package/src/store/chat-store.ts +119 -119
  175. package/src/store/graph-store.ts +249 -249
  176. package/src/store/mini-skill-store.ts +349 -349
  177. package/src/store/orama-store.ts +61 -6
  178. package/src/store/persistence-json.ts +212 -212
  179. package/src/store/persistence.ts +291 -291
  180. package/src/store/project-affinity.ts +195 -195
  181. package/src/store/sqlite-db.ts +23 -1
  182. package/src/store/sqlite-store.ts +12 -2
  183. package/src/team/event-bus.ts +76 -76
  184. package/src/team/file-locks.ts +173 -173
  185. package/src/team/handoff.ts +168 -161
  186. package/src/team/messages.ts +203 -203
  187. package/src/team/poll.ts +132 -132
  188. package/src/team/tasks.ts +211 -211
  189. package/src/types.ts +51 -0
  190. package/src/wiki/generator.ts +2 -0
  191. package/src/workspace/mcp-adapters/codex.ts +191 -191
  192. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  193. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  194. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  195. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  196. package/src/workspace/mcp-adapters/trae.ts +134 -134
  197. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  198. package/src/workspace/sanitizer.ts +60 -60
  199. package/src/workspace/workflow-sync.ts +131 -131
@@ -6,6 +6,14 @@ import { KnowledgeWorkspaceStore } from './workspace-store.js';
6
6
  import { loadKnowledgeWorkspace } from './workspace.js';
7
7
  import { WorkflowStore } from './workflow-store.js';
8
8
  import { selectWorkflows } from './workflows.js';
9
+ import type {
10
+ ContextCandidateFreshness,
11
+ ContextCandidateKind,
12
+ ContextDeliveryTarget,
13
+ ContextReceipt,
14
+ ContextReceiptOmission,
15
+ ContextReceiptSelection,
16
+ } from './context-assembly.js';
9
17
  import type { CodeGraphProviderQuality, ExternalCodeGraphOutline } from '../codegraph/types.js';
10
18
  import type { KnowledgeClaim, ClaimEvidenceRef } from './types.js';
11
19
  import type { KnowledgePageRecord, KnowledgeWorkspace } from './workspace-types.js';
@@ -98,6 +106,8 @@ export interface TaskWorkset {
98
106
  tokenCount: number;
99
107
  omitted: string[];
100
108
  };
109
+ /** Privacy-safe selection metadata for diagnostics, never appended to the prompt. */
110
+ receipt: ContextReceipt;
101
111
  prompt: string;
102
112
  }
103
113
 
@@ -128,6 +138,8 @@ export interface BuildTaskWorksetInput {
128
138
  };
129
139
  runtimeCautions?: WorksetCaution[];
130
140
  maxTokens?: number;
141
+ /** Delivery surface controls receipt semantics without changing prompt shape. */
142
+ deliveryTarget?: ContextDeliveryTarget;
131
143
  }
132
144
 
133
145
  function unique(values: string[]): string[] {
@@ -228,35 +240,104 @@ function appendLine(
228
240
  maxTokens: number,
229
241
  omitted: string[],
230
242
  omittedKind: string,
243
+ selected?: ContextReceiptSelection[],
244
+ receiptSelection?: ContextReceiptSelection,
231
245
  ): boolean {
232
246
  const next = lines.length ? lines.join('\n') + '\n' + candidate : candidate;
233
247
  if (countTextTokens(next) <= maxTokens) {
234
248
  lines.push(candidate);
249
+ if (receiptSelection) selected?.push(receiptSelection);
235
250
  return true;
236
251
  }
237
252
  omitted.push(omittedKind);
238
253
  return false;
239
254
  }
240
255
 
256
+ function freshnessForMemory(status: WorksetMemorySource['status']): ContextCandidateFreshness {
257
+ if (status === 'current' || status === 'suspect' || status === 'stale') return status;
258
+ return 'unknown';
259
+ }
260
+
261
+ function receiptOmissionKind(raw: string): ContextCandidateKind | undefined {
262
+ if (raw.includes('task')) return 'task';
263
+ if (raw.includes('fact')) return 'current-fact';
264
+ if (raw.includes('state')) return 'code-state';
265
+ if (raw.includes('semantic')) return 'semantic-code';
266
+ if (raw.includes('start')) return 'start-here';
267
+ if (raw.includes('memory')) return 'memory';
268
+ if (raw.includes('claim')) return 'claim';
269
+ if (raw.includes('knowledge-page')) return 'knowledge-page';
270
+ if (raw.includes('workflow')) return 'workflow';
271
+ if (raw.includes('verification')) return 'verification';
272
+ if (raw.includes('caution')) return 'caution';
273
+ return undefined;
274
+ }
275
+
276
+ function receiptOmissions(omitted: string[], hiddenCautionMemoryCount: number): ContextReceiptOmission[] {
277
+ const counts = new Map<ContextCandidateKind, number>();
278
+ for (const raw of omitted) {
279
+ const kind = receiptOmissionKind(raw);
280
+ if (!kind || raw.endsWith('-heading')) continue;
281
+ counts.set(kind, (counts.get(kind) ?? 0) + 1);
282
+ }
283
+ const receipt: ContextReceiptOmission[] = [...counts.entries()].map(([kind, count]) => ({
284
+ kind,
285
+ reason: 'token-budget',
286
+ count,
287
+ }));
288
+ if (hiddenCautionMemoryCount > 0) {
289
+ receipt.push({
290
+ kind: 'caution',
291
+ reason: 'hidden-by-task-lens',
292
+ count: hiddenCautionMemoryCount,
293
+ });
294
+ }
295
+ return receipt;
296
+ }
297
+
298
+ function scheduledActions(cautions: WorksetCaution[]): string[] {
299
+ return cautions
300
+ .filter(caution => caution.kind === 'codegraph-refresh-queued')
301
+ .map(caution => short(caution.message, 28));
302
+ }
303
+
241
304
  /**
242
305
  * Render a bounded prompt from whole evidence items. It never cuts a page,
243
306
  * workflow, or claim body into an untraceable partial fragment.
244
307
  */
245
- export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'budget'> & {
308
+ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'budget' | 'receipt'> & {
246
309
  budget?: Partial<TaskWorkset['budget']>;
247
- }): { prompt: string; tokenCount: number; omitted: string[] } {
310
+ }): {
311
+ prompt: string;
312
+ tokenCount: number;
313
+ /** Compatibility summary: unique omission categories. */
314
+ omitted: string[];
315
+ /** Internal receipt input: one entry per candidate that did not fit. */
316
+ omittedItems: string[];
317
+ selected: ContextReceiptSelection[];
318
+ } {
248
319
  const maxTokens = input.budget?.maxTokens ?? 180;
249
320
  const omitted: string[] = [];
321
+ const selected: ContextReceiptSelection[] = [];
250
322
  const lines: string[] = ['Memorix Autopilot Brief'];
251
323
  const task = short(input.task || 'Continue the current task.', 34);
252
- appendLine(lines, 'Task: ' + task, maxTokens, omitted, 'task-detail');
324
+ appendLine(lines, 'Task: ' + task, maxTokens, omitted, 'task-detail', selected, {
325
+ kind: 'task',
326
+ reason: 'current task supplied by the caller',
327
+ trust: 'source-backed',
328
+ });
253
329
  appendLine(lines, 'Task lens: ' + input.lens, maxTokens, omitted, 'lens');
254
330
 
255
331
  if (input.cautions.length > 0 || input.cautionMemory.length > 0) {
256
332
  appendLine(lines, '', maxTokens, omitted, 'caution-heading');
257
333
  appendLine(lines, 'Cautions', maxTokens, omitted, 'caution-heading');
258
334
  for (const caution of input.cautions.slice(0, 6)) {
259
- appendLine(lines, '- ' + short(caution.message, 22), maxTokens, omitted, 'caution');
335
+ appendLine(lines, '- ' + short(caution.message, 22), maxTokens, omitted, 'caution', selected, {
336
+ kind: 'caution',
337
+ id: 'caution:' + caution.kind,
338
+ reason: 'current project caution',
339
+ trust: 'source-backed',
340
+ });
260
341
  }
261
342
  for (const memory of input.cautionMemory.slice(0, 3)) {
262
343
  const location = memory.path
@@ -269,6 +350,14 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
269
350
  maxTokens,
270
351
  omitted,
271
352
  'caution-memory',
353
+ selected,
354
+ {
355
+ kind: 'memory',
356
+ id: 'memory:' + memory.id,
357
+ reason: 'task-relevant memory requiring source verification',
358
+ freshness: freshnessForMemory(memory.status),
359
+ trust: 'historical',
360
+ },
272
361
  );
273
362
  }
274
363
  if (input.hiddenCautionMemoryCount > 0) {
@@ -280,14 +369,23 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
280
369
  appendLine(lines, '', maxTokens, omitted, 'facts-heading');
281
370
  appendLine(lines, 'Current project facts', maxTokens, omitted, 'facts-heading');
282
371
  for (const fact of input.currentFacts.slice(0, 4)) {
283
- appendLine(lines, '- ' + short(fact, 40), maxTokens, omitted, 'current-fact');
372
+ appendLine(lines, '- ' + short(fact, 40), maxTokens, omitted, 'current-fact', selected, {
373
+ kind: 'current-fact',
374
+ reason: 'current project state',
375
+ trust: 'source-backed',
376
+ });
284
377
  }
285
378
  }
286
379
 
287
380
  if (input.codeState) {
288
381
  appendLine(lines, '', maxTokens, omitted, 'state-heading');
289
382
  appendLine(lines, 'Project state', maxTokens, omitted, 'state-heading');
290
- appendLine(lines, input.codeState, maxTokens, omitted, 'code-state');
383
+ appendLine(lines, input.codeState, maxTokens, omitted, 'code-state', selected, {
384
+ kind: 'code-state',
385
+ ...(input.provenance.snapshotId ? { id: 'snapshot:' + input.provenance.snapshotId } : {}),
386
+ reason: 'latest available Code State snapshot',
387
+ trust: 'source-backed',
388
+ });
291
389
  }
292
390
 
293
391
  if (input.semanticCode && (input.semanticCode.entryPoints.length > 0 || input.semanticCode.relations.length > 0)) {
@@ -301,6 +399,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
301
399
  maxTokens,
302
400
  omitted,
303
401
  'semantic-relation',
402
+ selected,
403
+ {
404
+ kind: 'semantic-code',
405
+ id: 'code:' + location,
406
+ reason: 'validated optional semantic code relation',
407
+ trust: 'derived',
408
+ },
304
409
  );
305
410
  }
306
411
  if (input.semanticCode.relations.length === 0) {
@@ -312,6 +417,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
312
417
  maxTokens,
313
418
  omitted,
314
419
  'semantic-entry',
420
+ selected,
421
+ {
422
+ kind: 'semantic-code',
423
+ id: 'code:' + location,
424
+ reason: 'validated optional semantic code entry point',
425
+ trust: 'derived',
426
+ },
315
427
  );
316
428
  }
317
429
  }
@@ -321,7 +433,12 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
321
433
  appendLine(lines, '', maxTokens, omitted, 'start-heading');
322
434
  appendLine(lines, 'Start here', maxTokens, omitted, 'start-heading');
323
435
  for (const source of input.startHere.slice(0, 5)) {
324
- appendLine(lines, '- ' + source, maxTokens, omitted, 'start-here');
436
+ appendLine(lines, '- ' + source, maxTokens, omitted, 'start-here', selected, {
437
+ kind: 'start-here',
438
+ id: 'path:' + source,
439
+ reason: 'task-lensed starting point',
440
+ trust: 'derived',
441
+ });
325
442
  }
326
443
  }
327
444
 
@@ -338,6 +455,14 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
338
455
  maxTokens,
339
456
  omitted,
340
457
  'reliable-memory',
458
+ selected,
459
+ {
460
+ kind: 'memory',
461
+ id: 'memory:' + memory.id,
462
+ reason: 'current code-bound memory',
463
+ freshness: freshnessForMemory(memory.status),
464
+ trust: 'historical',
465
+ },
341
466
  );
342
467
  }
343
468
  }
@@ -346,10 +471,27 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
346
471
  appendLine(lines, '', maxTokens, omitted, 'knowledge-heading');
347
472
  appendLine(lines, 'Project knowledge', maxTokens, omitted, 'knowledge-heading');
348
473
  for (const claim of input.claims.slice(0, 3)) {
349
- appendLine(lines, '- ' + claim.assertion + ' [' + claim.id + ']', maxTokens, omitted, 'claim');
474
+ appendLine(lines, '- ' + claim.assertion + ' [' + claim.id + ']', maxTokens, omitted, 'claim', selected, {
475
+ kind: 'claim',
476
+ id: 'claim:' + claim.id,
477
+ reason: 'source-qualified task match',
478
+ trust: 'source-backed',
479
+ });
350
480
  }
351
481
  for (const page of input.pages.slice(0, 2)) {
352
- appendLine(lines, '- page: ' + page.relativePath, maxTokens, omitted, 'knowledge-page');
482
+ const supportsDeliveredClaim = page.claimIds.some(claimId => selected.some(item => (
483
+ item.kind === 'claim' && item.id === 'claim:' + claimId
484
+ )));
485
+ if (!supportsDeliveredClaim) {
486
+ omitted.push('knowledge-page-dependency');
487
+ continue;
488
+ }
489
+ appendLine(lines, '- page: ' + page.relativePath, maxTokens, omitted, 'knowledge-page', selected, {
490
+ kind: 'knowledge-page',
491
+ id: 'page:' + page.id,
492
+ reason: 'approved page linked to a selected claim',
493
+ trust: 'source-backed',
494
+ });
353
495
  }
354
496
  }
355
497
 
@@ -363,6 +505,13 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
363
505
  maxTokens,
364
506
  omitted,
365
507
  'workflow',
508
+ selected,
509
+ {
510
+ kind: 'workflow',
511
+ id: 'workflow:' + workflow.id,
512
+ reason: 'task-matching project workflow',
513
+ trust: 'source-backed',
514
+ },
366
515
  );
367
516
  }
368
517
  }
@@ -371,7 +520,11 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
371
520
  appendLine(lines, '', maxTokens, omitted, 'verification-heading');
372
521
  appendLine(lines, 'Verify', maxTokens, omitted, 'verification-heading');
373
522
  for (const check of input.verification.slice(0, 4)) {
374
- appendLine(lines, '- ' + short(check, 20), maxTokens, omitted, 'verification');
523
+ appendLine(lines, '- ' + short(check, 20), maxTokens, omitted, 'verification', selected, {
524
+ kind: 'verification',
525
+ reason: 'task-lensed verification guidance',
526
+ trust: 'derived',
527
+ });
375
528
  }
376
529
  }
377
530
 
@@ -379,6 +532,8 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
379
532
  prompt: lines.join('\n'),
380
533
  tokenCount: countTextTokens(lines.join('\n')),
381
534
  omitted: unique(omitted),
535
+ omittedItems: omitted,
536
+ selected,
382
537
  };
383
538
  }
384
539
 
@@ -388,6 +543,7 @@ export function renderTaskWorksetPrompt(input: Omit<TaskWorkset, 'prompt' | 'bud
388
543
  * context response.
389
544
  */
390
545
  export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<TaskWorkset> {
546
+ const startedAt = Date.now();
391
547
  const task = input.task?.trim() ?? '';
392
548
  const maxTokens = Math.max(96, Math.min(Math.floor(input.maxTokens ?? 180), 320));
393
549
  const cautions = [...(input.runtimeCautions ?? []), ...snapshotCautions(input)];
@@ -503,6 +659,18 @@ export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<Ta
503
659
  ...base,
504
660
  budget: { maxTokens },
505
661
  });
662
+ const receipt: ContextReceipt = {
663
+ version: '1.2.2',
664
+ target: input.deliveryTarget ?? 'project-context',
665
+ elapsedMs: Math.max(0, Date.now() - startedAt),
666
+ budget: {
667
+ maxTokens,
668
+ tokenCount: rendered.tokenCount,
669
+ },
670
+ selected: rendered.selected,
671
+ omitted: receiptOmissions(rendered.omittedItems, base.hiddenCautionMemoryCount),
672
+ scheduledActions: scheduledActions(normalizedCautions),
673
+ };
506
674
  return {
507
675
  ...base,
508
676
  budget: {
@@ -510,6 +678,7 @@ export async function buildTaskWorkset(input: BuildTaskWorksetInput): Promise<Ta
510
678
  tokenCount: rendered.tokenCount,
511
679
  omitted: rendered.omitted,
512
680
  },
681
+ receipt,
513
682
  prompt: rendered.prompt,
514
683
  };
515
684
  }