agents-can-communicate 0.2.0 → 0.3.0

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 (86) hide show
  1. package/README.md +17 -7
  2. package/bin/acc-bootstrap.mjs +56 -0
  3. package/bin/acc-claude-channel.mjs +177 -0
  4. package/bin/acc.mjs +7 -2
  5. package/docs/ADAPTER_AUTHORING.md +34 -2
  6. package/docs/CAPABILITIES.md +25 -10
  7. package/docs/CLI.md +10 -3
  8. package/docs/CONFIGURATION.md +4 -0
  9. package/docs/HOW_IT_WORKS.md +277 -0
  10. package/docs/PROTOCOL.md +1 -1
  11. package/docs/RELEASING.md +7 -1
  12. package/docs/TROUBLESHOOTING.md +7 -1
  13. package/docs/index.md +3 -1
  14. package/node_modules/@agents-can-communicate/adapter-claude-code/certification.json +196 -46
  15. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/certification-provenance.json +237 -45
  16. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.252.json +3 -1
  17. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.258.json +23 -0
  18. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.260.json +23 -0
  19. package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +5 -2
  20. package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/.mcp.json +8 -0
  21. package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/skills/acc/SKILL.md +4 -2
  22. package/node_modules/@agents-can-communicate/adapter-claude-code/src/adapter.mjs +34 -2
  23. package/node_modules/@agents-can-communicate/adapter-claude-code/src/channel.mjs +377 -0
  24. package/node_modules/@agents-can-communicate/adapter-claude-code/src/install.mjs +27 -7
  25. package/node_modules/@agents-can-communicate/adapter-claude-code/src/native-delivery.mjs +229 -0
  26. package/node_modules/@agents-can-communicate/adapter-codex/certification.json +38 -5
  27. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/certification-provenance.json +171 -38
  28. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.0.json +3 -1
  29. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-remote-workspace.json +25 -0
  30. package/node_modules/@agents-can-communicate/adapter-codex/package.json +4 -2
  31. package/node_modules/@agents-can-communicate/adapter-codex/plugin/skills/acc/SKILL.md +4 -2
  32. package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +42 -7
  33. package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +121 -0
  34. package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +151 -0
  35. package/node_modules/@agents-can-communicate/adapter-codex/src/ws-json-rpc.mjs +192 -0
  36. package/node_modules/@agents-can-communicate/adapter-gemini-cli/certification.json +44 -28
  37. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
  38. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/skills/acc/SKILL.md +4 -2
  39. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeAgent.json → BeforeAgent-0.57.0.json} +2 -2
  40. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeTool.json → BeforeTool-0.57.0.json} +2 -2
  41. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeTool-shell.json → BeforeTool-shell-0.57.0.json} +2 -2
  42. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{SessionEnd.json → SessionEnd-0.57.0.json} +2 -2
  43. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{SessionStart.json → SessionStart-0.57.0.json} +2 -2
  44. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/certification-provenance.json +266 -39
  45. package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +6 -6
  46. package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/adapter.mjs +25 -11
  47. package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
  48. package/node_modules/@agents-can-communicate/adapter-grok/plugin/skills/acc/SKILL.md +4 -2
  49. package/node_modules/@agents-can-communicate/adapter-grok/src/adapter.mjs +3 -1
  50. package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
  51. package/node_modules/@agents-can-communicate/adapter-kimi/plugin/skills/acc/SKILL.md +4 -2
  52. package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
  53. package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +18 -0
  54. package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +2 -0
  55. package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +6 -2
  56. package/node_modules/@agents-can-communicate/adapter-sdk/src/native-activation.mjs +76 -0
  57. package/node_modules/@agents-can-communicate/adapter-sdk/src/native-delivery.mjs +202 -0
  58. package/node_modules/@agents-can-communicate/adapter-sdk/src/native-vocabulary.mjs +101 -0
  59. package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +17 -2
  60. package/node_modules/@agents-can-communicate/cli/package.json +1 -1
  61. package/node_modules/@agents-can-communicate/cli/src/args.mjs +2 -2
  62. package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +67 -5
  63. package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +103 -11
  64. package/node_modules/@agents-can-communicate/core/package.json +1 -1
  65. package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +52 -2
  66. package/node_modules/@agents-can-communicate/core/src/service.mjs +10 -0
  67. package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
  68. package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +26 -12
  69. package/node_modules/@agents-can-communicate/hook-runner/package.json +4 -2
  70. package/node_modules/@agents-can-communicate/hook-runner/src/native-binding.mjs +90 -0
  71. package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +123 -90
  72. package/node_modules/@agents-can-communicate/installer/package.json +1 -1
  73. package/node_modules/@agents-can-communicate/installer/src/apply.mjs +48 -4
  74. package/node_modules/@agents-can-communicate/installer/src/bootstrap-runtime.mjs +144 -0
  75. package/node_modules/@agents-can-communicate/installer/src/detect.mjs +72 -3
  76. package/node_modules/@agents-can-communicate/installer/src/index.mjs +7 -0
  77. package/node_modules/@agents-can-communicate/installer/src/native-activation.mjs +161 -0
  78. package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +6 -2
  79. package/node_modules/@agents-can-communicate/installer/src/plan.mjs +41 -6
  80. package/node_modules/@agents-can-communicate/installer/src/shell-bootstrap.mjs +210 -0
  81. package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
  82. package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
  83. package/node_modules/@agents-can-communicate/protocol/src/fields.mjs +17 -0
  84. package/node_modules/@agents-can-communicate/protocol/src/schema.mjs +18 -3
  85. package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
  86. package/package.json +2 -1
