@iowarp/clio-coder 0.3.3 → 0.3.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 (244) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +3 -3
  4. package/dist/{acp-P2AQILE2.js → acp-S5R4RR5B.js} +7 -6
  5. package/dist/{agents-72W3BI7I.js → agents-P6DMMVZY.js} +24 -21
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5TWEIYDN.js → auth-2XCZLPKS.js} +12 -8
  8. package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
  9. package/dist/{chunk-2DJ2KNFG.js → chunk-2LZI5CAG.js} +133 -13
  10. package/dist/{chunk-OAO4GE4M.js → chunk-2TZWSW76.js} +2 -2
  11. package/dist/{chunk-OOJYHWRB.js → chunk-34475P3I.js} +2 -2
  12. package/dist/{chunk-4XUGQOHA.js → chunk-35MKKU5R.js} +4 -4
  13. package/dist/{chunk-LM5TQCJZ.js → chunk-3HZ5RWN2.js} +5 -5
  14. package/dist/{chunk-AGYYIBLL.js → chunk-3JLKSKD7.js} +2 -2
  15. package/dist/{chunk-KZWTDYJF.js → chunk-4JUF2NNX.js} +7 -7
  16. package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
  17. package/dist/chunk-5M54SPOL.js +926 -0
  18. package/dist/{chunk-STBPMHSX.js → chunk-7RXG6QRZ.js} +51 -11
  19. package/dist/{chunk-X6IAEBZR.js → chunk-A2GZF7DC.js} +5 -5
  20. package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
  21. package/dist/chunk-AOCYTWAV.js +449 -0
  22. package/dist/chunk-BEY543CS.js +258 -0
  23. package/dist/{chunk-6N5PTWMY.js → chunk-BP4OYD6A.js} +32 -13
  24. package/dist/chunk-BPGS2WCQ.js +612 -0
  25. package/dist/{chunk-V6RTAOC2.js → chunk-BRXQQJFP.js} +8 -8
  26. package/dist/chunk-CFGTUFWB.js +67 -0
  27. package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
  28. package/dist/{chunk-DUYJ5IO6.js → chunk-EDRHSCIE.js} +4 -4
  29. package/dist/{chunk-XBXAASKX.js → chunk-EFADSJET.js} +2 -2
  30. package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
  31. package/dist/chunk-FYYLNIL5.js +313 -0
  32. package/dist/{chunk-FNTMWMX5.js → chunk-HV5X7OR2.js} +14 -12
  33. package/dist/{chunk-TZTZS7QK.js → chunk-HXG4IURW.js} +5 -3
  34. package/dist/{chunk-5UFT4SUX.js → chunk-K6WL7QZT.js} +3 -3
  35. package/dist/chunk-K7VKOLQQ.js +15 -0
  36. package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
  37. package/dist/{chunk-OC7FIQPC.js → chunk-KRPY7NTG.js} +10 -7
  38. package/dist/chunk-LL4KHSZI.js +22 -0
  39. package/dist/{chunk-DSELYM6W.js → chunk-MEQ45TQ4.js} +15 -9
  40. package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
  41. package/dist/{chunk-6SGHMWE3.js → chunk-N4CZJQRK.js} +5 -5
  42. package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
  43. package/dist/chunk-OZNBF4L3.js +23 -0
  44. package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
  45. package/dist/chunk-QQK64KLB.js +1360 -0
  46. package/dist/{chunk-SRDMMSEP.js → chunk-QQL5RT5M.js} +979 -1619
  47. package/dist/{chunk-LZSJBIVT.js → chunk-QWU7ZBO7.js} +70 -720
  48. package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
  49. package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
  50. package/dist/{chunk-OQ33BKR3.js → chunk-TTNYS3EA.js} +3 -60
  51. package/dist/chunk-TW3WDMVS.js +677 -0
  52. package/dist/chunk-TZSKNMZG.js +434 -0
  53. package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
  54. package/dist/{chunk-PIWWS5BL.js → chunk-UZHIZC5S.js} +7 -7
  55. package/dist/{chunk-UFIIWP2H.js → chunk-VAWWTKDP.js} +8 -8
  56. package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
  57. package/dist/{chunk-LW6DSM3M.js → chunk-VMNQ6OZA.js} +98 -202
  58. package/dist/chunk-VSNATDE6.js +122 -0
  59. package/dist/chunk-W6GROXXM.js +69 -0
  60. package/dist/chunk-WPQLXFOZ.js +375 -0
  61. package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
  62. package/dist/{chunk-PAJK6MAQ.js → chunk-X6COSD2O.js} +5 -5
  63. package/dist/chunk-ZGVHUX3M.js +66 -0
  64. package/dist/{chunk-LWLEKMDQ.js → chunk-ZYKPLLNQ.js} +510 -547
  65. package/dist/cli/index.js +27 -23
  66. package/dist/{clio-JOU4FXVA.js → clio-J5JIOIDS.js} +7 -6
  67. package/dist/{code-nav-7AX6FYE6.js → code-nav-AXCXSBHX.js} +5 -3
  68. package/dist/{config-XCDVKR23.js → config-OEBMIN2U.js} +37 -27
  69. package/dist/{configure-4GAP54ZW.js → configure-PUQOSIXQ.js} +16 -13
  70. package/dist/{context-5VKGUVJJ.js → context-EKDCKUUZ.js} +82 -7
  71. package/dist/{context-4UOGGLQ5.js → context-MGSE4Z2T.js} +33 -23
  72. package/dist/{context-77FM5DV5.js → context-URSXPBCK.js} +17 -9
  73. package/dist/{context-clear-XXJRLCJJ.js → context-clear-KDAJRNUK.js} +33 -23
  74. package/dist/context-working-set-SBKMPPI2.js +1552 -0
  75. package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-MSWN72NK.js} +43 -29
  76. package/dist/{doctor-HR46URBJ.js → doctor-7BSE27PJ.js} +10 -10
  77. package/dist/{eval-XSSNATB4.js → eval-IZGDOO4H.js} +9 -8
  78. package/dist/{evidence-6HG2PY2B.js → evidence-SR7WXB5B.js} +51 -23
  79. package/dist/{evolve-K7YU3NCY.js → evolve-K7VE2CBX.js} +30 -20
  80. package/dist/{fleet-VY3HHKN6.js → fleet-7XMJNQNF.js} +48 -38
  81. package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-AQNAH644.js} +3 -3
  82. package/dist/{init-JYGXI3FK.js → init-JGNPAYXT.js} +41 -31
  83. package/dist/{memory-WFZMGYHX.js → memory-4ALKDJ4Q.js} +32 -22
  84. package/dist/{models-I5QWSEOM.js → models-ZMMLFJNN.js} +22 -19
  85. package/dist/{monitor-GE4ID3IA.js → monitor-2F3T5KHP.js} +55 -43
  86. package/dist/{orchestrator-EM5MC3HM.js → orchestrator-ORHT43JB.js} +572 -388
  87. package/dist/{reset-L2FQEE3E.js → reset-NXGTYNUO.js} +4 -3
  88. package/dist/{run-ZU3QMZPZ.js → run-RF4WJGMT.js} +51 -41
  89. package/dist/{share-S5BZQC5I.js → share-UT3W6E4M.js} +5 -4
  90. package/dist/{skills-X5VXCRNQ.js → skills-PSACKC5Q.js} +2 -2
  91. package/dist/{skills-eval-WKIHWTHR.js → skills-eval-WJSI55RZ.js} +34 -24
  92. package/dist/{targets-SNCPI2NR.js → targets-PIIRAOYS.js} +23 -20
  93. package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-ULWXWNVY.js} +4 -3
  94. package/dist/{upgrade-JQHHPQ4K.js → upgrade-346TZ6AV.js} +18 -17
  95. package/dist/{usage-OR4O5SMZ.js → usage-6KKXR32N.js} +34 -24
  96. package/dist/verifiers-4UUM6TEE.js +1214 -0
  97. package/dist/verify-X5HDROLA.js +25 -0
  98. package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-7STOCIFZ.js} +42 -31
  99. package/dist/worker/entry.js +33 -24
  100. package/docs/README.md +7 -6
  101. package/docs/acp.md +1 -1
  102. package/docs/alcf-provider.md +1 -1
  103. package/docs/architecture.md +2 -2
  104. package/docs/artifact-versions.md +1 -1
  105. package/docs/built-in-agents.md +1 -1
  106. package/docs/capacity-and-scheduling.md +1 -1
  107. package/docs/commands-and-modes.md +53 -21
  108. package/docs/config-knobs-audit.md +1 -2
  109. package/docs/configuration-and-targets.md +15 -1
  110. package/docs/context-engine.md +64 -12
  111. package/docs/context-working-set.md +194 -0
  112. package/docs/development-pipeline.md +1 -1
  113. package/docs/documentation-coverage.md +5 -5
  114. package/docs/documentation-guide.md +6 -5
  115. package/docs/environment-variables.md +2 -1
  116. package/docs/eval-runner.md +1 -1
  117. package/docs/evals-internal.md +14 -1
  118. package/docs/evidence-and-memory.md +74 -2
  119. package/docs/evolution.md +1 -1
  120. package/docs/exit-codes-and-output.md +1 -1
  121. package/docs/extensions-and-sharing.md +2 -2
  122. package/docs/fleet-dispatch.md +22 -7
  123. package/docs/glossary.md +21 -1
  124. package/docs/installation-and-lifecycle.md +2 -2
  125. package/docs/middleware-and-components.md +1 -1
  126. package/docs/model-catalog.md +7 -9
  127. package/docs/observability.md +4 -4
  128. package/docs/proactive-memory.md +1 -1
  129. package/docs/prompt-envelope-and-tools.md +4 -4
  130. package/docs/provider-adapter-cookbook.md +1 -1
  131. package/docs/release-cut-checklist.md +31 -31
  132. package/docs/safety-model.md +23 -4
  133. package/docs/scientific-validation.md +21 -3
  134. package/docs/session-lifecycle.md +3 -3
  135. package/docs/skills-marketplace.md +1 -1
  136. package/docs/tool-usage.md +79 -12
  137. package/docs/trace-store.md +1 -1
  138. package/docs/troubleshooting.md +1 -1
  139. package/docs/tui-design.md +1 -1
  140. package/docs/worker-dispatch-mechanics.md +11 -1
  141. package/package.json +8 -11
  142. package/skills/meta/clio-test/SKILL.md +20 -17
  143. package/skills/meta/clio-test/evals.md +3 -3
  144. package/skills/meta/clio-test/references/harness.md +35 -6
  145. package/skills/meta/clio-test/references/test-map.md +20 -10
  146. package/skills/registry.yaml +2 -2
  147. package/skills/skill-marketplace.json +1 -1
  148. package/src/cli/context-working-set.ts +513 -0
  149. package/src/cli/context.ts +8 -0
  150. package/src/cli/evidence.ts +20 -2
  151. package/src/cli/index.ts +4 -0
  152. package/src/cli/verifiers.ts +325 -0
  153. package/src/core/bash-exec.ts +39 -14
  154. package/src/core/bus-events.ts +19 -4
  155. package/src/core/config.ts +54 -0
  156. package/src/core/defaults.ts +50 -3
  157. package/src/core/verification-scripts.ts +6 -0
  158. package/src/domains/agents/builtins/verifier.md +3 -0
  159. package/src/domains/config/classify.ts +1 -0
  160. package/src/domains/context/working-set/contract.ts +161 -0
  161. package/src/domains/context/working-set/defaults.ts +28 -0
  162. package/src/domains/context/working-set/engine.ts +203 -0
  163. package/src/domains/context/working-set/fold.ts +62 -0
  164. package/src/domains/context/working-set/horizon.ts +38 -0
  165. package/src/domains/context/working-set/marker.ts +103 -0
  166. package/src/domains/context/working-set/path-index.ts +436 -0
  167. package/src/domains/context/working-set/payload.ts +152 -0
  168. package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
  169. package/src/domains/context/working-set/policies/index.ts +21 -0
  170. package/src/domains/context/working-set/policies/structural.ts +160 -0
  171. package/src/domains/context/working-set/project.ts +132 -0
  172. package/src/domains/context/working-set/protect.ts +109 -0
  173. package/src/domains/context/working-set/recall.ts +177 -0
  174. package/src/domains/context/working-set/replay/controls.ts +112 -0
  175. package/src/domains/context/working-set/replay/load-clio.ts +199 -0
  176. package/src/domains/context/working-set/replay/metrics.ts +185 -0
  177. package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
  178. package/src/domains/context/working-set/replay/report.ts +139 -0
  179. package/src/domains/context/working-set/replay/runner.ts +325 -0
  180. package/src/domains/context/working-set/replay/synthetic.ts +422 -0
  181. package/src/domains/context/working-set/replay/trace.ts +21 -0
  182. package/src/domains/context/working-set/visible.ts +54 -0
  183. package/src/domains/evidence/build.ts +112 -45
  184. package/src/domains/evidence/eval.ts +24 -7
  185. package/src/domains/evidence/index.ts +53 -0
  186. package/src/domains/evidence/ordering.ts +12 -0
  187. package/src/domains/evidence/run-trust.ts +221 -0
  188. package/src/domains/evidence/store.ts +46 -6
  189. package/src/domains/evidence/trust-status.ts +854 -0
  190. package/src/domains/evidence/types.ts +26 -0
  191. package/src/domains/middleware/memory-intervention.ts +3 -0
  192. package/src/domains/middleware/stalled-turn.ts +165 -4
  193. package/src/domains/safety/autonomy.ts +1 -1
  194. package/src/domains/safety/default-path-policy.ts +8 -0
  195. package/src/domains/safety/finish-contract.ts +4 -3
  196. package/src/domains/safety/policy-engine.ts +48 -6
  197. package/src/domains/session/compaction/compact.ts +23 -1
  198. package/src/domains/session/compaction/cut-point.ts +2 -0
  199. package/src/domains/session/compaction/tokens.ts +16 -1
  200. package/src/domains/session/context-ledger.ts +2 -0
  201. package/src/domains/session/entries.ts +107 -1
  202. package/src/domains/session/manager.ts +9 -2
  203. package/src/domains/session/migrations/index.ts +22 -3
  204. package/src/engine/acp/server.ts +3 -0
  205. package/src/engine/agent.ts +18 -1
  206. package/src/engine/session.ts +9 -3
  207. package/src/entry/orchestrator.ts +16 -4
  208. package/src/interactive/chat-loop-messages.ts +18 -6
  209. package/src/interactive/chat-panel.ts +17 -1
  210. package/src/interactive/chat-renderer.ts +30 -21
  211. package/src/interactive/context-meter.ts +10 -0
  212. package/src/interactive/context-overlay.ts +81 -6
  213. package/src/interactive/context-recall-command.ts +110 -0
  214. package/src/interactive/interactive-slash-runtime.ts +37 -1
  215. package/src/interactive/model-session-replay.ts +21 -0
  216. package/src/interactive/overlay-general-openers.ts +6 -0
  217. package/src/interactive/overlay-session-lifecycle.ts +8 -4
  218. package/src/interactive/renderers/tool-execution.ts +18 -2
  219. package/src/interactive/session-transcript.ts +2 -2
  220. package/src/interactive/slash-commands.ts +29 -2
  221. package/src/interactive/turn-context.ts +238 -88
  222. package/src/interactive/turn-middleware.ts +6 -6
  223. package/src/tools/agent-tools.ts +11 -4
  224. package/src/tools/bash.ts +144 -82
  225. package/src/tools/builtin-tool-catalog.ts +11 -5
  226. package/src/tools/context/index.ts +105 -3
  227. package/src/tools/context/surface.ts +3 -2
  228. package/src/tools/core-bootstrap.ts +21 -0
  229. package/src/tools/dispatch-runner.ts +9 -7
  230. package/src/tools/monitor.ts +28 -20
  231. package/src/tools/registry.ts +59 -7
  232. package/src/tools/result-disposition.ts +550 -0
  233. package/src/tools/result-shaping.ts +262 -19
  234. package/src/tools/safe-exec.ts +2 -0
  235. package/src/tools/verify/authoring.ts +1119 -0
  236. package/src/tools/verify/catalog.ts +346 -0
  237. package/src/tools/verify/index.ts +13 -3
  238. package/src/tools/verify/scripts.ts +135 -37
  239. package/src/tools/verify/surface.ts +9 -5
  240. package/src/tools/worker-evidence.ts +35 -12
  241. package/dist/chunk-J7CWMCQD.js +0 -255
  242. package/dist/chunk-T6YILFSB.js +0 -80
  243. package/dist/chunk-VAKQQHWR.js +0 -434
  244. package/dist/chunk-VPAYEGVX.js +0 -184
