@clien-ai/mcp 0.3.0 → 0.4.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.
@@ -0,0 +1,531 @@
1
+ /**
2
+ * The `get_report` TRUST DIGEST (FUL-243) — renders the report's machine-checked
3
+ * trust spine into the tool result's TEXT.
4
+ *
5
+ * WHY THIS EXISTS. Every trust field this module renders was already returned by
6
+ * `get_report` — in `_meta.report_data`. But `_meta` is an OPTIONAL host channel:
7
+ * a host is not obliged to surface it to the model, and Claude Code does not. A
8
+ * wire capture against published `@clien-ai/mcp@0.3.0` showed the JSON-RPC
9
+ * `result` carrying both `_meta` and `content`, and the calling agent receiving
10
+ * only `content` — so in the ~58KB of markdown an agent actually reads, `RCP-`
11
+ * appeared 0 times, `RRCP-` 0 times, `identityPriors` 0 times, `qaFlagged` 0
12
+ * times. We had typed the whole Trust Engine and then delivered it down a channel
13
+ * the reader never sees.
14
+ *
15
+ * So the rule this module implements: ANY FACT AN AGENT MUST ACT ON HAS TO APPEAR
16
+ * IN THE RENDERED TEXT. Text works on every host, today, with no capability
17
+ * negotiation. `structuredContent` (the sanctioned machine-readable channel, added
18
+ * alongside this in the same change) is the richer path where supported, and
19
+ * `_meta` stays as-is for back-compat — but neither is allowed to be the ONLY
20
+ * place a trust signal lives.
21
+ *
22
+ * DEGRADATION PROPERTY (copied deliberately from `list_competitors`). Every line
23
+ * here is written so that a missing, absent, or unrecognised value makes an agent
24
+ * UNDER-trust the report rather than over-trust it:
25
+ * - No trust data at all → an explicit "treat every figure above as unverified"
26
+ * banner, not silence. Silence reads as "nothing to worry about".
27
+ * - A spine that is absent → said out loud ("not present on this run"), because
28
+ * an absent claim registry is NOT the same as a clean one.
29
+ * - A `state` we do not recognise → rendered verbatim and counted as
30
+ * un-grounded, never coerced into GROUNDED.
31
+ * - A capped list → the cap is STATED with the dropped count (no silent
32
+ * truncation, which reads as "that was all of them").
33
+ *
34
+ * READS DEFENSIVELY, ON PURPOSE. `getReport` passes the RAW payload through when
35
+ * `ResearchReportDataSchema` rejects it (never drop report data on backend drift),
36
+ * so this module is the one consumer guaranteed to sometimes meet a shape Zod
37
+ * refused. Hence the local `asArray` / `asRecord` / `str` / `num` accessors rather
38
+ * than typed field access: a reshaped field must degrade to "not shown", never
39
+ * throw and lose the whole digest.
40
+ */
41
+ import { truncate } from './research.js';
42
+ /**
43
+ * Max claims rendered per spine. Above this the digest states how many were
44
+ * dropped and where the full list lives — never a silent cut. Sized so a typical
45
+ * run (~40 persona claims, ~15 report claims) renders COMPLETE; the cap is a
46
+ * runaway backstop, not a routine trim.
47
+ */
48
+ const CLAIM_RENDER_CAP = 40;
49
+ /** Max chars of claim text per line. Keeps a 40-claim spine to roughly 5KB. */
50
+ const CLAIM_TEXT_MAX = 140;
51
+ /** Max personas / hypotheses / disagreements listed before capping. */
52
+ const LIST_RENDER_CAP = 25;
53
+ // ---------------------------------------------------------------------------
54
+ // Defensive accessors — every one of these answers "or nothing" rather than throwing
55
+ // ---------------------------------------------------------------------------
56
+ function asRecord(value) {
57
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
58
+ ? value
59
+ : null;
60
+ }
61
+ function asArray(value) {
62
+ return Array.isArray(value) ? value : [];
63
+ }
64
+ function str(value) {
65
+ return typeof value === 'string' && value.length > 0 ? value : null;
66
+ }
67
+ function num(value) {
68
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
69
+ }
70
+ /**
71
+ * TRI-STATE boolean read: `true`, `false`, or `null` for "absent or unreadable".
72
+ *
73
+ * A plain `value === true` collapses the third case into `false`, and every flag
74
+ * this module reads is a WARNING flag — so a schema-drifted `qaFlagged: "true"`
75
+ * would render as "none QA-flagged" and a drifted `flipped: "true"` as "no
76
+ * verdict flipped". That is the exact inversion this module exists to prevent:
77
+ * unreadable must never present as clean. Callers distinguish the three cases and
78
+ * say "unknown" for `null`.
79
+ */
80
+ function tribool(value) {
81
+ return typeof value === 'boolean' ? value : null;
82
+ }
83
+ /** True only for a real `true`. Use where a `null` is handled separately. */
84
+ function bool(value) {
85
+ return tribool(value) === true;
86
+ }
87
+ /** True when a flag was present but not a boolean, or absent where required. */
88
+ function unreadable(value) {
89
+ return value !== undefined && typeof value !== 'boolean';
90
+ }
91
+ /** `count` + a correctly pluralised noun, e.g. `3 claims` / `1 claim`. */
92
+ function plural(count, noun, pluralNoun) {
93
+ return `${count} ${count === 1 ? noun : (pluralNoun ?? `${noun}s`)}`;
94
+ }
95
+ /**
96
+ * "(showing N of M — …)" tail, or '' when everything rendered.
97
+ *
98
+ * Always names WHERE the rest is, because a capped list with no pointer is
99
+ * indistinguishable from a complete one to a reader who cannot see the source.
100
+ */
101
+ function capNote(shown, total, channel, path) {
102
+ if (shown >= total)
103
+ return '';
104
+ return `\n_(showing ${shown} of ${total} — the remaining ${total - shown} are in \`${channel}.${path}\`)_`;
105
+ }
106
+ function tallyStates(claims) {
107
+ const tally = { grounded: 0, speculation: 0, noReceipt: 0, other: 0 };
108
+ for (const raw of claims) {
109
+ const state = str(asRecord(raw)?.state);
110
+ if (state === 'GROUNDED')
111
+ tally.grounded += 1;
112
+ else if (state === 'SPECULATION')
113
+ tally.speculation += 1;
114
+ else if (state === 'NO_RECEIPT')
115
+ tally.noReceipt += 1;
116
+ // An unrecognised (or missing) state counts as OTHER — deliberately not
117
+ // folded into any of the three known buckets, and never into `grounded`.
118
+ else
119
+ tally.other += 1;
120
+ }
121
+ return tally;
122
+ }
123
+ function tallyLine(tally, total) {
124
+ const parts = [
125
+ `${tally.grounded} GROUNDED`,
126
+ `${tally.speculation} SPECULATION`,
127
+ `${tally.noReceipt} NO_RECEIPT`,
128
+ ];
129
+ if (tally.other > 0) {
130
+ parts.push(`${tally.other} with an unrecognised state (treat as UNGROUNDED)`);
131
+ }
132
+ return `${plural(total, 'claim')}: ${parts.join(' · ')}`;
133
+ }
134
+ /**
135
+ * One persona-spine claim line: `[STATE] id ← RCP-… — "text"`.
136
+ *
137
+ * The receipt id is rendered INLINE rather than described, because the marker
138
+ * itself is what an agent pattern-matches on — a digest that says "this claim has
139
+ * a receipt" without printing `RCP-p0-s2` leaves the agent unable to follow it.
140
+ */
141
+ function renderPersonaClaim(raw) {
142
+ const claim = asRecord(raw);
143
+ if (!claim)
144
+ return '- (unreadable claim entry)';
145
+ const state = str(claim.state) ?? 'UNKNOWN_STATE';
146
+ const id = str(claim.id) ?? '(no id)';
147
+ const personaId = str(claim.personaId);
148
+ const sourceId = str(claim.sourceId);
149
+ const text = str(claim.text);
150
+ // Gated on `state`, not on `sourceId` presence — see `renderReportClaim` for
151
+ // why a pointer on a non-GROUNDED claim must never render as a receipt.
152
+ let receipt = '';
153
+ if (state === 'GROUNDED') {
154
+ receipt = sourceId ? ` ← ${sourceId}` : ' · GROUNDED but no receipt id — unresolvable';
155
+ }
156
+ else if (sourceId) {
157
+ receipt = ` (carries ${sourceId}, which does NOT grant grounding — state is ${state})`;
158
+ }
159
+ const who = personaId ? ` (${personaId})` : '';
160
+ const body = text ? ` — "${truncate(text, CLAIM_TEXT_MAX)}"` : '';
161
+ return `- [${state}] ${id}${who}${receipt}${body}`;
162
+ }
163
+ /**
164
+ * One report-spine claim line. Differs from the persona one in two ways that
165
+ * matter to a reader: it carries a `section` (market/competitor) instead of a
166
+ * persona, and a NO_RECEIPT claim has TWO distinct provenance readings that must
167
+ * be told apart — model-attested (a page was read and independently vouched, no
168
+ * exact span pinned) versus plain model knowledge (recalled, unverified).
169
+ *
170
+ * Neither reading is grounding. The attestation's `sourceId` is printed under an
171
+ * explicit `model-attested →` label rather than the bare `←` used for real
172
+ * receipts, so the two can never be skim-read as the same thing.
173
+ */
174
+ function renderReportClaim(raw) {
175
+ const claim = asRecord(raw);
176
+ if (!claim)
177
+ return '- (unreadable claim entry)';
178
+ const state = str(claim.state) ?? 'UNKNOWN_STATE';
179
+ const id = str(claim.id) ?? '(no id)';
180
+ const section = str(claim.section);
181
+ const sourceId = str(claim.sourceId);
182
+ const text = str(claim.text);
183
+ const attestation = asRecord(claim.attestation);
184
+ const attestedSourceId = str(attestation?.sourceId);
185
+ // The bare `←` arrow means RECEIPT, so it is gated on `state`, NOT on the mere
186
+ // presence of a `sourceId`. Keying on presence would render an explicitly
187
+ // unsupported claim with the same marker a span-verified one gets: the schema
188
+ // types `state` and `sourceId` independently and `.passthrough()`s unknown
189
+ // shapes, and `getReport` hands the RAW payload through when Zod rejects it, so
190
+ // `{ state: 'NO_RECEIPT', sourceId: 'RRCP-s0' }` genuinely reaches this code.
191
+ // An agent following that arrow would treat a NO_RECEIPT figure as source-checked.
192
+ let provenance = '';
193
+ if (state === 'GROUNDED') {
194
+ provenance = sourceId ? ` ← ${sourceId}` : ' · GROUNDED but no receipt id — unresolvable';
195
+ }
196
+ else if (state === 'NO_RECEIPT' && attestedSourceId) {
197
+ provenance = ` · model-attested → ${attestedSourceId} (NOT a receipt)`;
198
+ }
199
+ else if (state === 'NO_RECEIPT') {
200
+ provenance = ' · from model knowledge — unverified';
201
+ }
202
+ // A pointer on a non-grounded claim is shown but explicitly disarmed, so it is
203
+ // neither hidden from the reader nor readable as grounding.
204
+ if (state !== 'GROUNDED' && sourceId) {
205
+ provenance += ` (carries ${sourceId}, which does NOT grant grounding — state is ${state})`;
206
+ }
207
+ const where = section ? ` (${section})` : '';
208
+ const body = text ? ` — "${truncate(text, CLAIM_TEXT_MAX)}"` : '';
209
+ return `- [${state}] ${id}${where}${provenance}${body}`;
210
+ }
211
+ function renderPersonaSpine(reportData, channel) {
212
+ const claims = asArray(reportData.claims);
213
+ if (claims.length === 0) {
214
+ return ('### Persona claim spine — NOT PRESENT on this run\n' +
215
+ 'No persona claim registry was produced, so NOTHING in the persona/interview prose above ' +
216
+ 'has been machine-checked. Absent is not clean: treat those statements as unverified.');
217
+ }
218
+ const tally = tallyStates(claims);
219
+ const shown = claims.slice(0, CLAIM_RENDER_CAP);
220
+ const lines = shown.map(renderPersonaClaim);
221
+ return (`### Persona claim spine — ${tallyLine(tally, claims.length)}\n` +
222
+ 'A GROUNDED claim\'s receipt id (`RCP-p{i}-s{j}`) indexes `personas[i].sources[j]` — the cached ' +
223
+ 'forum post its quote span was code-verified against. NO_RECEIPT can mean a bad claim OR merely ' +
224
+ 'sparse evidence: check that persona\'s `insufficientEvidence` / `sourcesFound` below before ' +
225
+ 'discounting it. Anything not GROUNDED is unverified.\n' +
226
+ `${lines.join('\n')}` +
227
+ capNote(shown.length, claims.length, channel, 'report_data.claims'));
228
+ }
229
+ function renderReportSpine(reportData, channel) {
230
+ const claims = asArray(reportData.reportClaims);
231
+ if (claims.length === 0) {
232
+ return ('### Market/competitor claim spine — NOT PRESENT on this run\n' +
233
+ 'No market/competitor claim registry was produced, so no sizing figure, trend, or competitor ' +
234
+ 'fact in the prose above has been machine-checked. Treat every such figure as unverified.');
235
+ }
236
+ const tally = tallyStates(claims);
237
+ const attested = claims.filter((raw) => {
238
+ const claim = asRecord(raw);
239
+ return str(claim?.state) === 'NO_RECEIPT' && str(asRecord(claim?.attestation)?.sourceId) !== null;
240
+ }).length;
241
+ const attestedNote = attested > 0 ? ` (of which ${attested} model-attested)` : '';
242
+ const shown = claims.slice(0, CLAIM_RENDER_CAP);
243
+ const lines = shown.map(renderReportClaim);
244
+ return (`### Market/competitor claim spine — ${tallyLine(tally, claims.length)}${attestedNote}\n` +
245
+ 'A SEPARATE pool from the persona spine — the two never cross. A GROUNDED claim\'s `RRCP-s{n}` ' +
246
+ 'indexes `reportEvidence[n]`. A NO_RECEIPT claim marked `model-attested` means Claude read a ' +
247
+ 'supporting page an independent check vouched for, but no exact span was pinned — stronger than ' +
248
+ 'recall, still NOT a receipt. Unmarked NO_RECEIPT is recalled model knowledge, unverified. ' +
249
+ 'Key on the state, never on whether a source id is present.\n' +
250
+ `${lines.join('\n')}` +
251
+ capNote(shown.length, claims.length, channel, 'report_data.reportClaims'));
252
+ }
253
+ /**
254
+ * The two receipt POOLS, so an agent that reads `← RCP-p0-s2` in a claim line can
255
+ * resolve the pointer without the structured channel. Rendered compactly (index,
256
+ * platform, url) — the verbatim quotes stay in the structured payload.
257
+ */
258
+ function renderReceiptPools(reportData, channel) {
259
+ const personas = asArray(reportData.personas);
260
+ const reportEvidence = asArray(reportData.reportEvidence);
261
+ const personaReceipts = [];
262
+ personas.forEach((rawPersona, i) => {
263
+ const sources = asArray(asRecord(rawPersona)?.sources);
264
+ sources.forEach((rawSource, j) => {
265
+ const source = asRecord(rawSource);
266
+ const platform = str(source?.platform) ?? 'unknown platform';
267
+ const url = str(source?.url) ?? '(no url)';
268
+ personaReceipts.push(`- RCP-p${i}-s${j} — ${platform} — ${url}`);
269
+ });
270
+ });
271
+ const evidenceReceipts = reportEvidence.map((raw, n) => {
272
+ const source = asRecord(raw);
273
+ const section = str(source?.section) ?? 'unknown section';
274
+ const platform = str(source?.platform) ?? 'unknown platform';
275
+ const url = str(source?.url) ?? '(no url)';
276
+ // FUL-148: `publishedDate` is the figure's recency; `retrievedAt` is only when
277
+ // WE fetched it. Rendering retrievedAt as recency would be a lie, so an absent
278
+ // publication date is shown honestly as unknown rather than substituted.
279
+ const published = str(source?.publishedDate) ?? 'publish date unknown';
280
+ return `- RRCP-s${n} (${section}) — ${platform} — ${published} — ${url}`;
281
+ });
282
+ if (personaReceipts.length === 0 && evidenceReceipts.length === 0) {
283
+ return ('### Receipt pools — EMPTY\n' +
284
+ 'No cached sources were attached to this run, so no claim above can be followed to a source. ' +
285
+ 'Any receipt id referenced in the prose is unresolvable.');
286
+ }
287
+ const sections = ['### Receipt pools'];
288
+ if (personaReceipts.length > 0) {
289
+ const shown = personaReceipts.slice(0, CLAIM_RENDER_CAP);
290
+ sections.push(`**Persona receipts** (${plural(personaReceipts.length, 'cached forum post')}) — the target of an \`RCP-\` pointer:\n` +
291
+ shown.join('\n') +
292
+ capNote(shown.length, personaReceipts.length, channel, 'report_data.personas[].sources'));
293
+ }
294
+ if (evidenceReceipts.length > 0) {
295
+ const shown = evidenceReceipts.slice(0, CLAIM_RENDER_CAP);
296
+ sections.push(`**Market/competitor evidence** (${plural(evidenceReceipts.length, 'cached page')}) — the target of an \`RRCP-\` pointer:\n` +
297
+ shown.join('\n') +
298
+ capNote(shown.length, evidenceReceipts.length, channel, 'report_data.reportEvidence'));
299
+ }
300
+ return sections.join('\n\n');
301
+ }
302
+ /**
303
+ * Per-persona QA + identity grounding.
304
+ *
305
+ * `qaFlagged` is rendered as a LOUD leading warning rather than a trailing field:
306
+ * a flagged persona either failed a quality check or could not be checked at all
307
+ * (FUL-132 fail-safe), and an agent about to interview or quote it needs that
308
+ * before it reads the persona's name, not after.
309
+ *
310
+ * `identityPriors` and `identityProvenance` are labelled as NOT receipts, because
311
+ * they sit next to real receipts and the failure mode is an agent citing
312
+ * "calibrated against N real ICP profiles" as if it were a source.
313
+ */
314
+ function renderPersonas(reportData, channel) {
315
+ const personas = asArray(reportData.personas);
316
+ if (personas.length === 0) {
317
+ return '### Personas — none carried on this run';
318
+ }
319
+ const shown = personas.slice(0, LIST_RENDER_CAP);
320
+ const lines = shown.map((raw, i) => {
321
+ const persona = asRecord(raw);
322
+ const name = str(persona?.name) ?? `persona-${i}`;
323
+ const role = str(persona?.role);
324
+ const sources = asArray(persona?.sources);
325
+ const flagged = bool(persona?.qaFlagged);
326
+ const reasons = asArray(persona?.qaFlagReasons)
327
+ .map((r) => str(r))
328
+ .filter((r) => r !== null);
329
+ const insufficient = bool(persona?.insufficientEvidence);
330
+ const sourcesFound = num(persona?.sourcesFound);
331
+ const priors = asRecord(persona?.identityPriors);
332
+ const seniority = str(priors?.seniority);
333
+ const careerPath = str(priors?.careerPath);
334
+ const provenance = str(persona?.identityProvenance);
335
+ const bits = [];
336
+ bits.push(`${plural(sources.length, 'receipt')}`);
337
+ if (insufficient) {
338
+ bits.push(`⚠️ insufficientEvidence${sourcesFound !== null ? ` (only ${sourcesFound} real posts found)` : ''}`);
339
+ }
340
+ else if (sourcesFound !== null) {
341
+ bits.push(`sourcesFound: ${sourcesFound}`);
342
+ }
343
+ // identityPriors are TYPED ENRICHMENT, not evidence — the label says so on
344
+ // the same line so the two can't be conflated at a glance.
345
+ if (seniority)
346
+ bits.push(`identityPriors.seniority: ${seniority}`);
347
+ if (careerPath)
348
+ bits.push(`identityPriors.careerPath: ${careerPath}`);
349
+ // A flag we cannot READ is reported as unknown, never as "not flagged" — an
350
+ // unreadable quality signal is a reason for less confidence, not more.
351
+ const flag = flagged
352
+ ? `⚠️ QA-FLAGGED${reasons.length > 0 ? ` (${reasons.join('; ')})` : ' (no reason recorded)'} — do not rely on this persona's claims. `
353
+ : unreadable(persona?.qaFlagged)
354
+ ? '⚠️ qaFlagged UNREADABLE (malformed value) — treat this persona as unchecked. '
355
+ : '';
356
+ const provenanceLine = provenance
357
+ ? `\n identityProvenance: "${truncate(provenance, 200)}" — aggregate calibration, NEVER a receipt; do not cite it as a source.`
358
+ : '';
359
+ return `- **${name}**${role ? ` (${role})` : ''} — ${flag}${bits.join(' · ')}${provenanceLine}`;
360
+ });
361
+ const flaggedCount = personas.filter((p) => bool(asRecord(p)?.qaFlagged)).length;
362
+ // "none QA-flagged" is a CLEAN BILL, so it is only claimed when every persona's
363
+ // flag was actually readable. One malformed value makes the aggregate unknown —
364
+ // otherwise drifted data would render as a passed quality check.
365
+ const unreadableCount = personas.filter((p) => unreadable(asRecord(p)?.qaFlagged)).length;
366
+ const header = flaggedCount > 0
367
+ ? `### Personas — ${personas.length}, ⚠️ ${flaggedCount} QA-FLAGGED`
368
+ : unreadableCount > 0
369
+ ? `### Personas — ${personas.length}, ⚠️ QA status UNREADABLE for ${unreadableCount} (not a clean result)`
370
+ : `### Personas — ${personas.length}, none QA-flagged`;
371
+ return (`${header}\n${lines.join('\n')}` +
372
+ capNote(shown.length, personas.length, channel, 'report_data.personas'));
373
+ }
374
+ /**
375
+ * The anti-sycophancy readout — deterministically computed from the interviews,
376
+ * not model-opined, which is exactly why it belongs in the text: it is the one
377
+ * signal that says whether the personas actually pushed back or just agreed.
378
+ */
379
+ function renderSycophancy(reportData, channel) {
380
+ const signals = asRecord(reportData.sycophancySignals);
381
+ if (!signals) {
382
+ return ('### Anti-sycophancy — NOT COMPUTED on this run\n' +
383
+ 'No broken-persona / rejection readout was produced. You cannot tell from this report whether ' +
384
+ 'the personas genuinely disagreed with the idea or simply agreed with everything.');
385
+ }
386
+ const totalRejections = num(signals.totalRejections);
387
+ const lowDiscriminationCount = num(signals.lowDiscriminationCount) ?? 0;
388
+ const personaSignals = asArray(signals.personaSignals);
389
+ const disagreements = asArray(signals.disagreements);
390
+ const lines = [];
391
+ // A healthy run has ≥1 explicit rejection; zero is itself the warning.
392
+ if (totalRejections !== null) {
393
+ lines.push(totalRejections === 0
394
+ ? '⚠️ 0 explicit rejections across all personas — nobody said no to anything. A run with no ' +
395
+ 'rejections is the classic sycophancy signature; discount the supportive findings above.'
396
+ : `${plural(totalRejections, 'explicit rejection')} across all personas.`);
397
+ }
398
+ if (lowDiscriminationCount > 0) {
399
+ const names = personaSignals
400
+ .filter((raw) => bool(asRecord(raw)?.lowDiscrimination))
401
+ .map((raw) => str(asRecord(raw)?.personaName) ?? '(unnamed)');
402
+ lines.push(`⚠️ ${lowDiscriminationCount} persona(s) flagged \`lowDiscrimination\` (uniformly supportive AND ` +
403
+ `rejected nothing — their answers carry little signal): ${names.join(', ')}`);
404
+ }
405
+ if (disagreements.length > 0) {
406
+ const shown = disagreements.slice(0, LIST_RENDER_CAP);
407
+ lines.push(`Hypotheses the personas SPLIT on (disagreement is signal, not noise):\n` +
408
+ shown
409
+ .map((raw) => {
410
+ const d = asRecord(raw);
411
+ const id = str(d?.hypothesisId) ?? '(no id)';
412
+ const supportive = asArray(d?.supportive).length;
413
+ const negative = asArray(d?.negative).length;
414
+ const neutral = asArray(d?.neutral).length;
415
+ return ` - ${id}: ${supportive} supportive / ${neutral} neutral / ${negative} pushed back`;
416
+ })
417
+ .join('\n') +
418
+ capNote(shown.length, disagreements.length, channel, 'report_data.sycophancySignals.disagreements'));
419
+ }
420
+ if (lines.length === 0) {
421
+ lines.push('Readout present but empty — treat the supportive findings above as unchecked.');
422
+ }
423
+ return `### Anti-sycophancy\n${lines.join('\n')}`;
424
+ }
425
+ /**
426
+ * Hypothesis verdict robustness.
427
+ *
428
+ * The load-bearing case is `flipped`: when a verdict changed under rephrasing the
429
+ * report's top-level `status` is NOT the verdict to act on — `downgradedStatus`
430
+ * is. That inversion is precisely the kind of thing an agent gets wrong when it
431
+ * reads only the prose, so it is stated per-hypothesis rather than as a footnote.
432
+ */
433
+ function renderRobustness(reportData, channel) {
434
+ const results = asArray(reportData.hypothesisResults);
435
+ if (results.length === 0)
436
+ return '';
437
+ const withRobustness = results.filter((raw) => asRecord(asRecord(raw)?.robustness) !== null);
438
+ if (withRobustness.length === 0) {
439
+ return ('### Hypothesis robustness — NOT RE-TESTED on this run\n' +
440
+ 'No verdict was re-asked under a reworded framing, so no verdict above carries a survival ' +
441
+ 'count. Treat each as a single-shot answer.');
442
+ }
443
+ const shown = withRobustness.slice(0, LIST_RENDER_CAP);
444
+ const lines = shown.map((raw) => {
445
+ const result = asRecord(raw);
446
+ const id = str(result?.hypothesisId) ?? '(no id)';
447
+ const status = str(result?.status) ?? 'unknown';
448
+ const robustness = asRecord(result?.robustness);
449
+ const survived = num(robustness?.survived);
450
+ const total = num(robustness?.total);
451
+ const flipped = tribool(robustness?.flipped);
452
+ const downgraded = str(robustness?.downgradedStatus);
453
+ const count = survived !== null && total !== null ? `held ${survived}/${total} framings` : 'survival count unavailable';
454
+ if (flipped === true) {
455
+ return (`- ${id}: reported \`${status}\` — ⚠️ FLIPPED under rephrasing (${count}). ` +
456
+ `The verdict to act on is \`${downgraded ?? 'weaker than reported — downgrade unavailable'}\`, NOT \`${status}\`.`);
457
+ }
458
+ // An unreadable `flipped` is NOT "held" — say so rather than printing the
459
+ // verdict as if it had survived re-asking.
460
+ if (flipped === null) {
461
+ return `- ${id}: reported \`${status}\` — ⚠️ flip status UNREADABLE (${count}); treat this verdict as un-retested.`;
462
+ }
463
+ return `- ${id}: \`${status}\` — ${count}`;
464
+ });
465
+ const flippedCount = withRobustness.filter((raw) => bool(asRecord(asRecord(raw)?.robustness)?.flipped)).length;
466
+ const unreadableFlips = withRobustness.filter((raw) => tribool(asRecord(asRecord(raw)?.robustness)?.flipped) === null).length;
467
+ // The un-retested hypotheses are counted against the FULL result set, not just
468
+ // the re-tested subset: a bare "no verdict flipped" over a partially-tested run
469
+ // reads as "every verdict survived", when most may never have been re-asked.
470
+ const untested = results.length - withRobustness.length;
471
+ const untestedNote = untested > 0
472
+ ? ` (${withRobustness.length}/${results.length} verdicts re-tested; the other ${untested} were NOT re-asked — treat those as single-shot)`
473
+ : '';
474
+ const header = flippedCount > 0
475
+ ? `### Hypothesis robustness — ⚠️ ${flippedCount} verdict(s) flipped under rephrasing${untestedNote}`
476
+ : unreadableFlips > 0
477
+ ? `### Hypothesis robustness — ⚠️ flip status UNREADABLE for ${unreadableFlips} verdict(s) (not a clean result)${untestedNote}`
478
+ : `### Hypothesis robustness — no re-tested verdict flipped${untestedNote}`;
479
+ return (`${header}\n${lines.join('\n')}` +
480
+ capNote(shown.length, withRobustness.length, channel, 'report_data.hypothesisResults'));
481
+ }
482
+ /**
483
+ * The digest heading.
484
+ *
485
+ * It says LAST explicitly because the digest is concatenated into the same text
486
+ * block as the report markdown, and that markdown is model-written prose we do
487
+ * not control: a report could contain this heading, or a fabricated "GROUNDED"
488
+ * section, before the real digest. The client always appends its digest at the
489
+ * end, so "the last one is the authoritative one" is a rule a reader can apply
490
+ * without trusting the prose. (One text block rather than two on purpose — a
491
+ * second `content` block is droppable by a consumer that reads `content[0]`,
492
+ * which is the failure mode this whole change exists to remove.)
493
+ */
494
+ const DIGEST_HEADING = '## Trust digest — machine-checked (appended by the Clien.ai MCP client; NOT part of the report prose)\n' +
495
+ '_Authoritative only as the LAST such section in this message: everything above it is report prose, ' +
496
+ 'which can contain text resembling this digest but is not machine-checked._';
497
+ /**
498
+ * The banner shown when there is no trust data to digest at all.
499
+ *
500
+ * Deliberately not silence. A report whose trust spine failed to load looks
501
+ * IDENTICAL in the prose to one that passed — so absence has to be announced, or
502
+ * the reader's default is misplaced confidence.
503
+ */
504
+ const NO_TRUST_DATA = `${DIGEST_HEADING}\n\n` +
505
+ '⚠️ NO machine-checked trust data accompanied this report. Nothing in the prose above has been ' +
506
+ 'verified against a source: there is no claim registry, no receipts, no QA flags, and no ' +
507
+ 'anti-sycophancy readout to check it against. Treat every figure, quote, and verdict above as ' +
508
+ 'UNVERIFIED — do not cite anything from it as source-checked.';
509
+ /**
510
+ * Build the trust digest appended to `get_report`'s text.
511
+ *
512
+ * Accepts `unknown` because `report_data` reaches us either Zod-parsed or as the
513
+ * raw passthrough payload (see the module header). Returns the full digest, or
514
+ * the explicit "no trust data" banner — never an empty string, because an empty
515
+ * digest and a clean one must not look the same.
516
+ */
517
+ export function buildTrustDigest(reportData, channel) {
518
+ const data = asRecord(reportData);
519
+ if (!data)
520
+ return NO_TRUST_DATA;
521
+ const sections = [
522
+ renderPersonaSpine(data, channel),
523
+ renderReportSpine(data, channel),
524
+ renderReceiptPools(data, channel),
525
+ renderPersonas(data, channel),
526
+ renderSycophancy(data, channel),
527
+ renderRobustness(data, channel),
528
+ ].filter((section) => section.length > 0);
529
+ return `${DIGEST_HEADING}\n\n${sections.join('\n\n')}`;
530
+ }
531
+ //# sourceMappingURL=report-digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-digest.js","sourceRoot":"","sources":["../../src/tools/report-digest.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@
28
28
  */
