agents-can-communicate 0.3.0 → 0.4.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 (157) hide show
  1. package/README.md +112 -91
  2. package/SECURITY.md +8 -5
  3. package/bin/acc-bootstrap.mjs +5 -54
  4. package/bin/acc-claude-channel.mjs +8 -175
  5. package/bin/acc-hook.mjs +4 -133
  6. package/bin/acc-mcp.mjs +4 -59
  7. package/bin/acc-update-worker.mjs +8 -0
  8. package/bin/acc.mjs +5 -39
  9. package/bin/entrypoints/acc-bootstrap.mjs +47 -0
  10. package/bin/entrypoints/acc-claude-channel.mjs +149 -0
  11. package/bin/entrypoints/acc-hook.mjs +58 -0
  12. package/bin/entrypoints/acc-mcp.mjs +70 -0
  13. package/bin/entrypoints/acc.mjs +51 -0
  14. package/bin/entrypoints/claude-channel-stdio.mjs +29 -0
  15. package/bin/entrypoints/hook-output.mjs +73 -0
  16. package/docs/ADAPTER_AUTHORING.md +62 -24
  17. package/docs/ARCHITECTURE.md +79 -20
  18. package/docs/CAPABILITIES.md +52 -30
  19. package/docs/CLI.md +164 -35
  20. package/docs/CONCEPTS.md +97 -93
  21. package/docs/CONFIGURATION.md +66 -45
  22. package/docs/DESIGN_DECISIONS.md +24 -15
  23. package/docs/GETTING_STARTED.md +124 -118
  24. package/docs/GLOSSARY.md +12 -6
  25. package/docs/HOW_IT_WORKS.md +136 -229
  26. package/docs/MCP.md +98 -31
  27. package/docs/PROTOCOL.md +76 -14
  28. package/docs/RELEASING.md +128 -86
  29. package/docs/SECURITY_MODEL.md +52 -15
  30. package/docs/TROUBLESHOOTING.md +88 -18
  31. package/docs/UPGRADING.md +119 -0
  32. package/docs/WHY_ACC.md +19 -16
  33. package/docs/index.md +40 -24
  34. package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +1 -1
  35. package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/skills/acc/SKILL.md +112 -9
  36. package/node_modules/@agents-can-communicate/adapter-claude-code/src/install.mjs +6 -6
  37. package/node_modules/@agents-can-communicate/adapter-claude-code/src/native-delivery.mjs +2 -1
  38. package/node_modules/@agents-can-communicate/adapter-codex/certification.json +38 -13
  39. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/certification-provenance.json +220 -0
  40. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-current-binding-product-evidence.json +1549 -0
  41. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-current-binding-product.json +27 -0
  42. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-product-evidence.json +1549 -0
  43. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-product.json +27 -0
  44. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-transport-evidence.json +259 -0
  45. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-transport.json +21 -0
  46. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-current-binding-product-evidence.json +1549 -0
  47. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-current-binding-product.json +27 -0
  48. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-product-evidence.json +1549 -0
  49. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-product.json +27 -0
  50. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-transport-evidence.json +259 -0
  51. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-transport.json +21 -0
  52. package/node_modules/@agents-can-communicate/adapter-codex/package.json +14 -2
  53. package/node_modules/@agents-can-communicate/adapter-codex/plugin/skills/acc/SKILL.md +111 -8
  54. package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +26 -44
  55. package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +70 -17
  56. package/node_modules/@agents-can-communicate/adapter-codex/src/config-block.mjs +231 -0
  57. package/node_modules/@agents-can-communicate/adapter-codex/src/hooks.mjs +1 -1
  58. package/node_modules/@agents-can-communicate/adapter-codex/src/install.mjs +71 -63
  59. package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +107 -103
  60. package/node_modules/@agents-can-communicate/adapter-codex/src/native-endpoint.mjs +96 -0
  61. package/node_modules/@agents-can-communicate/adapter-codex/src/ws-json-rpc.mjs +3 -2
  62. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
  63. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/skills/acc/SKILL.md +111 -8
  64. package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +1 -1
  65. package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/install.mjs +2 -2
  66. package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
  67. package/node_modules/@agents-can-communicate/adapter-grok/plugin/skills/acc/SKILL.md +111 -8
  68. package/node_modules/@agents-can-communicate/adapter-grok/src/install.mjs +2 -2
  69. package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
  70. package/node_modules/@agents-can-communicate/adapter-kimi/plugin/skills/acc/SKILL.md +111 -8
  71. package/node_modules/@agents-can-communicate/adapter-kimi/src/hooks.mjs +1 -1
  72. package/node_modules/@agents-can-communicate/adapter-kimi/src/install.mjs +2 -2
  73. package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
  74. package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +5 -0
  75. package/node_modules/@agents-can-communicate/adapter-sdk/src/context-projector.mjs +26 -4
  76. package/node_modules/@agents-can-communicate/adapter-sdk/src/decision-text.mjs +19 -0
  77. package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +5 -3
  78. package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +1 -0
  79. package/node_modules/@agents-can-communicate/adapter-sdk/src/native-delivery.mjs +9 -2
  80. package/node_modules/@agents-can-communicate/adapter-sdk/src/native-vocabulary.mjs +2 -6
  81. package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +29 -9
  82. package/node_modules/@agents-can-communicate/adapter-sdk/src/toml-block.mjs +8 -6
  83. package/node_modules/@agents-can-communicate/cli/package.json +4 -2
  84. package/node_modules/@agents-can-communicate/cli/src/args.mjs +49 -22
  85. package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +11 -4
  86. package/node_modules/@agents-can-communicate/cli/src/git-probe.mjs +9 -3
  87. package/node_modules/@agents-can-communicate/cli/src/help.mjs +109 -14
  88. package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +66 -18
  89. package/node_modules/@agents-can-communicate/cli/src/main.mjs +35 -12
  90. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/activation.mjs +110 -0
  91. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/command.mjs +63 -0
  92. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/download.mjs +71 -0
  93. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/entry.mjs +110 -0
  94. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation.mjs +167 -0
  95. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/install.mjs +73 -0
  96. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +60 -0
  97. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/leases.mjs +60 -0
  98. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/location.mjs +55 -0
  99. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/mutex.mjs +145 -0
  100. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/policy.mjs +4 -0
  101. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/refresh.mjs +40 -0
  102. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/schedule.mjs +21 -0
  103. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/state.mjs +122 -0
  104. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/worker.mjs +65 -0
  105. package/node_modules/@agents-can-communicate/cli/src/session-owner.mjs +33 -108
  106. package/node_modules/@agents-can-communicate/cli/src/update-command.mjs +25 -7
  107. package/node_modules/@agents-can-communicate/core/package.json +1 -1
  108. package/node_modules/@agents-can-communicate/core/src/attention.mjs +3 -0
  109. package/node_modules/@agents-can-communicate/core/src/claims.mjs +13 -8
  110. package/node_modules/@agents-can-communicate/core/src/conversations.mjs +48 -24
  111. package/node_modules/@agents-can-communicate/core/src/decision-changes.mjs +36 -0
  112. package/node_modules/@agents-can-communicate/core/src/decision-state.mjs +42 -0
  113. package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +11 -4
  114. package/node_modules/@agents-can-communicate/core/src/inbox.mjs +48 -17
  115. package/node_modules/@agents-can-communicate/core/src/intents.mjs +35 -15
  116. package/node_modules/@agents-can-communicate/core/src/materialisation.mjs +7 -5
  117. package/node_modules/@agents-can-communicate/core/src/message-pages.mjs +75 -0
  118. package/node_modules/@agents-can-communicate/core/src/next-turn-delivery.mjs +31 -0
  119. package/node_modules/@agents-can-communicate/core/src/session-opening.mjs +128 -0
  120. package/node_modules/@agents-can-communicate/core/src/sessions.mjs +58 -132
  121. package/node_modules/@agents-can-communicate/core/src/sync.mjs +31 -2
  122. package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
  123. package/node_modules/@agents-can-communicate/delivery-router/src/refresh-binding.mjs +38 -0
  124. package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +86 -10
  125. package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
  126. package/node_modules/@agents-can-communicate/hook-runner/src/client-version.mjs +1 -0
  127. package/node_modules/@agents-can-communicate/hook-runner/src/native-binding.mjs +6 -4
  128. package/node_modules/@agents-can-communicate/hook-runner/src/native-retirement.mjs +48 -0
  129. package/node_modules/@agents-can-communicate/hook-runner/src/process-table.mjs +1 -1
  130. package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +175 -67
  131. package/node_modules/@agents-can-communicate/hook-runner/src/session-lifecycle.mjs +13 -0
  132. package/node_modules/@agents-can-communicate/installer/package.json +4 -2
  133. package/node_modules/@agents-can-communicate/installer/src/apply.mjs +17 -2
  134. package/node_modules/@agents-can-communicate/installer/src/bootstrap-runtime.mjs +11 -5
  135. package/node_modules/@agents-can-communicate/installer/src/detect.mjs +1 -1
  136. package/node_modules/@agents-can-communicate/installer/src/index.mjs +1 -0
  137. package/node_modules/@agents-can-communicate/installer/src/live-policy.mjs +21 -0
  138. package/node_modules/@agents-can-communicate/installer/src/native-activation.mjs +20 -6
  139. package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +10 -4
  140. package/node_modules/@agents-can-communicate/installer/src/plan.mjs +3 -3
  141. package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
  142. package/node_modules/@agents-can-communicate/mcp-server/src/protocol.mjs +85 -0
  143. package/node_modules/@agents-can-communicate/mcp-server/src/resources.mjs +3 -2
  144. package/node_modules/@agents-can-communicate/mcp-server/src/server.mjs +59 -57
  145. package/node_modules/@agents-can-communicate/mcp-server/src/tools.mjs +47 -33
  146. package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
  147. package/node_modules/@agents-can-communicate/protocol/src/conversations.mjs +3 -0
  148. package/node_modules/@agents-can-communicate/protocol/src/decision-changes.mjs +15 -0
  149. package/node_modules/@agents-can-communicate/protocol/src/index.mjs +3 -1
  150. package/node_modules/@agents-can-communicate/protocol/src/schema.mjs +14 -5
  151. package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
  152. package/node_modules/@agents-can-communicate/storage-filesystem/src/atomic-json.mjs +5 -1
  153. package/node_modules/@agents-can-communicate/storage-filesystem/src/deadline.mjs +7 -0
  154. package/node_modules/@agents-can-communicate/storage-filesystem/src/index.mjs +2 -0
  155. package/node_modules/@agents-can-communicate/storage-filesystem/src/session-read.mjs +25 -0
  156. package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +28 -25
  157. package/package.json +2 -1
