@punica/editor 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/index.bundle.esm.js +2 -1
  2. package/dist/index.bundle.esm.js.map +1 -1
  3. package/dist/index.bundle.umd.js +2 -1
  4. package/dist/index.bundle.umd.js.map +1 -1
  5. package/package.json +28 -3
  6. package/types/index.d.ts +120 -11
  7. package/types/punica.module.bootstrap.d.ts +45 -0
  8. package/types/punica.module.capability.d.ts +359 -0
  9. package/types/punica.module.extensions.api.d.ts +766 -0
  10. package/types/punica.module.extensions.settings.d.ts +106 -0
  11. package/types/punica.module.flow.agent.d.ts +75 -0
  12. package/types/punica.module.flow.api.d.ts +128 -0
  13. package/types/punica.module.flow.d.ts +490 -0
  14. package/types/punica.module.flow.engine.d.ts +228 -0
  15. package/types/punica.module.flow.mcp.d.ts +26 -0
  16. package/types/punica.module.flow.notebook.d.ts +210 -0
  17. package/types/punica.module.flow.primitives.d.ts +700 -0
  18. package/types/punica.module.flow.shell.d.ts +374 -0
  19. package/types/punica.module.kernel.ai.d.ts +462 -0
  20. package/types/punica.module.kernel.commands.d.ts +49 -0
  21. package/types/punica.module.kernel.events.d.ts +274 -0
  22. package/types/punica.module.kernel.history.d.ts +20 -0
  23. package/types/punica.module.kernel.llm.d.ts +343 -0
  24. package/types/punica.module.kernel.notifications.d.ts +64 -0
  25. package/types/punica.module.kernel.policy.d.ts +273 -0
  26. package/types/punica.module.kernel.tasks.d.ts +107 -0
  27. package/types/punica.module.kernel.timeServer.d.ts +16 -0
  28. package/types/punica.module.runtime.api.d.ts +214 -0
  29. package/types/punica.module.runtime.capabilities.d.ts +175 -0
  30. package/types/punica.module.runtime.compute.d.ts +339 -0
  31. package/types/punica.module.runtime.datasets.d.ts +234 -0
  32. package/types/punica.module.runtime.fs.d.ts +385 -0
  33. package/types/punica.module.runtime.harness.d.ts +246 -0
  34. package/types/punica.module.runtime.host.d.ts +272 -0
  35. package/types/punica.module.runtime.inference.d.ts +164 -0
  36. package/types/punica.module.runtime.lifecycle.d.ts +15 -0
  37. package/types/punica.module.runtime.llm.d.ts +470 -0
  38. package/types/punica.module.runtime.mcp.d.ts +139 -0
  39. package/types/punica.module.runtime.modelRuntimes.d.ts +90 -0
  40. package/types/punica.module.runtime.models.d.ts +254 -0
  41. package/types/punica.module.runtime.search.d.ts +59 -0
  42. package/types/punica.module.runtime.secrets.d.ts +26 -0
  43. package/types/punica.module.runtime.tasks.d.ts +27 -0
  44. package/types/punica.module.runtime.vcs.d.ts +67 -0
  45. package/types/punica.module.runtime.vectors.d.ts +74 -0
  46. package/types/punica.module.runtime.workspace.d.ts +134 -0
  47. package/types/punica.module.shell.activityBar.d.ts +42 -0
  48. package/types/punica.module.shell.components.d.ts +87 -0
  49. package/types/punica.module.shell.contentTabs.d.ts +33 -0
  50. package/types/punica.module.shell.dragDrop.d.ts +25 -0
  51. package/types/punica.module.shell.keyboardShortcuts.d.ts +38 -0
  52. package/types/punica.module.shell.layout.d.ts +106 -0
  53. package/types/punica.module.shell.markdown.d.ts +36 -0
  54. package/types/punica.module.shell.panelTabs.d.ts +71 -0
  55. package/types/punica.module.shell.profile.d.ts +278 -0
  56. package/types/punica.module.shell.statusbar.d.ts +26 -0
  57. package/types/punica.module.shell.view.d.ts +455 -0
  58. package/types/punica.module.shell.views.d.ts +150 -0
  59. package/types/punica.module.test.d.ts +562 -0
  60. package/types/punica.module.activityBar.d.ts +0 -21
  61. package/types/punica.module.commands.d.ts +0 -21
  62. package/types/punica.module.dragDrop.d.ts +0 -23
  63. package/types/punica.module.extensions.d.ts +0 -157
  64. package/types/punica.module.history.d.ts +0 -18
  65. package/types/punica.module.keyboardShortcuts.d.ts +0 -29
  66. package/types/punica.module.layout.d.ts +0 -22
  67. package/types/punica.module.statusbar.d.ts +0 -21
  68. package/types/punica.module.timeServer.d.ts +0 -14
  69. package/types/punica.module.view.d.ts +0 -8
