@wildo-ai/platform-core-shared 1.1.10 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/esm/core/resources/resources-operations.custom.shared.definitions.d.ts.map +1 -1
  2. package/dist/esm/core/resources/resources-relationships.custom.shared.definitions.d.ts.map +1 -1
  3. package/dist/esm/index.d.ts.map +1 -1
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/runtime/application-backend-env.contracts.d.ts +9 -2
  6. package/dist/esm/runtime/application-backend-env.contracts.d.ts.map +1 -1
  7. package/dist/esm/runtime/application-backend-env.contracts.js +12 -0
  8. package/dist/esm/runtime/application-backend-env.contracts.js.map +1 -1
  9. package/dist/esm/runtime/application-worker-env.contracts.d.ts +4 -2
  10. package/dist/esm/runtime/application-worker-env.contracts.d.ts.map +1 -1
  11. package/dist/esm/runtime/application-worker-env.contracts.js +3 -0
  12. package/dist/esm/runtime/application-worker-env.contracts.js.map +1 -1
  13. package/dist/esm/runtime/backend-start-outcome.contracts.d.ts.map +1 -1
  14. package/dist/esm/runtime/backend-start-outcome.contracts.js.map +1 -1
  15. package/dist/esm/runtime/runtime-topology.contracts.d.ts.map +1 -1
  16. package/dist/esm/security/authorizations/roles.custom.shared.definitions.d.ts.map +1 -1
  17. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts +362 -44
  18. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts.map +1 -1
  19. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.d.ts +400 -45
  20. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.d.ts.map +1 -1
  21. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.js +107 -1
  22. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.js.map +1 -1
  23. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts +24 -14
  24. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts.map +1 -1
  25. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts +31 -15
  26. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts.map +1 -1
  27. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.js +26 -2
  28. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.js.map +1 -1
  29. package/dist/esm/wildo-applications/wildo-applications.custom.shared.resources-config.schemas.d.ts.map +1 -1
  30. package/dist/esm/wildo-applications/wildo-applications.custom.shared.schemas.d.ts.map +1 -1
  31. package/dist/esm/wildo-applications-versions/wildo-applications-versions.custom.shared.resources-config.schemas.d.ts.map +1 -1
  32. package/dist/esm/wildo-applications-versions/wildo-applications-versions.custom.shared.schemas.d.ts.map +1 -1
  33. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.d.ts.map +1 -1
  34. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js +30 -0
  35. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js.map +1 -1
  36. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.d.ts.map +1 -1
  37. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.js.map +1 -1
  38. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.d.ts +21 -3
  39. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.js +7 -0
  41. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.js.map +1 -1
  42. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts +185 -0
  43. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts.map +1 -1
  44. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js +78 -2
  45. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js.map +1 -1
  46. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts +412 -10
  47. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts.map +1 -1
  48. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js +524 -15
  49. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js.map +1 -1
  50. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.d.ts +34 -0
  51. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.d.ts.map +1 -1
  52. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.js +31 -0
  53. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.js.map +1 -1
  54. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts +7 -2
  55. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts.map +1 -1
  56. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js +12 -2
  57. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js.map +1 -1
  58. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts +93 -0
  59. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts.map +1 -1
  60. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js +1 -0
  61. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js.map +1 -1
  62. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.d.ts.map +1 -1
  63. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
1
  import { ApplicationInterviewDepth, MetaWorkflow_ClarificationAction, MetaWorkflow_EvaluationVerdict } from '@wildo-ai/saas-models/meta-workflows';
2
- import { EngineCapability, HumanDecision_FieldKind, } from '@wildo-ai/saas-models';
2
+ import { AgentWorkShortfallKind, EngineCapability, FlowsActors_Status, HumanDecision_FieldKind, } from '@wildo-ai/saas-models';
3
3
  import { z } from 'zod';
4
4
  import { initZodDecorators, StringEditMode } from '@wildo-ai/zod-decorators';
5
5
  import { WorkbenchSpecificationArtifactConcern } from './workbench-resources.custom.shared.schemas.js';
@@ -53,6 +53,8 @@ export var WorkbenchCreationPlaneBehavior;
53
53
  /** The build lane's dispatch history, one row per attempt. */
54
54
  WorkbenchCreationPlaneBehavior["BUILD_DISPATCH_PLAN"] = "creation-plane.build-dispatch-plan";
55
55
  WorkbenchCreationPlaneBehavior["BUILD_DISPATCHES"] = "creation-plane.build-dispatches";
56
+ /** Everything the build knows about each task (#2530): its attempts, whose failures they were, what they cost, why it has not landed. */
57
+ WorkbenchCreationPlaneBehavior["BUILD_TASK_RECORDS"] = "creation-plane.build-task-records";
56
58
  /** The playbook runs suspended waiting on a person. */
57
59
  WorkbenchCreationPlaneBehavior["PLAYBOOK_RUNS"] = "creation-plane.playbook-runs";
58
60
  WorkbenchCreationPlaneBehavior["WAITING_PLAYBOOK_RUNS"] = "creation-plane.waiting-playbook-runs";
@@ -201,6 +203,75 @@ export var Workbench_BuildTaskStuckReason;
201
203
  */
202
204
  Workbench_BuildTaskStuckReason["IN_FLIGHT"] = "in_flight";
203
205
  })(Workbench_BuildTaskStuckReason || (Workbench_BuildTaskStuckReason = {}));
