@sublang/playbook 17.3.0 → 17.4.1

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 (50) hide show
  1. package/README.md +5 -2
  2. package/docs/configuration.md +45 -4
  3. package/docs/embedding.md +94 -0
  4. package/package.json +34 -5
  5. package/reference/sdlc/captain.md +6 -4
  6. package/reference/sdlc/captain.playbook/captain.fsm.d.ts +5 -0
  7. package/reference/sdlc/captain.playbook/captain.fsm.js +4 -3
  8. package/reference/sdlc/captain.playbook/captain.fsm.ts +9 -4
  9. package/reference/sdlc/captain.playbook/captain.gears.md +6 -3
  10. package/reference/sdlc/captain.playbook/captain.playbook.d.ts +2 -0
  11. package/reference/sdlc/captain.playbook/captain.playbook.js +7 -3
  12. package/reference/sdlc/captain.playbook/captain.playbook.ts +8 -4
  13. package/reference/sdlc/code.md +24 -4
  14. package/reference/sdlc/code.playbook/asset-types.d.ts +32 -0
  15. package/reference/sdlc/code.playbook/bin/launch-config.js +2 -0
  16. package/reference/sdlc/code.playbook/bin/portable-codec.js +12 -5
  17. package/reference/sdlc/code.playbook/bin/run.js +68 -4
  18. package/reference/sdlc/code.playbook/bin/session-host.js +16 -4
  19. package/reference/sdlc/code.playbook/bin/session-media.js +46 -0
  20. package/reference/sdlc/code.playbook/bin/session-store.js +145 -13
  21. package/reference/sdlc/code.playbook/code.fsm.d.ts +12 -0
  22. package/reference/sdlc/code.playbook/code.fsm.js +40 -6
  23. package/reference/sdlc/code.playbook/code.fsm.ts +53 -6
  24. package/reference/sdlc/code.playbook/code.gears.md +32 -4
  25. package/reference/sdlc/code.playbook/playbook-captain.d.ts +17 -1
  26. package/reference/sdlc/code.playbook/playbook-captain.js +201 -19
  27. package/reference/sdlc/code.playbook/playbook-captain.ts +224 -24
  28. package/reference/sdlc/code.playbook/playbook.config.template.yaml +16 -3
  29. package/reference/sdlc/code.playbook/session-assets.d.ts +53 -0
  30. package/reference/sdlc/code.playbook/session-assets.js +303 -0
  31. package/reference/sdlc/code.playbook/session-host.d.ts +9 -1
  32. package/reference/sdlc/code.playbook/session-store.d.ts +26 -2
  33. package/reference/sdlc/code.playbook/worker-evidence.d.ts +8 -0
  34. package/reference/sdlc/code.playbook/worker-evidence.js +51 -0
  35. package/reference/sdlc/inspect.md +40 -0
  36. package/reference/sdlc/inspect.playbook/inspect.fsm.d.ts +168 -0
  37. package/reference/sdlc/inspect.playbook/inspect.fsm.js +354 -0
  38. package/reference/sdlc/inspect.playbook/inspect.fsm.ts +455 -0
  39. package/reference/sdlc/inspect.playbook/inspect.gears.md +36 -0
  40. package/reference/sdlc/inspect.playbook/inspect.playbook.d.ts +17 -0
  41. package/reference/sdlc/inspect.playbook/inspect.playbook.js +142 -0
  42. package/reference/sdlc/inspect.playbook/inspect.playbook.ts +184 -0
  43. package/reference/sdlc/inspect.playbook/inspect.registry.d.ts +41 -0
  44. package/reference/sdlc/inspect.playbook/inspect.registry.js +51 -0
  45. package/reference/sdlc/inspect.playbook/inspect.registry.ts +110 -0
  46. package/slc/gears2fsm.md +17 -3
  47. package/slc/text2gears.md +7 -0
  48. package/slc/workflow-contracts.json +43 -1
  49. package/src/xstate-playbook-runtime.js +5 -0
  50. package/src/xstate-playbook-runtime.ts +7 -0
