@sublang/playbook 12.2.1 → 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.1",
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');