package/docs/PROTOCOL.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Protocol
2
2
 
3
- The protocol is the vendor-neutral contract shared by core, CLI, MCP, storage, and every
4
- adapter. Version 0.2 uses store schema version `3` and deliberately rejects v0.1 state.
5
- There is no compatibility reader, conversion, archive path, or automatic deletion.
3
+ Use this page when implementing or checking a boundary shared by core, CLI, MCP, storage,
4
+ and adapters. Protocol version 0.2 uses store schema version `3` and deliberately rejects
5
+ v0.1 state. There is no compatibility reader, conversion, archive path, or automatic
6
+ deletion.
6
7
 
7
8
  ## Durable records
8
9
 
@@ -24,7 +25,9 @@ Workspace
24
25
  ```
25
26
 
26
27
  - A workspace is one local coordination room.
27
- - A participant is the stable recipient of a message.
28
+ - A participant is the recipient address for a message. A hooked session gets a default
29
+ address derived from its client session id; only an explicitly supplied participant id
30
+ is stable across unrelated client conversations.
28
31
  - A session is one client conversation. Its unguessable generation token proves that a
29
32
  later mutation still belongs to the current opening.
30
33
 
@@ -71,11 +74,57 @@ inside the message so an uncertain caller can retry explicitly.
71
74
 
72
75
  An empty `toParticipantIds` creates a room record. At commit time, core resolves every
73
76
  known peer participant with an open session and creates a receipt for each. Participants
74
- that arrive later can inspect room history through a full sync but do not receive
77
+ that arrive later can inspect room records through history sync but do not receive
75
78
  retroactive receipts. Those already-present recipients get the normal inbox and certified
76
79
  next-turn path; a successful next-turn write advances their room receipt to `offered`.
77
80
  Room records are never eligible for native live push.
78
81
 
82
+ ## Decision lifecycle
83
+
84
+ A decision may additionally carry `decisionChange` with exactly two fields:
85
+ `action` (`replace` or `withdraw`) and `messageIds` (1..16 unique portable IDs of
86
+ existing decisions in the same workspace). Generic send inputs use `supersedes`
87
+ or `withdraws`; the durable payload is built after transactional validation.
88
+ The sorted target set participates in idempotency. The author may be any owned
89
+ participant; attribution does not confer system authority.
90
+
91
+ Targets and their receipts are immutable. Changes inherit target receipt recipients
92
+ and target authors, excluding the changing author from inherited recipients. Extra
93
+ explicit recipients are merged, sorted, and persisted in `toParticipantIds` before
94
+ recording. This also notifies offline readers and makes live routing use the same set.
95
+ No old receipt is acknowledged, deleted, or advanced by a lifecycle change.
96
+
97
+ Explicit links form a graph. Within a connected group, terminal records are heads;
98
+ multiple heads mean a conflict, even if their prose looks similar. A change may target
99
+ an already replaced decision, creating a competing branch. Resolve branches by
100
+ explicitly linking a new change to all their current heads. A withdrawal is itself
101
+ a terminal record; superseding it explicitly records a new decision.
102
+
103
+ Decision summaries and exact read copies expose `decisionStatus`:
104
+
105
+ | Field | Meaning |
106
+ |---|---|
107
+ | `state` | `current` for a terminal choice; `withdrawn` for a terminal cancellation or history with only cancelled heads; otherwise `superseded` |
108
+ | `isHead` | no recorded successor links to this record |
109
+ | `conflicted` / `headCount` | whether the group has multiple terminal positions and their count |
110
+ | `currentMessageId` | sole current head, or null if there is no unique head |
111
+ | `groupId` | derived representative root ID for finding related heads; may change when groups are joined |
112
+
113
+ This metadata is never persisted. `history` + kind `decision` + `current: true`
114
+ lists heads, including withdrawals and conflicts, using the same summary budget.
115
+ Ordinary inbox, bulk reads, automatic delivery and attention omit non-head decisions;
116
+ exact inbox/history retain them. Timestamps and acknowledgements never choose a winner.
117
+ A decision without an explicit successor may still be factually stale.
118
+
119
+ Next-turn context and each native offer use a lifecycle snapshot; text already shown
120
+ or in flight cannot be recalled. Changes get their own delivery receipts. Native
121
+ transport carries the change/status inside its existing untrusted text envelope.
122
+
123
+ The optional field preserves reading of existing schema-3 records by this build.
124
+ Older ACC builds cannot interpret these semantics and may reject new records with
125
+ unknown fields. Upgrade participating ACC installations together; this is not a
126
+ forward-compatible promise or an automatic state migration.
127
+
79
128
  ## Kinds and obligations
80
129
 
81
130
  | Kind | Valid obligation | Addressing |
@@ -152,13 +201,19 @@ leaves the receipt queued.
152
201
 
153
202
  ## Inbox, reply, and acknowledgement
154
203
 
155
- `inbox` returns unresolved messages owned by the calling participant and advances only
156
- that participant's receipt to `retrieved`. An exact message id is the recovery path after
157
- compaction or an over-budget projection.
204
+ Without an id, public `inbox` lists bounded summary pages for unresolved messages owned
205
+ by the calling participant, without changing receipts. An exact read returns the complete
206
+ message and advances only that participant's receipt to `retrieved`. It is the narrow
207
+ recovery and inspection path, including after compaction or acknowledgement. Reading an
208
+ acknowledged message preserves its receipt, timestamp, and event history; it does not put
209
+ the message back into the unresolved inbox. Ownership and current-generation checks still
210
+ apply to every read.
158
211
 
159
212
  `reply` verifies that ownership, records an `answer` in the original thread, and advances
160
213
  the original receipt to `acknowledged` in one transaction. Only after that durable commit
161
214
  may the answer be offered to the original author. A transport error cannot roll back it.
215
+ CLI and MCP reply results expose both facts: `message` and `delivery` describe the outgoing
216
+ answer, while `receipt` describes the caller's acknowledgement of the original message.
162
217
 
163
218
  `ack` advances the caller's receipt without creating a reply. It exposes no state override;
164
219
  callers cannot claim that a transport offered or a participant retrieved a message.
@@ -185,15 +240,22 @@ The recipient owns `livePolicy` because native push may start a model turn:
185
240
  - `actionable`: questions, requests, answers, decisions, and addressed handoffs may use live push;
186
241
  - `all`: every addressed kind may use live push.
187
242
 
188
- Default is `off`. Policy never creates a capability. The router still requires a current
189
- reachable binding, one unambiguous recipient generation, a passing exact-version
190
- certification, and adapter acceptance. The current Codex and Claude captures do not meet
191
- those requirements; all shipped native live routes therefore fall back durably.
243
+ Default is `off`. Policy never creates a capability. The router requires one
244
+ current eligible recipient generation, supported client evidence, a verified
245
+ binding and adapter acceptance. Claude Code Channel uses a captured 2.1.258
246
+ minimum, confirmed on 2.1.260. Codex LocalDaemon uses a 0.152.1 minimum, confirmed
247
+ through installed-product captures on 0.152.1 and 0.153.4; recorded consent and
248
+ exact thread, cwd, process, version and protocol verification govern every session.
249
+ Unavailable or refused routes fall back durably. Codex replies use the ACC CLI;
250
+ its native reply route remains false.
192
251
 
193
252
  ## Attention and sync
194
253
 
195
- Bounded sync returns events after a cursor plus explicit attention. Full sync is a
196
- forensic workspace snapshot, not the normal way to recover one message. Attention is
254
+ Default sync returns a bounded event page after a 16-digit cursor plus explicit attention.
255
+ History sync returns read-only message summaries (20 items by default, at most 12,000
256
+ formatted JSON bytes) and complete-message-id cursors, or one exact full message. Neither
257
+ history mode changes receipts. Full sync adds an unbounded forensic workspace snapshot.
258
+ Message discovery and exact-read contracts are in [CLI](CLI.md) and [MCP](MCP.md). Attention is
197
259
  limited to six explicit rules: `reply_required`, `acknowledgement_required`,
198
260
  `recipient_unavailable`, `claim_conflict`, `claim_contended`, and `claim_expired`.
199
261
 
package/docs/RELEASING.md CHANGED
@@ -1,115 +1,157 @@
1
1
  # Releasing
2
2
 
3
+ Use this procedure to build one auditable npm artifact, verify that exact tarball, and keep
4
+ its evidence tied to the commit that supplied its bytes. The package is currently `0.4.0`;
5
+ the commands derive the version from `package.json` so the filename cannot drift.
6
+
3
7
  ```mermaid