@@ -0,0 +1,184 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
+ // Generated by slc/materialize-link.mjs; governed by the complete slc/link.md.
4
+ // FSM: "./inspect.fsm.js"; export: inspectMachine; strategies: shared defaults with labelled string relays and nested actors.
5
+ import { inspectMachine as machine } from "./inspect.fsm.js";
6
+ import type { PlayerInput as SourcePlayerInput } from "./inspect.fsm.js";
7
+ import {
8
+ createXStatePlaybookRuntime, snapshotJsonValue,
9
+ composePlayerContinuation, type XStatePromptIdentity,
10
+ type PlaybookPlayerInput,
11
+ type XStatePlaybookRuntimeConstruction,
12
+ type XStatePlaybookRuntimeFactory,
13
+ type XStatePlaybookRuntimeSpecV3,
14
+ } from '@sublang/playbook/xstate-runtime';
15
+ export type {
16
+ PlayerResult,
17
+ PlayerCallOptions,
18
+ PlayerSessionStore,
19
+ CaptainResult,
20
+ CaptainCallOptions,
21
+ JsonValue,
22
+ NormalizedError,
23
+ PlaybookCallRequest,
24
+ PlaybookCallResult,
25
+ PlaybookCallStart,
26
+ PlaybookStateValue,
27
+ PlaybookState,
28
+ PlaybookPendingCall,
29
+ PlaybookRunResult,
30
+ PlaybookRuntime,
31
+ PlaybookRuntimeFactory,
32
+ PlaybookRuntimeSnapshot,
33
+ PlaybookSession,
34
+ PlaybookPorts,
35
+ PlaybookTraceEvent,
36
+ PlaybookTraceType,
37
+ PlaybookControlReceipt,
38
+ PlaybookControlView,
39
+ } from '@sublang/playbook/runtime';
40
+
41
+ export interface PlaybookRuntimeOptions {
42
+ readonly "discussionContext"?: string;
43
+ }
44
+ export type PlaybookHostCapabilities = XStatePlaybookRuntimeConstruction<
45
+ PlaybookRuntimeOptions, { readonly authority: object }
46
+ >['hostCapabilities'];
47
+
48
+ const OPTION_SCHEMA = {
49
+ "discussionContext": {
50
+ "type": "string",
51
+ "required": false
52
+ }
53
+ } as const;
54
+ const INPUT_MAPPING = {
55
+ "discussionContext": "discussionContext"
56
+ } as const;
57
+ const RESUMABLE_STATE_IDS: ReadonlySet<string> = new Set([
58
+ "inspecting"
59
+ ]);
60
+ const UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string> = new Set([
61
+ "unavailable"
62
+ ]);
63
+ const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
64
+ "report"
65
+ ]);
66
+ export function validateOptions(value: unknown): PlaybookRuntimeOptions {
67
+ const captured = snapshotJsonValue(value === undefined ? {} : value, "INSPECT runtime options");
68
+ if (captured === null || typeof captured !== 'object' || Array.isArray(captured)) {
69
+ throw new TypeError("INSPECT runtime options must be an object");
70
+ }
71
+ const fields = captured as Readonly<Record<string, unknown>>;
72
+ for (const key of Object.keys(captured)) {
73
+ if (!Object.hasOwn(OPTION_SCHEMA, key)) throw new TypeError("INSPECT runtime options." + key + ' is not declared');
74
+ }
75
+ for (const [key, schema] of Object.entries(OPTION_SCHEMA) as [string, { type: string; required: boolean }][]) {
76
+ if (!Object.hasOwn(captured, key)) {
77
+ if (schema.required) throw new TypeError("INSPECT runtime options." + key + ' is required');
78
+ } else if (typeof fields[key] !== schema.type || (schema.type === 'number' && !Number.isFinite(fields[key]))) {
79
+ throw new TypeError("INSPECT runtime options." + key + ' must be a ' + schema.type);
80
+ }
81
+ }
82
+ return captured as unknown as PlaybookRuntimeOptions;
83
+ }
84
+ function renderPlayerPrompt(input: SourcePlayerInput, promptIdentity: XStatePromptIdentity, resuming = false): string {
85
+ const fields = input as unknown as Readonly<Record<string, unknown>>;
86
+ const mapping: Readonly<Record<string, string>> = {};
87
+ const identities: Readonly<Record<string, string>> = {};
88
+ const omitted = new Set<string>(["> Discussion context: <discussion-context>"]);
89
+ const fieldFor = (token: string): string => Object.hasOwn(mapping, token) ? mapping[token]! : (token === '#' ? 'irNumber' : token.replace(/-([A-Za-z0-9_$])/g, (_match: string, next: string) => next.toUpperCase()));
90
+ const parts = input.prompt.split(/(\r?\n)/);
91
+ let body = '';
92
+ for (let index = 0; index < parts.length; index += 2) {
93
+ const line = parts[index]!;
94
+ if (omitted.has(line)) {
95
+ const token = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>$/.exec(line)![1]!;
96
+ if (fields[fieldFor(token)] === '') continue;
97
+ }
98
+ body += line.replace(/<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g, (match: string, token: string): string => {
99
+ const value = Object.hasOwn(identities, token) ? promptIdentity(identities[token]!) : fields[fieldFor(token)];
100
+ if (typeof value !== 'string') return match;
101
+ return line.startsWith('> ') ? value.replace(/\r?\n/g, (ending: string) => ending + '> ') : value;
102
+ }) + (parts[index + 1] ?? '');
103
+ }
104
+ return composePlayerContinuation(input, body, resuming);
105
+ }
106
+ const composePlayerPrompt = (input: PlaybookPlayerInput, promptIdentity: XStatePromptIdentity, resuming?: boolean): string =>
107
+ renderPlayerPrompt(input as SourcePlayerInput, promptIdentity, resuming);
108
+ const runtimeSpec = {
109
+ composePlayerPrompt,
110
+ ...{
111
+ "label": "INSPECT",
112
+ "compat": {
113
+ "artifactSchema": 3,
114
+ "runtimeAbi": 1
115
+ },
116
+ "entryEvent": {
117
+ "type": "START",
118
+ "textField": "inspectionRequest",
119
+ "contextField": "inspectionRequest"
120
+ },
121
+ "bossEvents": [],
122
+ "roleStates": {
123
+ "inspecting": {
124
+ "role": "inspector",
125
+ "label": "Inspector investigates the requested material and gives an evidence-based explanation."
126
+ }
127
+ },
128
+ "outcomeAuthority": {
129
+ "governedPlayerStates": {
130
+ "inspecting": {
131
+ "completed": {
132
+ "fields": {
133
+ "status": "semantic",
134
+ "report": "presentation"
135
+ },
136
+ "repositoryDisposition": "unchanged"
137
+ },
138
+ "unavailable": {
139
+ "fields": {
140
+ "status": "semantic",
141
+ "report": "presentation"
142
+ },
143
+ "repositoryDisposition": "unchanged"
144
+ },
145
+ "needsBossReply": {
146
+ "fields": {
147
+ "question": "presentation"
148
+ },
149
+ "repositoryDisposition": "unchanged"
150
+ }
151
+ }
152
+ }
153
+ },
154
+ "placeholderFields": {},
155
+ "transitionEventFields": [
156
+ "inspectionRequest",
157
+ "discussionContext",
158
+ "answer",
159
+ "questionId"
160
+ ],
161
+ "controlContextFields": [
162
+ "inspectionRequest"
163
+ ]
164
+ },
165
+ snapshotOptions: validateOptions,
166
+ machineInput: (options: PlaybookRuntimeOptions) => Object.fromEntries(
167
+ Object.entries(INPUT_MAPPING).filter(([, key]) => options[key as keyof PlaybookRuntimeOptions] !== undefined)
168
+ .map(([field, key]) => [field, options[key as keyof PlaybookRuntimeOptions]]),
169
+ ),
170
+ verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
171
+ resumableStateIds: RESUMABLE_STATE_IDS,
172
+ unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
173
+ } satisfies XStatePlaybookRuntimeSpecV3<PlaybookRuntimeOptions>;
174
+
175
+ export const _internal = {
176
+ composePlayerPrompt,
177
+ RESUMABLE_STATE_IDS,
178
+ UNFINISHED_FINAL_STATE_IDS,
179
+ VERBATIM_PAYLOAD_FIELDS,
180
+ };
181
+ const createPlaybookRuntime: XStatePlaybookRuntimeFactory<
182
+ XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, PlaybookHostCapabilities>, 3
183
+ > = createXStatePlaybookRuntime<PlaybookRuntimeOptions, PlaybookHostCapabilities>(machine, runtimeSpec);
184
+ export default createPlaybookRuntime;
@@ -0,0 +1,41 @@
1
+ import { type PlaybookRuntimeOptions, type PlaybookHostCapabilities, type PlaybookRuntime } from './inspect.playbook.js';
2
+ import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
3
+ export interface PlaybookSummaryPolicy {
4
+ stateCountLabels: Readonly<Record<string, string>>;
5
+ copyPasteGuardNames: readonly string[];
6
+ savedCountsLine(counts: {
7
+ interruptions: number;
8
+ copyPastes: number;
9
+ }, rounds: number): string;
10
+ }
11
+ export type InspectOptions = PlaybookRuntimeOptions;
12
+ export interface InspectPlaybookRegistryEntry {
13
+ id: 'inspect';
14
+ command: 'inspect';
15
+ intent: string;
16
+ artifactSchema: 3;
17
+ runtimeProfile: {
18
+ readonly kind: 'shared-factory';
19
+ readonly compat: {
20
+ readonly artifactSchema: 3;
21
+ readonly runtimeAbi: number;
22
+ };
23
+ };
24
+ requiredRoleIds: readonly ['inspector'];
25
+ concurrentRoleSets: readonly [];
26
+ summaryPolicy: PlaybookSummaryPolicy;
27
+ validateOptions(optionSlice: unknown): InspectOptions;
28
+ createRuntime(options: InspectOptions, hostCapabilities: PlaybookHostConstructionCapabilities & PlaybookHostCapabilities): PlaybookRuntime;
29
+ }
30
+ export declare const inspectStateCountLabels: {
31
+ readonly inspecting: "inspection round";
32
+ };
33
+ export declare const inspectCopyPasteGuardNames: readonly ["completed"];
34
+ export declare function inspectSavedCountsLine(counts: {
35
+ interruptions: number;
36
+ copyPastes: number;
37
+ }, rounds: number): string;
38
+ export declare const inspectSummaryPolicy: PlaybookSummaryPolicy;
39
+ export declare function validateInspectOptions(optionSlice: unknown): InspectOptions;
40
+ export declare const inspectPlaybookRegistryEntry: InspectPlaybookRegistryEntry;
41
+ export default inspectPlaybookRegistryEntry;
@@ -0,0 +1,51 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
+ import createPlaybookRuntime, { validateOptions, } from './inspect.playbook.js';
4
+ // INSPECT counts its delegated evidence-gathering calls as inspection rounds.
5
+ export const inspectStateCountLabels = {
6
+ inspecting: 'inspection round',
7
+ };
8
+ export const inspectCopyPasteGuardNames = ['completed'];
9
+ function countNoun(count, singular, plural = `${singular}s`) {
10
+ return `${count} ${count === 1 ? singular : plural}`;
11
+ }
12
+ export function inspectSavedCountsLine(counts, rounds) {
13
+ return [
14
+ 'Saved you',
15
+ countNoun(counts.interruptions, 'interruption'),
16
+ 'and',
17
+ countNoun(counts.copyPastes, 'copy-paste'),
18
+ 'across',
19
+ countNoun(rounds, 'round'),
20
+ 'of inspection.',
21
+ ].join(' ');
22
+ }
23
+ export const inspectSummaryPolicy = {
24
+ stateCountLabels: inspectStateCountLabels,
25
+ copyPasteGuardNames: inspectCopyPasteGuardNames,
26
+ savedCountsLine: inspectSavedCountsLine,
27
+ };
28
+ export function validateInspectOptions(optionSlice) {
29
+ return validateOptions(optionSlice);
30
+ }
31
+ export const inspectPlaybookRegistryEntry = {
32
+ id: 'inspect',
33
+ command: 'inspect',
34
+ intent: 'inspect supplied material or a running web interface and explain observed evidence without changing the repository',
35
+ artifactSchema: 3,
36
+ runtimeProfile: Object.freeze({
37
+ kind: 'shared-factory',
38
+ compat: createPlaybookRuntime.compat,
39
+ }),
40
+ requiredRoleIds: ['inspector'],
41
+ concurrentRoleSets: [],
42
+ summaryPolicy: inspectSummaryPolicy,
43
+ validateOptions: validateInspectOptions,
44
+ createRuntime(options, hostCapabilities) {
45
+ return createPlaybookRuntime({
46
+ configuredOptions: options,
47
+ hostCapabilities,
48
+ });
49
+ },
50
+ };
51
+ export default inspectPlaybookRegistryEntry;
@@ -0,0 +1,110 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
+
4
+ import createPlaybookRuntime, {
5
+ validateOptions,
6
+ type PlaybookRuntimeOptions,
7
+ type PlaybookHostCapabilities,
8
+ type PlaybookRuntime,
9
+ } from './inspect.playbook.js';
10
+ import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
11
+
12
+ export interface PlaybookSummaryPolicy {
13
+ stateCountLabels: Readonly<Record<string, string>>;
14
+ copyPasteGuardNames: readonly string[];
15
+ savedCountsLine(
16
+ counts: { interruptions: number; copyPastes: number },
17
+ rounds: number,
18
+ ): string;
19
+ }
20
+
21
+ export type InspectOptions = PlaybookRuntimeOptions;
22
+
23
+ export interface InspectPlaybookRegistryEntry {
24
+ id: 'inspect';
25
+ command: 'inspect';
26
+ intent: string;
27
+ artifactSchema: 3;
28
+ runtimeProfile: {
29
+ readonly kind: 'shared-factory';
30
+ readonly compat: {
31
+ readonly artifactSchema: 3;
32
+ readonly runtimeAbi: number;
33
+ };
34
+ };
35
+ requiredRoleIds: readonly ['inspector'];
36
+ concurrentRoleSets: readonly [];
37
+ summaryPolicy: PlaybookSummaryPolicy;
38
+ validateOptions(optionSlice: unknown): InspectOptions;
39
+ // The linked module types live authority as opaque (link-materialization);
40
+ // the Captain entry binds its own construction capabilities here.
41
+ createRuntime(
42
+ options: InspectOptions,
43
+ hostCapabilities: PlaybookHostConstructionCapabilities &
44
+ PlaybookHostCapabilities,
45
+ ): PlaybookRuntime;
46
+ }
47
+
48
+ // INSPECT counts its delegated evidence-gathering calls as inspection rounds.
49
+ export const inspectStateCountLabels = {
50
+ inspecting: 'inspection round',
51
+ } as const;
52
+
53
+ export const inspectCopyPasteGuardNames = ['completed'] as const;
54
+
55
+ function countNoun(
56
+ count: number,
57
+ singular: string,
58
+ plural = `${singular}s`,
59
+ ): string {
60
+ return `${count} ${count === 1 ? singular : plural}`;
61
+ }
62
+
63
+ export function inspectSavedCountsLine(
64
+ counts: { interruptions: number; copyPastes: number },
65
+ rounds: number,
66
+ ): string {
67
+ return [
68
+ 'Saved you',
69
+ countNoun(counts.interruptions, 'interruption'),
70
+ 'and',
71
+ countNoun(counts.copyPastes, 'copy-paste'),
72
+ 'across',
73
+ countNoun(rounds, 'round'),
74
+ 'of inspection.',
75
+ ].join(' ');
76
+ }
77
+
78
+ export const inspectSummaryPolicy: PlaybookSummaryPolicy = {
79
+ stateCountLabels: inspectStateCountLabels,
80
+ copyPasteGuardNames: inspectCopyPasteGuardNames,
81
+ savedCountsLine: inspectSavedCountsLine,
82
+ };
83
+
84
+ export function validateInspectOptions(optionSlice: unknown): InspectOptions {
85
+ return validateOptions(optionSlice);
86
+ }
87
+
88
+ export const inspectPlaybookRegistryEntry: InspectPlaybookRegistryEntry = {
89
+ id: 'inspect',
90
+ command: 'inspect',
91
+ intent:
92
+ 'inspect supplied material or a running web interface and explain observed evidence without changing the repository',
93
+ artifactSchema: 3,
94
+ runtimeProfile: Object.freeze({
95
+ kind: 'shared-factory',
96
+ compat: createPlaybookRuntime.compat,
97
+ }),
98
+ requiredRoleIds: ['inspector'],
99
+ concurrentRoleSets: [],
100
+ summaryPolicy: inspectSummaryPolicy,
101
+ validateOptions: validateInspectOptions,
102
+ createRuntime(options, hostCapabilities) {
103
+ return createPlaybookRuntime({
104
+ configuredOptions: options,
105
+ hostCapabilities,
106
+ });
107
+ },
108
+ };
109
+
110
+ export default inspectPlaybookRegistryEntry;
package/slc/gears2fsm.md CHANGED
@@ -602,6 +602,9 @@ safety beyond the guarded direct transition.
602
602
  ## Context and prompts