@@ -0,0 +1,700 @@
1
+ /// <reference path="./punica.module.flow.d.ts" />
2
+ /// <reference path="./punica.module.flow.engine.d.ts" />
3
+
4
+ declare module 'punica' {
5
+ // eslint-disable-next-line @typescript-eslint/no-namespace
6
+ export namespace flow {
7
+ /**
8
+ * Trinity verification seam — every `ivyNode` / `flowBook` ref in a
9
+ * `FlowBookDocument` is checked against this predicate at validation
10
+ * time. Substrate's `validator.module.ts` plumbs it through
11
+ * `unifiedCapabilityRegistry.getCapability(...)`; unit tests inject
12
+ * a deterministic set without touching the registry.
13
+ *
14
+ * Anayasal sözleşme: CONSTITUTION § 0.1 — a flow document may name
15
+ * a capability from any of the three origins (extension /
16
+ * instruction-class / ivy-node) and the validator walks a single
17
+ * registry surface. Returning `false` for a referenced id means the
18
+ * Trinity invariant is broken; load-time rejection is the safest
19
+ * signal.
20
+ */
21
+ export type CapabilityLookup = (capabilityId: string) => boolean;
22
+
23
+ /**
24
+ * Built-in primitive node kinds carried by `FlowBookDocument` graphs.
25
+ * Substrate ships the executor surface (4.C); host extensions can
26
+ * register additional kinds via the node registry. Primitives are
27
+ * deliberately small — they exist so a domain author can compose
28
+ * branches/loops/error-handling without writing custom capabilities.
29
+ *
30
+ * - 'if' / 'else' : predicate-gated branch
31
+ * - 'forEach' : collection iteration with max-iterations cap
32
+ * - 'while' : predicate-driven loop with max-iterations cap
33
+ * - 'try'/'catch'/'finally' : structured error handling triplet
34
+ * - 'lambda' : inline pure transform (explicit alternative to
35
+ * "wrap every transform as a capability")
36
+ */
37
+ export type FlowPrimitiveKind =
38
+ | 'if'
39
+ | 'else'
40
+ | 'forEach'
41
+ | 'while'
42
+ | 'try'
43
+ | 'catch'
44
+ | 'finally'
45
+ | 'lambda';
46
+
47
+ /**
48
+ * Redaction directive per node, intersected with the capability's
49
+ * declared `dataClassification` at persistence time (4.J). Substrate
50
+ * `artifactStore` honors this when serializing inputs/outputs to the
51
+ * run record; `'all'` redacts both surfaces, `'none'` is the default.
52
+ */
53
+ export type RedactionPolicy = 'none' | 'input' | 'output' | 'all';
54
+
55
+ /**
56
+ * Checkpoint format version. The substrate ships a single literal
57
+ * (`'1'`) and a `CheckpointMigrator` surface (4.H) so future versions
58
+ * can be transformed forward without breaking persisted state.
59
+ */
60
+ export type CheckpointVersion = '1';
61
+
62
+ /**
63
+ * Migration transformer pinned to a semver pair. The substrate ships
64
+ * an empty registry; hosts inject transformers via
65
+ * `flow.migrate` (4.F). `from` and `to` follow semver (`major.minor.patch`);
66
+ * the substrate accepts any string and defers semver parsing to the
67
+ * registry to keep this surface I/O-free.
68
+ */
69
+ export interface FlowMigrationTransformer {
70
+ from: string;
71
+ to: string;
72
+ transform(doc: FlowBookDocument): FlowBookDocument;
73
+ }
74
+
75
+ /**
76
+ * Severity emitted by lint rules. Mirrors `ValidationSeverity` but
77
+ * adds `'info'` so style/hygiene rules can surface without elevating
78
+ * to a build break.
79
+ */
80
+ export type FlowLintSeverity = 'error' | 'warning' | 'info';
81
+
82
+ /**
83
+ * One finding produced by a lint rule. `path` is a dot-path into
84
+ * `FlowBookDocument` (e.g. `graph.nodes[2].ref.id`); `nodeId` is the
85
+ * resolved node id when applicable. `code` is the rule's stable
86
+ * machine identifier (e.g. `WF_UNKNOWN_CAPABILITY`).
87
+ */
88
+ export interface FlowLintIssue {
89
+ ruleId: string;
90
+ severity: FlowLintSeverity;
91
+ message: string;
92
+ path?: string;
93
+ nodeId?: NodeId;
94
+ code?: string;
95
+ }
96
+
97
+ /**
98
+ * Aggregated lint result returned by `FlowLinter.lint(...)`. `ok` is
99
+ * false when at least one `error`-severity issue is present;
100
+ * warnings and infos do not affect `ok`.
101
+ */
102
+ export interface FlowLintResult {
103
+ ok: boolean;
104
+ issues: FlowLintIssue[];
105
+ }
106
+
107
+ /**
108
+ * Context the substrate passes into each lint rule. Pure analyzer
109
+ * surface — rules MUST NOT close over global state or perform I/O;
110
+ * anything they need is on `ctx`.
111
+ *
112
+ * - `hasCapability` mirrors the validator's Trinity seam — the
113
+ * `capability-not-declared` rule uses it to flag refs to ids
114
+ * the unified registry has never heard of.
115
+ * - `getCapability` returns the full `CapabilityDefinition` so
116
+ * schema-aware rules (`schema-mismatch`,
117
+ * `idempotency-required-but-no-key`) can inspect policy + IO
118
+ * schemas without performing registry I/O.
119
+ * - `maxSubflowDepth` lets the `subflow-depth-exceeded` rule
120
+ * use a custom cap (CI may pass a tighter value than the
121
+ * runtime `MAX_SUBFLOW_DEPTH`).
122
+ */
123
+ export interface FlowLintContext {
124
+ hasCapability?: CapabilityLookup;
125
+ getCapability?: (id: string) => CapabilityDefinition | undefined;
126
+ maxSubflowDepth?: number;
127
+ }
128
+
129
+ /**
130
+ * Substrate-shipped lint aggregator (flow linter). Pure analyzer:
131
+ * `lint(spec, ctx?)` runs every registered rule against the
132
+ * `FlowBookDocument` and returns a single aggregated
133
+ * `FlowLintResult`. `register` / `unregister` let extensions
134
+ * add custom rules without forking the substrate. The default
135
+ * rule set (7 rules — `capability-not-declared`,
136
+ * `unreachable-node`, `dep-cycle`,
137
+ * `idempotency-required-but-no-key`, `schema-mismatch`,
138
+ * `infinite-loop`, `subflow-depth-exceeded`) is shipped by the
139
+ * substrate; `reset()` restores it.
140
+ */
141
+ export interface FlowLinter {
142
+ lint(spec: FlowBookDocument, ctx?: FlowLintContext): FlowLintResult;
143
+ register(rule: FlowLintRule): void;
144
+ unregister(ruleId: string): boolean;
145
+ list(): readonly string[];
146
+ reset(): void;
147
+ }
148
+
149
+ /**
150
+ * A single lint rule. Substrate ships a fixed rule set (4.E); host
151
+ * extensions can register additional rules via the linter registry.
152
+ * `check` MUST be pure (deterministic + no I/O) so the analyzer is
153
+ * usable in CI without booting the runtime.
154
+ */
155
+ export interface FlowLintRule {
156
+ id: string;
157
+ severity: FlowLintSeverity;
158
+ check(spec: FlowBookDocument, ctx: FlowLintContext): FlowLintIssue[];
159
+ }
160
+
161
+ /**
162
+ * Stable identifier for a trigger registered through a
163
+ * `TriggerProvider`.
164
+ */
165
+ export type TriggerId = string;
166
+
167
+ /**
168
+ * Trigger kind discriminator. `'manual'` is the substrate default
169
+ * (`ManualTriggerProvider` ships in 4.G). `'scheduled'`,
170
+ * `'webhook'`, and `'event'` are host territory (cron parser, HTTP
171
+ * server, kernel-event binding live outside the substrate). The
172
+ * trailing `string` widening lets hosts introduce custom kinds
173
+ * without a substrate change.
174
+ */
175
+ export type TriggerKind =
176
+ | 'manual'
177
+ | 'scheduled'
178
+ | 'webhook'
179
+ | 'event'
180
+ | (string & {});
181
+
182
+ /**
183
+ * Declarative trigger definition. `flowId` is the capability id of
184
+ * the flow to start when the trigger fires; `config` is opaque to
185
+ * the substrate and interpreted by the host provider.
186
+ */
187
+ export interface TriggerDefinition {
188
+ id: TriggerId;
189
+ kind: TriggerKind;
190
+ flowId: CapabilityId;
191
+ config?: JSONObject;
192
+ disabled?: boolean;
193
+ }
194
+
195
+ /**
196
+ * Per-firing context delivered to the registered callback. The
197
+ * substrate threads `correlationId` into the resulting run so the
198
+ * audit ring can link trigger firing → run start.
199
+ */
200
+ export interface TriggerFiringContext {
201
+ triggerId: TriggerId;
202
+ firedAtMs: number;
203
+ payload?: JSONValue;
204
+ correlationId?: string;
205
+ }
206
+
207
+ /**
208
+ * Callback handed to `TriggerProvider.register`. Substrate calls
209
+ * this when the host provider observes the trigger has fired; the
210
+ * default implementation starts a run for `trigger.flowId`.
211
+ */
212
+ export type TriggerCallback = (
213
+ ctx: TriggerFiringContext
214
+ ) => void | Promise<void>;
215
+
216
+ /**
217
+ * Handle returned by `TriggerProvider.register`. `unsubscribe` is
218
+ * idempotent — calling twice is a no-op.
219
+ */
220
+ export interface TriggerSubscription {
221
+ triggerId: TriggerId;
222
+ unsubscribe(): void;
223
+ }
224
+
225
+ /**
226
+ * Lifecycle event surfaced through `TriggerProvider.subscribe`.
227
+ * Substrate uses this to emit the `flow.trigger.fired` kernel event
228
+ * (event correlation / audit) and to drive trigger-firing observability dashboards
229
+ * (host territory). Discriminated by `type`.
230
+ */
231
+ export type TriggerEvent =
232
+ | {
233
+ type: 'registered';
234
+ triggerId: TriggerId;
235
+ kind: TriggerKind;
236
+ ts: number;
237
+ }
238
+ | { type: 'unregistered'; triggerId: TriggerId; ts: number }
239
+ | {
240
+ type: 'fired';
241
+ triggerId: TriggerId;
242
+ ts: number;
243
+ payload?: JSONValue;
244
+ correlationId?: string;
245
+ }
246
+ | {
247
+ type: 'error';
248
+ triggerId: TriggerId;
249
+ ts: number;
250
+ error: { code?: string; message: string };
251
+ };
252
+
253
+ /**
254
+ * Substrate-defined value reference for primitive nodes. Predicates,
255
+ * loop collections, and lambda inputs read from either a literal
256
+ * inline value or a dot-path against the per-run `nodeOutputs` map
257
+ * the engine populates as upstream nodes produce structured output.
258
+ *
259
+ * - `{ kind: 'literal', value }` — inline value
260
+ * - `{ kind: 'path', path: 'nodeA.foo.b' }` — dot-path into outputs
261
+ *
262
+ * Path semantics: the first segment is a node id; the remainder is
263
+ * a property chain. Missing segments resolve to `undefined`; the
264
+ * resolver never throws on a miss so primitive executors can
265
+ * surface a structured "predicate undefined" artifact instead of
266
+ * crashing the run.
267
+ */
268
+ export type PrimitiveValueRef =
269
+ | { kind: 'literal'; value: JSONValue }
270
+ | { kind: 'path'; path: string };
271
+
272
+ /**
273
+ * Result of resolving a `PrimitiveValueRef` against the per-run
274
+ * `nodeOutputs` map. Substrate uses a discriminated shape so
275
+ * primitive executors can disambiguate "resolved to undefined"
276
+ * from "the value was actually undefined".
277
+ */
278
+ export type PrimitiveValueResolution =
279
+ | { ok: true; value: JSONValue }
280
+ | { ok: false; reason: 'missing-node' | 'missing-path' | 'invalid-ref' };
281
+
282
+ /**
283
+ * `node.data` shape for the `'if'` primitive. The executor evaluates
284
+ * `predicate` (truthy/falsy semantics on the resolved value) and
285
+ * records `{ taken: 'then' | 'else' }` as the node's artifact.
286
+ * `thenBodyFlowId` / `elseBodyFlowId` reference subflows (subflow
287
+ * spawning); flow primitives only records the decision, the actual subflow dispatch
288
+ * lands when `flow.runSubflow` ships.
289
+ *
290
+ * `'else'` primitives are paired-marker nodes for graph readability
291
+ * and have no data of their own — the dispatch decision lives on
292
+ * the `'if'` node.
293
+ */
294
+ export interface IfPrimitiveData {
295
+ predicate: PrimitiveValueRef;
296
+ thenBodyFlowId?: CapabilityId;
297
+ elseBodyFlowId?: CapabilityId;
298
+ }
299
+
300
+ /**
301
+ * `node.data` shape for the `'forEach'` primitive. `collection`
302
+ * must resolve to an array (or `null`/`undefined`, treated as
303
+ * empty). `maxIterations` is mandatory — the substrate refuses
304
+ * to ship an unbounded loop primitive; the lint engine (4.E)
305
+ * upgrades absence to an `infinite-loop` finding. `itemBinding`
306
+ * is the property name an iteration body uses to read the current
307
+ * item from its subflow input (`{ [itemBinding]: item, index }`).
308
+ */
309
+ export interface ForEachPrimitiveData {
310
+ collection: PrimitiveValueRef;
311
+ bodyFlowId: CapabilityId;
312
+ maxIterations: number;
313
+ itemBinding?: string;
314
+ }
315
+
316
+ /**
317
+ * `node.data` shape for the `'while'` primitive. `predicate` is
318
+ * re-evaluated on every iteration; `maxIterations` is the
319
+ * substrate's hard safety cap. Same forward-defer note as
320
+ * `ForEachPrimitiveData`.
321
+ */
322
+ export interface WhilePrimitiveData {
323
+ predicate: PrimitiveValueRef;
324
+ bodyFlowId: CapabilityId;
325
+ maxIterations: number;
326
+ }
327
+
328
+ /**
329
+ * `node.data` shape for the `'try'` primitive. `tryBodyFlowId`
330
+ * runs first; on uncaught failure the engine dispatches
331
+ * `catchBodyFlowId` (when present) with the error structured as
332
+ * the catch body's input. `finallyBodyFlowId` always runs once,
333
+ * after either success or catch. `'catch'` and `'finally'` are
334
+ * marker primitives — their data is empty and they are present
335
+ * for graph readability + the lint engine's pairing checks.
336
+ */
337
+ export interface TryCatchFinallyPrimitiveData {
338
+ tryBodyFlowId: CapabilityId;
339
+ catchBodyFlowId?: CapabilityId;
340
+ finallyBodyFlowId?: CapabilityId;
341
+ }
342
+
343
+ /**
344
+ * `node.data` shape for the `'lambda'` primitive. `lambdaId`
345
+ * resolves through `punica.flow.primitives.lambdas` (substrate
346
+ * ships an empty registry; hosts / extensions register pure
347
+ * transforms). `input` resolves through `PrimitiveValueRef`;
348
+ * the transform's return value is recorded as the node's artifact
349
+ * and threaded into `nodeOutputs[nodeId]`.
350
+ */
351
+ export interface LambdaPrimitiveData {
352
+ lambdaId: string;
353
+ input?: PrimitiveValueRef;
354
+ }
355
+
356
+ /**
357
+ * Per-invocation context handed to a registered lambda. Substrate
358
+ * keeps this small + immutable so transforms can be deterministic;
359
+ * I/O and side-effects are explicitly out of scope (lambdas that
360
+ * need them should be modelled as capabilities instead).
361
+ */
362
+ export interface LambdaContext {
363
+ nodeId: NodeId;
364
+ attemptCorrelationId: string;
365
+ traceId: string;
366
+ }
367
+
368
+ /**
369
+ * Pure transform body. Lambdas SHOULD be deterministic (same input
370
+ * + same context → same output) and MUST NOT throw for control
371
+ * flow — surface domain errors by returning a structured payload.
372
+ */
373
+ export type LambdaFn = (
374
+ input: JSONValue,
375
+ ctx: LambdaContext
376
+ ) => JSONValue | Promise<JSONValue>;
377
+
378
+ /**
379
+ * Substrate-shipped registry for lambda transforms. Hosts /
380
+ * extensions register pure transforms; the `'lambda'` primitive
381
+ * looks them up by id at execution time. Substrate ships an empty
382
+ * registry; real transforms are host / extension territory.
383
+ */
384
+ export interface LambdaRegistry {
385
+ register(id: string, fn: LambdaFn): void;
386
+ unregister(id: string): boolean;
387
+ get(id: string): LambdaFn | undefined;
388
+ list(): readonly string[];
389
+ clear(): void;
390
+ }
391
+
392
+ /**
393
+ * Primitive-side façade exposed at `punica.flow.primitives`.
394
+ * Substrate ships the `lambdas` registry (flow primitives) and the
395
+ * pure `linter` aggregator (flow linter); future sub-steps
396
+ * (4.F migrator) extend this with additional analysis surfaces.
397
+ */
398
+ export interface PrimitivesApi {
399
+ lambdas: LambdaRegistry;
400
+ linter: FlowLinter;
401
+ migrations: MigrationRegistry;
402
+ checkpoints: CheckpointsApi;
403
+ }
404
+
405
+ /**
406
+ * Host-injected trigger surface (D7). Substrate ships the interface
407
+ * + `ManualTriggerProvider` default (4.G); real `scheduled`,
408
+ * `webhook`, and `event` providers are host territory (cron parser,
409
+ * HTTP server with HMAC verification + rate limit, kernel-event
410
+ * binding). LLM/FS provider injection pattern: substrate defines contract +
411
+ * test fixture, host injects production impl.
412
+ *
413
+ * - `register` subscribes a callback to a trigger and returns an
414
+ * idempotent handle.
415
+ * - `unregister` returns `true` when the trigger existed.
416
+ * - `list` is a snapshot of currently registered triggers.
417
+ * - `subscribe` is the lifecycle observer (registered / fired /
418
+ * error); the returned function unsubscribes.
419
+ */
420
+ export interface TriggerProvider {
421
+ register(
422
+ trigger: TriggerDefinition,
423
+ callback: TriggerCallback
424
+ ): TriggerSubscription;
425
+ unregister(triggerId: TriggerId): boolean;
426
+ list(): readonly TriggerDefinition[];
427
+ subscribe(listener: (event: TriggerEvent) => void): () => void;
428
+ }
429
+
430
+ /**
431
+ * Substrate-shipped checkpoint format version (run status / checkpoints). The
432
+ * substrate ships a single literal (`'1'`); future versions are
433
+ * introduced by registering a `CheckpointMigrator` that walks
434
+ * from the prior version forward. The literal is pinned in
435
+ * `flow.CheckpointVersion` so callers cannot drift.
436
+ */
437
+ export interface CheckpointMigrator {
438
+ from: CheckpointVersion | string;
439
+ to: CheckpointVersion | string;
440
+ migrate(checkpoint: JSONValue): JSONValue;
441
+ }
442
+
443
+ /**
444
+ * Age policy for resume-time checkpoint reads (run status / checkpoints,
445
+ * F26). Substrate honors `maxAgeMs` — a checkpoint older than
446
+ * the cap is rejected at resume and the run restarts from
447
+ * scratch (substrate refuses to silently replay stale state).
448
+ * Hosts that want unbounded retention pass `undefined` (the
449
+ * default) — substrate then trusts the host's storage policy.
450
+ */
451
+ export interface CheckpointAgePolicy {
452
+ maxAgeMs?: number;
453
+ }
454
+
455
+ /**
456
+ * Substrate-shipped registry for `CheckpointMigrator` entries.
457
+ * Same shape as `MigrationRegistry` (4.F) but operates on
458
+ * checkpoint payloads rather than FlowBookDocuments. Substrate
459
+ * ships an EMPTY registry — hosts inject migrators when the
460
+ * checkpoint version moves forward.
461
+ */
462
+ export interface CheckpointMigratorRegistry {
463
+ register(migrator: CheckpointMigrator): void;
464
+ unregister(from: string, to: string): boolean;
465
+ find(from: string, to: string): CheckpointMigrator | undefined;
466
+ list(): readonly CheckpointMigrator[];
467
+ clear(): void;
468
+ }
469
+
470
+ /**
471
+ * Façade exposed at `punica.flow.primitives.checkpoints`. Bundles
472
+ * the migrator registry + the substrate-shipped pure age helper
473
+ * (`isFresh(savedAtMs, policy, nowMs?)`).
474
+ */
475
+ export interface CheckpointsApi {
476
+ migrators: CheckpointMigratorRegistry;
477
+ isFresh(
478
+ savedAtMs: number,
479
+ policy?: CheckpointAgePolicy,
480
+ nowMs?: number
481
+ ): boolean;
482
+ }
483
+
484
+ /**
485
+ * Host-swappable triggers façade (flow triggers). Substrate ships
486
+ * `ManualTriggerProvider` as the default; hosts inject a custom
487
+ * provider (scheduled / webhook / event) via `setProvider`. The
488
+ * `manager` field is always the currently-active provider —
489
+ * mirrors the FS provider injection pattern: substrate
490
+ * defines the contract + a substrate-default fixture, host owns
491
+ * the real implementation.
492
+ */
493
+ export interface TriggersApi {
494
+ manager: TriggerProvider;
495
+ /**
496
+ * Swap the active provider. Substrate clears every subscription
497
+ * routed through the previous provider before handing control
498
+ * over so the host never inherits stale callbacks.
499
+ */
500
+ setProvider(provider: TriggerProvider): void;
501
+ /**
502
+ * Restore the substrate default (`ManualTriggerProvider`).
503
+ * Used by tests + by hosts that want to revert to manual after
504
+ * disabling a scheduled provider at runtime.
505
+ */
506
+ resetProvider(): void;
507
+ }
508
+
509
+ /**
510
+ * Substrate-shipped triggers façade exposed at
511
+ * `punica.flow.triggers`. flow triggers ships `ManualTriggerProvider`
512
+ * as the substrate default; hosts inject scheduled / webhook /
513
+ * event impls.
514
+ */
515
+ export const triggers: TriggersApi;
516
+
517
+ /**
518
+ * Substrate-shipped primitives façade. Exposed at
519
+ * `punica.flow.primitives`. Surfaces the lambda registry +
520
+ * (subflow spawning) the recursion-guard cap; future sub-steps
521
+ * (4.E linter, 4.F migrator) extend this with additional
522
+ * pure-analysis surfaces.
523
+ */
524
+ export const primitives: PrimitivesApi;
525
+
526
+ /**
527
+ * Policy for handling a `FlowBookDocument` whose `version` differs
528
+ * from the runtime's expected version (flow migration).
529
+ *
530
+ * - `'auto-migrate'` — attempt to apply registered transformers
531
+ * in sequence; if no chain is found, fall back to `'reject'`.
532
+ * - `'warn'` — emit a warning but execute the spec as-is.
533
+ * - `'reject'` — refuse to load the spec. Substrate default.
534
+ *
535
+ * Substrate's pragmatic stance: silent acceptance of mismatched
536
+ * versions is the worst option (a flow that "works" on a stale
537
+ * substrate may silently drop fields). The host picks one of the
538
+ * three explicitly; substrate ships no implicit fallback.
539
+ */
540
+ export type VersionMismatchPolicy = 'auto-migrate' | 'warn' | 'reject';
541
+
542
+ /**
543
+ * Outcome of a `flow.migrate` invocation. Discriminated by `ok`:
544
+ * a successful migration returns the transformed document + the
545
+ * chain of transformer ids that ran; a failed migration carries
546
+ * a stable `reason` code so callers can branch programmatically.
547
+ *
548
+ * - `'no-path'` — no transformer chain reaches the target.
549
+ * - `'transformer-threw'` — a transformer threw mid-chain. The
550
+ * document is left at the last successfully-migrated state.
551
+ * - `'invalid-result'` — a transformer returned a document that
552
+ * failed substrate validation. Same partial-progress semantics
553
+ * as `'transformer-threw'`.
554
+ * - `'no-migrate-policy'` — the caller selected `'reject'` and
555
+ * the input version did not match the target.
556
+ */
557
+ export type MigrationFailureReason =
558
+ | 'no-path'
559
+ | 'transformer-threw'
560
+ | 'invalid-result'
561
+ | 'no-migrate-policy';
562
+
563
+ export type MigrationResult =
564
+ | {
565
+ ok: true;
566
+ document: FlowBookDocument;
567
+ appliedTransformers: readonly string[];
568
+ fromVersion: string;
569
+ toVersion: string;
570
+ }
571
+ | {
572
+ ok: false;
573
+ reason: MigrationFailureReason;
574
+ message: string;
575
+ partialDocument?: FlowBookDocument;
576
+ appliedTransformers: readonly string[];
577
+ };
578
+
579
+ /**
580
+ * Input payload accepted by the substrate `flow.migrate`
581
+ * capability + the `MigrationRegistry.migrate` orchestrator
582
+ * (flow migration). `targetVersion` is the version the caller wants
583
+ * to land at; substrate looks up a transformer chain from
584
+ * `document.version` to `targetVersion`. When `policy` is
585
+ * `'auto-migrate'` and the chain is empty (spec already at
586
+ * target), substrate returns `{ ok: true, appliedTransformers: [] }`.
587
+ */
588
+ export interface MigrationInvocation {
589
+ document: FlowBookDocument;
590
+ targetVersion: string;
591
+ policy?: VersionMismatchPolicy;
592
+ }
593
+
594
+ /**
595
+ * Substrate-shipped registry for `FlowMigrationTransformer`
596
+ * entries. The substrate ships an EMPTY registry — real
597
+ * transformers are host territory (matching the
598
+ * `LambdaRegistry` + `TriggerProvider` pattern). `find(from, to)`
599
+ * returns the registered chain (single-hop or composite) the
600
+ * substrate planner can apply; `migrate(input)` orchestrates
601
+ * the full sequence with policy-driven mismatch handling.
602
+ */
603
+ export interface MigrationRegistry {
604
+ register(transformer: FlowMigrationTransformer): void;
605
+ unregister(from: string, to: string): boolean;
606
+ find(from: string, to: string): FlowMigrationTransformer | undefined;
607
+ list(): readonly FlowMigrationTransformer[];
608
+ clear(): void;
609
+ /**
610
+ * Apply a transformer chain to `input.document` until it
611
+ * reaches `input.targetVersion`. Substrate honors the
612
+ * `policy` argument: `'reject'` refuses any mismatch,
613
+ * `'warn'` returns the original doc unchanged with a
614
+ * note in the failure path, `'auto-migrate'` performs the
615
+ * full chain. Pure relative to the registry's transformer
616
+ * functions — no kernel access.
617
+ */
618
+ migrate(input: MigrationInvocation): MigrationResult;
619
+ }
620
+
621
+ /**
622
+ * Substrate hard cap on subflow recursion depth (subflow spawning).
623
+ * `flow.runSubflow` rejects any invocation whose `parentDepth + 1`
624
+ * would exceed this value with a `SUBFLOW_DEPTH_EXCEEDED` error.
625
+ * The 4.E lint engine surfaces a `subflow-depth-exceeded` finding
626
+ * for graphs whose statically-derivable depth pierces the cap.
627
+ *
628
+ * Substrate's anayasal stance: a runaway flow that spawns
629
+ * subflows in a cycle would silently exhaust the host's stack /
630
+ * approval queue; a substrate cap is the safest default. Hosts
631
+ * cannot lift this cap — the substrate ships the constant
632
+ * because the contract is "substrate, not host, owns the safety
633
+ * floor" (fail-closed ethos).
634
+ */
635
+ export const MAX_SUBFLOW_DEPTH: 8;
636
+
637
+ /**
638
+ * Substrate error code for a depth-cap violation. Surfaced both
639
+ * by the runtime `flow.runSubflow` capability and by the 4.E
640
+ * lint engine.
641
+ */
642
+ export const SUBFLOW_DEPTH_EXCEEDED_CODE: 'SUBFLOW_DEPTH_EXCEEDED';
643
+
644
+ /**
645
+ * Input payload accepted by the `flow.runSubflow` capability
646
+ * (subflow spawning). The substrate spawns a fresh `RunRecord` for the
647
+ * subflow, threads the parent's workspace + depth, and inherits
648
+ * the parent's approval scope (D5: `'once'` is per-workspace + per
649
+ * session, so a parent's `'once'` approval is naturally honored
650
+ * by the child as long as `workspaceId` matches — F33 dedup).
651
+ *
652
+ * - `spec` — required `FlowBookDocument` to run.
653
+ * - `workspaceId` — inherited from the parent run; the
654
+ * substrate refuses to spawn a subflow into
655
+ * a different workspace by default.
656
+ * - `input` — optional structured input threaded into
657
+ * the child's `flow-input` node.
658
+ * - `parentRunId` — id of the spawning run; recorded on the
659
+ * child for audit (event correlation / audit timeline
660
+ * stitching).
661
+ * - `parentTraceId` — trace correlation id propagated so
662
+ * parent + child appear on the same audit
663
+ * timeline.
664
+ * - `parentDepth` — current depth of the spawning run
665
+ * (`0` for top-level). Substrate rejects
666
+ * any invocation with
667
+ * `parentDepth + 1 > MAX_SUBFLOW_DEPTH`.
668
+ * - `filePathOrUri` — optional source ref forwarded for
669
+ * notebookCell-backed flows.
670
+ */
671
+ export interface SubflowInvocation {
672
+ spec: FlowBookDocument;
673
+ workspaceId?: string;
674
+ input?: JSONValue;
675
+ parentRunId?: string;
676
+ parentTraceId?: string;
677
+ parentDepth?: number;
678
+ filePathOrUri?: string;
679
+ }
680
+
681
+ /**
682
+ * Result returned by the `flow.runSubflow` capability after the
683
+ * child run reaches a terminal state. Substrate always returns
684
+ * the structured shape — exceptions are reserved for synchronous
685
+ * pre-flight failures (`SUBFLOW_DEPTH_EXCEEDED`, missing spec,
686
+ * missing engine). Run-time failures surface as
687
+ * `status: 'FAILED'` + `error`.
688
+ */
689
+ export interface SubflowResult {
690
+ runId: string;
691
+ parentRunId?: string;
692
+ depth: number;
693
+ status: engine.RunStatus;
694
+ output?: JSONValue;
695
+ error?: { message: string; code?: string; nodeId?: string };
696
+ startedAtMs?: number;
697
+ endedAtMs?: number;
698
+ }
699
+ }
700
+ }