4
8
  graph LR
5
- A[npm ci] --> B[npm run check] --> C[npm test] --> D[clean candidate commit] --> E[npm pack] --> F[verify-package] --> G{approved?}
9
+ A[syntax · diff · staged-set review] --> B[candidate commit A]
10
+ B --> C[pack exact tarball]
11
+ C --> D[verify installed artifact]
12
+ D --> E[evidence commit B]
13
+ E --> F[full suite]
14
+ F --> G{maintainer approval}
6
15
  G -->|yes| H[tag · publish · release]
7
16
  G -->|no| I[stop]
8
17
  ```
9
18
 
10
- ## Build the candidate
19
+ ## Prepare candidate commit A
20
+
21
+ Commit A must contain every file npm will pack and every release gate. Use a clean,
22
+ dedicated release worktree; an existing clean isolated worktree is fine. Update the version
23
+ and candidate files, then run:
11
24
 
12
25
  ```bash
13
- npm ci
26
+ release_cache="$(mktemp -d "${TMPDIR:-/tmp}/acc-npm-cache.XXXXXX")"
27
+ candidate_dir="$(mktemp -d "${TMPDIR:-/tmp}/acc-candidate.XXXXXX")"
28
+ package_version="$(node -p "require('./package.json').version")"
29
+
30
+ env npm_config_cache="$release_cache" npm ci
14
31
  npm run check
