@astrosheep/square 0.3.106 → 0.4.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/dist/activity-feed.js +1 -1
- package/dist/artifact-store.d.ts +41 -0
- package/dist/artifact-store.js +272 -0
- package/dist/artifact.d.ts +6 -12
- package/dist/artifact.js +43 -344
- package/dist/attention-presentation.d.ts +13 -7
- package/dist/attention-presentation.js +29 -68
- package/dist/boundary-presentation.d.ts +3 -16
- package/dist/boundary-presentation.js +29 -109
- package/dist/card-presentation.d.ts +1 -0
- package/dist/card-presentation.js +2 -0
- package/dist/catch-decisions.d.ts +2 -2
- package/dist/catch-decisions.js +7 -3
- package/dist/catch-selection.d.ts +8 -0
- package/dist/catch-selection.js +5 -0
- package/dist/claude-delivery.d.ts +14 -12
- package/dist/claude-delivery.js +42 -142
- package/dist/claude-mcp-context.js +2 -2
- package/dist/claude-mod.js +28 -140
- package/dist/claude-transport.d.ts +5 -0
- package/dist/claude-transport.js +34 -0
- package/dist/cli/context.d.ts +2 -2
- package/dist/cli/context.js +7 -10
- package/dist/cli/maintenance-commands.d.ts +0 -4
- package/dist/cli/maintenance-commands.js +2 -29
- package/dist/cli/observation-commands.d.ts +2 -0
- package/dist/cli/observation-commands.js +12 -2
- package/dist/cli/program.js +1 -1
- package/dist/cli/registry.js +4 -3
- package/dist/codex-address.d.ts +2 -2
- package/dist/codex-boundary-state.d.ts +1 -5
- package/dist/codex-boundary-state.js +0 -4
- package/dist/codex-hook.d.ts +7 -10
- package/dist/codex-hook.js +69 -33
- package/dist/codex-queue.d.ts +10 -11
- package/dist/codex-queue.js +32 -34
- package/dist/codex-watch.d.ts +2 -0
- package/dist/codex-watch.js +100 -0
- package/dist/decisions.js +3 -3
- package/dist/delivery-deferral.d.ts +1 -19
- package/dist/delivery-deferral.js +1 -29
- package/dist/delivery-frame.d.ts +7 -0
- package/dist/delivery-frame.js +11 -0
- package/dist/delivery-ledger-sqlite.d.ts +97 -0
- package/dist/delivery-ledger-sqlite.js +496 -0
- package/dist/delivery-ledger.d.ts +196 -0
- package/dist/delivery-ledger.js +268 -0
- package/dist/delivery-lifetime.d.ts +6 -0
- package/dist/delivery-lifetime.js +45 -0
- package/dist/harness-links.js +61 -7
- package/dist/harness.js +12 -17
- package/dist/help.js +3 -6
- package/dist/http-delivery.d.ts +5 -9
- package/dist/http-delivery.js +20 -79
- package/dist/inbox.d.ts +6 -57
- package/dist/inbox.js +24 -380
- package/dist/index.d.ts +7 -4
- package/dist/index.js +5 -2
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.js +40 -70
- package/dist/message.d.ts +7 -0
- package/dist/message.js +23 -0
- package/dist/model.d.ts +15 -91
- package/dist/model.js +2 -140
- package/dist/neutral.d.ts +72 -0
- package/dist/neutral.js +27 -0
- package/dist/notifications.d.ts +24 -26
- package/dist/notifications.js +39 -143
- package/dist/operation-control.d.ts +4 -0
- package/dist/operation-control.js +20 -0
- package/dist/operation-presentation.d.ts +1 -2
- package/dist/operation-presentation.js +1 -7
- package/dist/owner.d.ts +2 -2
- package/dist/owner.js +1 -1
- package/dist/packages/agent-delivery/src/claude-native.d.ts +2 -0
- package/dist/packages/agent-delivery/src/claude-native.js +5 -0
- package/dist/packages/agent-delivery/src/codex-boundary.d.ts +11 -6
- package/dist/packages/agent-delivery/src/codex-boundary.js +31 -40
- package/dist/packages/agent-delivery/src/codex-hook.d.ts +17 -12
- package/dist/packages/agent-delivery/src/codex-hook.js +26 -39
- package/dist/packages/agent-delivery/src/codex.d.ts +3 -0
- package/dist/packages/agent-delivery/src/codex.js +41 -4
- package/dist/packages/agent-delivery/src/index.d.ts +3 -1
- package/dist/packages/agent-delivery/src/index.js +1 -1
- package/dist/packages/agent-delivery/src/paseo.js +11 -2
- package/dist/packages/agent-delivery/src/types.d.ts +1 -0
- package/dist/paseo-delivery.d.ts +5 -5
- package/dist/paseo-delivery.js +19 -99
- package/dist/paseo.d.ts +1 -1
- package/dist/paseo.js +1 -1
- package/dist/plugins/opencode/index.d.ts +5 -3
- package/dist/plugins/opencode/index.js +99 -21
- package/dist/plugins/opencode-shared/delivery.d.ts +23 -0
- package/dist/plugins/opencode-shared/delivery.js +109 -0
- package/dist/plugins/opencode-v1/index.d.ts +28 -0
- package/dist/plugins/opencode-v1/index.js +41 -0
- package/dist/plugins/opencode-v1/runtime.d.ts +56 -0
- package/dist/plugins/opencode-v1/runtime.js +152 -0
- package/dist/plugins/opencode-v1/transport.d.ts +13 -0
- package/dist/plugins/opencode-v1/transport.js +50 -0
- package/dist/plugins/paseo/shared/card-presentation.d.ts +10 -0
- package/dist/plugins/paseo/shared/card-presentation.js +7 -0
- package/dist/ports.d.ts +33 -214
- package/dist/presentation.d.ts +5 -5
- package/dist/presentation.js +1 -0
- package/dist/runtime.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-lifecycle.d.ts +8 -7
- package/dist/session-lifecycle.js +40 -42
- package/dist/sqlite-framing.d.ts +8 -0
- package/dist/sqlite-framing.js +31 -0
- package/dist/sqlite-square.d.ts +16 -26
- package/dist/sqlite-square.js +199 -262
- package/dist/sqlite-values.d.ts +21 -0
- package/dist/sqlite-values.js +78 -0
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +5 -8
- package/dist/square-core.d.ts +0 -1
- package/dist/square-domain.d.ts +12 -10
- package/dist/square-domain.js +105 -223
- package/dist/square-facade.d.ts +25 -76
- package/dist/square-location.d.ts +6 -1
- package/dist/square-location.js +1 -1
- package/dist/square-post.d.ts +53 -0
- package/dist/square-post.js +4 -0
- package/dist/square-posting.d.ts +13 -0
- package/dist/square-posting.js +174 -0
- package/dist/square-producer-sqlite.d.ts +11 -0
- package/dist/square-producer-sqlite.js +210 -0
- package/dist/square-receive.d.ts +2 -3
- package/dist/square-sqlite.d.ts +33 -42
- package/dist/square-sqlite.js +236 -768
- package/dist/square-tools.d.ts +8 -0
- package/dist/square-tools.js +39 -0
- package/dist/square-values.d.ts +27 -0
- package/dist/square-values.js +90 -0
- package/dist/views.d.ts +6 -6
- package/dist/views.js +14 -9
- package/dist/wake-sink.d.ts +4 -11
- package/dist/wake-sink.js +8 -32
- package/dist/wake-transports.d.ts +4 -0
- package/dist/wake-transports.js +11 -0
- package/examples/symmetric-domains.mjs +29 -249
- package/guides/change-waits.md +13 -53
- package/guides/claude-native.md +19 -172
- package/guides/codex-delivery.md +55 -78
- package/guides/delivery-primitives.md +48 -207
- package/guides/operation-cancellation.md +2 -5
- package/guides/participant-ownership.md +25 -89
- package/guides/pi-native-delivery.md +19 -56
- package/guides/pi-tools.md +6 -8
- package/guides/row-runtime-delivery-evidence.md +2 -0
- package/guides/row-storage-design.md +19 -44
- package/guides/square-api.md +113 -538
- package/package.json +8 -8
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/hooks.json +1 -1
- package/plugins/claude/{hooks/register.js → mods/square.js} +4 -7
- package/plugins/claude/types.d.ts +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/hooks/hooks.json +11 -23
- package/plugins/opencode/index.ts +91 -23
- package/plugins/opencode-shared/delivery.ts +91 -0
- package/plugins/opencode-v1/index.ts +36 -0
- package/plugins/opencode-v1/runtime.ts +134 -0
- package/plugins/opencode-v1/transport.ts +41 -0
- package/plugins/paseo/OVERVIEW.md +5 -5
- package/plugins/paseo/README.md +7 -6
- package/plugins/paseo/client/markdown.tsx +5 -5
- package/plugins/paseo/client/square-message.tsx +28 -24
- package/plugins/paseo/client/transform.ts +8 -5
- package/plugins/paseo/shared/card-presentation.ts +16 -0
- package/plugins/paseo/shared/message.ts +6 -11
- package/plugins/pi/square-pi.js +167 -451
- package/dist/channel.d.ts +0 -74
- package/dist/channel.js +0 -92
- package/dist/claude-delivery-status.d.ts +0 -13
- package/dist/claude-delivery-status.js +0 -46
- package/dist/cmd/notify-once.d.ts +0 -2
- package/dist/cmd/notify-once.js +0 -29
- package/dist/delivery-attempts.d.ts +0 -52
- package/dist/delivery-attempts.js +0 -73
- package/dist/delivery-effects.d.ts +0 -139
- package/dist/delivery-effects.js +0 -163
- package/dist/delivery-health.d.ts +0 -51
- package/dist/delivery-health.js +0 -173
- package/dist/delivery-operations.d.ts +0 -9
- package/dist/delivery-operations.js +0 -168
- package/dist/delivery-primitives.d.ts +0 -5
- package/dist/delivery-primitives.js +0 -3
- package/dist/delivery.d.ts +0 -45
- package/dist/delivery.js +0 -106
- package/dist/plugins/opencode/delivery.d.ts +0 -19
- package/dist/plugins/opencode/delivery.js +0 -238
- package/dist/presentation-operations.d.ts +0 -18
- package/dist/presentation-operations.js +0 -86
- package/dist/square-index.d.ts +0 -16
- package/dist/square-index.js +0 -106
- package/dist/square-legacy-framing.d.ts +0 -11
- package/dist/square-legacy-framing.js +0 -64
- package/dist/square-migration-host-ledger.d.ts +0 -26
- package/dist/square-migration-host-ledger.js +0 -169
- package/dist/square-migration.d.ts +0 -30
- package/dist/square-migration.js +0 -599
- package/guides/migration.md +0 -156
- package/plugins/opencode/delivery.ts +0 -211
package/guides/square-api.md
CHANGED
|
@@ -1,37 +1,18 @@
|
|
|
1
1
|
# Square and Participant API
|
|
2
2
|
|
|
3
|
-
`Square`
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
For transaction-scoped attempt custody and the storage-independent dispatch/prepared presentation
|
|
8
|
-
lifecycles used by Square's actual adapters, see the [delivery primitives](delivery-primitives.md).
|
|
9
|
-
Full presentation settlement atomically completes its captured attempt and full-consumption receipts;
|
|
10
|
-
clipped previews record no full receipt. Cancellation/deferral is pre-effect policy, never a veto of a
|
|
11
|
-
successful sink. The public primitive distinguishes sink observations from refused/failed persistence;
|
|
12
|
-
Square retains its existing result shapes and explicit failed classification for rejected sinks.
|
|
13
|
-
For caller-owned item admission and sparse consumption, see the [receive primitive](receive-primitive.md).
|
|
14
|
-
`square-facade.ts` contains only public types. There is no separate operation factory, policy
|
|
15
|
-
dispatcher or `{data, projection}` envelope.
|
|
3
|
+
`Square` is the concrete resource shared by SDK, CLI, MCP and Pi; `square.ts` is the CLI
|
|
4
|
+
entrypoint. `square-facade.ts` declares public operation types, not a second execution path. See
|
|
5
|
+
[attention-primitive.md](attention-primitive.md) for audience computation and
|
|
6
|
+
[delivery-primitives.md](delivery-primitives.md) for the host delivery ledger.
|
|
16
7
|
|
|
17
|
-
## Open
|
|
18
|
-
|
|
19
|
-
Membership is explicit: no harness joins a square based on its filename or working directory.
|
|
20
|
-
`PUBLIC.square` has exactly the same behavior as any other square file. Membership (join/done,
|
|
21
|
-
read horizon and listens) is separate from host attachment (whether an exact owner is currently
|
|
22
|
-
executing for that participant). Host shutdown detaches; it does not make the participant leave.
|
|
23
|
-
An owner is an opaque, non-secret string compared only for equality. It is not a participant name
|
|
24
|
-
or authentication credential: one owner may control several names. The SDK requires it explicitly;
|
|
25
|
-
`localUserOwner()` supplies `user:<OS username>@<hostname>` when that is the intended actor.
|
|
8
|
+
## Open and join
|
|
26
9
|
|
|
27
10
|
```ts
|
|
28
11
|
import { Square } from '@astrosheep/square';
|
|
29
12
|
|
|
30
|
-
const owner = 'example:alice-process';
|
|
31
13
|
const square = await Square.at({ path: './discussion.square' });
|
|
32
14
|
try {
|
|
33
|
-
const
|
|
34
|
-
const alice = joined.participant;
|
|
15
|
+
const { participant: alice } = await square.join('Alice', { owner: 'example:alice' });
|
|
35
16
|
const sent = await alice.express('Hello @Bob', { force: true });
|
|
36
17
|
const page = await square.history();
|
|
37
18
|
console.log(sent.activity.id, page.activities);
|
|
@@ -40,516 +21,110 @@ try {
|
|
|
40
21
|
}
|
|
41
22
|
```
|
|
42
23
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
`
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
`
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
} },
|
|
151
|
-
});
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
The URL must have an HTTP(S) scheme and hostname, with no embedded username/password or fragment.
|
|
155
|
-
Local/private endpoints are allowed. HTTPS uses normal certificate validation. The sender POSTs
|
|
156
|
-
`Content-Type: application/json` to that URL without following redirects. When `tokenEnv` is
|
|
157
|
-
configured, the sender resolves it in its own environment (`env` at open, otherwise `process.env`),
|
|
158
|
-
not the receiver's. A missing, blank or invalid bearer token refuses locally without HTTP I/O.
|
|
159
|
-
Keep the secret in that environment variable, never in the stored address. Diagnostics do not echo
|
|
160
|
-
URLs or raw network errors; URL query strings may themselves be sensitive and remain stored config.
|
|
161
|
-
|
|
162
|
-
The JSON body contains only:
|
|
163
|
-
|
|
164
|
-
```json
|
|
165
|
-
{
|
|
166
|
-
"location": "/sender/path/discussion.square",
|
|
167
|
-
"participant": "Bob",
|
|
168
|
-
"activity": "act/12",
|
|
169
|
-
"actor": "Alice",
|
|
170
|
-
"attemptN": 0,
|
|
171
|
-
"preview": "<existing rendered Square wake reminder>"
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
`attemptN` is omitted when unavailable. The preview is the existing rendered awareness reminder,
|
|
176
|
-
not a new payload template or full artifact. Owner, route and claim token are never included. `location` is the
|
|
177
|
-
**sender's artifact locator**, not a downloadable URL. HTTP adds wake notification, not a remote
|
|
178
|
-
Square backend: the receiver owns how it queues/wakes its agent and gives it access to Square.
|
|
179
|
-
|
|
180
|
-
Return 2xx promptly only after accepting wake custody. A 2xx records an accepted wake, **not** catch
|
|
181
|
-
or presentation; activity remains unread until normal consumption. Redirects and 4xx are rejected,
|
|
182
|
-
5xx are transient failures, and other non-2xx statuses are rejected. A network error or timeout
|
|
183
|
-
after sending starts is **unknown**: the receiver may already have accepted. Unknown/accepted wakes
|
|
184
|
-
are not automatically replayed. There is no retry loop in the HTTP adapter; existing delivery policy
|
|
185
|
-
owns future dispatch. Local configuration, absent preview, expired pre-send budget or a refused final
|
|
186
|
-
gate sends nothing. One deadline covers preparation, the final gate and waiting for response headers;
|
|
187
|
-
response bodies are cancelled rather than read. Claims, per-owner ordering, deferral, attachment and
|
|
188
|
-
cancellation checks are shared with every transport. `wakeTransport: false` still disables wakes,
|
|
189
|
-
and an injected transport remains authoritative.
|
|
190
|
-
|
|
191
|
-
The enclosing dispatcher's safety deadline is transport-neutral: if an attempt is still unsettled,
|
|
192
|
-
it records conservative **unknown**, even when HTTP has not started (for example, while the final
|
|
193
|
-
send gate is stalled). A local pre-send expiry is known no-send only when the adapter's result arrives
|
|
194
|
-
before that outer fallback. HTTP still must not start I/O after a stalled gate resumes past its
|
|
195
|
-
deadline; the persisted unknown remains and prevents automatic replay. This does not change the
|
|
196
|
-
shared dispatcher's timeout or retry policy.
|
|
197
|
-
|
|
198
|
-
## One set of operations and defaults
|
|
199
|
-
|
|
200
|
-
Square owns `history`, `status`, `participants`, `stream`, and recovery observations.
|
|
201
|
-
A file-backed `stream` follows the path with a fresh artifact read for each page, so atomic file
|
|
202
|
-
replacement is visible even while the resource holds its original connection. Its iterator owns
|
|
203
|
-
its observation lifetime: `return()` interrupts a pending pull; closing a local Square does not close
|
|
204
|
-
that independent path observation.
|
|
205
|
-
Internal readers that explicitly borrow an artifact port leave its lifetime with the lender and
|
|
206
|
-
propagate port failures rather than waiting for path repair.
|
|
207
|
-
|
|
208
|
-
`Activity` is `{id, at, kind, actor, body?, metadata?, mentions, reach?, target?, reply?}` throughout
|
|
209
|
-
the SDK. Stream without a recipient yields these activities; with a recipient it selects
|
|
210
|
-
their landed directed activities and adds `perception` and the landing route `via`
|
|
211
|
-
(`mention`, `reply`, `attention`, or `bell`). Perception follows the viewer's actual landed audience;
|
|
212
|
-
`via` is absent when no directed route exists. Stream starts at a bounded tail or after an `ActivityId`
|
|
213
|
-
like `act/12`; it never consumes activity.
|
|
214
|
-
Participant owns `express`, `catch`, `pending`, `ack`, `listen`, `unlisten`, `ignore`, `listening`, `done`,
|
|
215
|
-
`deferDelivery`, `renewDeliveryDeferral`, and `releaseDeliveryDeferral`. History belongs only to
|
|
216
|
-
Square; there is no `Participant.history`.
|
|
217
|
-
|
|
218
|
-
- Express waits when throttled unless `noWait: true`, for **every** caller. `ExpressResult`
|
|
219
|
-
includes the committed `activity`, optional landing-time warnings (`unmatchedMentions`,
|
|
220
|
-
`replyAuthorNotHere`), `hint` and `observation`. Warnings are not stored on the activity.
|
|
221
|
-
- A say may carry `metadata`, an immutable JSON object with nested JSON values and a maximum serialized
|
|
222
|
-
UTF-8 size of 16 KiB (`ACTIVITY_METADATA_MAX_BYTES`). `alice.express({body?, metadata?, ...options}, control?)`
|
|
223
|
-
is the object form; the existing `express(body, options?, control?)` form remains valid. A non-empty
|
|
224
|
-
body may carry `{}`; an omitted, empty or whitespace-only body requires non-empty metadata. Metadata-only
|
|
225
|
-
says omit `body` from public activity records. Invalid objects, cycles, unsupported values and oversized
|
|
226
|
-
metadata refuse before landing with `activityUnsent`. Metadata is carried unchanged by express, history,
|
|
227
|
-
catch, status/latest, unread projections and stream records through the SDK, CLI and stream.
|
|
228
|
-
MCP and Pi tools are not a metadata surface: their `express` requires a body and its schema rejects a
|
|
229
|
-
`metadata` argument. Tool history/catch return rendered text with a structured-activity placeholder,
|
|
230
|
-
not metadata JSON or activity objects. Metadata does not affect mentions, replies, listening, audience,
|
|
231
|
-
ordering, consumption or permissions. A current participant may temporarily defer proactive delivery
|
|
232
|
-
by exact metadata match through the SDK lease API below. Metadata may nest up to 256 levels; the bound is enforced before
|
|
233
|
-
persistence and public reads. Human text uses a concise structured-activity placeholder and never prints
|
|
234
|
-
metadata JSON. SDK history and pending queries accept exact metadata matches; there is no query
|
|
235
|
-
language or metadata index. CLI `--metadata <json>` remains an express input flag.
|
|
236
|
-
- Catch returns `{activities, remaining, reason, hint?, observation?}`. Each activity includes
|
|
237
|
-
viewer-relative `perception` and `via`. Reasons are `drained`, `idle`, `capped`, `quorum`,
|
|
238
|
-
`replaced`, or `already-active`. Omitted/zero idle is immediate; positive idle uses the single
|
|
239
|
-
leased quiet wait. Receipt selection, perception, routes, counts and terminal facts settle
|
|
240
|
-
in the receipt transaction. Cancellation/replacement releases only that waiter's lease and never
|
|
241
|
-
consumes future activity.
|
|
242
|
-
- All history callers return a `HistoryResult` object with `activities`. Default page size is ten;
|
|
243
|
-
`limit: null` explicitly requests an unbounded archive. Numeric limits must be 1–100. Contextual
|
|
244
|
-
queries still reject an implicit merged window over 100 activities; an explicit numeric limit
|
|
245
|
-
bounds it. CLI/tool schemas accept numeric limits only. History never writes receipts; history
|
|
246
|
-
observations retain lifetime say ordinals for CLI `history --format number`.
|
|
247
|
-
- `participants()` returns `{participants, observation?}` and `listening()` returns
|
|
248
|
-
`{listening, observation?}`, not arrays carrying metadata. Participant summaries use `presence`
|
|
249
|
-
(`never-joined`, `active`, `watching`, `away`, or `done`). Away participants remain members,
|
|
250
|
-
count toward in-square totals and keep receiving normal bell, mention and listened audience. Its roster
|
|
251
|
-
supplies the participant counts. Core `square.status({viewer})` uses only the explicitly supplied viewer; with
|
|
252
|
-
no viewer it returns an unfiltered overview without viewer-specific `listening`. Core status does
|
|
253
|
-
not select or authorize a seat. CLI and tools check an explicit `--as`/`as` with `selectOwnSeat`;
|
|
254
|
-
otherwise exactly one attached seat of the caller's owner becomes the viewer, while zero or multiple
|
|
255
|
-
seats (or no owner) produce the overview. Snapshot participants use the same `name`, `presence` and
|
|
256
|
-
`listening` facts, excluding never-joined people; its detached `delivered(name, id)` predicate
|
|
257
|
-
remains available.
|
|
258
|
-
- `unlisten(target)` removes only that participant's current listen edge to the target, without
|
|
259
|
-
leaving or blocking future mentions/replies. It returns the same `ListenerChangeResult` as listen
|
|
260
|
-
and ignore, with `activity: null` when no listen exists. Existing ignores are unchanged. Earlier
|
|
261
|
-
landed audiences and receipts are never rewritten; listening again remains available.
|
|
262
|
-
- Lifecycle operations return `{activity, observation?}` and use the same artifact custody gate;
|
|
263
|
-
observations do not repeat the activity. Join entry uses public activities with settled perception,
|
|
264
|
-
and status observations use public join activities. Done accepts no message and retires only its
|
|
265
|
-
attached, captured owner/join generation; it never implicitly rejoins. A done participant is not
|
|
266
|
-
recoverable authority for any host path.
|
|
267
|
-
- Recovery summarizes unread directed activity with per-sender count, latest age and the single
|
|
268
|
-
greatest-index preview. Age uses the greatest timestamp, which may belong to another activity.
|
|
269
|
-
|
|
270
|
-
Operations that accept an `OperationControl` use a final argument with `signal` and optional typed
|
|
271
|
-
`onProgress`. Listener/lifecycle operations take optional observation options before that argument;
|
|
272
|
-
participant selection, seat discovery and host cleanup methods do not take an `OperationControl`.
|
|
273
|
-
|
|
274
|
-
## Shared history and pending filters
|
|
275
|
-
|
|
276
|
-
`HistoryQuery` and `PendingOptions` extend the same exported `ActivityQuery`:
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
interface ActivityQuery {
|
|
280
|
-
at?: readonly ActivityId[];
|
|
281
|
-
from?: readonly string[];
|
|
282
|
-
match?: MetadataMatch;
|
|
283
|
-
search?: { text: string; mode: 'literal' | 'regex' };
|
|
284
|
-
cursor?: { id: ActivityId; direction: 'before' | 'after' };
|
|
285
|
-
}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
- Filters combine with AND. IDs in `at` and senders in `from` each combine with OR; an absent array
|
|
289
|
-
is unrestricted, while an explicitly empty array matches nothing. `at` is an exact ID selection;
|
|
290
|
-
only history can expand those IDs with `contextBefore` / `contextAfter`.
|
|
291
|
-
- Sender names use case-insensitive identity matching and need not belong to a joined participant.
|
|
292
|
-
Direct senders such as `keiyaku-notice` can be queried without inventing membership. A valid but
|
|
293
|
-
unmatched sender returns no activities, not an unknown-participant error.
|
|
294
|
-
- `match` uses the same nested own-property, exact type-sensitive scalar equalities as deferrals.
|
|
295
|
-
`search` tests each activity's ID, sender and body independently, case-insensitively. Literal mode
|
|
296
|
-
treats regex characters as plain text; regex mode uses JavaScript's built-in regular expressions,
|
|
297
|
-
without a ReDoS timeout. Search text must be nonempty and regex syntax must be valid. History
|
|
298
|
-
searches says and departures, not joins; pending always selects addressed, unconsumed says.
|
|
299
|
-
- A cursor is an exclusive activity-ID boundary, independent of `limit`: before excludes the anchor
|
|
300
|
-
and everything newer; after excludes the anchor and everything older. No consumption is involved.
|
|
301
|
-
Storage applies the shared filters before limiting and uses the same predicates for counts.
|
|
302
|
-
- History keeps its archive-specific `order`, `mention`, `since` and context options. By default it
|
|
303
|
-
selects the newest page and returns it oldest first; an after cursor selects the oldest following
|
|
304
|
-
page. `order: 'desc'` reverses the selected page, not which activities belong to it. Numeric limits
|
|
305
|
-
stay 1–100, default ten; `limit: null` reads all matches. Exact/context history keeps its existing
|
|
306
|
-
implicit full-window selection with a 100-activity bound unless a numeric limit is supplied.
|
|
307
|
-
- Pending always selects oldest first, including with a before cursor. Its default and maximum page
|
|
308
|
-
size remain 100, and `remaining` counts matching unconsumed activities beyond that page within
|
|
309
|
-
the supplied cursor boundary. It has no history context, ordering or audience override.
|
|
310
|
-
|
|
311
|
-
The SDK accepts only `search` and `cursor`, not the removed `grep` / `fixed` / `before` / `after`
|
|
312
|
-
fields. CLI flags and tool arguments keep those familiar spellings and translate at the adapter
|
|
313
|
-
boundary, e.g. `--fixed text` becomes `search: {text, mode: 'literal'}` and `--after act/12` becomes
|
|
314
|
-
`cursor: {id: 'act/12', direction: 'after'}`. The artifact format and stored activities do not change.
|
|
315
|
-
|
|
316
|
-
## Pending query and exact acknowledgement
|
|
317
|
-
|
|
318
|
-
`Participant.pending(options?, control?)` and `Participant.ack(ids, control?)` separate a read-only
|
|
319
|
-
query from explicit consumption. `ChannelEndpoint` from `@astrosheep/square/channel` exposes the
|
|
320
|
-
identical methods by forwarding to its captured Participant; it has no independent inbox or storage.
|
|
321
|
-
|
|
322
|
-
`Channel.send` / `Square.send` address joined members, including detached members. Attachment gates
|
|
323
|
-
proactive wake, not landing: a detached recipient retains its unread addressed activity without a
|
|
324
|
-
wake and can query/ack it after reattachment. Recipient validation remains all-or-nothing; a missing
|
|
325
|
-
or departed recipient rejects the entire send without landing activity or waking other recipients.
|
|
326
|
-
|
|
327
|
-
```ts
|
|
328
|
-
import type { ChannelEndpoint, MetadataMatch } from '@astrosheep/square/channel';
|
|
329
|
-
|
|
330
|
-
async function drain(endpoint: ChannelEndpoint, match: MetadataMatch) {
|
|
331
|
-
for (;;) {
|
|
332
|
-
const page = await endpoint.pending({ match });
|
|
333
|
-
if (page.activities.length === 0) break;
|
|
334
|
-
// Process the entire page successfully before acknowledging its exact IDs.
|
|
335
|
-
for (const activity of page.activities) await processNotice(activity);
|
|
336
|
-
const { consumed } = await endpoint.ack(page.activities.map(activity => activity.id));
|
|
337
|
-
// consumed may be smaller if another consumer acknowledged some IDs first.
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
- `pending(query: PendingOptions = {}, control?)` returns
|
|
343
|
-
`{activities: readonly PerceivedActivity[], remaining: number}`. It selects only landed,
|
|
344
|
-
addressed, unconsumed says, oldest first. Body, metadata, delivery information, perception and
|
|
345
|
-
route use the same public records as catch; bodies are full stored bodies, not clipped previews.
|
|
346
|
-
- Limit defaults to 100 and must be an integer from 1 through 100. The shared filters above are
|
|
347
|
-
available alongside that limit. Storage applies addressedness, consumption and all supplied
|
|
348
|
-
filters **before** limiting. `remaining` counts matching unconsumed activities outside the returned
|
|
349
|
-
page in the same read transaction. It is not the global unread count or a durable cursor.
|
|
350
|
-
- A pending query consumes nothing, changes no read horizon and writes no delivery/presentation
|
|
351
|
-
evidence. Deferrals, catch leases, cancellation and prior clipped presentation do not hide these
|
|
352
|
-
explicit reads. Like catch, pending includes historical addressed receipt holes before a rejoin;
|
|
353
|
-
it is not the proactive delivery eligibility query.
|
|
354
|
-
- `ack(ids: readonly ActivityId[], control?)` returns `{consumed: number}`, the count of newly
|
|
355
|
-
consumed exact IDs. It validates that **every** supplied ID is addressed to this participant before
|
|
356
|
-
recording any receipts. Malformed, nonexistent or unaddressed IDs reject the whole batch with
|
|
357
|
-
`invalid_args` (`reason: 'not_addressed'` for valid but unaddressed IDs). There is no implicit prefix
|
|
358
|
-
acknowledgement, no match reselection and no requirement for an earlier pending call.
|
|
359
|
-
- Duplicate IDs, repeated acknowledgement and an empty array are idempotent. Existing receipt
|
|
360
|
-
timestamps remain unchanged. Acknowledgement uses the same sparse receipts as catch/full
|
|
361
|
-
presentation, so it removes those IDs from pending and ordinary catch, but exact catch remains
|
|
362
|
-
repeatable. It does **not** assert wake acceptance or presentation and writes no such evidence.
|
|
363
|
-
- Both operations require their captured current owner, generation and attached seat; even an empty
|
|
364
|
-
query/ack cannot reuse a detached, retired or replaced handle. No storage format change is needed.
|
|
365
|
-
Cancellation before the receipt transaction prevents consumption; a committed ack is not undone.
|
|
366
|
-
- To drain all matching notices, keep querying and acknowledging pages until an **empty** page.
|
|
367
|
-
Acknowledging one page exposes the next without a cursor. For read-only pagination instead, pass
|
|
368
|
-
`cursor: {id: page.activities.at(-1)!.id, direction: 'after'}` with the same filters; earlier pages
|
|
369
|
-
stay unconsumed. Do not silently stop after the default page or treat a snapshot `remaining: 0`
|
|
370
|
-
as proof that concurrent producers have stopped. Query and
|
|
371
|
-
ack are separate operations, not an exclusive claim or an exactly-once external-effect guarantee.
|
|
372
|
-
|
|
373
|
-
## Temporary proactive delivery deferral
|
|
374
|
-
|
|
375
|
-
SDK Participants expose three operations. There are no CLI/MCP/Pi authoring
|
|
376
|
-
commands or listing operation in this delivery. Existing proactive adapters still obey deferrals.
|
|
377
|
-
|
|
378
|
-
```ts
|
|
379
|
-
const lease = await alice.deferDelivery({
|
|
380
|
-
match: { fields: [
|
|
381
|
-
{ path: ['job', 'kind'], equals: 'outcome' },
|
|
382
|
-
{ path: ['job', 'id'], equals: 7 },
|
|
383
|
-
] },
|
|
384
|
-
durationMs: 60_000,
|
|
385
|
-
});
|
|
386
|
-
try {
|
|
387
|
-
// Explicit history and catch remain available, including catch({id}).
|
|
388
|
-
const renewed = await alice.renewDeliveryDeferral(lease.id, 60_000);
|
|
389
|
-
// null means absent, expired, or not owned by this current generation.
|
|
390
|
-
} finally {
|
|
391
|
-
await alice.releaseDeliveryDeferral(lease.id);
|
|
392
|
-
}
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
- `MetadataScalar` is `null | boolean | number | string`; numbers must be finite. `MetadataMatch`
|
|
396
|
-
has nonempty `fields`, each `{path: readonly string[], equals: MetadataScalar}`. Paths have one
|
|
397
|
-
or more nonempty string segments, with no duplicates. Only JSON object own properties are
|
|
398
|
-
traversed: arrays, missing/nonobject intermediates and inherited properties do not match.
|
|
399
|
-
Equalities are exact and type-sensitive. A dot inside one segment is a literal key, not path
|
|
400
|
-
syntax. All fields combine with AND; any matching live lease blocks delivery (OR across leases).
|
|
401
|
-
- Each acquire returns a fresh UUID and an operation-clock ISO `expiresAt`: `{id, expiresAt}`.
|
|
402
|
-
Match objects are not returned. `durationMs` must be a positive safe integer and is capped at
|
|
403
|
-
24 hours. Invalid matches, durations and IDs refuse with `invalid_args` before mutation.
|
|
404
|
-
- Renewal extends that same live lease from the renewal operation's clock; expired/missing IDs
|
|
405
|
-
return `null`, and release returns `false`. Independent overlapping leases are never merged;
|
|
406
|
-
releasing one cannot end another. A captured current owner/join generation is required for every
|
|
407
|
-
mutation. Stale handles retain the ownership refusal; done/takeover/rejoin retire old leases.
|
|
408
|
-
- Lease writes change delivery revision, not conversation history. They do not create a receipt,
|
|
409
|
-
change audience or unread counts, hide an archive record, or prohibit explicit catch/pending/ack.
|
|
410
|
-
Catch and ack consume normally; a consumed record is not replayed when a deferral ends. The catch
|
|
411
|
-
lease is a separate, single quiet-wait lease with its existing filters and lifecycle.
|
|
412
|
-
- Producer/sweep, atomic claims, session/native projections, final pre-send checks and proactive
|
|
413
|
-
presentation all share current-generation unexpired matching. Suppressed items get no seen or
|
|
414
|
-
presented receipt. An active pending observer rechecks on release and the earliest relevant
|
|
415
|
-
expiry, including renewed deadlines, without needing a new conversation activity. A one-shot
|
|
416
|
-
producer skips and returns promptly. With no active observer, eligibility is reconsidered at
|
|
417
|
-
the next normal opportunity; no daemon or per-message timer is created.
|
|
418
|
-
- Acquiring a lease is not recall. An external send already past its final freshness check can race
|
|
419
|
-
with acquisition and remain dispatched; a sink effect already written cannot be withdrawn.
|
|
420
|
-
Presentation eligibility is checked before the effect, not again as a veto after success. A batch
|
|
421
|
-
claims and filters its items before its one sink call, then records exactly the successfully rendered
|
|
422
|
-
set under each captured owner/join generation. A lease acquired while the sink returns or before a
|
|
423
|
-
later item's evidence commit does not erase success or allow replay after release. Cancellation
|
|
424
|
-
likewise stops pre-effect work, not truthful completion after a successful sink: evidence settles
|
|
425
|
-
on the original connection with an independent bounded storage lifetime and the same seat fences.
|
|
426
|
-
A rejected/cancelled native landing is not a successful sink. Items filtered
|
|
427
|
-
out before the sink receive no success receipt.
|
|
428
|
-
Cancellation before commit prevents the lease mutation; after commit it remains until explicit
|
|
429
|
-
release, expiry, or seat retirement. See [operation-cancellation.md](operation-cancellation.md).
|
|
430
|
-
|
|
431
|
-
## Optional observations, not another execution path
|
|
432
|
-
|
|
433
|
-
Request `observe: true` on the **same method** when rendering needs additional facts. Each operation
|
|
434
|
-
has a concrete optional observation type, without conditional generics or a generic outcome wrapper.
|
|
435
|
-
Data-only calls do not hydrate join history, the pre-expression feed, catch presence enrichment,
|
|
436
|
-
or history/status presentation annotations.
|
|
437
|
-
|
|
438
|
-
Express captures optional unread context before the attempt: the latest five directed,
|
|
439
|
-
unseen activities after the current join, each preview capped at 400 Unicode characters,
|
|
440
|
-
plus the count outside that preview. It hydrates only that page, not the entire cursor suffix.
|
|
441
|
-
This is a nonconsuming preview even when a short body fits in full; consumption requires `catch`,
|
|
442
|
-
explicit `ack`, or the normal full-notification presentation path. Count and time facts come
|
|
443
|
-
from the committed transaction. Listener and lifecycle observations likewise use their mutation's
|
|
444
|
-
facts, with no postcommit context read. Join uses its mutation's essential facts and treats optional
|
|
445
|
-
entry/history enrichment as best-effort: `observation.enrichmentUnavailable` is explicit and the
|
|
446
|
-
successful receipt survives. Catch preserves its committed page even if optional nearby presence
|
|
447
|
-
fails. A cancellation or failed clock after commit cannot turn these receipts into an unsent retry.
|
|
448
|
-
|
|
449
|
-
Delivery readiness is participant-specific, not a property of the Square resource.
|
|
450
|
-
`ParticipantSummary.deliveryAvailable`, `JoinObservation.deliveryAvailable` and
|
|
451
|
-
`CatchObservation.deliveryAvailable` reflect whether the participant's seat has a stored wake
|
|
452
|
-
address. Catch captures this fact with its selection. Join and catch observations require
|
|
453
|
-
`observe: true`. These flags do not prove that a receiver is live or that delivery succeeded.
|
|
454
|
-
|
|
455
|
-
`OperationError.operation` supplements authoritative error facts with caller/filter/recipient and
|
|
456
|
-
express certainty. Selected-row/execution failures remain unknown unless admission proved the
|
|
457
|
-
expression unsent. CLI saves raw drafts even when opening the resource fails; its initial open
|
|
458
|
-
receives the express abort signal, while recovery reopening is deliberately uncancelled.
|
|
459
|
-
|
|
460
|
-
## Adapters and standalone functions
|
|
461
|
-
|
|
462
|
-
CLI and tools only adapt input, identity, resource lifetime and output. They do not import private
|
|
463
|
-
actions, storage, admission, scanners or query execution. CLI `--json` for join, express, catch,
|
|
464
|
-
history, listen, ignore, unlisten, listening, done, status, participants and inbox
|
|
465
|
-
serializes the same SDK result without requesting `observe: true`. Only `observation` is omitted and
|
|
466
|
-
a live Participant handle becomes `{name}`. History returns one JSON document, including an empty
|
|
467
|
-
`activities` array; `history --format` remains human-oriented. `participants --limit` limits only
|
|
468
|
-
human text, not the SDK result. Stream `--ndjson` remains one SDK stream record per line.
|
|
469
|
-
|
|
470
|
-
MCP/Pi use the shared `square-tools.ts` definitions. All seven tools return only the CLI's rendered text, with no `outputSchema`
|
|
471
|
-
or `structuredContent`. Join text includes its context and recent activity; express text
|
|
472
|
-
includes landing ID/reach, warnings and bounded unread previews, never the sent body echo
|
|
473
|
-
or internal observation tables. Failures remain failed tool results with readable recovery
|
|
474
|
-
text. The SDK and CLI JSON keep their full domain receipts. The optional express observation
|
|
475
|
-
contains `context: {activities: [{id, actor, preview, truncated}], remaining}`, not the old
|
|
476
|
-
unbounded `pendingPublic`/ordinal/perception tables.
|
|
477
|
-
|
|
478
|
-
Express still finishes attempted notification delivery before releasing its resource.
|
|
479
|
-
It overlaps at most four receiving sessions per dispatch, preserving order within each
|
|
480
|
-
session and draining started work even on failure. Claims, final freshness checks and
|
|
481
|
-
uncertain-delivery suppression remain unchanged. Paseo inventory discovery is asynchronous;
|
|
482
|
-
overlapping attempts share only the in-flight inventory read, never a cached idle status.
|
|
483
|
-
The standalone `discoverPaseoAgents` export now returns a promise.
|
|
484
|
-
|
|
485
|
-
`discover(input, options?, control?)`, `inbox(input, owner, options?, control?)`,
|
|
486
|
-
`diagnoseSquare(input, control?)`, and `migrateSquare(input, control?)` are ordinary public exports.
|
|
487
|
-
They are not methods on a synthetic cross-square object. Diagnose/migrate resolve a path without
|
|
488
|
-
opening a valid current-format Square first.
|
|
489
|
-
|
|
490
|
-
## Artifact format and explicit migration
|
|
491
|
-
|
|
492
|
-
The current artifact format is 7. It stores opaque owners rather than harness coordinates and
|
|
493
|
-
preserves format 6's attached/detached distinction. Seats, delivery evidence, cancellation and
|
|
494
|
-
independent delivery deferrals remain separate from conversation activities and catch ownership.
|
|
495
|
-
Ordinary opens refuse older formats with migration guidance and never convert them implicitly.
|
|
496
|
-
|
|
497
|
-
Stop all sessions and services using the artifact, make an offline backup, then run
|
|
498
|
-
`square --location <path.square> migrate` and `doctor` before reopening with upgraded runtimes.
|
|
499
|
-
Supported formats 2–6 convert to 7 in one transaction. Format 6's Body coordinates become encoded
|
|
500
|
-
owners while attachment, generations, wakes, evidence and revisions survive. Formats 4/5 first gain
|
|
501
|
-
attached seats; format 4 also gains empty deferral support. Formats 4–6 never consult HostLedger.
|
|
502
|
-
Historic host-cleanup departures cannot be distinguished from voluntary `done` and stay done.
|
|
503
|
-
For formats 2/3, also freeze and back up the legacy HostLedger used for verified owner/evidence
|
|
504
|
-
import; no authority is manufactured for done participants. Replay-critical native ambiguity
|
|
505
|
-
refuses rather than disappears, including any nonempty legacy token-only tombstones.
|
|
506
|
-
Current-format migration is a byte-preserving no-op. See [migration.md](migration.md) for the
|
|
507
|
-
narrow metadata policy, source-preserving refusal and filesystem requirements. Updating a package
|
|
508
|
-
does not migrate files or install a new runtime.
|
|
509
|
-
|
|
510
|
-
## SDK breaking migration: opaque owners
|
|
511
|
-
|
|
512
|
-
Artifact format 7 introduced opaque owners; format-6 artifacts required explicit migration before
|
|
513
|
-
opening with that format. Current artifacts use format 8 and require explicit migration from format 7.
|
|
514
|
-
`Body`, `sameBody` and `validateBody` are removed from the core and public API. Replace identity
|
|
515
|
-
objects with an explicit owner at each identity-bearing operation; do not put identity on a resource:
|
|
516
|
-
|
|
517
|
-
```ts
|
|
518
|
-
import { Square } from '@astrosheep/square';
|
|
519
|
-
|
|
520
|
-
const aliceOwner = 'example:alice-process';
|
|
521
|
-
const bobOwner = 'example:bob-process';
|
|
522
|
-
const square = await Square.at({ path: './discussion.square' });
|
|
523
|
-
try {
|
|
524
|
-
// Previously: pass body/wakeAddress/participant to Square.at and join(name).
|
|
525
|
-
const { participant: alice } = await square.join('Alice', { owner: aliceOwner }); // wakeAddress is optional
|
|
526
|
-
const { participant: bob } = await square.join('Bob', { owner: bobOwner }); // same resource, another owner
|
|
527
|
-
// For an already attached seat, select it without joining:
|
|
528
|
-
const selected = await square.participant('Alice', { owner: aliceOwner });
|
|
529
|
-
const seats = await square.seatsOf(aliceOwner);
|
|
530
|
-
const { activities } = await square.history(); // not alice.history()
|
|
531
|
-
const status = await square.status({ viewer: selected.name });
|
|
532
|
-
console.log(alice.name, bob.name, seats, activities, status);
|
|
533
|
-
} finally {
|
|
534
|
-
await square.close();
|
|
535
|
-
}
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
Replace `recognize()`/`bodySeats()` with `seatsOf(owner)`, followed by explicit attached-seat
|
|
539
|
-
selection as needed; replace `implicitJoin` with `reattach(name, {owner, wakeAddress?})`. Replace
|
|
540
|
-
`detachOwnedSession`/`endOwnedSession` with the generation-fenced `detach`/`endHeld` methods above.
|
|
541
|
-
`forBody` is removed: use the same Square with operation-local owners. Read readiness from
|
|
542
|
-
participant summaries or join/catch observations, not the removed resource-level
|
|
543
|
-
`automaticDeliveryAvailable`. Core status no longer infers a viewer. Participant selection no longer
|
|
544
|
-
returns a handle for a missing, done, foreign or detached seat.
|
|
545
|
-
|
|
546
|
-
## Other deliberate migration breaks
|
|
547
|
-
|
|
548
|
-
The independent `createSquareApplication` API, its options/results/aliases, and `square-application.ts`
|
|
549
|
-
are deleted. Consumers must open/close an actual Square and select a Participant. SDK joins return
|
|
550
|
-
`(await square.join(name, {owner})).participant`; history callers must use `.activities` and opt into
|
|
551
|
-
full archive reads with `limit: null`. SDK express now waits by default. MCP constructor configuration
|
|
552
|
-
uses `path`, consistent with `Square.at`, rather than `squarePath`.
|
|
553
|
-
|
|
554
|
-
External consumers must migrate before taking this source version. Editing source does not update
|
|
555
|
-
an installed plugin, build, or running extension.
|
|
24
|
+
`Square.at`, `Square.build` and `Square.inMemory` open resources; an owner is supplied per join or
|
|
25
|
+
selection, never captured as the resource's default participant. Owners are opaque non-secret strings,
|
|
26
|
+
not authorization credentials. Adapters resolve their own harness identity without rewriting process
|
|
27
|
+
environment. Membership is explicit; `PUBLIC.square` is an ordinary filename. A participant handle
|
|
28
|
+
captures owner and join generation; rejoin or takeover fences old handles. `done` ends membership;
|
|
29
|
+
host attachment is separate, as described in [participant-ownership.md](participant-ownership.md).
|
|
30
|
+
|
|
31
|
+
## Activity and delivery
|
|
32
|
+
|
|
33
|
+
`Participant.express` lands activity in Square, with optional immutable JSON `metadata` (maximum
|
|
34
|
+
16 KiB). Mentions, replies, bells, listening and ignores determine the landed audience. Activity IDs
|
|
35
|
+
are `act/N`. `Square.history` is the read-only archive; `Participant.catch` consumes directed activity,
|
|
36
|
+
and `Participant.pending` reads addressed unconsumed says without consuming them. `listen`, `unlisten`,
|
|
37
|
+
`ignore`, `listening` and `done` operate on the participant. History, status and participants are
|
|
38
|
+
Square operations. `OperationControl` can carry cancellation; a committed mutation is not undone by
|
|
39
|
+
later cancellation.
|
|
40
|
+
|
|
41
|
+
A live idle catch owns matching activity notifications before producer export ownership is acquired.
|
|
42
|
+
Matching uses its sender and directed-attention filters against the activity's landed delivery route;
|
|
43
|
+
other activities and direct notices remain eligible. Release or expiry permits still-unconsumed activity
|
|
44
|
+
at the next ordinary posting opportunity; caught or ACKed activity is not exported. Starting a catch
|
|
45
|
+
cannot recall or retroactively suppress export ownership already committed.
|
|
46
|
+
|
|
47
|
+
After landing, Square renders and posts a card per audience member to the host delivery ledger using
|
|
48
|
+
`square:<canonical-path>#act/N/recipient/<encodeURIComponent(nameKey(recipient))>/join/<encodeURIComponent(capturedJoinGeneration)>`.
|
|
49
|
+
Notices use the analogous `notice/N` key. The recipient and participant join generation are frozen at
|
|
50
|
+
landing; ledger attachment rotation does not change the key. Post, receipt lookup and suppression use
|
|
51
|
+
the same captured coordinates. A later mutating operation retries unposted work idempotently. Directed
|
|
52
|
+
activity cards bound the body to 200 characters and point to `square_catch` when shortened. Square records which cards contain
|
|
53
|
+
the full activity. Unread means after the read horizon, not caught, and without a ledger receipt for
|
|
54
|
+
a full card. Square folds retained receipts lazily during privileged producer operations; catch permanently suppresses
|
|
55
|
+
the corresponding ledger cards when possible. Ledger receipt evidence has finite retention: after proof
|
|
56
|
+
expires, locally unproved activity remains unread until explicit catch or ACK. Missing evidence proves
|
|
57
|
+
neither consumption nor non-delivery. A shortened card cannot consume the full activity. Handoff
|
|
58
|
+
acceptance is not presentation; a boundary receipt is not proof of comprehension.
|
|
59
|
+
|
|
60
|
+
`Square.send({from, to, body, metadata?}, control?)` creates a producer-owned notice, not a say or a
|
|
61
|
+
membership. `to` is a participant name or readonly array of names. It returns Square-owned
|
|
62
|
+
`SendResult` `{id, at, from, to, body, metadata?}` with `id: notice/N`, distinct from `act/N`.
|
|
63
|
+
Recipients are frozen when the notice lands. The delivered notice text is exactly the supplied body,
|
|
64
|
+
including its original newlines; no sender label or metadata is added to that text. Sender and metadata
|
|
65
|
+
remain producer facts for queries and exact ACK. There is no sender truncate or preview option.
|
|
66
|
+
Notices use the same producer export ownership path as activity cards.
|
|
67
|
+
|
|
68
|
+
## Queries and acknowledgement
|
|
69
|
+
|
|
70
|
+
`Square.participants({local: true, observe?: true}, control?)` reads only World-known participant
|
|
71
|
+
facts, including known departure and attachment state. It needs no host ledger access and does not
|
|
72
|
+
prove current host liveness; `deliveryAvailable` is false in this mode. The default query still overlays
|
|
73
|
+
host attachment and route availability. Local discovery can distinguish known names before selection;
|
|
74
|
+
it does not grant custody or allow fallback over a departed, foreign or detached identity.
|
|
75
|
+
|
|
76
|
+
`Square.history` returns `{activities}` without consuming; `Participant.pending` returns
|
|
77
|
+
`{activities, remaining}` oldest first. Activity queries support exact IDs, senders, metadata matches,
|
|
78
|
+
search and exclusive `act/N` cursors. Filters combine with AND. History defaults to ten records;
|
|
79
|
+
`limit: null` requests the complete archive. Pending defaults to 100 and accepts limits 1–100.
|
|
80
|
+
A pending read does not claim work or change the read horizon.
|
|
81
|
+
|
|
82
|
+
`Participant.ack(ids: readonly ActivityId[], control?)` remains the exact-ID consumption operation,
|
|
83
|
+
returning `{consumed}`. All IDs must be addressed to the participant; invalid or unaddressed IDs
|
|
84
|
+
reject the batch. Duplicate and already consumed IDs are idempotent. It does not assert presentation.
|
|
85
|
+
|
|
86
|
+
For producer waiting, the explicit opt-in
|
|
87
|
+
`Participant.ack({from: string, match: MetadataMatch, future: 'exact'}, control?)` returns
|
|
88
|
+
`Promise<{consumed: number}>` and records a durable recipient-scoped sender and metadata predicate,
|
|
89
|
+
including for a matching notice inserted later. Zero consumed still means the future consumption fact
|
|
90
|
+
committed. This is exact equality of each specified nested scalar field, not equality of the whole
|
|
91
|
+
metadata object, nor a prefix or wildcard match. Supply the full outcome identity; unrelated recipients
|
|
92
|
+
and outcomes remain unaffected. The ordinary ID form does not create a future predicate.
|
|
93
|
+
|
|
94
|
+
Insertion, ACK and producer export ownership serialize in World storage. Once export ownership commits,
|
|
95
|
+
the asynchronous ledger post runs outside that transaction: a later ACK cannot promise recall. The
|
|
96
|
+
fact remains until the producer can prove the corresponding source cannot be inserted or exported
|
|
97
|
+
again; no TTL or first-admission cutoff is required. Producer bookkeeping records the immutable
|
|
98
|
+
`firstPossibleExport` at initial export ownership using actual host time, on the ledger's clock basis.
|
|
99
|
+
A claim is recoverable when its process dies or its 60-second ownership expires; settlement is fenced
|
|
100
|
+
to the captured token. An abandoned uncertain export at or beyond the ledger's minimum 30-day identity
|
|
101
|
+
retention window is not automatically reinserted. Clock or boundary uncertainty is treated conservatively.
|
|
102
|
+
This limit is not a source TTL: it does not reject or expire never-exported sources, and catch and ACK
|
|
103
|
+
remain available. A crash between export and bookkeeping leaves honest uncertainty. A token-fenced
|
|
104
|
+
initial attempt proved not to have invoked insertion, or given a definite insertion refusal, releases
|
|
105
|
+
its export bookkeeping while keeping the source pending. Recovering a prior uncertain attempt never
|
|
106
|
+
erases its original export time merely because the current retry was unsent.
|
|
107
|
+
|
|
108
|
+
`MetadataMatch` has nonempty `fields` with nonempty path segments and exact, type-sensitive scalar
|
|
109
|
+
`equals` values (`null`, boolean, finite number or string). Only own object properties are traversed;
|
|
110
|
+
arrays and missing intermediates do not match. Fields combine with AND.
|
|
111
|
+
|
|
112
|
+
Sandbox participant selection and exact ACK check captured owner, join generation and locally
|
|
113
|
+
known lifecycle in World storage only. They do not need ledger access and do not prove host liveness.
|
|
114
|
+
Ledger-only detach or delete is learned at the next privileged producer reconciliation; actual export
|
|
115
|
+
is gated by the ledger's current state. Local controls cannot grant delivery authority or resurrect a
|
|
116
|
+
deleted session. Known stale, departed or replaced custody refuses.
|
|
117
|
+
|
|
118
|
+
## Storage and lifecycle
|
|
119
|
+
|
|
120
|
+
Format 12 is a breaking fresh-store format. Square owns its activities, audience, participants, read
|
|
121
|
+
state and posting/full-card bookkeeping in the `.square` SQLite artifact. The per-user host delivery
|
|
122
|
+
ledger owns producer-neutral cards, attachment, routes, attempts and receipts; there is no discovery
|
|
123
|
+
index. Older artifacts are refused read-only: no migration, conversion or deletion. Host start/resume
|
|
124
|
+
and end attach/detach the ledger session, not Square seats. Host-confirmed deletion is reconciled to a
|
|
125
|
+
fenced `done` lazily by the next mutating operation, never by history, status or participants.
|
|
126
|
+
|
|
127
|
+
The package exports `DeliveryLedger` and its types from both the root and
|
|
128
|
+
`@astrosheep/square/delivery-ledger`. External producers post finished text and own their content;
|
|
129
|
+
the ledger does not match producer metadata. Proactive delivery suppression uses the ledger's exact
|
|
130
|
+
or prefix `suppress` operation, with an optional expiry; see [delivery-primitives.md](delivery-primitives.md).
|