pi-daddy 0.17.0 → 0.18.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 (113) hide show
  1. package/CHANGELOG.md +154 -80
  2. package/README.md +54 -25
  3. package/dist/approval-prompt.d.ts +3 -1
  4. package/dist/approval-prompt.d.ts.map +1 -1
  5. package/dist/approval-prompt.js +1 -1
  6. package/dist/approval-prompt.js.map +1 -1
  7. package/dist/approval-store.d.ts.map +1 -1
  8. package/dist/approval-store.js +4 -1
  9. package/dist/approval-store.js.map +1 -1
  10. package/dist/approval.d.ts +20 -2
  11. package/dist/approval.d.ts.map +1 -1
  12. package/dist/approval.js +26 -6
  13. package/dist/approval.js.map +1 -1
  14. package/dist/chain.d.ts +6 -1
  15. package/dist/chain.d.ts.map +1 -1
  16. package/dist/chain.js +1 -1
  17. package/dist/chain.js.map +1 -1
  18. package/dist/check-runner.d.ts +61 -0
  19. package/dist/check-runner.d.ts.map +1 -0
  20. package/dist/check-runner.js +237 -0
  21. package/dist/check-runner.js.map +1 -0
  22. package/dist/correlation.d.ts +90 -0
  23. package/dist/correlation.d.ts.map +1 -0
  24. package/dist/correlation.js +183 -0
  25. package/dist/correlation.js.map +1 -0
  26. package/dist/delegate-types.d.ts +140 -0
  27. package/dist/delegate-types.d.ts.map +1 -0
  28. package/dist/delegate-types.js +8 -0
  29. package/dist/delegate-types.js.map +1 -0
  30. package/dist/delegate.d.ts +4 -128
  31. package/dist/delegate.d.ts.map +1 -1
  32. package/dist/delegate.js +68 -72
  33. package/dist/delegate.js.map +1 -1
  34. package/dist/delegation-approval.d.ts +36 -0
  35. package/dist/delegation-approval.d.ts.map +1 -0
  36. package/dist/delegation-approval.js +67 -0
  37. package/dist/delegation-approval.js.map +1 -0
  38. package/dist/git-identity.d.ts +13 -0
  39. package/dist/git-identity.d.ts.map +1 -0
  40. package/dist/git-identity.js +44 -0
  41. package/dist/git-identity.js.map +1 -0
  42. package/dist/index.d.ts +5 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +5 -1
  45. package/dist/index.js.map +1 -1
  46. package/dist/lease-record.d.ts +78 -0
  47. package/dist/lease-record.d.ts.map +1 -0
  48. package/dist/lease-record.js +52 -0
  49. package/dist/lease-record.js.map +1 -0
  50. package/dist/ledger-events.d.ts +87 -0
  51. package/dist/ledger-events.d.ts.map +1 -0
  52. package/dist/ledger-events.js +45 -0
  53. package/dist/ledger-events.js.map +1 -0
  54. package/dist/ledger-report.d.ts +19 -12
  55. package/dist/ledger-report.d.ts.map +1 -1
  56. package/dist/ledger-report.js +81 -1
  57. package/dist/ledger-report.js.map +1 -1
  58. package/dist/ledger.d.ts +44 -1
  59. package/dist/ledger.d.ts.map +1 -1
  60. package/dist/ledger.js +20 -2
  61. package/dist/ledger.js.map +1 -1
  62. package/dist/refusals.d.ts +16 -0
  63. package/dist/refusals.d.ts.map +1 -0
  64. package/dist/refusals.js +51 -0
  65. package/dist/refusals.js.map +1 -0
  66. package/dist/run-child.d.ts +4 -0
  67. package/dist/run-child.d.ts.map +1 -1
  68. package/dist/run-child.js +21 -1
  69. package/dist/run-child.js.map +1 -1
  70. package/dist/run-herdr.d.ts +7 -0
  71. package/dist/run-herdr.d.ts.map +1 -1
  72. package/dist/run-herdr.js +41 -12
  73. package/dist/run-herdr.js.map +1 -1
  74. package/dist/workspace-lease.d.ts +28 -0
  75. package/dist/workspace-lease.d.ts.map +1 -0
  76. package/dist/workspace-lease.js +276 -0
  77. package/dist/workspace-lease.js.map +1 -0
  78. package/dist/workspace.d.ts +32 -0
  79. package/dist/workspace.d.ts.map +1 -0
  80. package/dist/workspace.js +79 -0
  81. package/dist/workspace.js.map +1 -0
  82. package/extensions/approval-banking.ts +66 -0
  83. package/extensions/approvals.ts +95 -7
  84. package/extensions/chain-approval-facts.ts +51 -0
  85. package/extensions/chain-ledger.ts +48 -0
  86. package/extensions/delegate-chain.ts +115 -81
  87. package/extensions/delegation.ts +81 -23
  88. package/extensions/execute-child.ts +289 -0
  89. package/extensions/fanout-outcome.ts +97 -0
  90. package/extensions/run-delegation.ts +130 -120
  91. package/extensions/session.ts +4 -0
  92. package/extensions/workspace-runtime.ts +165 -0
  93. package/package.json +17 -1
  94. package/src/approval-prompt.ts +4 -2
  95. package/src/approval-store.ts +4 -1
  96. package/src/approval.ts +47 -14
  97. package/src/chain.ts +3 -1
  98. package/src/check-runner.ts +341 -0
  99. package/src/correlation.ts +260 -0
  100. package/src/delegate-types.ts +144 -0
  101. package/src/delegate.ts +80 -179
  102. package/src/delegation-approval.ts +99 -0
  103. package/src/git-identity.ts +52 -0
  104. package/src/index.ts +50 -0
  105. package/src/lease-record.ts +119 -0
  106. package/src/ledger-events.ts +138 -0
  107. package/src/ledger-report.ts +90 -2
  108. package/src/ledger.ts +68 -3
  109. package/src/refusals.ts +66 -0
  110. package/src/run-child.ts +23 -1
  111. package/src/run-herdr.ts +41 -11
  112. package/src/workspace-lease.ts +303 -0
  113. package/src/workspace.ts +135 -0