15
- env npm_config_cache=/private/tmp/acc-npm-cache-v02 npm test
16
- git status --short
17
- git commit -m "release: prepare ACC v0.2.0"
18
- candidate_dir="$(mktemp -d /private/tmp/acc-v0.2.XXXXXX)"
19
- env npm_config_cache=/private/tmp/acc-npm-cache-v02 npm pack --pack-destination "$candidate_dir"
20
- env npm_config_cache=/private/tmp/acc-npm-cache-v02 node scripts/verify-package.mjs \
21
- "$candidate_dir/agents-can-communicate-0.2.0.tgz"
22
32
  git diff --check
33
+ git status --short
34
+ git diff --name-only
35
+ # Repeat with every reviewed candidate path; never use `.` or `-A` here.
36
+ git add -- path/to/reviewed-file
37
+ git diff --cached --name-status
38
+ git diff --cached --check
39
+ git commit -m "release: prepare ACC v$package_version"
40
+ candidate_commit="$(git rev-parse HEAD)"
41
+ test -z "$(git status --short)"
23
42
  ```
24
43
 
25
- `verify-package.mjs` is the gate that matters. It installs the tarball into a
26
- clean directory with **no workspace anywhere** and then drives the product. The
27
- acceptance suite additionally opens independent Claude/Codex hook sessions from
28
- the installed artifact, completes both message directions, proves downgrade and
29
- restart behavior, exercises the installed MCP binary, and removes client wiring twice.
30
-
31
- Development cannot catch what this catches. Workspace symlinks are always
32
- present there, so an unbundled package imports fine right up until somebody
33
- else installs it.
34
-
35
- ## What it refuses
36
-
37
- | Refused | Why |
38
- |---|---|
39
- | `tests/`, `test/` | test suite |
40
- | unreferenced `fixtures/` | material that is not exact redacted certification evidence |
41
- | `scripts/spikes/`, `*.sock` | development probes and local endpoints |
42
- | runtime, transcript, or secret directories | machine state and private material |
43
- | `.github/`, `.githooks/`, `.agents/` | local configuration |
44
- | `*.jsonl` | looks like a transcript |
45
- | Workspaces missing from `node_modules/` | every internal import would fail |
46
-
47
- ## Record the evidence
48
-
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.3.0.md` and
51
- the current `CHANGELOG.md` release table. A release without them is a release nobody can
52
- audit later. Test count is deliberately left out: nothing verifies it, so it only
53
- decorates or, when it drifts, misleads.
54
-
55
- The commit matters because every workspace travels inside the tarball, so any
56
- change to shipped code changes the digest. A digest recorded alone goes stale
57
- on the next merge and then reads as a false claim about the current tree
58
- rather than a true one about an older commit. `verify-package.mjs` prints
59
- both on one line for exactly this reason, and refuses to imply
60
- reproducibility when the working tree is dirty:
61
-
62
- ```text
63
- PASS agents-can-communicate-0.0.0.tgz sha256 a5c8bb1d… built from 39d0dcf
44
+ Replace `path/to/reviewed-file` with each explicit path you just reviewed. Never use
45
+ `git add .` or `git add -A` in this procedure: an unrelated file does not become release
46
+ content merely because it shares a worktree. Check `git diff --cached --name-status` before
47
+ committing and stop if `git status --short` after the commit is not empty.
48
+
49
+ Never bypass the pre-push hook. The full suite belongs after commit B because the
50
+ recorded-candidate gate deliberately includes working-tree and committed packed changes;
51
+ before refreshed evidence exists, that one check is expected to fail.
52
+
53
+ ## Pack and verify the exact artifact
54
+
55
+ ```bash
56
+ env npm_config_cache="$release_cache" npm pack --pack-destination "$candidate_dir"
57
+ tarball="$candidate_dir/agents-can-communicate-$package_version.tgz"
58
+ shasum -a 256 "$tarball"
59
+ env npm_config_cache="$release_cache" node scripts/verify-package.mjs "$tarball"
64
60
  ```
65
61
 
66
- It went stale four times in a row anyway, each caught by hand and only
67
- because someone happened to run the script. So `npm test` now checks it:
68
- `tests/acceptance/recorded-candidate.test.mjs` fails when shipped code has
69
- changed since the recorded commit, and names the files. A shallow clone that
70
- does not have the commit reports that instead of failing — the check is of
71
- the record, not of the checkout depth.
62
+ `verify-package.mjs` installs the supplied tarball into a clean directory with no workspace
63
+ symlinks, then exercises doctor, a non-Git workspace, client install/uninstall, bundled
64
+ workspaces, certification evidence, and packed documentation links. It rejects tests,
65
+ development probes, sockets, transcript-shaped data, runtime state, and unreferenced
66
+ fixtures. Keep `ACC_NO_UPDATE_CHECK=1` set for release checks so installing an integration
67
+ cannot schedule a real registry update. The managed-update acceptance tests explicitly
68
+ enable networking only against their isolated local registry and npm cache.
72
69
 
73
- The candidate therefore uses two commits. Commit A contains every packed file and every
74
- release gate. Pack and verify clean commit A, then commit B records its digest and evidence
75
- only in files that are not packed. Never record a dirty-tree digest: changing a packed file
76
- after commit A means making a new candidate commit and packing again.
70
+ The managed-update checks exercise actual installed archives: automatic enrollment and
71
+ activation, a persistent MCP process holding the old version, integrity rejection, recovery
72
+ from a failed integration refresh, and stable launchers after the initial package is gone.
73
+ Run them before recording the candidate:
77
74
 
78
- Native real-client tests run only where the retained capture proved that native boundary.
79
- For v0.2.0 neither Codex 0.152.0 nor Claude Code 2.1.252 did: the Codex control socket was
80
- absent and Claude stopped at the development-channel warning. Record those exact failed
81
- captures and run the packed inbox/next-turn fallback instead of promoting an unobserved
82
- native path. Windows is an explicit unsupported-platform skip, not a passing capture.
75
+ ```bash
76
+ env npm_config_cache="$release_cache" node --test tests/acceptance/managed-*-packed.test.mjs
77
+ ```
83
78
 
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.
79
+ Repeat the published-version upgrade preflight with this exact tarball and isolated home,
80
+ data, and project directories. Retain the source/archive/installed file comparison with the
81
+ preflight evidence. Local-registry checks and direct process checks do not establish native
82
+ client activation; capture that separately on supported real clients.
89
83
 
90
- A published version's record is history and is not rewritten; later changes
91
- get a new `## Unreleased` entry at the top, checked the same way against the
92
- current tree.
84
+ When passed an existing tarball, the verifier intentionally prints `revision unknown`:
85
+ the current checkout cannot prove which commit produced arbitrary supplied bytes. Record
86
+ `$candidate_commit`, captured while the tree was clean immediately before packing, as the
87
+ artifact's source. Running the verifier without a tarball makes it pack the current tree
88
+ itself and can report that tree's revision, but it does not verify a separately saved
89
+ release artifact.
93
90
 