603
603
 
604
604
  Context fields used to drive guards or compose prompts shall be **typed and named**.
605
+ Where Source owns array-valued retained discussion whose initial state is no history, initialize that context field to `[]` and reset it to `[]` only at its Source lifecycle boundaries.
606
+ Carry its declared array shape through ordinary and continuation `invoke.input`; do not leave the empty structural history absent so a prompt-contract probe mistakes it for a scalar.
607
+ This empty history is not a default caller intent, prerequisite report, domain evidence, approval, or prior-stage result; those remain unavailable until actually established.
605
608
  The compiler shall not branch on untyped properties of `lastResult`; persistent routing decisions belong in typed context fields. (`lastResult` is for inspection only.)
606
609
  Where Source declares a finite ordered plan, represent it as a typed readonly
607
610
  JSON-safe array and validate that shape on the actor-output transition; an
@@ -835,8 +838,8 @@ Only
835
838
  The canonical storage paths are `context.pendingBossQuestion` and `context.bossReply` for the scalar form, or `context.pendingBossQuestions[stateId]` and `context.bossReplies[stateId]` for the keyed form.
836
839
  A private wrapper such as `context.continuation` shall not replace these fields directly on machine context.
837
840
 
838
- A machine with at most one active Captain or player task may use the scalar
839
- form:
841
+ A machine that declares no root parallel group shall use the scalar form;
842
+ keyed storage alone is not visible to the flat shared factory:
840
843
 
