@sublang/playbook 11.0.0 → 12.1.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/docs/cli.md +9 -6
- package/docs/configuration.md +15 -1
- package/docs/embedding.md +83 -1
- package/package.json +28 -3
- package/reference/sdlc/code.playbook/bin/repository-effects.js +501 -170
- package/reference/sdlc/code.playbook/bin/session-store.js +4 -1
- package/reference/sdlc/code.playbook/code.fsm.d.ts +22 -19
- package/reference/sdlc/code.playbook/code.fsm.js +116 -52
- package/reference/sdlc/code.playbook/code.fsm.ts +149 -64
- package/reference/sdlc/code.playbook/code.gears.md +40 -20
- package/reference/sdlc/code.playbook/code.playbook.js +23 -2
- package/reference/sdlc/code.playbook/code.playbook.ts +23 -2
- package/reference/sdlc/code.playbook/host-capabilities.d.ts +291 -0
- package/reference/sdlc/code.playbook/host-capabilities.js +40 -0
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +18 -2
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +13 -6
- package/reference/sdlc/decide.playbook/decide.fsm.js +54 -27
- package/reference/sdlc/decide.playbook/decide.fsm.ts +68 -29
- package/reference/sdlc/decide.playbook/decide.gears.md +25 -19
- package/reference/sdlc/decide.playbook/decide.playbook.js +11 -3
- package/reference/sdlc/decide.playbook/decide.playbook.ts +11 -3
- package/reference/sdlc/decide.playbook/decide.registry.js +1 -1
- package/reference/sdlc/decide.playbook/decide.registry.ts +1 -1
- package/reference/sdlc/dev.md +52 -0
- package/reference/sdlc/dev.playbook/dev.fsm.d.ts +261 -0
- package/reference/sdlc/dev.playbook/dev.fsm.js +723 -0
- package/reference/sdlc/dev.playbook/dev.fsm.ts +988 -0
- package/reference/sdlc/dev.playbook/dev.gears.md +91 -0
- package/reference/sdlc/dev.playbook/dev.playbook.d.ts +21 -0
- package/reference/sdlc/dev.playbook/dev.playbook.js +143 -0
- package/reference/sdlc/dev.playbook/dev.playbook.ts +246 -0
- package/reference/sdlc/dev.playbook/dev.registry.d.ts +40 -0
- package/reference/sdlc/dev.playbook/dev.registry.js +64 -0
- package/reference/sdlc/dev.playbook/dev.registry.ts +120 -0
- package/reference/sdlc/review.playbook/review.fsm.d.ts +15 -2
- package/reference/sdlc/review.playbook/review.fsm.js +77 -27
- package/reference/sdlc/review.playbook/review.fsm.ts +96 -30
- package/reference/sdlc/review.playbook/review.gears.md +52 -26
- package/reference/sdlc/review.playbook/review.playbook.js +17 -7
- package/reference/sdlc/review.playbook/review.playbook.ts +17 -7
- package/reference/sdlc/review.playbook/review.registry.js +1 -1
- package/reference/sdlc/review.playbook/review.registry.ts +1 -1
- package/slc/gears2fsm.md +20 -0
- package/slc/link.md +28 -5
- package/slc/text2gears.md +21 -1
- package/src/xstate-playbook-runtime.js +5 -2
- package/src/xstate-playbook-runtime.ts +5 -2
- package/src/xstate-runtime.js +13 -1
- package/src/xstate-runtime.ts +13 -1
package/slc/gears2fsm.md
CHANGED
|
@@ -540,6 +540,10 @@ The artifact shall not bake them into machine input, options, or context; model
|
|
|
540
540
|
Host-owned configuration such as an enabled-playbook catalog shall remain
|
|
541
541
|
immutable machine input/context for the session. Boss events and actor outputs
|
|
542
542
|
shall not carry, replace, append to, or otherwise overwrite that catalog.
|
|
543
|
+
A placeholder whose value Source assigns to the host — for example the
|
|
544
|
+
`<definition>` a phase host supplies to a compiled phase — is such host-owned
|
|
545
|
+
configuration: a required machine `input` field carried into typed context and
|
|
546
|
+
the acting actor's input, never a Boss-event or actor-output payload.
|
|
543
547
|
Every machine with a dynamic call shall receive its own registered or authored
|
|
544
548
|
playbook id as immutable machine input/context named `selfPlaybookId`, and its
|
|
545
549
|
dynamic-call guard shall reject that target. The leaf-level `stateId` name is
|
|
@@ -776,6 +780,22 @@ compile as `{ response: string }`, not `{ response?: string }`; reaching the
|
|
|
776
780
|
final state without a non-empty response shall be guarded out before the
|
|
777
781
|
machine output is constructed.
|
|
778
782
|
|
|
783
|
+
## Compiled execution
|
|
784
|
+
|
|
785
|
+
This section governs compiled execution of this phase; the rules above remain the transformation's normative content for both execution paths.
|
|
786
|
+
|
|
787
|
+
Where the phase host supplies `<definition>` as the exact bytes of the definition file the request names, when a transformation request names a `gears` Source (`.md`) and an `fsm` Target (`.ts`), Captain shall carry out the GEARS-to-FSM transformation as specified:
|
|
788
|
+
|
|
789
|
+
> Follow the definition relayed between the `--- DEFINITION ---` and `--- END DEFINITION ---` lines exactly, adding no rules of your own: read the named Source and write the named Target as the definition specifies.
|
|
790
|
+
> If the Source cannot be transformed under the definition, do not guess: leave the Target unwritten and report the concrete reason.
|
|
791
|
+
> --- DEFINITION ---
|
|
792
|
+
> \<definition\>
|
|
793
|
+
> --- END DEFINITION ---
|
|
794
|
+
|
|
795
|
+
Results:
|
|
796
|
+
- `compiled`: Captain wrote the named Target as the relayed definition specifies.
|
|
797
|
+
- `rejected`: Captain reported that the Source cannot be transformed under the relayed definition and left the Target unwritten.
|
|
798
|
+
|
|
779
799
|
## References
|
|
780
800
|
|
|
781
801
|
[1]: https://stately.ai/docs/xstate 'XState Official Documentation'
|
package/slc/link.md
CHANGED
|
@@ -423,7 +423,7 @@ After a governed operation settles, the host shall retain any exact proposed com
|
|
|
423
423
|
Each state shall name exactly the outcomes in that state's `invoke.input.result`, and each outcome shall contain exactly `fields` and `repositoryDisposition`.
|
|
424
424
|
The outcome key owns the semantic discriminator, so `guard` shall not appear in `fields`; the `fields` keys shall equal every additional payload field named by that outcome's result description.
|
|
425
425
|
Each field shall have exactly one authority from `presentation`, `semantic`, `effect`, or `runtime`; every linker-declared verbatim payload field and `question` shall be `presentation`, `latestCommit` shall be `effect`, and the payload fields `irNumber` and `irTask` shall be `semantic`, while outcome keys such as `moreTasks` and `finalTask` remain semantic discriminators.
|
|
426
|
-
Each repository disposition shall be exactly `unchanged`, `one-descendant-commit`, or `deferred`; an effect-owned field is valid
|
|
426
|
+
Each repository disposition shall be exactly `unchanged`, `one-descendant-commit`, or `deferred`; an effect-owned field is valid on `one-descendant-commit` and `unchanged` and never on `deferred`, and `deferred` is valid only on `needsBossReply` with presentation-owned `question` and another outcome in that state declaring `one-descendant-commit`.
|
|
427
427
|
The shared factory shall reject every legacy artifact schema and reject schema-3 missing, extra, unknown, wrongly owned, or inconsistent metadata before the affected player call.
|
|
428
428
|
|
|
429
429
|
`init` receives the host-owned playbook session identity and ports, constructs the XState actor with FSM `input` derived from `options`, and starts the actor.
|
|
@@ -1081,8 +1081,11 @@ field shall satisfy the result map's required-field type before any actor
|
|
|
1081
1081
|
output is delivered.
|
|
1082
1082
|
The reconciler shall construct the complete actor output rather than accept a
|
|
1083
1083
|
cross-authority object from the judge: every presentation-owned payload field
|
|
1084
|
-
shall receive the canonical `finalText.trim()` value
|
|
1085
|
-
|
|
1084
|
+
shall receive the canonical `finalText.trim()` value; every effect-owned
|
|
1085
|
+
field shall receive only the qualifying receipt's repository fact selected by
|
|
1086
|
+
the accepted outcome's declared disposition — the exact new-descendant commit
|
|
1087
|
+
OID on `one-descendant-commit`, or the matching `unchanged` receipt's
|
|
1088
|
+
observed HEAD OID on `unchanged` — never a value keyed on the field's name;
|
|
1086
1089
|
and no authority may supply, overwrite, or contradict another authority's
|
|
1087
1090
|
field.
|
|
1088
1091
|
It shall reject an absent required field, an undeclared or extra field, a
|
|
@@ -1092,8 +1095,12 @@ inconsistent candidate before FSM delivery.
|
|
|
1092
1095
|
For a non-deferred candidate, reconciliation shall require a complete durable
|
|
1093
1096
|
physical receipt, or the complete cumulative logical receipt of a deferred
|
|
1094
1097
|
operation, whose classification is exactly the outcome's declared
|
|
1095
|
-
`unchanged` or `one-descendant-commit` disposition;
|
|
1096
|
-
exactly the after-HEAD OID used for
|
|
1098
|
+
`unchanged` or `one-descendant-commit` disposition; a `one-descendant-commit`
|
|
1099
|
+
receipt shall carry exactly the after-HEAD OID used for the arm's effect-owned
|
|
1100
|
+
fields, while an `unchanged` receipt's complete validated observation supplies
|
|
1101
|
+
its observed HEAD OID for them, and a receipt that cannot prove that observed
|
|
1102
|
+
HEAD shall leave the envelope unresolved rather than inject a fabricated
|
|
1103
|
+
value.
|
|
1097
1104
|
A `deferred` candidate shall be admissible only for its already-validated
|
|
1098
1105
|
effect-authorized `needsBossReply` outcome and only from a complete after
|
|
1099
1106
|
observation whose HEAD equals the logical operation's original baseline HEAD
|
|
@@ -2444,6 +2451,22 @@ This spec is silent on the choice; the contract is the same in any location.
|
|
|
2444
2451
|
|
|
2445
2452
|
New behavior in any of these areas requires a separate slc spec.
|
|
2446
2453
|
|
|
2454
|
+
## Compiled execution
|
|
2455
|
+
|
|
2456
|
+
This section governs compiled execution of this phase; the rules above remain the transformation's normative content for both execution paths.
|
|
2457
|
+
|
|
2458
|
+
Where the phase host supplies `<definition>` as the exact bytes of the definition file the request names, when a transformation request names an `fsm` Source (`.ts`) and a `playbook` Target (`.ts`), Captain shall carry out the FSM-to-runtime linking as specified:
|
|
2459
|
+
|
|
2460
|
+
> Follow the definition relayed between the `--- DEFINITION ---` and `--- END DEFINITION ---` lines exactly, adding no rules of your own: read the named Source and write the named Target as the definition specifies.
|
|
2461
|
+
> If the Source cannot be transformed under the definition, do not guess: leave the Target unwritten and report the concrete reason.
|
|
2462
|
+
> --- DEFINITION ---
|
|
2463
|
+
> \<definition\>
|
|
2464
|
+
> --- END DEFINITION ---
|
|
2465
|
+
|
|
2466
|
+
Results:
|
|
2467
|
+
- `compiled`: Captain wrote the named Target as the relayed definition specifies.
|
|
2468
|
+
- `rejected`: Captain reported that the Source cannot be transformed under the relayed definition and left the Target unwritten.
|
|
2469
|
+
|
|
2447
2470
|
## References
|
|
2448
2471
|
|
|
2449
2472
|
[1]: text2gears.md "First phase: text → GEARS spec items."
|
package/slc/text2gears.md
CHANGED
|
@@ -79,6 +79,9 @@ If Source supplies a blockquoted template for that relay, text2gears shall keep
|
|
|
79
79
|
If Source names the relayed value but supplies no template, text2gears shall emit its canonical typed placeholder on a line beginning with literal `> ` and shall not summarize, paraphrase, or invent a value in its place.
|
|
80
80
|
An ordinary Source blockquote that specifies a complete acting prompt without requiring quoted relay retains the existing rule above: its one leading marker is Source syntax and is not prompt content.
|
|
81
81
|
|
|
82
|
+
An acting prompt whose instructions refer to a runtime value the acting role cannot otherwise observe — for example the Boss input task that triggered the workflow — shall relay that value as a quoted `<placeholder>` line appended to the prompt even when Source states no explicit relay.
|
|
83
|
+
A prompt that references an undelivered value asks its player to act on data it never received; omitting the relay is a compilation defect, not a faithful rendering of Source.
|
|
84
|
+
|
|
82
85
|
Source statements that assign active-leaf routing, call identity, suspension,
|
|
83
86
|
or return matching to the host describe execution preconditions rather than
|
|
84
87
|
behaviors for Captain to perform. text2gears shall use such a statement only as
|
|
@@ -318,7 +321,8 @@ exact English form regardless of Source language.
|
|
|
318
321
|
## Transformation-spec sources
|
|
319
322
|
|
|
320
323
|
A Source may itself be the normative specification of a transformation — e.g., a compiler phase definition, as when a meta pipeline compiles this file.
|
|
321
|
-
Such a Source declares no roles and prompts none;
|
|
324
|
+
Such a Source declares no roles and prompts none; Captain performs the specified transformation on request.
|
|
325
|
+
Where such a Source carries a `## Compiled execution` section, text2gears shall compile it from that section alone: the section is the Source's complete behavior — its acting item, prompt, and `Results:` contract — and the remaining definition text is relayed content, not behaviors to transcribe, so the composition below applies only to a Source without that section.
|
|
322
326
|
Compose Captain-acting spec items for it: when a transformation request names the specification's source and target, Captain shall carry out the transformation as specified.
|
|
323
327
|
Prompts shall carry the specification's normative requirements as instructions to Captain — deduplicated, one point per line — without inventing roles, triggers, or requirements the specification does not state.
|
|
324
328
|
|
|
@@ -349,6 +353,22 @@ Partition items by every variable that determines prompt content — including a
|
|
|
349
353
|
Drop disjunctive branches incompatible with the rest of an item's condition or prompt.
|
|
350
354
|
Dead branches mislead readers and downstream phases.
|
|
351
355
|
|
|
356
|
+
## Compiled execution
|
|
357
|
+
|
|
358
|
+
This section governs compiled execution of this phase; the rules above remain the transformation's normative content for both execution paths.
|
|
359
|
+
|
|
360
|
+
Where the phase host supplies `<definition>` as the exact bytes of the definition file the request names, when a transformation request names a `text` Source (`.md`) and a `gears` Target (`.md`), Captain shall carry out the text-to-GEARS transformation as specified:
|
|
361
|
+
|
|
362
|
+
> Follow the definition relayed between the `--- DEFINITION ---` and `--- END DEFINITION ---` lines exactly, adding no rules of your own: read the named Source and write the named Target as the definition specifies.
|
|
363
|
+
> If the Source cannot be transformed under the definition, do not guess: leave the Target unwritten and report the concrete reason.
|
|
364
|
+
> --- DEFINITION ---
|
|
365
|
+
> \<definition\>
|
|
366
|
+
> --- END DEFINITION ---
|
|
367
|
+
|
|
368
|
+
Results:
|
|
369
|
+
- `compiled`: Captain wrote the named Target as the relayed definition specifies.
|
|
370
|
+
- `rejected`: Captain reported that the Source cannot be transformed under the relayed definition and left the Target unwritten.
|
|
371
|
+
|
|
352
372
|
## References
|
|
353
373
|
|
|
354
374
|
[1]: GEARS definition shipped by the installed `@sublang/spex` package: `@sublang/spex/scaffold/specs/meta.md` (English) and `@sublang/spex/scaffold/i18n/zh/specs/meta.md` (Chinese); canonical renditions [GEARS: AI-Ready Spec Syntax](https://sublang.ai/ref/gears-ai-ready-spec-syntax) (en) and [GEARS:面向 AI 的规约语法](https://sublang.ai/zh/ref/gears-ai-ready-spec-syntax) (zh)
|
|
@@ -1242,9 +1242,12 @@ function snapshotOutcomeAuthority(descriptor, label, playerStates, verbatimPaylo
|
|
|
1242
1242
|
!REPOSITORY_DISPOSITIONS.has(disposition)) {
|
|
1243
1243
|
throw new TypeError(`${outcomePath}.repositoryDisposition must be unchanged, one-descendant-commit, or deferred`);
|
|
1244
1244
|
}
|
|
1245
|
-
|
|
1245
|
+
// DR-045: an unchanged arm may declare effect-owned fields (injected
|
|
1246
|
+
// from the matching unchanged receipt's observed HEAD); only deferred
|
|
1247
|
+
// arms remain barred from effect ownership.
|
|
1248
|
+
if (disposition === 'deferred' &&
|
|
1246
1249
|
Object.values(fields).includes('effect')) {
|
|
1247
|
-
throw new TypeError(`${outcomePath} may declare effect-owned fields
|
|
1250
|
+
throw new TypeError(`${outcomePath} may not declare effect-owned fields for deferred`);
|
|
1248
1251
|
}
|
|
1249
1252
|
outcomes[outcome] = Object.freeze({
|
|
1250
1253
|
fields: Object.freeze(fields),
|
|
@@ -2226,12 +2226,15 @@ function snapshotOutcomeAuthority(
|
|
|
2226
2226
|
`${outcomePath}.repositoryDisposition must be unchanged, one-descendant-commit, or deferred`,
|
|
2227
2227
|
);
|
|
2228
2228
|
}
|
|
2229
|
+
// DR-045: an unchanged arm may declare effect-owned fields (injected
|
|
2230
|
+
// from the matching unchanged receipt's observed HEAD); only deferred
|
|
2231
|
+
// arms remain barred from effect ownership.
|
|
2229
2232
|
if (
|
|
2230
|
-
disposition
|
|
2233
|
+
disposition === 'deferred' &&
|
|
2231
2234
|
Object.values(fields).includes('effect')
|
|
2232
2235
|
) {
|
|
2233
2236
|
throw new TypeError(
|
|
2234
|
-
`${outcomePath} may declare effect-owned fields
|
|
2237
|
+
`${outcomePath} may not declare effect-owned fields for deferred`,
|
|
2235
2238
|
);
|
|
2236
2239
|
}
|
|
2237
2240
|
outcomes[outcome] = Object.freeze({
|
package/src/xstate-runtime.js
CHANGED
|
@@ -892,7 +892,19 @@ export function reconcilePlaybookSemanticEvidence(input) {
|
|
|
892
892
|
value = finalText;
|
|
893
893
|
}
|
|
894
894
|
else if (authority === 'effect') {
|
|
895
|
-
|
|
895
|
+
// DR-045: effect injection selects by the accepted arm's declared
|
|
896
|
+
// repository disposition, never by the field's name. A
|
|
897
|
+
// one-descendant-commit arm's effect fields carry the qualifying
|
|
898
|
+
// receipt's exact new-descendant commit OID; an unchanged arm's effect
|
|
899
|
+
// fields carry the matching unchanged receipt's observed HEAD OID. A
|
|
900
|
+
// deferred arm declares no effect field, and any shape the validated
|
|
901
|
+
// receipt cannot prove fails closed as unresolved.
|
|
902
|
+
value =
|
|
903
|
+
disposition === 'one-descendant-commit'
|
|
904
|
+
? receipt.commitOid
|
|
905
|
+
: disposition === 'unchanged'
|
|
906
|
+
? receipt.after?.head
|
|
907
|
+
: undefined;
|
|
896
908
|
if (value === undefined) {
|
|
897
909
|
return unresolvedSemanticEvidence('missing-effect-evidence', evidence);
|
|
898
910
|
}
|
package/src/xstate-runtime.ts
CHANGED
|
@@ -1416,7 +1416,19 @@ export function reconcilePlaybookSemanticEvidence(
|
|
|
1416
1416
|
} else if (authority === 'presentation') {
|
|
1417
1417
|
value = finalText;
|
|
1418
1418
|
} else if (authority === 'effect') {
|
|
1419
|
-
|
|
1419
|
+
// DR-045: effect injection selects by the accepted arm's declared
|
|
1420
|
+
// repository disposition, never by the field's name. A
|
|
1421
|
+
// one-descendant-commit arm's effect fields carry the qualifying
|
|
1422
|
+
// receipt's exact new-descendant commit OID; an unchanged arm's effect
|
|
1423
|
+
// fields carry the matching unchanged receipt's observed HEAD OID. A
|
|
1424
|
+
// deferred arm declares no effect field, and any shape the validated
|
|
1425
|
+
// receipt cannot prove fails closed as unresolved.
|
|
1426
|
+
value =
|
|
1427
|
+
disposition === 'one-descendant-commit'
|
|
1428
|
+
? receipt.commitOid
|
|
1429
|
+
: disposition === 'unchanged'
|
|
1430
|
+
? receipt.after?.head
|
|
1431
|
+
: undefined;
|
|
1420
1432
|
if (value === undefined) {
|
|
1421
1433
|
return unresolvedSemanticEvidence('missing-effect-evidence', evidence);
|
|
1422
1434
|
}
|