@@ -0,0 +1,277 @@
1
+ # How ACC works
2
+
3
+ ACC is a local communication layer around AI sessions that the user opened independently.
4
+ It gives those sessions a shared set of coordination facts without giving ACC ownership of
5
+ their prompts, permissions, processes, or work.
6
+
7
+ This page follows one interaction from client startup to an acknowledged answer. It is the
8
+ engineering tour; [Protocol](PROTOCOL.md) is the normative record contract and
9
+ [Architecture](ARCHITECTURE.md) is the package-level reference.
10
+
11
+ ## The whole system in one picture
12
+
13
+ ```mermaid
14
+ flowchart LR
15
+ U["human direction and authority"] --> A["independent session A"]
16
+ U --> B["independent session B"]
17
+ A --> X["CLI, MCP, or adapter hook"]
18
+ X --> C["vendor-neutral core"]
19
+ C <--> S[("filesystem store outside the repository")]
20
+ C --> Y["B adapter hook or acc inbox"]
21
+ Y --> B
22
+ C --> R["optional live-delivery router"]
23
+ R -.-> B
24
+ B --> Z["CLI, MCP, or adapter hook"]
25
+ Z --> C
26
+ ```
27
+
28
+ There is no required ACC daemon and no coordinator model. CLI commands and native hooks
29
+ are short-lived local processes that open the same workspace store when needed. An MCP
30
+ client may keep its own `acc-mcp` stdio child running, but that child is a tool boundary for
31
+ one participant, not a scheduler or owner of the room.
32
+
33
+ ## 1. A client session joins a workspace
34
+
35
+ For a native client, an installed startup hook sends the client event to `acc-hook`. The
36
+ vendor adapter normalizes that event, then the hook runner:
37
+
38
+ 1. discovers the workspace;
39
+ 2. opens its filesystem store;
40
+ 3. resolves the exact client version and its certified capabilities;
41
+ 4. opens or resumes one ACC session generation; and
42
+ 5. stores a small binding from the client's session id to that ACC generation.
43
+
44
+ Workspace discovery uses an explicit `acc.workspace.json` first, the Git common directory
45
+ second, and the canonical plain directory otherwise. Git worktrees therefore share one
46
+ room but keep separate checkout and branch facts. Git itself is optional.
47
+
48
+ A participant is the address messages target. A session is one current opening of that
49
+ participant, and its unguessable generation token prevents an old process from mutating a
50
+ replacement session. The default participant name is derived from the client session. Set
51
+ `ACC_PARTICIPANT` in the client launch environment when an address must survive a client
52
+ restart and recover messages sent while it was away.
53
+
54
+ Attaching one session does not create durable workspace history. Its presence and intent
55
+ can remain ephemeral until a second live session appears or someone creates the first
56
+ claim, message, or handoff. This is how ACC stays silent when a session is alone without
57
+ making discovery unreliable when a peer arrives.
58
+
59
+ ## 2. Sessions publish awareness, not assignments
60
+
61
+ An intent records a short summary, mode, and resource hints. A claim adds a leased
62
+ reservation for a canonical resource such as `file:src/item.mjs` or `file:src/**`.
63
+ Neither creates a task or grants one session authority over another.
64
+
65
+ A claim is `guarded` only when every live client path involved has a captured pre-write
66
+ guard. Otherwise it is `advisory`: visible coordination that peers should respect, but not
67
+ an operating-system lock. Even a guarded claim cannot stop unrelated programs or a write
68
+ path the client never exposes to its adapter.
69
+
70
+ ## 3. Sending commits the durable truth first
71
+
72
+ When session A sends an addressed question, the CLI or MCP boundary validates the closed
73
+ protocol shape and resolves A's current session generation. Core then performs one
74
+ filesystem transaction that creates:
75
+
76
+ - the immutable logical message, including sender, recipients, kind, obligation, thread,
77
+ and explicit body;
78
+ - one `queued` receipt for each recipient; and
79
+ - a `message.recorded` event.
80
+
81
+ The first message in a thread uses its own `messageId` as `threadId`. A caller-supplied
82
+ `clientMessageId` is a retry key: identical retries return the original message, while the
83
+ same key with different content is rejected.
84
+
85
+ For a room message, recipients are the known peer participants with open sessions at
86
+ commit time. Participants arriving later can find the room record through full forensic
87
+ sync, but they do not receive retroactive receipts.
88
+
89
+ Only after the transaction commits may ACC try to make the message arrive sooner. Thus a
90
+ crashed, unsupported, or unreachable adapter cannot erase a successfully recorded
91
+ question.
92
+
93
+ ## 4. Delivery has three paths
94
+
95
+ The paths share one durable record but prove different facts.
96
+
97
+ ### Durable inbox
98
+
99
+ `acc inbox` is the universal recovery path. It returns only messages addressed to the
100
+ calling participant and atomically advances that participant's receipt to `retrieved`.
101
+ An exact `acc inbox --message message_x` remains usable after context compaction or when a
102
+ message was too large to project safely.
103
+
104
+ ### Certified next-turn projection
105
+
106
+ On an exact client version and platform with passing evidence, a before-turn hook asks core
107
+ for queued messages just before the client's next normal turn. The adapter projects each
108
+ complete body inside an attributed `untrusted peer message` frame. If the complete frame
109
+ does not fit the configured byte budget, the hook keeps the message id and the exact inbox
110
+ recovery command instead of silently truncating peer text.
111
+
112
+ The hook entry point records `offered` only after its stdout transport reports that the
113
+ bytes crossed the boundary. The state is not `retrieved`: ACC still has no observation
114
+ that the model attended to those bytes.
115
+
116
+ ### Native live push
117
+
118
+ The delivery router offers an actionable message to an already-running session when all of
119
+ these hold at once:
120
+
121
+ - exactly one live generation for the recipient;
122
+ - an unexpired generation-bound delivery binding published by that session's own start;
123
+ - a recorded policy permitting this message kind (`actionable` covers question, request,
124
+ answer, decision, and handoff; `all` adds note; room messages are never live);
125
+ - an adapter that declares `delivery.livePush` and a native contract; and
126
+ - adapter acceptance of the bytes.
127
+
128
+ Any missing condition leaves the receipt `queued` and returns a safe fallback reason. Two
129
+ adapters ship a native transport, both experimental and off until a per-client opt-in:
130
+
131
+ ```text
132
+ sender -> durable ACC record -> exact live binding -> vendor transport -> receiver
133
+ \-> queued inbox on every failure
134
+ ```
135
+
136
+ - **Claude Code 2.1.258** uses a vendor Channel: an ACC-owned MCP child, started only when
137
+ the user's ordinary `claude` launch carries the captured development-channel flag, offers
138
+ the message as a native notification and routes the model's explicit `acc_reply` back as a
139
+ real ACC answer. Claude's development-channel warning is vendor-owned and stays visible.
140
+ - **Codex 0.152.1** adds the message to the App Server thread queue over the vendor daemon's
141
+ control socket; it is presented on the idle thread or after the current turn. Codex answers
142
+ through the ordinary `acc reply` command, so its reply route is not native.
143
+
144
+ Compatibility is decided at the launch-time bootstrap and again by a per-session handshake
145
+ bound to the exact client process; there is no maximum client version, but a newer stable
146
+ release must pass a current probe and handshake for the captured protocol, and an older,
147
+ prerelease, known-bad, or uncaptured client stays durable-only. ACC is never the parent of
148
+ a model session after the shell `exec`, and `ACC_BYPASS=1` starts the unmodified client.
149
+
150
+ ## 5. Reply closes the communication obligation
151
+
152
+ The complete question-and-answer path is:
153
+
154
+ ```mermaid
155
+ sequenceDiagram
156
+ participant A as Session A
157
+ participant Core
158
+ participant Store
159
+ participant B as Session B
160
+ A->>Core: addressed question for B
161
+ Core->>Store: message + queued receipt + event
162
+ Store-->>Core: transaction committed
163
+ Core-->>A: recorded with delivery outcome
164
+ alt certified next-turn
165
+ B->>Core: normal turn hook
166
+ Core-->>B: attributed untrusted envelope
167
+ Core->>Store: receipt offered after transport accepts bytes
168
+ else durable inbox
169
+ B->>Core: acc inbox for the message
170
+ Core->>Store: advance B receipt to retrieved
171
+ Core-->>B: attributed message and receipt
172
+ end
173
+ B->>Core: reply to the question id
174
+ Core->>Store: answer + A receipt + acknowledge B receipt
175
+ Core-->>A: answer through next-turn or inbox
176
+ ```
177
+
178
+ `reply` verifies that B owns the original receipt, writes an `answer` in the same thread,
179
+ creates the answer's receipt for A, and advances B's original receipt to `acknowledged` in
180
+ one transaction. A transport failure after that cannot undo the reply. `ack` performs the
181
+ last transition without creating an answer when the obligation only asks for
182
+ acknowledgement.
183
+
184
+ Receipts are per recipient and monotonic:
185
+
186
+ ```text
187
+ queued -> offered -> retrieved -> acknowledged
188
+ ```
189
+
190
+ `recorded` is the successful send boundary, not a receipt state. `offered` does not mean
191
+ read, `retrieved` does not prove model attention, and `acknowledged` resolves communication
192
+ only. A reply saying “I will do it” is not evidence that the requested work finished; ACC
193
+ does not have accepted, running, or done task states.
194
+
195
+ ## 6. The filesystem is the control plane
196
+
197
+ Each workspace lives below the platform data home, conceptually:
198
+
199
+ ```text
200
+ <platform data home>/acc/workspaces/workspace_x/
201
+ ├── protocol.json store version and workspace identity
202
+ ├── state/<kind>/<id>.json materialised current records
203
+ ├── events/<sequence>.json immutable semantic history
204
+ ├── journal/ crash-recovery authority
205
+ ├── locks/ one cross-process writer mutex
206
+ ├── ephemeral/ non-durable presence, intent, and delivery bindings
207
+ ├── bindings/ client-session to ACC-generation mappings
208
+ ├── retained/ logical deletion and retired evidence
209
+ └── tmp/ staged atomic publications
210
+ ```
211
+
212
+ This layout is diagnostic, not a public mutation API. Clients write through the protocol
213
+ and core rather than editing these files.
214
+
215
+ On macOS the platform data home is `~/Library/Application Support`; on Linux it is
216
+ `$XDG_DATA_HOME` or `~/.local/share`. `ACC_DATA_HOME` replaces that base. Runtime paths are
217
+ checked against workspace roots so ACC state cannot be placed inside the project.
218
+
219
+ Every durable mutation holds the same writer mutex, loads only its declared record kinds,
220
+ checks state generations, stages the full result, and writes a recovery journal before
221
+ publishing. Events are immutable no-replace files; current state is a materialised view
222
+ replaced atomically. While publication is incomplete, the active journal bounds event
223
+ cursors below the transaction's first sequence; the next store opener rolls a decided
224
+ transaction forward before serving a read. The store prefers a recoverable duplicate offer
225
+ after a crash to an unearned delivery claim.
226
+
227
+ Paths are opened with containment and no-follow checks. Corrupt records, a foreign
228
+ workspace identity, and unknown store versions fail before mutation rather than being
229
+ guessed into a compatible shape.
230
+
231
+ ## 7. Adapters translate evidence, not product semantics
232
+
233
+ The vendor-neutral layers know nothing about Codex, Claude Code, Gemini CLI, Grok, or Kimi
234
+ Code. `protocol` owns record shapes and state transitions; `core` owns coordination rules;
235
+ `storage-filesystem` owns persistence. Vendor adapters own hook payloads, installation,
236
+ client-specific response shapes, and captured capability evidence. `hook-runner` applies
237
+ the common bounded fail-open lifecycle, while `delivery-router` evaluates optional live
238
+ delivery.
239
+
240
+ Unknown client versions and platforms inherit no capability. A method in an adapter or a
241
+ vendor documentation example is not enough: every `true` capability needs a retained
242
+ real-client fixture. This is why the same product can degrade visibly from next-turn
243
+ projection to inbox polling without changing its message or receipt semantics.
244
+
245
+ ## 8. What crosses the trust boundary
246
+
247
+ ACC stores only explicit coordination data: identity, presence, one-line intent, claims,
248
+ messages the sender chose to send, structured handoffs, receipts, artifacts, and events.
249
+ It does not collect raw prompts, assistant responses, transcripts, environment variables,
250
+ credentials, or permission approvals.
251
+
252
+ Peer bodies remain untrusted data. The projector attributes the sender, escapes framing
253
+ and terminal control sequences, and never promotes peer text to system authority. The
254
+ receiving session still evaluates it under its own instructions and permissions.
255
+
256
+ Every native hook has a five-second ceiling and fails open: if ACC cannot read the store or
257
+ decide safely, the client's action continues. Coordination may become less effective, but
258
+ ACC itself must not stop a session from working.
259
+
260
+ ## Trace the implementation
261
+
262
+ The shortest source-code path is:
263
+
264
+ 1. `packages/hook-runner/src/runner.mjs` — attach, before-turn projection, guards, and the
265
+ fail-open boundary;
266
+ 2. `packages/core/src/conversations.mjs` — record-first messages, threads, receipts, and
267
+ handoffs;
268
+ 3. `packages/core/src/inbox.mjs` — recipient-owned retrieval, reply, and acknowledgement;
269
+ 4. `packages/delivery-router/src/router.mjs` — policy, reachability, certification, and live
270
+ fallback;
271
+ 5. `packages/storage-filesystem/src/store.mjs` — transactions, snapshots, ephemeral state,
272
+ and recovery; and
273
+ 6. `packages/adapter-sdk/src/context-projector.mjs` — bounded untrusted peer framing.
274
+
275
+ Continue with [Capabilities](CAPABILITIES.md) for what each shipped client actually proves,
276
+ [Security model](SECURITY_MODEL.md) for trust boundaries and attack tests, and
277
+ [Adapter authoring](ADAPTER_AUTHORING.md) for the integration contract.
package/docs/PROTOCOL.md CHANGED
@@ -182,7 +182,7 @@ livePolicy · opaqueEndpointRef · leaseUntil
182
182
  The recipient owns `livePolicy` because native push may start a model turn:
