carrick 0.3.82 → 0.3.84

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 (88) hide show
  1. package/README.md +62 -30
  2. package/bin/carrick.mjs +45 -2
  3. package/dist/contract.d.ts +17 -0
  4. package/dist/contract.js.map +1 -1
  5. package/dist/hook/apply-patch.d.ts +13 -0
  6. package/dist/hook/apply-patch.js +100 -0
  7. package/dist/hook/apply-patch.js.map +1 -0
  8. package/dist/hook/post-edit.d.ts +30 -1
  9. package/dist/hook/post-edit.js +95 -24
  10. package/dist/hook/post-edit.js.map +1 -1
  11. package/dist/hook/reuse.d.ts +97 -0
  12. package/dist/hook/reuse.js +245 -0
  13. package/dist/hook/reuse.js.map +1 -0
  14. package/dist/hook/stop.d.ts +3 -0
  15. package/dist/hook/stop.js +76 -0
  16. package/dist/hook/stop.js.map +1 -0
  17. package/dist/hook/user-prompt.d.ts +9 -0
  18. package/dist/hook/user-prompt.js +79 -0
  19. package/dist/hook/user-prompt.js.map +1 -0
  20. package/dist/init/codex.d.ts +51 -0
  21. package/dist/init/codex.js +167 -0
  22. package/dist/init/codex.js.map +1 -0
  23. package/dist/init/connect.d.ts +13 -0
  24. package/dist/init/connect.js +21 -15
  25. package/dist/init/connect.js.map +1 -1
  26. package/dist/init/doctor.d.ts +57 -0
  27. package/dist/init/doctor.js +132 -3
  28. package/dist/init/doctor.js.map +1 -1
  29. package/dist/init/files.d.ts +15 -0
  30. package/dist/init/files.js +20 -1
  31. package/dist/init/files.js.map +1 -1
  32. package/dist/init/hosted.d.ts +30 -5
  33. package/dist/init/hosted.js +75 -9
  34. package/dist/init/hosted.js.map +1 -1
  35. package/dist/init/mcp.d.ts +45 -30
  36. package/dist/init/mcp.js +47 -88
  37. package/dist/init/mcp.js.map +1 -1
  38. package/dist/init/outdated.d.ts +54 -0
  39. package/dist/init/outdated.js +175 -0
  40. package/dist/init/outdated.js.map +1 -0
  41. package/dist/init/output.d.ts +72 -3
  42. package/dist/init/output.js +187 -23
  43. package/dist/init/output.js.map +1 -1
  44. package/dist/init/projects.d.ts +27 -13
  45. package/dist/init/projects.js +48 -50
  46. package/dist/init/projects.js.map +1 -1
  47. package/dist/init/remove.d.ts +0 -2
  48. package/dist/init/remove.js +61 -15
  49. package/dist/init/remove.js.map +1 -1
  50. package/dist/init/repos.d.ts +34 -0
  51. package/dist/init/repos.js +77 -0
  52. package/dist/init/repos.js.map +1 -1
  53. package/dist/init/run.d.ts +148 -26
  54. package/dist/init/run.js +577 -125
  55. package/dist/init/run.js.map +1 -1
  56. package/dist/init/settings.d.ts +20 -0
  57. package/dist/init/settings.js +42 -4
  58. package/dist/init/settings.js.map +1 -1
  59. package/dist/init/task-skills.d.ts +27 -0
  60. package/dist/init/task-skills.js +64 -1
  61. package/dist/init/task-skills.js.map +1 -1
  62. package/dist/init/workspace-file.d.ts +73 -0
  63. package/dist/init/workspace-file.js +173 -0
  64. package/dist/init/workspace-file.js.map +1 -0
  65. package/dist/render.d.ts +16 -0
  66. package/dist/render.js +57 -6
  67. package/dist/render.js.map +1 -1
  68. package/package.json +7 -6
  69. package/plugin/hooks/hooks.json +11 -0
  70. package/sidecar/dist/src/capture/api.d.ts +23 -1
  71. package/sidecar/dist/src/capture/check-classify.d.ts +10 -1
  72. package/sidecar/dist/src/capture/check-classify.js +96 -9
  73. package/sidecar/dist/src/capture/check-deep.d.ts +16 -4
  74. package/sidecar/dist/src/capture/check-deep.js +21 -17
  75. package/sidecar/dist/src/capture/check-fields.d.ts +112 -0
  76. package/sidecar/dist/src/capture/check-fields.js +311 -0
  77. package/sidecar/dist/src/capture/check-probe.d.ts +21 -1
  78. package/sidecar/dist/src/capture/check-probe.js +39 -0
  79. package/sidecar/dist/src/capture/check.js +14 -2
  80. package/sidecar/dist/src/capture/index.js +6 -1
  81. package/sidecar/dist/src/capture/self-check.d.ts +6 -1
  82. package/sidecar/dist/src/capture/self-check.js +65 -11
  83. package/sidecar/dist/src/validators.d.ts +40 -40
  84. package/sidecar/dist/src/validators.js +6 -1
  85. package/templates/skills/carrick-census.md +18 -9
  86. package/templates/skills/carrick-drift.md +7 -1
  87. package/templates/skills/carrick-impact.md +3 -1
  88. package/templates/skills/carrick-reuse.md +43 -26
