pi-daddy 0.36.0 → 0.38.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +4 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/kernel/context-handoff.d.ts +71 -1
  7. package/dist/kernel/context-handoff.d.ts.map +1 -1
  8. package/dist/kernel/context-handoff.js +65 -6
  9. package/dist/kernel/context-handoff.js.map +1 -1
  10. package/dist/kernel/delegate-types.d.ts +9 -0
  11. package/dist/kernel/delegate-types.d.ts.map +1 -1
  12. package/dist/kernel/delegate-types.js.map +1 -1
  13. package/dist/kernel/delegate.d.ts.map +1 -1
  14. package/dist/kernel/delegate.js +6 -1
  15. package/dist/kernel/delegate.js.map +1 -1
  16. package/dist/kernel/env-names.d.ts +2 -0
  17. package/dist/kernel/env-names.d.ts.map +1 -1
  18. package/dist/kernel/env-names.js +3 -0
  19. package/dist/kernel/env-names.js.map +1 -1
  20. package/dist/kernel/propagation.d.ts +24 -1
  21. package/dist/kernel/propagation.d.ts.map +1 -1
  22. package/dist/kernel/propagation.js +28 -1
  23. package/dist/kernel/propagation.js.map +1 -1
  24. package/dist/kernel/workspace-pin.d.ts +56 -0
  25. package/dist/kernel/workspace-pin.d.ts.map +1 -0
  26. package/dist/kernel/workspace-pin.js +139 -0
  27. package/dist/kernel/workspace-pin.js.map +1 -0
  28. package/dist/kernel/workspace.d.ts +20 -1
  29. package/dist/kernel/workspace.d.ts.map +1 -1
  30. package/dist/kernel/workspace.js +32 -2
  31. package/dist/kernel/workspace.js.map +1 -1
  32. package/extensions/context-staging.ts +32 -5
  33. package/extensions/grants-command.ts +16 -1
  34. package/extensions/grants.ts +1 -0
  35. package/extensions/pruning-advice.ts +20 -8
  36. package/extensions/reload-environment.ts +25 -0
  37. package/extensions/run-delegation.ts +1 -0
  38. package/extensions/session-report.ts +7 -0
  39. package/extensions/session.ts +111 -0
  40. package/extensions/workspace-runtime.ts +16 -1
  41. package/package.json +1 -1
  42. package/src/index.ts +13 -0
  43. package/src/kernel/context-handoff.ts +96 -6
  44. package/src/kernel/delegate-types.ts +9 -0
  45. package/src/kernel/delegate.ts +6 -0
  46. package/src/kernel/env-names.ts +3 -0
  47. package/src/kernel/propagation.ts +40 -0
  48. package/src/kernel/workspace-pin.ts +158 -0
  49. package/src/kernel/workspace.ts +34 -1