183
183
 
184
184
  - `off`: inbox and normal next-turn paths only;
185
- - `actionable`: questions, requests, and addressed handoffs may use live push;
185
+ - `actionable`: questions, requests, answers, decisions, and addressed handoffs may use live push;
186
186
  - `all`: every addressed kind may use live push.
187
187
 
188
188
  Default is `off`. Policy never creates a capability. The router still requires a current
package/docs/RELEASING.md CHANGED
@@ -47,7 +47,7 @@ else installs it.
47
47
  ## Record the evidence
48
48
 
49
49
  Put the tarball name, sha256, **the commit it was built from**, exact platform/client
50
- facts, fallback result, and known limitations in `docs/release-evidence/v0.2.0.md` and
50
+ facts, fallback result, and known limitations in `docs/release-evidence/v0.3.0.md` and
51
51
  the current `CHANGELOG.md` release table. A release without them is a release nobody can
52
52
  audit later. Test count is deliberately left out: nothing verifies it, so it only
53
53
  decorates or, when it drifts, misleads.
@@ -81,6 +81,12 @@ absent and Claude stopped at the development-channel warning. Record those exact
81
81
  captures and run the packed inbox/next-turn fallback instead of promoting an unobserved
82
82
  native path. Windows is an explicit unsupported-platform skip, not a passing capture.