@@ -24,7 +24,8 @@ import { classifyPair, parseTscOutput, } from './check-classify.js';
24
24
  import { scrubPaths } from './check-scrub.js';
25
25
  import { assembleWorkspace, writeProbes, } from './check-workspace.js';
26
26
  import { buildPoisonIndexes } from './check-poison.js';
27
- import { probeDeepFindings } from './check-deep.js';
27
+ import { openProbeProgram, probeDeepFindings } from './check-deep.js';
28
+ import { pairFieldReports } from './check-fields.js';
28
29
  function runProcess(command, args, cwd) {
29
30
  return new Promise((resolve, reject) => {
30
31
  const child = spawn(command, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
@@ -82,6 +83,9 @@ function unverifiableAll(plans, gate, diagnostic) {
82
83
  codes: [],
83
84
  resolved: false,
84
85
  unresolved_reason: diagnostic,
86
+ // Nothing was compared here, so there is nothing to observe about the
87
+ // comparison (carrick#1341). Empty is the honest answer, not a default.
88
+ notes: [],
85
89
  }));
86
90
  }
87
91
  function sortVerdicts(verdicts) {
@@ -141,6 +145,7 @@ export async function runCheck(opts, onProgress) {
141
145
  codes: [],
142
146
  resolved: false,
143
147
  unresolved_reason: 'one side of this pair has no captured type surface',
148
+ notes: [],
144
149
  });
145
150
  }
146
151
  }
@@ -185,6 +190,7 @@ export async function runCheck(opts, onProgress) {
185
190
  unresolved_reason: hit.kind === 'budget_exhausted'
186
191
  ? `the ${hit.side} type is too deep or wide to verify at '${hit.path}'`
187
192
  : `the ${hit.side} type carries '${hit.kind}' at '${hit.path}'`,
193
+ notes: [],
188
194
  });
189
195
  }
190
196
  writeProbes(ws, probing);