@@ -1 +1 @@
1
- {"version":3,"file":"env-names.d.ts","sourceRoot":"","sources":["../../src/kernel/env-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAGxD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAC1D,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAChE,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAC9E,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AACtE,eAAO,MAAM,qBAAqB,+BAA+B,CAAC;AAClE,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AACtE,eAAO,MAAM,0BAA0B,oCAAoC,CAAC;AAC5E,eAAO,MAAM,cAAc,wBAAwB,CAAC;AACpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAC9C,oHAAoH;AACpH,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EA0B/C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuB5D,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,EAAE,CASvE;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK3E"}
1
+ {"version":3,"file":"env-names.d.ts","sourceRoot":"","sources":["../../src/kernel/env-names.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAGxD,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAC1D,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAChE,eAAO,MAAM,2BAA2B,qCAAqC,CAAC;AAC9E,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AACpE,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AACtE,iHAAiH;AACjH,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAC1D,eAAO,MAAM,qBAAqB,+BAA+B,CAAC;AAClE,eAAO,MAAM,uBAAuB,iCAAiC,CAAC;AACtE,eAAO,MAAM,0BAA0B,oCAAoC,CAAC;AAC5E,eAAO,MAAM,cAAc,wBAAwB,CAAC;AACpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,yBAAyB,CAAC;AACtD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,qBAAqB,CAAC;AAC9C,oHAAoH;AACpH,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EA2B/C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuB5D,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,EAAE,CASvE;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAK3E"}
@@ -32,6 +32,8 @@ export const ENV_APPROVAL_TIMEOUT = "PI_DADDY_APPROVAL_TIMEOUT";
32
32
  export const ENV_ALLOW_UNRESOLVED_MODELS = "PI_DADDY_ALLOW_UNRESOLVED_MODELS";
33
33
  export const ENV_WORKSPACE_REGISTRY = "PI_DADDY_WORKSPACE_REGISTRY";
34
34
  export const ENV_WORKSPACE_LEASE_DIR = "PI_DADDY_WORKSPACE_LEASE_DIR";
35
+ /** ADR-0042: what each authorised workspace id MEANT when the grant was established. Authority, not metadata. */
36
+ export const ENV_WORKSPACE_PIN = "PI_DADDY_WORKSPACE_PIN";
35
37
  export const ENV_EXECUTION_ARCHIVE = "PI_DADDY_EXECUTION_ARCHIVE";
36
38
  export const ENV_NATIVE_SESSION_ROOT = "PI_DADDY_NATIVE_SESSION_ROOT";
37
39
  export const ENV_RETAIN_NATIVE_SESSIONS = "PI_DADDY_RETAIN_NATIVE_SESSIONS";
@@ -80,6 +82,7 @@ export const GOVERNANCE_ENV_KEYS = Object.freeze([
80
82
  ENV_ALLOW_UNRESOLVED_MODELS,
81
83
  ENV_WORKSPACE_REGISTRY,
82
84
  ENV_WORKSPACE_LEASE_DIR,
85
+ ENV_WORKSPACE_PIN,
83
86
  ENV_EXECUTION_ARCHIVE,
84
87
  ENV_NATIVE_SESSION_ROOT,
85
88
  ENV_RETAIN_NATIVE_SESSIONS,
@@ -1 +1 @@
1
- {"version":3,"file":"env-names.js","sourceRoot":"","sources":["../../src/kernel/env-names.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"env-names.js","sourceRoot":"","sources":["../../src/kernel/env-names.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@
25
25
  * interceptor and pi handed the child more than the parent held, the intersection clamps it back.
26
26
  */
27
27
  import type { Capability } from "./resolve.ts";
28
+ import { type WorkspacePins } from "./workspace-pin.ts";
28
29
  import { type InheritableApproval } from "./approval.ts";
29
30
  export { ENV_GRANT, ENV_FANOUT, ENV_PARENT_ID, ENV_EXECUTION_ID, ENV_DEPTH, ENV_MAX_DEPTH, ENV_GATED, ENV_LEDGER, ENV_APPROVED, } from "./env-names.ts";
30
31
  /**
@@ -47,7 +48,7 @@ export { ENV_GRANT, ENV_FANOUT, ENV_PARENT_ID, ENV_EXECUTION_ID, ENV_DEPTH, ENV_
47
48
  * environment into a child's — a governance variable a child inherits by accident is one nobody decided
48
49
  * to give it.
49
50
  */
50
- export declare const GRANT_ENV_KEYS: readonly ["PI_DADDY_ADVISOR_KEY", "PI_DADDY_ADVISOR", "PI_DADDY_GRANT", "PI_DADDY_DEPTH", "PI_DADDY_MAX_DEPTH", "PI_DADDY_GATED", "PI_DADDY_LEDGER", "PI_DADDY_APPROVED", "PI_DADDY_FANOUT", "PI_DADDY_PARENT_ID", "PI_DADDY_EXECUTION_ID"];
51
+ export declare const GRANT_ENV_KEYS: readonly ["PI_DADDY_ADVISOR_KEY", "PI_DADDY_ADVISOR", "PI_DADDY_GRANT", "PI_DADDY_DEPTH", "PI_DADDY_MAX_DEPTH", "PI_DADDY_GATED", "PI_DADDY_LEDGER", "PI_DADDY_APPROVED", "PI_DADDY_FANOUT", "PI_DADDY_PARENT_ID", "PI_DADDY_EXECUTION_ID", "PI_DADDY_WORKSPACE_PIN"];
51
52
  export declare const parseList: (raw: string | undefined) => Capability[];
52
53
  /**
53
54
  * Derive this session's own grant from what it inherited and what pi actually gave it.
@@ -119,6 +120,14 @@ export declare function gatedFromEnv(raw: string | undefined): Capability[];
119
120
  export interface ChildEnvInput {
120
121
  /** This session's own grant — becomes the child's inherited parent grant. */
121
122
  ownGrant: Capability[];
123
+ /**
124
+ * This session's destination pins (ADR-0042), narrowed here to what the child's grant names.
125
+ *
126
+ * Passed in rather than read from the environment for the reason `inheritableGrant`'s comment records: a rule
127
+ * with two spellings gets the guard on the quieter one. Absent means this session established none, and the
128
+ * child then inherits no pin and can route nowhere — which is the fail-closed direction.
129
+ */
130
+ workspacePin?: WorkspacePins;
122
131
  /** This session's depth; children are one deeper. */
123
132
  depth: number;
124
133
  maxDepth: number;
@@ -179,6 +188,20 @@ export interface ChildEnvInput {
179
188
  */
180
189
  export declare function inheritableGrant(grant: readonly Capability[]): Capability[];
181
190
  export declare function childEnv(input: ChildEnvInput): Record<string, string>;
191
+ /**
192
+ * The destination-pin half of a child's environment (ADR-0042), spelled ONCE for both spawn paths.
193
+ *
194
+ * **There are two places a child's environment is built**, and this file already carries the scar: the
195
+ * "held but never inherited" rule for `workspace:*` lived only in `childEnv`, so `delegate.ts` — the path a
196
+ * delegated child's grant actually travels — handed the wildcard straight down, and the test written beside
197
+ * that fix exercised the wrong path. The pin reached the same fork. The ADR is explicit that "the process and
198
+ * Herdr paths must share one propagation builder", so this is that builder and both callers use it.
199
+ *
200
+ * Written even when it narrows to nothing, and omitted only when this session has no pin at all: an omitted
201
+ * key does not overwrite, so the child would inherit the parent's UNNARROWED pin through the process-global
202
+ * publication path. Empty parses back as "a pin exists and you got none of it", which refuses at routing.
203
+ */
204
+ export declare function workspacePinEnv(pins: WorkspacePins | undefined, inheritable: readonly Capability[]): Record<string, string>;
182
205
  /**
183
206
  * The environment for a child this process spawns itself: the parent's environment with every governance
184
207
  * variable stripped, then the per-child plan applied.
@@ -1 +1 @@
1
- {"version":3,"file":"propagation.d.ts","sourceRoot":"","sources":["../../src/kernel/propagation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAgB3E,OAAO,EACL,SAAS,EACT,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH;;;;GAIG;AACH,sGAAsG;AAEtG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,6OAkBjB,CAAC;AAEX,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,GAAG,SAAS,KAAG,UAAU,EAI9B,CAAC;AAkBjC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,oBAAoB,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,UAAU,EAAE,CAc/G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAO7E;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAStG;AAED,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;;;;;;;GASG;AAKH,eAAO,MAAM,aAAa,EAAE,UAAU,EAAkC,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,CAGlE;AAED,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB;;;;;;OAMG;IACH;;;OAGG;IACH,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAE3E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAI9G;AAED,2GAA2G;AAC3G,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,IAAI,CAoBlE"}
1
+ {"version":3,"file":"propagation.d.ts","sourceRoot":"","sources":["../../src/kernel/propagation.ts"],"names":[],"mappings":"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"}
@@ -24,11 +24,12 @@
24
24
  * descendant can exceed the root. It is also defence in depth — even if a spawn slipped past the
25
25
  * interceptor and pi handed the child more than the parent held, the intersection clamps it back.
26
26
  */
27
+ import { attenuateWorkspacePin, formatWorkspacePin } from "./workspace-pin.js";
27
28
  import { WILDCARD } from "./pi-tools.js";
28
29
  import { WORKSPACE_WILDCARD } from "./resolve.js";
29
30
  import { inheritApprovals } from "./approval.js";
30
31
  import { assertCapabilitiesArePropagatable } from "./capabilities.js";
31
- import { ENV_ADVISOR_MODEL, ENV_ADVISOR_KEY, ENV_ADVISOR, ENV_GRANT, ENV_FANOUT, ENV_PARENT_ID, ENV_EXECUTION_ID, ENV_DEPTH, ENV_MAX_DEPTH, ENV_GATED, ENV_LEDGER, ENV_APPROVED, } from "./env-names.js";
32
+ import { ENV_ADVISOR_MODEL, ENV_ADVISOR_KEY, ENV_ADVISOR, ENV_GRANT, ENV_FANOUT, ENV_PARENT_ID, ENV_EXECUTION_ID, ENV_DEPTH, ENV_MAX_DEPTH, ENV_GATED, ENV_LEDGER, ENV_APPROVED, ENV_WORKSPACE_PIN, } from "./env-names.js";
32
33
  export { ENV_GRANT, ENV_FANOUT, ENV_PARENT_ID, ENV_EXECUTION_ID, ENV_DEPTH, ENV_MAX_DEPTH, ENV_GATED, ENV_LEDGER, ENV_APPROVED, } from "./env-names.js";
33
34
  /**
34
35
  * Total descendants this session may create in its whole subtree (`src/kernel/fanout.ts`).
@@ -68,6 +69,9 @@ export const GRANT_ENV_KEYS = [
68
69
  ENV_FANOUT,
69
70
  ENV_PARENT_ID,
70
71
  ENV_EXECUTION_ID,
72
+ // ADR-0042: a child must never keep its parent's unnarrowed pin, so it is stripped like every other
73
+ // governance value and re-supplied only by the spawn plan.
74
+ ENV_WORKSPACE_PIN,
71
75
  ];
72
76
  export const parseList = (raw) => (raw ?? "")
73
77
  .split(",")
@@ -241,8 +245,31 @@ export function childEnv(input) {
241
245
  // Empty is an explicit one-run ledger opt-out and must overwrite a prior publication too.
242
246
  if (input.ledgerPath !== undefined)
243
247
  env[ENV_LEDGER] = input.ledgerPath;
248
+ // ADR-0042. ALWAYS written when this session has any pin at all, empty string included, for the same reason
249
+ // `ENV_APPROVED` is: an omitted key does not overwrite, so a child would inherit the PARENT's unnarrowed pin
250
+ // through the process-global publication path. An empty value parses back as "a pin was established and you
251
+ // got nothing from it", which refuses at routing with a different message from "no pin exists".
252
+ Object.assign(env, workspacePinEnv(input.workspacePin, inheritable));
244
253
  return env;
245
254
  }
255
+ /**
256
+ * The destination-pin half of a child's environment (ADR-0042), spelled ONCE for both spawn paths.
257
+ *
258
+ * **There are two places a child's environment is built**, and this file already carries the scar: the
259
+ * "held but never inherited" rule for `workspace:*` lived only in `childEnv`, so `delegate.ts` — the path a
260
+ * delegated child's grant actually travels — handed the wildcard straight down, and the test written beside
261
+ * that fix exercised the wrong path. The pin reached the same fork. The ADR is explicit that "the process and
262
+ * Herdr paths must share one propagation builder", so this is that builder and both callers use it.
263
+ *
264
+ * Written even when it narrows to nothing, and omitted only when this session has no pin at all: an omitted
265
+ * key does not overwrite, so the child would inherit the parent's UNNARROWED pin through the process-global
266
+ * publication path. Empty parses back as "a pin exists and you got none of it", which refuses at routing.
267
+ */
268
+ export function workspacePinEnv(pins, inheritable) {
269
+ return pins === undefined
270
+ ? {}
271
+ : { [ENV_WORKSPACE_PIN]: formatWorkspacePin(attenuateWorkspacePin(pins, inheritable)) };
272
+ }
246
273
  /**
247
274
  * The environment for a child this process spawns itself: the parent's environment with every governance
248
275
  * variable stripped, then the per-child plan applied.
@@ -1 +1 @@
1
- {"version":3,"file":"propagation.js","sourceRoot":"","sources":["../../src/kernel/propagation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"propagation.js","sourceRoot":"","sources":["../../src/kernel/propagation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { Capability } from "./resolve.ts";
2
+ export { ENV_WORKSPACE_PIN } from "./env-names.ts";
3
+ /** A canonical destination, reduced to something an environment variable can carry. */
4
+ export declare function destinationDigest(canonicalRoot: string): string;
5
+ export type WorkspacePins = ReadonlyMap<string, string>;
6
+ /** `id:digest` pairs. Ids cannot contain `:` or `,` — `isSafeWorkspaceId` is the reason this is unambiguous. */
7
+ export declare function formatWorkspacePin(pins: WorkspacePins): string;
8
+ export type ParsedPin = {
9
+ pins: WorkspacePins;
10
+ } | {
11
+ refusal: string;
12
+ };
13
+ /**
14
+ * Read a pin, refusing anything that is not exactly the shape this module writes.
15
+ *
16
+ * An absent variable is NOT the same as an empty one and both are distinguished by the caller: absent means no
17
+ * root ever established a pin, empty means a parent established one and this child inherited no entries. Both
18
+ * refuse at routing time; they need different messages to be diagnosable.
19
+ */
20
+ export declare function parseWorkspacePin(raw: string | undefined): ParsedPin;
21
+ /**
22
+ * The pin a child inherits: the parent's entries, narrowed to the workspaces the child's grant actually names.
23
+ *
24
+ * Narrowing here rather than passing the parent's whole map is the difference between a pin and a hint. A child
25
+ * that cannot see an entry cannot route to it even if it rewrites the registry to make the id resolve, because
26
+ * routing needs a pin entry and it has none to offer.
27
+ */
28
+ export declare function attenuateWorkspacePin(pins: WorkspacePins, inheritable: readonly Capability[]): WorkspacePins;
29
+ /**
30
+ * Does the registry still resolve this id to what the grant meant?
31
+ *
32
+ * Returns a refusal reason, or `undefined` when the destination matches. A string rather than a thrown error
33
+ * because the one caller already owns the refusal code and the `details` this belongs in.
34
+ */
35
+ export declare function checkPinnedDestination(input: {
36
+ workspaceId: string;
37
+ canonicalRoot: string;
38
+ pin: ParsedPin;
39
+ }): string | undefined;
40
+ /**
41
+ * Establish a root's pin by resolving every registered id to its canonical destination.
42
+ *
43
+ * **Only a session that inherited NO pin may call this**, and that rule is the mechanism. If a descendant could
44
+ * mint its own pin it would simply rewrite the registry and then re-establish, and the whole thing would be a
45
+ * comment. The caller enforces it because only the caller knows whether a pin was inherited; this function is
46
+ * the resolution, not the policy.
47
+ *
48
+ * An id whose destination cannot be canonicalised is LEFT OUT rather than pinned to a guess. Routing then
49
+ * refuses it for having no pin, which is the same direction as every other failure here.
50
+ */
51
+ export declare function establishWorkspacePin(registry: {
52
+ workspaces: Record<string, {
53
+ path: string;
54
+ }>;
55
+ }, canonicalise: (path: string) => Promise<string>, onSkipped?: (id: string, reason: string) => void): Promise<WorkspacePins>;
56
+ //# sourceMappingURL=workspace-pin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-pin.d.ts","sourceRoot":"","sources":["../../src/kernel/workspace-pin.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AASnD,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,gHAAgH;AAChH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAK9D;AAED,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAoBpE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,UAAU,EAAE,GAAG,aAAa,CAG5G;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,SAAS,CAAC;CAChB,GAAG,MAAM,GAAG,SAAS,CAgBrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EAC1D,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAC/C,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAC/C,OAAO,CAAC,aAAa,CAAC,CAmBxB"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * The inherited destination pin (ADR-0042): what a workspace id MEANT when the authority was granted.
3
+ *
4
+ * **The escalation this closes, measured in `g37-registry-tamper`.** `workspace:<id>` attenuates the NAME, not
5
+ * the mutable id-to-path meaning. A child holding `workspace:staging` and `tool:write` — no `bash` — can rewrite
6
+ * the operator's registry so `staging` points at the `prod` worktree, route a grandchild there, and take an
7
+ * exclusive write lease on it. Every capability check passes, because the id it was granted is the id it used.
8
+ * File ownership cannot help: a governed child runs as the parent's uid, so the registry is as writable to it as
9
+ * to the operator.
10
+ *
11
+ * **The mechanism is authority, not metadata.** A root resolves each registered id to its canonical destination
12
+ * and records a digest of it. Descendants inherit only the entries their effective grant authorises, cannot mint
13
+ * an entry, and routing requires an exact match against the inherited digest. A rewritten registry therefore
14
+ * changes where an id points and NOT what an inherited id is allowed to mean, which is the whole property.
15
+ *
16
+ * **Why a digest rather than the path.** The path is already visible to the child through the registry it can
17
+ * read; pinning the digest keeps the wire small for a realistic registry and makes an equality check the only
18
+ * operation, so there is no path-comparison subtlety to get wrong. `validateRegisteredWorkspace` still does the
19
+ * canonicalisation; this only asks whether the answer changed.
20
+ *
21
+ * **Every failure refuses.** Missing, empty, malformed and mismatched all refuse, because the alternative is a
22
+ * mechanism a child can disable by corrupting one byte. ADR-0042 records that an earlier attempt was reverted
23
+ * after four failures, and that it failed "specifically because it was treated as a small patch".
24
+ */
25
+ import { createHash } from "node:crypto";
26
+ import { isSafeWorkspaceId, workspaceCapability } from "./capabilities.js";
27
+ export { ENV_WORKSPACE_PIN } from "./env-names.js";
28
+ /**
29
+ * Half a SHA-256, hex. The comparison is equality against a value the operator's own root computed, not a
30
+ * signature, so this is sized to make accidental collision impossible rather than to resist an adversary who
31
+ * can already choose both sides.
32
+ */
33
+ const DIGEST_HEX = 32;
34
+ /** A canonical destination, reduced to something an environment variable can carry. */
35
+ export function destinationDigest(canonicalRoot) {
36
+ return createHash("sha256").update(canonicalRoot, "utf8").digest("hex").slice(0, DIGEST_HEX);
37
+ }
38
+ /** `id:digest` pairs. Ids cannot contain `:` or `,` — `isSafeWorkspaceId` is the reason this is unambiguous. */
39
+ export function formatWorkspacePin(pins) {
40
+ return [...pins.entries()]
41
+ .sort(([a], [b]) => a.localeCompare(b))
42
+ .map(([id, digest]) => `${id}:${digest}`)
43
+ .join(",");
44
+ }
45
+ /**
46
+ * Read a pin, refusing anything that is not exactly the shape this module writes.
47
+ *
48
+ * An absent variable is NOT the same as an empty one and both are distinguished by the caller: absent means no
49
+ * root ever established a pin, empty means a parent established one and this child inherited no entries. Both
50
+ * refuse at routing time; they need different messages to be diagnosable.
51
+ */
52
+ export function parseWorkspacePin(raw) {
53
+ if (raw === undefined)
54
+ return { refusal: "no destination pin was inherited" };
55
+ const trimmed = raw.trim();
56
+ if (trimmed === "")
57
+ return { pins: new Map() };
58
+ const pins = new Map();
59
+ for (const entry of trimmed.split(",")) {
60
+ const at = entry.lastIndexOf(":");
61
+ if (at <= 0)
62
+ return { refusal: `destination pin entry ${JSON.stringify(entry)} is not id:digest` };
63
+ const id = entry.slice(0, at);
64
+ const digest = entry.slice(at + 1);
65
+ if (!isSafeWorkspaceId(id))
66
+ return { refusal: `destination pin names a malformed workspace id ${JSON.stringify(id)}` };
67
+ if (!/^[0-9a-f]{32}$/.test(digest))
68
+ return { refusal: `destination pin for ${id} is not a ${DIGEST_HEX}-character digest` };
69
+ // A duplicated id with two digests is ambiguous, and picking either would let a tamperer supply both.
70
+ if (pins.has(id) && pins.get(id) !== digest)
71
+ return { refusal: `destination pin names ${id} twice with different destinations` };
72
+ pins.set(id, digest);
73
+ }
74
+ return { pins };
75
+ }
76
+ /**
77
+ * The pin a child inherits: the parent's entries, narrowed to the workspaces the child's grant actually names.
78
+ *
79
+ * Narrowing here rather than passing the parent's whole map is the difference between a pin and a hint. A child
80
+ * that cannot see an entry cannot route to it even if it rewrites the registry to make the id resolve, because
81
+ * routing needs a pin entry and it has none to offer.
82
+ */
83
+ export function attenuateWorkspacePin(pins, inheritable) {
84
+ const held = new Set(inheritable);
85
+ return new Map([...pins.entries()].filter(([id]) => held.has(workspaceCapability(id))));
86
+ }
87
+ /**
88
+ * Does the registry still resolve this id to what the grant meant?
89
+ *
90
+ * Returns a refusal reason, or `undefined` when the destination matches. A string rather than a thrown error
91
+ * because the one caller already owns the refusal code and the `details` this belongs in.
92
+ */
93
+ export function checkPinnedDestination(input) {
94
+ if ("refusal" in input.pin)
95
+ return input.pin.refusal;
96
+ const expected = input.pin.pins.get(input.workspaceId);
97
+ if (expected === undefined)
98
+ return (`no destination pin was inherited for workspace ${input.workspaceId}` +
99
+ (input.pin.pins.size > 0 ? ` — pinned: ${[...input.pin.pins.keys()].sort().join(", ")}` : ""));
100
+ const actual = destinationDigest(input.canonicalRoot);
101
+ if (actual !== expected)
102
+ return (`workspace ${input.workspaceId} now resolves to ${input.canonicalRoot}, which is not the destination this ` +
103
+ `session was granted. The registry has been rewritten since the grant was established, so the id no longer ` +
104
+ `means what it meant when it was authorised (ADR-0042)`);
105
+ return undefined;
106
+ }
107
+ /**
108
+ * Establish a root's pin by resolving every registered id to its canonical destination.
109
+ *
110
+ * **Only a session that inherited NO pin may call this**, and that rule is the mechanism. If a descendant could
111
+ * mint its own pin it would simply rewrite the registry and then re-establish, and the whole thing would be a
112
+ * comment. The caller enforces it because only the caller knows whether a pin was inherited; this function is
113
+ * the resolution, not the policy.
114
+ *
115
+ * An id whose destination cannot be canonicalised is LEFT OUT rather than pinned to a guess. Routing then
116
+ * refuses it for having no pin, which is the same direction as every other failure here.
117
+ */
118
+ export async function establishWorkspacePin(registry, canonicalise, onSkipped) {
119
+ const pins = new Map();
120
+ for (const [id, entry] of Object.entries(registry.workspaces)) {
121
+ if (!isSafeWorkspaceId(id)) {
122
+ onSkipped?.(id, "its id is malformed");
123
+ continue;
124
+ }
125
+ try {
126
+ pins.set(id, destinationDigest(await canonicalise(entry.path)));
127
+ }
128
+ catch (error) {
129
+ // Rule 8, and `registeredWorkspaceIds` one file over carries the long version of why: this was a bare
130
+ // `catch {}`, so an unmounted worktree or a directory not yet created dropped a workspace silently and
131
+ // the operator met it later as "no destination pin was inherited", a message that names neither the
132
+ // directory nor the reason. Unresolvable still means no pin — routing must not invent one — but the
133
+ // caller is told which id and why.
134
+ onSkipped?.(id, `its destination could not be canonicalised (${String(error)})`);
135
+ }
136
+ }
137
+ return pins;
138
+ }
139
+ //# sourceMappingURL=workspace-pin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-pin.js","sourceRoot":"","sources":["../../src/kernel/workspace-pin.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type ParsedPin } from "./workspace-pin.ts";
1
2
  export { ENV_WORKSPACE_REGISTRY } from "./env-names.ts";
2
3
  export type WorkspaceAccess = "read" | "write";
3
4
  export interface WorkspaceRegistryFile {
@@ -44,11 +45,29 @@ export declare function loadWorkspaceRegistry(path: string): Promise<WorkspaceRe
44
45
  * the old behaviour, which is why this is an optional parameter and not a changed return type.
45
46
  */
46
47
  export declare function registeredWorkspaceIds(registryPath?: string | undefined, onRefusal?: (reason: string) => void): Promise<string[]>;
47
- export declare function resolveWorkspace(registry: WorkspaceRegistryFile, workspaceId: string): Promise<ValidatedWorkspace>;
48
+ /**
49
+ * Resolve an authorised id to a worktree, refusing if the id no longer means what the grant meant.
50
+ *
51
+ * **`pin` is REQUIRED, and it used to default to reading the environment.** That default was the last
52
+ * environment fallback in the routing path, and it was the wrong reassurance: after `publishChildEnv` the
53
+ * variable holds a session's CHILD's pin, so a two-argument call checked a session against its child's
54
+ * authority. It is dead in-tree — the one production caller always passes one — but this is a public export,
55
+ * so an embedder could reach it. Requiring the argument closes it permanently and makes "a session's own pin
56
+ * lives in memory" unbreakable rather than merely currently-true.
57
+ */
58
+ export declare function resolveWorkspace(registry: WorkspaceRegistryFile, workspaceId: string, pin: ParsedPin): Promise<ValidatedWorkspace>;
48
59
  /**
49
60
  * Canonicalize and validate the initial workspace against Git's registered worktree list.
50
61
  * This prevents accidental misrouting. It does not constrain any path a child accesses after spawn.
51
62
  */
63
+ /**
64
+ * Canonicalise and verify a registered root as a git worktree.
65
+ *
66
+ * **This performs NO destination-pin check (ADR-0042), deliberately and dangerously.** It answers "is this
67
+ * path the worktree it claims to be", not "may this session route here" — `resolveWorkspace` is the one that
68
+ * asks the second question, and it is the only path production takes. It is a public export, so it is said
69
+ * here rather than left to be discovered: an embedder calling this directly routes unpinned.
70
+ */
52
71
  export declare function validateRegisteredWorkspace(input: {
53
72
  workspaceId: string;
54
73
  registeredRoot: string;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/kernel/workspace.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAsBD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAyFxF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,qBAAsC,EAClD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GACnC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CAe7B;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0D9B"}
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/kernel/workspace.ts"],"names":[],"mappings":"AAWA,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAsBD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAyFxF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,qBAAsC,EAClD,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GACnC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,qBAAqB,EAC/B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,SAAS,GACb,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED;;;GAGG;AACH;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0D9B"}
@@ -9,6 +9,7 @@ import { promisify } from "node:util";
9
9
  import { GovernanceRefusal, refusal } from "./refusals.js";
10
10
  import { isSafeWorkspaceId, workspaceCapability } from "./capabilities.js";
11
11
  import { ENV_WORKSPACE_REGISTRY } from "./env-names.js";
12
+ import { checkPinnedDestination } from "./workspace-pin.js";
12
13
  export { ENV_WORKSPACE_REGISTRY } from "./env-names.js";
13
14
  const execFileAsync = promisify(execFile);
14
15
  /**
@@ -127,7 +128,17 @@ export async function registeredWorkspaceIds(registryPath = process.env[ENV_WORK
127
128
  return [];
128
129
  }
129
130
  }
130
- export async function resolveWorkspace(registry, workspaceId) {
131
+ /**
132
+ * Resolve an authorised id to a worktree, refusing if the id no longer means what the grant meant.
133
+ *
134
+ * **`pin` is REQUIRED, and it used to default to reading the environment.** That default was the last
135
+ * environment fallback in the routing path, and it was the wrong reassurance: after `publishChildEnv` the
136
+ * variable holds a session's CHILD's pin, so a two-argument call checked a session against its child's
137
+ * authority. It is dead in-tree — the one production caller always passes one — but this is a public export,
138
+ * so an embedder could reach it. Requiring the argument closes it permanently and makes "a session's own pin
139
+ * lives in memory" unbreakable rather than merely currently-true.
140
+ */
141
+ export async function resolveWorkspace(registry, workspaceId, pin) {
131
142
  const registered = Object.hasOwn(registry.workspaces, workspaceId) ? registry.workspaces[workspaceId] : undefined;
132
143
  const known = Object.keys(registry.workspaces).sort();
133
144
  if (!registered) {
@@ -135,12 +146,31 @@ export async function resolveWorkspace(registry, workspaceId) {
135
146
  (registry.source ? ` ${registry.source}` : "") +
136
147
  (known.length > 0 ? ` — it lists: ${known.join(", ")}` : " — it lists nothing"), { workspace_id: workspaceId, ...(registry.source ? { registry_path: registry.source } : {}) }));
137
148
  }
138
- return validateRegisteredWorkspace({ workspaceId, registeredRoot: registered.path });
149
+ const validated = await validateRegisteredWorkspace({ workspaceId, registeredRoot: registered.path });
150
+ // **ADR-0042, and it is checked HERE on purpose.** The capability check upstream asks whether this session may
151
+ // route to this NAME. This asks whether the name still points where it pointed when the name was granted —
152
+ // the question `g37-registry-tamper` showed nobody was asking. It runs after canonicalisation because the
153
+ // digest is of the canonical root; comparing the registry's raw string would be defeated by a symlink.
154
+ const mismatch = checkPinnedDestination({ workspaceId, canonicalRoot: validated.root, pin });
155
+ if (mismatch)
156
+ throw new GovernanceRefusal(refusal("WORKSPACE_NOT_AUTHORIZED", `workspace ${workspaceId} is not routable: ${mismatch}`, {
157
+ workspace_id: workspaceId,
158
+ resolved_root: validated.root,
159
+ }));
160
+ return validated;
139
161
  }
140
162
  /**
141
163
  * Canonicalize and validate the initial workspace against Git's registered worktree list.
142
164
  * This prevents accidental misrouting. It does not constrain any path a child accesses after spawn.
143
165
  */
166
+ /**
167
+ * Canonicalise and verify a registered root as a git worktree.
168
+ *
169
+ * **This performs NO destination-pin check (ADR-0042), deliberately and dangerously.** It answers "is this
170
+ * path the worktree it claims to be", not "may this session route here" — `resolveWorkspace` is the one that
171
+ * asks the second question, and it is the only path production takes. It is a public export, so it is said
172
+ * here rather than left to be discovered: an embedder calling this directly routes unpinned.
173
+ */
144
174
  export async function validateRegisteredWorkspace(input) {
145
175
  let registered;
146
176
  let supplied;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/kernel/workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/kernel/workspace.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ import { randomUUID } from "node:crypto";
19
19
  import { closeSync, mkdirSync, openSync, readSync, realpathSync, rmSync, statSync } from "node:fs";
20
20
  import { isAbsolute, relative, resolve } from "node:path";
21
21
  import {
22
+ CONTEXT_RANK,
22
23
  fenceContext,
23
24
  selectPrunedTurns,
24
25
  type ContextRequest,
@@ -69,14 +70,21 @@ export function createHandoffStager(input: StagingInput) {
69
70
  return (granted: ContextRequest, options: { keepTurnIds?: readonly string[] } = {}): StagedHandoff => {
70
71
  if (granted.mode === "fork") return stageFork(input);
71
72
  const sections: ContextSection[] = [];
73
+ /** Which entries of `sections` are parent turns, so the record can count the ones that survived the cap. */
74
+ const turnSectionIndices: number[] = [];
72
75
  let keptTurns: number | undefined;
73
76
  let droppedTurns: number | undefined;
74
77
  let rule: string | undefined;
75
78
 
76
79
  if (granted.mode === "summary")
77
- sections.push({ label: "what your parent says you need to know", body: granted.summary ?? "" });
80
+ sections.push({
81
+ label: "what your parent says you need to know",
82
+ body: granted.summary ?? "",
83
+ keepRank: CONTEXT_RANK.summary,
84
+ });
78
85
  if (granted.mode === "files" || granted.mode === "pruned")
79
- for (const path of granted.files ?? []) sections.push(readSection(input.cwd, path));
86
+ for (const path of granted.files ?? [])
87
+ sections.push({ ...readSection(input.cwd, path), keepRank: CONTEXT_RANK.file });
80
88
  if (granted.mode === "pruned") {
81
89
  const all = parentTurns(input.parentSession);
82
90
  const selection = selectPrunedTurns(all, {
@@ -93,20 +101,39 @@ export function createHandoffStager(input: StagingInput) {
93
101
  keptTurns = chosen.length;
94
102
  droppedTurns = all.length - chosen.length;
95
103
  rule = options.keepTurnIds === undefined ? selection.rule : `${selection.rule}+advice`;
96
- for (const turn of chosen) sections.push({ label: `parent turn ${turn.id}`, body: turn.text });
104
+ // Two bands, then position within the band. The probe measured array-order filling losing exactly the
105
+ // turns nearest the task; review then measured the first fix losing the file-matched turns instead,
106
+ // because those sit at the FRONT of `chosen` and a bare positional rank made oldest mean least.
107
+ const matched = new Set(selection.fileMatched);
108
+ chosen.forEach((turn, index) => {
109
+ turnSectionIndices.push(sections.length);
110
+ sections.push({
111
+ label: `parent turn ${turn.id}`,
112
+ body: turn.text,
113
+ keepRank: (matched.has(turn.id) ? CONTEXT_RANK.fileMatchedTurn : CONTEXT_RANK.recentTurn) + index,
114
+ });
115
+ });
97
116
  if (chosen.length === 0)
98
117
  sections.push({ label: "parent turns", body: "(no turn of your parent's session matched the selection)" });
99
118
  }
100
119
 
101
120
  const fenced = fenceContext(sections);
121
+ // **The record counts what CROSSED, which is what this module says it does.** These were counted before
122
+ // the budget ran, so a handoff could record `keptTurns: 21` having sent thirteen. Review measured it, and
123
+ // raising the default turn count moved the cap from binding in 13% of handoffs to 60% — so the wrong
124
+ // number became the usual number.
125
+ const crossed = new Set(fenced.keptIndices);
126
+ const turnsCrossed = turnSectionIndices.filter((index) => crossed.has(index)).length;
102
127
  return {
103
128
  contextPrompt: fenced.text,
104
129
  record: {
105
130
  mode: granted.mode,
106
- sections: sections.length,
131
+ sections: fenced.keptIndices.length,
107
132
  bytes: Buffer.byteLength(fenced.text),
108
133
  truncatedBytes: fenced.truncatedBytes,
109
- ...(keptTurns !== undefined ? { keptTurns, droppedTurns, rule } : {}),
134
+ ...(keptTurns !== undefined
135
+ ? { keptTurns: turnsCrossed, droppedTurns: droppedTurns! + (keptTurns - turnsCrossed), rule }
136
+ : {}),
110
137
  },
111
138
  };
112
139
  };