841
844
  - An `awaitBossReply` state with stable `id: 'awaitBossReply'`, tag
842
845
  `playbook.parked`, and description
@@ -847,7 +850,9 @@ form:
847
850
  - `resumableStates(ids)`, `setPendingBossQuestion`, and
848
851
  `clearBossReplyContext` helpers with the existing single-question behavior.
849
852
 
850
- A machine with parallel delegated-player tasks shall use the keyed form:
853
+ A machine that declares a root parallel group shall use the keyed form
854
+ throughout the machine, including any sequential working leaves and their
855
+ root reply wait:
851
856
 
852
857
  - One local waiting leaf per branch, tagged `playbook.parked`.
853
858
  - A `BOSS_REPLY` event carrying `{ questionId: string; answer: string }`.
@@ -884,6 +889,15 @@ pending question and reply selected for that working leaf as singular
884
889
  `pendingBossQuestion` and `bossReply` fields, regardless of the scalar or keyed
885
890
  context representation, so prompt composition has one stable contract.
886
891
  When Source requires earlier discussion or constraints on a later invocation, the compiler shall persist that source-owned history in serializable machine context before replacing or clearing the pending Q/A fields.
892
+ Where that Source-owned value is the complete received Boss reply, retain it
893
+ directly from the current working leaf's canonical reply context at the
894
+ Source-authored accepted-outcome boundary, before clearing that leaf's Q/A.
895
+ Preserve its exact string, including surrounding whitespace, CRLF/LF separators,
896
+ blank lines and trailing separators; do not require a model-produced echo or
897
+ replace it with one. Acceptance remains the acting agent's semantic judgment,
898
+ guarded by the current matching question's state, Source-item and asker binding
899
+ and actual receipt of a nonempty reply. Neither stale question/reply context
900
+ nor a different actor-supplied value establishes that binding or approval.
887
901
  The later `invoke.input` shall relay that persisted context on both resumed and fresh calls that Source says need it, preserving Source-owned relevance and format without imposing all-history semantics on sources that do not require it.