@@ -279,7 +285,12 @@ export async function runCheck(opts, onProgress) {
279
285
  // carries a member-level any/unknown HERE — after install, where the capture
280
286
  // could not look (carrick#450). It sets `resolved` and nothing else; no
281
287
  // bucket depends on it.
282
- const deepByPair = probeDeepFindings(ws.probesDir, probing);
288
+ const probeProgram = openProbeProgram(ws.probesDir, probing);
289
+ const deepByPair = probeDeepFindings(probeProgram, probing);
290
+ // The same program answers which FIELDS differ on a pair the judge called
291
+ // incompatible (carrick-tools/carrick-cloud#1118). It names what the verdict
292
+ // is about; it never decides one.
293
+ const fieldsByPair = pairFieldReports(probeProgram, probing);
283
294
  const verdicts = sortVerdicts([
284
295
  ...probing.map((plan) => classifyPair({
285
296
  plan,
@@ -287,6 +298,7 @@ export async function runCheck(opts, onProgress) {
287
298
  poisonReason,
288
299
  scrubCtx,
289
300
  deepFindings: deepByPair.get(plan.pairId),
301
+ fieldReport: fieldsByPair.get(plan.pairId),
290
302
  })),
291
303
  ...preGated,
292
304
  ...unresolved,
@@ -95,7 +95,12 @@ function emptyFidelity() {
95
95
  total_aliases: 0,
96
96
  by_serialization: { emitted: 0, node_builder: 0, structural_fallback: 0 },
97
97
  by_self_check: { ok: 0, allowlisted_external: 0, decayed_internal: 0 },
98
- by_anchor_origin: { 'llm-symbol': 0, 'deterministic-infer': 0, 'anchor-backfill': 0 },
98
+ by_anchor_origin: {
99
+ 'llm-symbol': 0,
100
+ 'deterministic-infer': 0,
101
+ 'anchor-backfill': 0,
102
+ 'manifest-placeholder': 0,
103
+ },
99
104
  usable_rate: 0,
100
105
  };
101
106
  }
@@ -22,7 +22,12 @@
22
22
  * Attribution is per-alias closure: failed specifiers are blamed on an alias
23
23
  * only if they occur in a file reachable from that alias's surface statement
24
24
  * (import-type seeds, then BFS over relative imports). The spike's
25
- * file-granularity shortcut is gone.
25
+ * file-granularity shortcut is gone -- including on the SURFACE file itself,
26
+ * which holds every alias, so a file-granular bucket there blamed the whole
27
+ * service for one alias's dangling specifier (cloud#1184). A surface
28
+ * diagnostic is attributed by `export type` statement span, exactly as
29
+ * check-poison.ts contains poison; one that no statement covers keeps the
30
+ * service-wide bucket.
26
31
  */
27
32
  import ts from 'typescript';
28
33
  import type { CaptureAliasRecord } from './api.js';
@@ -22,7 +22,12 @@
22
22
  * Attribution is per-alias closure: failed specifiers are blamed on an alias
23
23
  * only if they occur in a file reachable from that alias's surface statement
24
24
  * (import-type seeds, then BFS over relative imports). The spike's
25
- * file-granularity shortcut is gone.
25
+ * file-granularity shortcut is gone -- including on the SURFACE file itself,
26
+ * which holds every alias, so a file-granular bucket there blamed the whole
27
+ * service for one alias's dangling specifier (cloud#1184). A surface
28
+ * diagnostic is attributed by `export type` statement span, exactly as
29
+ * check-poison.ts contains poison; one that no statement covers keeps the
30
+ * service-wide bucket.
26
31
  */
27
32
  import ts from 'typescript';
28
33
  import * as fs from 'node:fs';
@@ -73,13 +78,26 @@ function runSelfCheck(args, treeFiles) {
73
78
  const program = ts.createProgram(treeFiles, options, args.compilerHost?.(options));
74
79
  const checker = program.getTypeChecker();
75
80
  const diagnostics = ts.getPreEmitDiagnostics(program);
76
- // Failed module specifiers, split external-pinned vs internal, per FILE.
81
+ const surfaceAbs = path.resolve(args.surfaceAbsPath);
82
+ const surfaceSource = program.getSourceFile(surfaceAbs);
83
+ // The surface holds EVERY alias, and every alias's closure starts there, so
84
+ // a file-granular failure bucket on it blames the whole service for one
85
+ // alias's dangling specifier (cloud#1184). Attribute by `export type`
86
+ // statement span, exactly as check-poison.ts contains poison.
87
+ const aliasAtSurfacePosition = buildSurfaceSpanIndex(surfaceSource);
88
+ // Failed module specifiers, split external-pinned vs internal, per FILE —
89
+ // except on the surface, where they are per ALIAS.
77
90
  const failuresByFile = new Map();
78
- const failuresFor = (fileName) => {
79
- let entry = failuresByFile.get(fileName);
91
+ const surfaceFailuresByAlias = new Map();
92
+ const emptyFailures = () => ({
93
+ externalPinned: new Set(),
94
+ internal: new Set(),
95
+ });
96
+ const bucketIn = (map, key) => {
97
+ let entry = map.get(key);
80
98
  if (!entry) {
81
- entry = { externalPinned: new Set(), internal: new Set() };
82
- failuresByFile.set(fileName, entry);
99
+ entry = emptyFailures();
100
+ map.set(key, entry);
83
101
  }
84
102
  return entry;
85
103
  };
@@ -91,7 +109,15 @@ function runSelfCheck(args, treeFiles) {
91
109
  if (!m)
92
110
  continue;
93
111
  const spec = m[1];
94
- const bucket = failuresFor(path.resolve(d.file.fileName));
112
+ const abs = path.resolve(d.file.fileName);
113
+ // A surface diagnostic outside every alias statement (a file-level import,
114
+ // a reference directive) is attributable to no alias and keeps the
115
+ // service-wide file bucket: soundness over precision, the same fallback
116
+ // check-poison.ts makes.
117
+ const owner = abs === surfaceAbs ? aliasAtSurfacePosition(d.start) : undefined;
118
+ const bucket = owner
119
+ ? bucketIn(surfaceFailuresByAlias, owner)
120
+ : bucketIn(failuresByFile, abs);
95
121
  if (!isRelative(spec) && args.pinned[packageNameOf(spec)]) {
96
122
  bucket.externalPinned.add(spec);
97
123
  }
@@ -113,8 +139,6 @@ function runSelfCheck(args, treeFiles) {
113
139
  }
114
140
  adjacency.set(abs, neighbors);
115
141
  }
116
- const surfaceAbs = path.resolve(args.surfaceAbsPath);
117
- const surfaceSource = program.getSourceFile(surfaceAbs);
118
142
  const records = [];
119
143
  for (const anchor of args.resolved) {
120
144
  // Demotions (failureReason present) never reached the surface with a
@@ -131,10 +155,35 @@ function runSelfCheck(args, treeFiles) {
131
155
  surfaceSource,
132
156
  adjacency,
133
157
  failuresByFile,
158
+ surfaceFailuresByAlias,
134
159
  }));
135
160
  }
136
161
  return records;
137
162
  }
163
+ /**
164
+ * Position -> the alias whose `export type` statement span covers it, for
165
+ * diagnostics reported on the surface file. `undefined` when no alias
166
+ * statement covers the position, or when the surface is not in the program.
167
+ */
168
+ function buildSurfaceSpanIndex(surfaceSource) {
169
+ if (!surfaceSource)
170
+ return () => undefined;
171
+ const spans = [];
172
+ for (const stmt of surfaceSource.statements) {
173
+ if (!ts.isTypeAliasDeclaration(stmt))
174
+ continue;
175
+ spans.push({
176
+ alias: stmt.name.text,
177
+ start: stmt.getStart(surfaceSource),
178
+ end: stmt.getEnd(),
179
+ });
180
+ }
181
+ return (position) => {
182
+ if (position === undefined)
183
+ return undefined;
184
+ return spans.find((span) => position >= span.start && position <= span.end)?.alias;
185
+ };
186
+ }
138
187
  /** An alias that never reached a capture-native tier: the failure reason was
139
188
  * recorded at demotion time; the surface line is `unknown` by construction. */
140
189
  function demotedRecord(anchor) {
@@ -195,8 +244,13 @@ function checkedRecord(anchor, ctx) {
195
244
  let blamedExternal;
196
245
  let internalFailure;
197
246
  const danglingSpecifiers = new Set();
198
- for (const file of closure) {
199
- const failures = ctx.failuresByFile.get(file);
247
+ // This alias's own surface statement, then the closure's files. The surface
248
+ // file bucket now holds only the diagnostics no alias statement covers.
249
+ const closureFailures = [
250
+ ctx.surfaceFailuresByAlias.get(alias),
251
+ ...[...closure].map((file) => ctx.failuresByFile.get(file)),
252
+ ];
253
+ for (const failures of closureFailures) {
200
254
  if (!failures)
201
255
  continue;
202
256
  if (!blamedExternal)
@@ -346,45 +346,45 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
346
346
  alias: z.ZodString;
347
347
  symbol_name: z.ZodString;
348
348
  source_file: z.ZodString;
349
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
349
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
350
350
  array_depth: z.ZodOptional<z.ZodNumber>;
351
351
  }, "strip", z.ZodTypeAny, {
352
352
  kind: "symbol";
353
353
  alias: string;
354
354
  source_file: string;
355
355
  symbol_name: string;
356
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
356
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
357
357
  array_depth?: number | undefined;
358
358
  }, {
359
359
  kind: "symbol";
360
360
  alias: string;
361
361
  source_file: string;
362
362
  symbol_name: string;
363
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
363
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
364
364
  array_depth?: number | undefined;
365
365
  }>, z.ZodObject<{
366
366
  kind: z.ZodLiteral<"handler_return">;
367
367
  alias: z.ZodString;
368
368
  symbol_name: z.ZodString;
369
369
  source_file: z.ZodString;
370
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
370
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
371
371
  }, "strip", z.ZodTypeAny, {
372
372
  kind: "handler_return";
373
373
  alias: string;
374
374
  source_file: string;
375
375
  symbol_name: string;
376
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
376
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
377
377
  }, {
378
378
  kind: "handler_return";
379
379
  alias: string;
380
380
  source_file: string;
381
381
  symbol_name: string;
382
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
382
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
383
383
  }>, z.ZodObject<{
384
384
  kind: z.ZodLiteral<"infer">;
385
385
  alias: z.ZodString;
386
386
  source_file: z.ZodString;
387
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
387
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
388
388
  span_start: z.ZodOptional<z.ZodNumber>;
389
389
  span_end: z.ZodOptional<z.ZodNumber>;
390
390
  line_number: z.ZodOptional<z.ZodNumber>;
@@ -394,7 +394,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
394
394
  kind: "infer";
395
395
  alias: string;
396
396
  source_file: string;
397
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
397
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
398
398
  line_number?: number | undefined;
399
399
  span_start?: number | undefined;
400
400
  span_end?: number | undefined;
@@ -404,7 +404,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
404
404
  kind: "infer";
405
405
  alias: string;
406
406
  source_file: string;
407
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
407
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
408
408
  line_number?: number | undefined;
409
409
  span_start?: number | undefined;
410
410
  span_end?: number | undefined;
@@ -414,18 +414,18 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
414
414
  kind: z.ZodLiteral<"literal">;
415
415
  alias: z.ZodString;
416
416
  type_text: z.ZodString;
417
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
417
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
418
418
  source_file: z.ZodOptional<z.ZodString>;
419
419
  }, "strip", z.ZodTypeAny, {
420
420
  kind: "literal";
421
421
  alias: string;
422
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
422
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
423
423
  type_text: string;
424
424
  source_file?: string | undefined;
425
425
  }, {
426
426
  kind: "literal";
427
427
  alias: string;
428
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
428
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
429
429
  type_text: string;
430
430
  source_file?: string | undefined;
431
431
  }>]>, "many">;
@@ -441,19 +441,19 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
441
441
  alias: string;
442
442
  source_file: string;
443
443
  symbol_name: string;
444
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
444
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
445
445
  array_depth?: number | undefined;
446
446
  } | {
447
447
  kind: "handler_return";
448
448
  alias: string;
449
449
  source_file: string;
450
450
  symbol_name: string;
451
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
451
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
452
452
  } | {
453
453
  kind: "infer";
454
454
  alias: string;
455
455
  source_file: string;
456
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
456
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
457
457
  line_number?: number | undefined;
458
458
  span_start?: number | undefined;
459
459
  span_end?: number | undefined;
@@ -462,7 +462,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
462
462
  } | {
463
463
  kind: "literal";
464
464
  alias: string;
465
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
465
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
466
466
  type_text: string;
467
467
  source_file?: string | undefined;
468
468
  })[];
@@ -478,19 +478,19 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
478
478
  alias: string;
479
479
  source_file: string;
480
480
  symbol_name: string;
481
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
481
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
482
482
  array_depth?: number | undefined;
483
483
  } | {
484
484
  kind: "handler_return";
485
485
  alias: string;
486
486
  source_file: string;
487
487
  symbol_name: string;
488
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
488
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
489
489
  } | {
490
490
  kind: "infer";
491
491
  alias: string;
492
492
  source_file: string;
493
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
493
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
494
494
  line_number?: number | undefined;
495
495
  span_start?: number | undefined;
496
496
  span_end?: number | undefined;
@@ -499,7 +499,7 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
499
499
  } | {
500
500
  kind: "literal";
501
501
  alias: string;
502
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
502
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
503
503
  type_text: string;
504
504
  source_file?: string | undefined;
505
505
  })[];
