@gotgenes/pi-permission-system 33.0.0 → 33.0.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 +7 -0
- package/docs/subagent-integration.md +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [33.0.1](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v33.0.0...pi-permission-system-v33.0.1) (2026-09-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* **pi-permission-system:** document the serving-liveness and bound-channel mechanism in the integration spec ([#942](https://github.com/gotgenes/pi-packages/issues/942)) ([2786acc](https://github.com/gotgenes/pi-packages/commit/2786accaf40136f192e6f8d187058ae60c7555b5)), closes [#942](https://github.com/gotgenes/pi-packages/issues/942)
|
|
14
|
+
|
|
8
15
|
## [33.0.0](https://github.com/gotgenes/pi-packages/compare/pi-permission-system-v32.1.0...pi-permission-system-v33.0.0) (2026-09-18)
|
|
9
16
|
|
|
10
17
|
|
|
@@ -160,7 +160,9 @@ The polling session publishes the session id it polls, and a child checks that i
|
|
|
160
160
|
|
|
161
161
|
The announcement goes out on two channels, because a child cannot always reach the same one.
|
|
162
162
|
A child running inside its parent's process reads a process-global registry.
|
|
163
|
+
A stale mark left in that registry by a session that died without `session_shutdown` suppresses the fast-fail and falls back to the timeout — the safe direction for that channel.
|
|
163
164
|
A child running as a separate `pi` process (the `PI_SUBAGENT_PARENT_SESSION` path) shares no memory with its parent, so it reads a heartbeat record the serving session refreshes under `<agent dir>/sessions/permission-forwarding/serving/`, holding the served session id, the serving process id, and the time it was last refreshed.
|
|
165
|
+
That `serving/` directory is created on demand and never removed.
|
|
164
166
|
|
|
165
167
|
For an out-of-process target, four things count as "not draining":
|
|
166
168
|
|
|
@@ -171,7 +173,7 @@ For an out-of-process target, four things count as "not draining":
|
|
|
171
173
|
| A record nobody has refreshed for several seconds | The parent's process survives but has stopped polling |
|
|
172
174
|
| A record for a different session id | The child is forwarding somewhere nobody is listening |
|
|
173
175
|
|
|
174
|
-
If the target is not draining its inbox, the child gives up after a two-second grace window rather than waiting out `forwardingTimeoutMs`, and the tool is blocked with:
|
|
176
|
+
If the target is not draining its inbox, the child gives up after a two-second grace window (`PERMISSION_FORWARDING_SERVING_GRACE_MS`) rather than waiting out `forwardingTimeoutMs`, and the tool is blocked with:
|
|
175
177
|
|
|
176
178
|
```text
|
|
177
179
|
[pi-permission-system] Running bash command 'pwd' requires approval, but no
|
|
@@ -180,6 +182,7 @@ permission requests.
|
|
|
180
182
|
```
|
|
181
183
|
|
|
182
184
|
The grace window exists so a request that arrives while the parent is switching sessions is not abandoned in the gap.
|
|
185
|
+
Absence of a record is deliberately **not** read as unknown: a cleanly exited parent leaves nothing behind, so treating absence as "maybe serving" would restore the full-timeout stall that the heartbeat exists to end.
|
|
183
186
|
A target that *is* draining its inbox is waited on for the full `forwardingTimeoutMs`, however long the human takes to decide.
|
|
184
187
|
That includes a parent whose human is still deliberating at an earlier forwarded prompt: it keeps refreshing its heartbeat throughout, so a second child does not read it as gone.
|
|
185
188
|
|
|
@@ -188,6 +191,7 @@ None of them is reported as a user denial, because no user was ever asked.
|
|
|
188
191
|
|
|
189
192
|
The two sides of the exchange are correlatable in the review log: the serving session writes `forwarded_permission.serving_started` with the id it polls, and the child writes `forwarded_permission.request_created` with the `targetSessionId` it forwarded to.
|
|
190
193
|
When a forwarded request goes unanswered, comparing those two entries distinguishes a parent that was not polling from one polling a different session.
|
|
194
|
+
The child's `forwarded_permission.no_serving_session` entry also records `servingChannel` and `servingState` beside the ids observed, since "exited", "killed", and "polling a different session id" are different diagnoses the shared denial string does not distinguish.
|
|
191
195
|
|
|
192
196
|
When a forwarded request *is* answered, the child's own terminal entry names both which session answered and what within it decided.
|
|
193
197
|
The serving node records its decider on the response — a rule of its own (with the surface, pattern, and origin that matched), the link that ruled, or the human who answered its dialog — and the child records it nested under a `forwarded` frame:
|