94
- ## Then stop
91
+ ## Record evidence in commit B
95
92
 
96
- Publishing, tagging, and cutting a GitHub release are **external mutations**.
97
- They need explicit approval from the maintainer, every time.
93
+ Write the tarball name, SHA-256, `$candidate_commit`, platform and client facts, fallback
94
+ result, and known limitations to `docs/release-evidence/v$package_version.md` and the
95
+ matching `CHANGELOG.md` section. Do not record an unverifiable test count.
98
96
 
99
- With two-factor authentication set to `auth-and-writes` — which is what `npm
100
- profile get` reports for this account — every publish needs a code, and npm
101
- does not prompt for one:
97
+ Commit B contains only evidence files that npm does not pack. If a packed file changes,
98
+ discard the candidate artifact, make a new commit A, and repeat the pack and verification.
102
99
 
103
100
  ```bash
104
- npm publish --otp=123456
101
+ git diff --check
102
+ git status --short
103
+ git add -- CHANGELOG.md "docs/release-evidence/v$package_version.md"
104
+ git diff --cached --name-status
105
+ git diff --cached --check
106
+ git commit -m "release: record ACC v$package_version candidate"
107
+ test -z "$(git status --short)"
108
+ env npm_config_cache="$release_cache" npm test
105
109
  ```