888
902
  Shared Boss-reply continuation carries only the latest Q/A pair, and a backend continuation token is not durable Source history.
889
903
  When both fields are present, the linked runtime shall compose the continuation preamble and labelled Q&A blocks per [link.md "Player prompt composition"](link.md#player-prompt-composition).
package/slc/text2gears.md CHANGED
@@ -189,6 +189,13 @@ between the Source and the catalog: leave the Target unwritten and report it
189
189
  as an incompatible compiler input rather than rename or invent.
190
190
  A Source outside those ids is named from its own words as above.
191
191
 
192
+ A value Source assigns to the received Boss input or reply is already runtime
193
+ input, not a value the acting agent produces. Where Source requires that
194
+ complete value retained for later calls, preserve the exact input's retention
195
+ and the Source's acceptance condition in non-acting GEARS prose; do not declare
196
+ a Judge-extracted echo property for it. The semantic approval or refusal stays
197
+ in the acting result contract.
198
+
192
199
  A produced value consumed later shall have a declared producer: where any
193
200
  later item's blockquote reads a value through a `<placeholder>`, the item
194
201
  whose behavior produces that value shall declare the `Results:` contract
@@ -359,6 +359,47 @@
359
359
  }
360
360
  ]
361
361
  }
362
+ },
363
+ "inspect": {
364
+ "callInput": "text",
365
+ "output": {
366
+ "anyOf": [
367
+ {
368
+ "type": "object",
369
+ "properties": {
370
+ "status": {
371
+ "const": "complete"
372
+ },
373
+ "report": {
374
+ "type": "string",
375
+ "description": "Inspector's complete explanation; presentation evidence, not independent effect authority."
376
+ }
377
+ },
378
+ "required": [
379
+ "status",
380
+ "report"
381
+ ],
382
+ "additionalProperties": false
383
+ },
384
+ {
385
+ "type": "object",
386
+ "properties": {
387
+ "status": {
388
+ "const": "unavailable"
389
+ },
390
+ "report": {
391
+ "type": "string",
392
+ "description": "Inspector's complete explanation; presentation evidence, not independent effect authority."
393
+ }
394
+ },
395
+ "required": [
396
+ "status",
397
+ "report"
398
+ ],
399
+ "additionalProperties": false
400
+ }
401
+ ]
402
+ }
362
403
  }