206
+ /**
207
+ * The stuck reasons a RE-ARM releases (#2530): the task is held by its own runs, and the remedy is to fix why and put it
208
+ * back — `WorkbenchBuildPlanTasks_Operations.REARM` is offered for these and no other.
209
+ *
210
+ * - `completed_unlanded`: a completed run holds it through the loop guard, and a re-arm releases that run.
211
+ * - `attempts_exhausted`: its failed runs hold it through the attempt budget, and a re-arm releases them.
212
+ *
213
+ * Left out, each because a re-arm would be the wrong remedy: `completed_awaiting_commit` (the product exists and wants
214
+ * accepting, and a re-arm would build it again), `parked_awaiting_answer` (a question waits), `in_flight` (a run is
215
+ * live), `no_document_blueprint` (no run can produce it).
216
+ */
217
+ export const WORKBENCH_REARMABLE_STUCK_REASONS = [
218
+ Workbench_BuildTaskStuckReason.COMPLETED_UNLANDED,
219
+ Workbench_BuildTaskStuckReason.ATTEMPTS_EXHAUSTED,
220
+ ];
221
+ /**
222
+ * Whose failure a failed coding run was (#1581), as the run's output records it.
223
+ *
224
+ * TASK runs are counted against the task's attempt budget; HOST runs (the run could not be recorded, or the turn was
225
+ * taken away: a mid-turn kill, a provider's 529/429, an exhausted quota, an expired login, an operator's cancel) are
226
+ * forgiven up to a bound. Declared here rather than beside its producer (the companion's coding dispatch) for the reason
227
+ * `Workbench_BuildTaskStuckReason` gives: the workbench shows it per attempt (#2530), and a browser bundle cannot import
228
+ * the companion.
229
+ */
230
+ export var CodingRunFailureAttribution;
231
+ (function (CodingRunFailureAttribution) {
232
+ /** The task's own failure: its checks went red, or its agent ran and failed at the work. Counted. */
233
+ CodingRunFailureAttribution["TASK"] = "task";
234
+ /** The host's: it could not record the run, or the turn was taken away. Forgiven, up to a bound. */
235
+ CodingRunFailureAttribution["HOST"] = "host";
236
+ })(CodingRunFailureAttribution || (CodingRunFailureAttribution = {}));
237
+ /**
238
+ * WHY a build task was put back in the queue (#1535) — the one question a later reader of a re-arm asks.
239
+ *
240
+ * A re-arm keeps a task's run history and adds one fact to it, on the runs it releases: they no longer hold the task,
241
+ * and here is why. Declared here rather than beside its producer (the companion's build dispatch) because the workbench
242
+ * both offers the re-arm (`WorkbenchBuildPlanTasks_Operations.REARM`) and shows each attempt's reason (#2530), and a
243
+ * browser bundle cannot import the companion.
244
+ */
245
+ export var BuildTaskRearmReason;
246
+ (function (BuildTaskRearmReason) {
247
+ /** The landing check was wrong about this task, and has been corrected. */
248
+ BuildTaskRearmReason["PROBE_CORRECTED"] = "probe-corrected";
249
+ /** A defect outside the task made its product impossible to produce, and has been fixed. */
250
+ BuildTaskRearmReason["BLOCKING_DEFECT_FIXED"] = "blocking-defect-fixed";
251
+ /** Neither of the above: an operator judged the work should run again. The note says why. */
252
+ BuildTaskRearmReason["OPERATOR_JUDGEMENT"] = "operator-judgement";
253
+ /**
254
+ * Set by the BUILD WAVE, never by a person (#2210): the run completed while other runs edited the same tree, and its
255
+ * declared product is missing from a file one of them also changed, so the loss is theirs rather than the task's. The
256
+ * wave re-arms the task and re-runs it alone, a bounded number of times (`MAXIMUM_INTERFERENCE_REARMS`).
257
+ * The run also carries the interference the wave found (`BuildTaskInterference`, companion-side).
258
+ *
259
+ * Like every re-arm it also releases the task's FAILED runs not yet re-armed, so the attempt budget starts afresh.
260
+ * Deliberate: the task did complete, so its earlier failures say nothing about whether the work can be done, and the
261
+ * interference bound still stops a task that keeps losing its product.
262
+ */
263
+ BuildTaskRearmReason["INTERFERED_BY_CONCURRENT_RUN"] = "interfered-by-concurrent-run";
264
+ })(BuildTaskRearmReason || (BuildTaskRearmReason = {}));
265
+ /**
266
+ * The reasons a PERSON may give (`wildo build rearm`, the companion's re-arm route, the workbench's `rearm` operation).
267
+ * The wave's own reason is left out: it asserts a measurement (a sibling changed the product's file during the run)
268
+ * that only the wave makes, and an operator choosing it would record a detection that never happened.
269
+ */
270
+ export const OPERATOR_BUILD_TASK_REARM_REASONS = [
271
+ BuildTaskRearmReason.PROBE_CORRECTED,
272
+ BuildTaskRearmReason.BLOCKING_DEFECT_FIXED,
273
+ BuildTaskRearmReason.OPERATOR_JUDGEMENT,
274
+ ];
204
275
  /**
205
276
  * How far one BUILD DISPATCH got — the whole of what `GET /build/dispatches` can honestly say.
206
277
  *
@@ -229,7 +300,10 @@ export var Workbench_BuildDispatchPhase;
229
300
  (function (Workbench_BuildDispatchPhase) {
230
301
  /** Selected and handed to its executor; nothing has resolved yet. */
231
302
  Workbench_BuildDispatchPhase["SUBMITTED"] = "submitted";
232
- /** A coding run was admitted and is running. Its outcome is the durable actor-task row `codingTaskId`. */
303
+ /**
304
+ * A coding run was admitted. The phase names the HAND-OFF and stays ADMITTED however the run ends: how
305
+ * the run stands is `Workbench_BuildDispatch.runStatus`, read off the same execution row (#2523).
306
+ */
233
307
  Workbench_BuildDispatchPhase["ADMITTED"] = "admitted";
234
308
  /** A companion generation step ran to completion. */
235
309
  Workbench_BuildDispatchPhase["FINISHED"] = "finished";
@@ -315,6 +389,27 @@ export const Workbench_Playbook_Schema = z.object({
315
389
  * is for. The default instance is not listed; it is the playbook itself. Absent without a line.
316
390
  */
317
391
  openInstances: z.array(z.object({ instanceKey: z.string().min(1), purpose: z.string().min(1) })).optional().isSummaryField(),
392
+ /*
393
+ * The playbook's DECLARED edges (#2530), each a reference a process map draws. With `outputOwners` (the families it
394
+ * writes) they make the catalogue a graph: a family feeds the playbooks that read it, which write the families that
395
+ * feed the next, and a composite admits its children.
396
+ *
397
+ * The family fields address the specification-artifact row of that family (its id IS the family); a family no row
398
+ * holds is a dangling reference, which the edge tolerates. `inputFamilyIds` and `preconditionFamilyIds` stay apart:
399
+ * a playbook gated on a family waits for it without reading it, and reads families it is not gated on. So does
400
+ * `conditionFamilyIds` (#2670): a family whose decision decides what the playbook waits for, which it never waits for.
401
+ */
402
+ /** The families it reads, from its declared inputs. */
403
+ inputFamilyIds: z.array(z.string().min(1).isForeignKey()).isSummaryField(),
404
+ /** The families its preconditions name: an artifact that must exist, be valid, be stale or decide. */
405
+ preconditionFamilyIds: z.array(z.string().min(1).isForeignKey()).isSummaryField(),
406
+ /**
407
+ * The families whose DECISION decides whether one of its preconditions applies: an `artifact_expected` gate's `when`
408
+ * (#2494). The build decomposition expects a website plan only once the capability composition decided it is NEEDED.
409
+ */
410
+ conditionFamilyIds: z.array(z.string().min(1).isForeignKey()).isSummaryField(),
411
+ /** The playbooks it admits as children when it is a composite, by their row id; empty otherwise. */
412
+ admittedPlaybookIds: z.array(z.string().min(1).isForeignKey()).isSummaryField(),
318
413
  /** When the served board was computed — the cache's honesty field, rendered as "as of". */
319
414
  computedAt: z.date().isSummaryField(),
320
415
  });