106
110
 
107
- An npm *Automation* token, or a granular token with write access, publishes
108
- without a code. A granular token scoped to selected packages cannot create a
109
- package that does not exist yet, which is the case exactly once per package.
110
- The `Release` workflow builds and verifies a candidate and uploads it as an
111
- artifact; it does not publish.
111
+ The staged-set review for commit B must name only those two evidence files. The final full
112
+ suite now sees candidate A's packed bytes plus candidate B's matching record, so candidate
113
+ freshness is a normal passing gate rather than an expected failure.
114
+
115
+ Published evidence is history. Do not rewrite it into a current capability claim; later
116
+ work belongs under `Unreleased` and gets a new candidate record.
117
+
118
+ ## Capture only capabilities you observed
119
+
120
+ Run native real-client checks on the exact versions and platforms recorded in
121
+ retained fixtures. Exact-version evidence governs normal-turn and guard behavior.
122
+ Claude Code Channel uses its captured macOS arm64 minimum plus a current probe and
123
+ per-session handshake; its vendor warning remains part of startup. Codex LocalDaemon
124
+ uses a separate 0.152.1 minimum with installed-product captures on 0.152.1 and
125
+ 0.153.4. Its passing capture must ship the hashed complete product matrix and
126
+ historical evidence references. Direct queue success alone cannot certify that route.
127
+
128
+ Record failed and unavailable paths as such, then exercise the packed next-turn or inbox
129
+ fallback. An unsupported platform is an explicit skip, never a passing capture. See
130
+ [Capabilities](CAPABILITIES.md) and each adapter's `COMPATIBILITY.md` for current evidence.
131
+
132
+ ## Publish only after explicit approval
133
+
134
+ Tagging, npm publication, and creating a GitHub release are external mutations. Stop after
135
+ commit B until a maintainer explicitly approves them. The manual `Release` workflow builds
136
+ and uploads a candidate; it does not publish.
137
+
138
+ Authentication requirements depend on the credential and npm policy in effect at release
139
+ time. Consult npm's current documentation and inspect the configured route instead of
140
+ copying a historical command. For example, the v0.3.0 publication succeeded without an OTP
141
+ while `npm profile get` returned `403`; that is a historical observation, not a universal
142
+ claim about current npm authentication or credential type.
143
+
144
+ After approval, publish the verified tarball by filename. Bare `npm publish` repacks the
145
+ tree and would send different, unverified bytes.
146
+
147
+ ```bash
148
+ npm publish "$tarball"
149
+ npm view "agents-can-communicate@$package_version" dist.shasum
150
+ shasum "$tarball"
151
+ ```
112
152
 
