@sublang/playbook 15.1.0 → 17.0.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.
- package/README.md +2 -0
- package/docs/cli.md +36 -18
- package/docs/configuration.md +7 -5
- package/docs/embedding.md +28 -7
- package/package.json +4 -4
- package/reference/sdlc/branch.playbook/branch.fsm.d.ts +63 -33
- package/reference/sdlc/branch.playbook/branch.fsm.js +190 -108
- package/reference/sdlc/branch.playbook/branch.fsm.ts +269 -147
- package/reference/sdlc/branch.playbook/branch.gears.md +7 -17
- package/reference/sdlc/branch.playbook/branch.playbook.d.ts +12 -16
- package/reference/sdlc/branch.playbook/branch.playbook.js +112 -101
- package/reference/sdlc/branch.playbook/branch.playbook.ts +128 -171
- package/reference/sdlc/branch.playbook/branch.registry.d.ts +3 -2
- package/reference/sdlc/branch.playbook/branch.registry.ts +6 -2
- package/reference/sdlc/captain.md +19 -10
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +6 -2
- package/reference/sdlc/captain.playbook/captain.fsm.js +19 -7
- package/reference/sdlc/captain.playbook/captain.fsm.ts +25 -10
- package/reference/sdlc/captain.playbook/captain.gears.md +16 -8
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +1 -1
- package/reference/sdlc/captain.playbook/captain.playbook.js +3 -2
- package/reference/sdlc/captain.playbook/captain.playbook.ts +4 -3
- package/reference/sdlc/code.playbook/bin/interactive-session.js +14 -1
- package/reference/sdlc/code.playbook/bin/portable-codec.js +3 -0
- package/reference/sdlc/code.playbook/bin/repository-effects.js +1 -0
- package/reference/sdlc/code.playbook/bin/run.js +128 -85
- package/reference/sdlc/code.playbook/bin/session-host.js +40 -8
- package/reference/sdlc/code.playbook/bin/session-store.js +162 -34
- package/reference/sdlc/code.playbook/code.fsm.d.ts +146 -93
- package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +8 -8
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +13 -13
- package/reference/sdlc/code.playbook/code.fsm.js +609 -649
- package/reference/sdlc/code.playbook/code.fsm.ts +890 -821
- package/reference/sdlc/code.playbook/code.gears.md +39 -29
- package/reference/sdlc/code.playbook/code.playbook.d.ts +13 -16
- package/reference/sdlc/code.playbook/code.playbook.js +166 -147
- package/reference/sdlc/code.playbook/code.playbook.ts +180 -229
- package/reference/sdlc/code.playbook/code.registry.d.ts +3 -2
- package/reference/sdlc/code.playbook/code.registry.ts +6 -2
- package/reference/sdlc/code.playbook/host-capabilities.d.ts +3 -0
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +74 -2
- package/reference/sdlc/code.playbook/playbook-captain.js +1548 -468
- package/reference/sdlc/code.playbook/playbook-captain.ts +1993 -573
- package/reference/sdlc/code.playbook/session-host.d.ts +4 -1
- package/reference/sdlc/code.playbook/session-store.d.ts +17 -0
- package/reference/sdlc/code.playbook/session-store.js +1 -0
- package/reference/sdlc/decide.md +1 -0
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +273 -157
- package/reference/sdlc/decide.playbook/decide.fsm.js +765 -732
- package/reference/sdlc/decide.playbook/decide.fsm.ts +1167 -945
- package/reference/sdlc/decide.playbook/decide.gears.md +28 -21
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -59
- package/reference/sdlc/decide.playbook/decide.playbook.js +155 -3696
- package/reference/sdlc/decide.playbook/decide.playbook.ts +186 -5244
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +8 -4
- package/reference/sdlc/decide.playbook/decide.registry.js +2 -2
- package/reference/sdlc/decide.playbook/decide.registry.ts +13 -6
- package/reference/sdlc/dev.playbook/dev.fsm.d.ts +116 -134
- package/reference/sdlc/dev.playbook/dev.fsm.js +517 -575
- package/reference/sdlc/dev.playbook/dev.fsm.ts +667 -787
- package/reference/sdlc/dev.playbook/dev.gears.md +52 -54
- package/reference/sdlc/dev.playbook/dev.playbook.d.ts +13 -10
- package/reference/sdlc/dev.playbook/dev.playbook.js +128 -120
- package/reference/sdlc/dev.playbook/dev.playbook.ts +143 -193
- package/reference/sdlc/dev.playbook/dev.registry.d.ts +3 -2
- package/reference/sdlc/dev.playbook/dev.registry.ts +6 -2
- package/reference/sdlc/pr.playbook/pr.fsm.d.ts +95 -88
- package/reference/sdlc/pr.playbook/pr.fsm.js +461 -518
- package/reference/sdlc/pr.playbook/pr.fsm.ts +533 -663
- package/reference/sdlc/pr.playbook/pr.gears.md +47 -63
- package/reference/sdlc/pr.playbook/pr.playbook.d.ts +13 -23
- package/reference/sdlc/pr.playbook/pr.playbook.js +118 -112
- package/reference/sdlc/pr.playbook/pr.playbook.ts +136 -190
- package/reference/sdlc/pr.playbook/pr.registry.d.ts +3 -2
- package/reference/sdlc/pr.playbook/pr.registry.ts +4 -2
- package/reference/sdlc/review.md +3 -3
- package/reference/sdlc/review.playbook/review.fsm.d.ts +150 -116
- package/reference/sdlc/review.playbook/review.fsm.js +479 -550
- package/reference/sdlc/review.playbook/review.fsm.ts +717 -662
- package/reference/sdlc/review.playbook/review.gears.md +32 -29
- package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -12
- package/reference/sdlc/review.playbook/review.playbook.js +180 -155
- package/reference/sdlc/review.playbook/review.playbook.ts +190 -230
- package/reference/sdlc/review.playbook/review.registry.d.ts +6 -5
- package/reference/sdlc/review.playbook/review.registry.js +3 -3
- package/reference/sdlc/review.playbook/review.registry.ts +9 -5
- package/slc/gears2fsm.md +77 -8
- package/slc/link.md +127 -60
- package/slc/materialize-link.mjs +51 -13
- package/slc/optimize.md +4 -1
- package/slc/prefix-prompts.mjs +29 -28
- package/slc/prefix.md +27 -24
- package/slc/slc.pin-inputs.json +11 -2
- package/slc/text2gears.md +71 -11
- package/src/runtime.d.ts +46 -2
- package/src/runtime.ts +42 -2
- package/src/xstate-playbook-runtime.d.ts +63 -23
- package/src/xstate-playbook-runtime.js +1637 -475
- package/src/xstate-playbook-runtime.ts +2105 -532
- package/src/xstate-runtime.d.ts +3 -4
- package/src/xstate-runtime.js +52 -0
- package/src/xstate-runtime.ts +59 -4
package/slc/gears2fsm.md
CHANGED
|
@@ -141,9 +141,11 @@ generic Captain forms, wire `<boss-intent>` from `bossIntent`,
|
|
|
141
141
|
`remainingPlan`, and `<completed-call-results>` from
|
|
142
142
|
`completedCallResults`. Other non-identity placeholders shall retain the
|
|
143
143
|
semantic typed field established by Source (for example `<#>` from
|
|
144
|
-
`irNumber`)
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
`irNumber`); a created-commit or labelled-section placeholder binds as
|
|
145
|
+
[Context and prompts](#context-and-prompts) states. Leaving an ordinary
|
|
146
|
+
runtime-value placeholder literal, replacing it with an empty default because
|
|
147
|
+
its field was omitted, or making the linker recover it from untyped context is
|
|
148
|
+
malformed.
|
|
147
149
|
The corresponding `invoke.input` object shall include that field beside `prompt`; storing it only in machine context does not satisfy the actor-input contract.
|
|
148
150
|
When Source declares a placeholder as the current identity of a local acting
|
|
149
151
|
role, preserve the placeholder literal in the FSM prompt and do not add any
|
|
@@ -241,15 +243,16 @@ teardown event. The completion rule of
|
|
|
241
243
|
output clause binds only where Source declares a terminal result, which a
|
|
242
244
|
controller Source does not.
|
|
243
245
|
The controller decision state's direct-Captain result contract discriminates
|
|
244
|
-
the closed action set of DR-029 as extended by DR-038. Its guard discriminants
|
|
246
|
+
the closed action set of DR-029 as extended by DR-038 and DR-069. Its guard discriminants
|
|
245
247
|
are a stable compiler contract, not names the compiler may invent — `respond`, `resume`,
|
|
246
|
-
`start`, `switch`, `dismiss`, `deliver`, and `runtime` — with each guard's
|
|
248
|
+
`start`, `switch`, `dismiss`, `deliver`, and `runtime`, plus `recover` when Source declares recovery preparation — with each guard's
|
|
247
249
|
required payload fields:
|
|
248
250
|
|
|
249
251
|
- `respond` requires `text`;
|
|
250
252
|
- `resume` requires `playbookId` and carries no `input`;
|
|
251
253
|
- `start` and `switch` each require `playbookId` and `input`;
|
|
252
254
|
- `runtime` requires `actionId`;
|
|
255
|
+
- `recover`, when declared, requires no payload and selects host-owned preparation followed by runtime-validated continuation;
|
|
253
256
|
- `dismiss` and `deliver` require none — a `deliver` result in particular
|
|
254
257
|
carries no text payload: the host is authoritative for the delivered text,
|
|
255
258
|
so the contract declares no field for it.
|
|
@@ -610,6 +613,37 @@ or remove remaining entries as evidence arrives, but it cannot grow or retain
|
|
|
610
613
|
the same-length plan indefinitely; the initial finite array therefore bounds
|
|
611
614
|
the number of sequential child calls without an arbitrary runtime call limit.
|
|
612
615
|
|
|
616
|
+
A placeholder that reads the commit an earlier call created — `<code-commit>`,
|
|
617
|
+
`<decide-commit>` — binds to a typed context field named by its canonical
|
|
618
|
+
mapping, assigned from that call's accepted `latestCommit`, the effect-owned
|
|
619
|
+
property the runtime fills from the repository receipt
|
|
620
|
+
([text2gears](text2gears.md#result-contracts)); the actor input carries the
|
|
621
|
+
field beside the prompt like any other relayed value.
|
|
622
|
+
A placeholder the GEARS defines as a labelled section of another relayed
|
|
623
|
+
text binds to a typed context field named by its canonical mapping. The
|
|
624
|
+
definition names the label that opens the section and the labels that end it —
|
|
625
|
+
`<original-intent>` as the `Original intent:` section of the caller's request,
|
|
626
|
+
which runs to the `Review scope:` line or to the end of the request. The
|
|
627
|
+
machine derives the field deterministically in the entry action or transition
|
|
628
|
+
that stores the text and again in every action that replaces it, such as a
|
|
629
|
+
fresh entry directive or an interrupt that restarts with new text:
|
|
630
|
+
|
|
631
|
+
- the text as read is the text itself, except that where every non-blank line
|
|
632
|
+
begins with `>`, each line is read without that marker and one optional space
|
|
633
|
+
after it, the literal quote layer a quoted relay adds;
|
|
634
|
+
- the section is the lines of the text as read from the first line that
|
|
635
|
+
begins with the opening label, the label removed, through the line before the
|
|
636
|
+
first later line that begins with an ending label, or through the last line,
|
|
637
|
+
with the result trimmed; a line that merely looks labelled, such as `Note:`
|
|
638
|
+
or `Constraints:`, stays in the section;
|
|
639
|
+
- where no line begins with the opening label, or the section is empty once
|
|
640
|
+
trimmed — its label directly followed by an ending label or by the end of
|
|
641
|
+
the text — the field is the whole text as read, trimmed, so the request is
|
|
642
|
+
never lost.
|
|
643
|
+
|
|
644
|
+
The derived field is ordinary context that actor inputs relay, never a player
|
|
645
|
+
or judge output.
|
|
646
|
+
|
|
613
647
|
Prompts shall pass only the **specific extracted fields** the player needs.
|
|
614
648
|
The compiler shall not dump `JSON.stringify(lastResult)` or any opaque blob: it leaks internal `guard` strings, wastes tokens, and confuses the LLM.
|
|
615
649
|
|
|
@@ -663,6 +697,26 @@ The compiler shall update or reset those source-owned facts only at their actual
|
|
|
663
697
|
Transitions shall be self-driving when source items define the next obligation.
|
|
664
698
|
Routing to an idle hub is for recovery, unrecoverable Boss input, or one-shot entry events — not the happy path.
|
|
665
699
|
|
|
700
|
+
Where an artifact-schema-3 delegated-player state's outcomes are governed by the
|
|
701
|
+
linked runtime ([link.md "Captain adjudication"](link.md#captain-adjudication)),
|
|
702
|
+
every accepted `onDone` arm — each arm that routes a declared outcome, not the
|
|
703
|
+
malformed-output fallback — shall carry, first among its actions, the
|
|
704
|
+
root-machine action
|
|
705
|
+
`{ type: 'playbook.acceptedOutcome', params: { source: '<stateId>', target: '<target stateId>', acceptedOutcome: '<guard>' } }`,
|
|
706
|
+
with the setup's `actions` declaring `'playbook.acceptedOutcome'` as a no-op
|
|
707
|
+
that types those three string params.
|
|
708
|
+
`target` names the state the next public snapshot shows for the arm: the arm's
|
|
709
|
+
own target, or the parallel parent's `onDone` target where the arm's target is a
|
|
710
|
+
region's final leaf that completes that parent, because the machine leaves that
|
|
711
|
+
leaf before the snapshot; an arm that completes the join only when every
|
|
712
|
+
sibling region is already final therefore splits into two arms guarded on that
|
|
713
|
+
condition, each naming the state it reaches.
|
|
714
|
+
The linked runtime retains the marker until the next public snapshot confirms
|
|
715
|
+
`source` in the prior snapshot and `target` in the new one, and only then
|
|
716
|
+
publishes the outcome's accepted trace and `→ <acceptedOutcome>` status; an arm
|
|
717
|
+
without the marker accepts its outcome silently, and the host counts none of the
|
|
718
|
+
work it saved.
|
|
719
|
+
|
|
666
720
|
### Auto-advance on approval
|
|
667
721
|
|
|
668
722
|
A review/approval state's success outcome shall **target the next workflow step**, not idle back to a hub.
|
|
@@ -726,8 +780,7 @@ current event, not solely from the context that action will populate.
|
|
|
726
780
|
For an omitted event value, use an existing context seed only where Source
|
|
727
781
|
permits it; do not manufacture a required constructor value to satisfy a
|
|
728
782
|
context-only entry guard. The linked runtime sends the entry event normally;
|
|
729
|
-
|
|
730
|
-
copy fresh text into context before the guard.
|
|
783
|
+
entry metadata does not copy fresh text into context before the guard.
|
|
731
784
|
An entry event's copy action shall not clear per-run parameters the event omits: an absent optional field falls back to the existing (input-seeded) context value.
|
|
732
785
|
The two surfaces shall not be collapsed. `BOSS_INTERRUPT` always carries its
|
|
733
786
|
target id and may additionally carry typed Boss-supplied fields such as an
|
|
@@ -750,7 +803,7 @@ Boss-reply suspension, because its hub already receives every Boss turn and a
|
|
|
750
803
|
clarifying question to Boss is a `respond` selection over the closed action
|
|
751
804
|
set. The rule below is therefore universal over workflow states and silent
|
|
752
805
|
about that class; in particular, adding `needsBossReply` to the controller
|
|
753
|
-
decision state would add an
|
|
806
|
+
decision state would add an unauthorized outcome to its closed controller contract
|
|
754
807
|
whose guard discriminants [Setup](#setup) fixes, and is nonconformant.
|
|
755
808
|
There is no source-level opt-in annotation and no `needsBossReply` result metadata in GEARS output.
|
|
756
809
|
The FSM compiler shall preserve the GEARS blockquote as the state's domain `prompt` body and shall not inject any Boss-question instruction into `invoke.input.prompt`.
|
|
@@ -811,6 +864,12 @@ Where several questions are pending, the classifier prompt and event shall
|
|
|
811
864
|
require `questionId` and shall reject an omitted or unknown id without moving
|
|
812
865
|
the FSM.
|
|
813
866
|
|
|
867
|
+
Every exit from a Captain- or player-invoking state other than into its own
|
|
868
|
+
Boss-reply wait — an accepted outcome, the malformed-output fallback, an actor
|
|
869
|
+
error — and every non-reply exit from a wait shall clear that state's pending
|
|
870
|
+
question and reply context, so a call that fails after resuming leaves no
|
|
871
|
+
stale question for the next turn's classifier to offer.
|
|
872
|
+
|
|
814
873
|
The scalar `awaitBossReply` state and every local branch wait are quiescent for
|
|
815
874
|
the runtime drive boundary.
|
|
816
875
|
They shall allow a fresh root entry event or interrupt to abandon the relevant
|
|
@@ -882,6 +941,16 @@ Where Source declares a JSON-safe terminal result, the setup types shall
|
|
|
882
941
|
declare that output and the root machine shall derive it from typed context
|
|
883
942
|
through XState's machine `output` function. A final-state transition alone does
|
|
884
943
|
not satisfy a declared output contract.
|
|
944
|
+
Where the selected pipeline supplies the
|
|
945
|
+
[workflow contracts](workflow-contracts.json) catalog and the compiled Source's
|
|
946
|
+
basename is one of its `literalTargetBindings`, the declared terminal output
|
|
947
|
+
shall be exactly that builtin's public interface — its variants, `status`
|
|
948
|
+
constants, property names, and requiredness — derived from typed context,
|
|
949
|
+
because callers compiled against the catalog consume it by those names; an
|
|
950
|
+
authored outcome the interface cannot express is an inconsistency between the
|
|
951
|
+
Source and the catalog, reported as an incompatible compiler input under
|
|
952
|
+
[Nested playbook calls](#nested-playbook-calls) rather than expressed by an
|
|
953
|
+
invented or renamed outcome.
|
|
885
954
|
Fields that Source requires in every terminal output shall be required in the
|
|
886
955
|
TypeScript output type. In particular, a declared `{ response }` result shall
|
|
887
956
|
compile as `{ response: string }`, not `{ response?: string }`; reaching the
|
package/slc/link.md
CHANGED
|
@@ -38,15 +38,20 @@ The link compiler shall not modify the FSM artifact and shall not re-derive Capt
|
|
|
38
38
|
|
|
39
39
|
## Optional deterministic materialization
|
|
40
40
|
|
|
41
|
-
For an ordinary
|
|
42
|
-
|
|
41
|
+
For an ordinary workflow using only `player` and `script` actors — flat, or
|
|
42
|
+
with root parallel groups of the [Parallel groups](gears2fsm.md#parallel-groups)
|
|
43
|
+
shape — the supported prompt profile below, shared remaining strategies, and primitive configured options, the linker may
|
|
43
44
|
use the adjacent `materialize-link.mjs` tool to emit the thin module.
|
|
44
45
|
The complete definition below remains binding; the tool replaces repetitive
|
|
45
46
|
module generation, not semantic analysis or emitted conformance verification.
|
|
46
47
|
Read the actual FSM and supply every erased or authored contract exactly.
|
|
47
48
|
Do not use `flat-defaults` or `flat-quoted-relays` when another custom composer, classifier, required-field
|
|
48
49
|
extractor, session-derived input mapping, controller strategy, nested call,
|
|
49
|
-
|
|
50
|
+
or compound state other than such a parallel group is needed.
|
|
51
|
+
Despite their names, every profile accepts those parallel groups: the tool
|
|
52
|
+
takes each region working leaf's role and label under its stable state id
|
|
53
|
+
like any other player state, declares nothing further, and leaves the
|
|
54
|
+
compiled shape to the factory preflight, which rejects any other form.
|
|
50
55
|
|
|
51
56
|
Invoke the tool with the actual definition directory, source FSM, and declared
|
|
52
57
|
target; supply a JSON descriptor on standard input:
|
|
@@ -60,7 +65,7 @@ node "<definition-directory>/materialize-link.mjs" --fsm "<source.fsm.ts>" --out
|
|
|
60
65
|
"label": "EXAMPLE",
|
|
61
66
|
"options": {},
|
|
62
67
|
"inputMapping": {},
|
|
63
|
-
"entryEvent": { "type": "BOSS_TASK", "textField": "bossIntent"
|
|
68
|
+
"entryEvent": { "type": "BOSS_TASK", "textField": "bossIntent" },
|
|
64
69
|
"bossEvents": [],
|
|
65
70
|
"outcomeAuthority": {
|
|
66
71
|
"governedPlayerStates": {
|
|
@@ -101,6 +106,12 @@ session-derived input values are outside this profile; do not widen their
|
|
|
101
106
|
contracts to an unconstrained primitive.
|
|
102
107
|
The tool adds optional string `cwd` for script-bearing machines; it does not
|
|
103
108
|
put `cwd` in FSM input unless the descriptor explicitly maps it.
|
|
109
|
+
When the linked module is part of a package that compiles and ships
|
|
110
|
+
JavaScript siblings, supply the optional `fsmSpecifier` — the `.js` sibling
|
|
111
|
+
the build emits for the source FSM, such as `./code.fsm.js`, in the same
|
|
112
|
+
directory and with the same basename — so the emitted import satisfies the
|
|
113
|
+
NodeNext rule under Output; omit it for a source-only host, where the tool
|
|
114
|
+
derives the specifier from the `--fsm` path.
|
|
104
115
|
An explicit `entryEvent: null` selects the shared classifier only where this
|
|
105
116
|
definition permits no deterministic entry; it does not relax entry rules.
|
|
106
117
|
`bossEvents` retains the exact additional erased event fields, source ownership,
|
|
@@ -125,8 +136,9 @@ correct the identified problem before treating linking as successful.
|
|
|
125
136
|
|
|
126
137
|
### Experimental labelled-string and nested-call profile
|
|
127
138
|
|
|
128
|
-
`flat-labelled-relays` is an unmeasured candidate for flat
|
|
129
|
-
|
|
139
|
+
`flat-labelled-relays` is an unmeasured candidate for machines with flat
|
|
140
|
+
root states or root parallel groups of that shape, whose delegated players,
|
|
141
|
+
scripts, and nested `playbook` calls it supports. It
|
|
130
142
|
requires the installed shared `composePlayerContinuation` API. It leaves
|
|
131
143
|
nested input composition, child targets, result guards, recovery, and terminal
|
|
132
144
|
semantics in the unchanged FSM; the shared factory provides the nested bridge.
|
|
@@ -154,8 +166,8 @@ source tokens. Undeclared empty relay lines retain their authored text.
|
|
|
154
166
|
The emitted verification composer has the same identity and optional third
|
|
155
167
|
resume arguments as the runtime; the shared helper owns fresh/resumed Q&A.
|
|
156
168
|
Structured rendering, custom classifiers/extractors/controllers, direct
|
|
157
|
-
Captain actors, compound
|
|
158
|
-
options remain unsupported. Source-derived metadata and all existing
|
|
169
|
+
Captain actors, compound topology other than such a parallel group, and
|
|
170
|
+
constrained/nonprimitive options remain unsupported. Source-derived metadata and all existing
|
|
159
171
|
conformance checks remain mandatory. This profile changes no runtime bridge,
|
|
160
172
|
workflow semantics, or measured performance claim.
|
|
161
173
|
|
|
@@ -184,6 +196,8 @@ interface PlaybookRuntime {
|
|
|
184
196
|
handleBossInput(turn: {
|
|
185
197
|
text: string;
|
|
186
198
|
signal: AbortSignal;
|
|
199
|
+
/** Called synchronously just before accepting the event, at most once. */
|
|
200
|
+
onAccepted?: () => void;
|
|
187
201
|
}): Promise<PlaybookRunResult>;
|
|
188
202
|
resumePlaybookCall(input: {
|
|
189
203
|
callId: string;
|
|
@@ -354,6 +368,7 @@ interface PlaybookEffectBoundary {
|
|
|
354
368
|
readonly baseline: PlaybookRepositoryObservation;
|
|
355
369
|
readonly after?: PlaybookRepositoryObservation;
|
|
356
370
|
readonly physicalReceipt?: PlaybookRepositoryReceipt;
|
|
371
|
+
readonly restored?: PlaybookRepositoryObservation;
|
|
357
372
|
readonly finalText?: string;
|
|
358
373
|
readonly semanticCandidate?: JsonValue;
|
|
359
374
|
readonly initialSemanticCandidate?: JsonValue;
|
|
@@ -393,6 +408,7 @@ type PlaybookEffectBoundaryStart = Omit<
|
|
|
393
408
|
| 'finalText'
|
|
394
409
|
| 'semanticCandidate'
|
|
395
410
|
| 'initialSemanticCandidate'
|
|
411
|
+
| 'restored'
|
|
396
412
|
>;
|
|
397
413
|
|
|
398
414
|
type PlaybookEffectLogicalOperationStart = Omit<
|
|
@@ -454,6 +470,23 @@ interface PlaybookEffectLedgerCapability {
|
|
|
454
470
|
): Promise<PlaybookEffectLedger>;
|
|
455
471
|
}
|
|
456
472
|
|
|
473
|
+
interface PlaybookRecoveryCheckpoint {
|
|
474
|
+
readonly id?: string;
|
|
475
|
+
readonly stateId: string;
|
|
476
|
+
readonly prompt: string;
|
|
477
|
+
readonly machine: JsonValue;
|
|
478
|
+
readonly boundaryPrefix: number;
|
|
479
|
+
readonly result?: JsonValue;
|
|
480
|
+
readonly delivered?: true;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
interface PlaybookStepRecord {
|
|
484
|
+
readonly id: string;
|
|
485
|
+
readonly kind: 'player' | 'captain' | 'script';
|
|
486
|
+
readonly stateId: string;
|
|
487
|
+
readonly result?: JsonValue;
|
|
488
|
+
}
|
|
489
|
+
|
|
457
490
|
interface PlaybookRuntimeSnapshot {
|
|
458
491
|
schemaVersion: 4;
|
|
459
492
|
playbookId: string;
|
|
@@ -484,6 +517,8 @@ interface PlaybookRuntimeSnapshot {
|
|
|
484
517
|
readonly boundaryPrefix: number;
|
|
485
518
|
readonly attemptId: string | null;
|
|
486
519
|
};
|
|
520
|
+
/** Interrupted invocation, captured before its external call (DR-069). */
|
|
521
|
+
recoveryCheckpoint?: PlaybookRecoveryCheckpoint;
|
|
487
522
|
suspendedCall?: PlaybookSuspendedCall;
|
|
488
523
|
}
|
|
489
524
|
|
|
@@ -568,7 +603,7 @@ interface XStatePlaybookRuntimeConstruction<
|
|
|
568
603
|
|
|
569
604
|
The shared type-only contract module shall export `PlaybookRepositoryDisposition`, `PlaybookRepositoryObservation`, `PlaybookRepositoryReceipt`, `PlaybookEffectBoundary`, `PlaybookEffectBoundaryStart`, `PlaybookEffectLogicalOperation`, `PlaybookEffectLedger`, `PlaybookEffectLedgerCommand`, `PlaybookEffectLedgerCommandBatch`, and `PlaybookEffectLedgerCapability`; the executable `@sublang/playbook/xstate-runtime` module shall export `assertPlaybookEffectLedger`, `emptyPlaybookEffectLedger`, and `isPlaybookEffectLedgerMonotonicExtension` over those types.
|
|
570
605
|
That executable module shall also export the centralized schema-3 semantic surface: `PlaybookSemanticFieldAuthority`, `PlaybookSemanticOutcomeSpec`, `PlaybookSemanticEvidenceInput`, `PlaybookReconciledSemanticOutput`, `PlaybookRetainedSemanticEvidence`, `PlaybookSemanticReconciliationReason`, `PlaybookSemanticReconciliation`, `PlaybookSemanticCandidateStructureError`, and `reconcilePlaybookSemanticEvidence`.
|
|
571
|
-
The pure reconciler shall accept the declared state-local outcomes, an unknown semantic candidate, and optional unknown `finalText`, repository receipt, and runtime-field evidence; shall return a detached frozen `resolved` or `deferred` decision with exact output and retained evidence, or an `unresolved` decision with retained evidence and one closed reason from `missing-presentation-evidence`, `missing-repository-receipt`, `invalid-repository-receipt`, `repository-disposition-mismatch`, `missing-effect-evidence`, `missing-runtime-evidence`, and `inconsistent-runtime-evidence`; and shall reserve `PlaybookSemanticCandidateStructureError` for candidate defects eligible for the bounded correction path rather than effect-evidence disagreement.
|
|
606
|
+
The pure reconciler shall accept the declared state-local outcomes, an unknown semantic candidate, and optional unknown `finalText`, repository receipt, and runtime-field evidence; shall return a detached frozen `resolved` or `deferred` decision with exact output and retained evidence, or an `unresolved` decision with retained evidence and one closed reason from `no-matching-outcome`, `missing-presentation-evidence`, `missing-repository-receipt`, `invalid-repository-receipt`, `repository-disposition-mismatch`, `missing-effect-evidence`, `missing-runtime-evidence`, and `inconsistent-runtime-evidence`; and shall reserve `PlaybookSemanticCandidateStructureError` for candidate defects eligible for the bounded correction path rather than effect-evidence disagreement.
|
|
572
607
|
The empty ledger shall be exactly `{ schemaVersion: 1, revision: 0, boundaries: [], logicalOperations: [] }`, and revision shall be zero if and only if both ordered ledgers are empty.
|
|
573
608
|
The validator shall capture the complete supplied ledger once as detached frozen JSON and enforce every closed member, identity, ordering, receipt, cross-reference, correction-budget, and logical-operation invariant represented above.
|
|
574
609
|
One optional host-owned UUID `cohortId` shall identify every member of exactly one contiguous, distinct-role, all-`unchanged` physical cohort in declared role order; every member shall share attempt, playbook, runtime-session, turn, canonical-worktree, and baseline identity and shall be uniformly started or uniformly complete, complete members shall carry the identical after observation and receipt, and the id shall never be reused by another group.
|
|
@@ -630,8 +665,8 @@ Boss text supplied by the entry event is not a required startup option unless So
|
|
|
630
665
|
A generated entry guard that requires the text already in context is likewise
|
|
631
666
|
not independent Source evidence; it is a producer defect when the entry action
|
|
632
667
|
has yet to copy the event's text. Do not compensate with a required option or
|
|
633
|
-
invented startup task.
|
|
634
|
-
|
|
668
|
+
invented startup task. Entry metadata does not populate fresh context before
|
|
669
|
+
FSM guards execute. Interrupted-step checkpoints retain accepted input.
|
|
635
670
|
A source-appropriate optional seed may remain, and genuine required bootstrap catalogs or other options shall not be erased or filled with invented defaults.
|
|
636
671
|
|
|
637
672
|
Concrete player binding and prompt identity are host policy and shall not enter `PlaybookRuntimeOptions`, machine input, or the emitted artifact.
|
|
@@ -642,6 +677,7 @@ The host shall derive `promptIdentity` from the current effective model when pre
|
|
|
642
677
|
|
|
643
678
|
```typescript
|
|
644
679
|
interface PlaybookPorts {
|
|
680
|
+
recordStep?(step: PlaybookStepRecord, position?: PlaybookRuntimeSnapshot): Promise<void>;
|
|
645
681
|
callPlayer(
|
|
646
682
|
roleId: string,
|
|
647
683
|
prompt: string,
|
|
@@ -1239,7 +1275,7 @@ undeclared extra key, so hidden adjudication cannot replace, paraphrase, or
|
|
|
1239
1275
|
decorate prose Boss already saw.
|
|
1240
1276
|
For an artifact-schema-3 governed delegated-player call, the shared engine
|
|
1241
1277
|
shall instead use one semantic reconciler for both the default linked runtime
|
|
1242
|
-
and any
|
|
1278
|
+
and any linked machinery of an artifact's own that adopts schema `3`.
|
|
1243
1279
|
That reconciler shall retain the validated player's exact non-empty
|
|
1244
1280
|
`finalText` as opaque presentation evidence, let the hidden adjudicator read
|
|
1245
1281
|
it only as semantic evidence, and require the adjudicator's detached
|
|
@@ -1257,8 +1293,8 @@ authored placeholder or guidance, with every presentation-, effect-, or
|
|
|
1257
1293
|
runtime-owned field named as runtime-supplied to omit — so the judge is never asked for a
|
|
1258
1294
|
field it does not own; the artifact's description text stays unchanged.
|
|
1259
1295
|
The shared engine shall export that rendering as `renderGovernedOutcomeContract`
|
|
1260
|
-
on `@sublang/playbook/xstate-runtime`, and
|
|
1261
|
-
render its judge prompt through it rather than restate the contract.
|
|
1296
|
+
on `@sublang/playbook/xstate-runtime`, and linked machinery of an artifact's
|
|
1297
|
+
own shall render its judge prompt through it rather than restate the contract.
|
|
1262
1298
|
The reconciler shall construct the complete actor output rather than accept a
|
|
1263
1299
|
cross-authority object from the judge: every presentation-owned payload field
|
|
1264
1300
|
shall receive the canonical `finalText.trim()` value; every effect-owned
|
|
@@ -1271,6 +1307,13 @@ field.
|
|
|
1271
1307
|
It shall reject an absent required field, an undeclared or extra field, a
|
|
1272
1308
|
field supplied by the wrong authority, an invalid value, or any mutually
|
|
1273
1309
|
inconsistent candidate before FSM delivery.
|
|
1310
|
+
When no outcome matches, a governed judge may instead return exactly
|
|
1311
|
+
`{ blocked: <nonempty explanation> }`.
|
|
1312
|
+
The shared reconciler retains this candidate and returns `no-matching-outcome`
|
|
1313
|
+
with its explanation as a `runtime-defect` cause; it authorizes neither a
|
|
1314
|
+
corrective judge nor an FSM outcome.
|
|
1315
|
+
Both shared and bespoke judge prompts shall state this alternative explicitly
|
|
1316
|
+
instead of forcing a match when the declared results are incomplete.
|
|
1274
1317
|
|
|
1275
1318
|
For a non-deferred candidate, reconciliation shall require a complete durable
|
|
1276
1319
|
physical receipt, or the complete cumulative logical receipt of a deferred
|
|
@@ -1344,7 +1387,8 @@ Two default adjudication strategies, in selection order:
|
|
|
1344
1387
|
answer keyed to exactly one of the declared guards: a nongoverned player uses
|
|
1345
1388
|
`{ guard, …structuralPayloadFields }`, while a governed schema-3 player uses
|
|
1346
1389
|
`{ guard, …semanticOwnedPayloadFields }` and explicitly forbids every other
|
|
1347
|
-
payload field.
|
|
1390
|
+
payload field. The governed form also permits the blocked report above when no outcome matches.
|
|
1391
|
+
Both forms exclude the runtime-injected direct-Captain
|
|
1348
1392
|
`question` and `response` fields above. The prompt shall identify hidden control work,
|
|
1349
1393
|
prohibit tool use, file inspection, and external evidence, direct the judge
|
|
1350
1394
|
to decide only from the supplied actor output and declared outcomes, and
|
|
@@ -1875,7 +1919,8 @@ rehydrate it in a later process (DR-014). A runtime that implements either
|
|
|
1875
1919
|
member shall implement both. When generated for a runtime whose host needs
|
|
1876
1920
|
durability, the pair shall behave as follows.
|
|
1877
1921
|
|
|
1878
|
-
`exportSnapshot()`
|
|
1922
|
+
A shared runtime may also receive the internal step-start snapshot for its current invocation or `exportSnapshot({child})` for a bridge-owned child during startup; these capture stopped positions without execution.
|
|
1923
|
+
Ordinary `exportSnapshot()` shall return `undefined` unless the runtime is at a safe
|
|
1879
1924
|
capture point: initialized, not disposing or disposed, no active
|
|
1880
1925
|
`handleBossInput`/`resumePlaybookCall` boundary, and the root actor at a
|
|
1881
1926
|
quiescent state with actor status `active`.
|
|
@@ -1960,9 +2005,11 @@ A linked runtime may implement the optional adoption capability of
|
|
|
1960
2005
|
initialization path distinct from `init` and same-engagement `restore`.
|
|
1961
2006
|
Adoption may bind a retained generation to a fresh valid `PlaybookSession`
|
|
1962
2007
|
identity. Every runtime the shared `createXStatePlaybookRuntime` factory
|
|
1963
|
-
constructs implements `adopt`, regardless of whether the
|
|
1964
|
-
retained-generation classification metadata;
|
|
1965
|
-
|
|
2008
|
+
constructs for a flat machine implements `adopt`, regardless of whether the
|
|
2009
|
+
artifact supplies retained-generation classification metadata; one it
|
|
2010
|
+
constructs for a machine that declares a parallel state omits it, as linked
|
|
2011
|
+
machinery of an artifact's own may, and hosts feature-detect the capability
|
|
2012
|
+
by member presence.
|
|
1966
2013
|
|
|
1967
2014
|
Before actor construction or any player-session-store, port, trace, status,
|
|
1968
2015
|
or telemetry effect, `adopt` shall validate and detach the target session, the
|
|
@@ -2053,9 +2100,9 @@ and detached from that declaration. Absence means the runtime contributes no
|
|
|
2053
2100
|
retained generation; presence supplies only terminal classification metadata
|
|
2054
2101
|
and does not itself supply the adoption operation.
|
|
2055
2102
|
Every runtime the shared `createXStatePlaybookRuntime` factory constructs from
|
|
2056
|
-
a supplied `unfinishedFinalStateIds` spec member shall expose the marker;
|
|
2057
|
-
|
|
2058
|
-
itself.
|
|
2103
|
+
a supplied `unfinishedFinalStateIds` spec member shall expose the marker;
|
|
2104
|
+
linked machinery of an artifact's own opts into classification only by
|
|
2105
|
+
implementing the public member itself.
|
|
2059
2106
|
|
|
2060
2107
|
## Control surface (optional)
|
|
2061
2108
|
|
|
@@ -2082,6 +2129,14 @@ interface PlaybookControlAction {
|
|
|
2082
2129
|
reason?: PlaybookControlActionReason; // why it is not `ready`
|
|
2083
2130
|
}
|
|
2084
2131
|
|
|
2132
|
+
interface PlaybookRecoveryOffer {
|
|
2133
|
+
prompt: string;
|
|
2134
|
+
description?: string;
|
|
2135
|
+
preparation?: string;
|
|
2136
|
+
evidence?: JsonValue;
|
|
2137
|
+
continuation: { kind: 'reply' } | { kind: 'runtime'; actionId: string };
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2085
2140
|
interface PlaybookControlView {
|
|
2086
2141
|
state: PlaybookState;
|
|
2087
2142
|
stateDescription?: string; // runtime-published meaning of the current state
|
|
@@ -2089,12 +2144,13 @@ interface PlaybookControlView {
|
|
|
2089
2144
|
pendingQuestions: readonly PlaybookPendingBossQuestion[];
|
|
2090
2145
|
lastError?: NormalizedError;
|
|
2091
2146
|
actions: readonly PlaybookControlAction[];
|
|
2147
|
+
recovery?: PlaybookRecoveryOffer;
|
|
2092
2148
|
}
|
|
2093
2149
|
|
|
2094
2150
|
type PlaybookControlReceipt =
|
|
2095
2151
|
| { disposition: 'rejected'; reason: string } // before any effect
|
|
2096
2152
|
| { disposition: 'executed'; run: PlaybookRunResult }
|
|
2097
|
-
| { disposition: 'failed'; error: NormalizedError }; // effects may exist
|
|
2153
|
+
| { disposition: 'failed'; error: NormalizedError; run?: PlaybookRunResult }; // effects may exist
|
|
2098
2154
|
|
|
2099
2155
|
// Optional PlaybookRuntime members — both or neither:
|
|
2100
2156
|
describe?(): PlaybookControlView;
|
|
@@ -2115,6 +2171,7 @@ throw. The view carries the current normalized state descriptor, the state
|
|
|
2115
2171
|
description defined below, the authored context projection defined below, the
|
|
2116
2172
|
pending Boss questions with their stable ids, the last recorded error in
|
|
2117
2173
|
normalized form, and the currently valid actions.
|
|
2174
|
+
The shared runtime owns the optional recovery context and invocation checkpoint; linked artifacts need no recovery-specific source, event, or actor.
|
|
2118
2175
|
|
|
2119
2176
|
`stateDescription` is the runtime's own Boss-facing statement of what its
|
|
2120
2177
|
current state means, taken from the same source state descriptions the action
|
|
@@ -2167,25 +2224,17 @@ parked-session snapshot uses (actor status `active`, quiescent, no pending
|
|
|
2167
2224
|
nested call); anywhere else `actions` is empty while the rest of the view
|
|
2168
2225
|
still describes the state.
|
|
2169
2226
|
While effect-possible outcome evidence remains unresolved, the view shall omit its pending Boss questions and state description and shall replace every ordinary action with exactly `reconcile:unresolved-effect` labeled `Retry unresolved effect reconciliation` and `abandon:unresolved-effect` labeled `Abandon unresolved workflow attempt`.
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
context member the machine's entry action copies the exact Boss text into
|
|
2177
|
-
(DR-034), the retry event is that deterministic entry event built from the
|
|
2178
|
-
live snapshot's member — excluded when the member is absent, not a string,
|
|
2179
|
-
or blank, and never falling back to the record. Where it names no member,
|
|
2180
|
-
the retry event is the recorded last classified event (the event a public
|
|
2181
|
-
Boss boundary sent that drove the run into `failed`, kept with its recorded
|
|
2182
|
-
payload), and there is none while the runtime holds none. The member is
|
|
2183
|
-
declared, never inferred from a context member that happens to match the
|
|
2184
|
-
entry event's text field.
|
|
2227
|
+
A valid invocation checkpoint is the only source of a retry: it retries only the stopped invocation after its effect checks, using `retry:<EVENT_TYPE>` for the same entry target or `retry:step` otherwise.
|
|
2228
|
+
Saved-result assessment (`retry:adjudication`) never repeats the player and is not offered for an output the machine has already received (checkpoint `delivered: true`), and verified read-only restoration (`retry:restored-step`) records an exact baseline check before replay.
|
|
2229
|
+
These retries have standing `ready`; an unsafe checkpoint grants no replay. Saved-result assessment withholds ordinary state jumps. Reconciliation and abandonment remain available whenever effects are unresolved, even alongside an eligible assessment or restoration.
|
|
2230
|
+
Ordinary retry and jump actions use source state descriptions and require assessment and unresolved-effect fences to be absent:
|
|
2231
|
+
|
|
2232
|
+
- **Failure-state retry** — a valid invocation checkpoint retries that step only; a completed saved result is consumed without executing the operation again. No checkpoint means no retry. Legacy `entryEvent.contextField` metadata is ignored.
|
|
2185
2233
|
- **Jump entries** — for each registered resumable state id whose
|
|
2186
2234
|
explicit-state-jump event (`BOSS_INTERRUPT` with that `targetId`, optional
|
|
2187
2235
|
textual fields omitted) the live snapshot accepts, guards included, the
|
|
2188
|
-
runtime shall advertise `jump:<stateId
|
|
2236
|
+
runtime shall advertise `jump:<stateId>`, except that a jump out of a governed
|
|
2237
|
+
failure must also pass the full failed-attempt effect check above.
|
|
2189
2238
|
|
|
2190
2239
|
A candidate whose event requires a payload the runtime cannot source from
|
|
2191
2240
|
recorded state shall be excluded from `actions` — `apply` never invents free
|
|
@@ -2195,9 +2244,8 @@ back to a target id or to the replayed event type, because a controller host
|
|
|
2195
2244
|
names an executed or refused action by its label and never by its id, so an
|
|
2196
2245
|
identifier used as a label defeats that substitution. A jump whose target
|
|
2197
2246
|
publishes no description is therefore not advertised — borrowing another
|
|
2198
|
-
state's description would name the wrong state — and a retry
|
|
2199
|
-
|
|
2200
|
-
neither exists.
|
|
2247
|
+
state's description would name the wrong state — and a retry requires the
|
|
2248
|
+
interrupted invocation's source description.
|
|
2201
2249
|
|
|
2202
2250
|
`apply({ actionId, key, signal })` shall revalidate the action against the
|
|
2203
2251
|
live state and settle `{ disposition: 'rejected', reason }` with no effect
|
|
@@ -2213,7 +2261,7 @@ pair, and may execute once the action is advertised — and a key whose call
|
|
|
2213
2261
|
threw before reaching acceptance (lifecycle misuse, invalid input, a
|
|
2214
2262
|
pre-acceptance abort, a rejected start-boundary sink) likewise records
|
|
2215
2263
|
nothing, so a later call with that key may execute.
|
|
2216
|
-
Executing
|
|
2264
|
+
Executing a jump sends the validated event through the same actor drive as `handleBossInput` — state
|
|
2217
2265
|
transitions, player/judge boundaries, statuses, and traces flow unchanged —
|
|
2218
2266
|
and settles `executed` with the projected run result, or `failed` with the
|
|
2219
2267
|
normalized error when the run settles in the failure state, aborts, or a
|
|
@@ -2246,12 +2294,18 @@ signal's own abort reason, in which case it evidences the cancellation and is
|
|
|
2246
2294
|
dropped, not latched
|
|
2247
2295
|
([DR-036](../specs/decisions/036-coherent-abort-settlement.md)).
|
|
2248
2296
|
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2297
|
+
Recorded control receipts are process-local. Invocation checkpoints retain the original input and accepted output across restoration; a restored runtime offers only the currently valid step controls.
|
|
2298
|
+
|
|
2299
|
+
The optional `PlaybookPorts.recordStep(step, position?)` lets a durable host save ordinary work without understanding machine internals.
|
|
2300
|
+
The shared runtime records player, direct-Captain and script starts before execution and their actor results before advancing.
|
|
2301
|
+
The runtime owns the complete stopped position, including accepted Boss input; the host joins nested frames and atomically stores starts and results; retention changes wait for settlement.
|
|
2302
|
+
An invocation inside a parallel region records its start and result without a single-invocation recovery position, including when only its last region is resuming.
|
|
2303
|
+
Sequential invocations after the join use ordinary checkpoints.
|
|
2304
|
+
A custom runtime that cannot provide a position remains runnable, but a crash without a supported position returns to Captain with recorded work preserved.
|
|
2305
|
+
Automatic recovery requires a failed or quiescent outcome produced by an operation in the same turn; resuming or adopting an older stop starts no preparation.
|
|
2306
|
+
The store identifies the step that owns a saved position, so a consumed result cannot be attached to a later stopped snapshot.
|
|
2307
|
+
Only internal step-start capture creates a synthetic failed position; public snapshot capture returns the actual stopped state.
|
|
2308
|
+
Opening or reporting an interrupted run executes no work; Boss chooses the next action after checking outside effects and stopping any surviving worker.
|
|
2255
2309
|
|
|
2256
2310
|
## Abort
|
|
2257
2311
|
|
|
@@ -2360,6 +2414,10 @@ The runtime shall emit, at minimum:
|
|
|
2360
2414
|
semantics matter to Boss — e.g., `respondToReview`, `failed`). The
|
|
2361
2415
|
default is to emit on every transition and let the host filter; hosts
|
|
2362
2416
|
may bind a stricter rule.
|
|
2417
|
+
Mark both a player-question status and its waiting marker with status data
|
|
2418
|
+
`{ kind: "boss-question" }`; the session Captain replaces those statuses with
|
|
2419
|
+
its own clear reply, using the complete pending question from the control view.
|
|
2420
|
+
Keep the original question in state and telemetry, and deliver Boss input unchanged.
|
|
2363
2421
|
- One `emitTelemetry` per state transition under a namespaced topic
|
|
2364
2422
|
(recommended `playbook.fsm.state`), with structured `from`, `to`, `event`,
|
|
2365
2423
|
`previousState`, and `state` fields. Descriptors carry the JSON-safe XState
|
|
@@ -2387,14 +2445,19 @@ Every linked artifact shall emit an `unfinishedFinalStateIds` set beside its res
|
|
|
2387
2445
|
The set shall contain exactly the stable ids of root `type: 'final'` states whose terminal outcomes leave the procedure unfinished, and shall be explicitly empty when no terminal outcome does.
|
|
2388
2446
|
The linker shall not infer the set from a state description, opaque output, or procedure prose.
|
|
2389
2447
|
The linker shall reject a declared id that does not name a root final state, and the shared factory shall independently reject it at construction before runtime effects.
|
|
2390
|
-
For a factory-backed artifact the set is a `spec` member;
|
|
2391
|
-
For
|
|
2392
|
-
|
|
2448
|
+
For a factory-backed artifact the set is a `spec` member; linked machinery of an artifact's own shall retain equivalent linked metadata, and the artifact declaration is not itself the public runtime retention marker or an adoption capability.
|
|
2449
|
+
For every FSM [gears2fsm.md](gears2fsm.md) produces — flat under its
|
|
2450
|
+
one-state-per-item mapping, or carrying root parallel groups of its
|
|
2451
|
+
[Parallel groups](gears2fsm.md#parallel-groups) shape — the linker shall
|
|
2393
2452
|
emit the thin shared-factory module defined below.
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2453
|
+
The shared factory interprets such a parallel group through its parallel
|
|
2454
|
+
profile under [DR-067](../specs/decisions/067-parallel-proposals-through-the-shared-factory.md), deriving the regions, their leaves, and the
|
|
2455
|
+
cohort of working leaves from the FSM and its exported `concurrentRoleSets`,
|
|
2456
|
+
so the emitted module declares nothing further for it; bespoke linked
|
|
2457
|
+
machinery is no longer the prescribed output for any such FSM.
|
|
2458
|
+
Linked machinery of an artifact's own that satisfies this document's runtime
|
|
2459
|
+
contract remains a valid implementation for an artifact outside this package
|
|
2460
|
+
and declares the `bespoke` registry profile below, so hosts keep accepting it.
|
|
2398
2461
|
The FSM-interpreter machinery — actor wiring, boundary tracing, Boss-event
|
|
2399
2462
|
mapping, adjudication, script execution, nested-playbook bridging, session
|
|
2400
2463
|
lifecycle, abort handling, and the optional parked-session snapshot and
|
|
@@ -2510,8 +2573,9 @@ The thin emitted module:
|
|
|
2510
2573
|
error.
|
|
2511
2574
|
`NO_ACTION` and `BOSS_REPLY` are runtime-owned event types the factory
|
|
2512
2575
|
supplies itself — `NO_ACTION` as exactly `{ type: 'NO_ACTION' }`, and
|
|
2513
|
-
`BOSS_REPLY` as
|
|
2514
|
-
|
|
2576
|
+
`BOSS_REPLY` as a judge-selected `questionId` — optional while one question
|
|
2577
|
+
is pending and required, from the pending ids, while several are — plus the
|
|
2578
|
+
exact-text `answer` the runtime attaches. `bossEvents` shall carry no entry for either
|
|
2515
2579
|
type; supplying one is a construction error, so a linker that judges a
|
|
2516
2580
|
runtime-owned arm to have lost payload detail under erasure shall report
|
|
2517
2581
|
that gap rather than emit the entry.
|
|
@@ -2553,8 +2617,11 @@ The thin emitted module:
|
|
|
2553
2617
|
host-construction boundary's setup diagnostic.
|
|
2554
2618
|
- Exposes, under an `_internal` export, the pure helpers verification
|
|
2555
2619
|
needs — at least the prompt composers its own machine uses, which may
|
|
2556
|
-
re-export the shared defaults when the spec does not override composition
|
|
2557
|
-
|
|
2620
|
+
re-export the shared defaults when the spec does not override composition,
|
|
2621
|
+
and the `VERBATIM_PAYLOAD_FIELDS` and `UNFINISHED_FINAL_STATE_IDS` sets the
|
|
2622
|
+
spec declares, which the linked-ownership check reads back — so
|
|
2623
|
+
compilation-correctness tests can exercise composition and ownership
|
|
2624
|
+
without a host.
|
|
2558
2625
|
A playbook that calls players exposes `composePlayerPrompt`; a playbook
|
|
2559
2626
|
whose states make direct-Captain calls exposes `composeCaptainPrompt`. A
|
|
2560
2627
|
controller playbook that calls no players exposes no player composer:
|