package/CHANGELOG.md CHANGED
@@ -12,86 +12,79 @@ the record of how the package got here and are worth keeping; they are not worth
12
12
  > the record of how the package arrived at what it does, and because the reasoning behind each one is
13
13
  > usually the clearest statement of why the current behaviour is what it is.
14
14
 
15
- ## 0.14.0 — `pi-daddy init`, and a startup line that names what it will and will not spawn
16
-
17
- > **Reviewed before release by five independent agents, one hypothesis each. All five found something, and
18
- > nine defects were fixed here** including one that executed arbitrary code from the file this feature
19
- > tells you to commit (R-78), one that overwrote an operator's file and wrote through symlinks (R-79), and
20
- > one where the startup line blamed your `SKILL.md` files for a misconfigured environment variable (R-81).
21
- > **ADR-0029 came out of that review**: the generated grant is read-only by default. The reasoning for each
22
- > is in `docs/03-risks.md` R-78 through R-82.
23
-
24
- The pi-daddy half of making this package and a package of skills work together out of the box
25
- (`docs/HANDOFF-principal-pi-skills-integration.md`, items B1/B2/B4; **ADR-0028**). Nothing about grant
26
- resolution, enforcement, approvals or the ledger changed this is the part before and around them.
27
-
28
- - **The generated grant is READ-ONLY by default** (ADR-0029). `init` grants what the copied skills declare
29
- minus anything that can change your machine — `bash`, `write`, `edit` and the universal capabilities are
30
- written **commented**, naming the definitions that need them. `init` + `source` gives a working read-only
31
- setup; widening costs one deliberate uncomment. The reason: `PI_GRANTS_GRANT` is what *bounds* a declared
32
- ceiling, so generating it from those ceilings would give the bound and the bounded one author, and it
33
- would not be you.
34
-
35
- - **`npx pi-daddy init` scaffolds a governed project.** It reads `<cwd>/node_modules` for packages declaring
36
- skills in their own `package.json` (`"pi": {"skills": [...]}`, pi's convention), copies each declared
37
- `SKILL.md` into `.pi/skills/`, and writes an annotated `.pi/grants.env`. That replaces, per skill: make a
38
- directory, copy the body, hand-write frontmatter, choose a capability set with no guidance, and assemble a
39
- `PI_GRANTS_GRANT` string by hand — seven times for `principal-pi-skills`.
40
-
41
- **It chooses no ceiling, and that boundary is the whole design.** A skill that declares `allowed-tools` is
42
- copied byte for byte; one that declares none is copied with a *commented* placeholder and stays
43
- unspawnable until a human fills it in. The placeholder is deliberately not a working example, so
44
- uncommenting it unedited fails loudly instead of granting something nobody decided. An existing file is
45
- **kept**, never overwritten that edit is the capability decision, and a second `init` run is exactly
46
- when it would be destroyed. `--force` exists and says what it costs.
47
-
48
- - **Session start says how many definitions are spawnable, and names the withheld ones.** The line reported
49
- the grant and never the definitions, so *"governance is working"* and *"did the install fail?"* looked
50
- identical:
51
-
52
- ```
53
- grants: 1 of 7 definitions spawnable review
54
- withheld: architect, build, need agent:architect, …, which this session does not hold
55
- ```
56
-
57
- Classified by the same planner a real spawn comes through (no human is asked, stored approvals count), and
58
- it speaks even when **nothing** is spawnable which is the state most worth being told about. It is an
59
- upper bound: it runs before the tool surface is observed, and `/grants` is the settled answer.
60
-
61
- - **A worked `principal-pi-skills` example in the README**, replacing the invented one, with every line
62
- produced by running the commands (`docs/probes/b2-init-principal-pi-skills`).
63
-
64
- - **Fixed before release: a skill's `allowed-tools` VALUE could execute code from the generated grant file**
65
- (R-78). `ceilingForDefinition` passes `ext:`/`skill:`/`agent:` entries through as written — correct for
66
- enforcement, where the catalog refuses what it does not know — so a package declaring
67
- `allowed-tools: Read,ext:x";touch /tmp/pwned;PI_GRANTS_GRANT="` produced a `.pi/grants.env` that ran the
68
- payload when sourced: silently, exit 0, with the variable left looking plausible. It survives
69
- `--ignore-scripts` and travels in the file you commit. Declared ids are whitelisted now, `tool:*`/`agent:*`
70
- from a package are refused, and the assembled grant is charset-checked before the file is written at all.
71
-
72
- - **Fixed before release: `init` overwrote an operator's file and wrote through symlinks** (R-79). The
73
- presence probe was `readFile`, which treats *unreadable* as *absent* so a permissions-restricted
74
- `SKILL.md` was replaced and its ceiling **widened**, with no `--force`. And `writeFile` follows symlinks, so
75
- a dangling link at a target path created the file outside the project while reporting an in-project path.
76
- Both are one `open(path, "wx")`. `--force` no longer regenerates `.pi/grants.env`, and `pi-daddy init
77
- --Force` is no longer accepted as a silent no-op.
78
-
79
- - **Fixed before release: the startup line blamed your files for a session-level refusal** (R-81). A session
80
- at its depth limit, or with a malformed `PI_GRANTS_MAX_DEPTH`, was told its `SKILL.md` files were written
81
- wrong two lines above `/grants` saying "delegation is disabled (maxDepth 0)". A session with no
82
- `tool:delegate`, which has no delegate tool at all, was told definitions were spawnable.
83
-
84
- - **Fixed before release: a skill's directory name could write a capability into the generated grant**
85
- (R-77). A name is interpolated into a comma-separated `PI_GRANTS_GRANT`, into a file the operator sources,
86
- and into a path. A package shipping a directory called `a,tool:bash` produced
87
- `PI_GRANTS_GRANT="agent:a,tool:bash,…"` `tool:bash` in an operator's grant, declared by no definition.
88
- Names are now whitelisted at discovery and a refusal is printed with its reason.
89
-
90
- - **Fixed before release: `npx pi-daddy init` printed nothing and exited 0 for every installed copy** (R-73).
91
- npm installs a bin as a symlink, so `process.argv[1]` is the link and the entry-point guard compared it
92
- against the real file's URL. Caught by the smoke test, which now runs the installed bin — the same class of
93
- defect as the `exports` map that worked in the tree and threw for every consumer, and the second time that
94
- script has caught it.
15
+ ## 0.18.0 — generic runtime enforcement for external controllers
16
+
17
+ - Optional correlation metadata joins capability decisions to run/task/workspace/context IDs, candidate
18
+ `tree_sha`, sequence floors and opaque policy metadata. Trusted task/definition/request/effective digests
19
+ are computed separately; supplied IDs and digests never grant authority.
20
+ - Correlated gated approvals bind the exact definition, task, requested/effective capabilities,
21
+ workspace/context and parent. They do not inherit. Legacy calls without correlation keep their existing
22
+ approval behavior. Persisted approvals retain the 30-day expiry; `once` remains one-use. Concurrent exact
23
+ scopes never share a dialog or rebind one human answer to another task.
24
+ - Operator-registered Git worktrees can be selected by ID. The child starts at the validated canonical root;
25
+ a kernel `flock` permits at most one pi-daddy-governed writer per canonical root. Caller `read` cannot
26
+ lower write-capable grants; parent death stops the attached process/herdr tab before recovery. This is
27
+ coordination, **not path confinement** and not exclusion of unrelated writers or detached bash children.
28
+ - Stable refusal codes accompany existing human diagnostics.
29
+ - `pi-daddy/check-runner` runs operator-named executable+argv definitions without shell interpolation,
30
+ with an environment allowlist, timeout/output bounds, privately staged exact executable bytes, and
31
+ pre/post-verified Git HEAD/candidate-tree receipts under an exclusive coordination lease. Arbitrary
32
+ executables remain arbitrary code; no filesystem/network sandbox is claimed.
33
+ - **BREAKING ledger format v2:** append-only capability, workspace-lease, child-lifecycle and
34
+ check-receipt events. The new reader accepts legacy grant lines. Three things a consumer must know, two of
35
+ which are compile-or-run breaks rather than advisories:
36
+ - External readers that assume every line is a grant record must **switch on `event`** first.
37
+ - `LedgerReport` (published via `pi-daddy/ledger`) gained **required** fields `events`,
38
+ `workspaceLeases`, `lifecycle`. Any TypeScript consumer that constructs one, or handles it
39
+ exhaustively, breaks at compile time.
40
+ - `report.records` **changed meaning**: it counted every parsed line and now counts capability decisions
41
+ only, with lease/lifecycle/receipt lines going to `events`. A consumer reading it as "ledger lines"
42
+ silently gets a different number.
43
+ - A line carrying `ledgerVersion` is now **rejected as corrupt** unless it satisfies the full v2 field
44
+ set, which matters to anyone who hand-writes or re-emits ledger lines.
45
+ - **BREAKING `correlation` is a whitelist.** Only the pinned schema 1.0 field set is accepted; strings are
46
+ capped at 512 characters, `assurance_scope` at 4 KB, and an **undeclared key is refused by name** rather
47
+ than passed through. A caller sending extra fields must stop. This is a privacy control: `correlation` is
48
+ model-facing and copied verbatim onto every append-only event, so an unbounded object was a channel for
49
+ writing arbitrary text into a file that carries no prompts, arguments or results.
50
+ - **BREAKING for direct API callers — `WorkspaceLease.release()` returns
51
+ `"released" | "released-unrecorded" | "lost"` and no longer throws**, and `recovered` is
52
+ `boolean | "unknown"`. `WorkspaceLeaseOutcome` gains `uncontended`, `released-unrecorded`, `lost` and
53
+ `retained`. Code that relied on `release()` rejecting must read the value instead.
54
+ - **Fixes from a six-reviewer pass over this candidate before release.** The capability invariant held on
55
+ every path any reviewer could construct; these are the runtime half. `flock`'s command inherits the lock
56
+ file descriptor (measured — `docs/probes/g35-flock-fd-inheritance`), so teardown killing only the wrapper
57
+ stranded the lock and reported it to everyone else as a conflict. `recovered` could assert a crash after a
58
+ clean handover and hide a real one. The herdr close loop retried forever while holding the lock. A bound
59
+ approval could be spent outside the workspace it named, because two of its six identity components were
60
+ read from caller-supplied correlation. A refused delegation could leave a 30-day approval on disk. A child
61
+ could mint the upstream controller's `BLOCKED_CRITICAL_ASSURANCE` verdict out of a timeout. Fan-out
62
+ discarded every sibling error but the first. Five planner refusals and every execution-phase failure
63
+ carried no stable code. See `docs/03-risks.md` R-99…R-118 and the ADR-0034 amendment, which also lists
64
+ what the pass did **not** resolve.
65
+
66
+ New public subpaths: `pi-daddy/correlation`, `pi-daddy/refusals`, `pi-daddy/workspace`, and
67
+ `pi-daddy/check-runner`.
68
+
69
+ ## 0.17.1 no functional change: the release that exists because a rule got enforced
70
+
71
+ **Nothing in the shipped code changed.** This tarball differs from 0.17.0 in its version and in this file,
72
+ and that is stated here rather than dressed up, because a changelog that implies behaviour changed is worse
73
+ than a version nobody needed. `dist/`, `src/` and `extensions/` are byte-identical to 0.17.0.
74
+
75
+ What happened is in the repository, not the package: working rule 10 **`main` is only ever advanced by
76
+ merging a pull request** plus `hooks/pre-commit`, which refuses a commit on `main` and names a recovery that
77
+ is never a force-push, and `test/branch-guard.test.ts`, which pins it against seven mutations of the hook
78
+ (tests are not published, so that file is not in this tarball either).
79
+
80
+ **Why a version at all**, since nothing here changed: rule 10 says version bumps take the same path as
81
+ everything else, and this one did branch, PR, review, squash-merge. The rule's first draft was reviewed by
82
+ six independent agents across two rounds that found sixteen defects, including that *"never commit to `main`"*
83
+ forbids the merge the rule requires, and that the guard written to fix that had reproduced the same defect in
84
+ shell. `docs/03-risks.md` R-85 and the 2026-08-18 session-log entry hold the details.
85
+
86
+ **Also fixed here:** this file claimed "Newest first" while 0.14.0 sat above 0.17.0, 0.16.0 and 0.15.0. The
87
+ order is now what the sentence says it is.
95
88
 
96
89
  ## 0.17.0 — `delegate_chain`
97
90
 
@@ -244,6 +237,87 @@ pi
244
237
  - **`init` counted authorisations and called them declarations** — "7 skill(s), 3 declaring allowed-tools"
245
238
  when all seven declared.
246
239
 
240
+ ## 0.14.0 — `pi-daddy init`, and a startup line that names what it will and will not spawn
241
+
242
+ > **Reviewed before release by five independent agents, one hypothesis each. All five found something, and
243
+ > nine defects were fixed here** — including one that executed arbitrary code from the file this feature
244
+ > tells you to commit (R-78), one that overwrote an operator's file and wrote through symlinks (R-79), and
245
+ > one where the startup line blamed your `SKILL.md` files for a misconfigured environment variable (R-81).
246
+ > **ADR-0029 came out of that review**: the generated grant is read-only by default. The reasoning for each
247
+ > is in `docs/03-risks.md` R-78 through R-82.
248
+
249
+ The pi-daddy half of making this package and a package of skills work together out of the box
250
+ (`docs/HANDOFF-principal-pi-skills-integration.md`, items B1/B2/B4; **ADR-0028**). Nothing about grant
251
+ resolution, enforcement, approvals or the ledger changed — this is the part before and around them.
252
+
253
+ - **The generated grant is READ-ONLY by default** (ADR-0029). `init` grants what the copied skills declare
254
+ minus anything that can change your machine — `bash`, `write`, `edit` and the universal capabilities are
255
+ written **commented**, naming the definitions that need them. `init` + `source` gives a working read-only
256
+ setup; widening costs one deliberate uncomment. The reason: `PI_GRANTS_GRANT` is what *bounds* a declared
257
+ ceiling, so generating it from those ceilings would give the bound and the bounded one author, and it
258
+ would not be you.
259
+
260
+ - **`npx pi-daddy init` scaffolds a governed project.** It reads `<cwd>/node_modules` for packages declaring
261
+ skills in their own `package.json` (`"pi": {"skills": [...]}`, pi's convention), copies each declared
262
+ `SKILL.md` into `.pi/skills/`, and writes an annotated `.pi/grants.env`. That replaces, per skill: make a
263
+ directory, copy the body, hand-write frontmatter, choose a capability set with no guidance, and assemble a
264
+ `PI_GRANTS_GRANT` string by hand — seven times for `principal-pi-skills`.
265
+
266
+ **It chooses no ceiling, and that boundary is the whole design.** A skill that declares `allowed-tools` is
267
+ copied byte for byte; one that declares none is copied with a *commented* placeholder and stays
268
+ unspawnable until a human fills it in. The placeholder is deliberately not a working example, so
269
+ uncommenting it unedited fails loudly instead of granting something nobody decided. An existing file is
270
+ **kept**, never overwritten — that edit is the capability decision, and a second `init` run is exactly
271
+ when it would be destroyed. `--force` exists and says what it costs.
272
+
273
+ - **Session start says how many definitions are spawnable, and names the withheld ones.** The line reported
274
+ the grant and never the definitions, so *"governance is working"* and *"did the install fail?"* looked
275
+ identical:
276
+
277
+ ```
278
+ grants: 1 of 7 definitions spawnable — review
279
+ withheld: architect, build, … — need agent:architect, …, which this session does not hold
280
+ ```
281
+
282
+ Classified by the same planner a real spawn comes through (no human is asked, stored approvals count), and
283
+ it speaks even when **nothing** is spawnable — which is the state most worth being told about. It is an
284
+ upper bound: it runs before the tool surface is observed, and `/grants` is the settled answer.
285
+
286
+ - **A worked `principal-pi-skills` example in the README**, replacing the invented one, with every line
287
+ produced by running the commands (`docs/probes/b2-init-principal-pi-skills`).
288
+
289
+ - **Fixed before release: a skill's `allowed-tools` VALUE could execute code from the generated grant file**
290
+ (R-78). `ceilingForDefinition` passes `ext:`/`skill:`/`agent:` entries through as written — correct for
291
+ enforcement, where the catalog refuses what it does not know — so a package declaring
292
+ `allowed-tools: Read,ext:x";touch /tmp/pwned;PI_GRANTS_GRANT="` produced a `.pi/grants.env` that ran the
293
+ payload when sourced: silently, exit 0, with the variable left looking plausible. It survives
294
+ `--ignore-scripts` and travels in the file you commit. Declared ids are whitelisted now, `tool:*`/`agent:*`
295
+ from a package are refused, and the assembled grant is charset-checked before the file is written at all.
296
+
297
+ - **Fixed before release: `init` overwrote an operator's file and wrote through symlinks** (R-79). The
298
+ presence probe was `readFile`, which treats *unreadable* as *absent* — so a permissions-restricted
299
+ `SKILL.md` was replaced and its ceiling **widened**, with no `--force`. And `writeFile` follows symlinks, so
300
+ a dangling link at a target path created the file outside the project while reporting an in-project path.
301
+ Both are one `open(path, "wx")`. `--force` no longer regenerates `.pi/grants.env`, and `pi-daddy init
302
+ --Force` is no longer accepted as a silent no-op.
303
+
304
+ - **Fixed before release: the startup line blamed your files for a session-level refusal** (R-81). A session
305
+ at its depth limit, or with a malformed `PI_GRANTS_MAX_DEPTH`, was told its `SKILL.md` files were written
306
+ wrong — two lines above `/grants` saying "delegation is disabled (maxDepth 0)". A session with no
307
+ `tool:delegate`, which has no delegate tool at all, was told definitions were spawnable.
308
+
309
+ - **Fixed before release: a skill's directory name could write a capability into the generated grant**
310
+ (R-77). A name is interpolated into a comma-separated `PI_GRANTS_GRANT`, into a file the operator sources,
311
+ and into a path. A package shipping a directory called `a,tool:bash` produced
312
+ `PI_GRANTS_GRANT="agent:a,tool:bash,…"` — `tool:bash` in an operator's grant, declared by no definition.
313
+ Names are now whitelisted at discovery and a refusal is printed with its reason.
314
+
315
+ - **Fixed before release: `npx pi-daddy init` printed nothing and exited 0 for every installed copy** (R-73).
316
+ npm installs a bin as a symlink, so `process.argv[1]` is the link and the entry-point guard compared it
317
+ against the real file's URL. Caught by the smoke test, which now runs the installed bin — the same class of
318
+ defect as the `exports` map that worked in the tree and threw for every consumer, and the second time that
319
+ script has caught it.
320
+
247
321
  ## 0.13.0 — the approvals file gets the lock the ledger already had, and two silences end
248
322
 
249
323
  Closing the last items that were open rather than out of scope, then **red-teaming the result**: an
package/README.md CHANGED
@@ -193,12 +193,13 @@ A chain's handoff is wrapped in a labelled, **nonce-delimited** fence, so the pr
193
193
  data — and because the nonce is minted after that agent finished, it cannot forge a closing delimiter to escape its
194
194
  own fence. The label itself is framing and this README will not pretend otherwise; the nonce is the mechanism.
195
195
 
196
- A chain is **gated upfront**: every step is planned first, and every approval it needs is asked for *before the
197
- first step starts* together, rather than interrupting a running pipeline. One dialog per capability *and*
198
- definition, each naming the step that needs it, because an approval for one definition must never satisfy another.
199
- Decline any of them and nothing runs. A step that could never run refuses the chain **before** anyone is asked, and
200
- `Allow once` covers exactly one step. A failed step stops the rest, and you still get everything that
201
- completed. Each step spends one unit of the fan-out budget, so a seven-step pipeline wants `PI_GRANTS_FANOUT=12`.
196
+ A legacy uncorrelated chain is **gated upfront**: every step is planned first, and every approval it needs is
197
+ asked for before the first step starts. Exact correlated steps gate only after their composed task exists;
198
+ binding a template and spending it on different generated instructions would be false assurance. One dialog
199
+ per capability and definition names the step that needs it. Decline an upfront gate and nothing runs. A step
200
+ that could never run refuses before anyone is asked; `Allow once` covers exactly the step it named. A failed
201
+ step stops the rest, and you still get everything completed—except `BLOCKED_CRITICAL_ASSURANCE`, which
202
+ remains a failed tool call. Each step spends one unit of the fan-out budget.
202
203
 
203
204
  ### Two executors, one plan
204
205
 
@@ -269,11 +270,10 @@ cannot make the next legitimate write destroy every other entry.
269
270
 
270
271
  **Other properties worth knowing:**
271
272
 
272
- - **An approval rides down the tree with the grant**, intersected with what each child actually receives at
273
- every hop, so `approved ⊆ grant` holds at every level. An approval unblocks part of a grant; it can never
274
- widen one. `once` is **dropped** on inheritance — the most conservative answer a human can give must not
275
- produce the least conservative outcomeand the subject is **kept**, so a `<delegate>` approval no longer
276
- matches any subject one hop down.
273
+ - **Legacy session/always approvals ride down the tree with the grant**, intersected with what each child
274
+ actually receives, so `approved ⊆ grant` holds at every level. `once` is dropped. A correlated approval
275
+ instead binds the exact definition, task, requested/effective sets, workspace/context and parent, and
276
+ never crosses a delegation boundaryapproval for one probe cannot become subtree authority.
277
277
  - **Concurrent callers share one dialog per `capability@subject`, but only share the *answer* when it was
278
278
  about more than one spawn.** `session`, `always`, a decline and an error answer everyone; **a `once` is
279
279
  consumed by exactly one caller** and the rest are asked their own question. Measured before the fix: four
@@ -320,6 +320,28 @@ Seven further tests in that file cost no model tokens and cover the reload and e
320
320
  transcripts in `docs/probes/approval-ux` describe an interceptor path that no longer exists — they are kept
321
321
  as the record of that run and are not a description of this version.
322
322
 
323
+ ## Runtime enforcement for external controllers (0.18.0)
324
+
325
+ All fields are optional; existing callers behave unchanged.
326
+
327
+ - `correlation` carries join-only run/task/workspace/context IDs, opaque policy metadata, base/head/tree SHAs
328
+ and sequence floors. Supplied IDs/digests never authorize; trusted digests are computed separately.
329
+ - `workspace: {workspace_id, access}` resolves through `PI_GRANTS_WORKSPACE_REGISTRY`, validates a canonical
330
+ Git worktree root, and sets initial CWD. A caller cannot label a write-capable grant read-only. Kernel
331
+ util-linux `flock` allows one **pi-daddy-governed** writer per canonical root; `setpriv --pdeathsig` plus
332
+ helper attachment stops the writer process or herdr tab on parent death before release. This does not confine paths or exclude unrelated writers; `bash` remains an escape.
333
+ - Refusals retain current prose and add stable codes such as `CAPABILITY_ESCALATION`,
334
+ `GATED_UNAPPROVED`, `APPROVAL_SCOPE_MISMATCH`, and `WORKSPACE_WRITE_CONFLICT`.
335
+ - Ledger v2 adds joinable capability, lease, lifecycle and check-receipt events while reading legacy lines.
336
+ - `pi-daddy/check-runner` selects an operator-named absolute executable+argv definition, never a shell
337
+ command string. It strips sensitive inherited environment, enforces timeout/output caps, executes a
338
+ private copy of the exact executable bytes it hashed, and pre/post-verifies Git head/candidate-tree
339
+ identity under an exclusive coordination lease. The executable remains arbitrary code; no filesystem or
340
+ network sandbox is claimed.
341
+
342
+ Public subpaths: `pi-daddy/correlation`, `pi-daddy/refusals`, `pi-daddy/workspace`,
343
+ `pi-daddy/check-runner`.
344
+
323
345
  ## Running it
324
346
 
325
347
  ```bash
@@ -485,8 +507,10 @@ everything below it.
485
507
  | `PI_GRANTS_APPROVED` | unset | Inherited `capability@subject#sha256` entries; set by the parent, clamped to the child's own grant, and honoured only against the definition body the child itself loaded (ADR-0022). |
486
508
  | `PI_GRANTS_APPROVAL_TIMEOUT` | `120` (seconds) | How long a dialog waits. `0` or an unreadable value means **no timeout**: waiting forever denies nothing, so it is the safe reading of a value we do not understand. |
487
509
  | `PI_GRANTS_LEDGER` | unset → not recording | **Setting this makes the ledger load-bearing** — see below. |
510
+ | `PI_GRANTS_WORKSPACE_REGISTRY` | unset | Operator-owned `{version:1, workspaces:{id:{path}}}` file, required only for workspace-routed spawns. |
511
+ | `PI_GRANTS_WORKSPACE_LEASE_DIR` | under `$PI_CODING_AGENT_DIR/pi-daddy/` | Kernel writer locks and ownership metadata. |
488
512
  | `PI_GRANTS_CHILD_TIMEOUT` | `600` (seconds) | Wall-clock limit for a child. Inherited by descendants — an operator preference, deliberately *not* attenuating state. |
489
- | `PI_GRANTS_FANOUT` | `8` | **Subtree budget**: total descendants this session may create. Attenuates downward like depth. Malformed or `0` falls back to the default — a bound a typo can switch off is not a bound. |
513
+ | `PI_GRANTS_FANOUT` | `8` | Per-call width and downward subtree budget; not a session-total counter. Malformed or `0` falls back to the default. |
490
514
  | `PI_GRANTS_PARENT_ID` | `d0` | This session's ledger id; set by the parent. Makes sibling records joinable into a tree. |
491
515
  | `PI_GRANTS_HERDR` | unset ⇒ **probe** | Three-state. Unset probes for a reachable herdr and uses panes if one answers; `1` demands panes and refuses every delegation if herdr is unreachable; `0` demands captured subprocesses. Never detected from `herdr` merely being on `PATH`. |
492
516
  | `PI_GRANTS_HERDR_WORKSPACE` | the parent's `HERDR_WORKSPACE_ID` | herdr workspace for spawned panes. Defaults to the workspace this session is in, so a child is a tab away rather than a workspace away. |
@@ -508,7 +532,10 @@ is broken after 10s.
508
532
 
509
533
  ## The ledger
510
534
 
511
- Append-only JSONL. One record per governed decision, **including refusals**, which are the interesting ones.
535
+ Append-only JSONL. Version 2 records capability decisions plus workspace-lease, child-lifecycle and
536
+ check-receipt events. Every per-child capability decision is present, **including refusals**; call-level
537
+ schema/cardinality rejections that create no child ID are not capability events. The reader still accepts
538
+ legacy grant-only lines.
512
539
 
513
540
  Ids are hierarchical and derived: a child of `d0` is `d0.1`, its own second child `d0.1.2`. Ancestry reads
514
541
  from the id alone with no join, and it is reproducible, so two runs of the same fan-out produce a diffable
@@ -516,9 +543,10 @@ ledger. `denied` non-empty is the one designated escalation signal — **an agen
516
543
  hold is an escalation attempt, and it is invisible without a record.**
517
544
 
518
545
  **Privacy is a property of this file, and the boundary is exact: capability ids, counts and identifiers only
519
- — never prompts, tool arguments or results.** The `definitionDigest` is on the identifier side of that line:
520
- it names a version of operator-authored text already committed to a repository. The **task** is on the other
521
- side and is never recorded, in any field.
546
+ — never prompts, task text, tool arguments or results.** Trusted `definitionDigest` and `taskDigest` values
547
+ identify the exact operator body and task. A predictable task can be guessed from SHA-256, so its digest is
548
+ sensitive/linkable metadata, not anonymization. Caller-supplied digest-looking values remain under
549
+ `correlation` and never authorize.
522
550
 
523
551
  ## Propagation is race-free by construction
524
552
 
@@ -655,12 +683,12 @@ every in-repo test passed. `npm run test:smoke` packs a tarball, installs it int
655
683
  ## Testing
656
684
 
657
685
  ```bash
658
- npm test # 353 unit tests. Fast, pure, no pi, no network.
686
+ npm test # 587 unit tests. Fast, pure, no pi, no network.
659
687
  npm run typecheck # src + extensions + tests + integration tests
660
- npm run test:integration # 28 tests against a REAL pi process. ~40s, no model tokens.
688
+ npm run test:integration # 44 tests against a REAL pi process. ~55s, no model tokens.
661
689
  npm run test:smoke # pack, install into a scratch project, import and use it — and run the
662
690
  # installed `pi-daddy init` bin, which is how R-73 was found
663
- PI_GRANTS_IT_MODEL=1 npm run test:integration # + 4 end-to-end tests with a real model. ~60s, costs money.
691
+ PI_GRANTS_IT_MODEL=1 npm run test:integration # + 10 end-to-end tests with a real model. Costs money.
664
692
  ```
665
693
 
666
694
  The resolver is a pure function, which is deliberate: it is the only place an escalation could be
@@ -685,15 +713,16 @@ its own author the day after it was added: rather than raise the cap, `delegatio
685
713
 
686
714
  ## Status
687
715
 
688
- **0.14.0 — usable, and honest about scope.** What exists and is verified against real pi: the resolver, the
689
- ledger with an integrity reader, the spawn planner, `SKILL.md` definitions with `allowed-tools` as an
690
- enforced ceiling, `delegate` and `delegate_all` with a subtree budget, two executors, and human approval for
691
- gated capabilities (once / session / always, inheritable down the tree, persisted for `always` and pinned to
692
- both the tools and the instructions).
716
+ **0.18.0 — generic runtime enforcement, still honest about scope.** The governed spawn path now includes
717
+ optional correlation, exact task-bound approvals, registered-worktree CWD validation, OS-backed governed
718
+ writer leases, structured refusals, lifecycle/lease ledger events, and a no-shell named-check subpath. All
719
+ new spawn fields are optional; legacy callers retain their behavior.
693
720
 
694
721
  Known gaps, stated because a gap nobody wrote down is the one that surprises somebody:
695
722
 
696
- - **`bash` escapes governance.** Out of scope by decision (ADR-0012).
723
+ - **`bash` escapes governance.** Out of scope by decision (ADR-0012); workspace routing and leases do not contain it.
724
+ - **A workspace lease coordinates only pi-daddy-governed writers.** It is not a filesystem sandbox and cannot stop unrelated processes. The measured writer path currently requires util-linux `flock`.
725
+ - **A named check is arbitrary code without shell interpolation.** It may write, use the network, invoke a shell or leave descendants; no OS containment is claimed.
697
726
  - **`subagents:rpc:spawn` bypasses the tripwire.** Unfixable from here.
698
727
  - **The ledger is verified at session start** when one is configured: a damaged trail announces itself, an intact one stays quiet.
699
728
  - **A pane outlives its tool call only if its child settled.** A child that answered keeps its pane so you can
@@ -26,8 +26,10 @@ export interface PromptRequest {
26
26
  /** Agent type name, or `DELEGATE_SUBJECT` on the delegate path. */
27
27
  subject: string;
28
28
  path: ApprovalPath;
29
- /** Shown to the human for context. Never part of a key. */
29
+ /** Shown to the human for context. Never itself part of a key. */
30
30
  task?: string;
31
+ /** Trusted exact-scope identity; bound requests single-flight only with an identical binding. */
32
+ bindingKey?: string;
31
33
  signal?: AbortSignal;
32
34
  }
33
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"approval-prompt.d.ts","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAA8B,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAChD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;CACpE;AAED,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAItD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAC;IACvB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,CAAC;IACnB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAEzF,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,qEAAqE;IACrE,IAAI,EAAE,iBAAiB,CAAC;IACxB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,UAAU,CAAC;IACf,0FAA0F;IAC1F,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACzD;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK5E;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,IAAI,CAAC,OAAO,EAAE,mBAAmB,KAAK,YAAY,CAG3F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,GAAE,iBAA6B,GACtC,YAAY,CAwEd"}
1
+ {"version":3,"file":"approval-prompt.d.ts","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAA8B,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAChD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;CACpE;AAED,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAItD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAC;IACvB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,CAAC;IACnB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAEzF,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IAC5B,qEAAqE;IACrE,IAAI,EAAE,iBAAiB,CAAC;IACxB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,UAAU,CAAC;IACf,0FAA0F;IAC1F,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACzD;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK5E;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,IAAI,CAAC,OAAO,EAAE,mBAAmB,KAAK,YAAY,CAG3F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,GAAE,iBAA6B,GACtC,YAAY,CAwEd"}
@@ -95,7 +95,7 @@ export function createApprovalGate(options, inFlight = new Map()) {
95
95
  `(mode: ${options.mode}). Pre-approve it in an interactive session, or drop it from the request.`,
96
96
  };
97
97
  }
98
- const key = approvalKey(request.capability, request.subject);
98
+ const key = `${approvalKey(request.capability, request.subject)}${request.bindingKey ? `#${request.bindingKey}` : ""}`;
99
99
  // R-29. Join an in-flight dialog, but only *keep* its answer if that answer was about more than one
100
100
  // spawn. A `once` belongs to whichever caller the human was actually looking at — the title shows
101
101
  // that caller's task — so anyone else who joined must ask their own question rather than ride a yes
@@ -1 +1 @@
1
- {"version":3,"file":"approval-prompt.js","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval-prompt.js","sourceRoot":"","sources":["../src/approval-prompt.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"approval-store.d.ts","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAOH,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAO1G,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,eAAe,GAAG,IAAI,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASjD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAmED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,sFAAsF;AACtF,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC,CAwB5E;AA4CD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErE,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7D"}
1
+ {"version":3,"file":"approval-store.d.ts","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAOH,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAQ1G,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,eAAe,GAAG,IAAI,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASjD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD;AAqED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,IAAI,CAAC;IACV,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED,sFAAsF;AACtF,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC,CAwB5E;AA4CD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErE,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,aAAa,EACzB,GAAG,EAAE,IAAI,GACR,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7D"}
@@ -35,6 +35,7 @@ import { withFileLock } from "./file-lock.js";
35
35
  import { homedir } from "node:os";
36
36
  import { basename, dirname, join } from "node:path";
37
37
  import { entryVerdict } from "./approval.js";
38
+ import { isApprovalBinding } from "./correlation.js";
38
39
  /**
39
40
  * Where persisted approvals live — **outside the governed workspace** (ADR-0014).
40
41
  *
@@ -121,7 +122,8 @@ function isValidEntryShape(entry) {
121
122
  return (typeof obj.approvedAt === "string" &&
122
123
  typeof obj.expiresAt === "string" &&
123
124
  typeof obj.cwd === "string" &&
124
- Array.isArray(obj.grantAtApproval));
125
+ Array.isArray(obj.grantAtApproval) &&
126
+ (obj.binding === undefined || isApprovalBinding(obj.binding)));
125
127
  }
126
128
  /**
127
129
  * Project every entry through its DECLARED fields on the way out (ADR-0021).
@@ -143,6 +145,7 @@ function sanitise(valid) {
143
145
  cwd: e.cwd,
144
146
  grantAtApproval: e.grantAtApproval,
145
147
  ...(e.bodyAtApproval !== undefined ? { bodyAtApproval: e.bodyAtApproval } : {}),
148
+ ...(e.binding !== undefined ? { binding: structuredClone(e.binding) } : {}),
146
149
  },
147
150
  ]));
148
151
  }
@@ -1 +1 @@
1
- {"version":3,"file":"approval-store.js","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approval-store.js","sourceRoot":"","sources":["../src/approval-store.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@
9
9
  * ADR-0010 records the four decisions encoded here.
10
10
  */
11
11
  import type { Capability, ResolveResult } from "./resolve.ts";
12
+ import { type ApprovalBinding } from "./correlation.ts";
12
13
  /** How far a single yes reaches in time. */
13
14
  export type ApprovalScope = "once" | "session" | "always";
14
15
  /** Where a yes came from, for the ledger. These call for different follow-ups, so they stay distinct. */
@@ -84,6 +85,11 @@ export interface InheritableApproval {
84
85
  * no file to hash — and, per ADR-0019, is never persisted or offered `always` for the same reason.
85
86
  */
86
87
  bodySha256?: string;
88
+ /**
89
+ * Exact delegation binding for controllers that supply correlation/workspace context (ADR-0034).
90
+ * Bound approvals are deliberately not inherited: authority for one task must not become subtree-wide.
91
+ */
92
+ binding?: ApprovalBinding;
87
93
  }
88
94
  /**
89
95
  * What a child may inherit, as `capability@subject` keys.
@@ -145,6 +151,8 @@ export interface ApprovalEntry {
145
151
  * predates 0.10.0 and cannot be verified, which `entryVerdict` treats as changed: fail closed.
146
152
  */
147
153
  bodyAtApproval?: string;
154
+ /** Exact task/grant/workspace/context/parent binding for correlated controller calls (ADR-0034). */
155
+ binding?: ApprovalBinding;
148
156
  }
149
157
  export type EntryVerdict = "valid" | "expired" | "foreign-cwd" | "type-changed" | "instructions-changed" | "type-missing";
150
158
  /**
@@ -193,9 +201,14 @@ export interface ResolveApprovalsInput {
193
201
  subject: string;
194
202
  /** Approval KEYS approved for this session, in memory only. */
195
203
  sessionApprovals: ReadonlySet<string>;
196
- /** Persisted entries by key, ALREADY validity-filtered by the store. */
204
+ /** Exact bindings for correlated session approvals. Kept separate so legacy keys remain compatible. */
205
+ sessionApprovalBindings?: ReadonlyMap<string, ApprovalBinding>;
206
+ /** Persisted entries by key, ALREADY definition/expiry-filtered by the store. */
197
207
  persisted: ReadonlyMap<string, ApprovalEntry>;
198
- /** Capabilities approved further up the tree and inherited with the grant. */
208
+ /** When present, only an exact binding may satisfy this gate. */
209
+ expectedBinding?: ApprovalBinding;
210
+ /** Same-key persisted entries dropped specifically because their expiry passed. */
211
+ expiredKeys?: ReadonlySet<string>;
199
212
  /**
200
213
  * `capability@subject` keys inherited from the delegator (ADR-0014).
201
214
  *
@@ -208,7 +221,12 @@ export interface ResolveApprovalsResult {
208
221
  approved: Capability[];
209
222
  /** Gated capabilities still requiring a live human. */
210
223
  needsPrompt: Capability[];
224
+ /** A same-key approval existed but named another task/workspace/context/parent. */
225
+ scopeMismatched: Capability[];
226
+ expired: Capability[];
211
227
  sources: Record<Capability, ApprovalSource>;
228
+ scopes: Record<Capability, ApprovalScope>;
229
+ expiresAt: Record<Capability, string>;
212
230
  }
213
231
  /**
214
232
  * Satisfy as much of `gated` as possible without asking anyone.