113
- ---
153
+ Add `--otp` only when the current authenticated npm route requires it. Compare the registry
154
+ SHA-1 with the local `shasum`, allowing for registry propagation delay, before creating the
155
+ tag or release record.
114
156
 
115
- See also: [README](index.md) for navigation and [Glossary](GLOSSARY.md) for terms.
157
+ See also: [documentation map](index.md) · [Security model](SECURITY_MODEL.md)
@@ -1,11 +1,13 @@
1
1
  # Security model
2
2
 
3
- ACC connects independently controlled sessions without merging their authority. A peer can
4
- send useful context, a question, or a request; its text never becomes system policy or a
5
- human instruction merely because ACC transported it.
3
+ Use this model to decide which boundary owns a security claim and which failure belongs to
4
+ the client or local account instead. ACC connects independently controlled sessions
5
+ without merging their authority. A peer can send context, a question, or a request; its
6
+ text never becomes system policy or a human instruction merely because ACC transported it.
6
7
 
7
- The first release coordinates processes under one local OS user. Same-user access protects
8
- local transport from the network; it does not make model output trustworthy.
8
+ The current local boundary coordinates processes under one OS user on one machine.
9
+ Same-user access protects local transport from the network; it does not make model output
10
+ trustworthy.
9
11
 
10
12
  ## Trust boundaries
11
13
 
@@ -40,7 +42,11 @@ own instruction hierarchy are the mitigation; ACC is not a model sandbox.
40
42
  ## Identity and ownership
41
43
 
42
44
  - Participant identity is the address; session identity is one current client opening.
