@sublang/playbook 12.2.0 → 12.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sublang/playbook",
3
- "version": "12.2.0",
3
+ "version": "12.2.2",
4
4
  "type": "module",
5
5
  "description": "Composable XState v5 playbook runtime with compiled Captain, CODE, REVIEW, DECIDE, and DEV workflows driven by GEARS specs.",
6
6
  "license": "Apache-2.0",
@@ -1952,9 +1952,9 @@ async function releaseRepositoryClaim(claim, primaryError) {
1952
1952
  }
1953
1953
  }
1954
1954
 
1955
- // A host binds the governed worktree identity for each durable call — fixed
1956
- // at construction for the Captain host, resolved afresh from `cwd` for the
1957
- // worktree host capability — and derives the schema-3 authority naming it.
1955
+ // A host binds the governed worktree identity for each durable call —
1956
+ // resolved afresh from `cwd` by both the Captain host and the worktree host
1957
+ // capability — and derives the schema-3 authority naming it.
1958
1958
  function bindHostWorktree(host) {
1959
1959
  return host.resolveIdentity().then((identity) => ({
1960
1960
  identity,
@@ -2978,33 +2978,43 @@ export async function createRepositoryEffectCapabilities({
2978
2978
  await sessionLease.assertOwner();
2979
2979
  const createdWriteAhead = await createWriteAhead(sessionLease);
2980
2980
  const ledgerService = assertEffectLedgerService(createdWriteAhead);
2981
- const identity = await resolveCanonicalGitWorktree(cwd);
2981
+ // The governed worktree is bound afresh from `cwd` at every governed call
2982
+ // and observation, so a working directory that is not a repository yet is
2983
+ // governed from launch as its own prospective root and the `git init` a
2984
+ // workflow's own setup step runs there keeps that one identity.
2985
+ const resolveIdentity = async () => (await resolveGovernedWorktree(cwd)).identity;
2986
+ const identity = await resolveIdentity();
2982
2987
  await sessionLease.assertOwner();
2983
2988
  const coordinator = createRepositoryEffectCoordinator();
2984
2989
 
2985
2990
  const capabilities = schema3Entries.map(
2986
2991
  ({ playbookId, requiredRoleIds, concurrentRoleSets }) => {
2987
- const authority = deepFreeze({
2988
- playbookId,
2989
- artifactSchema: 3,
2990
- cwd,
2991
- sessionId,
2992
- leaseOwnerToken: sessionLease.ownerToken,
2993
- canonicalWorktree: identity,
2994
- requiredRoleIds,
2995
- concurrentRoleSets,
2996
- });
2992
+ const authorityNaming = (canonicalWorktree) =>
2993
+ deepFreeze({
2994
+ playbookId,
2995
+ artifactSchema: 3,
2996
+ cwd,
2997
+ sessionId,
2998
+ leaseOwnerToken: sessionLease.ownerToken,
2999
+ canonicalWorktree,
3000
+ requiredRoleIds,
3001
+ concurrentRoleSets,
3002
+ });
3003
+ const authority = authorityNaming(identity);
2997
3004
  const host = Object.freeze({
2998
- resolveIdentity: async () => identity,
2999
- authorityFor: () => authority,
3005
+ resolveIdentity,
3006
+ authorityFor: (canonicalWorktree) =>
3007
+ isDeepStrictEqual(canonicalWorktree, identity)
3008
+ ? authority
3009
+ : authorityNaming(canonicalWorktree),
3000
3010
  });
3001
3011
  const observe = async (options = {}) => {
3002
3012
  rejectBoundRepositoryOverride(options, 'observe', ['cwd']);
3003
- return observeResolvedWorktree(identity, options);
3013
+ return observeGovernedWorktree(await resolveGovernedWorktree(cwd), options);
3004
3014
  };
3005
3015
  const acquire = async (options = {}) => {
3006
3016
  rejectBoundRepositoryOverride(options, 'acquire', ['cwd']);
3007
- return coordinator.acquire(identity.worktree, options);
3017
+ return coordinator.acquire(cwd, options);
3008
3018
  };
3009
3019
  const runExclusive = async (options) => {
3010
3020
  return runDurableExclusive({
@@ -3139,11 +3149,11 @@ async function assertExistingDirectory(cwd, label) {
3139
3149
  // DR-046: the lease-free worktree capability an embedding host constructs
3140
3150
  // through `@sublang/playbook/host-capabilities`. It runs the same claim,
3141
3151
  // observation, receipt, completion, and deferred-operation path as the
3142
- // Captain-hosted capability above, over one host-owned in-memory ledger.
3143
- // Unlike that capability, it binds its worktree lazily: `cwd` need not be a
3144
- // repository yet, and every governed call and observation re-resolves the
3145
- // governed worktree of `cwd`, so a `git init` there — inside a governed call
3146
- // or between calls — is observed rather than hidden behind a stale identity.
3152
+ // Captain-hosted capability above, over one host-owned in-memory ledger, and
3153
+ // binds its worktree the same lazy way: `cwd` need not be a repository yet,
3154
+ // and every governed call and observation re-resolves the governed worktree
3155
+ // of `cwd`, so a `git init` there — inside a governed call or between calls —
3156
+ // is observed rather than hidden behind a stale identity.
3147
3157
  export async function createWorktreeHostCapabilities(options = {}) {
3148
3158
  if (!isPlainObject(options)) {
3149
3159
  throw new TypeError('worktree host capability options must be an object');
package/slc/gears2fsm.md CHANGED
@@ -385,6 +385,9 @@ implementation.
385
385
 
386
386
  A literal call shall retain the existing representation: `playbookId` is the
387
387
  literal target and `text` is the composed GEARS blockquote.
388
+ Composing that text follows the quoted-relay rules of [link](link.md): a
389
+ relayed value that is empty contributes no line, a multi-line value is quoted
390
+ line by line, and the composer inserts no empty quoted line of its own.
388
391
 
389
392
  A dynamic call written
390
393
  ``Captain shall call playbook selected by `<target-field>`:`` shall declare the
package/slc/link.md CHANGED
@@ -2413,6 +2413,10 @@ original template. Replacement strings are literal: placeholder-looking text
2413
2413
  inside Boss/catalog/plan/result values and JavaScript replacement tokens such
2414
2414
  as `$&`, `$$`, dollar-backtick, and `$'` shall not be interpreted or
2415
2415
  substituted again.
2416
+ A quoted relay line `> <placeholder>` whose value is empty shall be omitted
2417
+ from the composed text rather than left as an empty quoted line, a multi-line
2418
+ value shall be quoted line by line so every continuation line keeps its `>`
2419
+ marker, and the composer shall insert no empty quoted line of its own.
2416
2420
 
2417
2421
  ## Host adaptation (informative, not normative)
2418
2422
 
package/slc/text2gears.md CHANGED
@@ -145,6 +145,11 @@ The guard name shall match the ASCII identifier pattern
145
145
  The bullet order is authoritative, guard names are unique within the item, and
146
146
  the description shall name every required output property with its exact
147
147
  case-sensitive identifier.
148
+ An output property name shall match the same ASCII identifier pattern as a
149
+ guard name: a kebab-case Source placeholder such as `<coder-output>` names the
150
+ property `coderOutput` through the canonical kebab-token-to-camel-field mapping
151
+ of [link](link.md), never a quoted kebab-case key, because downstream artifacts
152
+ and calling playbooks consume these properties by name.
148
153
 
149
154
  A produced value consumed later shall have a declared producer: where any
150
155
  later item's blockquote reads a value through a `<placeholder>`, the item
@@ -242,6 +247,12 @@ text2gears shall emit an item whose behavior uses
242
247
  complete JSON-safe input-text template for that call.
243
248
  The literal target id shall be a stable configured playbook id, not a slash
244
249
  command or module specifier.
250
+ A nested-call item shall carry no `Results:` label: the child's terminal result
251
+ is its outcome, so Source's continuation after child success, abort, or failure
252
+ stays as prose after the blockquote for
253
+ [gears2fsm](gears2fsm.md#nested-playbook-calls) to route through
254
+ `invoke.onDone` and `invoke.onError`; a `Results:` block on a nested-call item
255
+ is malformed.
245
256
 
246
257
  Example:
247
258