@@ -1412,45 +1412,45 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1412
1412
  alias: z.ZodString;
1413
1413
  symbol_name: z.ZodString;
1414
1414
  source_file: z.ZodString;
1415
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
1415
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
1416
1416
  array_depth: z.ZodOptional<z.ZodNumber>;
1417
1417
  }, "strip", z.ZodTypeAny, {
1418
1418
  kind: "symbol";
1419
1419
  alias: string;
1420
1420
  source_file: string;
1421
1421
  symbol_name: string;
1422
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1422
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1423
1423
  array_depth?: number | undefined;
1424
1424
  }, {
1425
1425
  kind: "symbol";
1426
1426
  alias: string;
1427
1427
  source_file: string;
1428
1428
  symbol_name: string;
1429
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1429
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1430
1430
  array_depth?: number | undefined;
1431
1431
  }>, z.ZodObject<{
1432
1432
  kind: z.ZodLiteral<"handler_return">;
1433
1433
  alias: z.ZodString;
1434
1434
  symbol_name: z.ZodString;
1435
1435
  source_file: z.ZodString;
1436
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
1436
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
1437
1437
  }, "strip", z.ZodTypeAny, {
1438
1438
  kind: "handler_return";
1439
1439
  alias: string;
1440
1440
  source_file: string;
1441
1441
  symbol_name: string;
1442
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1442
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1443
1443
  }, {
1444
1444
  kind: "handler_return";
1445
1445
  alias: string;
1446
1446
  source_file: string;
1447
1447
  symbol_name: string;
1448
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1448
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1449
1449
  }>, z.ZodObject<{
1450
1450
  kind: z.ZodLiteral<"infer">;
1451
1451
  alias: z.ZodString;
1452
1452
  source_file: z.ZodString;
1453
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
1453
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
1454
1454
  span_start: z.ZodOptional<z.ZodNumber>;
1455
1455
  span_end: z.ZodOptional<z.ZodNumber>;
1456
1456
  line_number: z.ZodOptional<z.ZodNumber>;
@@ -1460,7 +1460,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1460
1460
  kind: "infer";
1461
1461
  alias: string;
1462
1462
  source_file: string;
1463
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1463
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1464
1464
  line_number?: number | undefined;
1465
1465
  span_start?: number | undefined;
1466
1466
  span_end?: number | undefined;
@@ -1470,7 +1470,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1470
1470
  kind: "infer";
1471
1471
  alias: string;
1472
1472
  source_file: string;
1473
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1473
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1474
1474
  line_number?: number | undefined;
1475
1475
  span_start?: number | undefined;
1476
1476
  span_end?: number | undefined;
@@ -1480,18 +1480,18 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1480
1480
  kind: z.ZodLiteral<"literal">;
1481
1481
  alias: z.ZodString;
1482
1482
  type_text: z.ZodString;
1483
- anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill"]>;
1483
+ anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
1484
1484
  source_file: z.ZodOptional<z.ZodString>;
1485
1485
  }, "strip", z.ZodTypeAny, {
1486
1486
  kind: "literal";
1487
1487
  alias: string;
1488
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1488
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1489
1489
  type_text: string;
1490
1490
  source_file?: string | undefined;
1491
1491
  }, {
1492
1492
  kind: "literal";
1493
1493
  alias: string;
1494
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1494
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1495
1495
  type_text: string;
1496
1496
  source_file?: string | undefined;
1497
1497
  }>]>, "many">;