@@ -340,6 +435,24 @@ export const Workbench_BuildPlanTask_Schema = z.object({
340
435
  /** Task refs that must land first — the only thing that decides what may run next. */
341
436
  prerequisiteTaskRefs: z.array(z.string()).isSummaryField(),
342
437
  });
438
+ /**
439
+ * The BUILD PLAN view's `ref` (#2531): the plan drawn as a graph, a menubar destination beside the domain model. Its
440
+ * nodes are the build-plan tasks and its edges their prerequisites; a node opens the task's own page.
441
+ *
442
+ * It must not contain a dot, for the reason `WORKBENCH_DOMAIN_MODEL_VIEW_REF` records: the label lookup splits the
443
+ * whole `composite_views.<translationRef>.<key>` path on `.`.
444
+ */
445
+ export const WORKBENCH_BUILD_PLAN_VIEW_REF = 'build-plan';
446
+ /** The label key the view's title and description hang off: the engine's `app.<ref>` derivation, restated. */
447
+ export const WORKBENCH_BUILD_PLAN_TRANSLATION_REF = `app.${WORKBENCH_BUILD_PLAN_VIEW_REF}`;
448
+ /**
449
+ * The PLAYBOOK MAP view's `ref` (#2531): the playbook catalog drawn as what unlocks what, a menubar destination beside
450
+ * the build plan. Its nodes are the playbooks and the families they name; its edges what each writes, reads, waits for
451
+ * and, as a composite, runs (the playbook row's declared edges, #2530). No dot, for the domain model's reason.
452
+ */
453
+ export const WORKBENCH_PLAYBOOK_MAP_VIEW_REF = 'playbook-map';
454
+ /** The label key the view's title and description hang off: the engine's `app.<ref>` derivation, restated. */
455
+ export const WORKBENCH_PLAYBOOK_MAP_TRANSLATION_REF = `app.${WORKBENCH_PLAYBOOK_MAP_VIEW_REF}`;
343
456
  /**
344
457
  * One run's write record — the evidence lane behind every dispatch.
345
458
  *
@@ -594,6 +707,13 @@ export var WorkbenchBuildPlanTasks_Operations;
594
707
  * A non-ready task answers 409 naming what it waits on. Costs a coding run.
595
708
  */
596
709
  WorkbenchBuildPlanTasks_Operations["DISPATCH_TASK"] = "dispatch_task";
710
+ /**
711
+ * Put THIS task back in the queue once the reason it did not land is fixed (#1535, #2530): its completed runs that
712
+ * still hold it, and its failed runs not yet re-armed, stop counting, each recording why. Offered for a task held by
713
+ * either guard (`completed_unlanded`, `attempts_exhausted`); a task with no such run answers 409, since there is
714
+ * nothing to release. Runs nothing itself: the next dispatch offers the task again.
715
+ */
716
+ WorkbenchBuildPlanTasks_Operations["REARM"] = "rearm";
597
717
  /**
598
718
  * ACCEPT what this task's latest completed coding run wrote: commit exactly those paths, from the
599
719
  * coding-run write register, in one commit whose message names the task. Paths carrying another
@@ -691,6 +811,13 @@ export const Workbench_BuildPlanDispatchTaskRequest_Schema = z.object({
691
811
  /** The conversation this dispatch belongs to, so the thread shows the run as a card. */
692
812
  conversationId: z.string().min(1).optional(),
693
813
  });