43
- - Mutating calls prove their owner with the session generation.
45
+ - Mutating CLI calls and inbox reads require an explicitly supplied session/generation
46
+ pair. The CLI never obtains a generation from a public ID, checkout, sole peer binding,
47
+ or inherited native environment value.
48
+ - `ACC_SESSION`/`ACC_GENERATION` are operator-supplied credentials. They do not authenticate
49
+ a process or protect against intentional sharing under the same local OS account.
44
50
  - A stale process cannot renew or release records owned by a newer generation.
45
51
  - Inbox, reply, and acknowledgement validate the recipient's participant id.
46
52
  - One participant cannot advance another participant's receipt.
@@ -64,15 +70,20 @@ There is no model-attention claim and no public state override. Failed accelerat
64
70
  the message queued and records only a closed safe error code. Diagnostics and offer events
65
71
  never copy the peer body.
66
72
 
67
- A future live adapter must match exact passing evidence, one unexpired generation-bound
68
- binding, and the recipient's opt-in policy. Opaque endpoint references remain inside the
69
- adapter and outside repositories. Current Codex and Claude native captures failed, so no
70
- live transport is enabled.
73
+ A live adapter must match its declared evidence contract, one current
74
+ generation-bound binding and recipient opt-in. Opaque endpoints remain private
75
+ and outside repositories. Claude Code Channel and Codex LocalDaemon delivery are
76
+ experimental and off by default. Codex verifies the exact receiver thread,
77
+ canonical cwd, live process, stable version and protocol, and rereads recorded
78
+ consent before offers. A loaded daemon thread can receive messages after its TUI
79
+ exits. Delivery off and uninstall prevent new Codex submissions; a submission
80
+ already accepted by the vendor queue cannot be withdrawn.
71
81
 
72
82
  ## Claims
73
83
 
74
- Claims are advisory unless every live participant exposes a certified guard for the
75
- relevant mutation path. Even guarded claims do not stop unrelated processes, runtime-built
84
+ CLI claims default to advisory. Guarded enforcement must be requested explicitly and
85
+ requires every live participant to expose a certified guard for the relevant mutation path.
86
+ MCP claims remain advisory. Even guarded claims do not stop unrelated processes, runtime-built
76
87
  paths, or tool calls the client never presents to the hook. Force release requires explicit
77
88
  authority and records actor and reason.
78
89
 
@@ -88,14 +99,40 @@ from operating merely because its own state is unavailable.
88
99
  - Corrupt or incompatible store versions fail closed before mutation.
89
100
  - Client installers preserve unrelated settings and record content hashes.
90
101
  - Uninstall removes only bytes still matching what ACC wrote.
91
- - Tokens, credentials, and environment contents are never copied into ACC or project config.
102
+ - Runtime credentials and private endpoints stay outside project config. Adapters do not
103
+ automatically collect client secrets or environment contents into peer messages.
104
+
105
+ ## Managed automatic updates
106
+
107
+ A normal managed installation enables automatic updates. The latency-sensitive hook path
108
+ does no network download; it may schedule a detached worker. That worker uses the configured
109
+ npm registry/network and local npm executable, checks stable package identity/version and
110
+ sha512 integrity against registry metadata, installs with lifecycle scripts disabled, and
111
+ validates the staged runtime before activation. These checks retain the registry and package
112
+ author as a software-supply trust boundary; they do not establish that package code is safe.
113
+
114
+ ACC process leases hold activation until confirmed exit. Native bindings hold until observed
115
+ SessionEnd cleanup or confirmed process death; unknown PIDs remain conservative holds.
116
+ `acc finish`, presence TTL, and delivery off do not establish native lifecycle end. ACC does
117
+ not manage the vendor daemon.
118
+
119
+ A failed download leaves the active runtime available. A partial integration refresh retains
120
+ the old active pointer but fences normal workspace admission in `activating`; it does not
121
+ leave the previous runtime available for normal work. Fix the reported problem and run
122
+ `acc update` to repair forward. Hooks continue to fail open while coordination is unavailable.
123
+
124
+ `acc update --auto off` disables background updates; `--pin <version>` holds an exact stable
125
+ version. `ACC_NO_UPDATE_CHECK=1` disables update networking and scheduling while allowing
126
+ manual recovery of an already verified pending update. See [Upgrading](UPGRADING.md).
92
127
 
93
128
  ## Data collected
94
129
 
95
130
  ACC stores participant/session identity, presence, one-line intent, explicit claims,
96
131
  explicit messages and structured handoffs, per-recipient receipts, artifact references,
97
- and coordination events. It excludes complete prompts, assistant responses, raw
98
- transcripts, secrets, environment variables, and unrelated files.
132
+ and coordination events. ACC does not automatically collect raw transcripts, full prompts
133
+ or assistant responses, secrets, environment contents, or unrelated files. Explicit message
134
+ bodies are caller-provided and preserved: ACC does not scan or scrub secrets from text a
135
+ caller chooses to send. The sender remains responsible for that content.
99
136
 
100
137
  ## Threat scenarios
101
138