83
83
 
84
+ By v0.3.0 that had gone both ways, which is the point of doing it per release rather than
85
+ once. Claude Code passed and ships a live Channel; Codex's queue capture passed and the
86
+ capability was **withdrawn anyway**, because the mode it needs hides which workspace the
87
+ session belongs to, and a session that cannot be placed must not be addressed. A capture
88
+ that works is not the same claim as a capability that is safe to ship.
89
+
84
90
  A published version's record is history and is not rewritten; later changes
85
91
  get a new `## Unreleased` entry at the top, checked the same way against the
86
92
  current tree.
@@ -53,9 +53,15 @@ do not run. `acc doctor` reports the installed cache copy and missing activation
53
53
  ## Gemini does not guard a write
54
54
 
55
55
  Default and `plan` modes expose no write tool to the model. `auto_edit` exposes edit tools;
56
- shell availability depends on approval mode. Only Gemini CLI 0.37.0 on `darwin-arm64` has
56
+ shell availability depends on approval mode. Only Gemini CLI 0.57.0 on `darwin-arm64` has
57
57
  package-shipped delivery certification; other versions still use inbox.
58
58
 
59
+ From 0.55 onwards there is a quieter cause with the same symptom: an untrusted folder. The
60
+ client prints `Approval mode overridden to "default" because the current folder is not
61
+ trusted` and keeps going, and the default mode has no write or shell tool to guard - so the
62
+ guard never fires and the mode you passed appears to have been ignored. Trust the folder,
63
+ or start the session somewhere trusted.
64
+
59
65
  ## Grok shows no injected message
