@opencxh/domain 1.172.1 → 1.173.0

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 (84) hide show
  1. package/dist/entities/activity/blocks.d.ts +30 -30
  2. package/dist/entities/activity/catalog.d.ts +63 -86
  3. package/dist/entities/activity/descriptor.d.ts +31 -32
  4. package/dist/entities/activity/index.d.ts +2 -2
  5. package/dist/entities/activity/preview.d.ts +7 -7
  6. package/dist/entities/activity/resolve.d.ts +37 -38
  7. package/dist/entities/activity/types.d.ts +64 -35
  8. package/dist/entities/ai-account/types.d.ts +3 -3
  9. package/dist/entities/ai-account/vendors.d.ts +25 -32
  10. package/dist/entities/ai-budget/types.d.ts +5 -5
  11. package/dist/entities/ai-conversation/types.d.ts +12 -12
  12. package/dist/entities/ai-profile/types.d.ts +14 -21
  13. package/dist/entities/ai-settings/types.d.ts +12 -13
  14. package/dist/entities/analytics/index.d.ts +4 -4
  15. package/dist/entities/analytics/source.d.ts +1 -1
  16. package/dist/entities/analytics/usage.d.ts +23 -28
  17. package/dist/entities/artifact/blocks.d.ts +54 -69
  18. package/dist/entities/artifact/markdown.d.ts +2 -3
  19. package/dist/entities/artifact/types.d.ts +46 -54
  20. package/dist/entities/assignment/types.d.ts +76 -90
  21. package/dist/entities/channel/index.d.ts +1 -1
  22. package/dist/entities/channel/signature.d.ts +8 -9
  23. package/dist/entities/communication/index.d.ts +1 -1
  24. package/dist/entities/contact/index.d.ts +1 -1
  25. package/dist/entities/custom-field-def/types.d.ts +14 -14
  26. package/dist/entities/external-identity/types.d.ts +45 -50
  27. package/dist/entities/interaction/index.d.ts +1 -1
  28. package/dist/entities/interaction/types.d.ts +44 -47
  29. package/dist/entities/live-lens/types.d.ts +39 -44
  30. package/dist/entities/mcp/types.d.ts +53 -57
  31. package/dist/entities/memory/alias.d.ts +7 -7
  32. package/dist/entities/memory/browse.d.ts +21 -21
  33. package/dist/entities/memory/ingest.d.ts +24 -28
  34. package/dist/entities/memory/item.d.ts +53 -58
  35. package/dist/entities/memory/kind.d.ts +25 -25
  36. package/dist/entities/memory/query.d.ts +49 -51
  37. package/dist/entities/playbook/actor.d.ts +17 -17
  38. package/dist/entities/playbook/assignment.d.ts +54 -63
  39. package/dist/entities/playbook/index.d.ts +2 -2
  40. package/dist/entities/playbook/labels.d.ts +4 -4
  41. package/dist/entities/playbook/trigger-vars.d.ts +17 -15
  42. package/dist/entities/playbook/types.d.ts +174 -303
  43. package/dist/entities/resource-reminder/types.d.ts +8 -9
  44. package/dist/entities/time-entry/duration.d.ts +11 -11
  45. package/dist/entities/time-entry/types.d.ts +59 -59
  46. package/dist/entities/time-entry/work-type.d.ts +21 -24
  47. package/dist/entities/topic/examples.d.ts +26 -27
  48. package/dist/entities/topic/scope.d.ts +11 -12
  49. package/dist/entities/topic/types.d.ts +26 -28
  50. package/dist/entities/user/types.d.ts +24 -28
  51. package/dist/entities/webhook/types.d.ts +6 -6
  52. package/dist/entities/work/activity.d.ts +36 -0
  53. package/dist/entities/work/index.d.ts +1 -0
  54. package/dist/entities/work/keys.d.ts +25 -26
  55. package/dist/entities/work/ladder.d.ts +48 -52
  56. package/dist/entities/work/types.d.ts +108 -114
  57. package/dist/index.cjs +6 -6
  58. package/dist/index.d.ts +29 -28
  59. package/dist/index.js +1416 -1258
  60. package/dist/platform/account.d.ts +34 -38
  61. package/dist/platform/ai-tools.d.ts +48 -52
  62. package/dist/platform/api.d.ts +9 -10
  63. package/dist/platform/author.d.ts +7 -9
  64. package/dist/platform/capabilities.d.ts +3 -3
  65. package/dist/platform/communication.d.ts +163 -204
  66. package/dist/platform/context.d.ts +8 -8
  67. package/dist/platform/identity.d.ts +16 -19
  68. package/dist/platform/kernel.d.ts +1 -1
  69. package/dist/platform/manifest.d.ts +2 -2
  70. package/dist/platform/media.d.ts +13 -15
  71. package/dist/platform/permission.d.ts +39 -0
  72. package/dist/platform/permission.test.d.ts +1 -0
  73. package/dist/platform/presence.d.ts +30 -30
  74. package/dist/platform/provider.d.ts +14 -15
  75. package/dist/platform/resource-source.d.ts +43 -45
  76. package/dist/platform/resource.d.ts +17 -23
  77. package/dist/platform/scope.d.ts +35 -61
  78. package/dist/platform/services.d.ts +4 -4
  79. package/dist/platform/storage.d.ts +1 -1
  80. package/dist/platform/sync-source.d.ts +196 -216
  81. package/dist/platform/transcript-cadence.d.ts +37 -41
  82. package/dist/platform/ui.d.ts +6 -6
  83. package/dist/text/endpoint.d.ts +11 -27
  84. package/package.json +3 -2
@@ -2,10 +2,10 @@ import { ActingIdentity } from '../../platform/identity';
2
2
  import { ResourceRef } from '../../platform/resource';
3
3
  import { OwnerScope } from '../scope/types';
4
4
  /**
5
- * Playbooks — event-driven automation met AI-stappen. Zie docs/PLAYBOOKS.md.
5
+ * Playbooks — event-driven automation with AI steps. See docs/PLAYBOOKS.md.
6
6
  *
7
- * Twee uitvoeringsvormen, één contract: zie {@link Decider}. Alle staptypes in
8
- * {@link Step} worden uitgevoerd; er is geen soort meer die de executor weigert.
7
+ * Two execution forms, one contract: see {@link Decider}. Every step type in
8
+ * {@link Step} is executed; there is no kind the executor refuses.
9
9
  */
10
10
  export type Autonomy = "suggest" | "auto";