363
404
  },
364
405
  "literalTargetBindings": {
@@ -366,6 +407,7 @@
366
407
  "decide": "decide",
367
408
  "code": "code",
368
409
  "branch": "branch",
369
- "pr": "pr"
410
+ "pr": "pr",
411
+ "inspect": "inspect"
370
412
  }
371
413
  }
@@ -866,12 +866,16 @@ export function defaultExtractRequiredFields(description) {
866
866
  fields.push(m[1]);
867
867
  return fields;
868
868
  }
869
+ const CURRENT_CALL_ADJUDICATION_GUIDANCE = "Classify the invoked role's current call by the result it reports at call end, using the full output and declared outcome meanings. " +
870
+ 'An earlier interim question is not outstanding when later prose explicitly resolves or supersedes it for this call; a prerequisite only for a later workflow stage does not block an affirmatively completed current call. ' +
871
+ 'A genuinely unanswered question needed to finish the current call remains outstanding. A commit statement alone does not establish semantic completion; do not force contradictory or insufficient evidence into a completed outcome.';
869
872
  /** Default delegated-player adjudicator prompt. */
870
873
  export function defaultBuildJudgePrompt(input, finalText) {
871
874
  const lines = [];
872
875
  lines.push('This is hidden control work. Do not call tools, inspect files, or ' +
873
876
  'seek external evidence. Decide only from the supplied player output ' +
874
877
  'and outcome descriptions. Reply with exactly one JSON object and no prose.');
878
+ lines.push(CURRENT_CALL_ADJUDICATION_GUIDANCE);
875
879
  lines.push('');
876
880
  lines.push(`The ${input.role} role just produced this output:`);
877
881
  lines.push('');
@@ -957,6 +961,7 @@ function buildGovernedJudgePrompt(input, finalText, outcomes, correction) {
957
961
  const lines = [
958
962
  'This is hidden control work. Do not call tools, inspect files, or seek external evidence.',
959
963
  'Decide only from the supplied player output and declared outcomes.',
964
+ CURRENT_CALL_ADJUDICATION_GUIDANCE,
960
965
  'Reply with exactly one JSON object and no prose.',
961
966
  '',
962
967
  `The ${input.role} role just produced this output:`,
@@ -1706,6 +1706,11 @@ export function defaultExtractRequiredFields(description: string): string[] {
1706
1706
  return fields;
1707
1707
  }
1708
1708
 
1709
+ const CURRENT_CALL_ADJUDICATION_GUIDANCE =
1710
+ "Classify the invoked role's current call by the result it reports at call end, using the full output and declared outcome meanings. " +
1711
+ 'An earlier interim question is not outstanding when later prose explicitly resolves or supersedes it for this call; a prerequisite only for a later workflow stage does not block an affirmatively completed current call. ' +
1712
+ 'A genuinely unanswered question needed to finish the current call remains outstanding. A commit statement alone does not establish semantic completion; do not force contradictory or insufficient evidence into a completed outcome.';
1713
+
1709
1714
  /** Default delegated-player adjudicator prompt. */
1710
1715
  export function defaultBuildJudgePrompt(
1711
1716
  input: PlaybookPlayerInput,
@@ -1717,6 +1722,7 @@ export function defaultBuildJudgePrompt(
1717
1722
  'seek external evidence. Decide only from the supplied player output ' +
1718
1723
  'and outcome descriptions. Reply with exactly one JSON object and no prose.',
1719
1724
  );
1725
+ lines.push(CURRENT_CALL_ADJUDICATION_GUIDANCE);
1720
1726
  lines.push('');
1721
1727
  lines.push(`The ${input.role} role just produced this output:`);
1722
1728
  lines.push('');
@@ -1822,6 +1828,7 @@ function buildGovernedJudgePrompt(
1822
1828
  const lines = [
1823
1829
  'This is hidden control work. Do not call tools, inspect files, or seek external evidence.',
1824
1830
  'Decide only from the supplied player output and declared outcomes.',
1831
+ CURRENT_CALL_ADJUDICATION_GUIDANCE,
1825
1832
  'Reply with exactly one JSON object and no prose.',
1826
1833
  '',
1827
1834
  `The ${input.role} role just produced this output:`,