60
66
 
61
67
  Grok 1.0.13 discarded UserPromptSubmit context in the real capture. Its next-turn and guard
package/docs/index.md CHANGED
@@ -8,7 +8,9 @@ separates protocol truth from adapter reach.
8
8
 
9
9
  1. [Why ACC](WHY_ACC.md) — the product boundary and when a managed runtime fits better.
10
10
  2. [Concepts](CONCEPTS.md) — peers, durable threads, receipts, intent, and claims.
11
- 3. [Capabilities](CAPABILITIES.md) — certified support, current reachability, recipient
11
+ 3. [How ACC works](HOW_IT_WORKS.md) — the end-to-end path from client hook and workspace
12
+ identity through durable storage, delivery fallback, reply, and acknowledgement.
13
+ 4. [Capabilities](CAPABILITIES.md) — certified support, current reachability, recipient
12
14
  policy, fallback, and limitations beside each adapter.
13
15
 
14
16
  ## Use it
@@ -1,59 +1,119 @@
1
1
  {
2
2
  "evidence": [
3
3
  {
4
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
5
- "observedAt": "2026-08-16", "capability": "lifecycle.sessionStart",
6
- "fixture": "fixtures/SessionStart.json", "idleBehavior": "fires when a session starts",
7
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "session-start",
8
- "busyBehavior": "fires before the first model turn", "authorityLevel": "advisory",
9
- "limitations": ["capture used a one-session --plugin-dir"], "result": "pass"
4
+ "client": "claude-code",
5
+ "version": "2.1.233",
6
+ "platform": "darwin-arm64",
7
+ "observedAt": "2026-08-16",
8
+ "capability": "lifecycle.sessionStart",
9
+ "fixture": "fixtures/SessionStart.json",
10
+ "idleBehavior": "fires when a session starts",
11
+ "provenance": "fixtures/certification-provenance.json",
12
+ "provenanceId": "session-start",
13
+ "busyBehavior": "fires before the first model turn",
14
+ "authorityLevel": "advisory",
15
+ "limitations": [
16
+ "capture used a one-session --plugin-dir"
17
+ ],
18
+ "result": "pass"
10
19
  },
11
20
  {
12
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
13
- "observedAt": "2026-08-16", "capability": "lifecycle.sessionEnd",
14
- "fixture": "fixtures/SessionEnd.json", "idleBehavior": "fires when a session exits",
15
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "session-end",
16
- "busyBehavior": "does not run until the session exits", "authorityLevel": "advisory",
17
- "limitations": ["cannot write a handoff after the model has stopped"], "result": "pass"
21
+ "client": "claude-code",
22
+ "version": "2.1.233",
23
+ "platform": "darwin-arm64",
24
+ "observedAt": "2026-08-16",
25
+ "capability": "lifecycle.sessionEnd",
26
+ "fixture": "fixtures/SessionEnd.json",
27
+ "idleBehavior": "fires when a session exits",
28
+ "provenance": "fixtures/certification-provenance.json",
29
+ "provenanceId": "session-end",
30
+ "busyBehavior": "does not run until the session exits",
31
+ "authorityLevel": "advisory",
32
+ "limitations": [
33
+ "cannot write a handoff after the model has stopped"
34
+ ],
35
+ "result": "pass"
18
36
  },
19
37
  {
20
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
21
- "observedAt": "2026-08-16", "capability": "context.beforeTurnInjection",
22
- "fixture": "fixtures/UserPromptSubmit.json", "idleBehavior": "waits for the next user prompt",
23
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "user-prompt-submit",
24
- "busyBehavior": "does not interrupt an in-progress turn", "authorityLevel": "context",
25
- "limitations": ["requires the hookSpecificOutput additionalContext envelope"], "result": "pass"
38
+ "client": "claude-code",
39
+ "version": "2.1.233",
40
+ "platform": "darwin-arm64",
41
+ "observedAt": "2026-08-16",
42
+ "capability": "context.beforeTurnInjection",
43
+ "fixture": "fixtures/UserPromptSubmit.json",
44
+ "idleBehavior": "waits for the next user prompt",
45
+ "provenance": "fixtures/certification-provenance.json",
46
+ "provenanceId": "user-prompt-submit",
47
+ "busyBehavior": "does not interrupt an in-progress turn",
48
+ "authorityLevel": "context",
49
+ "limitations": [
50
+ "requires the hookSpecificOutput additionalContext envelope"
51
+ ],
52
+ "result": "pass"
26
53
  },
27
54
  {
28
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
29
- "observedAt": "2026-08-16", "capability": "guards.beforeWrite",
30
- "fixture": "fixtures/PreToolUse-Edit.json", "idleBehavior": "no write exists to guard",
31
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "pre-tool-use-edit",
32
- "busyBehavior": "denies a file edit before disk mutation", "authorityLevel": "blocking",
33
- "limitations": ["runtime writes are outside the hook boundary"], "result": "pass"
55
+ "client": "claude-code",
56
+ "version": "2.1.233",
57
+ "platform": "darwin-arm64",
58
+ "observedAt": "2026-08-16",
59
+ "capability": "guards.beforeWrite",
60
+ "fixture": "fixtures/PreToolUse-Edit.json",
61
+ "idleBehavior": "no write exists to guard",
62
+ "provenance": "fixtures/certification-provenance.json",
63
+ "provenanceId": "pre-tool-use-edit",
64
+ "busyBehavior": "denies a file edit before disk mutation",
65
+ "authorityLevel": "blocking",
66
+ "limitations": [
67
+ "runtime writes are outside the hook boundary"
68
+ ],
69
+ "result": "pass"
34
70
  },
35
71
  {
36
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
37
- "observedAt": "2026-08-16", "capability": "guards.beforeShell",
38
- "fixture": "fixtures/PreToolUse.json", "idleBehavior": "no shell call exists to guard",
39
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "pre-tool-use-bash",
40
- "busyBehavior": "denies a Bash call before execution", "authorityLevel": "blocking",
41
- "limitations": ["only tool calls reaching PreToolUse are guarded"], "result": "pass"
72
+ "client": "claude-code",
73
+ "version": "2.1.233",
74
+ "platform": "darwin-arm64",
75
+ "observedAt": "2026-08-16",
76
+ "capability": "guards.beforeShell",
77
+ "fixture": "fixtures/PreToolUse.json",
78
+ "idleBehavior": "no shell call exists to guard",
79
+ "provenance": "fixtures/certification-provenance.json",
80
+ "provenanceId": "pre-tool-use-bash",
81
+ "busyBehavior": "denies a Bash call before execution",
82
+ "authorityLevel": "blocking",
83
+ "limitations": [
84
+ "only tool calls reaching PreToolUse are guarded"
85
+ ],
86
+ "result": "pass"
42
87
  },
43
88
  {
44
- "client": "claude-code", "version": "2.1.233", "platform": "darwin-arm64",
45
- "observedAt": "2026-08-16", "capability": "delivery.nextTurn",
46
- "fixture": "fixtures/UserPromptSubmit.json", "idleBehavior": "offers complete peer messages at the next prompt",
47
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "user-prompt-submit",
48
- "busyBehavior": "does not interrupt an in-progress turn", "authorityLevel": "context",
49
- "limitations": ["delivery requires the next normal user turn"], "result": "pass"
89
+ "client": "claude-code",
90
+ "version": "2.1.233",
91
+ "platform": "darwin-arm64",
92
+ "observedAt": "2026-08-16",
93
+ "capability": "delivery.nextTurn",
94
+ "fixture": "fixtures/UserPromptSubmit.json",
95
+ "idleBehavior": "offers complete peer messages at the next prompt",
96
+ "provenance": "fixtures/certification-provenance.json",
97
+ "provenanceId": "user-prompt-submit",
98
+ "busyBehavior": "does not interrupt an in-progress turn",
99
+ "authorityLevel": "context",
100
+ "limitations": [
101
+ "delivery requires the next normal user turn"
102
+ ],
103
+ "result": "pass"
50
104
  },
51
105
  {
52
- "client": "claude-code", "version": "2.1.252", "platform": "darwin-arm64",
53
- "observedAt": "2026-09-01T16:17:06Z", "capability": "delivery.livePush",
54
- "fixture": "fixtures/delivery/claude-code-2.1.252.json", "idleBehavior": "unobserved",
55
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "native-delivery-2-1-252",
56
- "busyBehavior": "unobserved", "authorityLevel": "none",
106
+ "client": "claude-code",
107
+ "version": "2.1.252",
108
+ "platform": "darwin-arm64",
109
+ "observedAt": "2026-09-01T16:17:06Z",
110
+ "capability": "delivery.livePush",
111
+ "fixture": "fixtures/delivery/claude-code-2.1.252.json",
112
+ "idleBehavior": "unobserved",
113
+ "provenance": "fixtures/certification-provenance.json",
114
+ "provenanceId": "native-delivery-2-1-252",
115
+ "busyBehavior": "unobserved",
116
+ "authorityLevel": "none",
57
117
  "limitations": [
58
118
  "Claude Code displayed the development-channel security warning and the operator did not accept it",
59
119
  "Claude Code did not spawn the acc-spike MCP child and the Unix-domain socket was never created",
@@ -62,17 +122,107 @@
62
122
  "result": "fail"
63
123
  },
64
124
  {
65
- "client": "claude-code", "version": "2.1.252", "platform": "darwin-arm64",
66
- "observedAt": "2026-09-01T16:17:06Z", "capability": "delivery.replyRoute",
67
- "fixture": "fixtures/delivery/claude-code-2.1.252.json", "idleBehavior": "unobserved",
68
- "provenance": "fixtures/certification-provenance.json", "provenanceId": "native-delivery-2-1-252",
69
- "busyBehavior": "unobserved", "authorityLevel": "none",
125
+ "client": "claude-code",
126
+ "version": "2.1.252",
127
+ "platform": "darwin-arm64",
128
+ "observedAt": "2026-09-01T16:17:06Z",
129
+ "capability": "delivery.replyRoute",
130
+ "fixture": "fixtures/delivery/claude-code-2.1.252.json",
131
+ "idleBehavior": "unobserved",
132
+ "provenance": "fixtures/certification-provenance.json",
133
+ "provenanceId": "native-delivery-2-1-252",
134
+ "busyBehavior": "unobserved",
135
+ "authorityLevel": "none",
70
136
  "limitations": [
71
137
  "Claude Code displayed the development-channel security warning and the operator did not accept it",
72
138
  "Claude Code did not spawn the acc-spike MCP child and the Unix-domain socket was never created",
73
139
  "idle, busy, reply, duplicate, and fallback branches were not observed"
74
140
  ],
75
141
  "result": "fail"
142
+ },
143
+ {
144
+ "client": "claude-code",
145
+ "version": "2.1.258",
146
+ "platform": "darwin-arm64",
147
+ "observedAt": "2026-09-02T21:20:11.676Z",
148
+ "capability": "delivery.livePush",
149
+ "fixture": "fixtures/delivery/claude-code-2.1.258.json",
150
+ "idleBehavior": "offered",
151
+ "provenance": "fixtures/certification-provenance.json",
152
+ "provenanceId": "native-delivery-2-1-258",
153
+ "busyBehavior": "queued_after_turn",
154
+ "authorityLevel": "experimental",
155
+ "limitations": [
156
+ "captured on darwin-arm64 only; Linux and Windows remain uncaptured",
157
+ "the vendor development-channel warning stayed visible and was accepted by the operator by hand",
158
+ "the plugin .mcp.json must live in the marketplace source copy; the plugin cache copy alone is not read",
159
+ "acc_reply routed through the spike's explicit tool call; the spike created no durable ACC answer record",
160
+ "presentation after the busy turn was observed by the operator; the channel log records the write at 21:18:45Z and the explicit reply at 21:19:21Z"
161
+ ],
162
+ "result": "pass"
163
+ },
164
+ {
165
+ "client": "claude-code",
166
+ "version": "2.1.258",
167
+ "platform": "darwin-arm64",
168
+ "observedAt": "2026-09-02T21:20:11.676Z",
169
+ "capability": "delivery.replyRoute",
170
+ "fixture": "fixtures/delivery/claude-code-2.1.258.json",
171
+ "idleBehavior": "offered",
172
+ "provenance": "fixtures/certification-provenance.json",
173
+ "provenanceId": "native-delivery-2-1-258",
174
+ "busyBehavior": "queued_after_turn",
175
+ "authorityLevel": "experimental",
176
+ "limitations": [
177
+ "captured on darwin-arm64 only; Linux and Windows remain uncaptured",
178
+ "the vendor development-channel warning stayed visible and was accepted by the operator by hand",
179
+ "the plugin .mcp.json must live in the marketplace source copy; the plugin cache copy alone is not read",
180
+ "acc_reply routed through the spike's explicit tool call; the spike created no durable ACC answer record",
181
+ "presentation after the busy turn was observed by the operator; the channel log records the write at 21:18:45Z and the explicit reply at 21:19:21Z"
182
+ ],
183
+ "result": "pass"
184
+ },
185
+ {
186
+ "client": "claude-code",
187
+ "version": "2.1.260",
188
+ "platform": "darwin-arm64",
189
+ "observedAt": "2026-09-04T03:41:29.688Z",
190
+ "capability": "delivery.livePush",
191
+ "fixture": "fixtures/delivery/claude-code-2.1.260.json",
192
+ "idleBehavior": "offered",
193
+ "provenance": "fixtures/certification-provenance.json",
194
+ "provenanceId": "native-delivery-2-1-260",
195
+ "busyBehavior": "queued_after_turn",
196
+ "authorityLevel": "experimental",
197
+ "limitations": [
198
+ "captured on darwin-arm64 only; Linux and Windows remain uncaptured",
199
+ "the vendor development-channel warning stayed visible and was accepted by the operator by hand",
200
+ "two ordinary sessions in one workspace, each bound to its own client process; the earlier 2.1.259 attempt is what exposed the channel binding another session identity, and this run is the verification of that fix",
201
+ "duplicate was observed as one logical message id and one native offer: the repeated send took the durable path, so the channel was never asked to notify twice, and exactly one answer was recorded",
202
+ "busy was observed by the operator: the running turn completed before the channel presented the message, and the session named that order in its own answer"
203
+ ],
204
+ "result": "pass"
205
+ },
206
+ {
207
+ "client": "claude-code",
208
+ "version": "2.1.260",
209
+ "platform": "darwin-arm64",
210
+ "observedAt": "2026-09-04T03:41:29.688Z",
211
+ "capability": "delivery.replyRoute",
212
+ "fixture": "fixtures/delivery/claude-code-2.1.260.json",
213
+ "idleBehavior": "offered",
214
+ "provenance": "fixtures/certification-provenance.json",
215
+ "provenanceId": "native-delivery-2-1-260",
216
+ "busyBehavior": "queued_after_turn",
217
+ "authorityLevel": "experimental",
218
+ "limitations": [
219
+ "captured on darwin-arm64 only; Linux and Windows remain uncaptured",
220
+ "the vendor development-channel warning stayed visible and was accepted by the operator by hand",
221
+ "two ordinary sessions in one workspace, each bound to its own client process; the earlier 2.1.259 attempt is what exposed the channel binding another session identity, and this run is the verification of that fix",
222
+ "duplicate was observed as one logical message id and one native offer: the repeated send took the durable path, so the channel was never asked to notify twice, and exactly one answer was recorded",
223
+ "busy was observed by the operator: the running turn completed before the channel presented the message, and the session named that order in its own answer"
224
+ ],
225
+ "result": "pass"
76
226
  }
77
227
  ]
78
228
  }