@@ -1507,19 +1507,19 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1507
1507
  alias: string;
1508
1508
  source_file: string;
1509
1509
  symbol_name: string;
1510
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1510
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1511
1511
  array_depth?: number | undefined;
1512
1512
  } | {
1513
1513
  kind: "handler_return";
1514
1514
  alias: string;
1515
1515
  source_file: string;
1516
1516
  symbol_name: string;
1517
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1517
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1518
1518
  } | {
1519
1519
  kind: "infer";
1520
1520
  alias: string;
1521
1521
  source_file: string;
1522
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1522
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1523
1523
  line_number?: number | undefined;
1524
1524
  span_start?: number | undefined;
1525
1525
  span_end?: number | undefined;
@@ -1528,7 +1528,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1528
1528
  } | {
1529
1529
  kind: "literal";
1530
1530
  alias: string;
1531
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1531
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1532
1532
  type_text: string;
1533
1533
  source_file?: string | undefined;
1534
1534
  })[];
@@ -1544,19 +1544,19 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1544
1544
  alias: string;
1545
1545
  source_file: string;
1546
1546
  symbol_name: string;
1547
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1547
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1548
1548
  array_depth?: number | undefined;
1549
1549
  } | {
1550
1550
  kind: "handler_return";
1551
1551
  alias: string;
1552
1552
  source_file: string;
1553
1553
  symbol_name: string;
1554
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1554
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1555
1555
  } | {
1556
1556
  kind: "infer";
1557
1557
  alias: string;
1558
1558
  source_file: string;
1559
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1559
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1560
1560
  line_number?: number | undefined;
1561
1561
  span_start?: number | undefined;
1562
1562
  span_end?: number | undefined;
@@ -1565,7 +1565,7 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
1565
1565
  } | {
1566
1566
  kind: "literal";
1567
1567
  alias: string;
1568
- anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill";
1568
+ anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
1569
1569
  type_text: string;
1570
1570
  source_file?: string | undefined;
1571
1571
  })[];
