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.
Files changed (2) hide show
  1. package/CHANGELOG.md +96 -76
  2. 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.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.
15
+ ## 0.17.1no functional change: the release that exists because a rule got enforced
34
16
 
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`.
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
- **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.
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
- - **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:
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
- 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.
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.0",
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",