You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+7-4Lines changed: 7 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ The product requirements document is in [`docs/prd/pi-postbox.md`](docs/prd/pi-p
8
8
9
9
## Current status
10
10
11
-
Version 0.2.7 coordinates protocol 0.1.9 with Android 0.4.2 (build 6), generated cross-language conformance fixtures, exact-match version gating, and hard-block mismatch UX.
11
+
Version 0.2.9 coordinates protocol 0.1.9 with Android 0.4.2 (build 6), generated cross-language conformance fixtures, exact-match version gating, hard-block mismatch UX, durable Answer-driven agent auto-wake, and answer-ready widget cleanup after reads.
12
12
13
13
Issues #1-#11 provide the v1 implementation: runnable TypeScript workspace, `pi-postbox-server` CLI, Pi extension with `write_question`, WebSocket session registration, SSE browser state, SQLite persistence/history, structured Questions and options, semantic working/blocked/idle state, reconnect/idempotency/expiry, local terminal fallback commands, editable presentation metadata, and packaging/deployment docs plus a release smoke script. Version 0.2.6 updates Android 0.4.1 to include the server-required Question revision when submitting an Answer. Version 0.2.5 keeps the footer and status surfaces from undercounting a locally tracked open Question when the durable owner snapshot is briefly stale, makes published package updates robust on npm 11, and prebuilds the shared protocol before clean-checkout test runs. Version 0.2.3 adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Version 0.2.2 adds complete npm license and source metadata, fixes the published CLI bin path, and excludes test source from the package tarball. Version 0.2.1 bounds and paginates every model-facing bulk read, uses compact stateless cursors, hides inactive historical owners by default, trims repeated list fields, and preserves checkout development ports across restarts. Version 0.2.0 replaces the separate model-facing create/update tools with one explicit-action `write_question` surface and returns reusable current Question handles from creation. Version 0.1.9 requires a concise ambiguity for new Questions, simplifies parent and expiry inputs, renames option `meaning` to `impact`, removes top-level handoff context and per-option context, removes reconstructed Question Chat, and renders single/multi choice with accessible ballot controls. Version 0.1.8 exposed single-Question create/idempotent receipt disposition and safely required a full Pi restart when `/reload` retained an incompatible shared protocol dependency. Version 0.1.7 reduced model-facing tool schemas, strictly described exact-owner filters, and made recovery reads compact by default with an explicit full view while preserving strict server-side action validation and internal provenance/expiry compatibility.
14
14
@@ -82,7 +82,7 @@ pi-postbox-server
82
82
83
83
## Agent tool contracts
84
84
85
-
`write_question` is the single model-facing write surface. Use `action: "create"` or `action: "create_batch"` to persist Questions, and `revise`, `cancel`, `supersede`, `reparent`, `transfer`, or `takeover` to change an existing Question. Creation returns after durable persistence rather than waiting for a human Answer. Continue any independent work and do not poll `get_answer`, `list_question_status`, or `list_questions`: Postbox notifies the owning Pi Session when an Answer is available. If that human decision becomes the only remaining blocker, call `wait_for_postbox`once to enter explicit idle/waiting mode; after it wakes, read the relevant Question with `get_answer`.
85
+
`write_question` is the single model-facing write surface. Use `action: "create"` or `action: "create_batch"` to persist Questions, and `revise`, `cancel`, `supersede`, `reparent`, `transfer`, or `takeover` to change an existing Question. Creation returns after durable persistence rather than waiting for a human Answer. Continue any independent work and do not poll `get_answer`, `list_question_status`, or `list_questions`: by default, Postbox coalesces Answer notifications and starts a follow-up agent turn for an owning Pi Session that is no longer running. The privacy-preserving wake contains Question identifiers, never Answer content, and tells the agent to read with `get_answer`. If that human decision becomes the only remaining blocker during the current turn, `wait_for_postbox`remains available as an explicit idle/waiting mode.
86
86
87
87
Batch idempotency is per Question: put a stable `requestId` on each item. A top-level batch `requestId` is invalid because Postbox does not claim an atomic batch-level idempotency contract. Questions may refer to an earlier item with `parentLocalRef`; the server validates the ordered batch before persisting independent Question records:
88
88
@@ -112,7 +112,7 @@ Agent query tools use small workflow-oriented results by default:
112
112
-`list_questions` returns at most 100 records per page; `list_question_status` returns at most 50. Both accept only `scope` and a strict `{ "harness": "…", "ownerId": "…" }` owner filter on the model-facing surface, and return `nextCursor` when another page exists.
113
113
-`list_postbox_owners()` derives the caller's feature scope, omits offline zero-count historical owners by default, and returns paged coarse presence and active/unread counts (100 maximum per page). Set `includeInactive: true` only for audit workflows.
114
114
-`get_postbox_owner_status({ owners })` accepts at most 20 exact owner identities.
115
-
-`get_answer({ questionId })` returns `{ "type": "pending", "status": "pending", "questionId": "…" }` while the Question remains unresolved; this is a normal bounded result, not an error.
115
+
-`get_answer({ questionId })` returns `{ "type": "pending", "status": "pending", "questionId": "…" }` while the Question remains unresolved; this is a normal bounded result, not an error. After it successfully reads an Answer, the extension clears only that Answer's matching answer-ready widget.
116
116
117
117
Pagination cursors are opaque, compact, stateless, and bound to the original query. Copy them unchanged into the next call with the same filters; malformed or cross-query cursors are rejected.
118
118
@@ -149,10 +149,13 @@ The extension resolves a server profile from the loaded package. Installed npm/g
149
149
150
150
```json
151
151
{
152
-
"serverUrl": "http://127.0.0.1:32187"
152
+
"serverUrl": "http://127.0.0.1:32187",
153
+
"autoWake": true
153
154
}
154
155
```
155
156
157
+
Answer auto-wake is enabled by default. Set `"autoWake": false` in the profile config, or set `PI_POSTBOX_AUTO_WAKE=off`, to keep widget-only notifications without starting an agent turn. `PI_POSTBOX_AUTO_WAKE=on` overrides a disabled config value.
158
+
156
159
Override config location with `PI_POSTBOX_CONFIG_PATH` or `PI_POSTBOX_CONFIG_DIR`. The extension creates a generated machine id on first startup and persists it in this config file. That generated machine id is stable across sessions; hostname and dashboard aliases provide human-readable names.
157
160
158
161
For local self-healing, each profile publishes only `<profile-state-dir>/active-local/server.json`. The extension validates that record against `/healthz` profile, instance, URL, protocol, and build identity. Health reports the package version separately from the protocol version, while the default build id fingerprints the loaded runtime bytes. It never orders or falls back across profiles. A global production loopback `serverUrl` is therefore invisible to a checkout development profile, while `PI_POSTBOX_URL` remains an intentional escape hatch.
Copy file name to clipboardExpand all lines: docs/configuration.md
+9-2Lines changed: 9 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -74,10 +74,15 @@ Example config:
74
74
75
75
```json
76
76
{
77
-
"serverUrl": "http://127.0.0.1:32187"
77
+
"serverUrl": "http://127.0.0.1:32187",
78
+
"autoWake": true
78
79
}
79
80
```
80
81
82
+
Answer auto-wake is enabled by default. When an Answer arrives while the owning Pi Session is not explicitly waiting, the extension durably records a wake intent, coalesces notifications arriving in the same short burst, and injects a privacy-preserving follow-up message that starts a turn if the agent is idle. The message includes Question identifiers but no Question text or Answer content. If Pi stops after recording the intent but before persisting the follow-up message, the active session branch recovers the wake after restart without duplicating already-persisted wakes.
83
+
84
+
Set `"autoWake": false` to retain the answer-ready widget without starting an agent turn. The `PI_POSTBOX_AUTO_WAKE` environment variable overrides the JSON value; accepted enabling values are `1`, `true`, `yes`, `on`, and `enabled`, while `0`, `false`, `no`, `off`, and `disabled` disable it.
85
+
81
86
The extension creates and persists a generated machine id in this same config file on first use. That generated machine id is the stable identity used by the dashboard. Hostname is also sent for display, and the dashboard can persist a friendlier machine alias.
82
87
83
88
Server payload limits are finite even though rich interviewer context is allowed: HTTP bodies and extension WebSocket messages are capped, rich text fields/options have generous schema limits, and project icons are limited to small image data URLs uploaded by the extension.
@@ -114,7 +119,9 @@ The icon path is resolved by the extension on the Pi machine, converted into a s
114
119
115
120
## Agent notification and explicit waiting
116
121
117
-
The `write_question` create actions return after durable persistence and include a reusable current Question handle. The owning Pi Session receives a lightweight notification when an Answer becomes available, so agents should continue independent work and must not poll `get_answer`, `list_question_status`, or `list_questions`. When the decision is the sole remaining blocker, call `wait_for_postbox` once to enter explicit idle/blocked mode; after it wakes, call `get_answer` for the relevant Question. Cancelling that ephemeral wait leaves durable Questions and Answers intact.
122
+
The `write_question` create actions return after durable persistence and include a reusable current Question handle. Agents should continue independent work and must not poll `get_answer`, `list_question_status`, or `list_questions`. With default auto-wake enabled, an Answer notification starts a privacy-preserving follow-up turn when the owning Pi Session is idle; the agent then calls `get_answer` for the notified Question identifiers. A successful Answer read clears only the matching answer-ready widget; pending and lifecycle-only reads leave Answer widgets unchanged. Multiple notifications in the batching window produce one turn.
123
+
124
+
When the decision is the sole remaining blocker during an active turn, `wait_for_postbox` can still enter explicit idle/blocked mode. The server does not send proactive Answer notifications while that owner is explicitly waiting, so the wait result resumes the existing turn without also scheduling an auto-wake follow-up. Cancelling that ephemeral wait leaves durable Questions and Answers intact. Disable auto-wake with `autoWake: false` or `PI_POSTBOX_AUTO_WAKE=off` when widget-only notification behavior is preferred.
Copy file name to clipboardExpand all lines: docs/protocol.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -283,7 +283,7 @@ Package-local autostart is a client recovery behavior for `write_question` and t
283
283
- Treat `requestId`, `sessionId`, `machineId`, and `projectId` as stable protocol identifiers.
284
284
- Handle unknown fields gracefully.
285
285
- Use `/healthz` to confirm service and protocol version before relying on newer fields.
286
-
- Package version 0.2.7 uses protocol 0.1.9 and Android 0.4.2 (versionCode 6). Android exact-matches its generated supported version, versions every consumed envelope, and hard-blocks incompatible connection-scoped workflows before decoding or side effects.
286
+
- Package version 0.2.9 uses protocol 0.1.9 and Android 0.4.2 (versionCode 6). Android exact-matches its generated supported version, versions every consumed envelope, and hard-blocks incompatible connection-scoped workflows before decoding or side effects.
287
287
- Question Chat is exact-fork only. `forkKind` accepts only `"exact"`; context-only activation endpoints and relay commands are not part of the current protocol.
288
288
- Package version 0.2.6 retains protocol compatibility version 0.1.8 and updates Android 0.4.1 to submit the current Question revision required by the Answer endpoint. Package version 0.2.5 retains protocol compatibility version 0.1.8, prevents stale durable owner counts from hiding locally tracked open Questions in status surfaces, makes published package updates robust on npm 11, and prebuilds the shared protocol before clean-checkout test runs. Package version 0.2.3 retains protocol compatibility version 0.1.8 and adds validated npm Trusted Publishing from pushes to the main branch through GitHub Actions OIDC. Package version 0.2.2 retained protocol compatibility version 0.1.8 and changed release packaging metadata only. Package version 0.2.1 introduced protocol compatibility version 0.1.8, adds server-enforced bulk-read limits and paged status/history/owner envelopes, emits compact stateless cursors, and omits inactive owners by default. Matching extension/server/protocol builds are required. Package version 0.2.0 used protocol 0.1.7, merged Question creation and updates into the model-facing `write_question` tool, and extended create receipts with current content/ownership revisions and lifecycle status. Package version 0.1.9 used protocol 0.1.6 and required ambiguity on new Questions, simplified model-facing parent/expiry fields, renamed legacy option `meaning` to `impact`, removed top-level handoff context and per-option context, removed reconstructed Question Chat, and used exact-fork Chat only. Package version 0.1.8 added single-Question receipt disposition and suppressed autostart when exact live-profile identity proved that `/reload` retained an incompatible protocol dependency; a full Pi restart was then required. Package version 0.1.7 added compact recovery views, explicit exact-owner schemas, and a compact model-facing update schema.
289
289
- V1 has no app-level authentication; restrict network reachability with Tailscale/lizardtail or an external auth proxy.
0 commit comments