@@ -1,7 +1,7 @@
1
1
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { rawDurationMs } from "../../core/timers.js";
4
- import { isVerificationScriptName } from "../../core/verification-scripts.js";
4
+ import { isProjectVerifierCheckId, isVerificationScriptName } from "../../core/verification-scripts.js";
5
5
  import type {
6
6
  RunEnvelope,
7
7
  RunKind,
@@ -10,12 +10,7 @@ import type {
10
10
  RunStatus,
11
11
  ToolCallStat,
12
12
  } from "../dispatch/index.js";
13
- import {
14
- type ExecutionRole,
15
- isExecutionRole,
16
- readGateDecisionArtifactsForRunIds,
17
- verifyReceiptIntegrity,
18
- } from "../dispatch/index.js";
13
+ import { type ExecutionRole, isExecutionRole, readGateDecisionArtifactsForRunIds } from "../dispatch/index.js";
19
14
  import { detectValidationCommand } from "../safety/protected-artifacts.js";
20
15
  import {
21
16
  type AuditJsonRow,
@@ -29,9 +24,13 @@ import {
29
24
  type SessionEntry,
30
25
  } from "../session/index.js";
31
26
  import { attributeEvidenceFailure } from "./failure-attribution.js";
27
+ import { compareCodepoints as compareStrings } from "./ordering.js";
32
28
  import { extractRunProvenance, provenanceTranscriptLines } from "./provenance.js";
33
29
  import { createRedactionTally, redactSecretsDeep, redactSecretsText } from "./redact.js";
30
+ import { buildEvidenceTrustStatusFile } from "./run-trust.js";
34
31
  import { EVIDENCE_FILES, evidenceDirectory, findingsFile } from "./store.js";
32
+ import type { TrustArtifactReference } from "./trust-status.js";
33
+ import { inspectRunReceiptTrustStatus } from "./trust-status.js";
35
34
  import {
36
35
  EVIDENCE_VERSION,
37
36
  type EvidenceAuditLinkedRow,
@@ -48,6 +47,7 @@ import {
48
47
  type EvidenceRunSource,
49
48
  type EvidenceTag,
50
49
  type EvidenceToolEvent,
50
+ type EvidenceTrustStatusFile,
51
51
  } from "./types.js";
52
52
 
53
53
  const MAX_TASK_CHARS = 500;
@@ -153,7 +153,15 @@ export async function buildEvidence(options: BuildEvidenceOptions): Promise<Evid
153
153
  const auditLinks = await linkAuditRows(options.stateDir, source, runSources, sessionLinks);
154
154
  const toolEventRows = toolEvents(runSources, sessionLinks, auditLinks);
155
155
  const protectedArtifactsRaw = protectedArtifactsFile(sessionLinks);
156
- const findings = buildFindings(runSources, sessionLinks, auditLinks, protectedArtifactsRaw);
156
+ const validationEvidence = validationEvidenceByRun(sessionLinks.entries, runSources);
157
+ const trustStatusRaw = buildEvidenceTrustStatusFile({
158
+ evidenceId,
159
+ runSources,
160
+ gateDecisions: gateDecisions.decisions,
161
+ auditRows: auditLinks.rows,
162
+ validationEvidence,
163
+ });
164
+ const findings = buildFindings(runSources, trustStatusRaw, sessionLinks, auditLinks, protectedArtifactsRaw);
157
165
  // Export-boundary redaction (cold path): secret-shaped values are scrubbed
158
166
  // from everything the bundle serializes: envelopes, receipts (including
159
167
  // delegation toolCallLog arguments), tool-event previews, audit rows,
@@ -176,6 +184,7 @@ export async function buildEvidence(options: BuildEvidenceOptions): Promise<Evid
176
184
  readErrors: auditLinks.readErrors,
177
185
  };
178
186
  const protectedArtifacts = redactSecretsDeep(protectedArtifactsRaw, tally);
187
+ const trustStatus = redactSecretsDeep(trustStatusRaw, tally);
179
188
  const overview = buildOverview(
180
189
  evidenceId,
181
190
  source,
@@ -197,10 +206,11 @@ export async function buildEvidence(options: BuildEvidenceOptions): Promise<Evid
197
206
  redactedAuditLinks,
198
207
  redactedToolEvents,
199
208
  gateDecisions,
209
+ trustStatus,
200
210
  protectedArtifacts,
201
211
  transcript,
202
212
  );
203
- return { evidenceId, directory, overview: finalOverview, findings };
213
+ return { evidenceId, directory, overview: finalOverview, findings, trustStatus };
204
214
  }
205
215
 
206
216
  function buildOverview(
@@ -264,18 +274,24 @@ function buildOverview(
264
274
 
265
275
  function buildFindings(
266
276
  runSources: ReadonlyArray<EvidenceRunSource>,
277
+ trustStatus: EvidenceTrustStatusFile,
267
278
  sessionLinks: SessionLinkResult,
268
279
  auditLinks: AuditLinkResult,
269
280
  protectedArtifacts: EvidenceProtectedArtifactsFile,
270
281
  ): EvidenceFinding[] {
271
282
  const findings: EvidenceFinding[] = [];
272
- const validationRunIds = validationEvidenceRunIds(sessionLinks.entries, runSources, auditLinks.rows);
283
+ const trustByRun = new Map(trustStatus.runs.map((entry) => [entry.runId, entry.status]));
273
284
  for (const source of runSources) {
285
+ const status = trustByRun.get(source.envelope.id);
286
+ if (status === undefined) throw new Error(`canonical trust status missing for run ${source.envelope.id}`);
274
287
  if (source.receiptError !== null) {
275
288
  const tag = source.receiptIntegrityFailed ? "receipt-integrity" : "unknown";
276
289
  findings.push(finding(findings.length, "warn", tag, source.envelope.id, source.receiptError));
277
290
  }
278
- if (isSuccessfulRun(source) && !validationRunIds.has(source.envelope.id)) {
291
+ if (
292
+ isSuccessfulRun(source) &&
293
+ (status.validationGrounding.state === "absent" || status.validationGrounding.state === "unknown")
294
+ ) {
279
295
  findings.push(
280
296
  finding(
281
297
  findings.length,
@@ -286,10 +302,21 @@ function buildFindings(
286
302
  ),
287
303
  );
288
304
  }
305
+ if (status.validationGrounding.state === "ungrounded") {
306
+ findings.push(
307
+ finding(
308
+ findings.length,
309
+ "warn",
310
+ "proxy-validation",
311
+ source.envelope.id,
312
+ "run claimed validation that was not grounded in an observed execution",
313
+ ),
314
+ );
315
+ }
289
316
  if (source.envelope.cwd.trim().length === 0) {
290
317
  findings.push(finding(findings.length, "warn", "cwd-missing", source.envelope.id, "run ledger cwd is empty"));
291
318
  }
292
- const receipt = source.receipt;
319
+ const receipt = authenticatedReceipt(source);
293
320
  const blocked = receipt?.toolStats.reduce((total, stat) => total + stat.blocked, 0) ?? 0;
294
321
  if (blocked > 0) {
295
322
  findings.push(
@@ -311,15 +338,17 @@ function buildFindings(
311
338
  ),
312
339
  );
313
340
  }
314
- const autonomyEnforcement = receipt?.autonomyEnforcement;
315
- if (autonomyEnforcement?.dangerousBypass === true) {
341
+ if (status.autonomyEnforcement.state === "bypassed") {
316
342
  const message =
317
- autonomyEnforcement.externalMode === "agent-managed"
343
+ status.autonomyEnforcement.authority.id === "agent-managed"
318
344
  ? "run used external agent-managed governance; Clio safety blocks were not enforced"
319
345
  : "run executed with external permission bypass (CLIO_CODER_ALLOW_EXTERNAL_FULL_ACCESS=1); Clio safety blocks were not enforced";
320
346
  findings.push(finding(findings.length, "warn", "external-bypass", source.envelope.id, message));
321
- } else if (autonomyEnforcement?.grade === "approximated") {
322
- const mode = autonomyEnforcement.externalMode ? ` via ${autonomyEnforcement.externalMode}` : "";
347
+ } else if (status.autonomyEnforcement.state === "approximated") {
348
+ const mode =
349
+ status.autonomyEnforcement.authority.id === "external-runtime"
350
+ ? ""
351
+ : ` via ${status.autonomyEnforcement.authority.id}`;
323
352
  findings.push(
324
353
  finding(
325
354
  findings.length,
@@ -410,25 +439,28 @@ function buildFindings(
410
439
  interface ValidationToolCallCandidate {
411
440
  toolCallId: string;
412
441
  runId: string | null;
442
+ artifact: TrustArtifactReference;
413
443
  }
414
444
 
415
- function validationEvidenceRunIds(
445
+ function validationEvidenceByRun(
416
446
  entries: ReadonlyArray<LinkedSessionEntry>,
417
447
  runSources: ReadonlyArray<EvidenceRunSource>,
418
- auditRows: ReadonlyArray<EvidenceAuditLinkedRow>,
419
- ): Set<string> {
420
- const runIds = new Set<string>();
421
- const sourceRunIds = new Set(runSources.map((source) => source.envelope.id));
448
+ ): Map<string, TrustArtifactReference[]> {
449
+ const evidence = new Map<string, TrustArtifactReference[]>();
422
450
  const calls = new Map<string, ValidationToolCallCandidate>();
423
451
  for (const linked of entries) {
424
452
  const runId = validationRunIdFor(linked, runSources);
425
453
  const entry = linked.entry;
426
454
  if (entry.kind === "bashExecution") {
427
- if (runId !== null && isSuccessfulValidationBashExecution(entry)) runIds.add(runId);
455
+ if (runId !== null && isSuccessfulValidationBashExecution(entry)) {
456
+ addValidationEvidence(evidence, runId, { kind: "session_entry", id: entry.turnId });
457
+ }
428
458
  continue;
429
459
  }
430
460
  if (entry.kind === "protectedArtifact") {
431
- if (runId !== null && isValidationProtectedArtifact(entry)) runIds.add(runId);
461
+ if (runId !== null && isValidationProtectedArtifact(entry)) {
462
+ addValidationEvidence(evidence, runId, { kind: "session_entry", id: entry.turnId });
463
+ }
432
464
  continue;
433
465
  }
434
466
  if (entry.kind !== "message") continue;
@@ -441,16 +473,21 @@ function validationEvidenceRunIds(
441
473
  const result = extractSessionToolResult(entry, linked);
442
474
  if (result.id === null || !isSuccessfulSessionToolResult(result)) continue;
443
475
  const candidate = calls.get(result.id);
444
- if (candidate?.runId !== null && candidate?.runId !== undefined) runIds.add(candidate.runId);
445
- }
446
- for (const linked of auditRows) {
447
- if (linked.auditKind !== "completion_contract") continue;
448
- if (linked.runId === null || !sourceRunIds.has(linked.runId)) continue;
449
- if (readOptionalString(linked.row.decision) !== "ok") continue;
450
- if (readOptionalString(linked.row.reason) !== "validation_evidence") continue;
451
- runIds.add(linked.runId);
476
+ if (candidate?.runId !== null && candidate?.runId !== undefined) {
477
+ addValidationEvidence(evidence, candidate.runId, candidate.artifact);
478
+ }
452
479
  }
453
- return runIds;
480
+ return evidence;
481
+ }
482
+
483
+ function addValidationEvidence(
484
+ evidence: Map<string, TrustArtifactReference[]>,
485
+ runId: string,
486
+ reference: TrustArtifactReference,
487
+ ): void {
488
+ const current = evidence.get(runId) ?? [];
489
+ current.push(reference);
490
+ evidence.set(runId, current);
454
491
  }
455
492
 
456
493
  function validationRunIdFor(linked: LinkedSessionEntry, runSources: ReadonlyArray<EvidenceRunSource>): string | null {
@@ -463,12 +500,19 @@ function validationRunIdFor(linked: LinkedSessionEntry, runSources: ReadonlyArra
463
500
  }
464
501
 
465
502
  function isSuccessfulRun(source: EvidenceRunSource): boolean {
466
- const outcome = source.receipt?.outcome ?? source.envelope.outcome ?? null;
503
+ const receipt = authenticatedReceipt(source);
504
+ const outcome = receipt?.outcome ?? source.envelope.outcome ?? null;
467
505
  if (outcome !== null) return outcome === "succeeded";
468
- const exitCode = source.receipt?.exitCode ?? source.envelope.exitCode;
506
+ const exitCode = receipt?.exitCode ?? source.envelope.exitCode;
469
507
  return source.envelope.status === "completed" && exitCode === 0;
470
508
  }
471
509
 
510
+ function authenticatedReceipt(source: EvidenceRunSource): RunReceipt | null {
511
+ return source.receipt !== null && source.receiptError === null && !source.receiptIntegrityFailed
512
+ ? source.receipt
513
+ : null;
514
+ }
515
+
472
516
  function isSuccessfulValidationBashExecution(entry: BashExecutionEntry): boolean {
473
517
  if (entry.cancelled || entry.exitCode !== 0) return false;
474
518
  return detectValidationCommand(entry.command).kind === "validation";
@@ -490,6 +534,7 @@ function validationToolCallCandidate(
490
534
  return {
491
535
  toolCallId: call.id,
492
536
  runId: validationRunIdFor(linked, runSources),
537
+ artifact: { kind: "session_entry", id: entry.turnId },
493
538
  };
494
539
  }
495
540
 
@@ -508,8 +553,10 @@ function validationToolCallSummary(toolName: string, args: unknown): string | nu
508
553
  const target = readOptionalString(argRecord?.path) ?? "artifact";
509
554
  return `verify frontend ${target}`;
510
555
  }
511
- if (check === null || !isVerificationScriptName(check)) return null;
512
- return `npm run ${check}`;
556
+ if (check === null) return null;
557
+ if (isVerificationScriptName(check)) return `npm run ${check}`;
558
+ if (isProjectVerifierCheckId(check)) return `verify ${check}`;
559
+ return null;
513
560
  }
514
561
  return null;
515
562
  }
@@ -546,6 +593,7 @@ async function writeEvidenceFiles(
546
593
  auditLinks: AuditLinkResult,
547
594
  toolEventRows: ReadonlyArray<EvidenceToolEvent>,
548
595
  gateDecisions: EvidenceGateDecisionsFile,
596
+ trustStatus: EvidenceTrustStatusFile,
549
597
  protectedArtifacts: EvidenceProtectedArtifactsFile,
550
598
  transcript?: string,
551
599
  ): Promise<void> {
@@ -562,6 +610,7 @@ async function writeEvidenceFiles(
562
610
  await writeJsonl(join(directory, "audit-linked.jsonl"), auditLinks.rows);
563
611
  await writeJson(join(directory, "receipt.json"), receiptsFile(runSources));
564
612
  await writeJson(join(directory, "gate-decisions.json"), gateDecisions);
613
+ await writeJson(join(directory, "trust-status.json"), trustStatus);
565
614
  await writeJson(join(directory, "protected-artifacts.json"), protectedArtifacts);
566
615
  await writeJson(join(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
567
616
  await writeFile(join(directory, "findings.md"), renderFindings(findings), "utf8");
@@ -1151,7 +1200,7 @@ function compareAuditLinkedRows(a: EvidenceAuditLinkedRow, b: EvidenceAuditLinke
1151
1200
  const aCorrelation = readOptionalString(a.row.correlationId) ?? "";
1152
1201
  const bCorrelation = readOptionalString(b.row.correlationId) ?? "";
1153
1202
  if (aCorrelation !== bCorrelation) return compareStrings(aCorrelation, bCorrelation);
1154
- return JSON.stringify(a.row).localeCompare(JSON.stringify(b.row));
1203
+ return compareStrings(JSON.stringify(a.row), JSON.stringify(b.row));
1155
1204
  }
1156
1205
 
1157
1206
  function receiptsFile(runSources: ReadonlyArray<EvidenceRunSource>): EvidenceReceiptFile {
@@ -1372,6 +1421,19 @@ function renderSessionTranscriptEntry(linked: LinkedSessionEntry): string[] {
1372
1421
  ];
1373
1422
  }
1374
1423
  if (entry.kind === "custom") return [`${prefix} custom:${entry.customType} ${previewUnknown(entry.data)}`];
1424
+ if (entry.kind === "contextEviction") {
1425
+ const pressure = entry.pressureBefore === null ? "" : ` pressure=${entry.pressureBefore.toFixed(3)}`;
1426
+ return [
1427
+ `${prefix} contextEviction policy=${entry.policyId} trigger=${entry.trigger} items=${entry.evicted.length} tokens=${entry.tokensBefore}->${entry.tokensAfter}${pressure}`,
1428
+ ...entry.evicted.map(
1429
+ (item) =>
1430
+ ` evicted ref=${item.ref.entry} reason=${item.reason}${item.by === undefined ? "" : ` by=${item.by}`} freed=${item.tokensFreed}`,
1431
+ ),
1432
+ ];
1433
+ }
1434
+ if (entry.kind === "contextRecall") {
1435
+ return [`${prefix} contextRecall ref=${entry.ref.entry} trigger=${entry.trigger} tokens=${entry.tokensReadmitted}`];
1436
+ }
1375
1437
  const _exhaustive: never = entry;
1376
1438
  return [`${prefix} ${String(_exhaustive)}`];
1377
1439
  }
@@ -1432,9 +1494,18 @@ async function readReceipt(
1432
1494
  }
1433
1495
  return { receipt: null, error: `receipt read error: ${err.message ?? String(err)}`, integrityFailed: false };
1434
1496
  }
1435
- const parsed = parseJson(raw, receiptPath);
1436
- const receipt = parseRunReceipt(parsed, receiptPath);
1437
- const integrity = verifyReceiptIntegrity(receipt, envelope);
1497
+ let receipt: RunReceipt;
1498
+ try {
1499
+ const parsed = parseJson(raw, receiptPath);
1500
+ receipt = parseRunReceipt(parsed, receiptPath);
1501
+ } catch (error) {
1502
+ return {
1503
+ receipt: null,
1504
+ error: `receipt invalid: ${error instanceof Error ? error.message : String(error)}`,
1505
+ integrityFailed: true,
1506
+ };
1507
+ }
1508
+ const integrity = inspectRunReceiptTrustStatus(receipt, envelope).integrity;
1438
1509
  if (!integrity.ok) {
1439
1510
  return { receipt, error: `receipt integrity: ${integrity.reason}`, integrityFailed: true };
1440
1511
  }
@@ -1709,10 +1780,6 @@ function uniqueTags(values: ReadonlyArray<EvidenceTag>): EvidenceTag[] {
1709
1780
  return [...new Set(values)].sort(compareStrings);
1710
1781
  }
1711
1782
 
1712
- function compareStrings(a: string, b: string): number {
1713
- return a.localeCompare(b);
1714
- }
1715
-
1716
1783
  function compareNullableStrings(a: string | null, b: string | null): number {
1717
1784
  if (a === b) return 0;
1718
1785
  if (a === null) return 1;
@@ -5,6 +5,8 @@ import { readGateDecisionArtifactsForRunIds } from "../dispatch/index.js";
5
5
  import { redactArtifactForStorage } from "../eval/artifacts/redact.js";
6
6
  import type { EvalCommandResult, EvalRunArtifact, EvalRunRecord } from "../eval/index.js";
7
7
  import { loadEvalArtifact } from "../eval/index.js";
8
+ import { compareCodepoints as compareStrings } from "./ordering.js";
9
+ import { buildEvidenceTrustStatusFile } from "./run-trust.js";
8
10
  import { evidenceDirectory, findingsFile } from "./store.js";
9
11
  import {
10
12
  EVIDENCE_VERSION,
@@ -21,6 +23,7 @@ import {
21
23
  type EvidenceReceiptFile,
22
24
  type EvidenceTag,
23
25
  type EvidenceToolEvent,
26
+ type EvidenceTrustStatusFile,
24
27
  } from "./types.js";
25
28
 
26
29
  const EVAL_EVIDENCE_FILES = [
@@ -32,6 +35,7 @@ const EVAL_EVIDENCE_FILES = [
32
35
  "audit-linked.jsonl",
33
36
  "receipt.json",
34
37
  "gate-decisions.json",
38
+ "trust-status.json",
35
39
  "protected-artifacts.json",
36
40
  "eval-result.json",
37
41
  "findings.json",
@@ -87,8 +91,23 @@ export async function buildEvalEvidence(options: BuildEvalEvidenceOptions): Prom
87
91
  options.stateDir,
88
92
  ).map((entry) => entry.artifact),
89
93
  };
90
- await writeEvalEvidenceFiles(directory, artifact, overview, findings, toolEventRows, linkedRuns, gateDecisions);
91
- return { evidenceId, directory, overview, findings };
94
+ const trustStatus = buildEvidenceTrustStatusFile({
95
+ evidenceId,
96
+ runSources: linkedRuns.runSources,
97
+ gateDecisions: gateDecisions.decisions,
98
+ auditRows: linkedRuns.auditRows,
99
+ });
100
+ await writeEvalEvidenceFiles(
101
+ directory,
102
+ artifact,
103
+ overview,
104
+ findings,
105
+ toolEventRows,
106
+ linkedRuns,
107
+ gateDecisions,
108
+ trustStatus,
109
+ );
110
+ return { evidenceId, directory, overview, findings, trustStatus };
92
111
  }
93
112
 
94
113
  export function evalEvidenceId(evalId: string): string {
@@ -218,6 +237,7 @@ async function writeEvalEvidenceFiles(
218
237
  toolEventRows: ReadonlyArray<EvidenceToolEvent>,
219
238
  linkedRuns: EvalLinkedRuns,
220
239
  gateDecisions: EvidenceGateDecisionsFile,
240
+ trustStatus: EvidenceTrustStatusFile,
221
241
  ): Promise<void> {
222
242
  const emptyProtected: EvidenceProtectedArtifactsFile = { version: EVIDENCE_VERSION, artifacts: [], events: [] };
223
243
  const receiptsFile: EvidenceReceiptFile = {
@@ -234,6 +254,7 @@ async function writeEvalEvidenceFiles(
234
254
  await writeJsonl(join(directory, "audit-linked.jsonl"), linkedRuns.auditRows);
235
255
  await writeJson(join(directory, "receipt.json"), receiptsFile);
236
256
  await writeJson(join(directory, "gate-decisions.json"), gateDecisions);
257
+ await writeJson(join(directory, "trust-status.json"), trustStatus);
237
258
  await writeJson(join(directory, "protected-artifacts.json"), emptyProtected);
238
259
  await writeJson(join(directory, "eval-result.json"), redactedArtifact);
239
260
  await writeJson(join(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
@@ -576,7 +597,7 @@ function compareAuditRows(a: EvidenceAuditLinkedRow, b: EvidenceAuditLinkedRow):
576
597
  return (
577
598
  compareNullableStrings(a.ts, b.ts) ||
578
599
  compareNullableStrings(a.runId, b.runId) ||
579
- JSON.stringify(a.row).localeCompare(JSON.stringify(b.row))
600
+ compareStrings(JSON.stringify(a.row), JSON.stringify(b.row))
580
601
  );
581
602
  }
582
603
 
@@ -596,10 +617,6 @@ function sanitizeEvidenceId(value: string): string {
596
617
  return sanitized.length === 0 ? "unknown" : sanitized;
597
618
  }
598
619
 
599
- function compareStrings(a: string, b: string): number {
600
- return a.localeCompare(b);
601
- }
602
-
603
620
  function isRecord(value: unknown): value is Record<string, unknown> {
604
621
  return typeof value === "object" && value !== null && !Array.isArray(value);
605
622
  }
@@ -20,7 +20,56 @@ export {
20
20
  listEvidenceOverviews,
21
21
  loadEvidenceGateDecisions,
22
22
  loadEvidenceRunProvenance,
23
+ loadEvidenceTrustStatus,
23
24
  } from "./store.js";
25
+ export type {
26
+ AbsentTrustStatus,
27
+ AdaptFinishContractTrustOptions,
28
+ AdaptRunReceiptTrustOptions,
29
+ ArtifactIntegrityStatus,
30
+ AttributedTrustStatus,
31
+ AutonomyEnforcementStatus,
32
+ CanonicalTrustStatus,
33
+ CompletionEvidenceStatus,
34
+ ContextProvenanceStatus,
35
+ GroundedEvidenceValidationInput,
36
+ IndependentReviewStatus,
37
+ PersistedRunReceiptTrustFacts,
38
+ RunReceiptTrustInspection,
39
+ TrustAbsenceReason,
40
+ TrustArtifactKind,
41
+ TrustArtifactReference,
42
+ TrustStatusAuthority,
43
+ TrustStatusAuthorityKind,
44
+ TrustStatusAxes,
45
+ TrustStatusAxis,
46
+ TrustStatusProjection,
47
+ TrustStatusSource,
48
+ TrustStatusSourceKind,
49
+ TrustStatusValidation,
50
+ ValidationGroundingStatus,
51
+ } from "./trust-status.js";
52
+ export {
53
+ absentTrustStatus,
54
+ adaptFinishContractCompletionStatus,
55
+ adaptGateDecisionReviewStatus,
56
+ adaptGroundedEvidenceValidationStatus,
57
+ adaptReceiptIntegrityStatus,
58
+ adaptRunReceiptAutonomyStatus,
59
+ adaptRunReceiptContextStatus,
60
+ adaptRunReceiptTrustStatus,
61
+ adaptRunReceiptValidationStatus,
62
+ composeTrustStatus,
63
+ inspectRunReceiptTrustStatus,
64
+ normalizeTrustStatus,
65
+ projectTrustStatus,
66
+ TRUST_STATUS_AXES,
67
+ TRUST_STATUS_MAX_ARTIFACT_REFERENCES,
68
+ TRUST_STATUS_MAX_IDENTIFIER_LENGTH,
69
+ TRUST_STATUS_STATES,
70
+ TRUST_STATUS_VERSION,
71
+ validateTrustStatus,
72
+ } from "./trust-status.js";
24
73
  export type {
25
74
  EvidenceAuditLinkedRow,
26
75
  EvidenceBuildResult,
@@ -39,13 +88,17 @@ export type {
39
88
  EvidenceRawTraceRow,
40
89
  EvidenceReceiptFile,
41
90
  EvidenceRunSource,
91
+ EvidenceRunTrustStatus,
42
92
  EvidenceSeverity,
43
93
  EvidenceSource,
44
94
  EvidenceTag,
45
95
  EvidenceToolEvent,
46
96
  EvidenceToolEventSource,
47
97
  EvidenceTotals,
98
+ EvidenceTrustStatusFile,
99
+ EvidenceTrustStatusView,
48
100
  FailureCauseTag,
101
+ HistoricalEvidenceTrustStatus,
49
102
  } from "./types.js";
50
103
  export {
51
104
  EVIDENCE_TAGS,
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Ordinal string comparison for determinism-critical orderings.
3
+ *
4
+ * `String.prototype.localeCompare` collates through ICU, so its answer depends
5
+ * on the process locale and the ICU build. Evidence rows, "latest" selectors,
6
+ * and verifier catalogs must order identically on every machine that rebuilds
7
+ * them, so they compare UTF-16 code units instead. That order is the code
8
+ * point order for all BMP text and never reads the environment.
9
+ */
10
+ export function compareCodepoints(left: string, right: string): number {
11
+ return left < right ? -1 : left > right ? 1 : 0;
12
+ }