pi-daddy 0.17.0 → 0.17.1
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 +96 -76
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,86 +12,25 @@ 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.
|
|
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.
|
|
15
|
+
## 0.17.1 — no functional change: the release that exists because a rule got enforced
|
|
34
16
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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`.
|
|
17
|
+
**Nothing in the shipped code changed.** This tarball differs from 0.17.0 in its version and in this file,
|
|
18
|
+
and that is stated here rather than dressed up, because a changelog that implies behaviour changed is worse
|
|
19
|
+
than a version nobody needed. `dist/`, `src/` and `extensions/` are byte-identical to 0.17.0.
|
|
40
20
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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.
|
|
21
|
+
What happened is in the repository, not the package: working rule 10 — **`main` is only ever advanced by
|
|
22
|
+
merging a pull request** — plus `hooks/pre-commit`, which refuses a commit on `main` and names a recovery that
|
|
23
|
+
is never a force-push, and `test/branch-guard.test.ts`, which pins it against seven mutations of the hook
|
|
24
|
+
(tests are not published, so that file is not in this tarball either).
|
|
47
25
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
26
|
+
**Why a version at all**, since nothing here changed: rule 10 says version bumps take the same path as
|
|
27
|
+
everything else, and this one did — branch, PR, review, squash-merge. The rule's first draft was reviewed by
|
|
28
|
+
six independent agents across two rounds that found sixteen defects, including that *"never commit to `main`"*
|
|
29
|
+
forbids the merge the rule requires, and that the guard written to fix that had reproduced the same defect in
|
|
30
|
+
shell. `docs/03-risks.md` R-85 and the 2026-08-18 session-log entry hold the details.
|
|
51
31
|
|
|
52
|
-
|
|
53
|
-
|
|
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.
|
|
32
|
+
**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
|
|
33
|
+
order is now what the sentence says it is.
|
|
95
34
|
|
|
96
35
|
## 0.17.0 — `delegate_chain`
|
|
97
36
|
|
|
@@ -244,6 +183,87 @@ pi
|
|
|
244
183
|
- **`init` counted authorisations and called them declarations** — "7 skill(s), 3 declaring allowed-tools"
|
|
245
184
|
when all seven declared.
|
|
246
185
|
|
|
186
|
+
## 0.14.0 — `pi-daddy init`, and a startup line that names what it will and will not spawn
|
|
187
|
+
|
|
188
|
+
> **Reviewed before release by five independent agents, one hypothesis each. All five found something, and
|
|
189
|
+
> nine defects were fixed here** — including one that executed arbitrary code from the file this feature
|
|
190
|
+
> tells you to commit (R-78), one that overwrote an operator's file and wrote through symlinks (R-79), and
|
|
191
|
+
> one where the startup line blamed your `SKILL.md` files for a misconfigured environment variable (R-81).
|
|
192
|
+
> **ADR-0029 came out of that review**: the generated grant is read-only by default. The reasoning for each
|
|
193
|
+
> is in `docs/03-risks.md` R-78 through R-82.
|
|
194
|
+
|
|
195
|
+
The pi-daddy half of making this package and a package of skills work together out of the box
|
|
196
|
+
(`docs/HANDOFF-principal-pi-skills-integration.md`, items B1/B2/B4; **ADR-0028**). Nothing about grant
|
|
197
|
+
resolution, enforcement, approvals or the ledger changed — this is the part before and around them.
|
|
198
|
+
|
|
199
|
+
- **The generated grant is READ-ONLY by default** (ADR-0029). `init` grants what the copied skills declare
|
|
200
|
+
minus anything that can change your machine — `bash`, `write`, `edit` and the universal capabilities are
|
|
201
|
+
written **commented**, naming the definitions that need them. `init` + `source` gives a working read-only
|
|
202
|
+
setup; widening costs one deliberate uncomment. The reason: `PI_GRANTS_GRANT` is what *bounds* a declared
|
|
203
|
+
ceiling, so generating it from those ceilings would give the bound and the bounded one author, and it
|
|
204
|
+
would not be you.
|
|
205
|
+
|
|
206
|
+
- **`npx pi-daddy init` scaffolds a governed project.** It reads `<cwd>/node_modules` for packages declaring
|
|
207
|
+
skills in their own `package.json` (`"pi": {"skills": [...]}`, pi's convention), copies each declared
|
|
208
|
+
`SKILL.md` into `.pi/skills/`, and writes an annotated `.pi/grants.env`. That replaces, per skill: make a
|
|
209
|
+
directory, copy the body, hand-write frontmatter, choose a capability set with no guidance, and assemble a
|
|
210
|
+
`PI_GRANTS_GRANT` string by hand — seven times for `principal-pi-skills`.
|
|
211
|
+
|
|
212
|
+
**It chooses no ceiling, and that boundary is the whole design.** A skill that declares `allowed-tools` is
|
|
213
|
+
copied byte for byte; one that declares none is copied with a *commented* placeholder and stays
|
|
214
|
+
unspawnable until a human fills it in. The placeholder is deliberately not a working example, so
|
|
215
|
+
uncommenting it unedited fails loudly instead of granting something nobody decided. An existing file is
|
|
216
|
+
**kept**, never overwritten — that edit is the capability decision, and a second `init` run is exactly
|
|
217
|
+
when it would be destroyed. `--force` exists and says what it costs.
|
|
218
|
+
|
|
219
|
+
- **Session start says how many definitions are spawnable, and names the withheld ones.** The line reported
|
|
220
|
+
the grant and never the definitions, so *"governance is working"* and *"did the install fail?"* looked
|
|
221
|
+
identical:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
grants: 1 of 7 definitions spawnable — review
|
|
225
|
+
withheld: architect, build, … — need agent:architect, …, which this session does not hold
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Classified by the same planner a real spawn comes through (no human is asked, stored approvals count), and
|
|
229
|
+
it speaks even when **nothing** is spawnable — which is the state most worth being told about. It is an
|
|
230
|
+
upper bound: it runs before the tool surface is observed, and `/grants` is the settled answer.
|
|
231
|
+
|
|
232
|
+
- **A worked `principal-pi-skills` example in the README**, replacing the invented one, with every line
|
|
233
|
+
produced by running the commands (`docs/probes/b2-init-principal-pi-skills`).
|
|
234
|
+
|
|
235
|
+
- **Fixed before release: a skill's `allowed-tools` VALUE could execute code from the generated grant file**
|
|
236
|
+
(R-78). `ceilingForDefinition` passes `ext:`/`skill:`/`agent:` entries through as written — correct for
|
|
237
|
+
enforcement, where the catalog refuses what it does not know — so a package declaring
|
|
238
|
+
`allowed-tools: Read,ext:x";touch /tmp/pwned;PI_GRANTS_GRANT="` produced a `.pi/grants.env` that ran the
|
|
239
|
+
payload when sourced: silently, exit 0, with the variable left looking plausible. It survives
|
|
240
|
+
`--ignore-scripts` and travels in the file you commit. Declared ids are whitelisted now, `tool:*`/`agent:*`
|
|
241
|
+
from a package are refused, and the assembled grant is charset-checked before the file is written at all.
|
|
242
|
+
|
|
243
|
+
- **Fixed before release: `init` overwrote an operator's file and wrote through symlinks** (R-79). The
|
|
244
|
+
presence probe was `readFile`, which treats *unreadable* as *absent* — so a permissions-restricted
|
|
245
|
+
`SKILL.md` was replaced and its ceiling **widened**, with no `--force`. And `writeFile` follows symlinks, so
|
|
246
|
+
a dangling link at a target path created the file outside the project while reporting an in-project path.
|
|
247
|
+
Both are one `open(path, "wx")`. `--force` no longer regenerates `.pi/grants.env`, and `pi-daddy init
|
|
248
|
+
--Force` is no longer accepted as a silent no-op.
|
|
249
|
+
|
|
250
|
+
- **Fixed before release: the startup line blamed your files for a session-level refusal** (R-81). A session
|
|
251
|
+
at its depth limit, or with a malformed `PI_GRANTS_MAX_DEPTH`, was told its `SKILL.md` files were written
|
|
252
|
+
wrong — two lines above `/grants` saying "delegation is disabled (maxDepth 0)". A session with no
|
|
253
|
+
`tool:delegate`, which has no delegate tool at all, was told definitions were spawnable.
|
|
254
|
+
|
|
255
|
+
- **Fixed before release: a skill's directory name could write a capability into the generated grant**
|
|
256
|
+
(R-77). A name is interpolated into a comma-separated `PI_GRANTS_GRANT`, into a file the operator sources,
|
|
257
|
+
and into a path. A package shipping a directory called `a,tool:bash` produced
|
|
258
|
+
`PI_GRANTS_GRANT="agent:a,tool:bash,…"` — `tool:bash` in an operator's grant, declared by no definition.
|
|
259
|
+
Names are now whitelisted at discovery and a refusal is printed with its reason.
|
|
260
|
+
|
|
261
|
+
- **Fixed before release: `npx pi-daddy init` printed nothing and exited 0 for every installed copy** (R-73).
|
|
262
|
+
npm installs a bin as a symlink, so `process.argv[1]` is the link and the entry-point guard compared it
|
|
263
|
+
against the real file's URL. Caught by the smoke test, which now runs the installed bin — the same class of
|
|
264
|
+
defect as the `exports` map that worked in the tree and threw for every consumer, and the second time that
|
|
265
|
+
script has caught it.
|
|
266
|
+
|
|
247
267
|
## 0.13.0 — the approvals file gets the lock the ledger already had, and two silences end
|
|
248
268
|
|
|
249
269
|
Closing the last items that were open rather than out of scope, then **red-teaming the result**: an
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-daddy",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Capability governance for pi sub-agents: spawn Agent Skills (SKILL.md) definitions whose allowed-tools becomes a grant that can only narrow going down a delegation tree, enforced by pi's own --tools allowlist, with an append-only ledger.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|