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.
- package/CHANGELOG.md +131 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/kernel/context-handoff.d.ts +71 -1
- package/dist/kernel/context-handoff.d.ts.map +1 -1
- package/dist/kernel/context-handoff.js +65 -6
- package/dist/kernel/context-handoff.js.map +1 -1
- package/dist/kernel/delegate-types.d.ts +9 -0
- package/dist/kernel/delegate-types.d.ts.map +1 -1
- package/dist/kernel/delegate-types.js.map +1 -1
- package/dist/kernel/delegate.d.ts.map +1 -1
- package/dist/kernel/delegate.js +6 -1
- package/dist/kernel/delegate.js.map +1 -1
- package/dist/kernel/env-names.d.ts +2 -0
- package/dist/kernel/env-names.d.ts.map +1 -1
- package/dist/kernel/env-names.js +3 -0
- package/dist/kernel/env-names.js.map +1 -1
- package/dist/kernel/propagation.d.ts +24 -1
- package/dist/kernel/propagation.d.ts.map +1 -1
- package/dist/kernel/propagation.js +28 -1
- package/dist/kernel/propagation.js.map +1 -1
- package/dist/kernel/workspace-pin.d.ts +56 -0
- package/dist/kernel/workspace-pin.d.ts.map +1 -0
- package/dist/kernel/workspace-pin.js +139 -0
- package/dist/kernel/workspace-pin.js.map +1 -0
- package/dist/kernel/workspace.d.ts +20 -1
- package/dist/kernel/workspace.d.ts.map +1 -1
- package/dist/kernel/workspace.js +32 -2
- package/dist/kernel/workspace.js.map +1 -1
- package/extensions/context-staging.ts +32 -5
- package/extensions/grants-command.ts +16 -1
- package/extensions/grants.ts +1 -0
- package/extensions/pruning-advice.ts +20 -8
- package/extensions/reload-environment.ts +25 -0
- package/extensions/run-delegation.ts +1 -0
- package/extensions/session-report.ts +7 -0
- package/extensions/session.ts +111 -0
- package/extensions/workspace-runtime.ts +16 -1
- package/package.json +1 -1
- package/src/index.ts +13 -0
- package/src/kernel/context-handoff.ts +96 -6
- package/src/kernel/delegate-types.ts +9 -0
- package/src/kernel/delegate.ts +6 -0
- package/src/kernel/env-names.ts +3 -0
- package/src/kernel/propagation.ts +40 -0
- package/src/kernel/workspace-pin.ts +158 -0
- 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,
|
|
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"}
|
package/dist/kernel/env-names.js
CHANGED
|
@@ -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;
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAA4B,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,iCAAiC,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,
|
|
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
|
-
|
|
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,
|
|
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"}
|
package/dist/kernel/workspace.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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({
|
|
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 ?? [])
|
|
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
|
-
|
|
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:
|
|
131
|
+
sections: fenced.keptIndices.length,
|
|
107
132
|
bytes: Buffer.byteLength(fenced.text),
|
|
108
133
|
truncatedBytes: fenced.truncatedBytes,
|
|
109
|
-
...(keptTurns !== undefined
|
|
134
|
+
...(keptTurns !== undefined
|
|
135
|
+
? { keptTurns: turnsCrossed, droppedTurns: droppedTurns! + (keptTurns - turnsCrossed), rule }
|
|
136
|
+
: {}),
|
|
110
137
|
},
|
|
111
138
|
};
|
|
112
139
|
};
|