@@ -186,7 +186,12 @@ export const EmitSurfaceRequestSchema = BaseRequestSchema.extend({
186
186
  output_path: z.string().min(1, 'Output path cannot be empty'),
187
187
  });
188
188
  /** v2 "tsc as serializer" capture (contract in ./capture/api.ts). */
189
- const AnchorOriginSchema = z.enum(['llm-symbol', 'deterministic-infer', 'anchor-backfill']);
189
+ const AnchorOriginSchema = z.enum([
190
+ 'llm-symbol',
191
+ 'deterministic-infer',
192
+ 'anchor-backfill',
193
+ 'manifest-placeholder',
194
+ ]);
190
195
  const CaptureAnchorRequestSchema = z.discriminatedUnion('kind', [
191
196
  z.object({
192
197
  kind: z.literal('symbol'),
@@ -12,31 +12,37 @@ does.
12
12
 
13
13
  ## 1. Two wordings
14
14
 
15
- Search twice. One query says what the code is for, the other says how it does
15
+ Ask in two wordings. One says what the code is for, the other says how it does
16
16
  it. A purpose wording misses a helper whose description names only its
17
17
  mechanism, and a mechanism wording misses one described only by its job.
18
18
 
19
19
  ```
20
- search_by_intent({{SCOPE}}, query: "<what it is for>", compact: true, top_k: 20)
21
- search_by_intent({{SCOPE}}, query: "<how it does it>", compact: true, top_k: 20)
20
+ search_by_intent({{SCOPE}}, query: "<what it is for>", also_phrased_as: ["<how it does it>"], compact: true, top_k: 20)
22
21
  ```
23
22
 
24
23
  `compact: true` returns locator-only rows, which is the shape a census needs.
25
- Page each query while `has_more` is true:
24
+ One answer holds both wordings, deduped, with `phrasings` naming them and
25
+ `matched_phrasings` on each row saying which ones reached it. Page it while
26
+ `has_more` is true:
26
27
 
27
28
  ```
28
- search_by_intent({{SCOPE}}, query: "<the same query>", compact: true, top_k: 20, offset: <next_offset>)
29
+ search_by_intent({{SCOPE}}, query: "<the same query>", also_phrased_as: ["<the same second wording>"], compact: true, top_k: 20, offset: <next_offset>)
29
30
  ```
30
31
 
32
+ Where the answer carries no `phrasings`, or the field comes back refused, the
33
+ server answering takes one wording per call. Run the second wording as its own
34
+ paged search.
35
+
31
36
  Stop when `has_more` is false. Lower `similarity_threshold` where the tail of a
32
37
  page is still on topic.
33
38
 
34
39
  ## 2. Union
35
40
 
36
- Join the two result sets on `file_path` and `line_number`. A row both wordings
37
- found is one row. Keep `retrieved_by` and `similarity` on each row, and keep
38
- which wording found it: a row only one wording reached is the row a single
39
- search would have lost.
41
+ One answer over both wordings is already deduped, and `matched_phrasings` says
42
+ which wordings reached each row. Two answers are joined here, on `file_path` and
43
+ `line_number`, and a row both wordings found is one row. Either way keep
44
+ `retrieved_by` and `similarity`, and keep which wording found each row. A row
45
+ only one wording reached is the row a single search would have lost.
40
46
 
41
47
  ## 3. Receipt
42
48
 
@@ -44,6 +50,9 @@ Report these numbers before the list, per query where the field is per query:
44
50
 
45
51
  - rows read, which is the count you paged to;
46
52
  - `total_candidates`, the exact size of the ranked list for that query;
53
+ - `hidden_by_threshold` where the answer carries it: how many rows the floor
54
+ removed, and `best` where it names the closest of them. A count above zero is
55
+ the case for one more search at a lower `similarity_threshold`;
47
56
  - `total_without_intent`, which is index-wide: functions carrying no intent
48
57
  text, which no search looked at;
49
58
  - `total_intent_carried_forward` where the response states it, which are intents
@@ -74,7 +74,13 @@ against a `string` on the other is not a difference.
74
74
  | POST /api/orders | UNRESOLVED | NewOrder | OrderDraft | web/src/orders.ts:52 | unresolved; type texts differ on `note` |
75
75
 
76
76
  Class words, and only these: MATCH, DRIFT, UNRESOLVED, NOT JUDGED, CONSUMER
77
- UNTYPED, PRODUCER UNTYPED. A reading of the two type texts goes in the verdict
77
+ UNTYPED, PRODUCER UNTYPED. Every operation the answer returned carries one of
78
+ them, the class column is never empty, and the report states operations returned
79
+ against operations classed. Where more than one word fits an operation, the row
80
+ takes the first that applies of DRIFT, PRODUCER UNTYPED, CONSUMER UNTYPED,
81
+ UNRESOLVED, NOT JUDGED, MATCH, because a stored incompatible verdict is the
82
+ finding and a side carrying no type is why nothing past it could be judged.
83
+ A reading of the two type texts goes in the verdict
78
84
  column beside the stored state, in the words "type texts differ", so nothing in
79
85
  the table reads as a verdict the index did not give you.
80
86
 
@@ -83,7 +83,9 @@ One table, then the detail.
83
83
  | admin-ui | src/api/orders.ts:44 | INCOMPATIBLE | fact |
84
84
 
85
85
  Verdict words, and only these: COMPATIBLE, INCOMPATIBLE, UNRESOLVED,
86
- NOT COMPARED. In the same message, state:
86
+ NOT COMPARED. Every consumer call site the answers returned carries one of them
87
+ and the verdict column is never empty, and the report states call sites returned
88
+ against call sites given a verdict. In the same message, state:
87
89
 
88
90
  - the producers, with file and line;
89
91
  - unmatched calls and near misses, listed apart from consumers;