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.
- package/README.md +17 -7
- package/bin/acc-bootstrap.mjs +56 -0
- package/bin/acc-claude-channel.mjs +177 -0
- package/bin/acc.mjs +7 -2
- package/docs/ADAPTER_AUTHORING.md +34 -2
- package/docs/CAPABILITIES.md +25 -10
- package/docs/CLI.md +10 -3
- package/docs/CONFIGURATION.md +4 -0
- package/docs/HOW_IT_WORKS.md +277 -0
- package/docs/PROTOCOL.md +1 -1
- package/docs/RELEASING.md +7 -1
- package/docs/TROUBLESHOOTING.md +7 -1
- package/docs/index.md +3 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/certification.json +196 -46
- package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/certification-provenance.json +237 -45
- package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.252.json +3 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.258.json +23 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.260.json +23 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +5 -2
- package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/.mcp.json +8 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/skills/acc/SKILL.md +4 -2
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/adapter.mjs +34 -2
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/channel.mjs +377 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/install.mjs +27 -7
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/native-delivery.mjs +229 -0
- package/node_modules/@agents-can-communicate/adapter-codex/certification.json +38 -5
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/certification-provenance.json +171 -38
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.0.json +3 -1
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-remote-workspace.json +25 -0
- package/node_modules/@agents-can-communicate/adapter-codex/package.json +4 -2
- package/node_modules/@agents-can-communicate/adapter-codex/plugin/skills/acc/SKILL.md +4 -2
- package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +42 -7
- package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +121 -0
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +151 -0
- package/node_modules/@agents-can-communicate/adapter-codex/src/ws-json-rpc.mjs +192 -0
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/certification.json +44 -28
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/skills/acc/SKILL.md +4 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeAgent.json → BeforeAgent-0.57.0.json} +2 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeTool.json → BeforeTool-0.57.0.json} +2 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{BeforeTool-shell.json → BeforeTool-shell-0.57.0.json} +2 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{SessionEnd.json → SessionEnd-0.57.0.json} +2 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/{SessionStart.json → SessionStart-0.57.0.json} +2 -2
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/certification-provenance.json +266 -39
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +6 -6
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/adapter.mjs +25 -11
- package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-grok/plugin/skills/acc/SKILL.md +4 -2
- package/node_modules/@agents-can-communicate/adapter-grok/src/adapter.mjs +3 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/plugin/skills/acc/SKILL.md +4 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +18 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +2 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +6 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-activation.mjs +76 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-delivery.mjs +202 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-vocabulary.mjs +101 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +17 -2
- package/node_modules/@agents-can-communicate/cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/cli/src/args.mjs +2 -2
- package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +67 -5
- package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +103 -11
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +52 -2
- package/node_modules/@agents-can-communicate/core/src/service.mjs +10 -0
- package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
- package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +26 -12
- package/node_modules/@agents-can-communicate/hook-runner/package.json +4 -2
- package/node_modules/@agents-can-communicate/hook-runner/src/native-binding.mjs +90 -0
- package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +123 -90
- package/node_modules/@agents-can-communicate/installer/package.json +1 -1
- package/node_modules/@agents-can-communicate/installer/src/apply.mjs +48 -4
- package/node_modules/@agents-can-communicate/installer/src/bootstrap-runtime.mjs +144 -0
- package/node_modules/@agents-can-communicate/installer/src/detect.mjs +72 -3
- package/node_modules/@agents-can-communicate/installer/src/index.mjs +7 -0
- package/node_modules/@agents-can-communicate/installer/src/native-activation.mjs +161 -0
- package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +6 -2
- package/node_modules/@agents-can-communicate/installer/src/plan.mjs +41 -6
- package/node_modules/@agents-can-communicate/installer/src/shell-bootstrap.mjs +210 -0
- package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
- package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
- package/node_modules/@agents-can-communicate/protocol/src/fields.mjs +17 -0
- package/node_modules/@agents-can-communicate/protocol/src/schema.mjs +18 -3
- package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
- 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.
|
|
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.
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -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.
|
|
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. [
|
|
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",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
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",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
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",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
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",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
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",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
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",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
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",
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
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",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
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
|
}
|