814
+ /** Why a build task goes back in the queue (#2530): a person's reason, and what was fixed. */
815
+ export const Workbench_BuildTaskRearmRequest_Schema = z.object({
816
+ /* A person's reasons only: the wave's own records a detection only the wave makes. */
817
+ reason: z.enum(OPERATOR_BUILD_TASK_REARM_REASONS).systemEnum('BuildTaskRearmReason'),
818
+ /** What was fixed, in a sentence. Required: a reason alone cannot say which defect. */
819
+ note: z.string().trim().min(1),
820
+ });
694
821
  export const Workbench_AcceptChangesRequest_Schema = z.object({
695
822
  /** Commit paths that diverged since the run. NOT defaulted on — a human edit is never silently swept in. */
696
823
  force: z.boolean().optional(),
@@ -725,10 +852,27 @@ export const Workbench_PlaybookRunOutcome_Schema = z.looseObject({
725
852
  status: z.enum(Workbench_PlaybookRunOutcomeStatus).optional(),
726
853
  note: z.string().optional(),
727
854
  });
855
+ /**
856
+ * How a build dispatch answers (#2531 review M1): the companion forwards its dispatch result as it is. One task run
857
+ * answers the task it dispatched (`plan`) and what started for it, a coding run's `admission` or the result of a
858
+ * `generationStep` the companion ran itself, exactly one of the two. A parallel `dispatch_next` answers the `wave` it
859
+ * started, with a `note`.
860
+ *
861
+ * There is no top-level `taskRef`. This schema declared one, which no answer ever carried, so the line saying what a run
862
+ * started was never shown and the raw answer opened in its place.
863
+ */
728
864
  export const Workbench_BuildPlanDispatchOutcome_Schema = z.looseObject({
729
- taskRef: z.string().optional(),
865
+ plan: z.looseObject({ taskRef: z.string().min(1) }).optional(),
866
+ admission: z.looseObject({}).optional(),
867
+ generationStep: z.looseObject({}).optional(),
868
+ wave: z.looseObject({}).optional(),
730
869
  note: z.string().optional(),
731
870
  });
871
+ /** How a re-arm answers: the runs it released, and the reason it recorded on them. */
872
+ export const Workbench_BuildTaskRearmOutcome_Schema = z.looseObject({
873
+ rearmedRunTaskIds: z.array(z.string()).optional(),
874
+ rearm: z.looseObject({ reason: z.enum(BuildTaskRearmReason), note: z.string(), rearmedAt: z.string() }).optional(),
875
+ });
732
876
  export const Workbench_BuildPlanAddTaskOutcome_Schema = z.looseObject({
733
877
  taskRef: z.string().optional(),
734
878
  /** TRUE when no plan existed and this task is its first. */
@@ -739,6 +883,13 @@ export const Workbench_BuildPlanAddTaskOutcome_Schema = z.looseObject({
739
883
  });
740
884
  /** How ACCEPT answers, for a task's coding run or a playbook run alike: what was committed, what was refused and why. */
741
885
  export const Workbench_AcceptChangesOutcome_Schema = z.looseObject({
886
+ /**
887
+ * TRUE when no new commit was made because what it would commit was already committed: the run was accepted before, or
888
+ * its files were committed by hand (#2531 review M3). `commitSha` is then that earlier commit, not a new one. An accept
889
+ * can be partial, holding back the files it cannot vouch for, and the task waits on them; only a forced accept
890
+ * (`force`) commits those.
891
+ */
892
+ alreadyCommitted: z.boolean().optional(),
742
893
  commitSha: z.string().optional(),
743
894
  committedPaths: z.array(z.string()).optional(),
744
895
  refusedPaths: z.array(z.object({ path: z.string(), reason: z.string() })).optional(),
@@ -858,7 +1009,10 @@ export const Workbench_BuildDispatchPlan_Schema = z.object({
858
1009
  landedCount: z.number().int().isSummaryField(),
859
1010
  });
860
1011
  export const Workbench_BuildDispatch_Schema = z.object({
861
- /** Emitted by the behavior as `<taskRef>--<startedAt>`, sanitized — a task can be dispatched twice. */
1012
+ /**
1013
+ * The dispatch's own EXECUTION id (#2530): a task can be dispatched twice, even in the same second, and was keyed on its
1014
+ * task and start instant until two such attempts shared one id.
1015
+ */
862
1016
  workbenchBuildDispatchId: z.string().min(1).isPrimaryKey().isSummaryField(),
863
1017
  /** The build-plan task this attempt ran. */
864
1018
  taskRef: z.string().min(1).isSummaryField(),
@@ -890,18 +1044,318 @@ export const Workbench_BuildDispatch_Schema = z.object({
890
1044
  codingTaskId: z.string().min(1).isForeignKey().isSummaryField().nullable(),
891
1045
  /** Why it failed, verbatim. NULL on every dispatch that did not. */
892
1046
  error: z.string().min(1).isSummaryField().nullable(),
1047
+ /**
1048
+ * Whose failure a failed coding run was (#1581): the task's, or the host's. HOST is everything that is not the task's: the
1049
+ * agent's turn taken by the environment (a signed-out agent, a spent quota, a killed turn, an operator's cancel) or a
1050
+ * change set or trace the host could not capture. Only the first kind is the coding lane's, so the dispatch's page and
1051
+ * card offer to see whether the lane is ready, never to explain the failure (#2530 review M2, #2531 review L1). NULL for
1052
+ * a run that did not fail, a generation step, and a run recorded before it.
1053
+ */
1054
+ failureAttribution: z.enum(CodingRunFailureAttribution).systemEnum('CodingRunFailureAttribution').nullable(),
893
1055
  /**
894
1056
  * The conversation the dispatch was started from (#1454, Step 7), so the thread shows it as a
895
1057
  * card. NULL for a dispatch started from the plan's next-task door or before conversations existed.
896
1058
  */
897
1059
  conversationId: z.string().min(1).isSummaryField().nullable(),
1060
+ /**
1061
+ * How the dispatch's RUN stands — the status of the actor execution the dispatch is (#2523).
1062
+ *
1063
+ * Every dispatch is one execution (#1359): a coding run on `application-coding.system`, a generation step
1064
+ * on `application-build.system`. Its status is the one truthful answer to "did it work", for both
1065
+ * executors. The phase cannot give it: a coding dispatch's phase resolves at ADMITTED, by design, so a run
1066
+ * that has since completed, failed or is waiting on an answer still reads ADMITTED there. Every consumer
1067
+ * that keyed a coding run's end on `phase === FINISHED` was asking a question no coding run could answer:
1068
+ * the conversation's dispatch card never offered Accept, and Home never listed a coding run as settled.
1069
+ */
1070
+ runStatus: z.enum(FlowsActors_Status).systemEnum('FlowsActors_Status').isSummaryField(),
1071
+ /** When the run ENDED. NULL while it is pending, running or waiting on an answer. */
1072
+ runFinishedAt: z.date().isSummaryField().nullable(),
898
1073
  /**
899
1074
  * Whether the coding run's writes have been ACCEPTED — committed through the `accept` verb, or
900
- * found already committed. NULL when there is nothing to accept: a generation step, a failed run,
901
- * a run that wrote nothing, or a run older than the coding-run write register.
1075
+ * found already committed.
1076
+ *
1077
+ * FALSE means exactly one thing: a coding run that COMPLETED, recorded writes, and has none committed
1078
+ * yet — the state the `accept` verb addresses. NULL when there is nothing to accept NOW: a generation
1079
+ * step, a run still running or waiting on an answer, a failed run, a run that wrote nothing, or a run
1080
+ * older than the coding-run write register.
902
1081
  */
903
1082
  accepted: z.boolean().isSummaryField().nullable(),
904
1083
  });
1084
+ /**
1085
+ * One ATTEMPT at a build task (#2530): one actor execution, as the build's record reads it. A coding run, or a companion
1086
+ * generation step (labels, migrations, translations).
1087
+ */
1088
+ export const Workbench_BuildTaskAttempt_Schema = z.object({
1089
+ /** The execution's own task id: the coding run's actor task, or the generation step's. */
1090
+ runTaskId: z.string().min(1),
1091
+ startedAt: z.date(),
1092
+ settledAt: z.date().nullable(),
1093
+ status: z.enum(FlowsActors_Status).systemEnum('FlowsActors_Status'),
1094
+ /**
1095
+ * A companion generation step (labels, migrations, translations) rather than a coding run. No agent ran, so its cost and
1096
+ * tokens are what its own model calls were MEASURED at, and may be a floor (`spendIsFloor`) where some reported nothing.
1097
+ */
1098
+ generationStep: z.boolean(),
1099
+ /**
1100
+ * Refused by the host before it started (an admission refusal, a run a stopped process left selected). In the
1101
+ * history, because it explains why nothing ran; counted by no figure, because it was no attempt of the task's.
1102
+ */
1103
+ refusedBeforeStart: z.boolean(),
1104
+ /** Nothing ran: a host refusal, or admission refusing the task's own contract (which the budget does count). */
1105
+ ranNothing: z.boolean(),
1106
+ /** Whose failure a failed run was; null for a run that did not fail, and for a run recorded before the field. */
1107
+ failureAttribution: z.enum(CodingRunFailureAttribution).systemEnum('CodingRunFailureAttribution').nullable(),
1108
+ /** It failed while other runs were editing the tree, so the failure may be theirs. */
1109
+ interferenceSuspected: z.boolean(),
1110
+ /**
1111
+ * Why the task was put back in the queue after this run, which then no longer held it; null when it was not. A person's
1112
+ * reason, or the build wave's own when the run's product was lost to a sibling run editing the same file.
1113
+ */
1114
+ rearmReason: z.enum(BuildTaskRearmReason).systemEnum('BuildTaskRearmReason').nullable(),
1115
+ /** What was fixed, as the re-arm recorded it; null when the run was not re-armed. */
1116
+ rearmNote: z.string().min(1).nullable(),
1117
+ /** Why it failed, verbatim; null when it did not. */
1118
+ error: z.string().min(1).nullable(),
1119
+ /**
1120
+ * What the run cost, with its currency: what the agent reported for a coding run, what its model calls were measured at
1121
+ * for a generation step (in one currency; a step that spent in several shows none). Null when nothing reported a cost —
1122
+ * never read as zero.
1123
+ */
1124
+ costAmount: z.number().nullable(),
1125
+ costCurrency: z.string().min(1).nullable(),
1126
+ /** The cost and tokens are a FLOOR: a generation step some of whose model calls reported no usage. */
1127
+ spendIsFloor: z.boolean(),
1128
+ /**
1129
+ * The tokens the run reported in all; null when it reported none. Mostly prompt-cache reads for a coding run, so a
1130
+ * large figure is the agent re-reading its context, not that much new work.
1131
+ */
1132
+ totalTokens: z.number().int().min(0).nullable(),
1133
+ /** Files the run itself changed; null when the run recorded none. */
1134
+ filesChanged: z.number().int().nullable(),
1135
+ /** The checks the run itself failed, by ref (a check already red when it started is not its failure, so not here). */
1136
+ failedCheckRefs: z.array(z.string().min(1)),
1137
+ /** Paths the run changed outside the task's declared scope: recorded, never refused. */
1138
+ outOfScopePaths: z.array(z.string().min(1)),
1139
+ /**
1140
+ * The run COMPLETED and a sibling of its wave overwrote its product (#2210): which runs, which of the task's product
1141
+ * files both changed, and whether the wave re-ran the task for it. Null for a run nobody overwrote. The case a person's
1142
+ * re-arm answers once the wave's own re-runs are spent.
1143
+ */
1144
+ interference: z.object({
1145
+ overlappingTaskRefs: z.array(z.string().min(1)),
1146
+ contendedProductPaths: z.array(z.string().min(1)),
1147
+ requeued: z.boolean(),
1148
+ }).nullable(),
1149
+ /*
1150
+ * NOT carried: why the agent's turn ended (`max_tokens`, `refusal`), which is the agent's own vocabulary with no
1151
+ * words here yet; the run's own page shows it.
1152
+ */
1153
+ });
1154
+ /**
1155
+ * What `wildo db diff --check` could tell the host about the resource model versus the accepted schema plan.
1156
+ *
1157
+ * THREE answers, not two. A boolean merged the two failures that lead to opposite places (found in review,
1158
+ * 2026-09-13): DRIFTED means the migration step has work and must run first; UNANSWERABLE means the check did not
1159
+ * report drift and did not pass — no accepted plan and an undeterminable store declaration, no built backend registry, a compiled model older than its
1160
+ * sources (`assessCompiledModelCurrency`, #403: before it, a dead watcher's stale dist answered IN_SYNC and landed
1161
+ * this step with drift on disk), a CLI that could not import
1162
+ * it or could not be spawned, a timeout, a lockfile that fails strict parsing, or an ENGINE planner-contract
1163
+ * mismatch (whose remedy is `wildo db generate --accept-planner-contract`, not a rebuild) — and
1164
+ * running the step then only throws. Read as one "not in sync", an unanswerable check put a step that can
1165
+ * only fail at the head of the build queue on every dispatch, so no other task could run.
1166
+ *
1167
+ * Only IN_SYNC ever lands the step: an unanswered question must not land a migration step either.
1168
+ *
1169
+ * Declared here rather than beside its producer (the companion's generation steps) because the workbench shows it on a
1170
+ * step's record (#2530).
1171
+ */
1172
+ export var SchemaPlanSyncState;
1173
+ (function (SchemaPlanSyncState) {
1174
+ /** The model and the accepted plan agree: the migration step has landed. */
1175
+ SchemaPlanSyncState["IN_SYNC"] = "in_sync";
1176
+ /** The check ran and reported ungenerated changes: the migration step has work to do. */
1177
+ SchemaPlanSyncState["DRIFTED"] = "drifted";
1178
+ /** The check neither passed nor reported drift (see above for the causes); running the step now would refuse or fail. */
1179
+ SchemaPlanSyncState["UNANSWERABLE"] = "unanswerable";
1180
+ })(SchemaPlanSyncState || (SchemaPlanSyncState = {}));
1181
+ /**
1182
+ * What `wildo design-tokens validate` could tell the host about the stylesheet's generated block.
1183
+ *
1184
+ * Three answers, for the reason {@link SchemaPlanSyncState} has three: the command exits non-zero for a
1185
+ * stale block AND for every could-not-ask failure (a config that does not load, a stylesheet with no
1186
+ * markers, a CLI that cannot start or times out), and the two lead to opposite places. STALE means the
1187
+ * `design-tokens` step has work; UNANSWERABLE means running it would refuse or fail the same way, so the
1188
+ * dispatch host passes over it while other work is ready.
1189
+ *
1190
+ * Declared here for the reason {@link SchemaPlanSyncState} is (#2530).
1191
+ */
1192
+ export var DesignTokenBlockState;
1193
+ (function (DesignTokenBlockState) {
1194
+ /** The block is exactly what `generate` would write from the config. */
1195
+ DesignTokenBlockState["CURRENT"] = "current";
1196
+ /** The block differs from what `generate` would write: the step has work. */
1197
+ DesignTokenBlockState["STALE"] = "stale";
1198
+ /** The command neither confirmed nor refuted the block; running the step now would fail the same way. */
1199
+ DesignTokenBlockState["UNANSWERABLE"] = "unanswerable";
1200
+ })(DesignTokenBlockState || (DesignTokenBlockState = {}));
1201
+ /**
1202
+ * Does every module the brand step writes (the frontend's brand design, and the website's colours when a website is
1203
+ * declared) say what the brand's visual tone now renders?
1204
+ *
1205
+ * Three answers, for the reason {@link DesignTokenBlockState} has three: STALE means the step has work and runs,
1206
+ * UNANSWERABLE means the brand could not be read (the specifications do not evaluate, or this host has no
1207
+ * introspection), and running the step then only throws, so the selector passes it over while other work is ready.
1208
+ *
1209
+ * Declared here for the reason {@link SchemaPlanSyncState} is (#2530).
1210
+ */
1211
+ export var BrandDesignState;
1212
+ (function (BrandDesignState) {
1213
+ /** Every module exists and equals the render of the brand's current visual tone. */
1214
+ BrandDesignState["CURRENT"] = "current";
1215
+ /** A module is absent or says something the brand no longer does. */
1216
+ BrandDesignState["STALE"] = "stale";
1217
+ /** The brand's visual tone could not be read, so currency cannot be decided either way. */
1218
+ BrandDesignState["UNANSWERABLE"] = "unanswerable";
1219
+ })(BrandDesignState || (BrandDesignState = {}));
1220
+ /** A landing probe HEAD does not satisfy (#2530): what landing searched for, and whether the working tree has it. */
1221
+ export const Workbench_BuildTaskUnmetProbe_Schema = z.object({
1222
+ /**
1223
+ * The files the probe reads, and how they are read: ONE path is that file, committed (and declaring `declarations`
1224
+ * when it names any); SEVERAL paths with `declarations` are candidates, any one of which may declare them; several with
1225
+ * `keyPrefix` are the language packs, every committed one of which must carry a key under it. Empty for a shell probe,
1226
+ * which reads the resolved shell rather than a fixed file (`shellSurface`, `shell`). The probe's KIND is the
1227
+ * companion's (`BuildPlanTaskLandedProbeKind`): these fields are what it looks for, and between them say which kind.
1228
+ */
1229
+ paths: z.array(z.string().min(1)),
1230
+ /**
1231
+ * The symbols the probe looks for in those files; empty for a probe that asks only that a file be committed. WHERE in
1232
+ * the file they must sit (a set, one call's arguments, a key at an object path, a list's entry) is the companion's
1233
+ * probe relation and is not carried: its parameters are code locations the companion derives only when it probes, and
1234
+ * no surface shows them, a run's included (#2531 review L4). A reader learns WHAT is missing here, not where it goes.
1235
+ */
1236
+ declarations: z.array(z.string().min(1)),
1237
+ /** The key every committed label pack must carry one under (a website section's words); null for other probes. */
1238
+ keyPrefix: z.string().min(1).nullable(),
1239
+ /**
1240
+ * The shell surface a placement probe reads — a `PlacementSurface` value of the specifications. A string declaring that
1241
+ * vocabulary, so it reads `system_enums.PlacementSurface` like the enum, since this package does not depend on the
1242
+ * specifications. Null for the probe that asks whether ANY surface carries a placement, and for every probe that reads
1243
+ * files.
1244
+ */
1245
+ shellSurface: z.string().min(1).systemEnum('PlacementSurface').nullable(),
1246
+ /** A shell probe's explanation: what the surface lacks, still carries, or could not be asked. Null for a file probe. */
1247
+ shell: z.object({
1248
+ /** Why the surface could not be read, verbatim: the probe is then unsatisfied without being a "no". */
1249
+ unanswerable: z.string().min(1).nullable(),
1250
+ /** Subjects the plan placed there that the surface does not carry. */
1251
+ missing: z.array(z.string().min(1)),
1252
+ /** Subjects the plan declined that the surface still carries. */
1253
+ declinedButPresent: z.array(z.string().min(1)),
1254
+ /** Files contributing the surface that are not committed as they are. */
1255
+ uncommittedPaths: z.array(z.string().min(1)),
1256
+ }).nullable(),
1257
+ /**
1258
+ * A REGISTRY probe's explanation (#2966): an agent, an approval gate, a work unit, a metered usage recording (#2305
1259
+ * S5) or a retention binding, proven from what the backend registers, and a role a relationship confers (#2305 S6),
1260
+ * proven from `wildo.saas.config.ts`. Null for every other probe. Kept apart from `shell`, which reads a surface: these read a registry, and
1261
+ * a "declined" entry has no meaning here.
1262
+ */
1263
+ registered: z.object({
1264
+ /** Why the registry could not be read, verbatim: the probe is then unsatisfied without being a "no". */
1265
+ unanswerable: z.string().min(1).nullable(),
1266
+ /**
1267
+ * What the task's module does not register as planned, one entry per shortfall: WHY (worded from
1268
+ * `system_enums.AgentWorkShortfallKind`), the ref it is about, and the planned and registered values where it compares
1269
+ * them (for a refused gate, the engine's refusal, verbatim).
1270
+ */
1271
+ missing: z.array(z.object({
1272
+ kind: z.enum(AgentWorkShortfallKind).systemEnum('AgentWorkShortfallKind'),
1273
+ ref: z.string().min(1),
1274
+ planned: z.string().min(1).nullable(),
1275
+ registered: z.string().min(1).nullable(),
1276
+ })),
1277
+ /** Files where the product is written that are not committed as they are. */
1278
+ uncommittedPaths: z.array(z.string().min(1)),
1279
+ }).nullable(),
1280
+ /**
1281
+ * The working tree satisfies it: the product is written and not committed — an acceptance question. False: it is
1282
+ * absent — a declaration or a work question. "Not landed" alone cannot tell the two apart.
1283
+ */
1284
+ satisfiedInWorkingTree: z.boolean(),
1285
+ });
1286
+ /**
1287
+ * Everything the build knows about ONE task, in one row (#2530, from the companion's per-task record, #1521).
1288
+ *
1289
+ * The case it exists for: "not landed" hid three facts — never dispatched, dispatched and FAILED, dispatched,
1290
+ * SUCCEEDED and unprovable — and they are three shapes here: no attempts; a failed attempt; a completed attempt with
1291
+ * unmet probes. Its id IS the build-plan task row's id, so a task's detail reads its record by the id it already has;
1292
+ * it is its own resource because reading attempts, classifying a stuck task and probing the tree is too much to pay on
1293
+ * every row of the task list.
1294
+ *
1295
+ * The attempts are read from the actor plane by ONE listing per coding system, bounded far above a whole build's runs;
1296
+ * `attemptsTruncated` says when that bound was met, so an early task's oldest runs may be missing and "never run" is not
1297
+ * claimed.
1298
+ */
1299
+ export const Workbench_BuildTaskRecord_Schema = z.object({
1300
+ workbenchBuildTaskRecordId: z.string().min(1).isPrimaryKey().isSummaryField(),
1301
+ /** The build-plan task this is the record of (the same id). */
1302
+ workbenchBuildPlanTaskId: z.string().min(1).isForeignKey().isSummaryField(),
1303
+ taskRef: z.string().min(1).isSummaryField(),
1304
+ status: z.enum(WorkbenchBuildPlanTaskStatus).systemEnum('WorkbenchBuildPlanTaskStatus').isSummaryField(),
1305
+ /**
1306
+ * Attempts that count (every one but a host refusal before start). Which FAILED ones count against the attempt
1307
+ * budget is the budget's own question (host failures and suspected interference are forgiven up to a bound); each
1308
+ * attempt says what it needs for that, and a spent budget is `stuckReason` ATTEMPTS_EXHAUSTED, never re-derived here.
1309
+ */
1310
+ attemptCount: z.number().int().min(0).isSummaryField(),
1311
+ /** Newest first. Empty: never dispatched (unless `attemptsTruncated`). */
1312
+ attempts: z.array(Workbench_BuildTaskAttempt_Schema),
1313
+ /** The attempt listing met its bound: the oldest attempts of an early task may be missing. */
1314
+ attemptsTruncated: z.boolean(),
1315
+ /** READY and passed over by dispatch: why, from the same classification the selector uses. */
1316
+ stuckReason: z.enum(Workbench_BuildTaskStuckReason).systemEnum('Workbench_BuildTaskStuckReason').isSummaryField().nullable(),
1317
+ /** `completed_awaiting_commit`: the files its run wrote that are not committed — what accepting it would commit. */
1318
+ stuckUncommittedPaths: z.array(z.string().min(1)),
1319
+ /** `parked_awaiting_answer`: the question its run is waiting on. */
1320
+ stuckQuestion: z.string().min(1).nullable(),
1321
+ /** `no_document_blueprint`: the governed document no blueprint defines. */
1322
+ stuckDocumentRef: z.string().min(1).nullable(),
1323
+ /** BLOCKED: the prerequisites that have not landed. */
1324
+ waitingOnTaskRefs: z.array(z.string().min(1)),
1325
+ /** Not landed and attempted: the probes HEAD does not satisfy. */
1326
+ unmetProbes: z.array(Workbench_BuildTaskUnmetProbe_Schema),
1327
+ /*
1328
+ * A GENERATION STEP lands on something other than a file it writes, and when it has not, which of these three it is
1329
+ * says whether running it again can help: the step's own state, null when it is current or is not that step.
1330
+ */
1331
+ /** The migration step: whether the model and the accepted schema plan agree. */
1332
+ schemaPlanSyncState: z.enum(SchemaPlanSyncState).systemEnum('SchemaPlanSyncState').nullable(),
1333
+ /** The design-tokens step: whether the stylesheet's generated block is what the config would generate. */
1334
+ designTokenBlockState: z.enum(DesignTokenBlockState).systemEnum('DesignTokenBlockState').nullable(),
1335
+ /** The brand-design step: whether the generated module says what the brand's visual tone renders. */
1336
+ brandDesignState: z.enum(BrandDesignState).systemEnum('BrandDesignState').nullable(),
1337
+ /**
1338
+ * A generation step whose landing cannot be judged, and why, verbatim (#2504): today a labels plan that hides units
1339
+ * the application owes. Named before the step's first run too, since it holds the step back from running. Null when
1340
+ * nothing holds its landing.
1341
+ */
1342
+ landingBlockedBy: z.string().min(1).nullable(),
1343
+ /*
1344
+ * The follow-up tasks (#2496): what the host derived from a gap this task's latest completed run reported still unmet,
1345
+ * and on a follow-up, the task whose gap derived it. By build-plan task row id, so each opens the task it names
1346
+ * (#2652); `wildo context journey` prints the same two facts.
1347
+ */
1348
+ /** The follow-up tasks derived from this task's reported gaps; empty when none was derived. */
1349
+ followUpTaskIds: z.array(z.string().min(1).isForeignKey()),
1350
+ /** On a follow-up task: the task whose reported gap derived it; null on every other task. */
1351
+ followUpOfTaskId: z.string().min(1).isForeignKey().nullable(),
1352
+ /** LANDED with no product to prove: it ran, and nothing can show what it made. */
1353
+ unverifiable: z.boolean(),
1354
+ /** LANDED before any run of its own started: something else made its product, or the probe reads the wrong thing. */
1355
+ landedBeforeAnyRun: z.boolean(),
1356
+ /** Where the probe found that product, so a reader can see what it took for it; empty unless `landedBeforeAnyRun`. */
1357
+ landedBeforeAnyRunPaths: z.array(z.string().min(1)),
1358
+ });
905
1359
  /**
906
1360
  * One playbook run SUSPENDED waiting on a person.
907
1361
  *
@@ -944,6 +1398,43 @@ export var Workbench_PlaybookRunState;
944
1398
  */
945
1399
  Workbench_PlaybookRunState["AWAITING_ANSWER"] = "awaiting_answer";
946
1400
  })(Workbench_PlaybookRunState || (Workbench_PlaybookRunState = {}));
1401
+ /**
1402
+ * One child of a composite run's round (#2530): the playbook that ran in it, why it was on the table, what it landed and
1403
+ * whether it failed — the record's own summary (`PlaybookRunChoreographyChildSummary`), with its measurement left on the
1404
+ * run's record. A child that was itself a LANE is known by the rounds that name it as their lane.
1405
+ */
1406
+ export const Workbench_PlaybookRunRoundChild_Schema = z.object({
1407
+ playbookRef: z.string().min(1),
1408
+ /** Why it was on the table, in the runtime's own sentence (a first run, a refresh and what moved, a re-opening). */
1409
+ ranBecause: z.string().min(1).nullable(),
1410
+ /** The specification files it landed, in landing order. Empty is a finding, not a gap. */
1411
+ landed: z.array(z.string().min(1)),
1412
+ /** Why it failed, bounded as the record keeps it; null when it did not. */
1413
+ failure: z.string().min(1).nullable(),
1414
+ });
1415
+ /**
1416
+ * One round of a composite run (#2530): the root's, or a nested lane's. FLAT rather than nested: a lane's rounds follow
1417
+ * the round whose child ran the lane and name it (`parentRoundKey`, `lanePlaybookRef`), so a process map nests them as
1418
+ * groups without a recursive contract, and every depth the record keeps reaches the row.
1419
+ *
1420
+ * The choreography's own stop reason (`PlaybookChoreographyStopReason`) is NOT here: it is a closed vocabulary of the
1421
+ * runtime, which this package does not depend on, and a raw code would render as words nobody authored. Each round's
1422
+ * `stopRationale` is the selector's own sentence for why that round ended the run; the reason code stays on the record.
1423
+ */
1424
+ export const Workbench_PlaybookRunRound_Schema = z.object({
1425
+ /** The round's place in the run: `3` for the root's third, `3/<lane playbook>/2` for the second round of that lane. */
1426
+ roundKey: z.string().min(1),
1427
+ /** The round whose child ran this lane; null for a round of the run itself. */
1428
+ parentRoundKey: z.string().min(1).nullable(),
1429
+ /** The child playbook whose lane this round belongs to; null for a round of the run itself. */
1430
+ lanePlaybookRef: z.string().min(1).nullable(),
1431
+ iteration: z.number().int().min(1),
1432
+ /** The earlier round of the same lane that began from the very same input state: a lane spending without converging. */
1433
+ sameInputStateAsIteration: z.number().int().min(1).nullable(),
1434
+ /** Why the selector stopped after this round, in its own sentence; null when it went on. */
1435
+ stopRationale: z.string().min(1).nullable(),
1436
+ children: z.array(Workbench_PlaybookRunRoundChild_Schema),
1437
+ });
947
1438
  /**
948
1439
  * One playbook run, in whatever state it is in.
949
1440
  *
@@ -1030,6 +1521,12 @@ export const Workbench_PlaybookRun_Schema = z.object({
1030
1521
  })).nullable(),
1031
1522
  /** Why the judge stayed silent, in its own words — a failed call, or an evaluation that never ran. */
1032
1523
  judgeSkipped: z.string().min(1).nullable(),
1524
+ /**
1525
+ * A COMPOSITE run's rounds, its own and every nested lane's, in run order (#2530), each with the children that ran in
1526
+ * it — what a process map draws as rounds, then child runs. Null for a run of a single playbook, and for a run not
1527
+ * settled yet (its rounds are on the record once it ends).
1528
+ */
1529
+ choreographyRounds: z.array(Workbench_PlaybookRunRound_Schema).nullable(),
1033
1530
  });
1034
1531
  export const Workbench_WaitingPlaybookRun_Schema = z.object({
1035
1532
  /** The run's own id, sanitized — run ids carry dots (see the playbook id note). */
@@ -1084,13 +1581,10 @@ export const Workbench_WaitingPlaybookRun_Schema = z.object({
1084
1581
  routedToUserId: z.string().min(1).isSummaryField().nullable(),
1085
1582
  });
1086
1583
  /**
1087
- * One coding run PARKED on a question.
1088
- *
1089
- * It arrives inside the coding-agent status payload, which is a singleton and stays a companion
1090
- * read. These do not: a parked question is identified by the task that parked on it, it persists
1091
- * until somebody answers, and a queue of work waiting on a person is the last thing that should be
1092
- * reachable only by reading a status blob.
1584
+ * The coding lane's one row id. Named, because the workbench links to the row from where the lane's trouble shows (an
1585
+ * attempt, a dispatch or a dispatch card the host failed, #2530) and the companion stamps it: two copies of the literal would be two ids.
1093
1586
  */
1587
+ export const WORKBENCH_CODING_LANE_STATUS_ROW_ID = 'coding-lane';
1094
1588
  /**
1095
1589
  * The coding lane's own posture — ONE row, always present.
1096
1590
  *
@@ -1113,7 +1607,7 @@ export const Workbench_WaitingPlaybookRun_Schema = z.object({
1113
1607
  * outstanding — which is why the parked queue has to be read beside it.
1114
1608
  */
1115
1609
  export const Workbench_CodingLaneStatus_Schema = z.object({
1116
- /** One row, one id. The projection stamps a constant: there is exactly one coding lane. */
1610
+ /** One row, one id ({@link WORKBENCH_CODING_LANE_STATUS_ROW_ID}): there is exactly one coding lane. */
1117
1611
  workbenchCodingLaneStatusId: z.string().min(1).isPrimaryKey().isSummaryField(),
1118
1612
  /** Every declared coding agent resolves in the registry. NOT a claim that the transport works. */
1119
1613
  codingAgentRegistered: z.boolean().isSummaryField(),
@@ -1176,6 +1670,14 @@ export var Workbench_ParkedCodingQuestionOptionRef;
1176
1670
  })(Workbench_ParkedCodingQuestionOptionRef || (Workbench_ParkedCodingQuestionOptionRef = {}));
1177
1671
  /** The single field a parked run asks: the agent's own question, verbatim. */
1178
1672
  export const WORKBENCH_PARKED_CODING_QUESTION_FIELD_REF = 'answer';
1673
+ /**
1674
+ * One coding run PARKED on a question.
1675
+ *
1676
+ * It arrives inside the coding-agent status payload, which is a singleton and stays a companion
1677
+ * read. These do not: a parked question is identified by the task that parked on it, it persists
1678
+ * until somebody answers, and a queue of work waiting on a person is the last thing that should be
1679
+ * reachable only by reading a status blob.
1680
+ */
1179
1681
  export const Workbench_ParkedCodingQuestion_Schema = z.object({
1180
1682
  /** The parked task's id, sanitized. */
1181
1683
  workbenchParkedCodingQuestionId: z.string().min(1).isPrimaryKey().isSummaryField(),
@@ -1736,7 +2238,10 @@ export var ApplicationSecretStanding;
1736
2238
  ApplicationSecretStanding["NEEDED"] = "needed";
1737
2239
  /** It has a value in this environment, and something reads it. */
1738
2240
  ApplicationSecretStanding["SET"] = "set";
1739
- /** Unset, and nothing waits for it: an optional key, or a capability another provider already serves. */
2241
+ /**
2242
+ * Unset, and nothing waits for it: an optional key, or a capability another provider already serves, ready, in every
2243
+ * runtime that would use this key for it (a provider ready in the backend serves nothing to the companion, #2985).
2244
+ */
1740
2245
  ApplicationSecretStanding["AVAILABLE"] = "available";
1741
2246
  /**
1742
2247
  * It has a value, and nothing CONSUMES it: a provider key no provider declares, a system-of-record key
@@ -1854,7 +2359,11 @@ export const Workbench_ApplicationSecret_Schema = z.object({
1854
2359
  ownerRef: z.string().min(1).nullable().isSummaryField(),
1855
2360
  /** Its owner's own description of it, when it has one. */
1856
2361
  description: z.string().nullable(),
1857
- /** The enabled capabilities a provider serves for this application — why the secret is needed. Empty for the other kinds. */
2362
+ /**
2363
+ * The enabled capabilities this secret serves — why it is needed: those of the provider arms that READ it, not every
2364
+ * capability its provider serves (#2978). Empty for a key no capability-serving arm reads (a sign-in client secret)
2365
+ * and for the other kinds.
2366
+ */
1858
2367
  capabilities: z.array(z.enum(EngineCapability).systemEnum('EngineCapability')),
1859
2368
  /**
1860
2369
  * The runtimes that RECEIVE it in their environment — the ones a change regenerates and restarts: `backend`,