11
11
  export type PlaybookTrigger = {
@@ -17,33 +17,26 @@ export type PlaybookTrigger = {
17
17
  channelIds?: string[];
18
18
  filter?: unknown;
19
19
  /**
20
- * Wacht dit aantal milliseconden en draai dan **één** run voor de berichten in dat
21
- * venster, in plaats van een run per bericht.
20
+ * Wait this many milliseconds, then run **once** for the messages in that window
21
+ * instead of once per message. The run executes on the **newest** message; the ones
22
+ * in between are already covered by the conversation lookup step.
22
23
  *
23
- * Voor een playbook dat bij elk bericht een modelcall doet is dit het verschil tussen
24
- * vier calls en één bij een mailwisseling van vier berichten in tien minuten. De run
25
- * draait op het **nieuwste** bericht uit het venster; wat ertussen zat is in de
26
- * samenvatting van dat gesprek al meegenomen via de lookup-stap.
27
- *
28
- * Bewust op de trigger en niet in de geheugenlaag: coalesceren is een eigenschap van
29
- * "hoe vaak wil ik hierop reageren", niet van wat je onthoudt.
24
+ * Deliberately on the trigger, not in the memory layer: coalescing is a property of
25
+ * "how often do I want to react", not of what you remember.
30
26
  */
31
27
  debounceMs?: number;
32
28
  } | {
33
29
  kind: "manual";
34
30
  }
35
31
  /**
36
- * Iemand wijst werk aan de agent van deze playbook toe — de wekker van een **opdracht**.
37
- *
38
- * Geen nieuw mechanisme: een toewijzing is al een activity, dus dezelfde poort levert hem af.
39
- * Wat deze soort toevoegt is de vraag die de engine niet zelf kan beantwoorden — *is dit aan
40
- * míjn agent?* — en het antwoord staat in `Playbook.agentId`, niet hier. Eén plek die de
41
- * agent benoemt, want dat veld bepaalt óók namens wie de run handelt; zou het hier nóg een
42
- * keer staan, dan kon een playbook op de toewijzing aan de één reageren namens de ander.
43
- *
44
- * Wélke soorten werk toegewezen kunnen worden is **gedeclareerd** door de app die ze bezit
45
- * (`assignment-source`-federatie, zie `./assignment.ts`) en staat daarom als losse id in
46
- * `targetKind` in plaats van als union hier.
32
+ * Someone assigns work to this playbook's agent — the wake-up call of an **assignment**.
33
+ *
34
+ * Not a new mechanism: an assignment is already an activity, so the same gate delivers it.
35
+ * The question the engine cannot answer itself — *is this for MY agent?* — is answered by
36
+ * `Playbook.agentId`, not here: one place names the agent, because that field also decides
37
+ * who the run acts as. Which kinds of work can be assigned is **declared** by the app that
38
+ * owns them (`assignment-source` federation, see `./assignment.ts`), hence a loose id in
39
+ * `targetKind` instead of a union here.
47
40
  */
48
41
  | {
49
42
  kind: "assignment";
@@ -54,18 +47,16 @@ export interface Guardrails {
54
47
  maxToolCalls?: number;
55
48
  }
56
49
  /**
57
- * Grenzen voor `maxTokens` op een AI-stap. De bovengrens is dezelfde als die van
58
- * `/generate`: geen enkele prompt hier heeft meer output nodig, en een op hol
59
- * geslagen run mag er niet voor betalen. De ondergrens houdt een typfout ("5")
60
- * tegen die elk antwoord halverwege een woord afkapt.
50
+ * Bounds for `maxTokens` on an AI step. The upper bound matches `/generate` — no prompt here
51
+ * needs more output, and a runaway run must not pay for it. The lower bound blocks a typo
52
+ * ("5") that would truncate every answer mid-word.
61
53
  */
62
54
  export declare const STEP_MAX_TOKENS_MIN = 64;
63
55
  export declare const STEP_MAX_TOKENS_MAX = 8000;
64
56
  /**
65
- * `maxTokens` van een stap naar een bruikbare waarde, of `undefined` als er niets
66
- * (bruikbaars) staat. Neemt ook strings aan, want de editor levert het veld als
67
- * tekst op (`<input type="number">`) en een string in `max_tokens` is bij OpenAI
68
- * en Anthropic een 400.
57
+ * Clamp a step's `maxTokens` to a usable value, or `undefined` when there is nothing usable.
58
+ * Also accepts strings: the editor delivers the field as text (`<input type="number">`), and
59
+ * a string in `max_tokens` is a 400 at OpenAI and Anthropic.
69
60
  */
70
61
  export declare function clampStepMaxTokens(value: unknown): number | undefined;
71
62
  export interface ConditionStep {
@@ -76,12 +67,10 @@ export interface ConditionStep {
76
67
  onFalse: "stop" | "escalate" | "continue";
77
68
  }
78
69
  /**
79
- * Generiek over wat er in de body mag staan, zodat een beperkte staptaal een **echt subtype** kan
80
- * zijn in plaats van een runtime-regel. Zie `ReadStep` in `../live-lens/types`: die laat hier
81
- * alleen leesbare stappen in, en dan is "een leesbaan kan niet schrijven" een typefout in plaats
82
- * van een controle die iemand kan vergeten aan te roepen.
83
- *
84
- * De default houdt elk bestaand gebruik (`ForEachStep` zonder parameter) ongewijzigd.
70
+ * Generic over the step body so a restricted step language can be a **real subtype** instead
71
+ * of a runtime rule — see `ReadStep` in `../live-lens/types`, which only admits readable
72
+ * steps, making "a read lane cannot write" a type error rather than a check someone can
73
+ * forget. The default keeps existing usage (`ForEachStep` without a parameter) unchanged.
85
74
  */
86
75
  export interface ForEachStep<S = Step> {
87
76
  type: "for-each";
@@ -103,45 +92,36 @@ export interface ActionStep {
103
92
  params: Record<string, unknown>;
104
93
  autonomy?: Autonomy;
105
94
  /**
106
- * Var waarin het resultaat van de actie landt, als je het nodig hebt.
107
- *
108
- * Bestond niet, en daardoor was er geen manier om te wachten op iets dat je zelf net had
109
- * aangemaakt: een `create_task` kon haar id nergens laten, dus `waitingOn: { on: "task" }` was
110
- * niet in te gaan. Dezelfde vorm als `LookupStep.as`, en dezelfde parsing — twee antwoorden op
111
- * "wat ís het resultaat van een tool" zou de volgende duplicatie zijn.
95
+ * Var that receives the action's result, when you need it (e.g. wait on a task you just
96
+ * created). Same shape and parsing as `LookupStep.as`.
112
97
  *
113
- * Onder autonomie `suggest` wordt de actie vastgehouden en draait ze pas na goedkeuring; het
114
- * resultaat landt dan bij het hervatten. Tot dat moment bestaat de var niet, en een stap die
115
- * er dan al naar verwijst faalt luid (zie `engine/utils.ts`) in plaats van met leegte verder
116
- * te gaan.
98
+ * Under autonomy `suggest` the action is held and runs only after approval; the result
99
+ * lands on resume. Until then the var does not exist, and a step that references it fails
100
+ * loudly (see `engine/utils.ts`) instead of continuing with emptiness.
117
101
  */
118
102
  as?: string;
119
103
  }
120
104
  /**
121
- * Wacht tot deze taak af is.
122
- *
123
- * De tegenhanger van `wait-for-reply`, voor het geval uit de support-procedure: "moet een
124
- * collega iets doen, maak een taak en wacht tot die af is". `taskId` is een gewone verwijzing,
125
- * dus `$newTask.id` na een `create_task` met een `as`.
105
+ * Wait until this task is done. Counterpart of `wait-for-reply`, for the support-procedure
106
+ * case "a colleague must do something: create a task and wait for it". `taskId` is an
107
+ * ordinary reference, e.g. `$newTask.id` after a `create_task` with an `as`.
126
108
  */
127
109
  export interface WaitForTaskStep {
128
110
  type: "wait-for-task";
129
- /** `$ref` of letterlijk id van de taak om op te wachten. */
111
+ /** `$ref` or literal id of the task to wait on. */
130
112
  taskId: string;
131
113
  }
132
114
  /**
133
- * Een enkele classificatie met gestructureerde uitvoer.
115
+ * A single classification with structured output.
134
116
  *
135
- * **`profileId` en niet `accountId` + `model`.** Dit was de enige AI-stap die zijn eigen account
136
- * en model droeg, terwijl de kernkeuze van dit systeem is dat een `AIProfile` het herbruikbare
137
- * brein is en AI-stappen daarnaar verwijzen (`docs/PLAYBOOKS.md` §2). Wat die uitzondering kostte:
138
- * sjablonen hadden `$default`/`$defaultModel`-placeholders nodig die de installer moest
139
- * vervangen, en een modelwissel raakte elke classify-stap van elke playbook afzonderlijk.
117
+ * **`profileId`, not `accountId` + `model`.** An `AIProfile` is the reusable brain and AI
118
+ * steps reference it (`docs/PLAYBOOKS.md` §2); carrying account/model here forced
119
+ * `$default`-placeholders on templates and made a model swap touch every classify step.
140
120
  */
141
121
  export interface ClassifyStep {
142
122
  type: "classify";
143
123
  as: string;
144
- /** Het brein dat classificeert. Een goedkoop, snel profiel is hier de bedoeling. */
124
+ /** The brain that classifies. A cheap, fast profile is the intent here. */
145
125
  profileId: string;
146
126
  mode: "topics" | "question" | "extract";
147
127
  topicIds?: string[];
@@ -149,22 +129,17 @@ export interface ClassifyStep {
149
129
  fields?: unknown;
150
130
  instruction?: string;
151
131
  /**
152
- * Wélke tekst geclassificeerd wordt, als `$ref` in de run-vars. Default `$trigger.text`.
153
- *
154
- * Nodig zodra de trigger zelf geen tekst draagt. Een `INTERACTION_STATUS_CHANGED`-activity
155
- * heeft alleen `{ fromStatus, toStatus }` in zijn payload, dus `trigger.text` is leeg — en
156
- * dan krijgt het model een lege invoer. Met `input: "$thread"` leest de stap wat een
157
- * eerdere `lookup` heeft opgehaald, zoals de berichten van het gesprek.
132
+ * Which text is classified, as a `$ref` into the run vars. Default `$trigger.text`.
133
+ * Needed when the trigger carries no text: an `INTERACTION_STATUS_CHANGED` activity has
134
+ * only `{ fromStatus, toStatus }`, so `trigger.text` is empty. With `input: "$thread"` the
135
+ * step reads what an earlier `lookup` fetched.
158
136
  */
159
137
  input?: string;
160
138
  /**
161
- * Plafond op de output van deze stap, per model-call. Leeg = het
162
- * `providerConfig` van het account/profiel, en anders de vendor-default.
163
- *
164
- * Bewust naast `guardrails` en niet erin: `maxSteps`/`maxToolCalls` begrenzen de
165
- * hele run, dit geldt per call. In dezelfde bak zou het lezen als "totaalbudget
166
- * voor deze stap", en dat is het niet — een agent-loop van vijf turns mag vijf
167
- * keer tot dit plafond komen.
139
+ * Output cap for this step, per model call. Empty = the account/profile `providerConfig`,
140
+ * else the vendor default. Deliberately next to `guardrails`, not inside:
141
+ * `maxSteps`/`maxToolCalls` bound the whole run, this applies per call — an agent loop of
142
+ * five turns may reach this cap five times.
168
143
  */
169
144
  maxTokens?: number;
170
145
  }
@@ -174,26 +149,22 @@ export interface GenerateStep {
174
149
  goal?: string;
175
150
  kind: "reply" | "compose" | "note";
176
151
  as?: string;
177
- /** Plafond op de output van deze stap. Zie `ClassifyStep.maxTokens`. */
152
+ /** Output cap for this step. See `ClassifyStep.maxTokens`. */
178
153
  maxTokens?: number;
179
154
  }
180
155
  /**
181
- * Een agentische beurt **binnen een flow**.
182
- *
183
- * Draagt een {@link Procedure} in plaats van diens velden nóg een keer: dit had
184
- * `goal`/`toolsOverride`/`guardrails`/`maxTokens` als eigen velden, wat exact dezelfde vijf
185
- * dingen waren onder twee namen — en `runAgentStep` was een adapter die `goal` op `text` en
186
- * `toolsOverride` op `tools` afbeeldde. Compositie in plaats van een tweede naamgeving.
156
+ * An agentic turn **inside a flow**. Carries a {@link Procedure} instead of repeating its
157
+ * fields — composition instead of a second naming of the same five things.
187
158
  *
188
- * `profileId` staat hiér en niet in de procedure: een workflow heeft geen agent, dus het brein
189
- * moet uit de stap komen. Bij een **opdracht** komt het brein van de agent
190
- * (`User.profileId`) en draagt de procedure er dus geen.
159
+ * `profileId` lives here, not in the procedure: a workflow has no agent, so the brain must
160
+ * come from the step. On an **assignment** the brain comes from the agent (`User.profileId`)
161
+ * and the procedure carries none.
191
162
  */
192
163
  export interface AgentStep {
193
164
  type: "agent";
194
- /** Het brein voor deze stap. */
165
+ /** The brain for this step. */
195
166
  profileId: string;
196
- /** Wat er moet gebeuren, en waarbinnen. */
167
+ /** What must happen, and within which bounds. */
197
168
  procedure: Procedure;
198
169
  autonomy?: Autonomy;
199
170
  as?: string;
@@ -203,85 +174,65 @@ export interface WaitForReplyStep {
203
174
  deadline?: number;
204
175
  }
205
176
  /**
206
- * Meerdere takken tegelijk, en pas verder als ze allemaal klaar zijn.
177
+ * Multiple branches at once; continue only when all are done. Exists because sequential
178
+ * lookups cost the sum and live-assist cadence can only afford the slowest.
207
179
  *
208
- * Bestaat voor één concreet probleem: stappen liepen strikt sequentieel, en drie lookups van
209
- * elk ~1200 ms achter elkaar passen niet in een cadans van seconden (live assist). Sequentieel
210
- * kost de som, parallel kost de langzaamste.
180
+ * **Read-only.** A branch may not pause — no approval, no waiting for a reply. Not a
181
+ * temporary limitation: a run pausing mid fan-out would need a second state machine next to
182
+ * `waitingOn`. Writes go in a step after the `parallel`.
211
183
  *
212
- * **Alleen lezen.** Een tak mag niet pauzeren — geen goedkeuring, geen wachten op een antwoord.
213
- * Dat is geen tijdelijke beperking maar een grens die het begrip eenvoudig houdt: een run die
214
- * halverwege een fan-out pauzeert zou moeten onthouden welke takken al klaar waren en waar hij
215
- * verder moet, en dat is een tweede toestandsmachine naast `waitingOn`. Wie iets wil schrijven
216
- * doet dat in een stap ná de `parallel`.
217
- *
218
- * Elke tak schrijft naar zijn eigen `as`-namen; twee takken die dezelfde naam vullen is een
219
- * fout, want wie er wint hangt dan van de timing af.
184
+ * Each branch writes to its own `as` names; two branches filling the same name is an error,
185
+ * because the winner would depend on timing.
220
186
  */
221
187
  export interface ParallelStep<S = Step> {
222
188
  type: "parallel";
223
- /** Elke tak is een eigen rijtje stappen. Zie {@link ForEachStep} over de parameter. */
189
+ /** Each branch is its own list of steps. See {@link ForEachStep} about the parameter. */
224
190
  branches: S[][];
225
191
  /**
226
- * Hoeveel takken er tegelijk mogen lopen. Leeg = alle.
227
- *
228
- * Een plafond bestaat omdat een tak een tool-call is: tien takken tegelijk zijn tien
229
- * gelijktijdige aanroepen naar andere apps.
192
+ * How many branches may run at once. Empty = all. A cap exists because a branch is a tool
193
+ * call: ten branches are ten concurrent calls into other apps.
230
194
  */
231
195
  maxConcurrent?: number;
232
196
  /**
233
- * Wat een falende tak betekent. Default `"fail"`: de stap faalt.
234
- *
235
- * `"continue"` laat de andere takken staan en gaat door — dat is wat een leesoppervlak wil
236
- * (één kapotte baan mag de andere twee niet wissen), en precies waarom het een keuze is en
237
- * geen aanname.
197
+ * What a failing branch means. Default `"fail"`: the step fails. `"continue"` keeps the
198
+ * other branches and proceeds — what a read surface wants (one broken lane must not wipe
199
+ * the other two), which is exactly why it is a choice and not an assumption.
238
200
  */
239
201
  onBranchError?: "fail" | "continue";
240
202
  }
241
203
  export type Step = ConditionStep | ForEachStep | ParallelStep | LookupStep | ActionStep | ClassifyStep | GenerateStep | AgentStep | WaitForReplyStep | WaitForTaskStep;
242
204
  /**
243
- * Een **procedure**: hoe een scenario aangepakt wordt, als prose met guardrails.
244
- *
245
- * Dit is de tweede uitvoeringsvorm naast `Step[]`, en {@link AgentStep} is er de
246
- * variant-binnen-een-flow van (die *bevat* er een, en herhaalt zijn velden niet).
247
- *
248
- * **Geen `profileId`.** Dat stond hier, en het was de tweede brein-verwijzing in het systeem:
249
- * `User.profileId` bestaat al — verplicht bij het aanmaken van een agent, met als doc "het brein
250
- * van een agent" — en de engine las hem nooit. Twee velden voor één feit, zonder dat iets ze aan
251
- * elkaar relateerde: `agentId: Alice` met het brein van Bob werd zonder klacht opgeslagen, en de
252
- * tijdlijn zei dan Alice terwijl het model, de tools en de prompt van Bob waren.
205
+ * A **procedure**: how a scenario is handled, as prose with guardrails. The second execution
206
+ * form next to `Step[]`; {@link AgentStep} is its inside-a-flow variant (it *contains* one).
253
207
  *
254
- * Nu is er één antwoord op "met welk brein": bij een opdracht dat van de agent, bij een
255
- * agent-stap in een workflow dat van de stap. De procedure beschrijft het scenario, niet wie het
256
- * uitvoert.
208
+ * **No `profileId`.** One answer to "which brain": on an assignment the agent's
209
+ * (`User.profileId`), on an agent step the step's. The procedure describes the scenario, not
210
+ * who executes it.
257
211
  *
258
- * `tools` is **narrowing-only**: het moet een deelverzameling zijn van `enabledTools` van het
259
- * brein dat hem uitvoert. Het profiel is de identiteit (één per agent), de procedure het scenario
260
- * (veel per agent), en een scenario mag nooit méér mogen dan de identiteit die het uitvoert.
212
+ * `tools` is **narrowing-only**: it must be a subset of the executing brain's
213
+ * `enabledTools`. The profile is the identity (one per agent), the procedure the scenario
214
+ * (many per agent), and a scenario may never be allowed more than the identity executing it.
261
215
  */
262
216
  export interface Procedure {
263
- /** De prose zelf — wat er moet gebeuren, in de woorden van wie het opschreef. */
217
+ /** The prose itself — what must happen, in the words of whoever wrote it down. */
264
218
  text: string;
265
- /** Toegestane tools. Narrowing-only t.o.v. `enabledTools` van het brein. */
219
+ /** Allowed tools. Narrowing-only w.r.t. the brain's `enabledTools`. */
266
220
  tools?: string[];
267
221
  guardrails?: Guardrails;
268
- /** Plafond per beurt. Zie `ClassifyStep.maxTokens`. */
222
+ /** Cap per turn. See `ClassifyStep.maxTokens`. */
269
223
  maxTokens?: number;
270
224
  }
271
225
  /**
272
- * Wie kiest de volgende zet.
226
+ * Who picks the next move. Two execution forms, one contract — both run through the same
227
+ * tool runtime and the same approval gate:
273
228
  *
274
- * Twee uitvoeringsvormen, één contract. Beide lopen door dezelfde toolruntime en dezelfde
275
- * goedkeuringspoort; alleen de manier waarop de volgende zet gekozen wordt verschilt:
229
+ * - **workflow** — deterministic `Step[]`, built on the canvas. Routing, triage, background
230
+ * automation. A free, testable gate instead of a prompt.
231
+ * - **procedure** — prose, a model chooses. For work whose steps are not branches in a tree.
276
232
  *
277
- * - **workflow** — deterministisch, `Step[]`, gebouwd op de canvas. Routing, triage,
278
- * achtergrondautomatisering. Een gratis, testbare poort in plaats van een prompt.
279
- * - **procedure** — prose, een model kiest. Voor werk waarvan de stappen geen takken in een
280
- * boom zijn (antwoorden *én* een taak maken, of eerst vragen en daarna alsnog antwoorden).
281
- *
282
- * Verkeerd om gebruikt faalt elke vorm op zijn eigen manier: een procedure als workflow
283
- * verspreidt logica over blokken tot het onbeheersbaar is, een workflow als procedure ruilt een
284
- * testbare conditie voor een onbetrouwbare prompt (en kost een modelaanroep per bericht).
233
+ * Misused, each form fails its own way: a procedure-as-workflow scatters logic across blocks
234
+ * until unmanageable; a workflow-as-procedure trades a testable condition for an unreliable
235
+ * prompt (and costs a model call per message).
285
236
  */
286
237
  export type Decider = {
287
238
  kind: "workflow";
@@ -291,32 +242,15 @@ export type Decider = {
291
242
  procedure: Procedure;
292
243
  };
293
244
  /**
294
- * **Eén veld, met de soort erin.** Dit was een paar losse kolommen — `steps: Step[]` naast
295
- * `procedure?: Procedure | null` — met een functie (`deciderOf`) die er een union van maakte
296
- * volgens de regel "procedure aanwezig ⇒ procedure".
297
- *
298
- * Wat die vorm kostte:
299
- *
300
- * - een rij met **beide** gevuld was representeerbaar, en betekende stil "de steps zijn dood";
301
- * - elk schrijfpad moest de onuitgesproken regel kennen: `crud/update.ts` moest expliciet `null`
302
- * schrijven om "de procedure eruit halen" te laten werken, en `run-playbook.ts` had een
303
- * conditionele spread om de kolom weg te laten;
304
- * - de frontend had de regel nóg een keer (`!!pb.procedure` als soort-filter);
305
- * - en het is al een keer stil fout gegaan: `fromView` droeg `procedure` niet mee, waardoor élke
306
- * procedure die je opende en opsloeg zichzelf tot een lege workflow maakte.
307
- *
308
- * Met `kind` in de kolom is de soort een feit in plaats van een gevolgtrekking, en kan er geen
309
- * derde toestand bestaan. De editor houdt zijn platte vorm — dat is wat `toView`/`fromView` doen.
245
+ * One field with the kind inside: a row cannot carry both steps and a procedure, so the sort
246
+ * is a fact rather than an inference from which columns happen to be filled (which once made
247
+ * every opened-and-saved procedure silently become an empty workflow). The editor keeps its
248
+ * flat form — that is what `toView`/`fromView` do.
310
249
  */
311
250
  export declare const EMPTY_WORKFLOW: Decider;
312
- /**
313
- * De stappen van deze decider, of een lege lijst als het een procedure is.
314
- *
315
- * Twee lezers-helpers en géén `deciderOf` terug: het verschil is dat deze de soort *lezen* in
316
- * plaats van hem te *raden* uit welke velden gevuld zijn.
317
- */
251
+ /** The steps of this decider, or an empty list when it is a procedure. */
318
252
  export declare function stepsOf(decider: Decider | undefined): Step[];
319
- /** De procedure van deze decider, of `undefined` als het een workflow is. */
253
+ /** The procedure of this decider, or `undefined` when it is a workflow. */
320
254
  export declare function procedureOf(decider: Decider | undefined): Procedure | undefined;
321
255
  export interface Playbook {
322
256
  id: string;
@@ -327,18 +261,16 @@ export interface Playbook {
327
261
  enabled: boolean;
328
262
  autonomy: Autonomy;
329
263
  trigger: PlaybookTrigger;
330
- /** Wie de volgende zet kiest: stappen of prose. Zie {@link Decider}. */
264
+ /** Who picks the next move: steps or prose. See {@link Decider}. */
331
265
  decider: Decider;
332
266
  /**
333
- * De agent die dit uitvoert: het `userId` van een gebruiker met `type: "agent"`.
267
+ * The agent that executes this: the `userId` of a user with `type: "agent"`. Determines
268
+ * **who the run acts as** (`runActor`): whose name is on the timeline, which interactions
269
+ * it may touch, whose budget it draws from.
334
270
  *
335
- * Bepaalt **namens wie** de run handelt (`runActor`), en daarmee: wiens naam er in de tijdlijn
336
- * staat, welke interacties hij mag raken, en van wiens budget het afgaat. Bewust náást
337
- * `ownerScope` en niet erin — dat veld bepaalt wie de playbook mag *beheren*, en dat blijven
338
- * mensen. Een agent logt nooit in, dus als beide op één veld leunden kon niemand hem meer
339
- * aanpassen.
340
- *
341
- * Leeg = de actor volgt de scope, precies zoals voorheen.
271
+ * Deliberately next to `ownerScope`, not inside it — that field says who may *manage* the
272
+ * playbook, and those stay humans; an agent never logs in, so if both leaned on one field
273
+ * nobody could edit it anymore. Empty = the actor follows the scope.
342
274
  */
343
275
  agentId?: string | null;
344
276
  /** Bumped on every change; runs pin to the version they started on. */
@@ -353,106 +285,77 @@ export interface Playbook {
353
285
  };
354
286
  }
355
287
  /**
356
- * Levenscyclus van een run. Geen `pending`: runs worden ingevoegd als `running` en
357
- * de `PLAYBOOK_STARTED`-activity dekt "hij is begonnen" al. (Die status bestond,
358
- * werd nooit geproduceerd, en had wél een label in de UI.)
288
+ * Run lifecycle. No `pending`: runs are inserted as `running`, and the `PLAYBOOK_STARTED`
289
+ * activity already covers "it has begun".
359
290
  */
360
291
  export type RunStatus = "running" | "waiting" | "done" | "escalated" | "failed" | "stopped";
361
292
  /**
362
- * Waaróp een wachtende run wacht.
363
- *
364
- * Dit was eerder statusinformatie: `awaiting_approval`, `awaiting_reply` en `timed_out` waren
365
- * drie statussen die alle drie "wacht op X" betekenden, en de reden zat in de naam. Daardoor
366
- * groeide de statusset met elke nieuwe reden mee — een run die op een taak wacht zou
367
- * `awaiting_task` hebben gevraagd, een run die op een moment wacht `awaiting_time`, en dan
368
- * moest elke lezer van `status` opnieuw worden bijgewerkt.
369
- *
370
- * De reden van het wachten is **data**, geen status. `status: "waiting"` zegt dát er gewacht
371
- * wordt; dit veld zegt waarop, en wie het signaal levert leest alleen dit.
293
+ * What a waiting run is waiting for. The reason is **data**, not status: `status: "waiting"`
294
+ * says that it waits, this field says what for — a new reason costs a member here, not a new
295
+ * status every reader must learn.
372
296
  *
373
- * `timed_out` staat er niet bij: een verstreken deadline is geen manier van wachten maar een
374
- * uitkomst, en landt via `decideFinalState` op een eindstand (zie {@link TerminalLifecycle}).
375
- *
376
- * Er is ook geen `{ on: "time" }`. Die stond hier, zonder dat iets hem schreef of las: het
377
- * wachten-op-een-moment dat wél bestaat is de timeout-job die bij `{ on: "reply" }` wordt
378
- * ingeplanned, en die leest de deadline uit de job en niet uit dit veld. Een lid dat door niets
379
- * geproduceerd wordt is een belofte aan elke lezer die hem moet afhandelen.
297
+ * No `timed_out`: an expired deadline is an outcome, not a way of waiting, and lands on a
298
+ * terminal state via `decideFinalState` (see {@link TerminalLifecycle}). No `{ on: "time" }`
299
+ * either: nothing produced or read it; the reply-timeout job carries its own deadline.
380
300
  */
381
301
  export type WaitingOn = {
382
302
  on: "approval";
383
303
  }
384
- /** De klant antwoordt, of een collega beantwoordt de interne vraag van de run. */
304
+ /** The customer replies, or a colleague answers the run's internal question. */
305
+ /** `interactionId` only when the subject is a conversation; a work item waits without one. */
385
306
  | {
386
307
  on: "reply";
387
- interactionId: string;
308
+ interactionId?: string;
388
309
  } | {
389
310
  on: "task";
390
311
  taskId: string;
391
312
  };
392
- /** Eindstanden: hier komt een run niet meer vanzelf uit. */
313
+ /** Terminal states: a run does not leave these on its own. */
393
314
  export declare const TERMINAL_RUN_STATUSES: readonly ["done", "escalated", "failed", "stopped"];
394
315
  /**
395
- * **Tweede vocabulaire, expliciet.** Waarom een run eindigde, zoals de tijdlijn het benoemt —
396
- * niet hetzelfde als de status die op de run staat.
397
- *
398
- * Twee redenen zijn geen `RunStatus`, en dat is geen omissie:
316
+ * **A second vocabulary, on purpose.** Why a run ended, as the timeline names it — not the
317
+ * same as the status on the run:
399
318
  *
400
- * - **`rejected`** — een afgewezen voorstel landt als status `"stopped"`, maar de tijdlijn moet
401
- * "afgewezen" kunnen zeggen.
402
- * - **`timed_out`** — een run waarvan de deadline verstreek landt als `"escalated"` (er moet een
403
- * mens iets mee), maar "geen antwoord binnen de deadline" is een andere mededeling dan
404
- * "geëscaleerd". Dit was eerder een eigen status; hij is verhuisd naar dit vocabulaire, want
405
- * het is een *reden* en geen toestand waar een run in kan verkeren.
319
+ * - **`rejected`** — a rejected proposal lands as status `"stopped"`, but the timeline must
320
+ * be able to say "rejected".
321
+ * - **`timed_out`** — a missed deadline lands as `"escalated"` (a human must act), but "no
322
+ * reply within the deadline" is a different message. A *reason*, not a state.
406
323
  *
407
- * Dat dit vocabulaire rijker is dan de statusset is precies waarom het apart bestaat: de
408
- * tijdlijn vertelt een mens wát er gebeurde, `status` vertelt de machine wat er nog te doen is.
324
+ * The timeline tells a human what happened; `status` tells the machine what is left to do.
409
325
  */
410
326
  export type TerminalLifecycle = RunStatus | "rejected" | "timed_out";
411
327
  /**
412
- * Is deze run klaar — en daarmee ook: mag hij opnieuw gedraaid worden?
413
- *
414
- * Die tweede vraag had een eigen functie (`isRetryable`) die niets anders deed dan deze
415
- * aanroepen. Twee namen voor één regel betekent dat een lezer moet uitzoeken of er een verschil
416
- * is; dat er geen was, was niet te zien zonder de body te openen.
417
- *
418
- * De regel zelf staat hier dus één keer: een retry mag op precies de eindstanden. Een lopende of
419
- * mens-gepauzeerde run blijft met rust, zodat een retry nooit over live uitvoering heen loopt of
420
- * een openstaand voorstel overschrijft.
328
+ * Is this run finished — and thereby: may it be retried? A retry is allowed on exactly the
329
+ * terminal states; a running or human-paused run stays untouched, so a retry never runs over
330
+ * live execution or overwrites an open proposal.
421
331
  */
422
332
  export declare function isTerminal(status: RunStatus | string): boolean;
423
333
  /**
424
- * Wacht deze run op iets externs?
425
- *
426
- * Eén statusvergelijking en niet meer een lijst: er was een `PAUSED_RUN_STATUSES` met twee
427
- * leden omdat de reden van het wachten ín de status zat. Nu staat de reden in
428
- * {@link WaitingOn} en is "wacht" één toestand — dus een nieuwe reden (een taak, een moment)
429
- * verandert deze functie niet meer.
334
+ * Is this run waiting on something external? One status comparison: the reason lives in
335
+ * {@link WaitingOn}, so a new wait reason does not change this function.
430
336
  */
431
337
  export declare function isPaused(status: RunStatus | string): boolean;
432
338
  /**
433
- * Loopt deze run nog — mag `finalizeRun` er een uitkomst over schrijven?
434
- *
435
- * "In de lucht" is precies "niet in een eindstand": `running` of `waiting`. De lock-retry in
436
- * `jobs/context.ts` herschedulet tot vijf keer, dus zonder deze check kan een late job met een
437
- * verouderde uitkomst over een al afgeronde run schrijven.
339
+ * Is this run still live — may `finalizeRun` write an outcome for it? "Live" is exactly "not
340
+ * terminal": `running` or `waiting`. The lock retry in `jobs/context.ts` reschedules up to
341
+ * five times, so without this check a late job could write a stale outcome over a finished
342
+ * run.
438
343
  */
439
344
  export declare function isInFlight(status: RunStatus | string): boolean;
440
345
  /**
441
- * Het onderwerp van een run als één verwijzing, of `undefined` als hij er geen heeft.
442
- *
443
- * Zo'n run bestaat: een org-brede playbook die een rollup doet heeft geen resource om over te
444
- * gaan. Dat is een geldige toestand en geen ontbrekend veld.
346
+ * The run's subject as one reference, or `undefined` when it has none. Such runs exist: an
347
+ * org-wide rollup playbook has no resource to be about — a valid state, not a missing field.
445
348
  */
446
349
  export declare function subjectOf(run: {
447
350
  subjectKind?: string;
448
351
  subjectId?: string;
449
352
  }): ResourceRef | undefined;
450
- /** De scope-sleutel van het onderwerp, klaar voor `authorizeScope`. */
353
+ /** The subject's scope key, ready for `authorizeScope`. */
451
354
  export declare function subjectKeyOf(run: {
452
355
  subjectKind?: string;
453
356
  subjectId?: string;
454
357
  }): string | undefined;
455
- /** Het interactie-id van deze run, als zijn onderwerp een gesprek is. */
358
+ /** This run's interaction id, when its subject is a conversation. */
456
359
  export declare function runInteractionId(run: {
457
360
  subjectKind?: string;
458
361
  subjectId?: string;
@@ -464,20 +367,14 @@ export interface RunStepTrace {
464
367
  note?: string;
465
368
  ms?: number;
466
369
  }
467
- /**
468
- * Wat deze run in beweging zette.
469
- *
470
- * Was `createdBy: string`, en dat veld droeg de auteur van de **playbook** — niet wie de run
471
- * startte. Dus "wie heeft dit gedaan" had geen antwoord, terwijl `run/start.ts` het userId van de
472
- * mens die op start drukte al meestuurde in de job-data, waar niemand het las.
473
- */
370
+ /** What set this run in motion — who started the run, not the playbook's author. */
474
371
  export type StartedBy =
475
- /** Een mens drukte op start (`POST /playbook-run/start`). */
372
+ /** A human pressed start (`POST /playbook-run/start`). */
476
373
  {
477
374
  kind: "user";
478
375
  id: string;
479
376
  }
480
- /** De trigger vuurde: een activity, een toewijzing, een afgeronde taak. */
377
+ /** The trigger fired: an activity, an assignment, a completed task. */
481
378
  | {
482
379
  kind: "trigger";
483
380
  id?: string;
@@ -488,40 +385,29 @@ export interface PlaybookRun {
488
385
  playbookId: string;
489
386
  playbookVersion: number;
490
387
  /**
491
- * De opdracht waarvan dit een **beurt** is, als er een is.
492
- *
493
- * Afwezig = een losstaande uitvoering (een automatisering die vuurt en klaar is). Aanwezig = één
494
- * zet in werk dat langer leeft dan deze run, met een draad als geheugen.
388
+ * The assignment this is a **turn** of, if any. Absent = a standalone execution (an
389
+ * automation that fires and is done). Present = one move in work that outlives this run,
390
+ * with a thread as memory.
495
391
  */
496
392
  assignmentId?: string;
497
393
  /**
498
- * Waar deze run **over gaat**, in twee platte kolommen.
499
- *
500
- * Dit was `interactionId?: string`, en dat leek onschuldig — het veld was immers optioneel. Maar
501
- * vier paden leunden er zwijgend op alsof het verplicht was: goedkeuren gooide `400` zonder
502
- * interactie, de lijst filterde op `audience` (leeg voor een org-actor, dus onvindbaar), de
503
- * tijdlijn deed niets, en de taak-wekker eiste een gesprek. Precies het geval waar de
504
- * toewijs-federatie voor bestaat — werk dat géén gesprek is — viel dus in dat gat.
505
- *
506
- * **Twee kolommen en geen genest object**, om dezelfde reden als {@link WaitingOn} zijn
507
- * `waitingOnKind` heeft: de store kan niet in een genest object zoeken, en hier moet op gezocht
508
- * worden (de runs van dit gesprek, de runs van deze taak). `subjectOf` maakt er een
509
- * {@link ResourceRef} van waar je hem als geheel nodig hebt.
394
+ * What this run is **about**, in two flat columns — not a nested object, for the same
395
+ * reason {@link WaitingOn} has its `waitingOnKind`: the store cannot search inside a
396
+ * nested object, and these must be queryable (the runs of this conversation, of this
397
+ * task). Genuinely optional: assignment-federation work that is not a conversation has no
398
+ * interaction. `subjectOf` builds a {@link ResourceRef} where you need it whole.
510
399
  */
511
400
  subjectKind?: string;
512
401
  subjectId?: string;
513
402
  status: RunStatus;
514
403
  /**
515
- * De aanleiding: wélk signaal deze run startte, plus de invoer zoals die er tóen uitzag.
404
+ * The cause: which signal started this run, plus the input as it looked **then**.
516
405
  *
517
- * **`vars` hier is niet hetzelfde als `vars.trigger` hieronder, en dat is met opzet.** Dit veld
518
- * is de *onveranderlijke invoer*; `vars` is de *werkkopie* die tijdens de run muteert — stappen
519
- * schrijven erin, en resume-on-reply overschrijft `vars.trigger` met het nieuwe bericht. Een
520
- * retry moet schoon herrekenen vanaf het oorspronkelijke signaal, en dat kan alleen als dat
521
- * signaal ergens bewaard is gebleven.
522
- *
523
- * Het veld heette `event`, wat suggereerde dat het de rauwe activity was; het zijn de
524
- * trigger-vars. Dezelfde vorm als `vars.trigger` betekent hier dus niet dezelfde betekenis.
406
+ * **`vars` here is not the same as `vars.trigger` below, on purpose.** This field is the
407
+ * *immutable input*; `vars` is the *working copy* that mutates during the run — steps
408
+ * write into it, and resume-on-reply overwrites `vars.trigger` with the new message. A
409
+ * retry must recompute cleanly from the original signal, which requires that signal to
410
+ * have been kept somewhere.
525
411
  */
526
412
  trigger: {
527
413
  activityType?: string;
@@ -531,27 +417,26 @@ export interface PlaybookRun {
531
417
  vars: Record<string, unknown>;
532
418
  trace: RunStepTrace[];
533
419
  /**
534
- * De uitvoeringsvorm, vastgepind bij de start: de playbook bijstellen mag een lopende of
535
- * geparkeerde run niet halverwege van gedrag of opdracht laten wisselen (docs 11.4).
420
+ * The execution form, pinned at start: editing the playbook must not switch a running or
421
+ * parked run's behaviour or mandate mid-flight (docs 11.4).
536
422
  */
537
423
  decider: Decider;
538
424
  /**
539
- * De agent die deze run uitvoert, vastgepind — en daarmee ook **met welk brein**: dat is
540
- * `User.profileId` van deze agent. Afwezig bij een workflow zonder agent; dan draagt een
541
- * agent-stap zijn eigen `profileId`.
425
+ * The agent executing this run, pinned — and thereby **which brain**: this agent's
426
+ * `User.profileId`. Absent for a workflow without an agent; an agent step then carries its
427
+ * own `profileId`.
542
428
  */
543
429
  agentId?: string | null;
544
430
  /**
545
- * Namens wie deze run handelt, vastgepind bij de start — net als `steps`. Anders
546
- * wisselt een lopende of geparkeerde run stilletjes van identiteit zodra iemand de
547
- * playbook van "Alleen ik" naar "Team Finance" zet. `resume`/`retry` lezen dit veld,
548
- * niet `playbook.ownerScope`.
431
+ * Who this run acts as, pinned at start — like `steps`. Otherwise a running or parked run
432
+ * silently switches identity the moment someone moves the playbook from "Only me" to
433
+ * "Team Finance". `resume`/`retry` read this field, not `playbook.ownerScope`.
549
434
  */
550
435
  actor?: ActingIdentity;
551
436
  /**
552
- * Held action(s) awaiting human approval (autonomy: suggest) — a batch per paused
553
- * step. `null` wanneer het veld gewist is; de store schrijft `null`, dus dat staat
554
- * ook in het type in plaats van dat elke lezer drie toestanden moet aankunnen.
437
+ * Held action(s) awaiting human approval (autonomy: suggest) — a batch per paused step.
438
+ * `null` when the field was cleared; the store writes `null`, so the type says so instead
439
+ * of every reader handling three states.
555
440
  */
556
441
  pending?: {
557
442
  action: string;
@@ -561,45 +446,31 @@ export interface PlaybookRun {
561
446
  /** The AI_ACTION_PROPOSED activity created for the current pending batch (for resolve on approve/reject). */
562
447
  proposalActivityId?: string | null;
563
448
  /**
564
- * Waarop deze run wacht, als `status === "waiting"`. `null` wanneer het veld gewist is (de
565
- * store schrijft `null`), en afwezig bij een run die niet wacht.
566
- *
567
- * Vervangt de drie `awaiting_*`/`timed_out`-statussen: de reden van het wachten is data, dus
568
- * een nieuwe reden kost een lid in {@link WaitingOn} en niet een status die elke lezer moet
569
- * kennen.
449
+ * What this run waits for, when `status === "waiting"`. `null` when cleared (the store
450
+ * writes `null`), absent on a run that is not waiting. A new wait reason costs a member in
451
+ * {@link WaitingOn}, not a status every reader must know.
570
452
  */
571
453
  waitingOn?: WaitingOn | null;
572
454
  /**
573
- * De **soort** van {@link WaitingOn}, als platte kolom — puur om op te kunnen queryen.
574
- *
575
- * `waitingOn` is een genest object en de store kan daar niet in zoeken, dus elke wekker deed
576
- * `status: "waiting"` en filterde daarna in het geheugen op `run.waitingOn?.on`
577
- * (`jobs/run-playbook.ts`, `triggers/from_tasks.ts`). Dat is goedkoop bij tien wachtende runs
578
- * en niet bij tienduizend. Afgeleid en op één plek geschreven (`finalizeRun`), zodat hij niet
579
- * uit de pas kan lopen met het object ernaast.
455
+ * The **kind** of {@link WaitingOn} as a flat column, purely to query on: the store cannot
456
+ * search inside the nested object, and filtering `status: "waiting"` in memory is cheap at
457
+ * ten waiting runs and not at ten thousand. Derived and written in one place
458
+ * (`finalizeRun`) so it cannot drift from the object next to it.
580
459
  */
581
460
  waitingOnKind?: WaitingOn["on"] | null;
582
461
  /**
583
- * Index van de stap waarop de flow pauzeerde — voor elke vorm van wachten.
584
- * (Was `resumeIndex` naast `pending.stepIndex`: twee velden voor
585
- * hetzelfde feit, in twee takken geschreven en in twee takken gelezen.)
586
- *
587
- * Heette `pausedAt`, wat een tijdstip suggereerde tussen velden die dat écht zijn
588
- * (`lastStepAt`, `lastRunAt`, `deadline`, `until`). Het is een stap-index.
462
+ * Index of the step the flow paused at — for every form of waiting. A step index, not a
463
+ * timestamp.
589
464
  */
590
465
  resumeAtStep?: number | null;
591
466
  rounds?: number;
592
467
  /**
593
- * Wie deze run in zijn lijst ziet — een **index**, geen autorisatie.
594
- *
595
- * Heette `audience`, en dat woord suggereerde een rechtenlijst; hij werd ook zo gebruikt in de
596
- * losse tak van `authorizeRunScope` terwijl de interactie-tak hem juist bewust negeerde (de
597
- * denormalisatie verouderd zodra een gesprek van inbox wisselt). Autorisatie komt nu van het
598
- * onderwerp of van de scope van de definitie; dit veld is er alleen om "mijn runs" te kunnen
599
- * queryen.
468
+ * Who sees this run in their list — an **index**, not authorization. Authorization comes
469
+ * from the subject or from the definition's scope; this field only exists to query "my
470
+ * runs".
600
471
  */
601
472
  visibleTo?: string[];
602
- /** Wie deze run in beweging zette. Zie {@link StartedBy}. */
473
+ /** Who set this run in motion. See {@link StartedBy}. */
603
474
  startedBy: StartedBy;
604
475
  approvedBy?: string | null;
605
476
  result?: {