29
29
  import { z } from 'zod';
30
30
  import { ResearchReportDataSchema } from '../types/report.js';
31
+ import { buildTrustDigest } from './report-digest.js';
31
32
  import { ToolError } from './errors.js';
32
33
  import { apiCall, categorizeFetchError, truncate, webJobUrl, } from './research.js';
33
34
  const REPORTS_FETCH_TIMEOUT_MS = 30_000;
@@ -198,8 +199,17 @@ export async function getReport(input, deps) {
198
199
  console.error('[clien-mcp] get_report: report_data failed schema validation; passing through raw payload:', parsedReport.error.issues[0]);
199
200
  }
200
201
  }
202
+ // FUL-243: the trust spine is appended to the TEXT, not left to `_meta`.
203
+ // `_meta` is an optional host channel — Claude Code drops it — so a report
204
+ // whose claims, receipts, QA flags and sycophancy signals live only there
205
+ // reaches the agent as unannotated prose. `buildTrustDigest` reads the same
206
+ // payload defensively (it also handles the raw passthrough above) and always
207
+ // returns something: when there is no trust data it says so loudly, because a
208
+ // silently-missing digest is indistinguishable from a clean one.
201
209
  return {
202
- content: [{ type: 'text', text: json.reportMarkdown }],
210
+ content: [
211
+ { type: 'text', text: `${json.reportMarkdown}\n\n---\n\n${buildTrustDigest(reportData, 'structuredContent')}` },
212
+ ],
203
213
  _meta: {
204
214
  job_id: jobId,
205
215
  status: json.status ?? 'complete',
@@ -1 +1 @@
1
- {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/tools/reports.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/tools/reports.ts"],"names":[],"mappings":"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"}