@iowarp/clio-coder 0.3.6 → 0.3.8
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 +59 -0
- package/README.md +22 -6
- package/dist/{acp-2BEHC4DL.js → acp-U67UHUK2.js} +14 -14
- package/dist/{agents-LNNFTM53.js → agents-YU6SGALZ.js} +42 -35
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-5ZPJOIVG.js} +32 -24
- package/dist/builtins-C6JMZVV6.js +17 -0
- package/dist/{chunk-E25LMLRW.js → chunk-26LEYJZH.js} +2 -2
- package/dist/{chunk-TSHXZTOQ.js → chunk-2HEJ2F35.js} +5 -5
- package/dist/{chunk-PBTHKCPN.js → chunk-2HFZQUHL.js} +7 -7
- package/dist/{chunk-FO5ZOVUY.js → chunk-3BINW3FP.js} +5 -5
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CKXWIANG.js → chunk-4SPRNWDE.js} +18 -16
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-XF5N4U5A.js → chunk-5DHKRSMQ.js} +9 -8
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-EKY57CSP.js → chunk-5H3GB5BO.js} +68 -772
- package/dist/{chunk-6XXKFVSN.js → chunk-5Q2VVUKB.js} +4 -4
- package/dist/{chunk-DJVECN66.js → chunk-7RFXX52T.js} +295 -3705
- package/dist/{chunk-ZXF4XRKW.js → chunk-7RGZWPB6.js} +158 -8
- package/dist/{chunk-FYYLNIL5.js → chunk-A2NJGIB3.js} +2 -2
- package/dist/{chunk-XXQNGV4M.js → chunk-A3WNZD3P.js} +548 -72
- package/dist/{chunk-VEZEGCGW.js → chunk-B5CSFE7B.js} +23 -21
- package/dist/{chunk-2SFS6XQE.js → chunk-DGSYXYMX.js} +3 -2
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-ZWLZP4ZT.js → chunk-DYIM5TJT.js} +98 -12
- package/dist/{chunk-QKMUKYO7.js → chunk-E77JEWSD.js} +270 -125
- package/dist/{chunk-LYF7OHWH.js → chunk-EMYUUSFG.js} +12 -467
- package/dist/{chunk-4VP4KH3K.js → chunk-EQ63NRB7.js} +8 -8
- package/dist/chunk-FBVTI2TJ.js +518 -0
- package/dist/{chunk-R46L2BIR.js → chunk-FHJEP5SW.js} +19 -25
- package/dist/{chunk-WR67VIZY.js → chunk-GN57SG4G.js} +66 -8
- package/dist/{chunk-RD5U66HV.js → chunk-GPIEI3LY.js} +9 -9
- package/dist/{chunk-PCZJO5TI.js → chunk-GU2UIAFZ.js} +13 -178
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/chunk-H7IXIC72.js +103 -0
- package/dist/{chunk-3BPUFZDL.js → chunk-HLE42MG7.js} +3 -3
- package/dist/{chunk-24I7BN55.js → chunk-IFBNV6H6.js} +3 -3
- package/dist/{chunk-QNQHSOLF.js → chunk-IGWKHNIQ.js} +114 -55
- package/dist/chunk-IIZWH4XA.js +172 -0
- package/dist/{chunk-AD2SYQYC.js → chunk-IJ7RPIYJ.js} +124 -6
- package/dist/chunk-J3YUBZWY.js +382 -0
- package/dist/{chunk-5JGRAMKL.js → chunk-JOZYP4GM.js} +8 -6
- package/dist/{chunk-OH3TOQTB.js → chunk-K4XHGFR5.js} +751 -15
- package/dist/{chunk-EYPA3EGJ.js → chunk-KTYTFRMB.js} +178 -14
- package/dist/chunk-LU7P4LHA.js +33 -0
- package/dist/chunk-ME6CCNFO.js +108 -0
- package/dist/chunk-MXKJU4JB.js +1100 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-N22QMJKY.js} +21 -18
- package/dist/chunk-NMPKI6XL.js +3006 -0
- package/dist/chunk-NUGM5KR6.js +165 -0
- package/dist/{chunk-22NAGB7X.js → chunk-P43ETTHK.js} +5 -94
- package/dist/{chunk-NILBFAPG.js → chunk-PMDBGQSJ.js} +2 -2
- package/dist/chunk-PT7HYKEM.js +165 -0
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-GEYXPTRF.js → chunk-RWSI4YD7.js} +2 -2
- package/dist/{chunk-4BPJXDWC.js → chunk-TANS5ZJS.js} +35 -19
- package/dist/{verifiers-NCBTHHN2.js → chunk-TB5666IT.js} +67 -324
- package/dist/{chunk-QM3F2GKX.js → chunk-TLQJPP24.js} +7927 -8088
- package/dist/{chunk-G7MUEIGA.js → chunk-TT36MB5S.js} +2 -1
- package/dist/chunk-TTHACPOM.js +961 -0
- package/dist/{chunk-6US73PDB.js → chunk-TYPGUK6W.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-U6MBIEMB.js} +554 -209
- package/dist/chunk-VAWNZU7Z.js +242 -0
- package/dist/{chunk-IR4CFBFN.js → chunk-VCBR6CU7.js} +12 -12
- package/dist/{chunk-WHJYKASB.js → chunk-VHN4MY6O.js} +2 -2
- package/dist/{chunk-XYDYPRZI.js → chunk-VWZOAB7K.js} +10 -10
- package/dist/{chunk-ZRGEBJ4T.js → chunk-WLFILSD5.js} +48 -48
- package/dist/{chunk-K7T3E2SR.js → chunk-WNIJTQQK.js} +12 -11
- package/dist/{chunk-CYQKWTG3.js → chunk-WSB3FPX7.js} +68 -20
- package/dist/{chunk-KHSFENX2.js → chunk-WWCZ5F23.js} +116 -14
- package/dist/{chunk-XE2VEJHX.js → chunk-WXY7KU3G.js} +2 -2
- package/dist/{chunk-PPAMZ32Z.js → chunk-XK56QHLX.js} +6 -1
- package/dist/{chunk-KOHPCX4K.js → chunk-XWSF374K.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-YS5VLNH5.js} +10 -10
- package/dist/{chunk-ZZMN5OM4.js → chunk-ZNLWCMVZ.js} +2 -2
- package/dist/{chunk-WHGPSPT5.js → chunk-ZVJ5BLO2.js} +2 -2
- package/dist/cli/index.js +33 -31
- package/dist/{clio-M2KGYUFZ.js → clio-QVTYJ57A.js} +10 -10
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +5 -5
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-5TTYYX6G.js → components-ZFA3SAER.js} +9 -9
- package/dist/{config-XUUYQIWO.js → config-LW5IJFQN.js} +65 -55
- package/dist/{configure-IHJ7YOMV.js → configure-7XIZCOU4.js} +29 -24
- package/dist/{context-75MIWW3U.js → context-L3WL3X7K.js} +54 -43
- package/dist/{context-ZQ7SIFJV.js → context-N52ZA626.js} +30 -14
- package/dist/{context-74JLXAWD.js → context-Y6Y7QPR6.js} +12 -12
- package/dist/{context-clear-GYKWNUML.js → context-clear-MBQRLSDQ.js} +54 -43
- package/dist/{context-index-SSR5ECNE.js → context-index-HVMFQHK3.js} +5 -5
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-GS6DSO7F.js} +18 -18
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-22ZCNOM3.js} +367 -79
- package/dist/{docs-6FZSCG5B.js → docs-7LQ23DLM.js} +9 -9
- package/dist/{doctor-SVJ5BZCW.js → doctor-M7YEDGAE.js} +27 -23
- package/dist/{eval-CG6LLBLD.js → eval-BEC2WHDA.js} +73 -20
- package/dist/{evidence-ZYFIEN42.js → evidence-REJUMSKM.js} +70 -59
- package/dist/{evolve-QGEXEMDW.js → evolve-PY5ZBA5K.js} +50 -39
- package/dist/{extensions-ADGNCJJD.js → extensions-HVKU65YU.js} +7 -7
- package/dist/{fleet-S5R4ZOQY.js → fleet-7WZEWRFA.js} +236 -377
- package/dist/fleet-commands-UVHWM76J.js +70 -0
- package/dist/fleet-graph-6ULH7PES.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/{fleet-preflight-BHSNPBMH.js → fleet-preflight-J53T6CCE.js} +5 -5
- package/dist/fleet-validate-72PC4SLA.js +79 -0
- package/dist/{init-5DRU55YR.js → init-OG3TPGQG.js} +69 -57
- package/dist/library-CNTMPLRF.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-6IS7F275.js} +52 -41
- package/dist/{models-ZPOLRU2C.js → models-ENRJDA5W.js} +37 -31
- package/dist/{monitor-US5F5YGZ.js → monitor-XLDVO7TN.js} +79 -42
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-6KSPYRHA.js} +4126 -762
- package/dist/{paths-E7KYAQWE.js → paths-DBXMZMDU.js} +6 -6
- package/dist/registry-LG64LTF4.js +11 -0
- package/dist/{reset-KZ652EK6.js → reset-RZ4ER727.js} +12 -12
- package/dist/{run-SRNBKDWD.js → run-Y2CNK5RU.js} +89 -76
- package/dist/{share-CGZE33UP.js → share-A55GYP6Z.js} +37 -13
- package/dist/{skills-S2X4DLY5.js → skills-ALC5J6AT.js} +29 -13
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-JPBEBYQU.js} +60 -48
- package/dist/support-MIETYA5E.js +38 -0
- package/dist/{targets-54SWINWB.js → targets-VGNXIR3S.js} +46 -36
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WOBR64YA.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-ZJF5H5ZN.js} +9 -9
- package/dist/{upgrade-JKAR27XC.js → upgrade-FUSUAGHR.js} +31 -28
- package/dist/{usage-MSAWCLX4.js → usage-N4MKVHKD.js} +140 -68
- package/dist/verifiers-YAWOJ3H2.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-LTDHYBGY.js} +10 -9
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-6M7GHTBJ.js} +75 -62
- package/dist/worker/entry.js +67 -57
- package/docs/README.md +3 -2
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-versions.md +11 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +83 -3
- package/docs/configuration-and-targets.md +86 -4
- package/docs/context-engine.md +1 -1
- package/docs/development-pipeline.md +1 -1
- package/docs/dispatch-architecture-rationale.md +1 -1
- package/docs/documentation-coverage.md +3 -3
- package/docs/documentation-guide.md +3 -3
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +1 -1
- package/docs/evidence-and-memory.md +74 -10
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +4 -1
- package/docs/extensions-and-sharing.md +6 -2
- package/docs/fleet-demo-runbook.md +2 -2
- package/docs/fleet-dispatch.md +228 -16
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +22 -2
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +2 -1
- package/docs/model-catalog.md +1 -1
- package/docs/observability.md +56 -9
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +4 -2
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +83 -65
- package/docs/resource-library.md +59 -0
- package/docs/safety-model.md +2 -2
- package/docs/scientific-validation.md +3 -3
- package/docs/session-lifecycle.md +37 -1
- package/docs/skills-marketplace.md +16 -3
- package/docs/tool-usage.md +14 -7
- 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 +3 -3
- package/package.json +1 -2
- package/src/cli/argv.ts +5 -0
- package/src/cli/configure.ts +107 -23
- package/src/cli/doctor.ts +5 -1
- package/src/cli/evidence.ts +30 -25
- package/src/cli/fleet-commands.ts +37 -0
- package/src/cli/fleet-graph.ts +102 -0
- package/src/cli/fleet-new.ts +36 -0
- package/src/cli/fleet-preflight.ts +111 -0
- package/src/cli/fleet-validate.ts +30 -0
- package/src/cli/fleet.ts +173 -335
- package/src/cli/index.ts +3 -1
- package/src/cli/library.ts +190 -0
- package/src/cli/share.ts +13 -1
- package/src/cli/shared.ts +1 -0
- package/src/cli/targets.ts +4 -1
- package/src/cli/usage.ts +111 -19
- package/src/cli/validate-model.ts +60 -5
- package/src/core/bus-events.ts +29 -0
- package/src/core/commit-attribution.ts +4 -4
- package/src/core/config.ts +130 -0
- package/src/core/defaults.ts +81 -0
- package/src/core/path-boundary.ts +100 -0
- package/src/domains/agents/builtins/architect.md +1 -0
- package/src/domains/agents/builtins/oracle.md +33 -0
- package/src/domains/agents/catalog.ts +13 -1
- package/src/domains/agents/extension.ts +2 -11
- package/src/domains/agents/fleet-contract.ts +304 -24
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/recipe.ts +7 -1
- package/src/domains/agents/registry.ts +73 -5
- package/src/domains/agents/result-contract.ts +360 -15
- package/src/domains/agents/write-boundary.ts +15 -50
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/context/project-rules.ts +51 -1
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- package/src/domains/dispatch/assignment-reconcile.ts +22 -5
- package/src/domains/dispatch/assignment-store.ts +151 -14
- package/src/domains/dispatch/backoff.ts +2 -1
- package/src/domains/dispatch/capability-match.ts +1 -0
- package/src/domains/dispatch/checkout-writer-lease.ts +175 -0
- package/src/domains/dispatch/contract.ts +48 -0
- package/src/domains/dispatch/delegation-plan.ts +164 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +12 -2
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +412 -74
- package/src/domains/dispatch/fleet-gate.ts +14 -0
- package/src/domains/dispatch/fleet-plan.ts +63 -3
- package/src/domains/dispatch/fleet-run.ts +791 -0
- package/src/domains/dispatch/gate-role-prompts.ts +47 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +41 -1
- package/src/domains/dispatch/intent-requirements.ts +40 -0
- package/src/domains/dispatch/intent.ts +235 -0
- package/src/domains/dispatch/path-scope.ts +370 -0
- package/src/domains/dispatch/receipt-integrity.ts +9 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +64 -12
- package/src/domains/dispatch/validation.ts +69 -6
- package/src/domains/dispatch/write-boundary-enforcer.ts +45 -0
- package/src/domains/dispatch/write-boundary.ts +201 -22
- package/src/domains/eval/metrics/evidence.ts +79 -2
- package/src/domains/eval/runners/clio-run.ts +12 -2
- package/src/domains/evidence/build.ts +69 -11
- package/src/domains/evidence/index.ts +21 -0
- package/src/domains/evidence/provenance.ts +46 -11
- package/src/domains/evidence/trust-projection.ts +274 -0
- package/src/domains/evidence/trust-status.ts +155 -18
- package/src/domains/evidence/types.ts +4 -0
- package/src/domains/extensions/discovery.ts +88 -1
- package/src/domains/extensions/resources.ts +20 -8
- package/src/domains/extensions/state.ts +6 -2
- package/src/domains/extensions/types.ts +4 -1
- package/src/domains/lifecycle/doctor.ts +140 -1
- package/src/domains/middleware/index.ts +15 -0
- package/src/domains/middleware/watchdog.ts +281 -0
- package/src/domains/observability/contract.ts +3 -1
- package/src/domains/observability/cost.ts +12 -1
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/observability/index.ts +10 -0
- package/src/domains/observability/out-of-turn-usage.ts +223 -0
- package/src/domains/prompts/contract.ts +3 -5
- package/src/domains/providers/extension.ts +30 -2
- package/src/domains/resources/common-loader.ts +3 -0
- package/src/domains/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/prompts/loader.ts +119 -14
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/safety/policy-engine.ts +5 -5
- package/src/domains/safety/run-effects.ts +64 -1
- package/src/domains/safety/scope.ts +7 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- package/src/engine/acp/server.ts +4 -1
- package/src/engine/prompt-templates.ts +18 -1
- package/src/engine/worker-runtime.ts +6 -3
- package/src/entry/orchestrator.ts +37 -0
- package/src/interactive/bus-notices.ts +26 -0
- package/src/interactive/chat-loop.ts +235 -1
- package/src/interactive/chat-renderer.ts +22 -0
- package/src/interactive/cost-overlay.ts +31 -3
- package/src/interactive/council-dispatch.ts +30 -0
- package/src/interactive/council-grid.ts +213 -0
- package/src/interactive/council.ts +99 -0
- package/src/interactive/dispatch-board.ts +311 -17
- package/src/interactive/fleet-run-preview.ts +307 -0
- package/src/interactive/footer/notifications.ts +219 -0
- package/src/interactive/handoff-round.ts +56 -0
- package/src/interactive/interactive-application.ts +43 -1
- package/src/interactive/interactive-event-projection.ts +23 -1
- package/src/interactive/interactive-slash-runtime.ts +52 -2
- package/src/interactive/interactive-subscriptions.ts +14 -2
- package/src/interactive/oracle.ts +179 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +6 -0
- package/src/interactive/overlay-general-openers.ts +190 -1
- package/src/interactive/overlay-key-routing.ts +17 -1
- package/src/interactive/overlay-lifecycle.ts +41 -1
- package/src/interactive/overlay-permission-lifecycle.ts +10 -0
- package/src/interactive/overlay-resource-openers.ts +11 -3
- package/src/interactive/overlay-session-lifecycle.ts +234 -2
- package/src/interactive/overlays/fleet-run-approval.ts +208 -0
- package/src/interactive/overlays/handoff-review.ts +185 -0
- package/src/interactive/overlays/library-install-confirm.ts +151 -0
- package/src/interactive/overlays/list-overlay.ts +168 -2
- package/src/interactive/overlays/settings.ts +221 -30
- package/src/interactive/overlays/side-question.ts +139 -0
- package/src/interactive/overlays/skills-hub.ts +401 -15
- package/src/interactive/side-question.ts +171 -0
- package/src/interactive/slash-commands.ts +439 -7
- package/src/interactive/slash-spec.ts +19 -6
- package/src/interactive/theme/tokens.ts +30 -0
- package/src/interactive/turn-middleware.ts +15 -1
- package/src/interactive/view/artifacts.ts +42 -9
- package/src/interactive/view/view-overlay.ts +15 -3
- package/src/interactive/watchdog-run.ts +75 -0
- package/src/interactive/worker-receipts.ts +14 -2
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +15 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +251 -18
- package/src/tools/dispatch-arguments.ts +84 -1
- package/src/tools/dispatch-plan.ts +165 -6
- package/src/tools/dispatch-runner.ts +364 -23
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +29 -0
- package/src/tools/profiles.ts +18 -4
- package/src/tools/task-worktree.ts +238 -0
- package/src/tools/verify/authoring.ts +61 -1
- package/src/tools/verify/scripts.ts +62 -0
- package/src/tools/worker-evidence.ts +21 -14
- package/src/worker/spec-contract.ts +3 -1
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -6,7 +6,35 @@
|
|
|
6
6
|
* than silently pass.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import type { RunEnvelope, RunReceipt } from "../../dispatch/types.js";
|
|
12
|
+
import { formatTrustSummary, summarizeTrustStatus } from "../../evidence/trust-projection.js";
|
|
13
|
+
import {
|
|
14
|
+
adaptRunReceiptTrustStatus,
|
|
15
|
+
inspectRunReceiptTrustStatus,
|
|
16
|
+
TRUST_STATUS_AXES,
|
|
17
|
+
} from "../../evidence/trust-status.js";
|
|
18
|
+
|
|
19
|
+
function dispatchScopeMetrics(receipt: RunReceipt): Record<string, string | boolean | number> {
|
|
20
|
+
const scope = receipt.pathScope;
|
|
21
|
+
if (scope === undefined) return {};
|
|
22
|
+
const entries = [...scope.workingContextPaths, ...scope.writeBoundaries];
|
|
23
|
+
const evidence = entries.flatMap((entry) => entry.evidence);
|
|
24
|
+
const count = (source: string): number => evidence.filter((entry) => entry.source === source).length;
|
|
25
|
+
return {
|
|
26
|
+
"dispatch.scope.mode": scope.mode,
|
|
27
|
+
"dispatch.scope.inferredPathCount": entries.filter((entry) =>
|
|
28
|
+
entry.evidence.some((item) => item.provenance === "inferred"),
|
|
29
|
+
).length,
|
|
30
|
+
"dispatch.scope.derivedPathCount": entries.filter((entry) =>
|
|
31
|
+
entry.evidence.some((item) => item.provenance === "derived"),
|
|
32
|
+
).length,
|
|
33
|
+
"dispatch.scope.source.task": count("task"),
|
|
34
|
+
"dispatch.scope.source.briefing": count("briefing"),
|
|
35
|
+
"dispatch.scope.source.writeRoots": count("writeRoots"),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
10
38
|
|
|
11
39
|
/**
|
|
12
40
|
* Extract the sealed RunReceipt that `clio-coder run --agent … --json` prints after
|
|
@@ -53,9 +81,14 @@ function isReceiptShaped(value: unknown): value is RunReceipt {
|
|
|
53
81
|
* mirrors the durable findings summary and is omitted when that summary is
|
|
54
82
|
* absent, so a gate on the metric fails closed instead of inventing a value.
|
|
55
83
|
*/
|
|
56
|
-
export function evidenceMetricsFromReceipt(
|
|
84
|
+
export function evidenceMetricsFromReceipt(
|
|
85
|
+
receipt: RunReceipt,
|
|
86
|
+
options: { envelope?: RunEnvelope | null } = {},
|
|
87
|
+
): Record<string, string | boolean | number> {
|
|
57
88
|
return {
|
|
58
89
|
"evidence.verification": receipt.verification.state,
|
|
90
|
+
...dispatchScopeMetrics(receipt),
|
|
91
|
+
...evidenceTrustMetrics(receipt, options.envelope ?? null),
|
|
59
92
|
...(receipt.findingsSummary === undefined
|
|
60
93
|
? {}
|
|
61
94
|
: { "evidence.firstPassSuccess": receipt.findingsSummary.firstPassSuccess === true }),
|
|
@@ -64,3 +97,47 @@ export function evidenceMetricsFromReceipt(receipt: RunReceipt): Record<string,
|
|
|
64
97
|
...(typeof receipt.costUsd === "number" && Number.isFinite(receipt.costUsd) ? { "cost.usd": receipt.costUsd } : {}),
|
|
65
98
|
};
|
|
66
99
|
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The canonical trust status as metrics, so a benchmark table reads the same
|
|
103
|
+
* verdict as every operator surface instead of the raw receipt marker. The
|
|
104
|
+
* receipt is authenticated against its ledger row when the caller can supply
|
|
105
|
+
* one; without a row the canonical model reports the seal unchecked and the
|
|
106
|
+
* receipt-owned axes unobserved, which is the honest answer for a receipt
|
|
107
|
+
* that only ever arrived through stdout.
|
|
108
|
+
*/
|
|
109
|
+
function evidenceTrustMetrics(
|
|
110
|
+
receipt: RunReceipt,
|
|
111
|
+
envelope: RunEnvelope | null,
|
|
112
|
+
): Record<string, string | boolean | number> {
|
|
113
|
+
// A missing row means the seal was never checked, not that it failed:
|
|
114
|
+
// only a row that exists and disagrees can break a seal.
|
|
115
|
+
const status =
|
|
116
|
+
envelope === null ? adaptRunReceiptTrustStatus(receipt) : inspectRunReceiptTrustStatus(receipt, envelope).status;
|
|
117
|
+
const summary = summarizeTrustStatus(status);
|
|
118
|
+
return {
|
|
119
|
+
"evidence.trust.version": summary.version,
|
|
120
|
+
"evidence.trust.verdict": summary.verdict,
|
|
121
|
+
"evidence.trust.summary": formatTrustSummary(status),
|
|
122
|
+
...Object.fromEntries(TRUST_STATUS_AXES.map((axis) => [`evidence.trust.${axis}`, status[axis].state])),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The ledger row a stdout receipt was sealed from, read from the state dir
|
|
128
|
+
* the run wrote to. Null when the ledger or the row cannot be read; the
|
|
129
|
+
* caller then reports the seal unchecked rather than guessing.
|
|
130
|
+
*/
|
|
131
|
+
export function readRunEnvelopeForReceipt(receipt: RunReceipt, stateDir: string): RunEnvelope | null {
|
|
132
|
+
try {
|
|
133
|
+
const parsed: unknown = JSON.parse(readFileSync(join(stateDir, "runs.json"), "utf8"));
|
|
134
|
+
if (!Array.isArray(parsed)) return null;
|
|
135
|
+
const row = parsed.find(
|
|
136
|
+
(entry): entry is RunEnvelope =>
|
|
137
|
+
typeof entry === "object" && entry !== null && (entry as { id?: unknown }).id === receipt.runId,
|
|
138
|
+
);
|
|
139
|
+
return row ?? null;
|
|
140
|
+
} catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { shellQuote } from "../../../core/shell-quote.js";
|
|
2
|
-
import {
|
|
2
|
+
import { clioStateDir } from "../../../core/xdg.js";
|
|
3
|
+
import {
|
|
4
|
+
evidenceMetricsFromReceipt,
|
|
5
|
+
readRunEnvelopeForReceipt,
|
|
6
|
+
receiptFromRunJsonStdout,
|
|
7
|
+
} from "../metrics/evidence.js";
|
|
3
8
|
import { streamInvariantMetrics } from "../metrics/invariants.js";
|
|
4
9
|
import { tokenMetricEntries } from "../metrics/token-stream.js";
|
|
5
10
|
import type { EvalRunnerV2, EvalSuiteTargetV2 } from "../schema/suite.js";
|
|
@@ -35,6 +40,11 @@ export async function runClioRunRunner(
|
|
|
35
40
|
// prints; a runner without a receipt leaves them absent so any gate on
|
|
36
41
|
// them fails closed instead of reading prose labels.
|
|
37
42
|
const receipt = receiptFromRunJsonStdout(result.stdout);
|
|
43
|
+
// The canonical trust metrics authenticate the receipt against the ledger
|
|
44
|
+
// row the child wrote; a stdout receipt on its own only ever reads as an
|
|
45
|
+
// unchecked seal.
|
|
46
|
+
const envelope =
|
|
47
|
+
receipt === null ? null : readRunEnvelopeForReceipt(receipt, env?.CLIO_CODER_STATE_DIR ?? clioStateDir());
|
|
38
48
|
return {
|
|
39
49
|
assignmentId: receipt === null ? null : (receipt.lineage?.rootRunId ?? receipt.runId),
|
|
40
50
|
terminalReceiptDigest: receipt?.integrity.digest ?? null,
|
|
@@ -52,7 +62,7 @@ export async function runClioRunRunner(
|
|
|
52
62
|
"tools.failed": tools.failed,
|
|
53
63
|
"tools.blocked": tools.blocked,
|
|
54
64
|
"verifier.exitCode": result.exitCode,
|
|
55
|
-
...(receipt === null ? {} : evidenceMetricsFromReceipt(receipt)),
|
|
65
|
+
...(receipt === null ? {} : evidenceMetricsFromReceipt(receipt, { envelope })),
|
|
56
66
|
...(receipt === null
|
|
57
67
|
? {}
|
|
58
68
|
: { "evidence.qualityLabel": receipt.quality.typedValidations.length > 0 ? "measured" : "unmeasured" }),
|
|
@@ -29,8 +29,8 @@ import { extractRunProvenance, provenanceTranscriptLines } from "./provenance.js
|
|
|
29
29
|
import { createRedactionTally, redactSecretsDeep, redactSecretsText } from "./redact.js";
|
|
30
30
|
import { buildEvidenceTrustStatusFile } from "./run-trust.js";
|
|
31
31
|
import { EVIDENCE_FILES, evidenceDirectory, findingsFile } from "./store.js";
|
|
32
|
-
import type { TrustArtifactReference } from "./trust-status.js";
|
|
33
|
-
import { inspectRunReceiptTrustStatus } from "./trust-status.js";
|
|
32
|
+
import type { CanonicalTrustStatus, TrustArtifactReference } from "./trust-status.js";
|
|
33
|
+
import { inspectRunReceiptTrustStatus, retiredIntegrityVersionOf } from "./trust-status.js";
|
|
34
34
|
import {
|
|
35
35
|
EVIDENCE_VERSION,
|
|
36
36
|
type EvidenceAuditLinkedRow,
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
type EvidenceReceiptFile,
|
|
46
46
|
type EvidenceRunLink,
|
|
47
47
|
type EvidenceRunSource,
|
|
48
|
+
type EvidenceSeverity,
|
|
48
49
|
type EvidenceTag,
|
|
49
50
|
type EvidenceToolEvent,
|
|
50
51
|
type EvidenceTrustStatusFile,
|
|
@@ -195,7 +196,10 @@ export async function buildEvidence(options: BuildEvidenceOptions): Promise<Evid
|
|
|
195
196
|
redactedToolEvents,
|
|
196
197
|
protectedArtifacts,
|
|
197
198
|
);
|
|
198
|
-
const transcript = redactSecretsText(
|
|
199
|
+
const transcript = redactSecretsText(
|
|
200
|
+
renderTranscript(overview, redactedRunSources, sessionLinks, trustStatusRaw),
|
|
201
|
+
tally,
|
|
202
|
+
);
|
|
199
203
|
const finalOverview: EvidenceOverview = { ...overview, redactionCount: tally.count };
|
|
200
204
|
await writeEvidenceFiles(
|
|
201
205
|
directory,
|
|
@@ -285,8 +289,14 @@ function buildFindings(
|
|
|
285
289
|
const status = trustByRun.get(source.envelope.id);
|
|
286
290
|
if (status === undefined) throw new Error(`canonical trust status missing for run ${source.envelope.id}`);
|
|
287
291
|
if (source.receiptError !== null) {
|
|
288
|
-
|
|
289
|
-
|
|
292
|
+
// The canonical axis, not the raw reason string, says whether the seal
|
|
293
|
+
// was retired: `receipt-retired` is the expected state of every run
|
|
294
|
+
// that predates an integrity bump and is an info row, while
|
|
295
|
+
// `receipt-integrity` stays the warning for a seal that was checked
|
|
296
|
+
// and rejected.
|
|
297
|
+
const retired = retiredIntegrityVersionOf(status.artifactIntegrity) !== null;
|
|
298
|
+
const tag = retired ? "receipt-retired" : source.receiptIntegrityFailed ? "receipt-integrity" : "unknown";
|
|
299
|
+
findings.push(finding(findings.length, retired ? "info" : "warn", tag, source.envelope.id, source.receiptError));
|
|
290
300
|
}
|
|
291
301
|
if (
|
|
292
302
|
isSuccessfulRun(source) &&
|
|
@@ -359,6 +369,13 @@ function buildFindings(
|
|
|
359
369
|
),
|
|
360
370
|
);
|
|
361
371
|
}
|
|
372
|
+
// The remaining axes were never read here, so a run could finish with
|
|
373
|
+
// no independent review, a contradictory context record, or a mutation
|
|
374
|
+
// nobody validated, and findings.md said nothing. Each finding is
|
|
375
|
+
// selected from the canonical state the way the validation and
|
|
376
|
+
// autonomy findings above are, with the detailed record left in
|
|
377
|
+
// trust-status.json.
|
|
378
|
+
findings.push(...axisFindings(findings.length, source, status));
|
|
362
379
|
if (source.envelope.status === "stale" || source.envelope.status === "dead") {
|
|
363
380
|
findings.push(
|
|
364
381
|
finding(findings.length, "warn", "timeout", source.envelope.id, `run status ${source.envelope.status}`),
|
|
@@ -601,7 +618,7 @@ async function writeEvidenceFiles(
|
|
|
601
618
|
await writeJson(join(directory, "overview.json"), overview);
|
|
602
619
|
await writeFile(
|
|
603
620
|
join(directory, "transcript.md"),
|
|
604
|
-
transcript ?? renderTranscript(overview, runSources, sessionLinks),
|
|
621
|
+
transcript ?? renderTranscript(overview, runSources, sessionLinks, trustStatus),
|
|
605
622
|
"utf8",
|
|
606
623
|
);
|
|
607
624
|
await writeJsonl(join(directory, "trace.raw.jsonl"), rawTraceRows(runSources));
|
|
@@ -636,9 +653,11 @@ function cleanedTraceRows(
|
|
|
636
653
|
const rows: EvidenceCleanTraceRow[] = [];
|
|
637
654
|
for (const source of runSources) {
|
|
638
655
|
const envelope = source.envelope;
|
|
639
|
-
// Clean trace rows project only provenance carried by
|
|
656
|
+
// Clean trace rows project only provenance carried by an authenticated
|
|
657
|
+
// receipt: a rejected or retired seal contributes none of its fields.
|
|
640
658
|
// Runs without receipt provenance keep the standard row shape.
|
|
641
|
-
const
|
|
659
|
+
const receipt = authenticatedReceipt(source);
|
|
660
|
+
const provenance = receipt === null ? {} : extractRunProvenance(receipt);
|
|
642
661
|
rows.push({
|
|
643
662
|
kind: "run",
|
|
644
663
|
runId: envelope.id,
|
|
@@ -1258,7 +1277,9 @@ function renderTranscript(
|
|
|
1258
1277
|
overview: EvidenceOverview,
|
|
1259
1278
|
runSources: ReadonlyArray<EvidenceRunSource>,
|
|
1260
1279
|
sessionLinks: SessionLinkResult,
|
|
1280
|
+
trustStatus: EvidenceTrustStatusFile,
|
|
1261
1281
|
): string {
|
|
1282
|
+
const trustByRun = new Map(trustStatus.runs.map((entry) => [entry.runId, entry.status]));
|
|
1262
1283
|
const lines = [
|
|
1263
1284
|
`# Evidence ${overview.evidenceId}`,
|
|
1264
1285
|
"",
|
|
@@ -1274,10 +1295,11 @@ function renderTranscript(
|
|
|
1274
1295
|
`- ${envelope.id} status=${envelope.status} exit=${exitCode ?? "?"} agent=${envelope.agentId} target=${envelope.targetId}`,
|
|
1275
1296
|
);
|
|
1276
1297
|
lines.push(` task: ${truncateText(envelope.task, MAX_TASK_CHARS)}`);
|
|
1277
|
-
// Run section rendering
|
|
1278
|
-
//
|
|
1298
|
+
// Run section rendering adds a sentence per provenance field the
|
|
1299
|
+
// canonical projection admits; a rejected or retired seal adds none.
|
|
1279
1300
|
if (source.receipt !== null) {
|
|
1280
|
-
|
|
1301
|
+
const status = trustByRun.get(envelope.id);
|
|
1302
|
+
for (const line of provenanceTranscriptLines(extractRunProvenance(source.receipt), status)) {
|
|
1281
1303
|
lines.push(` ${line}`);
|
|
1282
1304
|
}
|
|
1283
1305
|
}
|
|
@@ -1438,6 +1460,39 @@ function renderSessionTranscriptEntry(linked: LinkedSessionEntry): string[] {
|
|
|
1438
1460
|
return [`${prefix} ${String(_exhaustive)}`];
|
|
1439
1461
|
}
|
|
1440
1462
|
|
|
1463
|
+
/** Independent review, context provenance, and completion evidence, read off the canonical axes. */
|
|
1464
|
+
function axisFindings(offset: number, source: EvidenceRunSource, status: CanonicalTrustStatus): EvidenceFinding[] {
|
|
1465
|
+
const out: EvidenceFinding[] = [];
|
|
1466
|
+
const runId = source.envelope.id;
|
|
1467
|
+
const next = (severity: EvidenceSeverity, tag: EvidenceTag, message: string): void => {
|
|
1468
|
+
out.push(finding(offset + out.length, severity, tag, runId, message));
|
|
1469
|
+
};
|
|
1470
|
+
const review = status.independentReview.state;
|
|
1471
|
+
if (review === "failed") {
|
|
1472
|
+
next("warn", "independent-review", "independent review failed for this run");
|
|
1473
|
+
} else if (review === "not_independent") {
|
|
1474
|
+
next("warn", "independent-review", "review was not independent of the run it judged");
|
|
1475
|
+
} else if (review === "inconclusive") {
|
|
1476
|
+
next("info", "independent-review", "independent review was inconclusive");
|
|
1477
|
+
} else if (isSuccessfulRun(source) && (review === "absent" || review === "unknown")) {
|
|
1478
|
+
next("info", "independent-review", "run was not independently reviewed; its result rests on its own receipt");
|
|
1479
|
+
}
|
|
1480
|
+
if (status.contextProvenance.state === "invalid") {
|
|
1481
|
+
next("warn", "context-provenance", "context provenance record is contradictory; see trust-status.json");
|
|
1482
|
+
}
|
|
1483
|
+
const completion = status.completionEvidence.state;
|
|
1484
|
+
if (completion === "incomplete") {
|
|
1485
|
+
next(
|
|
1486
|
+
"warn",
|
|
1487
|
+
"completion-evidence",
|
|
1488
|
+
"run mutated the workspace and finished without validation evidence at the completion boundary",
|
|
1489
|
+
);
|
|
1490
|
+
} else if (completion === "limited") {
|
|
1491
|
+
next("info", "completion-evidence", "run finished with an explicit limitation instead of validation evidence");
|
|
1492
|
+
}
|
|
1493
|
+
return out;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1441
1496
|
function renderFindings(findings: ReadonlyArray<EvidenceFinding>): string {
|
|
1442
1497
|
if (findings.length === 0) return "# Findings\n\nNo findings.\n";
|
|
1443
1498
|
const lines = ["# Findings", ""];
|
|
@@ -1507,6 +1562,9 @@ async function readReceipt(
|
|
|
1507
1562
|
}
|
|
1508
1563
|
const integrity = inspectRunReceiptTrustStatus(receipt, envelope).integrity;
|
|
1509
1564
|
if (!integrity.ok) {
|
|
1565
|
+
// A retired seal is set aside unread, the way a missing receipt is; it
|
|
1566
|
+
// is not a failed one, and its reason already names both versions.
|
|
1567
|
+
if (integrity.retired !== undefined) return { receipt, error: integrity.reason, integrityFailed: false };
|
|
1510
1568
|
return { receipt, error: `receipt integrity: ${integrity.reason}`, integrityFailed: true };
|
|
1511
1569
|
}
|
|
1512
1570
|
return { receipt, error: null, integrityFailed: false };
|
|
@@ -5,6 +5,7 @@ export { buildEvalEvidence, evalEvidenceId } from "./eval.js";
|
|
|
5
5
|
export { FINISH_CONTRACT_EVIDENCE_TAGS, finishContractEvidenceTags } from "./finish-contract-map.js";
|
|
6
6
|
export type { RunEscalationCounts, RunProvenanceView } from "./provenance.js";
|
|
7
7
|
export {
|
|
8
|
+
admitRunProvenance,
|
|
8
9
|
extractRunProvenance,
|
|
9
10
|
hasRunProvenance,
|
|
10
11
|
PERSONA_HASH_PREFIX_CHARS,
|
|
@@ -22,6 +23,20 @@ export {
|
|
|
22
23
|
loadEvidenceRunProvenance,
|
|
23
24
|
loadEvidenceTrustStatus,
|
|
24
25
|
} from "./store.js";
|
|
26
|
+
export type { TrustSummaryProjection, TrustVerdict } from "./trust-projection.js";
|
|
27
|
+
export {
|
|
28
|
+
formatTrustAxes,
|
|
29
|
+
formatTrustSummary,
|
|
30
|
+
formatTrustSummaryLine,
|
|
31
|
+
summarizeTrustStatus,
|
|
32
|
+
TRUST_STATE_WORDS,
|
|
33
|
+
TRUST_SUMMARY_MAX_REFS,
|
|
34
|
+
TRUST_SUMMARY_VERSION,
|
|
35
|
+
TRUST_VERDICTS,
|
|
36
|
+
trustStateWord,
|
|
37
|
+
trustSummaryReferences,
|
|
38
|
+
trustVerdict,
|
|
39
|
+
} from "./trust-projection.js";
|
|
25
40
|
export type {
|
|
26
41
|
AbsentTrustStatus,
|
|
27
42
|
AdaptFinishContractTrustOptions,
|
|
@@ -35,6 +50,8 @@ export type {
|
|
|
35
50
|
GroundedEvidenceValidationInput,
|
|
36
51
|
IndependentReviewStatus,
|
|
37
52
|
PersistedRunReceiptTrustFacts,
|
|
53
|
+
ReceiptIntegrityOutcome,
|
|
54
|
+
RetiredReceiptIntegrity,
|
|
38
55
|
RunReceiptTrustInspection,
|
|
39
56
|
TrustAbsenceReason,
|
|
40
57
|
TrustArtifactKind,
|
|
@@ -63,12 +80,16 @@ export {
|
|
|
63
80
|
inspectRunReceiptTrustStatus,
|
|
64
81
|
normalizeTrustStatus,
|
|
65
82
|
projectTrustStatus,
|
|
83
|
+
retiredIntegrityVersionOf,
|
|
84
|
+
retiredReceiptIntegrity,
|
|
85
|
+
retiredReceiptIntegrityReason,
|
|
66
86
|
TRUST_STATUS_AXES,
|
|
67
87
|
TRUST_STATUS_MAX_ARTIFACT_REFERENCES,
|
|
68
88
|
TRUST_STATUS_MAX_IDENTIFIER_LENGTH,
|
|
69
89
|
TRUST_STATUS_STATES,
|
|
70
90
|
TRUST_STATUS_VERSION,
|
|
71
91
|
validateTrustStatus,
|
|
92
|
+
verifyReceiptIntegrityOutcome,
|
|
72
93
|
} from "./trust-status.js";
|
|
73
94
|
export type {
|
|
74
95
|
EvidenceAuditLinkedRow,
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
RunReceipt,
|
|
5
5
|
RunReceiptAutonomyEnforcement,
|
|
6
6
|
} from "../dispatch/types.js";
|
|
7
|
+
import type { CanonicalTrustStatus } from "./trust-status.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Worker permission-escalation counters projected from sealed receipt
|
|
@@ -50,6 +51,33 @@ export function extractRunProvenance(receipt: ProvenanceReceipt): RunProvenanceV
|
|
|
50
51
|
return view;
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* The slice of a provenance view the canonical projection admits. The
|
|
56
|
+
* projection is the only thing that decides whether an axis is reported, so
|
|
57
|
+
* the autonomy detail (`autonomy=`, `mode=`, `dangerousBypass=`) is kept only
|
|
58
|
+
* when the projection reports the autonomy axis in a recorded state, and the
|
|
59
|
+
* non-axis provenance (pipeline, persona override, escalations) only when the
|
|
60
|
+
* seal that carries it verified. With no projection at hand no axis detail is
|
|
61
|
+
* admitted at all, whatever the receipt says; the non-axis provenance passes
|
|
62
|
+
* through for a caller that prints it beside its own integrity banner.
|
|
63
|
+
*/
|
|
64
|
+
export function admitRunProvenance(view: RunProvenanceView, status?: CanonicalTrustStatus): RunProvenanceView {
|
|
65
|
+
const admitted: RunProvenanceView = {};
|
|
66
|
+
if (status === undefined || status.artifactIntegrity.state === "verified") {
|
|
67
|
+
if (view.pipeline !== undefined) admitted.pipeline = view.pipeline;
|
|
68
|
+
if (view.personaOverride !== undefined) admitted.personaOverride = view.personaOverride;
|
|
69
|
+
if (view.escalation !== undefined) admitted.escalation = view.escalation;
|
|
70
|
+
}
|
|
71
|
+
const autonomy = status?.autonomyEnforcement.state;
|
|
72
|
+
if (
|
|
73
|
+
view.autonomyEnforcement !== undefined &&
|
|
74
|
+
(autonomy === "enforced" || autonomy === "approximated" || autonomy === "bypassed")
|
|
75
|
+
) {
|
|
76
|
+
admitted.autonomyEnforcement = view.autonomyEnforcement;
|
|
77
|
+
}
|
|
78
|
+
return admitted;
|
|
79
|
+
}
|
|
80
|
+
|
|
53
81
|
/** True when at least one provenance field set is present. */
|
|
54
82
|
export function hasRunProvenance(view: RunProvenanceView): boolean {
|
|
55
83
|
return (
|
|
@@ -144,10 +172,15 @@ function formatPersonaHashPrefix(promptHash: string): string {
|
|
|
144
172
|
}
|
|
145
173
|
|
|
146
174
|
/**
|
|
147
|
-
* Human transcript sentences for each
|
|
148
|
-
*
|
|
175
|
+
* Human transcript sentences for each admitted provenance field set, gated
|
|
176
|
+
* through {@link admitRunProvenance}. The autonomy line carries only the
|
|
177
|
+
* detail the canonical projection does not: the policy name, the external
|
|
178
|
+
* mode, and the bypass flag. The axis itself (mediated, approximated,
|
|
179
|
+
* bypassed) is printed by the trust summary and nowhere else, so one
|
|
180
|
+
* autonomy fact never appears in two vocabularies on one screen.
|
|
149
181
|
*/
|
|
150
|
-
export function provenanceTranscriptLines(
|
|
182
|
+
export function provenanceTranscriptLines(source: RunProvenanceView, status?: CanonicalTrustStatus): string[] {
|
|
183
|
+
const view = admitRunProvenance(source, status);
|
|
151
184
|
const lines: string[] = [];
|
|
152
185
|
if (view.pipeline !== undefined) {
|
|
153
186
|
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
@@ -163,20 +196,22 @@ export function provenanceTranscriptLines(view: RunProvenanceView): string[] {
|
|
|
163
196
|
lines.push(`escalations: ${requested} requested, ${approved} approved, ${denied} denied, ${timedOut} timed out`);
|
|
164
197
|
}
|
|
165
198
|
if (view.autonomyEnforcement !== undefined) {
|
|
166
|
-
const {
|
|
199
|
+
const { autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
167
200
|
const mode = externalMode !== undefined ? ` mode=${externalMode}` : "";
|
|
168
201
|
const bypass = dangerousBypass === true ? " dangerousBypass=true" : "";
|
|
169
|
-
lines.push(`autonomy
|
|
202
|
+
lines.push(`autonomy: ${autonomy}${mode}${bypass}`);
|
|
170
203
|
}
|
|
171
204
|
return lines;
|
|
172
205
|
}
|
|
173
206
|
|
|
174
207
|
/**
|
|
175
|
-
* Compact ` key=value` suffix for the dispatch tool's per-run and CLI lines
|
|
176
|
-
*
|
|
177
|
-
*
|
|
208
|
+
* Compact ` key=value` suffix for the dispatch tool's per-run and CLI lines,
|
|
209
|
+
* gated through {@link admitRunProvenance} on the same terms as the
|
|
210
|
+
* transcript lines. The leading space lets callers append it directly. An
|
|
211
|
+
* empty admitted view returns an empty string.
|
|
178
212
|
*/
|
|
179
|
-
export function provenanceCompactSuffix(
|
|
213
|
+
export function provenanceCompactSuffix(source: RunProvenanceView, status?: CanonicalTrustStatus): string {
|
|
214
|
+
const view = admitRunProvenance(source, status);
|
|
180
215
|
const parts: string[] = [];
|
|
181
216
|
if (view.pipeline !== undefined) {
|
|
182
217
|
const { fromRunId, position, inputBytes, inputTruncated } = view.pipeline;
|
|
@@ -191,10 +226,10 @@ export function provenanceCompactSuffix(view: RunProvenanceView): string {
|
|
|
191
226
|
parts.push(`escalations=${requested}req/${approved}appr/${denied}deny/${timedOut}timeout`);
|
|
192
227
|
}
|
|
193
228
|
if (view.autonomyEnforcement !== undefined) {
|
|
194
|
-
const {
|
|
229
|
+
const { autonomy, externalMode, dangerousBypass } = view.autonomyEnforcement;
|
|
195
230
|
const mode = externalMode !== undefined ? `/${externalMode}` : "";
|
|
196
231
|
const bypass = dangerousBypass === true ? "/bypass" : "";
|
|
197
|
-
parts.push(`
|
|
232
|
+
parts.push(`autonomy=${autonomy}${mode}${bypass}`);
|
|
198
233
|
}
|
|
199
234
|
return parts.length === 0 ? "" : ` ${parts.join(" ")}`;
|
|
200
235
|
}
|