@iowarp/clio-coder 0.3.6 → 0.3.7
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 +28 -0
- package/README.md +16 -5
- package/dist/{acp-2BEHC4DL.js → acp-SK4MD6MM.js} +10 -10
- package/dist/{agents-LNNFTM53.js → agents-2FN2K6ME.js} +30 -25
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-KXXFI2VS.js → auth-QIYZWM5I.js} +13 -13
- package/dist/{chunk-KHSFENX2.js → chunk-3HAPLH5M.js} +10 -10
- package/dist/{chunk-24I7BN55.js → chunk-465YSENW.js} +2 -2
- package/dist/{chunk-4OC57DA6.js → chunk-4DGYLA73.js} +53 -2
- package/dist/{chunk-CYQKWTG3.js → chunk-4DWFMQDR.js} +4 -4
- package/dist/{chunk-E2ER4LJF.js → chunk-5C3AQNDW.js} +25 -1
- package/dist/{chunk-22NAGB7X.js → chunk-5C77SEEY.js} +5 -94
- package/dist/{chunk-43AOLP7E.js → chunk-5FR74PWO.js} +2 -1
- package/dist/{chunk-K7T3E2SR.js → chunk-5UJ6ECTS.js} +10 -9
- package/dist/{chunk-6US73PDB.js → chunk-6M7VS3J3.js} +5 -5
- package/dist/{chunk-CJUB2JJ2.js → chunk-6TUKSZVF.js} +5 -5
- package/dist/{chunk-5JGRAMKL.js → chunk-AB4XIIVB.js} +8 -6
- package/dist/{chunk-R46L2BIR.js → chunk-BMWK7ZIZ.js} +14 -20
- package/dist/{chunk-4BPJXDWC.js → chunk-C4JBQ5SR.js} +30 -14
- package/dist/{chunk-XXQNGV4M.js → chunk-CEYBNUGC.js} +243 -63
- package/dist/{chunk-VEZEGCGW.js → chunk-D4MDIG46.js} +20 -18
- package/dist/chunk-DJNLUABN.js +843 -0
- package/dist/{chunk-RY3LY4J5.js → chunk-DMD2AGVS.js} +5 -4
- package/dist/{chunk-KOHPCX4K.js → chunk-DOOEX22V.js} +2 -2
- package/dist/chunk-DQA7QLMD.js +123 -0
- package/dist/chunk-DR52UMZW.js +21 -0
- package/dist/{chunk-XF5N4U5A.js → chunk-EBEFWSGL.js} +6 -5
- package/dist/{chunk-EYPA3EGJ.js → chunk-EELBMBT6.js} +120 -13
- package/dist/{chunk-CKXWIANG.js → chunk-EOOQZZDE.js} +16 -14
- package/dist/{chunk-WR67VIZY.js → chunk-FOT2FX5J.js} +63 -5
- package/dist/{chunk-FYYLNIL5.js → chunk-GH5622CP.js} +2 -2
- package/dist/chunk-GWS3VEIW.js +195 -0
- package/dist/{chunk-LYF7OHWH.js → chunk-J7PIKKWC.js} +8 -463
- package/dist/{chunk-NILBFAPG.js → chunk-JNXPYBB4.js} +2 -2
- package/dist/{chunk-4VP4KH3K.js → chunk-JRIO5UD2.js} +4 -4
- package/dist/{chunk-6XXKFVSN.js → chunk-JTSEDYVQ.js} +7 -7
- package/dist/{chunk-QKMUKYO7.js → chunk-KCMKRQX4.js} +236 -84
- package/dist/chunk-KZ2H5X4G.js +1026 -0
- package/dist/{chunk-QNQHSOLF.js → chunk-LADCF22A.js} +12 -12
- package/dist/chunk-M4AKACEO.js +382 -0
- package/dist/{chunk-XYDYPRZI.js → chunk-MXI6J5JF.js} +7 -7
- package/dist/{chunk-G7MUEIGA.js → chunk-OB5HIGJY.js} +1 -1
- package/dist/{chunk-EKY57CSP.js → chunk-OBMAI2DP.js} +61 -767
- package/dist/chunk-PD3MESLB.js +242 -0
- package/dist/{chunk-ZRGEBJ4T.js → chunk-QCTRSGHQ.js} +21 -21
- package/dist/chunk-RVG5JXAL.js +41 -0
- package/dist/{chunk-RD5U66HV.js → chunk-SROCI7ZU.js} +7 -7
- package/dist/{chunk-MFFY33HR.js → chunk-THKY7CD7.js} +466 -205
- package/dist/{chunk-PCZJO5TI.js → chunk-UFQ3F4FW.js} +13 -178
- package/dist/{chunk-AD2SYQYC.js → chunk-UHXRNZ2J.js} +121 -3
- package/dist/chunk-UND3GU2L.js +103 -0
- package/dist/{chunk-QM3F2GKX.js → chunk-UUANF5CR.js} +2247 -2096
- package/dist/chunk-UVDSQ6LW.js +472 -0
- package/dist/{chunk-DJVECN66.js → chunk-VQNODYQ4.js} +14 -14
- package/dist/{chunk-3BPUFZDL.js → chunk-VREKEFLL.js} +3 -3
- package/dist/{chunk-PBTHKCPN.js → chunk-WJHBC77E.js} +6 -6
- package/dist/{chunk-XE2VEJHX.js → chunk-X2KV5FXT.js} +2 -2
- package/dist/{chunk-ZXF4XRKW.js → chunk-XEGB6BCN.js} +157 -7
- package/dist/{chunk-E25LMLRW.js → chunk-YD734TPH.js} +2 -2
- package/dist/{verifiers-NCBTHHN2.js → chunk-YTYFXUI3.js} +65 -322
- package/dist/{chunk-OH3TOQTB.js → chunk-ZGH7FGS5.js} +13 -7
- package/dist/cli/index.js +32 -30
- package/dist/{clio-M2KGYUFZ.js → clio-WBVQEBKO.js} +7 -7
- package/dist/{code-nav-GQNL7XA6.js → code-nav-FGGFIE7L.js} +3 -3
- package/dist/{components-5TTYYX6G.js → components-F7OEATSO.js} +4 -4
- package/dist/{config-XUUYQIWO.js → config-TRBL3RCF.js} +34 -29
- package/dist/{configure-IHJ7YOMV.js → configure-OLCVPHNM.js} +15 -15
- package/dist/{context-74JLXAWD.js → context-MJIJ6GOX.js} +11 -11
- package/dist/{context-ZQ7SIFJV.js → context-WFPKQSM6.js} +19 -3
- package/dist/{context-75MIWW3U.js → context-XEWE3MOJ.js} +31 -26
- package/dist/{context-clear-GYKWNUML.js → context-clear-KNOS2JPB.js} +31 -26
- package/dist/{context-working-set-UX5KEP4J.js → context-working-set-EUXAZI6N.js} +8 -8
- package/dist/{dispatch-runner-GIJBHNFL.js → dispatch-runner-B7MTOVKL.js} +313 -53
- package/dist/{docs-6FZSCG5B.js → docs-FLJTIDSE.js} +4 -4
- package/dist/{doctor-SVJ5BZCW.js → doctor-RN4YKO2X.js} +14 -14
- package/dist/{eval-CG6LLBLD.js → eval-RUBJVSNQ.js} +8 -7
- package/dist/{evidence-ZYFIEN42.js → evidence-JZNBUOQZ.js} +30 -25
- package/dist/{evolve-QGEXEMDW.js → evolve-FJVC4KKI.js} +30 -25
- package/dist/{extensions-ADGNCJJD.js → extensions-IQL36S7K.js} +4 -4
- package/dist/{fleet-S5R4ZOQY.js → fleet-BDKYJFCP.js} +214 -360
- package/dist/fleet-commands-ZFIWZSB3.js +70 -0
- package/dist/fleet-graph-Y6HPXIVF.js +125 -0
- package/dist/fleet-new-RDVJLHHH.js +48 -0
- package/dist/fleet-validate-BIYREGIK.js +79 -0
- package/dist/{init-5DRU55YR.js → init-LQUB5COQ.js} +44 -37
- package/dist/library-NJAHIGG4.js +217 -0
- package/dist/{memory-7YKKR6UC.js → memory-OG6HOYKM.js} +31 -26
- package/dist/{models-ZPOLRU2C.js → models-5ZG5XY7J.js} +21 -20
- package/dist/{monitor-US5F5YGZ.js → monitor-TJ7AMTGB.js} +49 -30
- package/dist/{orchestrator-E2AL4T5N.js → orchestrator-WZYB54DM.js} +3827 -581
- package/dist/{paths-E7KYAQWE.js → paths-XUC7GS6E.js} +4 -4
- package/dist/{reset-KZ652EK6.js → reset-PXQT45IY.js} +7 -7
- package/dist/{run-SRNBKDWD.js → run-FQ74YF62.js} +53 -45
- package/dist/{share-CGZE33UP.js → share-FW7SVCL3.js} +33 -9
- package/dist/{skills-S2X4DLY5.js → skills-7E7IRB3R.js} +24 -8
- package/dist/{skills-eval-W2GGIC4R.js → skills-eval-LI75W6OK.js} +34 -27
- package/dist/{targets-54SWINWB.js → targets-4CIFKCTW.js} +23 -22
- package/dist/{terminal-lease-SAIF2OGY.js → terminal-lease-WUZY7ZV5.js} +4 -4
- package/dist/{uninstall-BVLWXKBT.js → uninstall-7FV7IP4E.js} +4 -4
- package/dist/{upgrade-JKAR27XC.js → upgrade-K2HVIVMQ.js} +20 -19
- package/dist/{usage-MSAWCLX4.js → usage-GTZELZQX.js} +116 -49
- package/dist/verifiers-RLAHT27O.js +336 -0
- package/dist/{verify-X5HDROLA.js → verify-BX3BRKH5.js} +7 -6
- package/dist/{wiki-generate-GUSOQ6ZP.js → wiki-generate-ASIFASCN.js} +45 -37
- package/dist/worker/entry.js +38 -35
- 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 +10 -6
- package/docs/built-in-agents.md +26 -2
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +82 -2
- package/docs/configuration-and-targets.md +79 -2
- 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 +5 -5
- 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 +197 -10
- package/docs/git-commit-provenance.md +2 -2
- package/docs/glossary.md +1 -1
- 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 +55 -8
- package/docs/proactive-memory.md +1 -1
- package/docs/prompt-envelope-and-tools.md +1 -1
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +79 -64
- 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 -1
- 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 +121 -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/usage.ts +111 -19
- package/src/core/bus-events.ts +4 -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/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/fleet-contract.ts +278 -16
- package/src/domains/agents/index.ts +14 -0
- package/src/domains/agents/result-contract.ts +235 -1
- package/src/domains/config/classify.ts +4 -0
- package/src/domains/dispatch/active-route-planner.ts +14 -0
- 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 +34 -0
- package/src/domains/dispatch/delegation-plan.ts +167 -0
- package/src/domains/dispatch/execution-plan.ts +76 -5
- package/src/domains/dispatch/execution-role.ts +3 -1
- package/src/domains/dispatch/execution-scheduler.ts +183 -67
- package/src/domains/dispatch/extension.ts +258 -9
- 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 +737 -0
- package/src/domains/dispatch/gate-role-prompts.ts +9 -0
- package/src/domains/dispatch/host-verification.ts +178 -0
- package/src/domains/dispatch/index.ts +38 -0
- package/src/domains/dispatch/intent.ts +159 -0
- package/src/domains/dispatch/receipt-integrity.ts +8 -4
- package/src/domains/dispatch/state.ts +36 -3
- package/src/domains/dispatch/types.ts +51 -6
- package/src/domains/dispatch/validation.ts +66 -6
- package/src/domains/evidence/trust-status.ts +10 -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/resources/index.ts +20 -0
- package/src/domains/resources/library.ts +326 -0
- package/src/domains/resources/skills/marketplace.ts +37 -12
- package/src/domains/session/handoff.ts +629 -0
- package/src/domains/share/archive.ts +67 -2
- 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 +260 -16
- 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 +9 -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 +101 -4
- 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 +432 -5
- 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/watchdog-run.ts +75 -0
- package/src/interactive/worker-share.ts +56 -1
- package/src/interactive/worker-stream.ts +7 -0
- package/src/tools/bootstrap.ts +3 -0
- package/src/tools/compete-worktrees.ts +13 -79
- package/src/tools/dispatch-admission.ts +242 -8
- package/src/tools/dispatch-arguments.ts +57 -1
- package/src/tools/dispatch-plan.ts +136 -6
- package/src/tools/dispatch-runner.ts +319 -13
- package/src/tools/dispatch-types.ts +20 -1
- package/src/tools/dispatch.ts +72 -2
- package/src/tools/monitor.ts +16 -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 +2 -1
- package/src/worker/spec-contract.ts +1 -0
- package/dist/chunk-HC4CLZ2Y.js +0 -68
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { createHash, randomBytes } from "node:crypto";
|
|
13
13
|
import { type Dirent, existsSync, readdirSync, readFileSync } from "node:fs";
|
|
14
14
|
import { isAbsolute, relative, resolve as resolvePath, sep } from "node:path";
|
|
15
|
-
import { BusChannels, type DispatchCompletedPayload } from "../../core/bus-events.js";
|
|
15
|
+
import { BusChannels, type DispatchCompletedPayload, type DispatchRunIdentity } from "../../core/bus-events.js";
|
|
16
16
|
import { DEFAULT_SETTINGS, type DelegationToolGovernance } from "../../core/defaults.js";
|
|
17
17
|
import type { DomainBundle, DomainContext, DomainExtension } from "../../core/domain-loader.js";
|
|
18
18
|
import { GUARDRAIL_DEFAULTS } from "../../core/guardrails.js";
|
|
@@ -40,6 +40,12 @@ import { WORKER_RUNTIME_MEDIATES_CLIO_DISPATCH } from "../../engine/worker-runti
|
|
|
40
40
|
import { toolPromptHintsForNames } from "../../tools/builtin-tool-catalog.js";
|
|
41
41
|
import { networkToolsDisabled } from "../../tools/network-policy.js";
|
|
42
42
|
import { applyToolProfile, assertToolProfileEnforceable, type ToolProfileName } from "../../tools/profiles.js";
|
|
43
|
+
import {
|
|
44
|
+
applyTaskWorktree,
|
|
45
|
+
cleanupTaskWorktree,
|
|
46
|
+
createTaskWorktree,
|
|
47
|
+
gitCheckoutRoot,
|
|
48
|
+
} from "../../tools/task-worktree.js";
|
|
43
49
|
import { truncateUtf8 } from "../../tools/truncate-utf8.js";
|
|
44
50
|
import {
|
|
45
51
|
serializeWorkerRuntimeDescriptor,
|
|
@@ -138,6 +144,7 @@ import { type BatchState, createBatch, onRunComplete, snapshotBatch } from "./ba
|
|
|
138
144
|
import { type RunToolBudgetEnvelope, resolveToolBudgetEnvelope } from "./budget-envelope.js";
|
|
139
145
|
import { assessCapabilityMismatch, type CapabilityMismatch } from "./capability-match.js";
|
|
140
146
|
import { capacityLeaseUsage, createNodeLeaseUsageReader } from "./capacity-lease.js";
|
|
147
|
+
import { acquireCheckoutWriterLease, type CheckoutWriterLease } from "./checkout-writer-lease.js";
|
|
141
148
|
import type {
|
|
142
149
|
DispatchAdmissionObserver,
|
|
143
150
|
DispatchContract,
|
|
@@ -159,6 +166,7 @@ import {
|
|
|
159
166
|
import { routeFactVerdict } from "./fleet-preflight.js";
|
|
160
167
|
import { competeStanceLiner, isBoundedGateRolePrompt } from "./gate-role-prompts.js";
|
|
161
168
|
import { classifyHeartbeat, DEFAULT_HEARTBEAT_SPEC, type HeartbeatSpec, type HeartbeatStatus } from "./heartbeat.js";
|
|
169
|
+
import { hostVerificationRejection, runHostVerification } from "./host-verification.js";
|
|
162
170
|
import { adaptJointRouteInput } from "./joint-route-adapter.js";
|
|
163
171
|
import {
|
|
164
172
|
configuredJointNodes,
|
|
@@ -209,7 +217,7 @@ import { createRouteObserver, type RouteObservationHandle, type RouteObserver }
|
|
|
209
217
|
import { reduceRouteQuality } from "./route-quality.js";
|
|
210
218
|
import { defaultRoutingIntent } from "./routing-intent.js";
|
|
211
219
|
import { detectRunIdentity } from "./run-identity.js";
|
|
212
|
-
import { type Ledger, openLedger } from "./state.js";
|
|
220
|
+
import { type Ledger, newRunId, openLedger } from "./state.js";
|
|
213
221
|
import {
|
|
214
222
|
countToolCalls,
|
|
215
223
|
hasPotentiallyMutatingAttempt,
|
|
@@ -1826,7 +1834,7 @@ function buildDispatchWorkerSpec(input: DispatchWorkerSpecInput, config?: Config
|
|
|
1826
1834
|
// A gate role that overrides the recipe contract gets no worker-side repair,
|
|
1827
1835
|
// for the same reason it gets no recipe validation.
|
|
1828
1836
|
if (appliesRecipeResultContract(input.req.gate?.role) && input.recipe?.resultContract) {
|
|
1829
|
-
spec.resultContract = input.recipe.resultContract;
|
|
1837
|
+
spec.resultContract = input.req.resultContractOverride ?? input.recipe.resultContract;
|
|
1830
1838
|
}
|
|
1831
1839
|
const product = input.req.product ?? input.recipe?.product;
|
|
1832
1840
|
if (product) spec.product = product;
|
|
@@ -3610,10 +3618,12 @@ export function createDispatchBundle(
|
|
|
3610
3618
|
let identity!: ReturnType<typeof detectRunIdentity>;
|
|
3611
3619
|
try {
|
|
3612
3620
|
envelope = ledgerRef.create({
|
|
3621
|
+
...(req.runIdHint !== undefined ? { id: req.runIdHint } : {}),
|
|
3613
3622
|
agentId: req.agentId,
|
|
3614
3623
|
executionRole: withAttemptRole(req.executionRole, req.lineage?.attempt ?? 0),
|
|
3615
3624
|
requestOrigin: lifecycle.requestOrigin,
|
|
3616
3625
|
task: req.task,
|
|
3626
|
+
...(req.intent !== undefined ? { intent: structuredClone(req.intent) } : {}),
|
|
3617
3627
|
targetId,
|
|
3618
3628
|
wireModelId,
|
|
3619
3629
|
runtimeId,
|
|
@@ -3645,6 +3655,7 @@ export function createDispatchBundle(
|
|
|
3645
3655
|
...(lifecycle.pipeline ? { pipeline: lifecycle.pipeline } : {}),
|
|
3646
3656
|
...(lifecycle.briefing ? { briefing: lifecycle.briefing } : {}),
|
|
3647
3657
|
...(req.gate !== undefined ? { gate: req.gate } : {}),
|
|
3658
|
+
...(req.council !== undefined ? { council: req.council } : {}),
|
|
3648
3659
|
...(req.plan !== undefined ? { plan: req.plan } : {}),
|
|
3649
3660
|
...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
|
|
3650
3661
|
});
|
|
@@ -3787,6 +3798,7 @@ export function createDispatchBundle(
|
|
|
3787
3798
|
executionRole: envelope.executionRole,
|
|
3788
3799
|
requestOrigin: lifecycle.requestOrigin,
|
|
3789
3800
|
task: req.task,
|
|
3801
|
+
...(req.intent !== undefined ? { intent: structuredClone(req.intent) } : {}),
|
|
3790
3802
|
targetId,
|
|
3791
3803
|
wireModelId,
|
|
3792
3804
|
runtimeId,
|
|
@@ -3801,6 +3813,7 @@ export function createDispatchBundle(
|
|
|
3801
3813
|
...(lifecycle.pipeline ? { pipeline: lifecycle.pipeline } : {}),
|
|
3802
3814
|
...(lifecycle.briefing ? { briefing: lifecycle.briefing } : {}),
|
|
3803
3815
|
...(req.gate !== undefined ? { gate: req.gate } : {}),
|
|
3816
|
+
...(req.council !== undefined ? { council: req.council } : {}),
|
|
3804
3817
|
...(req.plan !== undefined ? { plan: req.plan } : {}),
|
|
3805
3818
|
...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
|
|
3806
3819
|
projectContext: lifecycle.projectContext,
|
|
@@ -3913,6 +3926,7 @@ export function createDispatchBundle(
|
|
|
3913
3926
|
durationMs,
|
|
3914
3927
|
exitCode: receipt.exitCode,
|
|
3915
3928
|
toolActivity: receipt.toolActivity ?? null,
|
|
3929
|
+
...(receipt.hostVerification !== undefined ? { hostVerification: receipt.hostVerification.status } : {}),
|
|
3916
3930
|
...(receipt.skillActivations && receipt.skillActivations.length > 0
|
|
3917
3931
|
? { skillActivations: [...receipt.skillActivations] }
|
|
3918
3932
|
: {}),
|
|
@@ -4444,7 +4458,8 @@ export function createDispatchBundle(
|
|
|
4444
4458
|
if (
|
|
4445
4459
|
event.type === "clio_run_outcome" &&
|
|
4446
4460
|
isRunOutcomeCode(event.payload?.outcomeCode) &&
|
|
4447
|
-
event.payload.outcomeCode !== "worker_final_output_missing"
|
|
4461
|
+
event.payload.outcomeCode !== "worker_final_output_missing" &&
|
|
4462
|
+
event.payload.outcomeCode !== "host_verification_rejected"
|
|
4448
4463
|
) {
|
|
4449
4464
|
if (acceptsOutcomeCodeEvents) {
|
|
4450
4465
|
trustedOutcomeCodes.add(event.payload.outcomeCode);
|
|
@@ -4604,11 +4619,13 @@ export function createDispatchBundle(
|
|
|
4604
4619
|
let identity!: ReturnType<typeof detectRunIdentity>;
|
|
4605
4620
|
try {
|
|
4606
4621
|
envelope = ledgerRef.create({
|
|
4622
|
+
...(req.runIdHint !== undefined ? { id: req.runIdHint } : {}),
|
|
4607
4623
|
agentId: req.agentId,
|
|
4608
4624
|
executionRole: withAttemptRole(req.executionRole, req.lineage?.attempt ?? 0),
|
|
4609
4625
|
agentAudience: lifecycle.agentAudience,
|
|
4610
4626
|
requestOrigin: lifecycle.requestOrigin,
|
|
4611
4627
|
task: req.task,
|
|
4628
|
+
...(req.intent !== undefined ? { intent: structuredClone(req.intent) } : {}),
|
|
4612
4629
|
budget: lifecycle.budgetEnvelope,
|
|
4613
4630
|
targetId: lifecycle.target.target.id,
|
|
4614
4631
|
wireModelId: lifecycle.target.wireModelId,
|
|
@@ -4658,6 +4675,7 @@ export function createDispatchBundle(
|
|
|
4658
4675
|
...(lifecycle.pipeline ? { pipeline: lifecycle.pipeline } : {}),
|
|
4659
4676
|
...(lifecycle.briefing ? { briefing: lifecycle.briefing } : {}),
|
|
4660
4677
|
...(req.gate !== undefined ? { gate: req.gate } : {}),
|
|
4678
|
+
...(req.council !== undefined ? { council: req.council } : {}),
|
|
4661
4679
|
...(req.plan !== undefined ? { plan: req.plan } : {}),
|
|
4662
4680
|
...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
|
|
4663
4681
|
...(heartbeatAt ? { heartbeatAt: heartbeatIso(heartbeatAt.current) } : {}),
|
|
@@ -4678,6 +4696,7 @@ export function createDispatchBundle(
|
|
|
4678
4696
|
budget: lifecycle.budgetEnvelope,
|
|
4679
4697
|
...(placement !== undefined && placement !== null ? { node: placement.node.id } : {}),
|
|
4680
4698
|
...(req.gate !== undefined ? { gate: { role: req.gate.role, cycle: req.gate.cycle } } : {}),
|
|
4699
|
+
...(req.council !== undefined ? { council: req.council } : {}),
|
|
4681
4700
|
...(req.reroutes !== undefined && req.reroutes.length > 0 ? { rerouteCount: req.reroutes.length } : {}),
|
|
4682
4701
|
...(lifecycle.target.modelCapabilities !== undefined &&
|
|
4683
4702
|
lifecycle.target.modelCapabilities !== null &&
|
|
@@ -4829,6 +4848,15 @@ export function createDispatchBundle(
|
|
|
4829
4848
|
const tokenCount =
|
|
4830
4849
|
tokenMeter.inputTokens + tokenMeter.outputTokens + tokenMeter.cacheReadTokens + tokenMeter.cacheWriteTokens;
|
|
4831
4850
|
const protectedArtifacts = protectedArtifactReceiptSummary(spec.protectedArtifactState);
|
|
4851
|
+
const fleetGate = (() => {
|
|
4852
|
+
if (req.fleetGateReceipt === undefined) return null;
|
|
4853
|
+
try {
|
|
4854
|
+
const content = readFileSync(resolvePath(lifecycle.cwd, req.fleetGateReceipt.path));
|
|
4855
|
+
return { path: req.fleetGateReceipt.path, pathHash: createHash("sha256").update(content).digest("hex") };
|
|
4856
|
+
} catch {
|
|
4857
|
+
return { path: req.fleetGateReceipt.path, pathHash: createHash("sha256").update("").digest("hex") };
|
|
4858
|
+
}
|
|
4859
|
+
})();
|
|
4832
4860
|
// Sealed from the stored board, never from anything the worker said
|
|
4833
4861
|
// about itself. Absent when the run had no ledger.
|
|
4834
4862
|
const ledgerContribution = (() => {
|
|
@@ -4864,6 +4892,7 @@ export function createDispatchBundle(
|
|
|
4864
4892
|
outcome,
|
|
4865
4893
|
outcomeCode,
|
|
4866
4894
|
lineage,
|
|
4895
|
+
...(req.intent !== undefined ? { intent: structuredClone(req.intent) } : {}),
|
|
4867
4896
|
identity,
|
|
4868
4897
|
node: placement?.node ?? LOCAL_RUN_NODE,
|
|
4869
4898
|
...receiptAttestationFields(worker.attestation?.() ?? null),
|
|
@@ -4874,7 +4903,9 @@ export function createDispatchBundle(
|
|
|
4874
4903
|
...(lifecycle.briefing ? { briefing: lifecycle.briefing } : {}),
|
|
4875
4904
|
...(steering.length > 0 ? { steering: steering.map((entry) => ({ ...entry })) } : {}),
|
|
4876
4905
|
...(req.gate !== undefined ? { gate: req.gate } : {}),
|
|
4906
|
+
...(req.council !== undefined ? { council: req.council } : {}),
|
|
4877
4907
|
...(req.plan !== undefined ? { plan: req.plan } : {}),
|
|
4908
|
+
...(fleetGate !== null ? { fleetGate } : {}),
|
|
4878
4909
|
...(lifecycle.personaOverride ? { personaOverride: lifecycle.personaOverride } : {}),
|
|
4879
4910
|
projectContext: lifecycle.projectContext,
|
|
4880
4911
|
rulesApplied: lifecycle.rulesApplied,
|
|
@@ -5004,6 +5035,7 @@ export function createDispatchBundle(
|
|
|
5004
5035
|
durationMs,
|
|
5005
5036
|
exitCode: receipt.exitCode,
|
|
5006
5037
|
toolActivity: receipt.toolActivity ?? null,
|
|
5038
|
+
...(receipt.hostVerification !== undefined ? { hostVerification: receipt.hostVerification.status } : {}),
|
|
5007
5039
|
...(receipt.skillActivations && receipt.skillActivations.length > 0
|
|
5008
5040
|
? { skillActivations: [...receipt.skillActivations] }
|
|
5009
5041
|
: {}),
|
|
@@ -5102,7 +5134,7 @@ export function createDispatchBundle(
|
|
|
5102
5134
|
const capturedOutput = outputCapture.snapshot();
|
|
5103
5135
|
const observedRunEffects = runEffects.snapshot();
|
|
5104
5136
|
const appliedResultContract = appliesRecipeResultContract(req.gate?.role)
|
|
5105
|
-
? (lifecycle.recipe?.resultContract ?? null)
|
|
5137
|
+
? (req.resultContractOverride ?? lifecycle.recipe?.resultContract ?? null)
|
|
5106
5138
|
: null;
|
|
5107
5139
|
const resultContract = validateRecipeResult({
|
|
5108
5140
|
contract: appliedResultContract,
|
|
@@ -5166,13 +5198,40 @@ export function createDispatchBundle(
|
|
|
5166
5198
|
finalDetail = [finalDetail, describeUngroundedValidations(validationGrounding)].filter(Boolean).join("; ");
|
|
5167
5199
|
}
|
|
5168
5200
|
const hasTerminalArtifact =
|
|
5169
|
-
lifecycle.recipe?.resultContract
|
|
5201
|
+
(req.resultContractOverride ?? lifecycle.recipe?.resultContract)?.kind === "architect-plan" &&
|
|
5202
|
+
resultValidation?.conformance === "pass";
|
|
5170
5203
|
if (finalOutcome === "succeeded" && !hasDurableFinalOutput(capturedOutput) && !hasTerminalArtifact) {
|
|
5171
5204
|
finalOutcome = "failed";
|
|
5172
5205
|
outcomeCode = "worker_final_output_missing";
|
|
5173
5206
|
finalDetail = WORKER_FINAL_OUTPUT_MISSING_DETAIL;
|
|
5174
5207
|
failureMessage = finalDetail;
|
|
5175
5208
|
}
|
|
5209
|
+
const hostVerification = await runHostVerification({
|
|
5210
|
+
runId: envelope.id,
|
|
5211
|
+
request: req,
|
|
5212
|
+
workerSuccessful: finalOutcome === "succeeded",
|
|
5213
|
+
onDiagnostic: (error) => reportDispatchDiagnostic(`write host verification memo for ${envelope.id}`, error),
|
|
5214
|
+
});
|
|
5215
|
+
const hostRejection = hostVerificationRejection(hostVerification);
|
|
5216
|
+
if (hostRejection !== null && finalOutcome === "succeeded") {
|
|
5217
|
+
finalOutcome = "failed";
|
|
5218
|
+
outcomeCode = hostRejection.outcomeCode;
|
|
5219
|
+
finalDetail = hostRejection.detail;
|
|
5220
|
+
failureMessage = finalDetail;
|
|
5221
|
+
}
|
|
5222
|
+
let worktreeReceipt: RunReceiptDraft["worktree"];
|
|
5223
|
+
if (req.taskWorktree !== undefined && finalOutcome === "succeeded") {
|
|
5224
|
+
worktreeReceipt = applyTaskWorktree({
|
|
5225
|
+
worktree: req.taskWorktree,
|
|
5226
|
+
apply: req.apply ?? "merge",
|
|
5227
|
+
protectedPaths: getProtectedArtifactState().artifacts.map((artifact) => artifact.path),
|
|
5228
|
+
});
|
|
5229
|
+
if (worktreeReceipt.reason !== undefined) {
|
|
5230
|
+
finalOutcome = "failed";
|
|
5231
|
+
finalDetail = worktreeReceipt.reason;
|
|
5232
|
+
failureMessage = finalDetail;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5176
5235
|
const status = runStatusForOutcome(finalOutcome);
|
|
5177
5236
|
const failureClass = classifyFailure(evidence, result, finalOutcome, outcomeCode);
|
|
5178
5237
|
const receiptDraft = buildReceiptDraft(
|
|
@@ -5186,6 +5245,8 @@ export function createDispatchBundle(
|
|
|
5186
5245
|
sealedResultContractFact,
|
|
5187
5246
|
validationGrounding === null ? null : { ...validationGrounding, ungrounded: [...validationGrounding.ungrounded] },
|
|
5188
5247
|
);
|
|
5248
|
+
if (hostVerification !== undefined) receiptDraft.hostVerification = hostVerification;
|
|
5249
|
+
if (worktreeReceipt !== undefined) receiptDraft.worktree = worktreeReceipt;
|
|
5189
5250
|
const ledgerPatch: Partial<RunEnvelope> = {
|
|
5190
5251
|
status,
|
|
5191
5252
|
outcome: finalOutcome,
|
|
@@ -5216,6 +5277,13 @@ export function createDispatchBundle(
|
|
|
5216
5277
|
ledgerRef.update(envelope.id, ledgerPatch);
|
|
5217
5278
|
const receipt = ledgerRef.recordReceipt(envelope.id, sealRouteDecision(receiptDraft, routeObservation.decision));
|
|
5218
5279
|
await ledgerRef.persist();
|
|
5280
|
+
if (worktreeReceipt?.applied === true && req.taskWorktree !== undefined) {
|
|
5281
|
+
try {
|
|
5282
|
+
cleanupTaskWorktree(req.taskWorktree, true);
|
|
5283
|
+
} catch (cleanupError) {
|
|
5284
|
+
reportDispatchDiagnostic(`clean applied task worktree ${req.taskWorktree.runId}`, cleanupError);
|
|
5285
|
+
}
|
|
5286
|
+
}
|
|
5219
5287
|
active.delete(envelope.id);
|
|
5220
5288
|
recordTargetOutcome(
|
|
5221
5289
|
lifecycle.target.target.id,
|
|
@@ -5303,10 +5371,58 @@ export function createDispatchBundle(
|
|
|
5303
5371
|
events: AsyncIterableIterator<unknown>;
|
|
5304
5372
|
finalPromise: Promise<RunReceipt>;
|
|
5305
5373
|
}> {
|
|
5374
|
+
let prepared = req;
|
|
5375
|
+
let createdWorktree: DispatchRequest["taskWorktree"];
|
|
5376
|
+
let writerLease: CheckoutWriterLease | undefined;
|
|
5377
|
+
const writerRecipe = agents.get(req.agentId);
|
|
5378
|
+
if (writerRecipe !== null && normalizeAgentSpec(writerRecipe).capabilityClass === "workspace-edit") {
|
|
5379
|
+
const checkout = req.taskWorktree?.root ?? gitCheckoutRoot(req.cwd ?? process.cwd());
|
|
5380
|
+
if (checkout !== null) writerLease = acquireCheckoutWriterLease({ checkout });
|
|
5381
|
+
}
|
|
5382
|
+
if (req.worktree === true && req.taskWorktree === undefined) {
|
|
5383
|
+
const requestedCwd = resolvePath(req.cwd ?? process.cwd());
|
|
5384
|
+
const root = gitCheckoutRoot(requestedCwd);
|
|
5385
|
+
if (root === null) throw new Error("worktree_non_git_checkout");
|
|
5386
|
+
if (req.taskWorktreeDestination !== undefined && root !== req.taskWorktreeDestination) {
|
|
5387
|
+
writerLease?.release();
|
|
5388
|
+
throw new Error("dispatch: worktree merge destination differs from the approved execution snapshot");
|
|
5389
|
+
}
|
|
5390
|
+
const runId = newRunId();
|
|
5391
|
+
let taskWorktree: NonNullable<DispatchRequest["taskWorktree"]>;
|
|
5392
|
+
try {
|
|
5393
|
+
taskWorktree = createTaskWorktree(root, runId);
|
|
5394
|
+
} catch (error) {
|
|
5395
|
+
writerLease?.release();
|
|
5396
|
+
throw error;
|
|
5397
|
+
}
|
|
5398
|
+
createdWorktree = taskWorktree;
|
|
5399
|
+
const cwdRelative = relative(root, requestedCwd);
|
|
5400
|
+
const workerCwd = resolvePath(taskWorktree.path, cwdRelative);
|
|
5401
|
+
const writeRoots = req.writeRoots?.map((entry) => {
|
|
5402
|
+
const rel = relative(root, entry);
|
|
5403
|
+
return rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel) ? entry : resolvePath(taskWorktree.path, rel);
|
|
5404
|
+
});
|
|
5405
|
+
prepared = {
|
|
5406
|
+
...req,
|
|
5407
|
+
runIdHint: runId,
|
|
5408
|
+
taskWorktree,
|
|
5409
|
+
cwd: workerCwd,
|
|
5410
|
+
protectedArtifactRemap: { sourceRoot: root, workerRoot: taskWorktree.path },
|
|
5411
|
+
...(writeRoots === undefined ? {} : { writeRoots }),
|
|
5412
|
+
};
|
|
5413
|
+
}
|
|
5306
5414
|
let handle: Awaited<ReturnType<typeof dispatchAttempt>>;
|
|
5307
5415
|
try {
|
|
5308
|
-
handle = await dispatchAttempt(
|
|
5416
|
+
handle = await dispatchAttempt(prepared, observer);
|
|
5309
5417
|
} catch (error) {
|
|
5418
|
+
writerLease?.release();
|
|
5419
|
+
if (createdWorktree !== undefined) {
|
|
5420
|
+
try {
|
|
5421
|
+
cleanupTaskWorktree(createdWorktree, true);
|
|
5422
|
+
} catch (cleanupError) {
|
|
5423
|
+
reportDispatchDiagnostic(`clean task worktree ${createdWorktree.runId} after admission failure`, cleanupError);
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5310
5426
|
if (req.reservation !== undefined && req.lineage === undefined) {
|
|
5311
5427
|
rollbackDispatchReservation(req.reservation.ownerId, now());
|
|
5312
5428
|
}
|
|
@@ -5314,7 +5430,7 @@ export function createDispatchBundle(
|
|
|
5314
5430
|
}
|
|
5315
5431
|
// Requests carrying lineage are internal attempts (retry or nested
|
|
5316
5432
|
// orchestration) and retain the per-attempt handle contract.
|
|
5317
|
-
if (req.lineage) return handle;
|
|
5433
|
+
if (req.lineage) return { ...handle, finalPromise: handle.finalPromise.finally(() => writerLease?.release()) };
|
|
5318
5434
|
|
|
5319
5435
|
const assignment = assignments.open(handle.runId, assignmentPolicyFor(handle.effectiveRequest));
|
|
5320
5436
|
persistAssignment(registerAssignment(assignment.id), `${assignment.id}:open`);
|
|
@@ -5327,9 +5443,10 @@ export function createDispatchBundle(
|
|
|
5327
5443
|
const reservation = req.reservation;
|
|
5328
5444
|
const terminal =
|
|
5329
5445
|
reservation === undefined
|
|
5330
|
-
? assignment.terminal
|
|
5446
|
+
? assignment.terminal.finally(() => writerLease?.release())
|
|
5331
5447
|
: assignment.terminal.finally(() => {
|
|
5332
5448
|
releaseDispatchReservationMember(reservation.ownerId, reservation.memberId, now());
|
|
5449
|
+
writerLease?.release();
|
|
5333
5450
|
});
|
|
5334
5451
|
return { runId: handle.runId, events: assignment.events, finalPromise: terminal };
|
|
5335
5452
|
}
|
|
@@ -5713,6 +5830,137 @@ export function createDispatchBundle(
|
|
|
5713
5830
|
};
|
|
5714
5831
|
}
|
|
5715
5832
|
|
|
5833
|
+
async function sealCouncilSynthesis(input: {
|
|
5834
|
+
group: string;
|
|
5835
|
+
round: number;
|
|
5836
|
+
kind: "none" | "vote";
|
|
5837
|
+
text: string;
|
|
5838
|
+
subjects: ReadonlyArray<{ runId: string; digest: string | null }>;
|
|
5839
|
+
template: RunReceipt;
|
|
5840
|
+
}): Promise<RunReceipt> {
|
|
5841
|
+
const l = requireLedger();
|
|
5842
|
+
const runId = newRunId();
|
|
5843
|
+
const task = `Council ${input.kind} synthesis`;
|
|
5844
|
+
// The synthesis is the council's own verdict, filed under the origin the
|
|
5845
|
+
// council was asked from: an internal origin would keep it out of the
|
|
5846
|
+
// transcript worker fold, and with it out of /share.
|
|
5847
|
+
const origin = input.template.requestOrigin ?? "agent";
|
|
5848
|
+
const gate = { role: "synthesis" as const, group: input.group, cycle: input.round, subjects: [...input.subjects] };
|
|
5849
|
+
const council = { group: input.group, label: "synthesis", round: input.round };
|
|
5850
|
+
const created = l.create({
|
|
5851
|
+
id: runId,
|
|
5852
|
+
agentId: "council-synthesis",
|
|
5853
|
+
executionRole: "judge",
|
|
5854
|
+
requestOrigin: origin,
|
|
5855
|
+
task,
|
|
5856
|
+
targetId: input.template.targetId,
|
|
5857
|
+
wireModelId: input.template.wireModelId,
|
|
5858
|
+
runtimeId: input.template.runtimeId,
|
|
5859
|
+
runtimeKind: input.template.runtimeKind,
|
|
5860
|
+
sessionId: input.template.sessionId,
|
|
5861
|
+
cwd: input.template.reproducibility?.cwd ?? process.cwd(),
|
|
5862
|
+
});
|
|
5863
|
+
const endedAt = new Date().toISOString();
|
|
5864
|
+
l.update(runId, {
|
|
5865
|
+
status: "completed",
|
|
5866
|
+
outcome: "succeeded",
|
|
5867
|
+
endedAt,
|
|
5868
|
+
exitCode: 0,
|
|
5869
|
+
gate,
|
|
5870
|
+
council,
|
|
5871
|
+
...(input.template.plan !== undefined ? { plan: input.template.plan } : {}),
|
|
5872
|
+
});
|
|
5873
|
+
const receipt = l.recordReceipt(runId, {
|
|
5874
|
+
runId,
|
|
5875
|
+
agentId: "council-synthesis",
|
|
5876
|
+
executionRole: "judge",
|
|
5877
|
+
requestOrigin: origin,
|
|
5878
|
+
task,
|
|
5879
|
+
targetId: input.template.targetId,
|
|
5880
|
+
wireModelId: input.template.wireModelId,
|
|
5881
|
+
runtimeId: input.template.runtimeId,
|
|
5882
|
+
runtimeKind: input.template.runtimeKind,
|
|
5883
|
+
startedAt: created.startedAt,
|
|
5884
|
+
endedAt,
|
|
5885
|
+
outcome: "succeeded",
|
|
5886
|
+
outcomeDetail: null,
|
|
5887
|
+
exitCode: 0,
|
|
5888
|
+
tokenCount: 0,
|
|
5889
|
+
inputTokenCount: 0,
|
|
5890
|
+
outputTokenCount: 0,
|
|
5891
|
+
reasoningTokenCount: 0,
|
|
5892
|
+
cacheReadTokenCount: 0,
|
|
5893
|
+
cacheWriteTokenCount: 0,
|
|
5894
|
+
output: { state: "final", text: input.text, bytes: Buffer.byteLength(input.text, "utf8"), truncated: false },
|
|
5895
|
+
costUsd: 0,
|
|
5896
|
+
costProvenance: "unknown",
|
|
5897
|
+
compiledPromptHash: null,
|
|
5898
|
+
staticCompositionHash: null,
|
|
5899
|
+
clioVersion: readClioVersion(),
|
|
5900
|
+
piMonoVersion: readPiMonoVersion(),
|
|
5901
|
+
platform: process.platform,
|
|
5902
|
+
nodeVersion: process.version,
|
|
5903
|
+
toolCalls: 0,
|
|
5904
|
+
toolStats: [],
|
|
5905
|
+
verification: { state: "unverified", basis: "no-validation-tool" },
|
|
5906
|
+
routingIntent: defaultRoutingIntent({}),
|
|
5907
|
+
quality: createRunReceiptQuality({ runtimeEnforceable: false, enforcementPassed: null, resultContract: null }),
|
|
5908
|
+
reproducibility: collectReproducibility(input.template.reproducibility?.cwd ?? process.cwd(), null),
|
|
5909
|
+
sessionId: input.template.sessionId,
|
|
5910
|
+
gate,
|
|
5911
|
+
council,
|
|
5912
|
+
...(input.template.plan !== undefined ? { plan: input.template.plan } : {}),
|
|
5913
|
+
});
|
|
5914
|
+
await l.persist();
|
|
5915
|
+
// The synthesis never ran as a worker, so nothing else publishes its
|
|
5916
|
+
// lifecycle. The Fleet Runs board and /share are built from these
|
|
5917
|
+
// events, and a council whose synthesis they cannot see is a council
|
|
5918
|
+
// whose verdict the operator cannot read or share.
|
|
5919
|
+
const identity: DispatchRunIdentity = {
|
|
5920
|
+
runId,
|
|
5921
|
+
agentId: "council-synthesis",
|
|
5922
|
+
task,
|
|
5923
|
+
requestOrigin: origin,
|
|
5924
|
+
targetId: receipt.targetId,
|
|
5925
|
+
wireModelId: receipt.wireModelId,
|
|
5926
|
+
runtimeId: receipt.runtimeId,
|
|
5927
|
+
runtimeKind: receipt.runtimeKind,
|
|
5928
|
+
gate: { role: gate.role, cycle: gate.cycle },
|
|
5929
|
+
council,
|
|
5930
|
+
};
|
|
5931
|
+
context.bus.emit(BusChannels.DispatchEnqueued, { ...identity, requestOrigin: origin });
|
|
5932
|
+
context.bus.emit(BusChannels.DispatchStarted, {
|
|
5933
|
+
...identity,
|
|
5934
|
+
requestOrigin: origin,
|
|
5935
|
+
pid: null,
|
|
5936
|
+
assignmentId: runId,
|
|
5937
|
+
attempt: 0,
|
|
5938
|
+
});
|
|
5939
|
+
context.bus.emit(BusChannels.DispatchCompleted, {
|
|
5940
|
+
...identity,
|
|
5941
|
+
requestOrigin: origin,
|
|
5942
|
+
outcome: "succeeded",
|
|
5943
|
+
outcomeCode: null,
|
|
5944
|
+
outcomeDetail: null,
|
|
5945
|
+
lineage: input.template.lineage ?? { parentRunId: null, rootRunId: runId, attempt: 0, depth: 0 },
|
|
5946
|
+
tokenCount: 0,
|
|
5947
|
+
inputTokenCount: 0,
|
|
5948
|
+
outputTokenCount: 0,
|
|
5949
|
+
cacheReadTokenCount: 0,
|
|
5950
|
+
cacheWriteTokenCount: 0,
|
|
5951
|
+
reasoningTokenCount: 0,
|
|
5952
|
+
staticShellHash: null,
|
|
5953
|
+
sessionShellHash: null,
|
|
5954
|
+
dynamicHash: null,
|
|
5955
|
+
costUsd: 0,
|
|
5956
|
+
costProvenance: "unknown",
|
|
5957
|
+
durationMs: 0,
|
|
5958
|
+
exitCode: 0,
|
|
5959
|
+
toolActivity: null,
|
|
5960
|
+
});
|
|
5961
|
+
return receipt;
|
|
5962
|
+
}
|
|
5963
|
+
|
|
5716
5964
|
const extension: DomainExtension = {
|
|
5717
5965
|
async start() {
|
|
5718
5966
|
// No in-memory executor survives a process restart, so every active
|
|
@@ -5947,6 +6195,7 @@ export function createDispatchBundle(
|
|
|
5947
6195
|
protectedArtifactState: () => getProtectedArtifactState(),
|
|
5948
6196
|
dispatch,
|
|
5949
6197
|
dispatchBatch,
|
|
6198
|
+
sealCouncilSynthesis,
|
|
5950
6199
|
listRuns(status) {
|
|
5951
6200
|
const l = requireLedger();
|
|
5952
6201
|
return status ? l.list({ status }) : l.list();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CODE_STEP_EXCERPT_MAX_BYTES } from "./code-step.js";
|
|
2
|
+
|
|
3
|
+
export function gateBaselineFailure(passed: boolean): "gate_not_discriminating" | null {
|
|
4
|
+
return passed ? "gate_not_discriminating" : null;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function gateFailureLines(output: string): string {
|
|
8
|
+
const lines = output
|
|
9
|
+
.split("\n")
|
|
10
|
+
.filter((line) => line.startsWith("FAIL"))
|
|
11
|
+
.join("\n");
|
|
12
|
+
if (Buffer.byteLength(lines, "utf8") <= CODE_STEP_EXCERPT_MAX_BYTES) return lines;
|
|
13
|
+
return Buffer.from(lines, "utf8").subarray(0, CODE_STEP_EXCERPT_MAX_BYTES).toString("utf8");
|
|
14
|
+
}
|
|
@@ -42,6 +42,10 @@ export interface FleetPlanAgentContext {
|
|
|
42
42
|
attempt: number;
|
|
43
43
|
/** Set when this node is a loop's verification, which is a gate position. */
|
|
44
44
|
gateRole?: "reviewer";
|
|
45
|
+
target?: string;
|
|
46
|
+
profile?: string;
|
|
47
|
+
planRole?: true;
|
|
48
|
+
gateAuthorRole?: true;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
export interface FleetPlanAgentResolution {
|
|
@@ -97,7 +101,7 @@ function declaredLoops(steps: ReadonlyArray<FleetContractStep>): Map<string, Exe
|
|
|
97
101
|
}
|
|
98
102
|
loops.set(step.id, {
|
|
99
103
|
id: step.id,
|
|
100
|
-
checkKind: step.check.kind,
|
|
104
|
+
checkKind: step.check.kind === "gate" ? "code" : step.check.kind,
|
|
101
105
|
maxAttempts: step.maxAttempts,
|
|
102
106
|
checkStepIds,
|
|
103
107
|
repairStepIds,
|
|
@@ -127,6 +131,10 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
127
131
|
dependencies: ReadonlyArray<string>,
|
|
128
132
|
writes: ReadonlyArray<string> | undefined,
|
|
129
133
|
loop?: { loopId: string; role: "check" | "repair"; attempt: number },
|
|
134
|
+
extra?: {
|
|
135
|
+
gate?: { path: string; commandId: string };
|
|
136
|
+
plan?: { roster: ReadonlyArray<string>; maxTasks: number; proposals: boolean };
|
|
137
|
+
},
|
|
130
138
|
): ExecutionPlanStepInput => {
|
|
131
139
|
const resolved = resolveAgent(context);
|
|
132
140
|
return {
|
|
@@ -142,14 +150,49 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
142
150
|
executionRole: resolved.executionRole,
|
|
143
151
|
...boundary(context.scope, writes),
|
|
144
152
|
...(loop !== undefined ? { loop } : {}),
|
|
153
|
+
...(context.target !== undefined ? { target: context.target } : {}),
|
|
154
|
+
...(context.profile !== undefined ? { profile: context.profile } : {}),
|
|
155
|
+
...extra,
|
|
145
156
|
};
|
|
146
157
|
};
|
|
158
|
+
const routeOf = (value: { target?: string; profile?: string }): { target?: string; profile?: string } => ({
|
|
159
|
+
...(value.target !== undefined ? { target: value.target } : {}),
|
|
160
|
+
...(value.profile !== undefined ? { profile: value.profile } : {}),
|
|
161
|
+
});
|
|
147
162
|
|
|
148
163
|
for (const step of contract.steps) {
|
|
149
164
|
const dependencies = expandDependencies(step.dependencies, loops);
|
|
150
165
|
if (step.kind === "agent") {
|
|
151
166
|
steps.push(
|
|
152
|
-
agentNode(
|
|
167
|
+
agentNode(
|
|
168
|
+
{ stepId: step.id, agentId: step.agent, scope: step.scope, attempt: 0, ...routeOf(step) },
|
|
169
|
+
dependencies,
|
|
170
|
+
step.writes,
|
|
171
|
+
),
|
|
172
|
+
);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (step.kind === "gate") {
|
|
176
|
+
steps.push(
|
|
177
|
+
agentNode(
|
|
178
|
+
{ stepId: step.id, agentId: step.agent, scope: "workspace", attempt: 0, gateAuthorRole: true, ...routeOf(step) },
|
|
179
|
+
dependencies,
|
|
180
|
+
[step.path],
|
|
181
|
+
undefined,
|
|
182
|
+
{ gate: { path: step.path, commandId: step.run } },
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (step.kind === "plan") {
|
|
188
|
+
steps.push(
|
|
189
|
+
agentNode(
|
|
190
|
+
{ stepId: step.id, agentId: step.agent, scope: step.scope, attempt: 0, planRole: true, ...routeOf(step) },
|
|
191
|
+
dependencies,
|
|
192
|
+
step.writes,
|
|
193
|
+
undefined,
|
|
194
|
+
{ plan: { roster: [...step.roster], maxTasks: step.maxTasks, proposals: step.proposals } },
|
|
195
|
+
),
|
|
153
196
|
);
|
|
154
197
|
continue;
|
|
155
198
|
}
|
|
@@ -185,6 +228,21 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
185
228
|
// when a workspace step lands after it.
|
|
186
229
|
verification: true,
|
|
187
230
|
});
|
|
231
|
+
} else if (step.check.kind === "gate") {
|
|
232
|
+
const gateId = step.check.gate;
|
|
233
|
+
const gate = contract.steps.find((candidate) => candidate.id === gateId);
|
|
234
|
+
if (gate?.kind !== "gate") throw new Error(`fleet plan: gate '${gateId}' failed to resolve`);
|
|
235
|
+
steps.push({
|
|
236
|
+
kind: "code",
|
|
237
|
+
id: checkId,
|
|
238
|
+
commandId: gate.run,
|
|
239
|
+
scope: "readonly",
|
|
240
|
+
dependencies: checkDependencies,
|
|
241
|
+
writes: [],
|
|
242
|
+
loop: membership,
|
|
243
|
+
verification: true,
|
|
244
|
+
gate: { gateId: gate.id, path: gate.path },
|
|
245
|
+
});
|
|
188
246
|
} else {
|
|
189
247
|
steps.push(
|
|
190
248
|
agentNode(
|
|
@@ -194,6 +252,7 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
194
252
|
scope: step.check.scope,
|
|
195
253
|
attempt: 0,
|
|
196
254
|
gateRole: "reviewer",
|
|
255
|
+
...routeOf(step.check),
|
|
197
256
|
},
|
|
198
257
|
checkDependencies,
|
|
199
258
|
step.check.writes,
|
|
@@ -205,7 +264,7 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
205
264
|
const repairId = loop.repairStepIds[attempt - 1] ?? "";
|
|
206
265
|
steps.push(
|
|
207
266
|
agentNode(
|
|
208
|
-
{ stepId: repairId, agentId: step.repair.agent, scope: step.repair.scope, attempt },
|
|
267
|
+
{ stepId: repairId, agentId: step.repair.agent, scope: step.repair.scope, attempt, ...routeOf(step.repair) },
|
|
209
268
|
[checkId],
|
|
210
269
|
step.repair.writes,
|
|
211
270
|
{ loopId: loop.id, role: "repair", attempt },
|
|
@@ -218,6 +277,7 @@ export function compileFleetExecutionPlan(input: CompileFleetPlanInput): Executi
|
|
|
218
277
|
topology: "fleet",
|
|
219
278
|
rootTask: task,
|
|
220
279
|
maxWorkers: contract.maxWorkers,
|
|
280
|
+
...(contract.writers === 1 ? { writers: 1 as const } : {}),
|
|
221
281
|
onFailure: contract.onFailure,
|
|
222
282
|
steps,
|
|
223
283
|
loops: [...loops.values()],
|