@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.
- package/CHANGELOG.md +39 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +3 -3
- package/dist/{acp-P2AQILE2.js → acp-S5R4RR5B.js} +7 -6
- package/dist/{agents-72W3BI7I.js → agents-P6DMMVZY.js} +24 -21
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5TWEIYDN.js → auth-2XCZLPKS.js} +12 -8
- package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
- package/dist/{chunk-2DJ2KNFG.js → chunk-2LZI5CAG.js} +133 -13
- package/dist/{chunk-OAO4GE4M.js → chunk-2TZWSW76.js} +2 -2
- package/dist/{chunk-OOJYHWRB.js → chunk-34475P3I.js} +2 -2
- package/dist/{chunk-4XUGQOHA.js → chunk-35MKKU5R.js} +4 -4
- package/dist/{chunk-LM5TQCJZ.js → chunk-3HZ5RWN2.js} +5 -5
- package/dist/{chunk-AGYYIBLL.js → chunk-3JLKSKD7.js} +2 -2
- package/dist/{chunk-KZWTDYJF.js → chunk-4JUF2NNX.js} +7 -7
- package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
- package/dist/chunk-5M54SPOL.js +926 -0
- package/dist/{chunk-STBPMHSX.js → chunk-7RXG6QRZ.js} +51 -11
- package/dist/{chunk-X6IAEBZR.js → chunk-A2GZF7DC.js} +5 -5
- package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
- package/dist/chunk-AOCYTWAV.js +449 -0
- package/dist/chunk-BEY543CS.js +258 -0
- package/dist/{chunk-6N5PTWMY.js → chunk-BP4OYD6A.js} +32 -13
- package/dist/chunk-BPGS2WCQ.js +612 -0
- package/dist/{chunk-V6RTAOC2.js → chunk-BRXQQJFP.js} +8 -8
- package/dist/chunk-CFGTUFWB.js +67 -0
- package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
- package/dist/{chunk-DUYJ5IO6.js → chunk-EDRHSCIE.js} +4 -4
- package/dist/{chunk-XBXAASKX.js → chunk-EFADSJET.js} +2 -2
- package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
- package/dist/chunk-FYYLNIL5.js +313 -0
- package/dist/{chunk-FNTMWMX5.js → chunk-HV5X7OR2.js} +14 -12
- package/dist/{chunk-TZTZS7QK.js → chunk-HXG4IURW.js} +5 -3
- package/dist/{chunk-5UFT4SUX.js → chunk-K6WL7QZT.js} +3 -3
- package/dist/chunk-K7VKOLQQ.js +15 -0
- package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
- package/dist/{chunk-OC7FIQPC.js → chunk-KRPY7NTG.js} +10 -7
- package/dist/chunk-LL4KHSZI.js +22 -0
- package/dist/{chunk-DSELYM6W.js → chunk-MEQ45TQ4.js} +15 -9
- package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
- package/dist/{chunk-6SGHMWE3.js → chunk-N4CZJQRK.js} +5 -5
- package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
- package/dist/chunk-OZNBF4L3.js +23 -0
- package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
- package/dist/chunk-QQK64KLB.js +1360 -0
- package/dist/{chunk-SRDMMSEP.js → chunk-QQL5RT5M.js} +979 -1619
- package/dist/{chunk-LZSJBIVT.js → chunk-QWU7ZBO7.js} +70 -720
- package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
- package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
- package/dist/{chunk-OQ33BKR3.js → chunk-TTNYS3EA.js} +3 -60
- package/dist/chunk-TW3WDMVS.js +677 -0
- package/dist/chunk-TZSKNMZG.js +434 -0
- package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
- package/dist/{chunk-PIWWS5BL.js → chunk-UZHIZC5S.js} +7 -7
- package/dist/{chunk-UFIIWP2H.js → chunk-VAWWTKDP.js} +8 -8
- package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
- package/dist/{chunk-LW6DSM3M.js → chunk-VMNQ6OZA.js} +98 -202
- package/dist/chunk-VSNATDE6.js +122 -0
- package/dist/chunk-W6GROXXM.js +69 -0
- package/dist/chunk-WPQLXFOZ.js +375 -0
- package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
- package/dist/{chunk-PAJK6MAQ.js → chunk-X6COSD2O.js} +5 -5
- package/dist/chunk-ZGVHUX3M.js +66 -0
- package/dist/{chunk-LWLEKMDQ.js → chunk-ZYKPLLNQ.js} +510 -547
- package/dist/cli/index.js +27 -23
- package/dist/{clio-JOU4FXVA.js → clio-J5JIOIDS.js} +7 -6
- package/dist/{code-nav-7AX6FYE6.js → code-nav-AXCXSBHX.js} +5 -3
- package/dist/{config-XCDVKR23.js → config-OEBMIN2U.js} +37 -27
- package/dist/{configure-4GAP54ZW.js → configure-PUQOSIXQ.js} +16 -13
- package/dist/{context-5VKGUVJJ.js → context-EKDCKUUZ.js} +82 -7
- package/dist/{context-4UOGGLQ5.js → context-MGSE4Z2T.js} +33 -23
- package/dist/{context-77FM5DV5.js → context-URSXPBCK.js} +17 -9
- package/dist/{context-clear-XXJRLCJJ.js → context-clear-KDAJRNUK.js} +33 -23
- package/dist/context-working-set-SBKMPPI2.js +1552 -0
- package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-MSWN72NK.js} +43 -29
- package/dist/{doctor-HR46URBJ.js → doctor-7BSE27PJ.js} +10 -10
- package/dist/{eval-XSSNATB4.js → eval-IZGDOO4H.js} +9 -8
- package/dist/{evidence-6HG2PY2B.js → evidence-SR7WXB5B.js} +51 -23
- package/dist/{evolve-K7YU3NCY.js → evolve-K7VE2CBX.js} +30 -20
- package/dist/{fleet-VY3HHKN6.js → fleet-7XMJNQNF.js} +48 -38
- package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-AQNAH644.js} +3 -3
- package/dist/{init-JYGXI3FK.js → init-JGNPAYXT.js} +41 -31
- package/dist/{memory-WFZMGYHX.js → memory-4ALKDJ4Q.js} +32 -22
- package/dist/{models-I5QWSEOM.js → models-ZMMLFJNN.js} +22 -19
- package/dist/{monitor-GE4ID3IA.js → monitor-2F3T5KHP.js} +55 -43
- package/dist/{orchestrator-EM5MC3HM.js → orchestrator-ORHT43JB.js} +572 -388
- package/dist/{reset-L2FQEE3E.js → reset-NXGTYNUO.js} +4 -3
- package/dist/{run-ZU3QMZPZ.js → run-RF4WJGMT.js} +51 -41
- package/dist/{share-S5BZQC5I.js → share-UT3W6E4M.js} +5 -4
- package/dist/{skills-X5VXCRNQ.js → skills-PSACKC5Q.js} +2 -2
- package/dist/{skills-eval-WKIHWTHR.js → skills-eval-WJSI55RZ.js} +34 -24
- package/dist/{targets-SNCPI2NR.js → targets-PIIRAOYS.js} +23 -20
- package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-ULWXWNVY.js} +4 -3
- package/dist/{upgrade-JQHHPQ4K.js → upgrade-346TZ6AV.js} +18 -17
- package/dist/{usage-OR4O5SMZ.js → usage-6KKXR32N.js} +34 -24
- package/dist/verifiers-4UUM6TEE.js +1214 -0
- package/dist/verify-X5HDROLA.js +25 -0
- package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-7STOCIFZ.js} +42 -31
- package/dist/worker/entry.js +33 -24
- package/docs/README.md +7 -6
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +53 -21
- package/docs/config-knobs-audit.md +1 -2
- package/docs/configuration-and-targets.md +15 -1
- package/docs/context-engine.md +64 -12
- package/docs/context-working-set.md +194 -0
- package/docs/development-pipeline.md +1 -1
- package/docs/documentation-coverage.md +5 -5
- package/docs/documentation-guide.md +6 -5
- package/docs/environment-variables.md +2 -1
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +14 -1
- package/docs/evidence-and-memory.md +74 -2
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +2 -2
- package/docs/fleet-dispatch.md +22 -7
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +1 -1
- package/docs/model-catalog.md +7 -9
- package/docs/observability.md +4 -4
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +4 -4
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +31 -31
- package/docs/safety-model.md +23 -4
- package/docs/scientific-validation.md +21 -3
- package/docs/session-lifecycle.md +3 -3
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +79 -12
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +1 -1
- package/docs/worker-dispatch-mechanics.md +11 -1
- package/package.json +8 -11
- package/skills/meta/clio-test/SKILL.md +20 -17
- package/skills/meta/clio-test/evals.md +3 -3
- package/skills/meta/clio-test/references/harness.md +35 -6
- package/skills/meta/clio-test/references/test-map.md +20 -10
- package/skills/registry.yaml +2 -2
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/context-working-set.ts +513 -0
- package/src/cli/context.ts +8 -0
- package/src/cli/evidence.ts +20 -2
- package/src/cli/index.ts +4 -0
- package/src/cli/verifiers.ts +325 -0
- package/src/core/bash-exec.ts +39 -14
- package/src/core/bus-events.ts +19 -4
- package/src/core/config.ts +54 -0
- package/src/core/defaults.ts +50 -3
- package/src/core/verification-scripts.ts +6 -0
- package/src/domains/agents/builtins/verifier.md +3 -0
- package/src/domains/config/classify.ts +1 -0
- package/src/domains/context/working-set/contract.ts +161 -0
- package/src/domains/context/working-set/defaults.ts +28 -0
- package/src/domains/context/working-set/engine.ts +203 -0
- package/src/domains/context/working-set/fold.ts +62 -0
- package/src/domains/context/working-set/horizon.ts +38 -0
- package/src/domains/context/working-set/marker.ts +103 -0
- package/src/domains/context/working-set/path-index.ts +436 -0
- package/src/domains/context/working-set/payload.ts +152 -0
- package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
- package/src/domains/context/working-set/policies/index.ts +21 -0
- package/src/domains/context/working-set/policies/structural.ts +160 -0
- package/src/domains/context/working-set/project.ts +132 -0
- package/src/domains/context/working-set/protect.ts +109 -0
- package/src/domains/context/working-set/recall.ts +177 -0
- package/src/domains/context/working-set/replay/controls.ts +112 -0
- package/src/domains/context/working-set/replay/load-clio.ts +199 -0
- package/src/domains/context/working-set/replay/metrics.ts +185 -0
- package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
- package/src/domains/context/working-set/replay/report.ts +139 -0
- package/src/domains/context/working-set/replay/runner.ts +325 -0
- package/src/domains/context/working-set/replay/synthetic.ts +422 -0
- package/src/domains/context/working-set/replay/trace.ts +21 -0
- package/src/domains/context/working-set/visible.ts +54 -0
- package/src/domains/evidence/build.ts +112 -45
- package/src/domains/evidence/eval.ts +24 -7
- package/src/domains/evidence/index.ts +53 -0
- package/src/domains/evidence/ordering.ts +12 -0
- package/src/domains/evidence/run-trust.ts +221 -0
- package/src/domains/evidence/store.ts +46 -6
- package/src/domains/evidence/trust-status.ts +854 -0
- package/src/domains/evidence/types.ts +26 -0
- package/src/domains/middleware/memory-intervention.ts +3 -0
- package/src/domains/middleware/stalled-turn.ts +165 -4
- package/src/domains/safety/autonomy.ts +1 -1
- package/src/domains/safety/default-path-policy.ts +8 -0
- package/src/domains/safety/finish-contract.ts +4 -3
- package/src/domains/safety/policy-engine.ts +48 -6
- package/src/domains/session/compaction/compact.ts +23 -1
- package/src/domains/session/compaction/cut-point.ts +2 -0
- package/src/domains/session/compaction/tokens.ts +16 -1
- package/src/domains/session/context-ledger.ts +2 -0
- package/src/domains/session/entries.ts +107 -1
- package/src/domains/session/manager.ts +9 -2
- package/src/domains/session/migrations/index.ts +22 -3
- package/src/engine/acp/server.ts +3 -0
- package/src/engine/agent.ts +18 -1
- package/src/engine/session.ts +9 -3
- package/src/entry/orchestrator.ts +16 -4
- package/src/interactive/chat-loop-messages.ts +18 -6
- package/src/interactive/chat-panel.ts +17 -1
- package/src/interactive/chat-renderer.ts +30 -21
- package/src/interactive/context-meter.ts +10 -0
- package/src/interactive/context-overlay.ts +81 -6
- package/src/interactive/context-recall-command.ts +110 -0
- package/src/interactive/interactive-slash-runtime.ts +37 -1
- package/src/interactive/model-session-replay.ts +21 -0
- package/src/interactive/overlay-general-openers.ts +6 -0
- package/src/interactive/overlay-session-lifecycle.ts +8 -4
- package/src/interactive/renderers/tool-execution.ts +18 -2
- package/src/interactive/session-transcript.ts +2 -2
- package/src/interactive/slash-commands.ts +29 -2
- package/src/interactive/turn-context.ts +238 -88
- package/src/interactive/turn-middleware.ts +6 -6
- package/src/tools/agent-tools.ts +11 -4
- package/src/tools/bash.ts +144 -82
- package/src/tools/builtin-tool-catalog.ts +11 -5
- package/src/tools/context/index.ts +105 -3
- package/src/tools/context/surface.ts +3 -2
- package/src/tools/core-bootstrap.ts +21 -0
- package/src/tools/dispatch-runner.ts +9 -7
- package/src/tools/monitor.ts +28 -20
- package/src/tools/registry.ts +59 -7
- package/src/tools/result-disposition.ts +550 -0
- package/src/tools/result-shaping.ts +262 -19
- package/src/tools/safe-exec.ts +2 -0
- package/src/tools/verify/authoring.ts +1119 -0
- package/src/tools/verify/catalog.ts +346 -0
- package/src/tools/verify/index.ts +13 -3
- package/src/tools/verify/scripts.ts +135 -37
- package/src/tools/verify/surface.ts +9 -5
- package/src/tools/worker-evidence.ts +35 -12
- package/dist/chunk-J7CWMCQD.js +0 -255
- package/dist/chunk-T6YILFSB.js +0 -80
- package/dist/chunk-VAKQQHWR.js +0 -434
- package/dist/chunk-VPAYEGVX.js +0 -184
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
protectedArtifactFromSessionEntry,
|
|
4
|
+
protectedArtifactStateFromSessionEntries,
|
|
5
|
+
readAuditRows,
|
|
6
|
+
readSessionEntriesForId
|
|
7
|
+
} from "./chunk-QQK64KLB.js";
|
|
7
8
|
import {
|
|
8
9
|
FLEET_COMMAND_BASE_ENV,
|
|
9
10
|
describeWriteBoundary,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
sumEvalHarnessMetrics,
|
|
24
25
|
verifyReceiptIntegrity,
|
|
25
26
|
withReceiptIntegrity
|
|
26
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-3JLKSKD7.js";
|
|
27
28
|
import {
|
|
28
29
|
LOCAL_NODE_ID,
|
|
29
30
|
computeSettingsFingerprint,
|
|
@@ -34,10 +35,7 @@ import {
|
|
|
34
35
|
receiptAttestationFields,
|
|
35
36
|
routeFactVerdict,
|
|
36
37
|
spawnNativeWorker
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import {
|
|
39
|
-
probeWorkspace
|
|
40
|
-
} from "./chunk-G4BMMOKF.js";
|
|
38
|
+
} from "./chunk-34475P3I.js";
|
|
41
39
|
import {
|
|
42
40
|
AGENT_LEDGER_PROMPT_MAX_CHARS,
|
|
43
41
|
RETRYABLE_OUTCOMES,
|
|
@@ -63,8 +61,6 @@ import {
|
|
|
63
61
|
isClaudeCanonicalTool,
|
|
64
62
|
isResponseSchemaRejection,
|
|
65
63
|
isRunOutcomeCode,
|
|
66
|
-
isSessionEntry,
|
|
67
|
-
isSessionHeader,
|
|
68
64
|
networkToolsDisabled,
|
|
69
65
|
projectExecutionHandoffs,
|
|
70
66
|
renderAgentLedger,
|
|
@@ -74,7 +70,7 @@ import {
|
|
|
74
70
|
serializeWorkerRuntimeDescriptor,
|
|
75
71
|
toolPromptHintsForNames,
|
|
76
72
|
validateJobSpec
|
|
77
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-ZYKPLLNQ.js";
|
|
78
74
|
import {
|
|
79
75
|
DEFAULT_AUTONOMY_LEVEL,
|
|
80
76
|
WRITE_ROOT_REFUSED_TOOLS,
|
|
@@ -84,7 +80,7 @@ import {
|
|
|
84
80
|
parseJsonObjectPayload,
|
|
85
81
|
parseVerifierResult,
|
|
86
82
|
validateRecipeResult
|
|
87
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-7RXG6QRZ.js";
|
|
88
84
|
import {
|
|
89
85
|
appliesRecipeResultContract,
|
|
90
86
|
decideRoute,
|
|
@@ -107,31 +103,41 @@ import {
|
|
|
107
103
|
sameRouteIdentity,
|
|
108
104
|
toRouteCandidate,
|
|
109
105
|
withAttemptRole
|
|
110
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-22NAGB7X.js";
|
|
111
107
|
import {
|
|
112
108
|
agentSpecFingerprint,
|
|
113
109
|
assertAgentSpecPolicy,
|
|
114
110
|
classify,
|
|
115
|
-
detectValidationCommand,
|
|
116
111
|
isUserVisibleAgent,
|
|
117
112
|
normalizeAgentSpec,
|
|
118
|
-
protectArtifact,
|
|
119
113
|
resolveAgentToolCompatibility
|
|
120
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-AOCYTWAV.js";
|
|
115
|
+
import {
|
|
116
|
+
detectValidationCommand
|
|
117
|
+
} from "./chunk-MV3K5QF2.js";
|
|
121
118
|
import {
|
|
122
119
|
canonicalJson,
|
|
123
120
|
endpointIdentityHash,
|
|
124
121
|
parseAgentLedgerBody
|
|
125
122
|
} from "./chunk-CMZWFGD2.js";
|
|
126
123
|
import {
|
|
124
|
+
compareCodepoints
|
|
125
|
+
} from "./chunk-FYYLNIL5.js";
|
|
126
|
+
import {
|
|
127
|
+
isProjectVerifierCheckId,
|
|
127
128
|
isVerificationScriptName
|
|
128
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-UL3WSD3F.js";
|
|
129
130
|
import {
|
|
130
131
|
canonicalizeExistingPath
|
|
131
132
|
} from "./chunk-ECH6PKUQ.js";
|
|
132
133
|
import {
|
|
133
134
|
isSkillActivation
|
|
134
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-BEY543CS.js";
|
|
136
|
+
import {
|
|
137
|
+
createRedactionTally,
|
|
138
|
+
redactSecretsDeep,
|
|
139
|
+
redactSecretsText
|
|
140
|
+
} from "./chunk-4BJ5BYCE.js";
|
|
135
141
|
import {
|
|
136
142
|
truncateUtf8
|
|
137
143
|
} from "./chunk-6XLNIQDB.js";
|
|
@@ -141,45 +147,28 @@ import {
|
|
|
141
147
|
} from "./chunk-CGKSTWHD.js";
|
|
142
148
|
import {
|
|
143
149
|
canonicalizeWireModelId,
|
|
144
|
-
ceilChars,
|
|
145
150
|
firstRuntimeResolutionError,
|
|
146
151
|
isDispatchEligibleRuntime,
|
|
147
152
|
resolveEffectivePricing,
|
|
148
153
|
resolveModelCapabilities,
|
|
149
154
|
resolveRuntimeTarget,
|
|
150
155
|
runtimeResolutionWarnings,
|
|
151
|
-
runtimeTargetSnapshot
|
|
152
|
-
|
|
153
|
-
} from "./chunk-LZSJBIVT.js";
|
|
156
|
+
runtimeTargetSnapshot
|
|
157
|
+
} from "./chunk-QWU7ZBO7.js";
|
|
154
158
|
import {
|
|
155
159
|
DEFAULT_DELEGATION_CONNECT_TIMEOUT_MS,
|
|
156
160
|
DEFAULT_DELEGATION_TURN_TIMEOUT_MS,
|
|
157
161
|
DEFAULT_SETTINGS,
|
|
158
162
|
THINKING_LEVELS
|
|
159
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-4OC57DA6.js";
|
|
160
164
|
import {
|
|
161
165
|
targetRequiresAuth
|
|
162
166
|
} from "./chunk-4VP4KH3K.js";
|
|
163
|
-
import {
|
|
164
|
-
CURRENT_SESSION_FORMAT_VERSION,
|
|
165
|
-
appendSessionFileEntry,
|
|
166
|
-
atomicWrite,
|
|
167
|
-
createSession,
|
|
168
|
-
cwdHash,
|
|
169
|
-
openSession,
|
|
170
|
-
readSessionFileEntries,
|
|
171
|
-
readSessionMeta,
|
|
172
|
-
resumeSession,
|
|
173
|
-
sessionPaths
|
|
174
|
-
} from "./chunk-M6SHUN7Q.js";
|
|
175
|
-
import {
|
|
176
|
-
assertSafeId
|
|
177
|
-
} from "./chunk-R346GLFC.js";
|
|
178
167
|
import {
|
|
179
168
|
gitCommitAttributionEnabled,
|
|
180
169
|
reportCommitAttributionDiagnostic,
|
|
181
170
|
withManagedGitCommitAttributionEnvironment
|
|
182
|
-
} from "./chunk-
|
|
171
|
+
} from "./chunk-VEZEGCGW.js";
|
|
183
172
|
import {
|
|
184
173
|
MAX_TIMER_DELAY_MS,
|
|
185
174
|
rawDurationMs
|
|
@@ -194,6 +183,15 @@ import {
|
|
|
194
183
|
processAlive,
|
|
195
184
|
processBirthToken
|
|
196
185
|
} from "./chunk-3I7MS7N2.js";
|
|
186
|
+
import {
|
|
187
|
+
ceilChars
|
|
188
|
+
} from "./chunk-BPGS2WCQ.js";
|
|
189
|
+
import {
|
|
190
|
+
atomicWrite
|
|
191
|
+
} from "./chunk-FO5ZOVUY.js";
|
|
192
|
+
import {
|
|
193
|
+
assertSafeId
|
|
194
|
+
} from "./chunk-R346GLFC.js";
|
|
197
195
|
import {
|
|
198
196
|
GUARDRAIL_DEFAULTS,
|
|
199
197
|
resolveGuardrail
|
|
@@ -208,7 +206,7 @@ import {
|
|
|
208
206
|
} from "./chunk-6EJMN2Y3.js";
|
|
209
207
|
import {
|
|
210
208
|
BusChannels
|
|
211
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-TTNYS3EA.js";
|
|
212
210
|
import {
|
|
213
211
|
readClioVersion,
|
|
214
212
|
readPiMonoVersion,
|
|
@@ -1426,8 +1424,8 @@ init_esm_shims();
|
|
|
1426
1424
|
|
|
1427
1425
|
// src/domains/evidence/build.ts
|
|
1428
1426
|
init_esm_shims();
|
|
1429
|
-
import { mkdir, readFile as
|
|
1430
|
-
import { join as
|
|
1427
|
+
import { mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
|
|
1428
|
+
import { join as join16 } from "node:path";
|
|
1431
1429
|
|
|
1432
1430
|
// src/domains/dispatch/index.ts
|
|
1433
1431
|
init_esm_shims();
|
|
@@ -12577,1521 +12575,807 @@ function createDispatchDomainModule(options = {}) {
|
|
|
12577
12575
|
};
|
|
12578
12576
|
}
|
|
12579
12577
|
|
|
12580
|
-
// src/domains/
|
|
12581
|
-
init_esm_shims();
|
|
12582
|
-
|
|
12583
|
-
// src/domains/session/extension.ts
|
|
12584
|
-
init_esm_shims();
|
|
12585
|
-
|
|
12586
|
-
// src/domains/session/checkpoint.ts
|
|
12587
|
-
init_esm_shims();
|
|
12588
|
-
async function performCheckpoint(state, reason) {
|
|
12589
|
-
await state.writer.persistTree();
|
|
12590
|
-
if (stateRootRemoved()) return;
|
|
12591
|
-
const paths = sessionPaths(state.meta);
|
|
12592
|
-
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
12593
|
-
const enriched = {
|
|
12594
|
-
...state.meta,
|
|
12595
|
-
lastCheckpointAt: at,
|
|
12596
|
-
lastCheckpointReason: reason ?? null
|
|
12597
|
-
};
|
|
12598
|
-
atomicWrite(paths.meta, JSON.stringify(enriched, null, 2));
|
|
12599
|
-
Object.assign(state.meta, enriched);
|
|
12600
|
-
}
|
|
12601
|
-
|
|
12602
|
-
// src/domains/session/history.ts
|
|
12603
|
-
init_esm_shims();
|
|
12604
|
-
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync12, statSync as statSync2 } from "node:fs";
|
|
12605
|
-
import { join as join15 } from "node:path";
|
|
12606
|
-
|
|
12607
|
-
// src/domains/session/compaction/session-entries.ts
|
|
12578
|
+
// src/domains/evidence/failure-attribution.ts
|
|
12608
12579
|
init_esm_shims();
|
|
12609
|
-
function
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
if (!isSessionEntry(raw)) {
|
|
12613
|
-
throw new Error(
|
|
12614
|
-
`session ledger contains an unreadable entry (missing kind discriminant): ${filePath}. Remove or compact the session to reset.`
|
|
12615
|
-
);
|
|
12616
|
-
}
|
|
12617
|
-
out.push(raw);
|
|
12618
|
-
}
|
|
12619
|
-
return out;
|
|
12620
|
-
}
|
|
12621
|
-
|
|
12622
|
-
// src/domains/session/history.ts
|
|
12623
|
-
function listSessionsForCwd(cwd) {
|
|
12624
|
-
const hash = cwdHash(cwd);
|
|
12625
|
-
const dir = join15(clioStateDir(), "sessions", hash);
|
|
12626
|
-
if (!existsSync14(dir)) return [];
|
|
12627
|
-
const metas = [];
|
|
12628
|
-
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
12629
|
-
if (!entry.isDirectory()) continue;
|
|
12630
|
-
const sessionDir = join15(dir, entry.name);
|
|
12631
|
-
const metaPath = join15(sessionDir, "meta.json");
|
|
12632
|
-
if (!existsSync14(metaPath)) continue;
|
|
12633
|
-
let meta;
|
|
12634
|
-
try {
|
|
12635
|
-
if (!statSync2(metaPath).isFile()) continue;
|
|
12636
|
-
const raw = readFileSync12(metaPath, "utf8");
|
|
12637
|
-
meta = JSON.parse(raw);
|
|
12638
|
-
} catch {
|
|
12639
|
-
continue;
|
|
12640
|
-
}
|
|
12641
|
-
enrichMetaForListing(meta, join15(sessionDir, "current.jsonl"));
|
|
12642
|
-
metas.push(meta);
|
|
12643
|
-
}
|
|
12644
|
-
metas.sort((a, b) => {
|
|
12645
|
-
const aKey = a.lastActivityAt ?? a.createdAt ?? "";
|
|
12646
|
-
const bKey = b.lastActivityAt ?? b.createdAt ?? "";
|
|
12647
|
-
return aKey === bKey ? 0 : aKey > bKey ? -1 : 1;
|
|
12648
|
-
});
|
|
12649
|
-
return metas;
|
|
12650
|
-
}
|
|
12651
|
-
var PREVIEW_MAX_CHARS = 240;
|
|
12652
|
-
function collapseWhitespace(text) {
|
|
12653
|
-
return text.replace(/\s+/g, " ").trim();
|
|
12654
|
-
}
|
|
12655
|
-
function extractUserText(payload) {
|
|
12656
|
-
if (typeof payload === "string") {
|
|
12657
|
-
const collapsed = collapseWhitespace(payload);
|
|
12658
|
-
return collapsed.length > 0 ? collapsed : null;
|
|
12580
|
+
function attributeEvidenceFailure(facts) {
|
|
12581
|
+
if (facts.outcomeCode === "worker_tool_call_cap_exhausted" || facts.outcomeCode === "loop_guard_tools_disabled_exhausted") {
|
|
12582
|
+
return "tool-loop";
|
|
12659
12583
|
}
|
|
12660
|
-
if (
|
|
12661
|
-
const
|
|
12662
|
-
if (
|
|
12663
|
-
|
|
12664
|
-
|
|
12584
|
+
if (facts.outcome === "timed_out" || facts.outcome === "stalled") return "timeout";
|
|
12585
|
+
const diagnostic = [facts.outcomeDetail, facts.failureMessage].filter((value) => value !== null).join("\n").toLowerCase();
|
|
12586
|
+
if (diagnostic.length === 0) return "unknown";
|
|
12587
|
+
if (/\b(?:401|403)\b|unauthorized|forbidden|invalid api key|authentication/.test(diagnostic)) {
|
|
12588
|
+
return "auth-failure";
|
|
12665
12589
|
}
|
|
12666
|
-
if (
|
|
12667
|
-
|
|
12668
|
-
for (const part of obj.content) {
|
|
12669
|
-
if (part && typeof part === "object" && part.type === "text" && typeof part.text === "string") {
|
|
12670
|
-
parts.push(part.text);
|
|
12671
|
-
}
|
|
12672
|
-
}
|
|
12673
|
-
const joined = collapseWhitespace(parts.join(" "));
|
|
12674
|
-
if (joined.length > 0) return joined;
|
|
12590
|
+
if (/\b429\b|rate[ -]?limit|too many requests|temporar(?:y|ily)|unavailable|\b50[234]\b/.test(diagnostic)) {
|
|
12591
|
+
return "provider-transient";
|
|
12675
12592
|
}
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
function scanCurrentJsonl(currentPath) {
|
|
12679
|
-
const result = {
|
|
12680
|
-
firstUserMessage: null,
|
|
12681
|
-
messageCount: 0,
|
|
12682
|
-
lastTimestamp: null,
|
|
12683
|
-
name: null,
|
|
12684
|
-
labels: /* @__PURE__ */ new Map()
|
|
12685
|
-
};
|
|
12686
|
-
if (!existsSync14(currentPath)) return result;
|
|
12687
|
-
const records = readSessionFileEntries(currentPath).filter((entry) => !isSessionHeader(entry));
|
|
12688
|
-
for (const parsed of collectSessionEntries(records, currentPath)) {
|
|
12689
|
-
if (result.lastTimestamp === null || parsed.timestamp > result.lastTimestamp) {
|
|
12690
|
-
result.lastTimestamp = parsed.timestamp;
|
|
12691
|
-
}
|
|
12692
|
-
if (parsed.kind === "message" && parsed.role === "user") {
|
|
12693
|
-
result.messageCount += 1;
|
|
12694
|
-
if (result.firstUserMessage === null) {
|
|
12695
|
-
const text = extractUserText(parsed.payload);
|
|
12696
|
-
if (text !== null) result.firstUserMessage = text;
|
|
12697
|
-
}
|
|
12698
|
-
}
|
|
12699
|
-
if (parsed.kind === "sessionInfo") {
|
|
12700
|
-
const info = parsed;
|
|
12701
|
-
if (info.name !== void 0) {
|
|
12702
|
-
const trimmed = info.name.trim();
|
|
12703
|
-
result.name = trimmed.length > 0 ? trimmed : null;
|
|
12704
|
-
}
|
|
12705
|
-
if (info.targetTurnId && info.label !== void 0) {
|
|
12706
|
-
const existing = result.labels.get(info.targetTurnId);
|
|
12707
|
-
if (!existing || existing.timestamp <= info.timestamp) {
|
|
12708
|
-
result.labels.set(info.targetTurnId, { label: info.label, timestamp: info.timestamp });
|
|
12709
|
-
}
|
|
12710
|
-
}
|
|
12711
|
-
}
|
|
12712
|
-
if (parsed.kind === "label") {
|
|
12713
|
-
const label = parsed;
|
|
12714
|
-
const existing = result.labels.get(label.targetTurnId);
|
|
12715
|
-
if (!existing || existing.timestamp <= label.timestamp) {
|
|
12716
|
-
result.labels.set(label.targetTurnId, { label: label.label ?? "", timestamp: label.timestamp });
|
|
12717
|
-
}
|
|
12718
|
-
}
|
|
12593
|
+
if (/context (?:length|window)|context[_ -]?overflow|maximum context|too many tokens/.test(diagnostic)) {
|
|
12594
|
+
return "context-overflow";
|
|
12719
12595
|
}
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
function enrichMetaForListing(meta, currentPath) {
|
|
12723
|
-
const scan = scanCurrentJsonl(currentPath);
|
|
12724
|
-
if (scan.name) meta.name = scan.name;
|
|
12725
|
-
const labelValues = [...scan.labels.values()].map((entry) => entry.label.trim()).filter((label) => label.length > 0);
|
|
12726
|
-
if (labelValues.length > 0) meta.labels = labelValues;
|
|
12727
|
-
if (scan.firstUserMessage) {
|
|
12728
|
-
meta.firstMessagePreview = scan.firstUserMessage.length > PREVIEW_MAX_CHARS ? `${scan.firstUserMessage.slice(0, PREVIEW_MAX_CHARS - 1)}\u2026` : scan.firstUserMessage;
|
|
12596
|
+
if (/module not found|cannot find module|missing (?:dependency|package)|dependency .* missing/.test(diagnostic)) {
|
|
12597
|
+
return "missing-dependency";
|
|
12729
12598
|
}
|
|
12730
|
-
if (
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
if (activity) meta.lastActivityAt = activity;
|
|
12734
|
-
}
|
|
12735
|
-
function readMtimeIso(path2) {
|
|
12736
|
-
try {
|
|
12737
|
-
return statSync2(path2).mtime.toISOString();
|
|
12738
|
-
} catch {
|
|
12739
|
-
return null;
|
|
12599
|
+
if (/wrong runtime|runtime mismatch|model mismatch|unsupported runtime/.test(diagnostic)) return "wrong-runtime";
|
|
12600
|
+
if (/\b(?:test|tests|pytest|ctest)\b.*(?:fail|error)|(?:fail|error).*\b(?:test|tests|pytest|ctest)\b/.test(diagnostic)) {
|
|
12601
|
+
return "test-failure";
|
|
12740
12602
|
}
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
Object.assign(meta, { parentSessionId, parentTurnId });
|
|
12744
|
-
const paths = sessionPaths(meta);
|
|
12745
|
-
atomicWrite(paths.meta, JSON.stringify(meta, null, 2));
|
|
12603
|
+
if (/\bbuild\b.*(?:fail|error)|(?:fail|error).*\bbuild\b/.test(diagnostic)) return "build-failure";
|
|
12604
|
+
return "unknown";
|
|
12746
12605
|
}
|
|
12747
12606
|
|
|
12748
|
-
// src/domains/
|
|
12749
|
-
init_esm_shims();
|
|
12750
|
-
|
|
12751
|
-
// node_modules/uuid/dist-node/index.js
|
|
12752
|
-
init_esm_shims();
|
|
12753
|
-
|
|
12754
|
-
// node_modules/uuid/dist-node/stringify.js
|
|
12607
|
+
// src/domains/evidence/provenance.ts
|
|
12755
12608
|
init_esm_shims();
|
|
12756
|
-
var
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12609
|
+
var PERSONA_HASH_PREFIX_CHARS = 12;
|
|
12610
|
+
function extractRunProvenance(receipt) {
|
|
12611
|
+
const view = {};
|
|
12612
|
+
if (receipt.pipeline !== void 0) view.pipeline = receipt.pipeline;
|
|
12613
|
+
if (receipt.personaOverride !== void 0) view.personaOverride = receipt.personaOverride;
|
|
12614
|
+
const escalation = escalationCountsFrom(receipt.safety);
|
|
12615
|
+
if (escalation !== null) view.escalation = escalation;
|
|
12616
|
+
if (receipt.autonomyEnforcement !== void 0) view.autonomyEnforcement = receipt.autonomyEnforcement;
|
|
12617
|
+
return view;
|
|
12762
12618
|
}
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
init_esm_shims();
|
|
12766
|
-
var rnds8 = new Uint8Array(16);
|
|
12767
|
-
function rng() {
|
|
12768
|
-
return crypto.getRandomValues(rnds8);
|
|
12619
|
+
function hasRunProvenance(view) {
|
|
12620
|
+
return view.pipeline !== void 0 || view.personaOverride !== void 0 || view.escalation !== void 0 || view.autonomyEnforcement !== void 0;
|
|
12769
12621
|
}
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
if (
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);
|
|
12783
|
-
}
|
|
12784
|
-
return buf ?? unsafeStringify(bytes);
|
|
12785
|
-
}
|
|
12786
|
-
function updateV7State(state, now, rnds) {
|
|
12787
|
-
state.msecs ??= -Infinity;
|
|
12788
|
-
state.seq ??= 0;
|
|
12789
|
-
if (now > state.msecs) {
|
|
12790
|
-
state.seq = rnds[6] << 23 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
12791
|
-
state.msecs = now;
|
|
12792
|
-
} else {
|
|
12793
|
-
state.seq = state.seq + 1 | 0;
|
|
12794
|
-
if (state.seq === 0) {
|
|
12795
|
-
state.msecs++;
|
|
12796
|
-
}
|
|
12797
|
-
}
|
|
12798
|
-
return state;
|
|
12622
|
+
function runProvenanceFromUnknown(value) {
|
|
12623
|
+
if (!isRecord9(value)) return {};
|
|
12624
|
+
const view = {};
|
|
12625
|
+
const pipeline = pipelineFromUnknown(value.pipeline);
|
|
12626
|
+
if (pipeline !== null) view.pipeline = pipeline;
|
|
12627
|
+
const personaOverride = personaOverrideFromUnknown(value.personaOverride);
|
|
12628
|
+
if (personaOverride !== null) view.personaOverride = personaOverride;
|
|
12629
|
+
const escalation = escalationFromUnknown(value.safety);
|
|
12630
|
+
if (escalation !== null) view.escalation = escalation;
|
|
12631
|
+
const autonomyEnforcement = autonomyEnforcementFromUnknown(value.autonomyEnforcement);
|
|
12632
|
+
if (autonomyEnforcement !== null) view.autonomyEnforcement = autonomyEnforcement;
|
|
12633
|
+
return view;
|
|
12799
12634
|
}
|
|
12800
|
-
function
|
|
12801
|
-
|
|
12802
|
-
throw new Error("Random bytes length must be >= 16");
|
|
12803
|
-
}
|
|
12804
|
-
if (!buf) {
|
|
12805
|
-
buf = new Uint8Array(16);
|
|
12806
|
-
offset = 0;
|
|
12807
|
-
} else {
|
|
12808
|
-
if (offset < 0 || offset + 16 > buf.length) {
|
|
12809
|
-
throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
|
|
12810
|
-
}
|
|
12811
|
-
}
|
|
12812
|
-
msecs ??= Date.now();
|
|
12813
|
-
seq ??= rnds[6] * 127 << 24 | rnds[7] << 16 | rnds[8] << 8 | rnds[9];
|
|
12814
|
-
buf[offset++] = msecs / 1099511627776 & 255;
|
|
12815
|
-
buf[offset++] = msecs / 4294967296 & 255;
|
|
12816
|
-
buf[offset++] = msecs / 16777216 & 255;
|
|
12817
|
-
buf[offset++] = msecs / 65536 & 255;
|
|
12818
|
-
buf[offset++] = msecs / 256 & 255;
|
|
12819
|
-
buf[offset++] = msecs & 255;
|
|
12820
|
-
buf[offset++] = 112 | seq >>> 28 & 15;
|
|
12821
|
-
buf[offset++] = seq >>> 20 & 255;
|
|
12822
|
-
buf[offset++] = 128 | seq >>> 14 & 63;
|
|
12823
|
-
buf[offset++] = seq >>> 6 & 255;
|
|
12824
|
-
buf[offset++] = seq << 2 & 255 | rnds[10] & 3;
|
|
12825
|
-
buf[offset++] = rnds[11];
|
|
12826
|
-
buf[offset++] = rnds[12];
|
|
12827
|
-
buf[offset++] = rnds[13];
|
|
12828
|
-
buf[offset++] = rnds[14];
|
|
12829
|
-
buf[offset++] = rnds[15];
|
|
12830
|
-
return buf;
|
|
12831
|
-
}
|
|
12832
|
-
var v7_default = v7;
|
|
12833
|
-
|
|
12834
|
-
// src/domains/session/migrations/index.ts
|
|
12835
|
-
init_esm_shims();
|
|
12836
|
-
function runMigrations(meta, sessionPath) {
|
|
12837
|
-
const from = meta.sessionFormatVersion ?? 1;
|
|
12838
|
-
if (from < CURRENT_SESSION_FORMAT_VERSION) {
|
|
12839
|
-
throw new Error(
|
|
12840
|
-
`session metadata has an unsupported format version (expected version 3, got ${from}): ${sessionPath}. Remove the session directory to start a new session.`
|
|
12841
|
-
);
|
|
12842
|
-
}
|
|
12843
|
-
return { migrated: false, from, to: from };
|
|
12635
|
+
function isRecord9(value) {
|
|
12636
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12844
12637
|
}
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
function newTurnId() {
|
|
12848
|
-
return v7_default();
|
|
12638
|
+
function finiteNumber(value) {
|
|
12639
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
12849
12640
|
}
|
|
12850
|
-
function
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
...input.parentSession !== void 0 ? { parentSession: input.parentSession } : {},
|
|
12858
|
-
...input.parentTurnId !== void 0 ? { parentTurnId: input.parentTurnId } : {}
|
|
12859
|
-
});
|
|
12860
|
-
return { meta, writer };
|
|
12641
|
+
function pipelineFromUnknown(value) {
|
|
12642
|
+
if (!isRecord9(value)) return null;
|
|
12643
|
+
const position = finiteNumber(value.position);
|
|
12644
|
+
const inputBytes = finiteNumber(value.inputBytes);
|
|
12645
|
+
if (position === null || inputBytes === null) return null;
|
|
12646
|
+
const fromRunId = typeof value.fromRunId === "string" ? value.fromRunId : null;
|
|
12647
|
+
return { fromRunId, position, inputBytes, inputTruncated: value.inputTruncated === true };
|
|
12861
12648
|
}
|
|
12862
|
-
function
|
|
12863
|
-
if (
|
|
12864
|
-
|
|
12649
|
+
function personaOverrideFromUnknown(value) {
|
|
12650
|
+
if (!isRecord9(value) || typeof value.promptHash !== "string" || value.promptHash.length === 0) return null;
|
|
12651
|
+
return { promptHash: value.promptHash };
|
|
12865
12652
|
}
|
|
12866
|
-
function
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
const {
|
|
12871
|
-
|
|
12653
|
+
function autonomyEnforcementFromUnknown(value) {
|
|
12654
|
+
if (!isRecord9(value)) return null;
|
|
12655
|
+
if (value.grade !== "mediated" && value.grade !== "approximated" && value.grade !== "bypassed") return null;
|
|
12656
|
+
if (typeof value.autonomy !== "string" || value.autonomy.length === 0) return null;
|
|
12657
|
+
const view = { grade: value.grade, autonomy: value.autonomy };
|
|
12658
|
+
if (typeof value.externalMode === "string" && value.externalMode.length > 0) view.externalMode = value.externalMode;
|
|
12659
|
+
if (typeof value.dangerousBypass === "boolean") view.dangerousBypass = value.dangerousBypass;
|
|
12660
|
+
return view;
|
|
12872
12661
|
}
|
|
12873
|
-
function
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12662
|
+
function escalationFromUnknown(safety) {
|
|
12663
|
+
if (!isRecord9(safety)) return null;
|
|
12664
|
+
const decisions = safety.decisions;
|
|
12665
|
+
if (!isRecord9(decisions)) return null;
|
|
12666
|
+
const requested = finiteNumber(decisions.escalationRequested);
|
|
12667
|
+
if (requested === null) return null;
|
|
12668
|
+
return {
|
|
12669
|
+
requested,
|
|
12670
|
+
approved: finiteNumber(decisions.escalationApproved) ?? 0,
|
|
12671
|
+
denied: finiteNumber(decisions.escalationDenied) ?? 0,
|
|
12672
|
+
timedOut: finiteNumber(decisions.escalationTimedOut) ?? 0
|
|
12880
12673
|
};
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12674
|
+
}
|
|
12675
|
+
function escalationCountsFrom(safety) {
|
|
12676
|
+
const decisions = safety?.decisions;
|
|
12677
|
+
if (decisions === void 0 || decisions.escalationRequested === void 0) return null;
|
|
12678
|
+
return {
|
|
12679
|
+
requested: decisions.escalationRequested,
|
|
12680
|
+
approved: decisions.escalationApproved ?? 0,
|
|
12681
|
+
denied: decisions.escalationDenied ?? 0,
|
|
12682
|
+
timedOut: decisions.escalationTimedOut ?? 0
|
|
12888
12683
|
};
|
|
12889
|
-
state.writer.appendEntry(entry, {
|
|
12890
|
-
treeNode: {
|
|
12891
|
-
id: record.id,
|
|
12892
|
-
parentId: record.parentId,
|
|
12893
|
-
at: record.at,
|
|
12894
|
-
kind: record.kind
|
|
12895
|
-
}
|
|
12896
|
-
});
|
|
12897
|
-
return record;
|
|
12898
12684
|
}
|
|
12899
|
-
function
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
const entry = { ...input, turnId, timestamp };
|
|
12903
|
-
if (!isSessionEntry(entry)) throw new Error(`session.appendEntry: invalid ${String(input.kind)} entry`);
|
|
12904
|
-
state.writer.appendEntry(entry);
|
|
12905
|
-
return entry;
|
|
12685
|
+
function formatPersonaHashPrefix(promptHash2) {
|
|
12686
|
+
if (promptHash2.length <= PERSONA_HASH_PREFIX_CHARS) return promptHash2;
|
|
12687
|
+
return `${promptHash2.slice(0, PERSONA_HASH_PREFIX_CHARS)}...`;
|
|
12906
12688
|
}
|
|
12907
|
-
function
|
|
12908
|
-
|
|
12909
|
-
|
|
12689
|
+
function provenanceTranscriptLines(view) {
|
|
12690
|
+
const lines = [];
|
|
12691
|
+
if (view.pipeline !== void 0) {
|
|
12692
|
+
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
12693
|
+
const source = fromRunId ?? "unknown";
|
|
12694
|
+
const truncation = inputTruncated ? "input truncated" : "not truncated";
|
|
12695
|
+
lines.push(`pipeline: step ${position}, input ${inputBytes} bytes from ${source} (${truncation})`);
|
|
12696
|
+
}
|
|
12697
|
+
if (view.personaOverride !== void 0) {
|
|
12698
|
+
lines.push(`persona override: prompt hash ${formatPersonaHashPrefix(view.personaOverride.promptHash)}`);
|
|
12699
|
+
}
|
|
12700
|
+
if (view.escalation !== void 0) {
|
|
12701
|
+
const { requested, approved, denied, timedOut } = view.escalation;
|
|
12702
|
+
lines.push(`escalations: ${requested} requested, ${approved} approved, ${denied} denied, ${timedOut} timed out`);
|
|
12703
|
+
}
|
|
12704
|
+
if (view.autonomyEnforcement !== void 0) {
|
|
12705
|
+
const { grade, autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
12706
|
+
const mode = externalMode !== void 0 ? ` mode=${externalMode}` : "";
|
|
12707
|
+
const bypass = dangerousBypass === true ? " dangerousBypass=true" : "";
|
|
12708
|
+
lines.push(`autonomy enforcement: ${grade} autonomy=${autonomy}${mode}${bypass}`);
|
|
12709
|
+
}
|
|
12710
|
+
return lines;
|
|
12711
|
+
}
|
|
12712
|
+
function provenanceCompactSuffix(view) {
|
|
12713
|
+
const parts = [];
|
|
12714
|
+
if (view.pipeline !== void 0) {
|
|
12715
|
+
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
12716
|
+
const from = fromRunId ?? "unknown";
|
|
12717
|
+
parts.push(`pipeline=step${position} from=${from} in=${inputBytes}b${inputTruncated ? " truncated" : ""}`);
|
|
12718
|
+
}
|
|
12719
|
+
if (view.personaOverride !== void 0) {
|
|
12720
|
+
parts.push(`persona=${formatPersonaHashPrefix(view.personaOverride.promptHash)}`);
|
|
12721
|
+
}
|
|
12722
|
+
if (view.escalation !== void 0) {
|
|
12723
|
+
const { requested, approved, denied, timedOut } = view.escalation;
|
|
12724
|
+
parts.push(`escalations=${requested}req/${approved}appr/${denied}deny/${timedOut}timeout`);
|
|
12725
|
+
}
|
|
12726
|
+
if (view.autonomyEnforcement !== void 0) {
|
|
12727
|
+
const { grade, autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
12728
|
+
const mode = externalMode !== void 0 ? `/${externalMode}` : "";
|
|
12729
|
+
const bypass = dangerousBypass === true ? "/bypass" : "";
|
|
12730
|
+
parts.push(`enforcement=${grade}:${autonomy}${mode}${bypass}`);
|
|
12910
12731
|
}
|
|
12911
|
-
|
|
12732
|
+
return parts.length === 0 ? "" : ` ${parts.join(" ")}`;
|
|
12912
12733
|
}
|
|
12913
12734
|
|
|
12914
|
-
// src/domains/
|
|
12735
|
+
// src/domains/evidence/run-trust.ts
|
|
12915
12736
|
init_esm_shims();
|
|
12916
12737
|
|
|
12917
|
-
// src/domains/
|
|
12738
|
+
// src/domains/evidence/trust-status.ts
|
|
12918
12739
|
init_esm_shims();
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12740
|
+
var TRUST_STATUS_VERSION = 1;
|
|
12741
|
+
var TRUST_STATUS_MAX_ARTIFACT_REFERENCES = 16;
|
|
12742
|
+
var TRUST_STATUS_MAX_IDENTIFIER_LENGTH = 512;
|
|
12743
|
+
var TRUST_STATUS_AXES = [
|
|
12744
|
+
"artifactIntegrity",
|
|
12745
|
+
"validationGrounding",
|
|
12746
|
+
"independentReview",
|
|
12747
|
+
"contextProvenance",
|
|
12748
|
+
"autonomyEnforcement",
|
|
12749
|
+
"completionEvidence"
|
|
12750
|
+
];
|
|
12751
|
+
var TRUST_STATUS_STATES = {
|
|
12752
|
+
artifactIntegrity: ["verified", "failed", "absent", "unknown", "not_applicable"],
|
|
12753
|
+
validationGrounding: ["validated", "failed", "ungrounded", "absent", "unknown", "not_applicable"],
|
|
12754
|
+
independentReview: ["passed", "failed", "inconclusive", "not_independent", "absent", "unknown", "not_applicable"],
|
|
12755
|
+
contextProvenance: ["recorded", "invalid", "absent", "unknown", "not_applicable"],
|
|
12756
|
+
autonomyEnforcement: ["enforced", "approximated", "bypassed", "absent", "unknown", "not_applicable"],
|
|
12757
|
+
completionEvidence: ["evidenced", "incomplete", "limited", "absent", "unknown", "not_applicable"]
|
|
12758
|
+
};
|
|
12759
|
+
var SELF_REPORTED_ARTIFACT_KINDS = /* @__PURE__ */ new Set([
|
|
12760
|
+
"finish_contract_evidence",
|
|
12761
|
+
"run_receipt"
|
|
12762
|
+
]);
|
|
12763
|
+
var AXIS_STATES = {
|
|
12764
|
+
artifactIntegrity: new Set(TRUST_STATUS_STATES.artifactIntegrity),
|
|
12765
|
+
validationGrounding: new Set(TRUST_STATUS_STATES.validationGrounding),
|
|
12766
|
+
independentReview: new Set(TRUST_STATUS_STATES.independentReview),
|
|
12767
|
+
contextProvenance: new Set(TRUST_STATUS_STATES.contextProvenance),
|
|
12768
|
+
autonomyEnforcement: new Set(TRUST_STATUS_STATES.autonomyEnforcement),
|
|
12769
|
+
completionEvidence: new Set(TRUST_STATUS_STATES.completionEvidence)
|
|
12770
|
+
};
|
|
12771
|
+
var AXIS_SOURCES = {
|
|
12772
|
+
artifactIntegrity: /* @__PURE__ */ new Set(["receipt_integrity_verification", "compatibility"]),
|
|
12773
|
+
validationGrounding: /* @__PURE__ */ new Set(["run_receipt", "evidence_bundle", "compatibility"]),
|
|
12774
|
+
independentReview: /* @__PURE__ */ new Set(["gate_decision", "compatibility"]),
|
|
12775
|
+
contextProvenance: /* @__PURE__ */ new Set(["run_receipt", "evidence_bundle", "compatibility"]),
|
|
12776
|
+
autonomyEnforcement: /* @__PURE__ */ new Set(["run_receipt", "compatibility"]),
|
|
12777
|
+
completionEvidence: /* @__PURE__ */ new Set(["finish_contract", "compatibility"])
|
|
12778
|
+
};
|
|
12779
|
+
var SOURCE_AUTHORITIES = {
|
|
12780
|
+
receipt_integrity_verification: /* @__PURE__ */ new Set(["clio"]),
|
|
12781
|
+
run_receipt: /* @__PURE__ */ new Set(["clio", "validator", "runtime", "external_system", "unknown"]),
|
|
12782
|
+
gate_decision: /* @__PURE__ */ new Set(["clio", "reviewer", "operator", "unknown"]),
|
|
12783
|
+
evidence_bundle: /* @__PURE__ */ new Set(["clio"]),
|
|
12784
|
+
finish_contract: /* @__PURE__ */ new Set(["clio"]),
|
|
12785
|
+
compatibility: /* @__PURE__ */ new Set(["clio", "unknown"])
|
|
12786
|
+
};
|
|
12787
|
+
var ABSENCE_REASONS = /* @__PURE__ */ new Set([
|
|
12788
|
+
"not_recorded",
|
|
12789
|
+
"not_observed",
|
|
12790
|
+
"artifact_missing",
|
|
12791
|
+
"historical_format"
|
|
12792
|
+
]);
|
|
12793
|
+
var SOURCE_KINDS = /* @__PURE__ */ new Set([
|
|
12794
|
+
"receipt_integrity_verification",
|
|
12795
|
+
"run_receipt",
|
|
12796
|
+
"gate_decision",
|
|
12797
|
+
"evidence_bundle",
|
|
12798
|
+
"finish_contract",
|
|
12799
|
+
"compatibility"
|
|
12800
|
+
]);
|
|
12801
|
+
var AUTHORITY_KINDS = /* @__PURE__ */ new Set([
|
|
12802
|
+
"clio",
|
|
12803
|
+
"validator",
|
|
12804
|
+
"reviewer",
|
|
12805
|
+
"operator",
|
|
12806
|
+
"runtime",
|
|
12807
|
+
"external_system",
|
|
12808
|
+
"unknown"
|
|
12809
|
+
]);
|
|
12810
|
+
var ARTIFACT_KINDS = /* @__PURE__ */ new Set([
|
|
12811
|
+
"run_receipt",
|
|
12812
|
+
"validation_result",
|
|
12813
|
+
"gate_decision",
|
|
12814
|
+
"briefing",
|
|
12815
|
+
"project_context",
|
|
12816
|
+
"autonomy_policy",
|
|
12817
|
+
"finish_contract_evidence",
|
|
12818
|
+
"evidence_bundle",
|
|
12819
|
+
"session_entry"
|
|
12820
|
+
]);
|
|
12821
|
+
function isRecord10(value) {
|
|
12822
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12965
12823
|
}
|
|
12966
|
-
function
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12824
|
+
function hasExactKeys(value, keys) {
|
|
12825
|
+
const expected = new Set(keys);
|
|
12826
|
+
return Object.keys(value).length === expected.size && Object.keys(value).every((key) => expected.has(key));
|
|
12827
|
+
}
|
|
12828
|
+
function isTrustStatusIdentifier(value) {
|
|
12829
|
+
if (typeof value !== "string" || value.trim().length === 0 || value.length > TRUST_STATUS_MAX_IDENTIFIER_LENGTH) {
|
|
12830
|
+
return false;
|
|
12972
12831
|
}
|
|
12973
|
-
|
|
12832
|
+
for (const character of value) {
|
|
12833
|
+
const codePoint = character.codePointAt(0);
|
|
12834
|
+
if (codePoint !== void 0 && (codePoint < 32 || codePoint === 127)) return false;
|
|
12835
|
+
}
|
|
12836
|
+
return true;
|
|
12974
12837
|
}
|
|
12975
|
-
|
|
12976
|
-
|
|
12977
|
-
|
|
12978
|
-
return
|
|
12979
|
-
id: entry.turnId,
|
|
12980
|
-
parentId: entry.parentTurnId,
|
|
12981
|
-
timestamp: entry.timestamp,
|
|
12982
|
-
treeKind: entry.kind === "message" ? entry.role : null,
|
|
12983
|
-
raw: entry
|
|
12984
|
-
};
|
|
12838
|
+
function compareArtifactReferences(left, right) {
|
|
12839
|
+
const leftKey = `${left.kind}\0${left.id}\0${left.digest?.value ?? ""}`;
|
|
12840
|
+
const rightKey = `${right.kind}\0${right.id}\0${right.digest?.value ?? ""}`;
|
|
12841
|
+
return leftKey < rightKey ? -1 : leftKey > rightKey ? 1 : 0;
|
|
12985
12842
|
}
|
|
12986
|
-
function
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12990
|
-
let current = byId.get(leafTurnId);
|
|
12991
|
-
if (!current) throw new Error(`session.fork: parent turn not found: ${leafTurnId}`);
|
|
12992
|
-
const seen = /* @__PURE__ */ new Set();
|
|
12993
|
-
while (current) {
|
|
12994
|
-
if (seen.has(current.id)) throw new Error(`session.fork: cycle in parent chain at ${current.id}`);
|
|
12995
|
-
seen.add(current.id);
|
|
12996
|
-
path2.unshift(current);
|
|
12997
|
-
if (current.parentId === null) break;
|
|
12998
|
-
const next = byId.get(current.parentId);
|
|
12999
|
-
if (!next) throw new Error(`session.fork: broken parent chain at ${current.id}`);
|
|
13000
|
-
current = next;
|
|
12843
|
+
function normalizeArtifactReference(value, path2) {
|
|
12844
|
+
if (!isRecord10(value)) throw new Error(`${path2} must be an object`);
|
|
12845
|
+
if (!hasExactKeys(value, value.digest === void 0 ? ["kind", "id"] : ["kind", "id", "digest"])) {
|
|
12846
|
+
throw new Error(`${path2} has unknown or missing fields`);
|
|
13001
12847
|
}
|
|
13002
|
-
|
|
13003
|
-
}
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
12848
|
+
if (typeof value.kind !== "string" || !ARTIFACT_KINDS.has(value.kind)) {
|
|
12849
|
+
throw new Error(`${path2}.kind is invalid`);
|
|
12850
|
+
}
|
|
12851
|
+
if (!isTrustStatusIdentifier(value.id)) throw new Error(`${path2}.id is invalid`);
|
|
12852
|
+
const reference = { kind: value.kind, id: value.id };
|
|
12853
|
+
if (value.digest !== void 0) {
|
|
12854
|
+
if (!isRecord10(value.digest) || !hasExactKeys(value.digest, ["algorithm", "value"]) || value.digest.algorithm !== "sha256" || typeof value.digest.value !== "string" || !/^[a-f0-9]{64}$/u.test(value.digest.value)) {
|
|
12855
|
+
throw new Error(`${path2}.digest is invalid`);
|
|
12856
|
+
}
|
|
12857
|
+
reference.digest = { algorithm: "sha256", value: value.digest.value };
|
|
12858
|
+
}
|
|
12859
|
+
return reference;
|
|
13011
12860
|
}
|
|
13012
|
-
function
|
|
13013
|
-
if (
|
|
13014
|
-
|
|
13015
|
-
}
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
12861
|
+
function normalizeAttributedStatus(axis, value) {
|
|
12862
|
+
if (!hasExactKeys(value, ["state", "source", "authority", "artifacts"])) {
|
|
12863
|
+
throw new Error(`${axis} has unknown or missing fields`);
|
|
12864
|
+
}
|
|
12865
|
+
if (!isRecord10(value.source) || !hasExactKeys(value.source, ["kind", "id"])) {
|
|
12866
|
+
throw new Error(`${axis}.source is invalid`);
|
|
12867
|
+
}
|
|
12868
|
+
if (typeof value.source.kind !== "string" || !SOURCE_KINDS.has(value.source.kind) || !AXIS_SOURCES[axis].has(value.source.kind) || !isTrustStatusIdentifier(value.source.id)) {
|
|
12869
|
+
throw new Error(`${axis}.source is invalid`);
|
|
12870
|
+
}
|
|
12871
|
+
if (!isRecord10(value.authority) || !hasExactKeys(value.authority, ["kind", "id"])) {
|
|
12872
|
+
throw new Error(`${axis}.authority is invalid`);
|
|
12873
|
+
}
|
|
12874
|
+
if (typeof value.authority.kind !== "string" || !AUTHORITY_KINDS.has(value.authority.kind) || !SOURCE_AUTHORITIES[value.source.kind].has(
|
|
12875
|
+
value.authority.kind
|
|
12876
|
+
) || !isTrustStatusIdentifier(value.authority.id)) {
|
|
12877
|
+
throw new Error(`${axis}.authority is invalid`);
|
|
12878
|
+
}
|
|
12879
|
+
if (value.source.kind === "compatibility" && value.state !== "unknown" && value.state !== "not_applicable") {
|
|
12880
|
+
throw new Error(`${axis} compatibility source cannot establish ${value.state}`);
|
|
12881
|
+
}
|
|
12882
|
+
if (!Array.isArray(value.artifacts) || value.artifacts.length > TRUST_STATUS_MAX_ARTIFACT_REFERENCES) {
|
|
12883
|
+
throw new Error(`${axis}.artifacts exceeds the bounded reference list`);
|
|
12884
|
+
}
|
|
12885
|
+
const artifacts = value.artifacts.map(
|
|
12886
|
+
(entry, index) => normalizeArtifactReference(entry, `${axis}.artifacts[${index}]`)
|
|
13026
12887
|
);
|
|
12888
|
+
artifacts.sort(compareArtifactReferences);
|
|
12889
|
+
for (let index = 1; index < artifacts.length; index += 1) {
|
|
12890
|
+
if (compareArtifactReferences(
|
|
12891
|
+
artifacts[index - 1],
|
|
12892
|
+
artifacts[index]
|
|
12893
|
+
) === 0) {
|
|
12894
|
+
throw new Error(`${axis}.artifacts contains a duplicate reference`);
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
13027
12897
|
return {
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
12898
|
+
state: value.state,
|
|
12899
|
+
source: { kind: value.source.kind, id: value.source.id },
|
|
12900
|
+
authority: { kind: value.authority.kind, id: value.authority.id },
|
|
12901
|
+
artifacts
|
|
13031
12902
|
};
|
|
13032
12903
|
}
|
|
13033
|
-
function
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
model: parentMeta.model,
|
|
13041
|
-
target: parentMeta.target,
|
|
13042
|
-
initialEntries: branch.entries,
|
|
13043
|
-
initialTree: branch.tree,
|
|
13044
|
-
parentSession: branch.parentCurrentPath,
|
|
13045
|
-
parentTurnId: input.parentTurnId
|
|
13046
|
-
});
|
|
13047
|
-
enrichForkMeta(next.meta, parentMeta.id, input.parentTurnId);
|
|
13048
|
-
void input.from.writer.close();
|
|
13049
|
-
return { next, parentMeta, nodes: branch.tree };
|
|
13050
|
-
}
|
|
13051
|
-
|
|
13052
|
-
// src/domains/session/tree/manager.ts
|
|
13053
|
-
init_esm_shims();
|
|
13054
|
-
import { existsSync as existsSync15, renameSync as renameSync5, rmSync as rmSync4 } from "node:fs";
|
|
13055
|
-
import { dirname as dirname3, join as join16 } from "node:path";
|
|
13056
|
-
function readTreeBundle(sessionId) {
|
|
13057
|
-
const reader = openSession(sessionId);
|
|
13058
|
-
const meta = reader.meta();
|
|
13059
|
-
const paths = sessionPaths(meta);
|
|
13060
|
-
const nodes = [...reader.tree()];
|
|
13061
|
-
const entries = collectSessionEntries(reader.turns(), paths.current);
|
|
13062
|
-
const labels = resolveLabelMap(entries);
|
|
13063
|
-
return { sessionId, meta, nodes, entries, labels };
|
|
13064
|
-
}
|
|
13065
|
-
function resolveLabelMap(entries) {
|
|
13066
|
-
const out = /* @__PURE__ */ new Map();
|
|
13067
|
-
for (const entry of entries) {
|
|
13068
|
-
const info = labelFields(entry);
|
|
13069
|
-
if (!info) continue;
|
|
13070
|
-
const existing = out.get(info.targetTurnId);
|
|
13071
|
-
if (existing && existing.timestamp > info.timestamp) continue;
|
|
13072
|
-
if (info.label === void 0 || info.label === "") {
|
|
13073
|
-
out.set(info.targetTurnId, { label: "", timestamp: info.timestamp });
|
|
13074
|
-
continue;
|
|
12904
|
+
function normalizeAxis(axis, value) {
|
|
12905
|
+
if (!isRecord10(value) || typeof value.state !== "string" || !AXIS_STATES[axis].has(value.state)) {
|
|
12906
|
+
throw new Error(`${axis}.state is invalid`);
|
|
12907
|
+
}
|
|
12908
|
+
if (value.state === "absent") {
|
|
12909
|
+
if (!hasExactKeys(value, ["state", "reason"]) || typeof value.reason !== "string" || !ABSENCE_REASONS.has(value.reason)) {
|
|
12910
|
+
throw new Error(`${axis} absent state is invalid`);
|
|
13075
12911
|
}
|
|
13076
|
-
|
|
12912
|
+
return { state: "absent", reason: value.reason };
|
|
13077
12913
|
}
|
|
13078
|
-
return
|
|
13079
|
-
}
|
|
13080
|
-
function labelFields(entry) {
|
|
13081
|
-
if (entry.kind === "label") return entry;
|
|
13082
|
-
if (entry.kind !== "sessionInfo") return null;
|
|
13083
|
-
const info = entry;
|
|
13084
|
-
if (!info.targetTurnId) return null;
|
|
13085
|
-
const out = {
|
|
13086
|
-
targetTurnId: info.targetTurnId,
|
|
13087
|
-
timestamp: info.timestamp
|
|
13088
|
-
};
|
|
13089
|
-
if (info.label !== void 0) out.label = info.label;
|
|
13090
|
-
return out;
|
|
13091
|
-
}
|
|
13092
|
-
function appendEntryToSessionFile(sessionId, entry) {
|
|
13093
|
-
const meta = readSessionMeta(sessionId);
|
|
13094
|
-
const paths = sessionPaths(meta);
|
|
13095
|
-
appendSessionFileEntry(paths.current, entry);
|
|
13096
|
-
}
|
|
13097
|
-
function removeSessionDirectory(sessionId) {
|
|
13098
|
-
const meta = readSessionMeta(sessionId);
|
|
13099
|
-
const paths = sessionPaths(meta);
|
|
13100
|
-
const dir = dirname3(paths.meta);
|
|
13101
|
-
rmSync4(dir, { recursive: true, force: true });
|
|
13102
|
-
}
|
|
13103
|
-
function tombstoneSession(sessionId) {
|
|
13104
|
-
const meta = readSessionMeta(sessionId);
|
|
13105
|
-
const paths = sessionPaths(meta);
|
|
13106
|
-
if (!existsSync15(paths.meta)) return;
|
|
13107
|
-
const tombstone = join16(dirname3(paths.meta), "meta.deleted.json");
|
|
13108
|
-
renameSync5(paths.meta, tombstone);
|
|
13109
|
-
}
|
|
13110
|
-
|
|
13111
|
-
// src/domains/session/tree/navigator.ts
|
|
13112
|
-
init_esm_shims();
|
|
13113
|
-
function pickMeta(meta) {
|
|
13114
|
-
const out = {
|
|
13115
|
-
id: meta.id,
|
|
13116
|
-
cwd: meta.cwd,
|
|
13117
|
-
createdAt: meta.createdAt,
|
|
13118
|
-
endedAt: meta.endedAt,
|
|
13119
|
-
model: meta.model,
|
|
13120
|
-
target: meta.target
|
|
13121
|
-
};
|
|
13122
|
-
if (meta.parentSessionId !== void 0) out.parentSessionId = meta.parentSessionId;
|
|
13123
|
-
if (meta.parentTurnId !== void 0) out.parentTurnId = meta.parentTurnId;
|
|
13124
|
-
return out;
|
|
12914
|
+
return normalizeAttributedStatus(axis, value);
|
|
13125
12915
|
}
|
|
13126
|
-
function
|
|
13127
|
-
if (
|
|
13128
|
-
|
|
13129
|
-
for (const node of nodes) {
|
|
13130
|
-
if (node.parentId) hasChild.add(node.parentId);
|
|
12916
|
+
function normalizeTrustStatus(value) {
|
|
12917
|
+
if (!isRecord10(value) || !hasExactKeys(value, ["version", ...TRUST_STATUS_AXES])) {
|
|
12918
|
+
throw new Error("trust status has unknown or missing fields");
|
|
13131
12919
|
}
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
12920
|
+
if (value.version !== TRUST_STATUS_VERSION) throw new Error("trust status version is invalid");
|
|
12921
|
+
return {
|
|
12922
|
+
version: TRUST_STATUS_VERSION,
|
|
12923
|
+
artifactIntegrity: normalizeAxis("artifactIntegrity", value.artifactIntegrity),
|
|
12924
|
+
validationGrounding: normalizeAxis("validationGrounding", value.validationGrounding),
|
|
12925
|
+
independentReview: normalizeAxis("independentReview", value.independentReview),
|
|
12926
|
+
contextProvenance: normalizeAxis("contextProvenance", value.contextProvenance),
|
|
12927
|
+
autonomyEnforcement: normalizeAxis("autonomyEnforcement", value.autonomyEnforcement),
|
|
12928
|
+
completionEvidence: normalizeAxis("completionEvidence", value.completionEvidence)
|
|
12929
|
+
};
|
|
12930
|
+
}
|
|
12931
|
+
function absentTrustStatus(reason) {
|
|
12932
|
+
return { state: "absent", reason };
|
|
12933
|
+
}
|
|
12934
|
+
function composeTrustStatus(...projections) {
|
|
12935
|
+
const axes = {
|
|
12936
|
+
artifactIntegrity: absentTrustStatus("not_recorded"),
|
|
12937
|
+
validationGrounding: absentTrustStatus("not_recorded"),
|
|
12938
|
+
independentReview: absentTrustStatus("not_recorded"),
|
|
12939
|
+
contextProvenance: absentTrustStatus("not_recorded"),
|
|
12940
|
+
autonomyEnforcement: absentTrustStatus("not_recorded"),
|
|
12941
|
+
completionEvidence: absentTrustStatus("not_recorded")
|
|
12942
|
+
};
|
|
12943
|
+
for (const projection of projections) {
|
|
12944
|
+
if (projection.artifactIntegrity !== void 0) axes.artifactIntegrity = projection.artifactIntegrity;
|
|
12945
|
+
if (projection.validationGrounding !== void 0) axes.validationGrounding = projection.validationGrounding;
|
|
12946
|
+
if (projection.independentReview !== void 0) axes.independentReview = projection.independentReview;
|
|
12947
|
+
if (projection.contextProvenance !== void 0) axes.contextProvenance = projection.contextProvenance;
|
|
12948
|
+
if (projection.autonomyEnforcement !== void 0) axes.autonomyEnforcement = projection.autonomyEnforcement;
|
|
12949
|
+
if (projection.completionEvidence !== void 0) axes.completionEvidence = projection.completionEvidence;
|
|
12950
|
+
}
|
|
12951
|
+
return normalizeTrustStatus({ version: TRUST_STATUS_VERSION, ...axes });
|
|
12952
|
+
}
|
|
12953
|
+
function sha256Reference(kind, id, digest) {
|
|
12954
|
+
const reference = { kind, id };
|
|
12955
|
+
if (digest !== void 0 && /^[a-f0-9]{64}$/u.test(digest)) {
|
|
12956
|
+
reference.digest = { algorithm: "sha256", value: digest };
|
|
12957
|
+
}
|
|
12958
|
+
return reference;
|
|
12959
|
+
}
|
|
12960
|
+
function receiptReference(receipt) {
|
|
12961
|
+
return sha256Reference("run_receipt", receipt.runId, receipt.integrity?.digest);
|
|
12962
|
+
}
|
|
12963
|
+
function attributed(state, source, authority, artifacts) {
|
|
12964
|
+
return { state, source, authority, artifacts: [...artifacts].sort(compareArtifactReferences) };
|
|
12965
|
+
}
|
|
12966
|
+
function receiptSource(receipt) {
|
|
12967
|
+
return { kind: "run_receipt", id: receipt.runId };
|
|
12968
|
+
}
|
|
12969
|
+
function compatibilitySource(receipt, field) {
|
|
12970
|
+
return { kind: "compatibility", id: `run_receipt:${receipt.runId}:${field}` };
|
|
12971
|
+
}
|
|
12972
|
+
var DISPATCH_AUTHORITY = { kind: "clio", id: "dispatch" };
|
|
12973
|
+
var COMPATIBILITY_AUTHORITY = { kind: "unknown", id: "historical-persisted-format" };
|
|
12974
|
+
function adaptReceiptIntegrityStatus(receipt, verification) {
|
|
12975
|
+
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
12976
|
+
const artifacts = [receiptReference(receipt)];
|
|
12977
|
+
if (verification === void 0 || verification.ok && receipt.integrity === void 0) {
|
|
12978
|
+
return attributed(
|
|
12979
|
+
"unknown",
|
|
12980
|
+
{
|
|
12981
|
+
kind: "compatibility",
|
|
12982
|
+
id: `run_receipt:${receipt.runId}:${receipt.integrity === void 0 ? "integrity-missing" : "integrity-unchecked"}`
|
|
12983
|
+
},
|
|
12984
|
+
COMPATIBILITY_AUTHORITY,
|
|
12985
|
+
artifacts
|
|
12986
|
+
);
|
|
13136
12987
|
}
|
|
13137
|
-
return
|
|
12988
|
+
return attributed(
|
|
12989
|
+
verification.ok ? "verified" : "failed",
|
|
12990
|
+
{ kind: "receipt_integrity_verification", id: receipt.runId },
|
|
12991
|
+
{ kind: "clio", id: "receipt-integrity" },
|
|
12992
|
+
artifacts
|
|
12993
|
+
);
|
|
13138
12994
|
}
|
|
13139
|
-
function
|
|
13140
|
-
const
|
|
13141
|
-
for (const
|
|
13142
|
-
|
|
13143
|
-
id: node.id,
|
|
13144
|
-
parentId: node.parentId,
|
|
13145
|
-
at: node.at,
|
|
13146
|
-
kind: node.kind,
|
|
13147
|
-
children: []
|
|
13148
|
-
};
|
|
13149
|
-
const resolved = input.labels.get(node.id);
|
|
13150
|
-
if (resolved && resolved.label !== "") entry.label = resolved.label;
|
|
13151
|
-
const preview = input.previews?.get(node.id);
|
|
13152
|
-
if (preview !== void 0 && preview.length > 0) entry.preview = preview;
|
|
13153
|
-
nodesById[node.id] = entry;
|
|
13154
|
-
}
|
|
13155
|
-
const rootIds = [];
|
|
13156
|
-
for (const node of input.nodes) {
|
|
13157
|
-
const parent = node.parentId ? nodesById[node.parentId] : void 0;
|
|
13158
|
-
if (!parent) {
|
|
13159
|
-
rootIds.push(node.id);
|
|
13160
|
-
} else {
|
|
13161
|
-
parent.children.push(node.id);
|
|
13162
|
-
}
|
|
12995
|
+
function validationArtifacts(receipt) {
|
|
12996
|
+
const artifacts = [receiptReference(receipt)];
|
|
12997
|
+
for (const fact of receipt.quality?.typedValidations ?? []) {
|
|
12998
|
+
artifacts.push(sha256Reference("validation_result", fact.sourceId, fact.validatorDigest));
|
|
13163
12999
|
}
|
|
13164
|
-
const
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
if (!na || !nb) return a < b ? -1 : a > b ? 1 : 0;
|
|
13168
|
-
if (na.at === nb.at) return na.id < nb.id ? -1 : na.id > nb.id ? 1 : 0;
|
|
13169
|
-
return na.at < nb.at ? -1 : 1;
|
|
13170
|
-
};
|
|
13171
|
-
rootIds.sort(byTime);
|
|
13172
|
-
for (const key of Object.keys(nodesById)) {
|
|
13173
|
-
const entry = nodesById[key];
|
|
13174
|
-
if (entry) entry.children.sort(byTime);
|
|
13000
|
+
const resultContract = receipt.quality?.resultContract;
|
|
13001
|
+
if (resultContract !== null && resultContract !== void 0) {
|
|
13002
|
+
artifacts.push(sha256Reference("validation_result", resultContract.sourceId, resultContract.validatorDigest));
|
|
13175
13003
|
}
|
|
13176
|
-
|
|
13177
|
-
return {
|
|
13178
|
-
sessionId: input.meta.id,
|
|
13179
|
-
meta: pickMeta(input.meta),
|
|
13180
|
-
leafId,
|
|
13181
|
-
nodesById,
|
|
13182
|
-
rootIds
|
|
13183
|
-
};
|
|
13184
|
-
}
|
|
13185
|
-
|
|
13186
|
-
// src/domains/session/tree/preview.ts
|
|
13187
|
-
init_esm_shims();
|
|
13188
|
-
var TURN_PREVIEW_MAX_CHARS = 60;
|
|
13189
|
-
var ESC = String.fromCharCode(27);
|
|
13190
|
-
var ANSI_CSI_RE = new RegExp(`${ESC}\\[[0-9;?]*[ -/]*[@-~]`, "g");
|
|
13191
|
-
var ANSI_FALLBACK_RE = new RegExp(`${ESC}[@-_]`, "g");
|
|
13192
|
-
function stripAnsi(text) {
|
|
13193
|
-
return text.replace(ANSI_CSI_RE, "").replace(ANSI_FALLBACK_RE, "");
|
|
13194
|
-
}
|
|
13195
|
-
function collapseSingleLine(text) {
|
|
13196
|
-
return text.replace(/\s+/g, " ").trim();
|
|
13004
|
+
return uniqueBoundedReferences(artifacts);
|
|
13197
13005
|
}
|
|
13198
|
-
function
|
|
13199
|
-
|
|
13006
|
+
function qualityHasFailure(quality) {
|
|
13007
|
+
if (quality === void 0) return false;
|
|
13008
|
+
if (quality.typedValidations.some((fact) => !fact.passed)) return true;
|
|
13009
|
+
return quality.resultContract?.conformance === "fail" || quality.resultContract?.quality === "fail";
|
|
13200
13010
|
}
|
|
13201
|
-
function
|
|
13202
|
-
if (
|
|
13203
|
-
if (
|
|
13204
|
-
return
|
|
13011
|
+
function qualityHasValidation(quality) {
|
|
13012
|
+
if (quality === void 0) return false;
|
|
13013
|
+
if (quality.typedValidations.some((fact) => fact.passed)) return true;
|
|
13014
|
+
return quality.resultContract?.quality === "pass";
|
|
13205
13015
|
}
|
|
13206
|
-
function
|
|
13207
|
-
if (
|
|
13208
|
-
|
|
13209
|
-
return sanitized.length > 0 ? sanitized : null;
|
|
13016
|
+
function verificationStatus(verification, receipt, artifacts) {
|
|
13017
|
+
if (verification.state === "verified") {
|
|
13018
|
+
return attributed("validated", receiptSource(receipt), { kind: "validator", id: verification.basis }, artifacts);
|
|
13210
13019
|
}
|
|
13211
|
-
if (
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
const sanitized = sanitize(obj.text);
|
|
13215
|
-
if (sanitized.length > 0) return sanitized;
|
|
13216
|
-
}
|
|
13217
|
-
if (Array.isArray(obj.content)) {
|
|
13218
|
-
const parts = [];
|
|
13219
|
-
for (const block of obj.content) {
|
|
13220
|
-
if (!block || typeof block !== "object") continue;
|
|
13221
|
-
const b = block;
|
|
13222
|
-
if (b.type === "text" && typeof b.text === "string") parts.push(b.text);
|
|
13223
|
-
}
|
|
13224
|
-
if (parts.length > 0) {
|
|
13225
|
-
const sanitized = sanitize(parts.join(" "));
|
|
13226
|
-
if (sanitized.length > 0) return sanitized;
|
|
13227
|
-
}
|
|
13020
|
+
if (verification.state === "unverified") return absentTrustStatus("not_observed");
|
|
13021
|
+
if (verification.state === "not_applicable") {
|
|
13022
|
+
return attributed("not_applicable", receiptSource(receipt), DISPATCH_AUTHORITY, artifacts);
|
|
13228
13023
|
}
|
|
13229
|
-
return
|
|
13024
|
+
return attributed(
|
|
13025
|
+
"unknown",
|
|
13026
|
+
receiptSource(receipt),
|
|
13027
|
+
verification.basis === "acp-external-unobserved" ? { kind: "external_system", id: "acp-delegation" } : COMPATIBILITY_AUTHORITY,
|
|
13028
|
+
artifacts
|
|
13029
|
+
);
|
|
13230
13030
|
}
|
|
13231
|
-
function
|
|
13232
|
-
if (
|
|
13233
|
-
const
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
write: ["path"],
|
|
13237
|
-
edit: ["path"],
|
|
13238
|
-
bash: ["command"],
|
|
13239
|
-
code_nav: ["query", "mode"],
|
|
13240
|
-
git: ["op"],
|
|
13241
|
-
verify: ["check"],
|
|
13242
|
-
grep: ["pattern", "query"],
|
|
13243
|
-
search: ["query", "pattern"],
|
|
13244
|
-
web_fetch: ["url"],
|
|
13245
|
-
web_search: ["query"]
|
|
13246
|
-
};
|
|
13247
|
-
const order = preferred[toolName] ?? [];
|
|
13248
|
-
for (const key of order) {
|
|
13249
|
-
const value = a[key];
|
|
13250
|
-
if (typeof value === "string" && value.length > 0) return sanitize(value);
|
|
13251
|
-
if (typeof value === "number") return String(value);
|
|
13031
|
+
function adaptRunReceiptValidationStatus(receipt) {
|
|
13032
|
+
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13033
|
+
const artifacts = validationArtifacts(receipt);
|
|
13034
|
+
if (qualityHasFailure(receipt.quality)) {
|
|
13035
|
+
return attributed("failed", receiptSource(receipt), { kind: "validator", id: "receipt-quality" }, artifacts);
|
|
13252
13036
|
}
|
|
13253
|
-
|
|
13254
|
-
|
|
13255
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
13037
|
+
if ((receipt.validationGrounding?.ungrounded.length ?? 0) > 0 || receipt.validationGrounding !== void 0 && receipt.validationGrounding.claimed > receipt.validationGrounding.grounded) {
|
|
13038
|
+
return attributed("ungrounded", receiptSource(receipt), { kind: "validator", id: "command-grounding" }, artifacts);
|
|
13256
13039
|
}
|
|
13257
|
-
|
|
13258
|
-
}
|
|
13259
|
-
function extractToolCall(payload) {
|
|
13260
|
-
if (!payload || typeof payload !== "object") return null;
|
|
13261
|
-
const p = payload;
|
|
13262
|
-
const toolName = typeof p.name === "string" ? p.name : typeof p.toolName === "string" ? p.toolName : null;
|
|
13263
|
-
if (!toolName) return null;
|
|
13264
|
-
const args = p.args !== void 0 ? p.args : p.arguments ?? p.input;
|
|
13265
|
-
return { toolName, args };
|
|
13266
|
-
}
|
|
13267
|
-
function extractToolResult(payload) {
|
|
13268
|
-
if (!payload || typeof payload !== "object") return null;
|
|
13269
|
-
const p = payload;
|
|
13270
|
-
if (!("toolCallId" in p) && !("result" in p) && !("isError" in p)) return null;
|
|
13271
|
-
const isError = p.isError === true;
|
|
13272
|
-
let text = "";
|
|
13273
|
-
const result = p.result;
|
|
13274
|
-
if (typeof result === "string") text = result;
|
|
13275
|
-
else if (result && typeof result === "object") {
|
|
13276
|
-
const r = result;
|
|
13277
|
-
if (Array.isArray(r.content)) {
|
|
13278
|
-
const parts = [];
|
|
13279
|
-
for (const block of r.content) {
|
|
13280
|
-
if (!block || typeof block !== "object") continue;
|
|
13281
|
-
const b = block;
|
|
13282
|
-
if (b.type === "text" && typeof b.text === "string") parts.push(b.text);
|
|
13283
|
-
}
|
|
13284
|
-
text = parts.join(" ");
|
|
13285
|
-
} else if (typeof r.text === "string") {
|
|
13286
|
-
text = r.text;
|
|
13287
|
-
}
|
|
13040
|
+
if (qualityHasValidation(receipt.quality)) {
|
|
13041
|
+
return attributed("validated", receiptSource(receipt), { kind: "validator", id: "receipt-quality" }, artifacts);
|
|
13288
13042
|
}
|
|
13289
|
-
if (
|
|
13290
|
-
return
|
|
13043
|
+
if (receipt.verification !== void 0) return verificationStatus(receipt.verification, receipt, artifacts);
|
|
13044
|
+
return attributed("unknown", compatibilitySource(receipt, "verification"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13291
13045
|
}
|
|
13292
|
-
function
|
|
13293
|
-
|
|
13294
|
-
const sr = payload.stopReason;
|
|
13295
|
-
if (sr === "aborted") return "(aborted)";
|
|
13296
|
-
if (sr === "error") return "(error)";
|
|
13297
|
-
return null;
|
|
13046
|
+
function validBriefing(briefing) {
|
|
13047
|
+
return Number.isSafeInteger(briefing.bytes) && briefing.bytes >= 0 && /^[a-f0-9]{64}$/u.test(briefing.contentHash);
|
|
13298
13048
|
}
|
|
13299
|
-
function
|
|
13300
|
-
|
|
13301
|
-
switch (turn.kind) {
|
|
13302
|
-
case "user": {
|
|
13303
|
-
const text = extractPlainText(turn.payload);
|
|
13304
|
-
return text === null ? "(empty)" : clamp(text, budget);
|
|
13305
|
-
}
|
|
13306
|
-
case "assistant": {
|
|
13307
|
-
const stop = assistantStopMarker(turn.payload);
|
|
13308
|
-
const text = extractPlainText(turn.payload);
|
|
13309
|
-
if (text !== null) return clamp(text, budget);
|
|
13310
|
-
if (stop !== null) return stop;
|
|
13311
|
-
if (turn.payload && typeof turn.payload === "object" && Array.isArray(turn.payload.content)) {
|
|
13312
|
-
const content = turn.payload.content;
|
|
13313
|
-
const toolCalls = content.filter(
|
|
13314
|
-
(b) => b && typeof b === "object" && b.type === "toolCall"
|
|
13315
|
-
);
|
|
13316
|
-
if (toolCalls.length > 0) {
|
|
13317
|
-
const names = toolCalls.map((b) => b.name).filter((n) => typeof n === "string");
|
|
13318
|
-
if (names.length > 0) return clamp(`(tool calls) ${names.join(", ")}`, budget);
|
|
13319
|
-
}
|
|
13320
|
-
}
|
|
13321
|
-
return "(empty)";
|
|
13322
|
-
}
|
|
13323
|
-
case "tool_call": {
|
|
13324
|
-
const call = extractToolCall(turn.payload);
|
|
13325
|
-
if (!call) return "(empty)";
|
|
13326
|
-
const arg = pickToolArg(call.toolName, call.args);
|
|
13327
|
-
const inner = arg.length > 0 ? `"${clamp(arg, Math.max(8, budget - call.toolName.length - 4))}"` : "";
|
|
13328
|
-
const composed = `${call.toolName}(${inner})`;
|
|
13329
|
-
return clamp(composed, budget);
|
|
13330
|
-
}
|
|
13331
|
-
case "tool_result": {
|
|
13332
|
-
const result = extractToolResult(turn.payload);
|
|
13333
|
-
if (!result) return "(empty)";
|
|
13334
|
-
const status = result.isError ? "err" : "ok";
|
|
13335
|
-
const head = `[${status}]`;
|
|
13336
|
-
if (result.text.length === 0) return head;
|
|
13337
|
-
const remaining = Math.max(4, budget - head.length - 1);
|
|
13338
|
-
return `${head} ${clamp(result.text, remaining)}`;
|
|
13339
|
-
}
|
|
13340
|
-
case "system": {
|
|
13341
|
-
const text = extractPlainText(turn.payload);
|
|
13342
|
-
return text === null ? "(system)" : clamp(text, budget);
|
|
13343
|
-
}
|
|
13344
|
-
case "checkpoint":
|
|
13345
|
-
return "(checkpoint)";
|
|
13346
|
-
default:
|
|
13347
|
-
return `(${String(turn.kind)})`;
|
|
13348
|
-
}
|
|
13049
|
+
function validBoundedProjectContext(context) {
|
|
13050
|
+
return context.tier === "bounded" && Number.isSafeInteger(context.chars) && (context.chars ?? -1) >= 0 && typeof context.contentHash === "string" && /^[a-f0-9]{64}$/u.test(context.contentHash);
|
|
13349
13051
|
}
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
|
|
13354
|
-
let currentTurnId = null;
|
|
13355
|
-
function emitPark(sessionId, reason) {
|
|
13356
|
-
context.bus.emit(BusChannels.SessionParked, { sessionId, reason, at: Date.now() });
|
|
13357
|
-
}
|
|
13358
|
-
function emitResume(sessionId, via) {
|
|
13359
|
-
context.bus.emit(BusChannels.SessionResumed, { sessionId, via, at: Date.now() });
|
|
13360
|
-
}
|
|
13361
|
-
function emitTurnSwitched(sessionId, turnId) {
|
|
13362
|
-
context.bus.emit(BusChannels.SessionTurnSwitched, { sessionId, turnId, at: Date.now() });
|
|
13363
|
-
}
|
|
13364
|
-
function resolveLeafOnOpen(resumed) {
|
|
13365
|
-
const pinned = resumed.state.meta.pinnedLeafTurnId;
|
|
13366
|
-
if (pinned && resumed.nodes.some((node) => node.id === pinned)) return pinned;
|
|
13367
|
-
return computeLeafId(resumed.nodes);
|
|
13368
|
-
}
|
|
13369
|
-
async function closeCurrent(reason = "close") {
|
|
13370
|
-
if (!state) return;
|
|
13371
|
-
const s = state;
|
|
13372
|
-
emitPark(s.meta.id, reason);
|
|
13373
|
-
state = null;
|
|
13374
|
-
currentTurnId = null;
|
|
13375
|
-
await s.writer.close();
|
|
13376
|
-
}
|
|
13377
|
-
async function flushIfCurrent(sessionId) {
|
|
13378
|
-
if (state?.meta.id === sessionId) {
|
|
13379
|
-
await state.writer.persistTree();
|
|
13380
|
-
}
|
|
13381
|
-
}
|
|
13382
|
-
function structuralTreeNodes(entries, previews) {
|
|
13383
|
-
const nodes = [];
|
|
13384
|
-
for (const entry of entries) {
|
|
13385
|
-
if (entry.kind === "compactionSummary") {
|
|
13386
|
-
nodes.push({ id: entry.turnId, parentId: entry.parentTurnId, at: entry.timestamp, kind: "compaction" });
|
|
13387
|
-
const summarized = entry.messagesSummarized === void 0 ? "history" : `${entry.messagesSummarized} entries`;
|
|
13388
|
-
const after = entry.tokensAfter === void 0 ? "" : ` -> ~${entry.tokensAfter}`;
|
|
13389
|
-
previews.set(entry.turnId, `${summarized} summarized, ~${entry.tokensBefore}${after} tokens`);
|
|
13390
|
-
continue;
|
|
13391
|
-
}
|
|
13392
|
-
if (entry.kind === "branchSummary") {
|
|
13393
|
-
nodes.push({ id: entry.turnId, parentId: entry.parentTurnId, at: entry.timestamp, kind: "branch" });
|
|
13394
|
-
const text = entry.summary.split("\n", 1)[0] ?? "";
|
|
13395
|
-
previews.set(
|
|
13396
|
-
entry.turnId,
|
|
13397
|
-
text.length > 0 ? `returned from ${entry.fromTurnId}: ${text}` : `returned from ${entry.fromTurnId}`
|
|
13398
|
-
);
|
|
13399
|
-
}
|
|
13400
|
-
}
|
|
13401
|
-
return nodes;
|
|
13052
|
+
function contextArtifacts(receipt) {
|
|
13053
|
+
const artifacts = [receiptReference(receipt)];
|
|
13054
|
+
if (receipt.briefing !== void 0 && validBriefing(receipt.briefing)) {
|
|
13055
|
+
artifacts.push(sha256Reference("briefing", `${receipt.runId}:briefing`, receipt.briefing.contentHash));
|
|
13402
13056
|
}
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
let structural = [];
|
|
13408
|
-
try {
|
|
13409
|
-
for (const entry of bundle.entries) {
|
|
13410
|
-
if (entry.kind !== "message") continue;
|
|
13411
|
-
const text = buildTurnPreview({ kind: entry.role, payload: entry.payload });
|
|
13412
|
-
if (text.length > 0) previews.set(entry.turnId, text);
|
|
13413
|
-
}
|
|
13414
|
-
structural = structuralTreeNodes(bundle.entries, previews);
|
|
13415
|
-
} catch {
|
|
13416
|
-
}
|
|
13417
|
-
const persistedLeaf = bundle.meta.pinnedLeafTurnId && bundle.nodes.some((node) => node.id === bundle.meta.pinnedLeafTurnId) ? bundle.meta.pinnedLeafTurnId : computeLeafId(bundle.nodes);
|
|
13418
|
-
return buildTreeSnapshot({
|
|
13419
|
-
meta,
|
|
13420
|
-
nodes: [...bundle.nodes, ...structural],
|
|
13421
|
-
labels: bundle.labels,
|
|
13422
|
-
previews,
|
|
13423
|
-
// The leaf is the next append point, so it is computed over turn nodes
|
|
13424
|
-
// only: a structural node marks a moment in the timeline, never a place
|
|
13425
|
-
// the session continues from.
|
|
13426
|
-
leafId: state?.meta.id === sessionId ? currentTurnId : persistedLeaf
|
|
13427
|
-
});
|
|
13057
|
+
if (receipt.projectContext?.tier === "bounded" && validBoundedProjectContext(receipt.projectContext)) {
|
|
13058
|
+
artifacts.push(
|
|
13059
|
+
sha256Reference("project_context", `${receipt.runId}:project-context`, receipt.projectContext.contentHash)
|
|
13060
|
+
);
|
|
13428
13061
|
}
|
|
13429
|
-
|
|
13430
|
-
current: () => state?.meta ?? null,
|
|
13431
|
-
create(input) {
|
|
13432
|
-
const cwd = input?.cwd ?? process.cwd();
|
|
13433
|
-
const startInput = { cwd };
|
|
13434
|
-
if (input?.model !== void 0) startInput.model = input.model;
|
|
13435
|
-
if (input?.target !== void 0) startInput.target = input.target;
|
|
13436
|
-
if (state) {
|
|
13437
|
-
const prior = state;
|
|
13438
|
-
emitPark(prior.meta.id, "create_new");
|
|
13439
|
-
state = null;
|
|
13440
|
-
void prior.writer.close();
|
|
13441
|
-
}
|
|
13442
|
-
const next = startSession(startInput);
|
|
13443
|
-
next.meta.workspace = probeWorkspace(cwd);
|
|
13444
|
-
persistSessionMeta(next);
|
|
13445
|
-
state = next;
|
|
13446
|
-
currentTurnId = null;
|
|
13447
|
-
return next.meta;
|
|
13448
|
-
},
|
|
13449
|
-
append(turn) {
|
|
13450
|
-
if (!state) throw new Error("session.append: no current session");
|
|
13451
|
-
if (turn.parentId !== currentTurnId) {
|
|
13452
|
-
throw new Error(
|
|
13453
|
-
`session.append: turn parentId ${turn.parentId ?? "null"} is not this session's current leaf (expected ${currentTurnId ?? "null"}); refusing to parent a turn onto another session's turn`
|
|
13454
|
-
);
|
|
13455
|
-
}
|
|
13456
|
-
const record = appendTurn(state, turn);
|
|
13457
|
-
currentTurnId = record.id;
|
|
13458
|
-
if (state.meta.pinnedLeafTurnId !== void 0 && state.meta.pinnedLeafTurnId !== null) {
|
|
13459
|
-
state.meta.pinnedLeafTurnId = null;
|
|
13460
|
-
persistSessionMeta(state);
|
|
13461
|
-
}
|
|
13462
|
-
return record;
|
|
13463
|
-
},
|
|
13464
|
-
appendEntry(entry) {
|
|
13465
|
-
if (!state) throw new Error("session.appendEntry: no current session");
|
|
13466
|
-
return appendEntry(state, entry);
|
|
13467
|
-
},
|
|
13468
|
-
replaceEntries(entries) {
|
|
13469
|
-
if (!state) throw new Error("session.replaceEntries: no current session");
|
|
13470
|
-
replaceEntries(state, entries);
|
|
13471
|
-
},
|
|
13472
|
-
recordSkillActivation(activation) {
|
|
13473
|
-
if (!state) throw new Error("session.recordSkillActivation: no current session");
|
|
13474
|
-
appendEntry(state, {
|
|
13475
|
-
kind: "skillActivation",
|
|
13476
|
-
parentTurnId: activation.turnId ?? null,
|
|
13477
|
-
activation
|
|
13478
|
-
});
|
|
13479
|
-
const existing = state.meta.skillActivations ?? [];
|
|
13480
|
-
state.meta.skillActivations = [...existing, activation];
|
|
13481
|
-
persistSessionMeta(state);
|
|
13482
|
-
return activation;
|
|
13483
|
-
},
|
|
13484
|
-
async checkpoint(reason) {
|
|
13485
|
-
if (!state) throw new Error("session.checkpoint: no current session");
|
|
13486
|
-
await performCheckpoint(state, reason);
|
|
13487
|
-
},
|
|
13488
|
-
flushAppends() {
|
|
13489
|
-
if (!state) throw new Error("session.flushAppends: no current session");
|
|
13490
|
-
state.writer.flushAppends();
|
|
13491
|
-
},
|
|
13492
|
-
resume(sessionId) {
|
|
13493
|
-
if (state && state.meta.id === sessionId) return state.meta;
|
|
13494
|
-
const resumed = resumeSessionState(sessionId);
|
|
13495
|
-
if (state) {
|
|
13496
|
-
const prior = state;
|
|
13497
|
-
emitPark(prior.meta.id, "resume_other");
|
|
13498
|
-
void prior.writer.close();
|
|
13499
|
-
}
|
|
13500
|
-
state = resumed.state;
|
|
13501
|
-
currentTurnId = resolveLeafOnOpen(resumed);
|
|
13502
|
-
emitResume(resumed.state.meta.id, "resume");
|
|
13503
|
-
return resumed.state.meta;
|
|
13504
|
-
},
|
|
13505
|
-
fork(parentTurnId, input) {
|
|
13506
|
-
if (!state) throw new Error("session.fork: no current session to fork from");
|
|
13507
|
-
const prior = state;
|
|
13508
|
-
const { next, nodes } = forkFromState({
|
|
13509
|
-
from: prior,
|
|
13510
|
-
parentTurnId,
|
|
13511
|
-
...input?.cwd !== void 0 ? { cwd: input.cwd } : {}
|
|
13512
|
-
});
|
|
13513
|
-
emitPark(prior.meta.id, "fork");
|
|
13514
|
-
state = next;
|
|
13515
|
-
currentTurnId = computeLeafId(nodes);
|
|
13516
|
-
return next.meta;
|
|
13517
|
-
},
|
|
13518
|
-
tree(sessionId) {
|
|
13519
|
-
const id = sessionId ?? state?.meta.id;
|
|
13520
|
-
if (!id) throw new Error("session.tree: no sessionId provided and no current session");
|
|
13521
|
-
if (state?.meta.id === id) void flushIfCurrent(id);
|
|
13522
|
-
return snapshotFor(id);
|
|
13523
|
-
},
|
|
13524
|
-
switchBranch(sessionId) {
|
|
13525
|
-
if (state?.meta.id === sessionId) return state.meta;
|
|
13526
|
-
const resumed = resumeSessionState(sessionId);
|
|
13527
|
-
if (state) {
|
|
13528
|
-
const prior = state;
|
|
13529
|
-
emitPark(prior.meta.id, "switch_branch");
|
|
13530
|
-
void prior.writer.close();
|
|
13531
|
-
}
|
|
13532
|
-
state = resumed.state;
|
|
13533
|
-
currentTurnId = resolveLeafOnOpen(resumed);
|
|
13534
|
-
emitResume(resumed.state.meta.id, "switch_branch");
|
|
13535
|
-
return resumed.state.meta;
|
|
13536
|
-
},
|
|
13537
|
-
switchTurn(turnId) {
|
|
13538
|
-
if (!state) throw new Error("session.switchTurn: no current session");
|
|
13539
|
-
void flushIfCurrent(state.meta.id);
|
|
13540
|
-
const nodes = readTreeBundle(state.meta.id).nodes;
|
|
13541
|
-
if (!nodes.some((node) => node.id === turnId)) {
|
|
13542
|
-
throw new Error(`session.switchTurn: turn not found: ${turnId}`);
|
|
13543
|
-
}
|
|
13544
|
-
currentTurnId = turnId;
|
|
13545
|
-
state.meta.pinnedLeafTurnId = turnId;
|
|
13546
|
-
persistSessionMeta(state);
|
|
13547
|
-
emitTurnSwitched(state.meta.id, turnId);
|
|
13548
|
-
return state.meta;
|
|
13549
|
-
},
|
|
13550
|
-
editLabel(turnId, label, sessionId) {
|
|
13551
|
-
const targetId = sessionId ?? state?.meta.id;
|
|
13552
|
-
if (!targetId) throw new Error("session.editLabel: no sessionId provided and no current session");
|
|
13553
|
-
if (state && state.meta.id === targetId) {
|
|
13554
|
-
appendEntry(state, {
|
|
13555
|
-
kind: "label",
|
|
13556
|
-
parentTurnId: null,
|
|
13557
|
-
targetTurnId: turnId,
|
|
13558
|
-
label
|
|
13559
|
-
});
|
|
13560
|
-
return;
|
|
13561
|
-
}
|
|
13562
|
-
const entry = {
|
|
13563
|
-
kind: "label",
|
|
13564
|
-
turnId: newTurnId(),
|
|
13565
|
-
parentTurnId: null,
|
|
13566
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13567
|
-
targetTurnId: turnId,
|
|
13568
|
-
label
|
|
13569
|
-
};
|
|
13570
|
-
appendEntryToSessionFile(targetId, entry);
|
|
13571
|
-
},
|
|
13572
|
-
setName(name, sessionId) {
|
|
13573
|
-
const targetId = sessionId ?? state?.meta.id;
|
|
13574
|
-
if (!targetId) throw new Error("session.setName: no sessionId provided and no current session");
|
|
13575
|
-
if (state && state.meta.id === targetId) {
|
|
13576
|
-
appendEntry(state, {
|
|
13577
|
-
kind: "sessionInfo",
|
|
13578
|
-
parentTurnId: null,
|
|
13579
|
-
name
|
|
13580
|
-
});
|
|
13581
|
-
return;
|
|
13582
|
-
}
|
|
13583
|
-
const entry = {
|
|
13584
|
-
kind: "sessionInfo",
|
|
13585
|
-
turnId: newTurnId(),
|
|
13586
|
-
parentTurnId: null,
|
|
13587
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13588
|
-
name
|
|
13589
|
-
};
|
|
13590
|
-
appendEntryToSessionFile(targetId, entry);
|
|
13591
|
-
},
|
|
13592
|
-
deleteSession(id, opts) {
|
|
13593
|
-
if (state?.meta.id === id) {
|
|
13594
|
-
throw new Error("session.deleteSession: refusing to delete the currently open session; close() first");
|
|
13595
|
-
}
|
|
13596
|
-
const options = opts ?? {};
|
|
13597
|
-
if (options.keepFiles) {
|
|
13598
|
-
tombstoneSession(id);
|
|
13599
|
-
} else {
|
|
13600
|
-
removeSessionDirectory(id);
|
|
13601
|
-
}
|
|
13602
|
-
},
|
|
13603
|
-
history() {
|
|
13604
|
-
const cwd = state?.meta.cwd ?? process.cwd();
|
|
13605
|
-
return listSessionsForCwd(cwd);
|
|
13606
|
-
},
|
|
13607
|
-
async close() {
|
|
13608
|
-
await closeCurrent();
|
|
13609
|
-
}
|
|
13610
|
-
};
|
|
13611
|
-
const extension = {
|
|
13612
|
-
async start() {
|
|
13613
|
-
},
|
|
13614
|
-
async stop() {
|
|
13615
|
-
if (!state) return;
|
|
13616
|
-
try {
|
|
13617
|
-
await performCheckpoint(state, "shutdown");
|
|
13618
|
-
} catch (err) {
|
|
13619
|
-
process.stderr.write(
|
|
13620
|
-
`[clio:session] shutdown checkpoint failed: ${err instanceof Error ? err.message : String(err)}
|
|
13621
|
-
`
|
|
13622
|
-
);
|
|
13623
|
-
}
|
|
13624
|
-
await closeCurrent("shutdown");
|
|
13625
|
-
}
|
|
13626
|
-
};
|
|
13627
|
-
return { extension, contract };
|
|
13062
|
+
return uniqueBoundedReferences(artifacts);
|
|
13628
13063
|
}
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
13636
|
-
|
|
13637
|
-
|
|
13638
|
-
|
|
13639
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
13640
|
-
import { join as join17 } from "node:path";
|
|
13641
|
-
async function readAuditRows(stateDir) {
|
|
13642
|
-
const root = join17(stateDir, "audit");
|
|
13643
|
-
let files;
|
|
13644
|
-
try {
|
|
13645
|
-
files = await readdir(root);
|
|
13646
|
-
} catch (error) {
|
|
13647
|
-
const err = error;
|
|
13648
|
-
if (err.code === "ENOENT") return { rows: [], errors: [] };
|
|
13649
|
-
return { rows: [], errors: [`audit root read error: ${err.message ?? String(err)}`] };
|
|
13064
|
+
function adaptRunReceiptContextStatus(receipt) {
|
|
13065
|
+
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13066
|
+
const artifacts = contextArtifacts(receipt);
|
|
13067
|
+
const source = receiptSource(receipt);
|
|
13068
|
+
const briefingInvalid = receipt.briefing !== void 0 && !validBriefing(receipt.briefing);
|
|
13069
|
+
if (briefingInvalid) return attributed("invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13070
|
+
const context = receipt.projectContext;
|
|
13071
|
+
if (context === void 0) {
|
|
13072
|
+
if (receipt.briefing !== void 0) return attributed("recorded", source, DISPATCH_AUTHORITY, artifacts);
|
|
13073
|
+
return attributed("unknown", compatibilitySource(receipt, "projectContext"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13650
13074
|
}
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
const path2 = join17(root, file);
|
|
13655
|
-
let raw;
|
|
13656
|
-
try {
|
|
13657
|
-
raw = await readFile(path2, "utf8");
|
|
13658
|
-
} catch (error) {
|
|
13659
|
-
const err = error;
|
|
13660
|
-
errors.push(`${path2}: ${err.message ?? String(err)}`);
|
|
13661
|
-
continue;
|
|
13662
|
-
}
|
|
13663
|
-
const lines = raw.split("\n");
|
|
13664
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
13665
|
-
const line = lines[index];
|
|
13666
|
-
if (line === void 0 || line.length === 0) continue;
|
|
13667
|
-
let parsed;
|
|
13668
|
-
try {
|
|
13669
|
-
parsed = JSON.parse(line);
|
|
13670
|
-
} catch (error) {
|
|
13671
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
13672
|
-
errors.push(`${path2}:${index + 1}: invalid JSON: ${message}`);
|
|
13673
|
-
continue;
|
|
13674
|
-
}
|
|
13675
|
-
if (!isRecord9(parsed)) {
|
|
13676
|
-
errors.push(`${path2}:${index + 1}: expected object`);
|
|
13677
|
-
continue;
|
|
13678
|
-
}
|
|
13679
|
-
const auditKind = readOptionalString(parsed.kind) ?? "tool_call";
|
|
13680
|
-
rows.push({
|
|
13681
|
-
file,
|
|
13682
|
-
line: index + 1,
|
|
13683
|
-
row: parsed,
|
|
13684
|
-
ts: readOptionalString(parsed.ts),
|
|
13685
|
-
auditKind,
|
|
13686
|
-
correlationId: readOptionalString(parsed.correlationId) ?? ""
|
|
13687
|
-
});
|
|
13075
|
+
if (context.tier === "none") {
|
|
13076
|
+
if (context.chars !== void 0 || context.contentHash !== void 0 || context.sections !== void 0) {
|
|
13077
|
+
return attributed("invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13688
13078
|
}
|
|
13079
|
+
return receipt.briefing === void 0 ? attributed("not_applicable", source, DISPATCH_AUTHORITY, artifacts) : attributed("recorded", source, DISPATCH_AUTHORITY, artifacts);
|
|
13689
13080
|
}
|
|
13690
|
-
return
|
|
13081
|
+
return attributed(validBoundedProjectContext(context) ? "recorded" : "invalid", source, DISPATCH_AUTHORITY, artifacts);
|
|
13691
13082
|
}
|
|
13692
|
-
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
const err = error;
|
|
13699
|
-
if (err.code === "ENOENT") return { entries: [], missing: true, errors: [] };
|
|
13700
|
-
return { entries: [], missing: false, errors: [`session root read error: ${err.message ?? String(err)}`] };
|
|
13083
|
+
function adaptRunReceiptAutonomyStatus(receipt) {
|
|
13084
|
+
if (receipt === null || receipt === void 0) return absentTrustStatus("artifact_missing");
|
|
13085
|
+
const enforcement = receipt.autonomyEnforcement;
|
|
13086
|
+
const artifacts = [receiptReference(receipt)];
|
|
13087
|
+
if (enforcement === void 0) {
|
|
13088
|
+
return attributed("unknown", compatibilitySource(receipt, "autonomyEnforcement"), COMPATIBILITY_AUTHORITY, artifacts);
|
|
13701
13089
|
}
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
}
|
|
13718
|
-
} else if (err.code === "ENOTDIR") {
|
|
13719
|
-
continue;
|
|
13720
|
-
} else {
|
|
13721
|
-
return { entries: [], missing: false, errors: [`${currentPath}: ${err.message ?? String(err)}`] };
|
|
13722
|
-
}
|
|
13723
|
-
}
|
|
13724
|
-
return parseSessionEntries(raw, source);
|
|
13090
|
+
artifacts.push({ kind: "autonomy_policy", id: `${receipt.runId}:${enforcement.autonomy}` });
|
|
13091
|
+
const authority = enforcement.grade === "mediated" ? { kind: "clio", id: "safety-autonomy" } : { kind: "runtime", id: enforcement.externalMode ?? "external-runtime" };
|
|
13092
|
+
const state = enforcement.dangerousBypass === true || enforcement.grade === "bypassed" ? "bypassed" : enforcement.grade === "approximated" ? "approximated" : "enforced";
|
|
13093
|
+
return attributed(state, receiptSource(receipt), authority, artifacts);
|
|
13094
|
+
}
|
|
13095
|
+
function receiptClaimsAreAuthenticated(receipt, integrity) {
|
|
13096
|
+
return receipt?.integrity !== void 0 && integrity?.ok === true;
|
|
13097
|
+
}
|
|
13098
|
+
function unauthenticatedReceiptProjection(receipt) {
|
|
13099
|
+
if (receipt === null || receipt === void 0) {
|
|
13100
|
+
return {
|
|
13101
|
+
validationGrounding: absentTrustStatus("artifact_missing"),
|
|
13102
|
+
contextProvenance: absentTrustStatus("artifact_missing"),
|
|
13103
|
+
autonomyEnforcement: absentTrustStatus("artifact_missing")
|
|
13104
|
+
};
|
|
13725
13105
|
}
|
|
13726
|
-
|
|
13106
|
+
if (receipt.integrity === void 0) {
|
|
13107
|
+
const artifacts = [receiptReference(receipt)];
|
|
13108
|
+
return {
|
|
13109
|
+
validationGrounding: attributed(
|
|
13110
|
+
"unknown",
|
|
13111
|
+
compatibilitySource(receipt, "canonical-projection"),
|
|
13112
|
+
COMPATIBILITY_AUTHORITY,
|
|
13113
|
+
artifacts
|
|
13114
|
+
),
|
|
13115
|
+
contextProvenance: attributed(
|
|
13116
|
+
"unknown",
|
|
13117
|
+
compatibilitySource(receipt, "canonical-projection"),
|
|
13118
|
+
COMPATIBILITY_AUTHORITY,
|
|
13119
|
+
artifacts
|
|
13120
|
+
),
|
|
13121
|
+
autonomyEnforcement: attributed(
|
|
13122
|
+
"unknown",
|
|
13123
|
+
compatibilitySource(receipt, "canonical-projection"),
|
|
13124
|
+
COMPATIBILITY_AUTHORITY,
|
|
13125
|
+
artifacts
|
|
13126
|
+
)
|
|
13127
|
+
};
|
|
13128
|
+
}
|
|
13129
|
+
return {
|
|
13130
|
+
validationGrounding: absentTrustStatus("not_observed"),
|
|
13131
|
+
contextProvenance: absentTrustStatus("not_observed"),
|
|
13132
|
+
autonomyEnforcement: absentTrustStatus("not_observed")
|
|
13133
|
+
};
|
|
13134
|
+
}
|
|
13135
|
+
function adaptRunReceiptTrustStatus(receipt, options = {}) {
|
|
13136
|
+
const authenticated2 = receiptClaimsAreAuthenticated(receipt, options.integrity);
|
|
13137
|
+
const receiptProjection = authenticated2 ? {
|
|
13138
|
+
validationGrounding: adaptRunReceiptValidationStatus(receipt),
|
|
13139
|
+
contextProvenance: adaptRunReceiptContextStatus(receipt),
|
|
13140
|
+
autonomyEnforcement: adaptRunReceiptAutonomyStatus(receipt)
|
|
13141
|
+
} : unauthenticatedReceiptProjection(receipt);
|
|
13142
|
+
return composeTrustStatus({
|
|
13143
|
+
artifactIntegrity: adaptReceiptIntegrityStatus(receipt, options.integrity),
|
|
13144
|
+
...receiptProjection,
|
|
13145
|
+
independentReview: absentTrustStatus(receipt === null || receipt === void 0 ? "artifact_missing" : "not_recorded"),
|
|
13146
|
+
completionEvidence: absentTrustStatus(
|
|
13147
|
+
receipt === null || receipt === void 0 ? "artifact_missing" : "not_recorded"
|
|
13148
|
+
)
|
|
13149
|
+
});
|
|
13727
13150
|
}
|
|
13728
|
-
function
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13735
|
-
let parsed;
|
|
13151
|
+
function inspectRunReceiptTrustStatus(receipt, envelope) {
|
|
13152
|
+
let integrity;
|
|
13153
|
+
if (receipt === null || receipt === void 0) {
|
|
13154
|
+
integrity = { ok: false, reason: "receipt unavailable" };
|
|
13155
|
+
} else if (envelope === null || envelope === void 0) {
|
|
13156
|
+
integrity = { ok: false, reason: "run ledger envelope unavailable" };
|
|
13157
|
+
} else {
|
|
13736
13158
|
try {
|
|
13737
|
-
|
|
13159
|
+
integrity = verifyReceiptIntegrity(receipt, envelope);
|
|
13738
13160
|
} catch (error) {
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
if (isSessionHeader(parsed)) continue;
|
|
13744
|
-
if (isSessionEntry(parsed)) {
|
|
13745
|
-
entries.push(parsed);
|
|
13746
|
-
continue;
|
|
13161
|
+
integrity = {
|
|
13162
|
+
ok: false,
|
|
13163
|
+
reason: `receipt invalid: ${error instanceof Error ? error.message : String(error)}`
|
|
13164
|
+
};
|
|
13747
13165
|
}
|
|
13748
|
-
errors.push(
|
|
13749
|
-
`session ledger contains an unreadable entry (missing kind discriminant): ${source}. Remove or compact the session to reset.`
|
|
13750
|
-
);
|
|
13751
13166
|
}
|
|
13752
|
-
return {
|
|
13753
|
-
|
|
13754
|
-
|
|
13755
|
-
|
|
13756
|
-
|
|
13757
|
-
|
|
13758
|
-
|
|
13759
|
-
|
|
13760
|
-
|
|
13167
|
+
return {
|
|
13168
|
+
integrity,
|
|
13169
|
+
status: adaptRunReceiptTrustStatus(receipt, { integrity })
|
|
13170
|
+
};
|
|
13171
|
+
}
|
|
13172
|
+
function gateReference(artifact) {
|
|
13173
|
+
return sha256Reference("gate_decision", artifact.id, artifact.integrity.digest);
|
|
13174
|
+
}
|
|
13175
|
+
function gateAuthority(artifact) {
|
|
13176
|
+
if (artifact.outcome === "operator-confirmed") return { kind: "operator", id: "gate-confirmation" };
|
|
13177
|
+
if (artifact.outcome === "full-auto-applied") return { kind: "clio", id: "full-auto-gate-policy" };
|
|
13178
|
+
return { kind: "reviewer", id: artifact.decider?.runId ?? "unavailable-decider" };
|
|
13179
|
+
}
|
|
13180
|
+
function adaptGateDecisionReviewStatus(artifact, subjectRunId, verification) {
|
|
13181
|
+
if (artifact === null || artifact === void 0) return absentTrustStatus("artifact_missing");
|
|
13182
|
+
const source = { kind: "gate_decision", id: artifact.id };
|
|
13183
|
+
const artifacts = [gateReference(artifact)];
|
|
13184
|
+
const authority = gateAuthority(artifact);
|
|
13185
|
+
if (!artifact.subjects.some((subject) => subject.runId === subjectRunId)) return absentTrustStatus("not_recorded");
|
|
13186
|
+
if (verification === void 0 || !verification.ok) {
|
|
13187
|
+
return attributed(
|
|
13188
|
+
"unknown",
|
|
13189
|
+
source,
|
|
13190
|
+
verification === void 0 ? COMPATIBILITY_AUTHORITY : { kind: "unknown", id: "unauthenticated-gate-artifact" },
|
|
13191
|
+
artifacts
|
|
13192
|
+
);
|
|
13761
13193
|
}
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
let sessionIds;
|
|
13766
|
-
try {
|
|
13767
|
-
sessionIds = await readdir(join17(root, cwdHash2));
|
|
13768
|
-
} catch {
|
|
13769
|
-
continue;
|
|
13770
|
-
}
|
|
13771
|
-
for (const sessionId of sessionIds.sort(compareStrings2)) {
|
|
13772
|
-
refs.push({ cwdHash: cwdHash2, sessionId, path: join17(root, cwdHash2, sessionId, "current.jsonl") });
|
|
13194
|
+
if (artifact.decider === void 0 || artifact.correlation === void 0) {
|
|
13195
|
+
if (artifact.outcome === "operator-confirmed" || artifact.outcome === "full-auto-applied") {
|
|
13196
|
+
return attributed("not_applicable", source, authority, artifacts);
|
|
13773
13197
|
}
|
|
13198
|
+
return attributed("inconclusive", source, authority, artifacts);
|
|
13774
13199
|
}
|
|
13775
|
-
return
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
13200
|
+
if (!artifact.correlation.independent) return attributed("not_independent", source, authority, artifacts);
|
|
13201
|
+
if (artifact.outcome === "pass") return attributed("passed", source, authority, artifacts);
|
|
13202
|
+
if (artifact.outcome === "fail") return attributed("failed", source, authority, artifacts);
|
|
13203
|
+
if (artifact.outcome === "winner") {
|
|
13204
|
+
return attributed(
|
|
13205
|
+
artifact.winner?.subject.runId === subjectRunId ? "passed" : "failed",
|
|
13206
|
+
source,
|
|
13207
|
+
authority,
|
|
13208
|
+
artifacts
|
|
13209
|
+
);
|
|
13210
|
+
}
|
|
13211
|
+
return attributed("inconclusive", source, authority, artifacts);
|
|
13779
13212
|
}
|
|
13780
|
-
function
|
|
13781
|
-
|
|
13213
|
+
function adaptGroundedEvidenceValidationStatus(input) {
|
|
13214
|
+
const observed = (input.artifacts ?? []).filter((artifact) => !SELF_REPORTED_ARTIFACT_KINDS.has(artifact.kind));
|
|
13215
|
+
if (observed.length === 0) return absentTrustStatus("not_observed");
|
|
13216
|
+
return attributed(
|
|
13217
|
+
"validated",
|
|
13218
|
+
{ kind: "evidence_bundle", id: `${input.evidenceId}:${input.runId}` },
|
|
13219
|
+
{ kind: "clio", id: "evidence-grounding" },
|
|
13220
|
+
uniqueBoundedReferences([{ kind: "evidence_bundle", id: input.evidenceId }, ...observed])
|
|
13221
|
+
);
|
|
13782
13222
|
}
|
|
13783
|
-
function
|
|
13784
|
-
|
|
13223
|
+
function adaptFinishContractCompletionStatus(assessment, options = {}) {
|
|
13224
|
+
const artifacts = uniqueBoundedReferences(
|
|
13225
|
+
options.artifacts ?? assessment.evidence.map((evidence, index) => ({
|
|
13226
|
+
kind: evidence.turnId === void 0 ? "finish_contract_evidence" : "session_entry",
|
|
13227
|
+
id: evidence.turnId ?? `${evidence.kind}:${index + 1}`
|
|
13228
|
+
}))
|
|
13229
|
+
);
|
|
13230
|
+
const source = { kind: "finish_contract", id: options.sourceId ?? assessment.reason };
|
|
13231
|
+
const authority = { kind: "clio", id: "finish-contract" };
|
|
13232
|
+
if (assessment.reason === "no_mutation") return attributed("not_applicable", source, authority, artifacts);
|
|
13233
|
+
if (assessment.reason === "validation_evidence") return attributed("evidenced", source, authority, artifacts);
|
|
13234
|
+
if (assessment.reason === "explicit_limitation") return attributed("limited", source, authority, artifacts);
|
|
13235
|
+
return attributed("incomplete", source, authority, artifacts);
|
|
13236
|
+
}
|
|
13237
|
+
function uniqueBoundedReferences(references) {
|
|
13238
|
+
const sorted = [...references].sort(compareArtifactReferences);
|
|
13239
|
+
const unique = sorted.filter(
|
|
13240
|
+
(reference, index) => index === 0 || compareArtifactReferences(sorted[index - 1], reference) !== 0
|
|
13241
|
+
);
|
|
13242
|
+
return unique.slice(0, TRUST_STATUS_MAX_ARTIFACT_REFERENCES);
|
|
13785
13243
|
}
|
|
13786
13244
|
|
|
13787
|
-
// src/domains/
|
|
13245
|
+
// src/domains/evidence/types.ts
|
|
13788
13246
|
init_esm_shims();
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
|
|
13795
|
-
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
if (context.correlationId !== void 0) entry.correlationId = context.correlationId;
|
|
13800
|
-
return entry;
|
|
13801
|
-
}
|
|
13802
|
-
function protectedArtifactFromSessionEntry(entry) {
|
|
13803
|
-
return protectedArtifactFromSnapshot(entry.artifact);
|
|
13804
|
-
}
|
|
13805
|
-
function protectedArtifactStateFromSessionEntries(entries) {
|
|
13806
|
-
let state = { artifacts: [] };
|
|
13807
|
-
const protectedEntries = entries.map((entry, index) => ({ entry, index })).filter((item) => item.entry.kind === "protectedArtifact").sort(compareProtectedEntryPositions);
|
|
13808
|
-
for (const item of protectedEntries) {
|
|
13809
|
-
if (item.entry.action !== "protect") continue;
|
|
13810
|
-
state = protectArtifact(state, protectedArtifactFromSessionEntry(item.entry));
|
|
13811
|
-
}
|
|
13812
|
-
return state;
|
|
13813
|
-
}
|
|
13814
|
-
function artifactSnapshot(artifact) {
|
|
13815
|
-
const snapshot = {
|
|
13816
|
-
path: artifact.path,
|
|
13817
|
-
protectedAt: artifact.protectedAt,
|
|
13818
|
-
reason: artifact.reason,
|
|
13819
|
-
source: artifact.source
|
|
13820
|
-
};
|
|
13821
|
-
if (artifact.validationCommand !== void 0) snapshot.validationCommand = artifact.validationCommand;
|
|
13822
|
-
if (artifact.validationExitCode !== void 0) snapshot.validationExitCode = artifact.validationExitCode;
|
|
13823
|
-
return snapshot;
|
|
13824
|
-
}
|
|
13825
|
-
function protectedArtifactFromSnapshot(snapshot) {
|
|
13826
|
-
const artifact = {
|
|
13827
|
-
path: snapshot.path,
|
|
13828
|
-
protectedAt: snapshot.protectedAt,
|
|
13829
|
-
reason: snapshot.reason,
|
|
13830
|
-
source: snapshot.source
|
|
13831
|
-
};
|
|
13832
|
-
if (snapshot.validationCommand !== void 0) artifact.validationCommand = snapshot.validationCommand;
|
|
13833
|
-
if (snapshot.validationExitCode !== void 0) artifact.validationExitCode = snapshot.validationExitCode;
|
|
13834
|
-
return artifact;
|
|
13835
|
-
}
|
|
13836
|
-
function compareProtectedEntryPositions(left, right) {
|
|
13837
|
-
return compareStrings3(left.entry.timestamp, right.entry.timestamp) || compareStrings3(left.entry.turnId, right.entry.turnId) || left.index - right.index;
|
|
13838
|
-
}
|
|
13839
|
-
function compareStrings3(left, right) {
|
|
13840
|
-
if (left < right) return -1;
|
|
13841
|
-
if (left > right) return 1;
|
|
13842
|
-
return 0;
|
|
13843
|
-
}
|
|
13247
|
+
var EVIDENCE_VERSION = 1;
|
|
13248
|
+
var FAILURE_CAUSE_TAG_ORDER = [
|
|
13249
|
+
"timeout",
|
|
13250
|
+
"auth-failure",
|
|
13251
|
+
"missing-dependency",
|
|
13252
|
+
"build-failure",
|
|
13253
|
+
"test-failure",
|
|
13254
|
+
"blocked-tool"
|
|
13255
|
+
];
|
|
13256
|
+
var FAILURE_CAUSE_TAGS = new Set(FAILURE_CAUSE_TAG_ORDER);
|
|
13844
13257
|
|
|
13845
|
-
// src/domains/
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13858
|
-
|
|
13859
|
-
|
|
13860
|
-
|
|
13861
|
-
|
|
13862
|
-
}
|
|
13863
|
-
return null;
|
|
13258
|
+
// src/domains/evidence/run-trust.ts
|
|
13259
|
+
function buildEvidenceTrustStatusFile(input) {
|
|
13260
|
+
return {
|
|
13261
|
+
version: EVIDENCE_VERSION,
|
|
13262
|
+
evidenceId: input.evidenceId,
|
|
13263
|
+
projection: "canonical",
|
|
13264
|
+
runs: input.runSources.map((source) => ({
|
|
13265
|
+
runId: source.envelope.id,
|
|
13266
|
+
status: composeEvidenceRunTrustStatus({
|
|
13267
|
+
evidenceId: input.evidenceId,
|
|
13268
|
+
source,
|
|
13269
|
+
gateDecisions: input.gateDecisions,
|
|
13270
|
+
auditRows: input.auditRows,
|
|
13271
|
+
validationEvidence: input.validationEvidence?.get(source.envelope.id) ?? []
|
|
13272
|
+
})
|
|
13273
|
+
}))
|
|
13274
|
+
};
|
|
13864
13275
|
}
|
|
13865
|
-
function
|
|
13866
|
-
const
|
|
13867
|
-
|
|
13868
|
-
let
|
|
13869
|
-
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
output: usage2.output,
|
|
13878
|
-
cacheRead: usage2.cacheRead,
|
|
13879
|
-
cacheWrite: usage2.cacheWrite,
|
|
13880
|
-
reasoningTokens: usage2.reasoning,
|
|
13881
|
-
totalTokens: usage2.totalTokens,
|
|
13882
|
-
costUsd: usage2.cost.total,
|
|
13883
|
-
// A split turn runs two summarization streams under one entry; the
|
|
13884
|
-
// provider served that many calls even though one row records them.
|
|
13885
|
-
apiCalls: Math.max(1, Math.round(usage2.apiCalls))
|
|
13886
|
-
});
|
|
13887
|
-
continue;
|
|
13888
|
-
}
|
|
13889
|
-
if (entry?.kind === "modelChange") {
|
|
13890
|
-
const change = entry;
|
|
13891
|
-
if (typeof change.target === "string" && change.target.length > 0) currentTarget = change.target;
|
|
13892
|
-
else if (typeof change.provider === "string" && change.provider.length > 0) currentTarget = change.provider;
|
|
13893
|
-
if (typeof change.modelId === "string" && change.modelId.length > 0) currentModel = change.modelId;
|
|
13894
|
-
continue;
|
|
13895
|
-
}
|
|
13896
|
-
if (entry?.kind !== "message" || entry.role !== "assistant") continue;
|
|
13897
|
-
const payload = entry.payload;
|
|
13898
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) continue;
|
|
13899
|
-
const record = payload;
|
|
13900
|
-
const stopReason = record.stopReason;
|
|
13901
|
-
if (stopReason === "aborted" || stopReason === "error") continue;
|
|
13902
|
-
const rawUsage = record.usage;
|
|
13903
|
-
if (!rawUsage || typeof rawUsage !== "object" || Array.isArray(rawUsage)) continue;
|
|
13904
|
-
const usage = rawUsage;
|
|
13905
|
-
const input = numberAt(usage, "input");
|
|
13906
|
-
const output = numberAt(usage, "output");
|
|
13907
|
-
const cacheRead = numberAt(usage, "cacheRead");
|
|
13908
|
-
const cacheWrite = numberAt(usage, "cacheWrite");
|
|
13909
|
-
const totalTokens = numberAt(usage, "totalTokens") || input + output + cacheRead + cacheWrite;
|
|
13910
|
-
if (totalTokens === 0) continue;
|
|
13911
|
-
const cost = usage.cost;
|
|
13912
|
-
const costUsd = cost && typeof cost === "object" ? numberAt(cost, "total") : 0;
|
|
13913
|
-
calls.push({
|
|
13914
|
-
providerId: currentTarget ?? stringAt(record, "provider", "api") ?? "unknown",
|
|
13915
|
-
modelId: currentModel ?? stringAt(record, "responseModel", "model") ?? "unknown",
|
|
13916
|
-
input,
|
|
13917
|
-
output,
|
|
13918
|
-
cacheRead,
|
|
13919
|
-
cacheWrite,
|
|
13920
|
-
reasoningTokens: reasoningTokensOf(usage),
|
|
13921
|
-
totalTokens,
|
|
13922
|
-
costUsd
|
|
13276
|
+
function composeEvidenceRunTrustStatus(input) {
|
|
13277
|
+
const inspection = inspectRunReceiptTrustStatus(input.source.receipt, input.source.envelope);
|
|
13278
|
+
const receiptRejected = inspection.status.artifactIntegrity.state === "failed";
|
|
13279
|
+
let status = inspection.status;
|
|
13280
|
+
const grounded = input.validationEvidence.filter((artifact) => isTrustStatusIdentifier(artifact.id));
|
|
13281
|
+
if (grounded.length > 0 && (status.validationGrounding.state === "absent" || status.validationGrounding.state === "unknown")) {
|
|
13282
|
+
status = composeTrustStatus(status, {
|
|
13283
|
+
validationGrounding: adaptGroundedEvidenceValidationStatus({
|
|
13284
|
+
evidenceId: input.evidenceId,
|
|
13285
|
+
runId: input.source.envelope.id,
|
|
13286
|
+
artifacts: grounded
|
|
13287
|
+
})
|
|
13923
13288
|
});
|
|
13924
13289
|
}
|
|
13925
|
-
|
|
13926
|
-
|
|
13927
|
-
|
|
13928
|
-
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
if (facts.outcomeCode === "worker_tool_call_cap_exhausted" || facts.outcomeCode === "loop_guard_tools_disabled_exhausted") {
|
|
13938
|
-
return "tool-loop";
|
|
13290
|
+
const gate = latestGateDecisionForRun(input.gateDecisions, input.source.envelope.id);
|
|
13291
|
+
if (gate !== null) {
|
|
13292
|
+
const artifactVerification = verifyGateDecisionArtifact(gate);
|
|
13293
|
+
const subject = gate.subjects.find((entry) => entry.runId === input.source.envelope.id);
|
|
13294
|
+
const receipt = inspection.integrity.ok ? input.source.receipt : null;
|
|
13295
|
+
const verification = artifactVerification.ok && subject !== void 0 && receipt?.integrity !== void 0 && subject.digest === receipt.integrity.digest ? { ok: true } : {
|
|
13296
|
+
ok: false,
|
|
13297
|
+
reason: artifactVerification.ok ? "gate subject receipt digest unavailable or mismatched" : artifactVerification.reason
|
|
13298
|
+
};
|
|
13299
|
+
status = composeTrustStatus(status, {
|
|
13300
|
+
independentReview: adaptGateDecisionReviewStatus(gate, input.source.envelope.id, verification)
|
|
13301
|
+
});
|
|
13939
13302
|
}
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13303
|
+
const finish = latestFinishContractForRun(input.auditRows, input.source.envelope.id);
|
|
13304
|
+
if (finish !== null) {
|
|
13305
|
+
const completion = adaptFinishContractCompletionStatus(finish.assessment, {
|
|
13306
|
+
sourceId: finish.sourceId,
|
|
13307
|
+
artifacts: finish.artifacts
|
|
13308
|
+
});
|
|
13309
|
+
status = composeTrustStatus(status, {
|
|
13310
|
+
completionEvidence: receiptRejected && completion.state === "evidenced" ? {
|
|
13311
|
+
state: "unknown",
|
|
13312
|
+
source: { kind: "finish_contract", id: finish.sourceId },
|
|
13313
|
+
authority: { kind: "clio", id: "finish-contract" },
|
|
13314
|
+
artifacts: finish.artifacts
|
|
13315
|
+
} : completion
|
|
13316
|
+
});
|
|
13945
13317
|
}
|
|
13946
|
-
|
|
13947
|
-
|
|
13318
|
+
return status;
|
|
13319
|
+
}
|
|
13320
|
+
function latestGateDecisionForRun(decisions, runId) {
|
|
13321
|
+
return decisions.filter((decision) => decision.subjects.some((subject) => subject.runId === runId)).sort(
|
|
13322
|
+
(left, right) => compareCodepoints(left.createdAt, right.createdAt) || left.cycle - right.cycle || compareCodepoints(left.id, right.id)
|
|
13323
|
+
).at(-1) ?? null;
|
|
13324
|
+
}
|
|
13325
|
+
function latestFinishContractForRun(rows, runId) {
|
|
13326
|
+
const candidates = rows.filter((row) => row.auditKind === "completion_contract" && row.runId === runId && row.confidence === "exact").flatMap((row) => {
|
|
13327
|
+
const assessment = finishContractAssessmentFromAudit(row.row);
|
|
13328
|
+
if (assessment === null) return [];
|
|
13329
|
+
const correlationId = readOptionalString(row.row.correlationId) ?? `${runId}:completion-contract`;
|
|
13330
|
+
if (!isTrustStatusIdentifier(correlationId)) return [];
|
|
13331
|
+
const turnId = readOptionalString(row.row.turnId);
|
|
13332
|
+
const artifacts = [
|
|
13333
|
+
{ kind: "finish_contract_evidence", id: correlationId },
|
|
13334
|
+
...turnId === null || !isTrustStatusIdentifier(turnId) ? [] : [{ kind: "session_entry", id: turnId }]
|
|
13335
|
+
];
|
|
13336
|
+
return [{ sourceId: correlationId, assessment, artifacts, timestamp: row.ts ?? "" }];
|
|
13337
|
+
}).sort(
|
|
13338
|
+
(left, right) => compareCodepoints(left.timestamp, right.timestamp) || compareCodepoints(left.sourceId, right.sourceId)
|
|
13339
|
+
);
|
|
13340
|
+
const latest2 = candidates.at(-1);
|
|
13341
|
+
return latest2 === void 0 ? null : { sourceId: latest2.sourceId, assessment: latest2.assessment, artifacts: latest2.artifacts };
|
|
13342
|
+
}
|
|
13343
|
+
function finishContractAssessmentFromAudit(row) {
|
|
13344
|
+
const reason = readOptionalString(row.reason);
|
|
13345
|
+
const decision = readOptionalString(row.decision);
|
|
13346
|
+
const mutatedPaths = Array.isArray(row.mutatedPaths) ? row.mutatedPaths.filter((entry) => typeof entry === "string") : [];
|
|
13347
|
+
const turnId = readOptionalString(row.turnId);
|
|
13348
|
+
const evidenceKinds = Array.isArray(row.evidenceKinds) ? row.evidenceKinds.filter(isFinishContractEvidenceKind) : [];
|
|
13349
|
+
const evidence = evidenceKinds.map((kind) => ({
|
|
13350
|
+
kind,
|
|
13351
|
+
summary: "recorded by the finish contract",
|
|
13352
|
+
...turnId === null ? {} : { turnId }
|
|
13353
|
+
}));
|
|
13354
|
+
if (decision === "ok" && reason === "no_mutation") {
|
|
13355
|
+
return { kind: "ok", reason, evidence: [], mutatedPaths };
|
|
13948
13356
|
}
|
|
13949
|
-
if (
|
|
13950
|
-
return "
|
|
13357
|
+
if (decision === "ok" && reason === "validation_evidence") {
|
|
13358
|
+
return { kind: "ok", reason, evidence, mutatedPaths };
|
|
13951
13359
|
}
|
|
13952
|
-
if (
|
|
13953
|
-
return "
|
|
13360
|
+
if (decision === "ok" && reason === "explicit_limitation") {
|
|
13361
|
+
return { kind: "ok", reason, evidence: [], mutatedPaths };
|
|
13954
13362
|
}
|
|
13955
|
-
if (
|
|
13956
|
-
|
|
13957
|
-
return "test-failure";
|
|
13363
|
+
if (decision === "engage" && reason === "unvalidated_mutation") {
|
|
13364
|
+
return { kind: "engage", reason, message: "finish contract engaged", evidence: [], mutatedPaths };
|
|
13958
13365
|
}
|
|
13959
|
-
|
|
13960
|
-
return "unknown";
|
|
13961
|
-
}
|
|
13962
|
-
|
|
13963
|
-
// src/domains/evidence/provenance.ts
|
|
13964
|
-
init_esm_shims();
|
|
13965
|
-
var PERSONA_HASH_PREFIX_CHARS = 12;
|
|
13966
|
-
function extractRunProvenance(receipt) {
|
|
13967
|
-
const view = {};
|
|
13968
|
-
if (receipt.pipeline !== void 0) view.pipeline = receipt.pipeline;
|
|
13969
|
-
if (receipt.personaOverride !== void 0) view.personaOverride = receipt.personaOverride;
|
|
13970
|
-
const escalation = escalationCountsFrom(receipt.safety);
|
|
13971
|
-
if (escalation !== null) view.escalation = escalation;
|
|
13972
|
-
if (receipt.autonomyEnforcement !== void 0) view.autonomyEnforcement = receipt.autonomyEnforcement;
|
|
13973
|
-
return view;
|
|
13974
|
-
}
|
|
13975
|
-
function hasRunProvenance(view) {
|
|
13976
|
-
return view.pipeline !== void 0 || view.personaOverride !== void 0 || view.escalation !== void 0 || view.autonomyEnforcement !== void 0;
|
|
13977
|
-
}
|
|
13978
|
-
function runProvenanceFromUnknown(value) {
|
|
13979
|
-
if (!isRecord10(value)) return {};
|
|
13980
|
-
const view = {};
|
|
13981
|
-
const pipeline = pipelineFromUnknown(value.pipeline);
|
|
13982
|
-
if (pipeline !== null) view.pipeline = pipeline;
|
|
13983
|
-
const personaOverride = personaOverrideFromUnknown(value.personaOverride);
|
|
13984
|
-
if (personaOverride !== null) view.personaOverride = personaOverride;
|
|
13985
|
-
const escalation = escalationFromUnknown(value.safety);
|
|
13986
|
-
if (escalation !== null) view.escalation = escalation;
|
|
13987
|
-
const autonomyEnforcement = autonomyEnforcementFromUnknown(value.autonomyEnforcement);
|
|
13988
|
-
if (autonomyEnforcement !== null) view.autonomyEnforcement = autonomyEnforcement;
|
|
13989
|
-
return view;
|
|
13990
|
-
}
|
|
13991
|
-
function isRecord10(value) {
|
|
13992
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13993
|
-
}
|
|
13994
|
-
function finiteNumber(value) {
|
|
13995
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
13996
|
-
}
|
|
13997
|
-
function pipelineFromUnknown(value) {
|
|
13998
|
-
if (!isRecord10(value)) return null;
|
|
13999
|
-
const position = finiteNumber(value.position);
|
|
14000
|
-
const inputBytes = finiteNumber(value.inputBytes);
|
|
14001
|
-
if (position === null || inputBytes === null) return null;
|
|
14002
|
-
const fromRunId = typeof value.fromRunId === "string" ? value.fromRunId : null;
|
|
14003
|
-
return { fromRunId, position, inputBytes, inputTruncated: value.inputTruncated === true };
|
|
14004
|
-
}
|
|
14005
|
-
function personaOverrideFromUnknown(value) {
|
|
14006
|
-
if (!isRecord10(value) || typeof value.promptHash !== "string" || value.promptHash.length === 0) return null;
|
|
14007
|
-
return { promptHash: value.promptHash };
|
|
14008
|
-
}
|
|
14009
|
-
function autonomyEnforcementFromUnknown(value) {
|
|
14010
|
-
if (!isRecord10(value)) return null;
|
|
14011
|
-
if (value.grade !== "mediated" && value.grade !== "approximated" && value.grade !== "bypassed") return null;
|
|
14012
|
-
if (typeof value.autonomy !== "string" || value.autonomy.length === 0) return null;
|
|
14013
|
-
const view = { grade: value.grade, autonomy: value.autonomy };
|
|
14014
|
-
if (typeof value.externalMode === "string" && value.externalMode.length > 0) view.externalMode = value.externalMode;
|
|
14015
|
-
if (typeof value.dangerousBypass === "boolean") view.dangerousBypass = value.dangerousBypass;
|
|
14016
|
-
return view;
|
|
14017
|
-
}
|
|
14018
|
-
function escalationFromUnknown(safety) {
|
|
14019
|
-
if (!isRecord10(safety)) return null;
|
|
14020
|
-
const decisions = safety.decisions;
|
|
14021
|
-
if (!isRecord10(decisions)) return null;
|
|
14022
|
-
const requested = finiteNumber(decisions.escalationRequested);
|
|
14023
|
-
if (requested === null) return null;
|
|
14024
|
-
return {
|
|
14025
|
-
requested,
|
|
14026
|
-
approved: finiteNumber(decisions.escalationApproved) ?? 0,
|
|
14027
|
-
denied: finiteNumber(decisions.escalationDenied) ?? 0,
|
|
14028
|
-
timedOut: finiteNumber(decisions.escalationTimedOut) ?? 0
|
|
14029
|
-
};
|
|
14030
|
-
}
|
|
14031
|
-
function escalationCountsFrom(safety) {
|
|
14032
|
-
const decisions = safety?.decisions;
|
|
14033
|
-
if (decisions === void 0 || decisions.escalationRequested === void 0) return null;
|
|
14034
|
-
return {
|
|
14035
|
-
requested: decisions.escalationRequested,
|
|
14036
|
-
approved: decisions.escalationApproved ?? 0,
|
|
14037
|
-
denied: decisions.escalationDenied ?? 0,
|
|
14038
|
-
timedOut: decisions.escalationTimedOut ?? 0
|
|
14039
|
-
};
|
|
14040
|
-
}
|
|
14041
|
-
function formatPersonaHashPrefix(promptHash2) {
|
|
14042
|
-
if (promptHash2.length <= PERSONA_HASH_PREFIX_CHARS) return promptHash2;
|
|
14043
|
-
return `${promptHash2.slice(0, PERSONA_HASH_PREFIX_CHARS)}...`;
|
|
13366
|
+
return null;
|
|
14044
13367
|
}
|
|
14045
|
-
function
|
|
14046
|
-
|
|
14047
|
-
if (view.pipeline !== void 0) {
|
|
14048
|
-
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
14049
|
-
const source = fromRunId ?? "unknown";
|
|
14050
|
-
const truncation = inputTruncated ? "input truncated" : "not truncated";
|
|
14051
|
-
lines.push(`pipeline: step ${position}, input ${inputBytes} bytes from ${source} (${truncation})`);
|
|
14052
|
-
}
|
|
14053
|
-
if (view.personaOverride !== void 0) {
|
|
14054
|
-
lines.push(`persona override: prompt hash ${formatPersonaHashPrefix(view.personaOverride.promptHash)}`);
|
|
14055
|
-
}
|
|
14056
|
-
if (view.escalation !== void 0) {
|
|
14057
|
-
const { requested, approved, denied, timedOut } = view.escalation;
|
|
14058
|
-
lines.push(`escalations: ${requested} requested, ${approved} approved, ${denied} denied, ${timedOut} timed out`);
|
|
14059
|
-
}
|
|
14060
|
-
if (view.autonomyEnforcement !== void 0) {
|
|
14061
|
-
const { grade, autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
14062
|
-
const mode = externalMode !== void 0 ? ` mode=${externalMode}` : "";
|
|
14063
|
-
const bypass = dangerousBypass === true ? " dangerousBypass=true" : "";
|
|
14064
|
-
lines.push(`autonomy enforcement: ${grade} autonomy=${autonomy}${mode}${bypass}`);
|
|
14065
|
-
}
|
|
14066
|
-
return lines;
|
|
13368
|
+
function isFinishContractEvidenceKind(value) {
|
|
13369
|
+
return value === "validation_command" || value === "protected_artifact" || value === "dispatch_receipt";
|
|
14067
13370
|
}
|
|
14068
|
-
function
|
|
14069
|
-
|
|
14070
|
-
if (view.pipeline !== void 0) {
|
|
14071
|
-
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
14072
|
-
const from = fromRunId ?? "unknown";
|
|
14073
|
-
parts.push(`pipeline=step${position} from=${from} in=${inputBytes}b${inputTruncated ? " truncated" : ""}`);
|
|
14074
|
-
}
|
|
14075
|
-
if (view.personaOverride !== void 0) {
|
|
14076
|
-
parts.push(`persona=${formatPersonaHashPrefix(view.personaOverride.promptHash)}`);
|
|
14077
|
-
}
|
|
14078
|
-
if (view.escalation !== void 0) {
|
|
14079
|
-
const { requested, approved, denied, timedOut } = view.escalation;
|
|
14080
|
-
parts.push(`escalations=${requested}req/${approved}appr/${denied}deny/${timedOut}timeout`);
|
|
14081
|
-
}
|
|
14082
|
-
if (view.autonomyEnforcement !== void 0) {
|
|
14083
|
-
const { grade, autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
14084
|
-
const mode = externalMode !== void 0 ? `/${externalMode}` : "";
|
|
14085
|
-
const bypass = dangerousBypass === true ? "/bypass" : "";
|
|
14086
|
-
parts.push(`enforcement=${grade}:${autonomy}${mode}${bypass}`);
|
|
14087
|
-
}
|
|
14088
|
-
return parts.length === 0 ? "" : ` ${parts.join(" ")}`;
|
|
13371
|
+
function readOptionalString(value) {
|
|
13372
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
14089
13373
|
}
|
|
14090
13374
|
|
|
14091
13375
|
// src/domains/evidence/store.ts
|
|
14092
13376
|
init_esm_shims();
|
|
14093
|
-
import { readdir
|
|
14094
|
-
import { join as
|
|
13377
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
13378
|
+
import { join as join15 } from "node:path";
|
|
14095
13379
|
var EVIDENCE_FILES = [
|
|
14096
13380
|
"overview.json",
|
|
14097
13381
|
"transcript.md",
|
|
@@ -14101,16 +13385,17 @@ var EVIDENCE_FILES = [
|
|
|
14101
13385
|
"audit-linked.jsonl",
|
|
14102
13386
|
"receipt.json",
|
|
14103
13387
|
"gate-decisions.json",
|
|
13388
|
+
"trust-status.json",
|
|
14104
13389
|
"protected-artifacts.json",
|
|
14105
13390
|
"findings.json",
|
|
14106
13391
|
"findings.md"
|
|
14107
13392
|
];
|
|
14108
13393
|
function evidenceRoot(dataDir) {
|
|
14109
|
-
return
|
|
13394
|
+
return join15(dataDir, "evidence");
|
|
14110
13395
|
}
|
|
14111
13396
|
function evidenceDirectory(dataDir, evidenceId) {
|
|
14112
13397
|
assertSafeId(evidenceId, "evidence");
|
|
14113
|
-
return
|
|
13398
|
+
return join15(evidenceRoot(dataDir), evidenceId);
|
|
14114
13399
|
}
|
|
14115
13400
|
var EvidenceNotFoundError = class extends Error {
|
|
14116
13401
|
constructor(evidenceId) {
|
|
@@ -14126,7 +13411,7 @@ function isMissingFile(error) {
|
|
|
14126
13411
|
async function loadEvidenceOverview(dataDir, evidenceId) {
|
|
14127
13412
|
let raw;
|
|
14128
13413
|
try {
|
|
14129
|
-
raw = await
|
|
13414
|
+
raw = await readFile(join15(evidenceDirectory(dataDir, evidenceId), "overview.json"), "utf8");
|
|
14130
13415
|
} catch (error) {
|
|
14131
13416
|
if (isMissingFile(error)) throw new EvidenceNotFoundError(evidenceId);
|
|
14132
13417
|
throw error;
|
|
@@ -14138,19 +13423,52 @@ async function inspectEvidence(dataDir, evidenceId) {
|
|
|
14138
13423
|
const overview = await loadEvidenceOverview(dataDir, evidenceId);
|
|
14139
13424
|
let findingsRaw;
|
|
14140
13425
|
try {
|
|
14141
|
-
findingsRaw = await
|
|
13426
|
+
findingsRaw = await readFile(join15(evidenceDirectory(dataDir, evidenceId), "findings.json"), "utf8");
|
|
14142
13427
|
} catch (error) {
|
|
14143
13428
|
if (isMissingFile(error)) throw new Error(`evidence artifact ${evidenceId} is missing findings.json`);
|
|
14144
13429
|
throw error;
|
|
14145
13430
|
}
|
|
14146
13431
|
const findingsParsed = parseJson(findingsRaw, `${evidenceId}/findings.json`);
|
|
14147
13432
|
const findings = parseFindingsFile(findingsParsed, `${evidenceId}/findings.json`);
|
|
14148
|
-
return { overview, findings };
|
|
13433
|
+
return { overview, findings, trustStatus: await loadEvidenceTrustStatus(dataDir, evidenceId) };
|
|
13434
|
+
}
|
|
13435
|
+
async function loadEvidenceTrustStatus(dataDir, evidenceId) {
|
|
13436
|
+
let raw;
|
|
13437
|
+
try {
|
|
13438
|
+
raw = await readFile(join15(evidenceDirectory(dataDir, evidenceId), "trust-status.json"), "utf8");
|
|
13439
|
+
} catch (error) {
|
|
13440
|
+
if (isMissingFile(error)) {
|
|
13441
|
+
return { version: 1, evidenceId, projection: "historical_format", runs: [] };
|
|
13442
|
+
}
|
|
13443
|
+
throw error;
|
|
13444
|
+
}
|
|
13445
|
+
const source = `${evidenceId}/trust-status.json`;
|
|
13446
|
+
const parsed = parseJson(raw, source);
|
|
13447
|
+
if (!isRecord11(parsed)) throw new Error(`${source}: expected object`);
|
|
13448
|
+
if (parsed.version !== 1) throw new Error(`${source}: expected version 1`);
|
|
13449
|
+
if (readString(parsed, source, "evidenceId") !== evidenceId) {
|
|
13450
|
+
throw new Error(`${source}.evidenceId: expected ${evidenceId}`);
|
|
13451
|
+
}
|
|
13452
|
+
if (parsed.projection !== "canonical") throw new Error(`${source}.projection: expected canonical`);
|
|
13453
|
+
if (!Array.isArray(parsed.runs)) throw new Error(`${source}.runs: expected array`);
|
|
13454
|
+
return {
|
|
13455
|
+
version: 1,
|
|
13456
|
+
evidenceId,
|
|
13457
|
+
projection: "canonical",
|
|
13458
|
+
runs: parsed.runs.map((entry, index) => {
|
|
13459
|
+
const entrySource = `${source}.runs[${index}]`;
|
|
13460
|
+
if (!isRecord11(entry)) throw new Error(`${entrySource}: expected object`);
|
|
13461
|
+
return {
|
|
13462
|
+
runId: readString(entry, entrySource, "runId"),
|
|
13463
|
+
status: normalizeTrustStatus(entry.status)
|
|
13464
|
+
};
|
|
13465
|
+
})
|
|
13466
|
+
};
|
|
14149
13467
|
}
|
|
14150
13468
|
async function loadEvidenceRunProvenance(dataDir, evidenceId) {
|
|
14151
13469
|
let raw;
|
|
14152
13470
|
try {
|
|
14153
|
-
raw = await
|
|
13471
|
+
raw = await readFile(join15(evidenceDirectory(dataDir, evidenceId), "receipt.json"), "utf8");
|
|
14154
13472
|
} catch (error) {
|
|
14155
13473
|
const err = error;
|
|
14156
13474
|
if (err.code === "ENOENT") return [];
|
|
@@ -14169,14 +13487,14 @@ async function loadEvidenceRunProvenance(dataDir, evidenceId) {
|
|
|
14169
13487
|
async function listEvidenceOverviews(dataDir) {
|
|
14170
13488
|
let entries;
|
|
14171
13489
|
try {
|
|
14172
|
-
entries = await
|
|
13490
|
+
entries = await readdir(evidenceRoot(dataDir));
|
|
14173
13491
|
} catch (error) {
|
|
14174
13492
|
const err = error;
|
|
14175
13493
|
if (err.code === "ENOENT") return [];
|
|
14176
13494
|
throw error;
|
|
14177
13495
|
}
|
|
14178
13496
|
const overviews = [];
|
|
14179
|
-
for (const entry of entries.sort(
|
|
13497
|
+
for (const entry of entries.sort(compareCodepoints)) {
|
|
14180
13498
|
try {
|
|
14181
13499
|
overviews.push(await loadEvidenceOverview(dataDir, entry));
|
|
14182
13500
|
} catch {
|
|
@@ -14313,26 +13631,10 @@ function parseJson(raw, source) {
|
|
|
14313
13631
|
function isRecord11(value) {
|
|
14314
13632
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14315
13633
|
}
|
|
14316
|
-
function compareStrings4(a, b) {
|
|
14317
|
-
return a.localeCompare(b);
|
|
14318
|
-
}
|
|
14319
13634
|
function findingsFile(evidenceId, findings) {
|
|
14320
13635
|
return { version: 1, evidenceId, findings };
|
|
14321
13636
|
}
|
|
14322
13637
|
|
|
14323
|
-
// src/domains/evidence/types.ts
|
|
14324
|
-
init_esm_shims();
|
|
14325
|
-
var EVIDENCE_VERSION = 1;
|
|
14326
|
-
var FAILURE_CAUSE_TAG_ORDER = [
|
|
14327
|
-
"timeout",
|
|
14328
|
-
"auth-failure",
|
|
14329
|
-
"missing-dependency",
|
|
14330
|
-
"build-failure",
|
|
14331
|
-
"test-failure",
|
|
14332
|
-
"blocked-tool"
|
|
14333
|
-
];
|
|
14334
|
-
var FAILURE_CAUSE_TAGS = new Set(FAILURE_CAUSE_TAG_ORDER);
|
|
14335
|
-
|
|
14336
13638
|
// src/domains/evidence/build.ts
|
|
14337
13639
|
var MAX_TASK_CHARS = 500;
|
|
14338
13640
|
var TRANSCRIPT_TEXT_MAX_CHARS = 500;
|
|
@@ -14376,7 +13678,15 @@ async function buildEvidence(options) {
|
|
|
14376
13678
|
const auditLinks = await linkAuditRows(options.stateDir, source, runSources, sessionLinks);
|
|
14377
13679
|
const toolEventRows = toolEvents(runSources, sessionLinks, auditLinks);
|
|
14378
13680
|
const protectedArtifactsRaw = protectedArtifactsFile(sessionLinks);
|
|
14379
|
-
const
|
|
13681
|
+
const validationEvidence = validationEvidenceByRun(sessionLinks.entries, runSources);
|
|
13682
|
+
const trustStatusRaw = buildEvidenceTrustStatusFile({
|
|
13683
|
+
evidenceId,
|
|
13684
|
+
runSources,
|
|
13685
|
+
gateDecisions: gateDecisions.decisions,
|
|
13686
|
+
auditRows: auditLinks.rows,
|
|
13687
|
+
validationEvidence
|
|
13688
|
+
});
|
|
13689
|
+
const findings = buildFindings(runSources, trustStatusRaw, sessionLinks, auditLinks, protectedArtifactsRaw);
|
|
14380
13690
|
const tally = createRedactionTally();
|
|
14381
13691
|
const redactedRunSources = runSources.map((item) => ({
|
|
14382
13692
|
...item,
|
|
@@ -14393,6 +13703,7 @@ async function buildEvidence(options) {
|
|
|
14393
13703
|
readErrors: auditLinks.readErrors
|
|
14394
13704
|
};
|
|
14395
13705
|
const protectedArtifacts = redactSecretsDeep(protectedArtifactsRaw, tally);
|
|
13706
|
+
const trustStatus = redactSecretsDeep(trustStatusRaw, tally);
|
|
14396
13707
|
const overview = buildOverview(
|
|
14397
13708
|
evidenceId,
|
|
14398
13709
|
source,
|
|
@@ -14414,16 +13725,17 @@ async function buildEvidence(options) {
|
|
|
14414
13725
|
redactedAuditLinks,
|
|
14415
13726
|
redactedToolEvents,
|
|
14416
13727
|
gateDecisions,
|
|
13728
|
+
trustStatus,
|
|
14417
13729
|
protectedArtifacts,
|
|
14418
13730
|
transcript
|
|
14419
13731
|
);
|
|
14420
|
-
return { evidenceId, directory, overview: finalOverview, findings };
|
|
13732
|
+
return { evidenceId, directory, overview: finalOverview, findings, trustStatus };
|
|
14421
13733
|
}
|
|
14422
13734
|
function buildOverview(evidenceId, source, runSources, findings, sessionLinks, auditLinks, toolEventRows, protectedArtifacts) {
|
|
14423
13735
|
const envelopes = runSources.map((item) => item.envelope);
|
|
14424
13736
|
const receipts = runSources.flatMap((item) => item.receipt === null ? [] : [item.receipt]);
|
|
14425
13737
|
const toolStats = receipts.flatMap((receipt) => receipt.toolStats);
|
|
14426
|
-
const runIds = envelopes.map((envelope) => envelope.id).sort(
|
|
13738
|
+
const runIds = envelopes.map((envelope) => envelope.id).sort(compareCodepoints);
|
|
14427
13739
|
const sessionIds = uniqueStrings(
|
|
14428
13740
|
envelopes.flatMap((envelope) => envelope.sessionId === null ? [] : [envelope.sessionId])
|
|
14429
13741
|
);
|
|
@@ -14468,15 +13780,17 @@ function buildOverview(evidenceId, source, runSources, findings, sessionLinks, a
|
|
|
14468
13780
|
files: [...EVIDENCE_FILES]
|
|
14469
13781
|
};
|
|
14470
13782
|
}
|
|
14471
|
-
function buildFindings(runSources, sessionLinks, auditLinks, protectedArtifacts) {
|
|
13783
|
+
function buildFindings(runSources, trustStatus, sessionLinks, auditLinks, protectedArtifacts) {
|
|
14472
13784
|
const findings = [];
|
|
14473
|
-
const
|
|
13785
|
+
const trustByRun = new Map(trustStatus.runs.map((entry) => [entry.runId, entry.status]));
|
|
14474
13786
|
for (const source of runSources) {
|
|
13787
|
+
const status = trustByRun.get(source.envelope.id);
|
|
13788
|
+
if (status === void 0) throw new Error(`canonical trust status missing for run ${source.envelope.id}`);
|
|
14475
13789
|
if (source.receiptError !== null) {
|
|
14476
13790
|
const tag = source.receiptIntegrityFailed ? "receipt-integrity" : "unknown";
|
|
14477
13791
|
findings.push(finding(findings.length, "warn", tag, source.envelope.id, source.receiptError));
|
|
14478
13792
|
}
|
|
14479
|
-
if (isSuccessfulRun(source) &&
|
|
13793
|
+
if (isSuccessfulRun(source) && (status.validationGrounding.state === "absent" || status.validationGrounding.state === "unknown")) {
|
|
14480
13794
|
findings.push(
|
|
14481
13795
|
finding(
|
|
14482
13796
|
findings.length,
|
|
@@ -14487,10 +13801,21 @@ function buildFindings(runSources, sessionLinks, auditLinks, protectedArtifacts)
|
|
|
14487
13801
|
)
|
|
14488
13802
|
);
|
|
14489
13803
|
}
|
|
13804
|
+
if (status.validationGrounding.state === "ungrounded") {
|
|
13805
|
+
findings.push(
|
|
13806
|
+
finding(
|
|
13807
|
+
findings.length,
|
|
13808
|
+
"warn",
|
|
13809
|
+
"proxy-validation",
|
|
13810
|
+
source.envelope.id,
|
|
13811
|
+
"run claimed validation that was not grounded in an observed execution"
|
|
13812
|
+
)
|
|
13813
|
+
);
|
|
13814
|
+
}
|
|
14490
13815
|
if (source.envelope.cwd.trim().length === 0) {
|
|
14491
13816
|
findings.push(finding(findings.length, "warn", "cwd-missing", source.envelope.id, "run ledger cwd is empty"));
|
|
14492
13817
|
}
|
|
14493
|
-
const receipt = source
|
|
13818
|
+
const receipt = authenticatedReceipt(source);
|
|
14494
13819
|
const blocked = receipt?.toolStats.reduce((total, stat) => total + stat.blocked, 0) ?? 0;
|
|
14495
13820
|
if (blocked > 0) {
|
|
14496
13821
|
findings.push(
|
|
@@ -14509,12 +13834,11 @@ function buildFindings(runSources, sessionLinks, auditLinks, protectedArtifacts)
|
|
|
14509
13834
|
)
|
|
14510
13835
|
);
|
|
14511
13836
|
}
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
const message = autonomyEnforcement.externalMode === "agent-managed" ? "run used external agent-managed governance; Clio safety blocks were not enforced" : "run executed with external permission bypass (CLIO_CODER_ALLOW_EXTERNAL_FULL_ACCESS=1); Clio safety blocks were not enforced";
|
|
13837
|
+
if (status.autonomyEnforcement.state === "bypassed") {
|
|
13838
|
+
const message = status.autonomyEnforcement.authority.id === "agent-managed" ? "run used external agent-managed governance; Clio safety blocks were not enforced" : "run executed with external permission bypass (CLIO_CODER_ALLOW_EXTERNAL_FULL_ACCESS=1); Clio safety blocks were not enforced";
|
|
14515
13839
|
findings.push(finding(findings.length, "warn", "external-bypass", source.envelope.id, message));
|
|
14516
|
-
} else if (autonomyEnforcement
|
|
14517
|
-
const mode = autonomyEnforcement.
|
|
13840
|
+
} else if (status.autonomyEnforcement.state === "approximated") {
|
|
13841
|
+
const mode = status.autonomyEnforcement.authority.id === "external-runtime" ? "" : ` via ${status.autonomyEnforcement.authority.id}`;
|
|
14518
13842
|
findings.push(
|
|
14519
13843
|
finding(
|
|
14520
13844
|
findings.length,
|
|
@@ -14601,19 +13925,22 @@ function buildFindings(runSources, sessionLinks, auditLinks, protectedArtifacts)
|
|
|
14601
13925
|
}
|
|
14602
13926
|
return findings;
|
|
14603
13927
|
}
|
|
14604
|
-
function
|
|
14605
|
-
const
|
|
14606
|
-
const sourceRunIds = new Set(runSources.map((source) => source.envelope.id));
|
|
13928
|
+
function validationEvidenceByRun(entries, runSources) {
|
|
13929
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
14607
13930
|
const calls = /* @__PURE__ */ new Map();
|
|
14608
13931
|
for (const linked of entries) {
|
|
14609
13932
|
const runId = validationRunIdFor(linked, runSources);
|
|
14610
13933
|
const entry = linked.entry;
|
|
14611
13934
|
if (entry.kind === "bashExecution") {
|
|
14612
|
-
if (runId !== null && isSuccessfulValidationBashExecution(entry))
|
|
13935
|
+
if (runId !== null && isSuccessfulValidationBashExecution(entry)) {
|
|
13936
|
+
addValidationEvidence(evidence, runId, { kind: "session_entry", id: entry.turnId });
|
|
13937
|
+
}
|
|
14613
13938
|
continue;
|
|
14614
13939
|
}
|
|
14615
13940
|
if (entry.kind === "protectedArtifact") {
|
|
14616
|
-
if (runId !== null && isValidationProtectedArtifact(entry))
|
|
13941
|
+
if (runId !== null && isValidationProtectedArtifact(entry)) {
|
|
13942
|
+
addValidationEvidence(evidence, runId, { kind: "session_entry", id: entry.turnId });
|
|
13943
|
+
}
|
|
14617
13944
|
continue;
|
|
14618
13945
|
}
|
|
14619
13946
|
if (entry.kind !== "message") continue;
|
|
@@ -14626,16 +13953,16 @@ function validationEvidenceRunIds(entries, runSources, auditRows) {
|
|
|
14626
13953
|
const result = extractSessionToolResult(entry, linked);
|
|
14627
13954
|
if (result.id === null || !isSuccessfulSessionToolResult(result)) continue;
|
|
14628
13955
|
const candidate = calls.get(result.id);
|
|
14629
|
-
if (candidate?.runId !== null && candidate?.runId !== void 0)
|
|
14630
|
-
|
|
14631
|
-
|
|
14632
|
-
if (linked.auditKind !== "completion_contract") continue;
|
|
14633
|
-
if (linked.runId === null || !sourceRunIds.has(linked.runId)) continue;
|
|
14634
|
-
if (readOptionalString2(linked.row.decision) !== "ok") continue;
|
|
14635
|
-
if (readOptionalString2(linked.row.reason) !== "validation_evidence") continue;
|
|
14636
|
-
runIds.add(linked.runId);
|
|
13956
|
+
if (candidate?.runId !== null && candidate?.runId !== void 0) {
|
|
13957
|
+
addValidationEvidence(evidence, candidate.runId, candidate.artifact);
|
|
13958
|
+
}
|
|
14637
13959
|
}
|
|
14638
|
-
return
|
|
13960
|
+
return evidence;
|
|
13961
|
+
}
|
|
13962
|
+
function addValidationEvidence(evidence, runId, reference) {
|
|
13963
|
+
const current = evidence.get(runId) ?? [];
|
|
13964
|
+
current.push(reference);
|
|
13965
|
+
evidence.set(runId, current);
|
|
14639
13966
|
}
|
|
14640
13967
|
function validationRunIdFor(linked, runSources) {
|
|
14641
13968
|
if (linked.link.runId !== null) return linked.link.runId;
|
|
@@ -14643,11 +13970,15 @@ function validationRunIdFor(linked, runSources) {
|
|
|
14643
13970
|
return runSources[0]?.envelope.id ?? null;
|
|
14644
13971
|
}
|
|
14645
13972
|
function isSuccessfulRun(source) {
|
|
14646
|
-
const
|
|
13973
|
+
const receipt = authenticatedReceipt(source);
|
|
13974
|
+
const outcome = receipt?.outcome ?? source.envelope.outcome ?? null;
|
|
14647
13975
|
if (outcome !== null) return outcome === "succeeded";
|
|
14648
|
-
const exitCode =
|
|
13976
|
+
const exitCode = receipt?.exitCode ?? source.envelope.exitCode;
|
|
14649
13977
|
return source.envelope.status === "completed" && exitCode === 0;
|
|
14650
13978
|
}
|
|
13979
|
+
function authenticatedReceipt(source) {
|
|
13980
|
+
return source.receipt !== null && source.receiptError === null && !source.receiptIntegrityFailed ? source.receipt : null;
|
|
13981
|
+
}
|
|
14651
13982
|
function isSuccessfulValidationBashExecution(entry) {
|
|
14652
13983
|
if (entry.cancelled || entry.exitCode !== 0) return false;
|
|
14653
13984
|
return detectValidationCommand(entry.command).kind === "validation";
|
|
@@ -14662,7 +13993,8 @@ function validationToolCallCandidate(entry, linked, runSources) {
|
|
|
14662
13993
|
if (validationToolCallSummary(call.tool, call.args) === null) return null;
|
|
14663
13994
|
return {
|
|
14664
13995
|
toolCallId: call.id,
|
|
14665
|
-
runId: validationRunIdFor(linked, runSources)
|
|
13996
|
+
runId: validationRunIdFor(linked, runSources),
|
|
13997
|
+
artifact: { kind: "session_entry", id: entry.turnId }
|
|
14666
13998
|
};
|
|
14667
13999
|
}
|
|
14668
14000
|
function validationToolCallSummary(toolName, args) {
|
|
@@ -14680,8 +14012,10 @@ function validationToolCallSummary(toolName, args) {
|
|
|
14680
14012
|
const target = readOptionalString2(argRecord?.path) ?? "artifact";
|
|
14681
14013
|
return `verify frontend ${target}`;
|
|
14682
14014
|
}
|
|
14683
|
-
if (check === null
|
|
14684
|
-
return `npm run ${check}`;
|
|
14015
|
+
if (check === null) return null;
|
|
14016
|
+
if (isVerificationScriptName(check)) return `npm run ${check}`;
|
|
14017
|
+
if (isProjectVerifierCheckId(check)) return `verify ${check}`;
|
|
14018
|
+
return null;
|
|
14685
14019
|
}
|
|
14686
14020
|
return null;
|
|
14687
14021
|
}
|
|
@@ -14700,23 +14034,24 @@ function finding(index, severity, tag, runId, message) {
|
|
|
14700
14034
|
message
|
|
14701
14035
|
};
|
|
14702
14036
|
}
|
|
14703
|
-
async function writeEvidenceFiles(directory, overview, runSources, findings, sessionLinks, auditLinks, toolEventRows, gateDecisions, protectedArtifacts, transcript) {
|
|
14037
|
+
async function writeEvidenceFiles(directory, overview, runSources, findings, sessionLinks, auditLinks, toolEventRows, gateDecisions, trustStatus, protectedArtifacts, transcript) {
|
|
14704
14038
|
await mkdir(directory, { recursive: true });
|
|
14705
|
-
await writeJson(
|
|
14039
|
+
await writeJson(join16(directory, "overview.json"), overview);
|
|
14706
14040
|
await writeFile(
|
|
14707
|
-
|
|
14041
|
+
join16(directory, "transcript.md"),
|
|
14708
14042
|
transcript ?? renderTranscript(overview, runSources, sessionLinks),
|
|
14709
14043
|
"utf8"
|
|
14710
14044
|
);
|
|
14711
|
-
await writeJsonl(
|
|
14712
|
-
await writeJsonl(
|
|
14713
|
-
await writeJsonl(
|
|
14714
|
-
await writeJsonl(
|
|
14715
|
-
await writeJson(
|
|
14716
|
-
await writeJson(
|
|
14717
|
-
await writeJson(
|
|
14718
|
-
await writeJson(
|
|
14719
|
-
await
|
|
14045
|
+
await writeJsonl(join16(directory, "trace.raw.jsonl"), rawTraceRows(runSources));
|
|
14046
|
+
await writeJsonl(join16(directory, "trace.cleaned.jsonl"), cleanedTraceRows(runSources, findings, toolEventRows));
|
|
14047
|
+
await writeJsonl(join16(directory, "tool-events.jsonl"), toolEventRows);
|
|
14048
|
+
await writeJsonl(join16(directory, "audit-linked.jsonl"), auditLinks.rows);
|
|
14049
|
+
await writeJson(join16(directory, "receipt.json"), receiptsFile(runSources));
|
|
14050
|
+
await writeJson(join16(directory, "gate-decisions.json"), gateDecisions);
|
|
14051
|
+
await writeJson(join16(directory, "trust-status.json"), trustStatus);
|
|
14052
|
+
await writeJson(join16(directory, "protected-artifacts.json"), protectedArtifacts);
|
|
14053
|
+
await writeJson(join16(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
|
|
14054
|
+
await writeFile(join16(directory, "findings.md"), renderFindings(findings), "utf8");
|
|
14720
14055
|
}
|
|
14721
14056
|
function rawTraceRows(runSources) {
|
|
14722
14057
|
const rows = [];
|
|
@@ -14835,7 +14170,7 @@ function linkSessionEntry(entry, windows) {
|
|
|
14835
14170
|
if (stamped !== null) {
|
|
14836
14171
|
return { runId: stamped, kind: "entry-run-id", confidence: "exact", candidateRunIds: [stamped] };
|
|
14837
14172
|
}
|
|
14838
|
-
const candidates = windows.filter((window) => timestampInRunWindow(entry.timestamp, window)).map((window) => window.runId).sort(
|
|
14173
|
+
const candidates = windows.filter((window) => timestampInRunWindow(entry.timestamp, window)).map((window) => window.runId).sort(compareCodepoints);
|
|
14839
14174
|
const only = candidates.length === 1 ? candidates[0] : void 0;
|
|
14840
14175
|
if (only !== void 0) {
|
|
14841
14176
|
return { runId: only, kind: "timestamp-window", confidence: "best-effort", candidateRunIds: candidates };
|
|
@@ -14867,7 +14202,7 @@ function attributionWindows(ledger, runSources, sessionIds) {
|
|
|
14867
14202
|
if (windows.has(id) || !linkedSessions.has(sessionId)) continue;
|
|
14868
14203
|
windows.set(id, { runId: id, startedAt, endedAt: readOptionalString2(row.endedAt) });
|
|
14869
14204
|
}
|
|
14870
|
-
return [...windows.values()].sort((left, right) =>
|
|
14205
|
+
return [...windows.values()].sort((left, right) => compareCodepoints(left.runId, right.runId));
|
|
14871
14206
|
}
|
|
14872
14207
|
function evidenceRunLink(link) {
|
|
14873
14208
|
return {
|
|
@@ -14884,11 +14219,11 @@ function timestampInRunWindow(timestamp, envelope) {
|
|
|
14884
14219
|
return value >= start && value <= end;
|
|
14885
14220
|
}
|
|
14886
14221
|
function compareLinkedSessionEntries(a, b) {
|
|
14887
|
-
const byTimestamp =
|
|
14222
|
+
const byTimestamp = compareCodepoints(a.entry.timestamp, b.entry.timestamp);
|
|
14888
14223
|
if (byTimestamp !== 0) return byTimestamp;
|
|
14889
|
-
const bySession =
|
|
14224
|
+
const bySession = compareCodepoints(a.sessionId, b.sessionId);
|
|
14890
14225
|
if (bySession !== 0) return bySession;
|
|
14891
|
-
return
|
|
14226
|
+
return compareCodepoints(a.entry.turnId, b.entry.turnId);
|
|
14892
14227
|
}
|
|
14893
14228
|
function sessionToolEvents(entries) {
|
|
14894
14229
|
const calls = /* @__PURE__ */ new Map();
|
|
@@ -15002,9 +14337,9 @@ function extractSessionToolResult(entry, linked) {
|
|
|
15002
14337
|
};
|
|
15003
14338
|
}
|
|
15004
14339
|
function compareSessionToolCalls(a, b) {
|
|
15005
|
-
const byTimestamp =
|
|
14340
|
+
const byTimestamp = compareCodepoints(a.timestamp, b.timestamp);
|
|
15006
14341
|
if (byTimestamp !== 0) return byTimestamp;
|
|
15007
|
-
return
|
|
14342
|
+
return compareCodepoints(a.id, b.id);
|
|
15008
14343
|
}
|
|
15009
14344
|
async function linkAuditRows(stateDir, source, runSources, sessionLinks) {
|
|
15010
14345
|
const auditRows = await readAuditRows(stateDir);
|
|
@@ -15089,7 +14424,7 @@ function bestEffortAuditLink(audit, source, runSources, sessionIds) {
|
|
|
15089
14424
|
linkKind: "ambiguous-timestamp-tool",
|
|
15090
14425
|
confidence: "best-effort",
|
|
15091
14426
|
reasons: ["audit timestamp and tool matched multiple runs in this session"],
|
|
15092
|
-
candidateRunIds: candidates.map((item) => item.envelope.id).sort(
|
|
14427
|
+
candidateRunIds: candidates.map((item) => item.envelope.id).sort(compareCodepoints)
|
|
15093
14428
|
};
|
|
15094
14429
|
}
|
|
15095
14430
|
if (source.kind === "session" && sessionIds.has(source.sessionId)) {
|
|
@@ -15156,12 +14491,12 @@ function auditToolEvents(rows) {
|
|
|
15156
14491
|
function compareAuditLinkedRows(a, b) {
|
|
15157
14492
|
const byTs = compareNullableStrings(a.ts, b.ts);
|
|
15158
14493
|
if (byTs !== 0) return byTs;
|
|
15159
|
-
const byKind =
|
|
14494
|
+
const byKind = compareCodepoints(a.auditKind, b.auditKind);
|
|
15160
14495
|
if (byKind !== 0) return byKind;
|
|
15161
14496
|
const aCorrelation = readOptionalString2(a.row.correlationId) ?? "";
|
|
15162
14497
|
const bCorrelation = readOptionalString2(b.row.correlationId) ?? "";
|
|
15163
|
-
if (aCorrelation !== bCorrelation) return
|
|
15164
|
-
return JSON.stringify(a.row)
|
|
14498
|
+
if (aCorrelation !== bCorrelation) return compareCodepoints(aCorrelation, bCorrelation);
|
|
14499
|
+
return compareCodepoints(JSON.stringify(a.row), JSON.stringify(b.row));
|
|
15165
14500
|
}
|
|
15166
14501
|
function receiptsFile(runSources) {
|
|
15167
14502
|
return {
|
|
@@ -15198,7 +14533,7 @@ function protectedArtifactsFile(sessionLinks) {
|
|
|
15198
14533
|
};
|
|
15199
14534
|
}
|
|
15200
14535
|
function compareProtectedArtifactEvents(left, right) {
|
|
15201
|
-
return
|
|
14536
|
+
return compareCodepoints(left.timestamp, right.timestamp) || compareCodepoints(left.sessionId, right.sessionId) || compareCodepoints(left.turnId, right.turnId) || compareCodepoints(left.artifact.path, right.artifact.path);
|
|
15202
14537
|
}
|
|
15203
14538
|
function renderTranscript(overview, runSources, sessionLinks) {
|
|
15204
14539
|
const lines = [
|
|
@@ -15259,7 +14594,7 @@ function renderSessionTranscriptEntry(linked) {
|
|
|
15259
14594
|
const error = result.isError ? " error=true" : "";
|
|
15260
14595
|
return [`${prefix} tool_result ${result.tool}${id}${error}: ${previewUnknown(result.result)}`];
|
|
15261
14596
|
}
|
|
15262
|
-
const text =
|
|
14597
|
+
const text = collapseWhitespace(extractTextFromPayload(entry.payload));
|
|
15263
14598
|
const rendered = text.length > 0 ? truncateText(text, TRANSCRIPT_TEXT_MAX_CHARS) : previewUnknown(entry.payload);
|
|
15264
14599
|
return [`${prefix} ${entry.role}: ${rendered}`];
|
|
15265
14600
|
}
|
|
@@ -15344,6 +14679,18 @@ function renderSessionTranscriptEntry(linked) {
|
|
|
15344
14679
|
];
|
|
15345
14680
|
}
|
|
15346
14681
|
if (entry.kind === "custom") return [`${prefix} custom:${entry.customType} ${previewUnknown(entry.data)}`];
|
|
14682
|
+
if (entry.kind === "contextEviction") {
|
|
14683
|
+
const pressure = entry.pressureBefore === null ? "" : ` pressure=${entry.pressureBefore.toFixed(3)}`;
|
|
14684
|
+
return [
|
|
14685
|
+
`${prefix} contextEviction policy=${entry.policyId} trigger=${entry.trigger} items=${entry.evicted.length} tokens=${entry.tokensBefore}->${entry.tokensAfter}${pressure}`,
|
|
14686
|
+
...entry.evicted.map(
|
|
14687
|
+
(item) => ` evicted ref=${item.ref.entry} reason=${item.reason}${item.by === void 0 ? "" : ` by=${item.by}`} freed=${item.tokensFreed}`
|
|
14688
|
+
)
|
|
14689
|
+
];
|
|
14690
|
+
}
|
|
14691
|
+
if (entry.kind === "contextRecall") {
|
|
14692
|
+
return [`${prefix} contextRecall ref=${entry.ref.entry} trigger=${entry.trigger} tokens=${entry.tokensReadmitted}`];
|
|
14693
|
+
}
|
|
15347
14694
|
const _exhaustive = entry;
|
|
15348
14695
|
return [`${prefix} ${String(_exhaustive)}`];
|
|
15349
14696
|
}
|
|
@@ -15359,10 +14706,10 @@ function renderFindings(findings) {
|
|
|
15359
14706
|
`;
|
|
15360
14707
|
}
|
|
15361
14708
|
async function readRunLedger(stateDir) {
|
|
15362
|
-
const target =
|
|
14709
|
+
const target = join16(stateDir, "runs.json");
|
|
15363
14710
|
let raw;
|
|
15364
14711
|
try {
|
|
15365
|
-
raw = await
|
|
14712
|
+
raw = await readFile2(target, "utf8");
|
|
15366
14713
|
} catch (error) {
|
|
15367
14714
|
const err = error;
|
|
15368
14715
|
if (err.code === "ENOENT") throw new Error("run ledger not found");
|
|
@@ -15380,10 +14727,10 @@ function selectRunEnvelopes(ledger, source) {
|
|
|
15380
14727
|
});
|
|
15381
14728
|
}
|
|
15382
14729
|
async function readReceipt(stateDir, envelope) {
|
|
15383
|
-
const receiptPath = envelope.receiptPath ??
|
|
14730
|
+
const receiptPath = envelope.receiptPath ?? join16(stateDir, "receipts", `${envelope.id}.json`);
|
|
15384
14731
|
let raw;
|
|
15385
14732
|
try {
|
|
15386
|
-
raw = await
|
|
14733
|
+
raw = await readFile2(receiptPath, "utf8");
|
|
15387
14734
|
} catch (error) {
|
|
15388
14735
|
const err = error;
|
|
15389
14736
|
if (err.code === "ENOENT") {
|
|
@@ -15391,9 +14738,18 @@ async function readReceipt(stateDir, envelope) {
|
|
|
15391
14738
|
}
|
|
15392
14739
|
return { receipt: null, error: `receipt read error: ${err.message ?? String(err)}`, integrityFailed: false };
|
|
15393
14740
|
}
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
14741
|
+
let receipt;
|
|
14742
|
+
try {
|
|
14743
|
+
const parsed = parseJson2(raw, receiptPath);
|
|
14744
|
+
receipt = parseRunReceipt(parsed, receiptPath);
|
|
14745
|
+
} catch (error) {
|
|
14746
|
+
return {
|
|
14747
|
+
receipt: null,
|
|
14748
|
+
error: `receipt invalid: ${error instanceof Error ? error.message : String(error)}`,
|
|
14749
|
+
integrityFailed: true
|
|
14750
|
+
};
|
|
14751
|
+
}
|
|
14752
|
+
const integrity = inspectRunReceiptTrustStatus(receipt, envelope).integrity;
|
|
15397
14753
|
if (!integrity.ok) {
|
|
15398
14754
|
return { receipt, error: `receipt integrity: ${integrity.reason}`, integrityFailed: true };
|
|
15399
14755
|
}
|
|
@@ -15582,15 +14938,15 @@ function extractTextFromPayload(payload) {
|
|
|
15582
14938
|
}
|
|
15583
14939
|
function previewUnknown(value) {
|
|
15584
14940
|
if (value === void 0) return "";
|
|
15585
|
-
if (typeof value === "string") return truncateText(
|
|
14941
|
+
if (typeof value === "string") return truncateText(collapseWhitespace(value), TOOL_PREVIEW_MAX_CHARS);
|
|
15586
14942
|
try {
|
|
15587
14943
|
const text = JSON.stringify(value);
|
|
15588
|
-
return text === void 0 ? "" : truncateText(
|
|
14944
|
+
return text === void 0 ? "" : truncateText(collapseWhitespace(text), TOOL_PREVIEW_MAX_CHARS);
|
|
15589
14945
|
} catch {
|
|
15590
|
-
return truncateText(
|
|
14946
|
+
return truncateText(collapseWhitespace(String(value)), TOOL_PREVIEW_MAX_CHARS);
|
|
15591
14947
|
}
|
|
15592
14948
|
}
|
|
15593
|
-
function
|
|
14949
|
+
function collapseWhitespace(text) {
|
|
15594
14950
|
return text.replace(/\s+/g, " ").trim();
|
|
15595
14951
|
}
|
|
15596
14952
|
async function writeJson(path2, value) {
|
|
@@ -15609,34 +14965,31 @@ function durationMs(startedAt, endedAt) {
|
|
|
15609
14965
|
}
|
|
15610
14966
|
function earliest(values) {
|
|
15611
14967
|
if (values.length === 0) return null;
|
|
15612
|
-
return [...values].sort(
|
|
14968
|
+
return [...values].sort(compareCodepoints)[0] ?? null;
|
|
15613
14969
|
}
|
|
15614
14970
|
function latest(values) {
|
|
15615
14971
|
if (values.length === 0) return null;
|
|
15616
|
-
return [...values].sort(
|
|
14972
|
+
return [...values].sort(compareCodepoints).at(-1) ?? null;
|
|
15617
14973
|
}
|
|
15618
14974
|
function uniqueStrings(values) {
|
|
15619
|
-
return [...new Set(values)].sort(
|
|
14975
|
+
return [...new Set(values)].sort(compareCodepoints);
|
|
15620
14976
|
}
|
|
15621
14977
|
function uniqueTags(values) {
|
|
15622
|
-
return [...new Set(values)].sort(
|
|
15623
|
-
}
|
|
15624
|
-
function compareStrings5(a, b) {
|
|
15625
|
-
return a.localeCompare(b);
|
|
14978
|
+
return [...new Set(values)].sort(compareCodepoints);
|
|
15626
14979
|
}
|
|
15627
14980
|
function compareNullableStrings(a, b) {
|
|
15628
14981
|
if (a === b) return 0;
|
|
15629
14982
|
if (a === null) return 1;
|
|
15630
14983
|
if (b === null) return -1;
|
|
15631
|
-
return
|
|
14984
|
+
return compareCodepoints(a, b);
|
|
15632
14985
|
}
|
|
15633
14986
|
function compareRuns(a, b) {
|
|
15634
|
-
const byStart =
|
|
14987
|
+
const byStart = compareCodepoints(a.startedAt, b.startedAt);
|
|
15635
14988
|
if (byStart !== 0) return byStart;
|
|
15636
|
-
return
|
|
14989
|
+
return compareCodepoints(a.id, b.id);
|
|
15637
14990
|
}
|
|
15638
14991
|
function compareToolStats(a, b) {
|
|
15639
|
-
return
|
|
14992
|
+
return compareCodepoints(a.tool, b.tool);
|
|
15640
14993
|
}
|
|
15641
14994
|
function compareEvidenceToolEvents(a, b) {
|
|
15642
14995
|
const byTimestamp = compareNullableStrings(a.timestamp ?? null, b.timestamp ?? null);
|
|
@@ -15645,7 +14998,7 @@ function compareEvidenceToolEvents(a, b) {
|
|
|
15645
14998
|
if (byRun !== 0) return byRun;
|
|
15646
14999
|
const bySession = compareNullableStrings(a.sessionId, b.sessionId);
|
|
15647
15000
|
if (bySession !== 0) return bySession;
|
|
15648
|
-
const byTool =
|
|
15001
|
+
const byTool = compareCodepoints(a.tool, b.tool);
|
|
15649
15002
|
if (byTool !== 0) return byTool;
|
|
15650
15003
|
return compareNullableStrings(a.toolCallId ?? null, b.toolCallId ?? null);
|
|
15651
15004
|
}
|
|
@@ -15661,8 +15014,8 @@ function sanitizeEvidenceId(value) {
|
|
|
15661
15014
|
|
|
15662
15015
|
// src/domains/evidence/eval.ts
|
|
15663
15016
|
init_esm_shims();
|
|
15664
|
-
import { mkdir as mkdir2, readdir as
|
|
15665
|
-
import { join as
|
|
15017
|
+
import { mkdir as mkdir2, readdir as readdir2, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
15018
|
+
import { join as join17 } from "node:path";
|
|
15666
15019
|
|
|
15667
15020
|
// src/domains/eval/index.ts
|
|
15668
15021
|
init_esm_shims();
|
|
@@ -15712,12 +15065,13 @@ var EVAL_EVIDENCE_FILES = [
|
|
|
15712
15065
|
"audit-linked.jsonl",
|
|
15713
15066
|
"receipt.json",
|
|
15714
15067
|
"gate-decisions.json",
|
|
15068
|
+
"trust-status.json",
|
|
15715
15069
|
"protected-artifacts.json",
|
|
15716
15070
|
"eval-result.json",
|
|
15717
15071
|
"findings.json",
|
|
15718
15072
|
"findings.md"
|
|
15719
15073
|
];
|
|
15720
|
-
var
|
|
15074
|
+
var PREVIEW_MAX_CHARS = 240;
|
|
15721
15075
|
async function buildEvalEvidence(options) {
|
|
15722
15076
|
if (options.evalId !== void 0 && options.artifact !== void 0) {
|
|
15723
15077
|
throw new Error("build eval evidence accepts either evalId or artifact, not both");
|
|
@@ -15740,8 +15094,23 @@ async function buildEvalEvidence(options) {
|
|
|
15740
15094
|
options.stateDir
|
|
15741
15095
|
).map((entry) => entry.artifact)
|
|
15742
15096
|
};
|
|
15743
|
-
|
|
15744
|
-
|
|
15097
|
+
const trustStatus = buildEvidenceTrustStatusFile({
|
|
15098
|
+
evidenceId,
|
|
15099
|
+
runSources: linkedRuns.runSources,
|
|
15100
|
+
gateDecisions: gateDecisions.decisions,
|
|
15101
|
+
auditRows: linkedRuns.auditRows
|
|
15102
|
+
});
|
|
15103
|
+
await writeEvalEvidenceFiles(
|
|
15104
|
+
directory,
|
|
15105
|
+
artifact,
|
|
15106
|
+
overview,
|
|
15107
|
+
findings,
|
|
15108
|
+
toolEventRows,
|
|
15109
|
+
linkedRuns,
|
|
15110
|
+
gateDecisions,
|
|
15111
|
+
trustStatus
|
|
15112
|
+
);
|
|
15113
|
+
return { evidenceId, directory, overview, findings, trustStatus };
|
|
15745
15114
|
}
|
|
15746
15115
|
function evalEvidenceId(evalId) {
|
|
15747
15116
|
return `eval-${sanitizeEvidenceId2(evalId)}`;
|
|
@@ -15756,7 +15125,7 @@ function evalOverview(evidenceId, artifact, findings, toolEventRows, linkedRuns,
|
|
|
15756
15125
|
evidenceId,
|
|
15757
15126
|
source: { kind: "eval", evalId: artifact.evalId },
|
|
15758
15127
|
generatedAt: artifact.endedAt,
|
|
15759
|
-
runIds: envelopes.length > 0 ? uniqueStrings2(envelopes.map((envelope) => envelope.id)) : artifact.results.map((result) => result.runId).sort(
|
|
15128
|
+
runIds: envelopes.length > 0 ? uniqueStrings2(envelopes.map((envelope) => envelope.id)) : artifact.results.map((result) => result.runId).sort(compareCodepoints),
|
|
15760
15129
|
sessionId: uniqueStrings2(envelopes.flatMap((envelope) => envelope.sessionId === null ? [] : [envelope.sessionId]))[0] ?? null,
|
|
15761
15130
|
statuses: envelopes.length > 0 ? uniqueStrings2(envelopes.map((envelope) => envelope.status)) : uniqueStrings2(artifact.results.map((result) => result.pass ? "passed" : "failed")),
|
|
15762
15131
|
startedAt: artifact.startedAt,
|
|
@@ -15843,7 +15212,7 @@ function evalToolEvents(artifact) {
|
|
|
15843
15212
|
}
|
|
15844
15213
|
return events.sort(compareEvidenceToolEvents2);
|
|
15845
15214
|
}
|
|
15846
|
-
async function writeEvalEvidenceFiles(directory, artifact, overview, findings, toolEventRows, linkedRuns, gateDecisions) {
|
|
15215
|
+
async function writeEvalEvidenceFiles(directory, artifact, overview, findings, toolEventRows, linkedRuns, gateDecisions, trustStatus) {
|
|
15847
15216
|
const emptyProtected = { version: EVIDENCE_VERSION, artifacts: [], events: [] };
|
|
15848
15217
|
const receiptsFile2 = {
|
|
15849
15218
|
version: EVIDENCE_VERSION,
|
|
@@ -15851,18 +15220,19 @@ async function writeEvalEvidenceFiles(directory, artifact, overview, findings, t
|
|
|
15851
15220
|
};
|
|
15852
15221
|
const redactedArtifact = redactArtifactForStorage(artifact);
|
|
15853
15222
|
await mkdir2(directory, { recursive: true });
|
|
15854
|
-
await writeJson2(
|
|
15855
|
-
await writeFile2(
|
|
15856
|
-
await writeJsonl2(
|
|
15857
|
-
await writeJsonl2(
|
|
15858
|
-
await writeJsonl2(
|
|
15859
|
-
await writeJsonl2(
|
|
15860
|
-
await writeJson2(
|
|
15861
|
-
await writeJson2(
|
|
15862
|
-
await writeJson2(
|
|
15863
|
-
await writeJson2(
|
|
15864
|
-
await writeJson2(
|
|
15865
|
-
await
|
|
15223
|
+
await writeJson2(join17(directory, "overview.json"), overview);
|
|
15224
|
+
await writeFile2(join17(directory, "transcript.md"), renderEvalTranscript(redactedArtifact, overview), "utf8");
|
|
15225
|
+
await writeJsonl2(join17(directory, "trace.raw.jsonl"), rawEvalTraceRows(redactedArtifact));
|
|
15226
|
+
await writeJsonl2(join17(directory, "trace.cleaned.jsonl"), cleanedEvalTraceRows(redactedArtifact, findings));
|
|
15227
|
+
await writeJsonl2(join17(directory, "tool-events.jsonl"), redactArtifactForStorage(toolEventRows));
|
|
15228
|
+
await writeJsonl2(join17(directory, "audit-linked.jsonl"), linkedRuns.auditRows);
|
|
15229
|
+
await writeJson2(join17(directory, "receipt.json"), receiptsFile2);
|
|
15230
|
+
await writeJson2(join17(directory, "gate-decisions.json"), gateDecisions);
|
|
15231
|
+
await writeJson2(join17(directory, "trust-status.json"), trustStatus);
|
|
15232
|
+
await writeJson2(join17(directory, "protected-artifacts.json"), emptyProtected);
|
|
15233
|
+
await writeJson2(join17(directory, "eval-result.json"), redactedArtifact);
|
|
15234
|
+
await writeJson2(join17(directory, "findings.json"), findingsFile(overview.evidenceId, [...findings]));
|
|
15235
|
+
await writeFile2(join17(directory, "findings.md"), renderFindings2(findings), "utf8");
|
|
15866
15236
|
}
|
|
15867
15237
|
function rawEvalTraceRows(artifact) {
|
|
15868
15238
|
return artifact.results.map((result) => ({
|
|
@@ -15971,22 +15341,22 @@ async function writeJsonl2(path2, rows) {
|
|
|
15971
15341
|
}
|
|
15972
15342
|
function commandPreview(command) {
|
|
15973
15343
|
const text = command.stderr.length > 0 ? command.stderr : command.stdout;
|
|
15974
|
-
return truncateText2(text,
|
|
15344
|
+
return truncateText2(text, PREVIEW_MAX_CHARS);
|
|
15975
15345
|
}
|
|
15976
15346
|
function truncateText2(value, maxChars) {
|
|
15977
15347
|
if (value.length <= maxChars) return value;
|
|
15978
15348
|
return `${value.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
15979
15349
|
}
|
|
15980
15350
|
function uniqueStrings2(values) {
|
|
15981
|
-
return [...new Set(values)].sort(
|
|
15351
|
+
return [...new Set(values)].sort(compareCodepoints);
|
|
15982
15352
|
}
|
|
15983
15353
|
function uniqueTags2(values) {
|
|
15984
|
-
return [...new Set(values)].sort(
|
|
15354
|
+
return [...new Set(values)].sort(compareCodepoints);
|
|
15985
15355
|
}
|
|
15986
15356
|
function compareEvidenceToolEvents2(a, b) {
|
|
15987
15357
|
const byRun = compareNullableStrings2(a.runId, b.runId);
|
|
15988
15358
|
if (byRun !== 0) return byRun;
|
|
15989
|
-
const byTool =
|
|
15359
|
+
const byTool = compareCodepoints(a.tool, b.tool);
|
|
15990
15360
|
if (byTool !== 0) return byTool;
|
|
15991
15361
|
const byArgs = compareNullableStrings2(a.argsPreview ?? null, b.argsPreview ?? null);
|
|
15992
15362
|
if (byArgs !== 0) return byArgs;
|
|
@@ -16013,7 +15383,7 @@ async function linkEvalRuns(stateDir, artifact) {
|
|
|
16013
15383
|
}
|
|
16014
15384
|
async function readRunLedger2(stateDir) {
|
|
16015
15385
|
try {
|
|
16016
|
-
const raw = await
|
|
15386
|
+
const raw = await readFile3(join17(stateDir, "runs.json"), "utf8");
|
|
16017
15387
|
const parsed = JSON.parse(raw);
|
|
16018
15388
|
return Array.isArray(parsed) ? parsed.filter(isRecord13) : [];
|
|
16019
15389
|
} catch {
|
|
@@ -16024,9 +15394,9 @@ function evalRunMatches(artifact, envelope) {
|
|
|
16024
15394
|
return artifact.results.some((result) => result.runId === envelope.id);
|
|
16025
15395
|
}
|
|
16026
15396
|
async function readReceiptForRun(stateDir, envelope) {
|
|
16027
|
-
const path2 = envelope.receiptPath ??
|
|
15397
|
+
const path2 = envelope.receiptPath ?? join17(stateDir, "receipts", `${envelope.id}.json`);
|
|
16028
15398
|
try {
|
|
16029
|
-
const parsed = JSON.parse(await
|
|
15399
|
+
const parsed = JSON.parse(await readFile3(path2, "utf8"));
|
|
16030
15400
|
return isRecord13(parsed) ? parsed : null;
|
|
16031
15401
|
} catch {
|
|
16032
15402
|
return null;
|
|
@@ -16038,7 +15408,7 @@ async function countSessionEntries(stateDir, sessionIds) {
|
|
|
16038
15408
|
const path2 = await findSessionLedgerPath(stateDir, sessionId);
|
|
16039
15409
|
if (path2 === null) continue;
|
|
16040
15410
|
try {
|
|
16041
|
-
const raw = await
|
|
15411
|
+
const raw = await readFile3(path2, "utf8");
|
|
16042
15412
|
count += raw.split("\n").filter((line) => line.trim().length > 0).filter((line) => {
|
|
16043
15413
|
try {
|
|
16044
15414
|
const parsed = JSON.parse(line);
|
|
@@ -16053,17 +15423,17 @@ async function countSessionEntries(stateDir, sessionIds) {
|
|
|
16053
15423
|
return count;
|
|
16054
15424
|
}
|
|
16055
15425
|
async function findSessionLedgerPath(stateDir, sessionId) {
|
|
16056
|
-
const root =
|
|
15426
|
+
const root = join17(stateDir, "sessions");
|
|
16057
15427
|
let cwdHashes;
|
|
16058
15428
|
try {
|
|
16059
|
-
cwdHashes = await
|
|
15429
|
+
cwdHashes = await readdir2(root);
|
|
16060
15430
|
} catch {
|
|
16061
15431
|
return null;
|
|
16062
15432
|
}
|
|
16063
|
-
for (const
|
|
16064
|
-
const path2 =
|
|
15433
|
+
for (const cwdHash of cwdHashes) {
|
|
15434
|
+
const path2 = join17(root, cwdHash, sessionId, "current.jsonl");
|
|
16065
15435
|
try {
|
|
16066
|
-
await
|
|
15436
|
+
await readFile3(path2, "utf8");
|
|
16067
15437
|
return path2;
|
|
16068
15438
|
} catch {
|
|
16069
15439
|
}
|
|
@@ -16071,16 +15441,16 @@ async function findSessionLedgerPath(stateDir, sessionId) {
|
|
|
16071
15441
|
return null;
|
|
16072
15442
|
}
|
|
16073
15443
|
async function linkedEvalAuditRows(stateDir, runIds, artifact) {
|
|
16074
|
-
const root =
|
|
15444
|
+
const root = join17(stateDir, "audit");
|
|
16075
15445
|
let files;
|
|
16076
15446
|
try {
|
|
16077
|
-
files = await
|
|
15447
|
+
files = await readdir2(root);
|
|
16078
15448
|
} catch {
|
|
16079
15449
|
return [];
|
|
16080
15450
|
}
|
|
16081
15451
|
const rows = [];
|
|
16082
|
-
for (const file of files.filter((name) => name.endsWith(".jsonl")).sort(
|
|
16083
|
-
const raw = await
|
|
15452
|
+
for (const file of files.filter((name) => name.endsWith(".jsonl")).sort(compareCodepoints)) {
|
|
15453
|
+
const raw = await readFile3(join17(root, file), "utf8").catch(() => "");
|
|
16084
15454
|
const lines = raw.split("\n");
|
|
16085
15455
|
for (let index = 0; index < lines.length; index += 1) {
|
|
16086
15456
|
const line = lines[index];
|
|
@@ -16144,27 +15514,24 @@ function timestampInEvalWindow(timestamp, artifact) {
|
|
|
16144
15514
|
return Number.isFinite(value) && Number.isFinite(start) && Number.isFinite(end) && value >= start && value <= end;
|
|
16145
15515
|
}
|
|
16146
15516
|
function compareRunEnvelopes(a, b) {
|
|
16147
|
-
return
|
|
15517
|
+
return compareCodepoints(a.startedAt, b.startedAt) || compareCodepoints(a.id, b.id);
|
|
16148
15518
|
}
|
|
16149
15519
|
function compareAuditRows(a, b) {
|
|
16150
|
-
return compareNullableStrings2(a.ts, b.ts) || compareNullableStrings2(a.runId, b.runId) || JSON.stringify(a.row)
|
|
15520
|
+
return compareNullableStrings2(a.ts, b.ts) || compareNullableStrings2(a.runId, b.runId) || compareCodepoints(JSON.stringify(a.row), JSON.stringify(b.row));
|
|
16151
15521
|
}
|
|
16152
15522
|
function compareToolStats2(a, b) {
|
|
16153
|
-
return
|
|
15523
|
+
return compareCodepoints(a.tool, b.tool);
|
|
16154
15524
|
}
|
|
16155
15525
|
function compareNullableStrings2(a, b) {
|
|
16156
15526
|
if (a === b) return 0;
|
|
16157
15527
|
if (a === null) return -1;
|
|
16158
15528
|
if (b === null) return 1;
|
|
16159
|
-
return
|
|
15529
|
+
return compareCodepoints(a, b);
|
|
16160
15530
|
}
|
|
16161
15531
|
function sanitizeEvidenceId2(value) {
|
|
16162
15532
|
const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16163
15533
|
return sanitized.length === 0 ? "unknown" : sanitized;
|
|
16164
15534
|
}
|
|
16165
|
-
function compareStrings6(a, b) {
|
|
16166
|
-
return a.localeCompare(b);
|
|
16167
|
-
}
|
|
16168
15535
|
function isRecord13(value) {
|
|
16169
15536
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16170
15537
|
}
|
|
@@ -16380,26 +15747,19 @@ export {
|
|
|
16380
15747
|
createWriteBoundaryEnforcer,
|
|
16381
15748
|
DispatchDomainModule,
|
|
16382
15749
|
createDispatchDomainModule,
|
|
16383
|
-
collectSessionEntries,
|
|
16384
|
-
filterEntriesToActivePath,
|
|
16385
|
-
readAuditRows,
|
|
16386
|
-
parseSessionEntries,
|
|
16387
|
-
listSessionLedgerRefs,
|
|
16388
|
-
protectedArtifactEntryFromArtifact,
|
|
16389
|
-
protectedArtifactStateFromSessionEntries,
|
|
16390
|
-
ledgerUsageCalls,
|
|
16391
|
-
SessionDomainModule,
|
|
16392
15750
|
extractRunProvenance,
|
|
16393
15751
|
provenanceTranscriptLines,
|
|
16394
15752
|
provenanceCompactSuffix,
|
|
15753
|
+
adaptRunReceiptTrustStatus,
|
|
15754
|
+
inspectRunReceiptTrustStatus,
|
|
15755
|
+
FAILURE_CAUSE_TAGS,
|
|
16395
15756
|
evidenceDirectory,
|
|
16396
15757
|
EvidenceNotFoundError,
|
|
16397
15758
|
inspectEvidence,
|
|
16398
15759
|
loadEvidenceRunProvenance,
|
|
16399
15760
|
listEvidenceOverviews,
|
|
16400
|
-
FAILURE_CAUSE_TAGS,
|
|
16401
15761
|
buildEvidence,
|
|
16402
15762
|
summarizeEvalResults,
|
|
16403
15763
|
buildEvalEvidence
|
|
16404
15764
|
};
|
|
16405
|
-
//# sourceMappingURL=chunk-
|
|
15765
|
+
//# sourceMappingURL=chunk-QQL5RT5M.js.map
|