agents-can-communicate 0.1.18 → 0.2.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 (134) hide show
  1. package/README.md +78 -70
  2. package/SECURITY.md +31 -0
  3. package/bin/acc-hook.mjs +94 -12
  4. package/bin/acc-mcp.mjs +6 -2
  5. package/bin/acc.mjs +6 -1
  6. package/docs/ADAPTER_AUTHORING.md +172 -0
  7. package/docs/ARCHITECTURE.md +131 -0
  8. package/docs/CAPABILITIES.md +102 -214
  9. package/docs/CLI.md +157 -0
  10. package/docs/CONCEPTS.md +134 -0
  11. package/docs/CONFIGURATION.md +143 -0
  12. package/docs/DESIGN_DECISIONS.md +89 -0
  13. package/docs/GETTING_STARTED.md +145 -0
  14. package/docs/GLOSSARY.md +26 -0
  15. package/docs/MCP.md +94 -0
  16. package/docs/PROTOCOL.md +200 -0
  17. package/docs/RELEASING.md +109 -0
  18. package/docs/SECURITY_MODEL.md +131 -0
  19. package/docs/TROUBLESHOOTING.md +102 -0
  20. package/docs/WHY_ACC.md +61 -0
  21. package/docs/index.md +42 -0
  22. package/node_modules/@agents-can-communicate/adapter-claude-code/certification.json +78 -0
  23. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/PreToolUse-Edit.json +19 -0
  24. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/PreToolUse.json +17 -0
  25. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/SessionEnd.json +8 -0
  26. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/SessionStart.json +7 -0
  27. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/UserPromptSubmit.json +9 -0
  28. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/certification-provenance.json +77 -0
  29. package/node_modules/@agents-can-communicate/adapter-claude-code/fixtures/delivery/claude-code-2.1.252.json +19 -0
  30. package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +9 -1
  31. package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/skills/acc/SKILL.md +20 -22
  32. package/node_modules/@agents-can-communicate/adapter-claude-code/src/adapter.mjs +12 -4
  33. package/node_modules/@agents-can-communicate/adapter-codex/certification.json +117 -0
  34. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/PreToolUse.json +14 -0
  35. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/SessionEnd.json +7 -0
  36. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/SessionStart.json +9 -0
  37. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/UserPromptSubmit.json +10 -0
  38. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/certification-provenance.json +66 -0
  39. package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.0.json +19 -0
  40. package/node_modules/@agents-can-communicate/adapter-codex/package.json +8 -1
  41. package/node_modules/@agents-can-communicate/adapter-codex/plugin/.codex-plugin/plugin.json +1 -1
  42. package/node_modules/@agents-can-communicate/adapter-codex/plugin/skills/acc/SKILL.md +20 -22
  43. package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +18 -11
  44. package/node_modules/@agents-can-communicate/adapter-gemini-cli/certification.json +52 -0
  45. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
  46. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/skills/acc/SKILL.md +20 -22
  47. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/BeforeAgent.json +8 -0
  48. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/BeforeTool-shell.json +12 -0
  49. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/BeforeTool.json +12 -0
  50. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/SessionEnd.json +8 -0
  51. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/SessionStart.json +8 -0
  52. package/node_modules/@agents-can-communicate/adapter-gemini-cli/fixtures/certification-provenance.json +66 -0
  53. package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +8 -1
  54. package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/adapter.mjs +7 -3
  55. package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/install.mjs +4 -2
  56. package/node_modules/@agents-can-communicate/adapter-grok/certification.json +3 -0
  57. package/node_modules/@agents-can-communicate/adapter-grok/package.json +2 -1
  58. package/node_modules/@agents-can-communicate/adapter-grok/plugin/skills/acc/SKILL.md +20 -22
  59. package/node_modules/@agents-can-communicate/adapter-grok/src/adapter.mjs +9 -9
  60. package/node_modules/@agents-can-communicate/adapter-kimi/certification.json +52 -0
  61. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/PreToolUse-Bash.json +12 -0
  62. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/PreToolUse-Write.json +12 -0
  63. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/SessionHeartbeat.json +7 -0
  64. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/SessionStart.json +9 -0
  65. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/UserPromptSubmit.json +8 -0
  66. package/node_modules/@agents-can-communicate/adapter-kimi/fixtures/certification-provenance.json +66 -0
  67. package/node_modules/@agents-can-communicate/adapter-kimi/package.json +8 -1
  68. package/node_modules/@agents-can-communicate/adapter-kimi/plugin/skills/acc/SKILL.md +20 -22
  69. package/node_modules/@agents-can-communicate/adapter-kimi/src/adapter.mjs +7 -3
  70. package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
  71. package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +34 -18
  72. package/node_modules/@agents-can-communicate/adapter-sdk/src/certification.mjs +158 -0
  73. package/node_modules/@agents-can-communicate/adapter-sdk/src/context-projector.mjs +36 -17
  74. package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +7 -1
  75. package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +1 -0
  76. package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +13 -4
  77. package/node_modules/@agents-can-communicate/cli/package.json +1 -1
  78. package/node_modules/@agents-can-communicate/cli/src/args.mjs +11 -30
  79. package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +3 -0
  80. package/node_modules/@agents-can-communicate/cli/src/help.mjs +2 -5
  81. package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +9 -2
  82. package/node_modules/@agents-can-communicate/cli/src/main.mjs +100 -121
  83. package/node_modules/@agents-can-communicate/core/package.json +1 -1
  84. package/node_modules/@agents-can-communicate/core/src/attention.mjs +106 -0
  85. package/node_modules/@agents-can-communicate/core/src/conversations.mjs +276 -0
  86. package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +81 -0
  87. package/node_modules/@agents-can-communicate/core/src/finish-retries.mjs +97 -0
  88. package/node_modules/@agents-can-communicate/core/src/inbox.mjs +91 -107
  89. package/node_modules/@agents-can-communicate/core/src/index.mjs +3 -3
  90. package/node_modules/@agents-can-communicate/core/src/intents.mjs +0 -1
  91. package/node_modules/@agents-can-communicate/core/src/ports.mjs +2 -1
  92. package/node_modules/@agents-can-communicate/core/src/receipts.mjs +109 -0
  93. package/node_modules/@agents-can-communicate/core/src/service.mjs +11 -10
  94. package/node_modules/@agents-can-communicate/core/src/sessions.mjs +22 -20
  95. package/node_modules/@agents-can-communicate/core/src/status.mjs +11 -9
  96. package/node_modules/@agents-can-communicate/core/src/sync.mjs +3 -294
  97. package/node_modules/@agents-can-communicate/delivery-router/package.json +12 -0
  98. package/node_modules/@agents-can-communicate/delivery-router/src/index.mjs +1 -0
  99. package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +117 -0
  100. package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
  101. package/node_modules/@agents-can-communicate/hook-runner/src/client-version.mjs +20 -0
  102. package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +115 -63
  103. package/node_modules/@agents-can-communicate/installer/package.json +1 -1
  104. package/node_modules/@agents-can-communicate/installer/src/apply.mjs +23 -7
  105. package/node_modules/@agents-can-communicate/installer/src/detect.mjs +20 -5
  106. package/node_modules/@agents-can-communicate/installer/src/index.mjs +3 -2
  107. package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +108 -12
  108. package/node_modules/@agents-can-communicate/installer/src/plan.mjs +19 -2
  109. package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
  110. package/node_modules/@agents-can-communicate/mcp-server/src/input-validator.mjs +79 -0
  111. package/node_modules/@agents-can-communicate/mcp-server/src/resources.mjs +23 -28
  112. package/node_modules/@agents-can-communicate/mcp-server/src/server.mjs +102 -72
  113. package/node_modules/@agents-can-communicate/mcp-server/src/tools.mjs +54 -97
  114. package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
  115. package/node_modules/@agents-can-communicate/protocol/src/config.mjs +1 -1
  116. package/node_modules/@agents-can-communicate/protocol/src/conversations.mjs +64 -0
  117. package/node_modules/@agents-can-communicate/protocol/src/index.mjs +4 -1
  118. package/node_modules/@agents-can-communicate/protocol/src/schema.mjs +49 -90
  119. package/node_modules/@agents-can-communicate/protocol/src/states.mjs +13 -40
  120. package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
  121. package/node_modules/@agents-can-communicate/storage-filesystem/src/active-journal.mjs +230 -0
  122. package/node_modules/@agents-can-communicate/storage-filesystem/src/atomic-json.mjs +77 -28
  123. package/node_modules/@agents-can-communicate/storage-filesystem/src/identity.mjs +1 -1
  124. package/node_modules/@agents-can-communicate/storage-filesystem/src/journal.mjs +83 -35
  125. package/node_modules/@agents-can-communicate/storage-filesystem/src/retention.mjs +112 -0
  126. package/node_modules/@agents-can-communicate/storage-filesystem/src/safe-file.mjs +18 -8
  127. package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +68 -26
  128. package/node_modules/@agents-can-communicate/storage-filesystem/src/writer-mutex.mjs +113 -35
  129. package/package.json +19 -1
  130. package/node_modules/@agents-can-communicate/core/src/communication.mjs +0 -334
  131. package/node_modules/@agents-can-communicate/core/src/message-signals.mjs +0 -41
  132. package/node_modules/@agents-can-communicate/core/src/notify.mjs +0 -95
  133. package/node_modules/@agents-can-communicate/core/src/tasks.mjs +0 -244
  134. package/node_modules/@agents-can-communicate/core/src/workstreams.mjs +0 -109
@@ -0,0 +1,134 @@
1
+ # Concepts
2
+
3
+ ACC connects AI sessions that were independently opened by a user. It adds communication
4
+ around those sessions; it does not turn them into one managed runtime. Each client keeps
5
+ its own context, permissions, lifecycle, checkout, and human authority.
6
+
7
+ ```mermaid
8
+ graph LR
9
+ A["independent session A"] --- ACC["ACC local room"]
10
+ B["independent session B"] --- ACC
11
+ C["independent session C"] --- ACC
12
+ ```
13
+
14
+ ## Peers, not workers
15
+
16
+ Sessions in one workspace may use different models, clients, trust settings, or people.
17
+ No participant is automatically in charge of another. A peer may ask, answer, reserve,
18
+ acknowledge, or hand off; the receiver evaluates the message under its own instructions.
19
+
20
+ This is the middle layer between isolated terminals and a system that owns the agents.
21
+ ACC owns durable coordination facts even when every model process is gone, but it never
22
+ owns the process itself.
23
+
24
+ ## Participant and session
25
+
26
+ A **participant** is the address used for communication. A stable participant id lets a
27
+ new session recover messages addressed before restart. A **session** is one current client
28
+ conversation with a generation token proving ownership of its mutations. Several sessions
29
+ may belong to one participant; a live offer is ambiguous unless exactly one current
30
+ generation is eligible.
31
+
32
+ A **workspace** is the local room. Git worktrees of one repository resolve to the same
33
+ workspace while retaining their checkout and branch in presence. In a non-Git directory,
34
+ the directory itself supplies identity. Git enriches the record but is never required.
35
+
36
+ ## Intent is awareness; a claim commits
37
+
38
+ An **intent** says what a session is doing and which resources may be affected. It
39
+ authorises nothing. Publish it early because it is cheap:
40
+
41
+ ```bash
42
+ acc work --summary "changing message rendering" --mode edit \
43
+ --hint 'file:packages/cli/**'
44
+ ```
45
+
46
+ A **claim** reserves a resource for a lease. It is narrow, explicit, and either
47
+ `advisory` or `guarded`:
48
+
49
+ ```bash
50
+ acc claim --resource 'file:packages/cli/**' --reason "changing message rendering"
51
+ ```
52
+
53
+ `guarded` means every live session exposes a measured pre-write guard for the path ACC can
54
+ recognise. It never means an unrelated process or a runtime-generated write is impossible.
55
+ If any live participant cannot be stopped, workspace protection is reported as
56
+ `advisory`.
57
+
58
+ File claims are repository-relative and canonical. `file:src/a.mjs` names a file;
59
+ `file:src/**` names a directory tree. Ambiguous spellings such as `file:src/*` are refused
60
+ instead of creating protection that covers nothing.
61
+
62
+ ## Messages are durable untrusted data
63
+
64
+ The message kinds are `note`, `question`, `request`, `answer`, `decision`, and `handoff`.
65
+ The generic send command creates the first four except `answer`, which requires `reply`,
66
+ and `handoff`, which requires `finish` so their thread and structured payloads cannot be
67
+ omitted.
68
+
69
+ An independent **obligation** says what the recipient owes:
70
+
71
+ | Kind | Obligation |
72
+ |---|---|
73
+ | `note` | `none` |
74
+ | `question` | `reply` |
75
+ | `request` | `reply` |
76
+ | `answer` | `none` |
77
+ | `decision` | `none`, or `acknowledge` when addressed |
78
+ | `handoff` | `acknowledge` when addressed, `none` as a room record |
79
+
80
+ A request is not an order. It asks for action and a result in the thread, but ACC does not
81
+ track execution state. Every body is attributed, escaped, and framed as peer input rather
82
+ than system authority.
83
+
84
+ ## Threads have no hidden status
85
+
86
+ The first message is the thread root and uses its own `messageId` as `threadId`. A reply
87
+ keeps that thread id and names the original with `inReplyTo`. There is no mutable thread
88
+ record. What still needs attention is derived from message obligations and per-recipient
89
+ receipts.
90
+
91
+ `clientMessageId` is the caller's retry key. Repeating equivalent content with the same
92
+ key returns the same logical message; reusing it for different content is rejected.
93
+
94
+ ## Delivery words are evidence
95
+
96
+ Each recipient has an independent monotonic receipt:
97
+
98
+ ```text
99
+ queued -> offered -> retrieved -> acknowledged
100
+ ```
101
+
102
+ - `queued`: message and receipt committed durably;
103
+ - `offered`: bytes crossed ACC's transport boundary or a certified native client accepted
104
+ the call;
105
+ - `retrieved`: the participant explicitly read the message through inbox or equivalent
106
+ certified evidence;
107
+ - `acknowledged`: the participant acknowledged it or replied.
108
+
109
+ There is no `seen`: ACC cannot observe model attention. There is no terminal delivery
110
+ failure: a failed acceleration leaves the durable message recoverable. Forward skips are
111
+ legal when a stronger fact implies the weaker ones; backward transitions are rejected.
112
+
113
+ ## Durable first, acceleration second
114
+
115
+ Every send records the message before attempting a transport. Inbox is the universal
116
+ recovery path. Exact-version certified adapters may offer complete peer messages at the
117
+ next normal turn. Native live push would additionally require passing certification, the
118
+ recipient's opt-in policy, exactly one current reachable binding, and a safe recipient
119
+ state.
120
+
121
+ No shipped adapter currently passes live-push certification. Codex 0.152.0 had no daemon
122
+ control socket; Claude Code 2.1.252 stopped at the development-channel warning before its
123
+ ACC child started. Those failures are shipped as evidence and result in visible fallback,
124
+ not a stronger promise.
125
+
126
+ ## Where state lives
127
+
128
+ Presence, intents, claims, messages, receipts, events, and handoffs live in platform app
129
+ data outside every repository. Raw transcripts remain in the client. A single session is
130
+ silent; durable workspace state materialises when a second session or the first durable
131
+ coordination object makes it necessary.
132
+
133
+ Next: [Getting started](GETTING_STARTED.md) · [Protocol](PROTOCOL.md) ·
134
+ [Capabilities](CAPABILITIES.md)
@@ -0,0 +1,143 @@
1
+ # Configuration
2
+
3
+ ACC works with no configuration at all. A workspace is identified by its Git common
4
+ directory when there is one and by the directory itself otherwise. Independently opened
5
+ sessions can communicate without adding runtime state to the project.
6
+
7
+ `acc.workspace.json` is only for stable workspace identity, roots, and shared claim/context
8
+ policy. It never defines agents, messages, execution state, or delivery endpoints. Project
9
+ map: [README](index.md). Terms used below: [Glossary](GLOSSARY.md).
10
+
11
+ ## When you need a config
12
+
13
+ - **Identity that survives a move.** Without a config, the same project checked out at two
14
+ paths is two workspaces, and two people whose clones sit in different directories do not
15
+ see each other. `workspaceId` fixes that, and it is the usual reason this file exists.
16
+ - **More than one root.** A monorepo whose apps live in separate directories, or a
17
+ workspace that spans sibling checkouts.
18
+ - **Shared policy.** Claim mode and context budget, agreed once and committed, rather than
19
+ each person's machine deciding.
20
+ - **Stated expectations.** `requiredAdapters` records which harnesses this project expects
21
+ to be installed, so `acc doctor` can say what is missing rather than leaving a session
22
+ silently uncoordinated.
23
+
24
+ ### The file
25
+
26
+ `acc.workspace.json`, at the root of the workspace. One name, so discovery is a lookup and
27
+ not a search. It is found by walking up from the working directory, because sessions start
28
+ wherever the human happens to be — a config that only counted at the top would apply to
29
+ some sessions in a project and not others. A config reached through a symlink is refused: a
30
+ link can point anywhere, including at a file the repository does not control.
31
+
32
+ ```json
33
+ {
34
+ "schemaVersion": 1,
35
+ "workspaceId": "workspace_9pQ2f1xJ",
36
+ "displayName": "Example",
37
+ "roots": ["."],
38
+ "policy": {
39
+ "claimMode": "advisory",
40
+ "contextBudgetBytes": 6000
41
+ },
42
+ "requiredAdapters": []
43
+ }
44
+ ```
45
+
46
+ | Field | Meaning | Default |
47
+ |---|---|---|
48
+ | `schemaVersion` | Must be `1` | required |
49
+ | `workspaceId` | Stable identity, portable id | required |
50
+ | `displayName` | What peers see in a roster | the directory name |
51
+ | `roots` | Directories in this workspace, relative to the config | `["."]` |
52
+ | `policy.claimMode` | `advisory` or `guarded` | `advisory` |
53
+ | `policy.contextBudgetBytes` | Ceiling on injected turn context, 1–64000 | `6000` |
54
+ | `requiredAdapters` | Harnesses this project expects | `[]` |
55
+ | `extensions` | Anything else, namespaced by whoever wrote it | `{}` |
56
+
57
+ Roots are refused if they are absolute or escape the workspace. An absolute root is one
58
+ machine's layout committed to a shared repository, and `packages/../../elsewhere` reaches
59
+ outside the boundary the workspace is supposed to be. The check counts path segments, so an
60
+ escape spelled in the middle is caught rather than only a leading `..`.
61
+
62
+ An unrecognised key is an error, not a shrug. `clam_mode` reads like a typo to a human and
63
+ like nothing at all to a parser that ignores what it does not know, and the result is a
64
+ team whose policy quietly stopped applying. `extensions` is the one declared door for
65
+ anything ACC does not define.
66
+
67
+ ### What it must never contain
68
+
69
+ Sessions, participants, messages, claims, receipts, intents, events, tokens, credentials.
70
+ All of it is refused, by name, with the key that caused it, for two reasons. Runtime state
71
+ belongs under the platform data directory, so a checkout can be deleted, cloned, or synced
72
+ without carrying presence and locks along. And a config lives in a repository, where anyone
73
+ who can open a pull request can edit it — a file that could declare sessions would be a way
74
+ to hand a peer state it should have had to earn.
75
+
76
+ ### Writing one while sessions are running
77
+
78
+ The config carries the workspace identity, so writing one moves the project to a new
79
+ workspace. Sessions already attached stay on the old one: they keep heartbeating it, they
80
+ drop off everyone else's roster, and claims they hold stop being seen. They do not recover
81
+ by themselves either — a session attaches when its client starts and at no other point.
82
+
83
+ So `init` refuses while sessions are attached, and names them:
84
+
85
+ ```text
86
+ 2 session(s) are attached here and would stop seeing each other: graphics (claude_code),
87
+ physics (codex). They re-attach only when their client starts, so close them first, or
88
+ pass --force to write anyway.
89
+ ```
90
+
91
+ Close them, or pass `--force` if you mean it — and restart them afterwards.
92
+
93
+ ### Commands
94
+
95
+ <!-- test:illustration asks a person to confirm; there is nobody to ask in a test -->
96
+ ```bash
97
+ acc config init # preview, then write after you agree
98
+ acc config validate # read-only; reports what applies
99
+ ```
100
+
101
+ `init` shows the exact file it would write and waits. In a non-interactive run — a pipe, a
102
+ CI job, an agent — there is nobody to ask, so it refuses unless you pass `--yes`. It never
103
+ overwrites an existing config: a committed identity is shared by everyone on the project,
104
+ and replacing it on a mistyped command would split one workspace into two.
105
+
106
+ `validate` only reads. A command someone runs to find out what is wrong must not change the
107
+ thing it is inspecting. With no config present it reports the defaults rather than failing,
108
+ because not having one is a valid state.
109
+
110
+ ## Delivery policy is not project policy
111
+
112
+ Live delivery may start a model turn and spend that recipient's tokens, so it is configured
113
+ through the recipient's user-owned client installation:
114
+
115
+ ```bash
116
+ acc install --adapter codex --delivery off
117
+ ```
118
+
119
+ The allowed values are `off`, `actionable`, and `all`; the default is `off`. This setting
120
+ does not belong in `acc.workspace.json`, where a pull request could opt someone else into
121
+ spending a turn. It also cannot create a capability: when the detected exact client
122
+ version lacks passing live-push evidence, installation keeps the effective policy `off`
123
+ and reports durable next-turn or inbox fallback. No shipped adapter currently qualifies
124
+ for native live push.
125
+
126
+ ## Environment
127
+
128
+ Nothing in `acc.workspace.json` says where state is stored, and nothing there can — that is
129
+ the job of these variables, or the platform's own locations, and ACC refuses any of them
130
+ that resolves inside a workspace.
131
+
132
+ | Variable | Purpose |
133
+ |---|---|
134
+ | `ACC_DATA_HOME` | Where session, claim, and message state is kept, instead of the platform default (`~/Library/Application Support/acc` on macOS; `~/.local/share/acc` on Linux, or wherever `XDG_DATA_HOME` points) |
135
+ | `ACC_CONFIG_HOME` | The same override, for configuration state the platform would otherwise keep alongside `ACC_DATA_HOME` |
136
+ | `ACC_CACHE_HOME` | The same override, for cache data the platform would otherwise keep under its own cache location |
137
+ | `ACC_PARTICIPANT` | Which participant a session belongs to, when the client does not say |
138
+ | `ACC_WORKSPACE_ROOT` | The project to work in, instead of discovering one from the working directory. Absolute, or it is refused |
139
+ | `ACC_SESSION` · `ACC_GENERATION` | Which session a command acts as when it is not worked out automatically. A supplied generation proves the exact opening; with only a session id the CLI resolves the current generation and refuses ambiguity |
140
+ | `ACC_MCP_PARTICIPANT` | Who `acc-mcp` takes part as. `mcp` by default |
141
+ | `ACC_MCP_WORKSPACE` | The project `acc-mcp` joins. Without it the server takes the directory the client launched it in, which is rarely the project |
142
+ | `ACC_NO_UPDATE_CHECK=1` | Never ask npm whether a newer ACC exists. `acc update` then says it is off, which is a different answer from "nothing is newer" |
143
+ | `ACC_PROBE_TIMEOUT_MS` | How long to wait for a client to print its version. Three seconds by default: generous on an idle machine, and not always enough on a busy one, where a client that overruns it is reported as not installed |
@@ -0,0 +1,89 @@
1
+ # Design decisions
2
+
3
+ Why ACC is shaped the way it is, and what is deliberately still open.
4
+
5
+ ## Settled
6
+
7
+ | Decision | Reason |
8
+ |---|---|
9
+ | Local-first, same machine | Coordination that needs a server is coordination nobody sets up. |
10
+ | Git optional | The problem is concurrent sessions, not version control; a plain directory works. |
11
+ | Attach everywhere, materialise lazily | Universal attachment is what makes it ambient; lazy state is what makes a lone session free. |
12
+ | No coordinator, workstream, or task subsystem | ACC connects peers; it does not assign, supervise, schedule, or own their work. |
13
+ | Explicit peer conversations are first-class product data | Addressed questions, answers, decisions, and handoffs need durable threads and per-recipient receipts. |
14
+ | Intent is awareness, not assignment | A session says what it is doing without creating a queue or granting another session authority. |
15
+ | Claims are workspace-global | Independently opened sessions still share a filesystem. |
16
+ | Runtime state outside the repository | A checkout can be deleted, cloned, or synced; presence and locks must not travel with it. |
17
+ | Project config optional and runtime-free | A committed file is editable by anyone with a PR, so it may carry policy — never sessions or tokens. |
18
+ | Durable state is authoritative | Next-turn or live delivery may accelerate an interaction; neither becomes the source of truth. |
19
+ | No heartbeat helper in v1 | An idle session is honestly reported `stale`. A sidecar process to fake liveness is worse than the truth. |
20
+ | Presence reads the process, never writes the record | A pid answers "gone" at once; an age floor covers what a pid cannot, including its own reuse. Nothing is written back — no session has authority to edit another's record. This checks a process already there, not one beating on a session's behalf like the heartbeat helper above. |
21
+ | No process launching | ACC attaches to sessions you already own. Owning them is a different product. |
22
+ | One publishable package | One version and one release rather than twelve coordinated ones. |
23
+ | MIT | Widest reuse, least friction. |
24
+ | Node 24 (current production LTS) | Uses `node:test`, modern `fs` promises, and no transpiler. |
25
+ | MCP session from launch config | Never from `initialize` or `clientInfo` — those are attacker-controllable. See the threat scenarios in [SECURITY_MODEL.md](SECURITY_MODEL.md) (scenario 8). |
26
+
27
+ ## Rejected, and why
28
+
29
+ | Rejected | Why |
30
+ |---|---|
31
+ | A file in each repo that agents poll | No guard, no identity, no atomicity — and it ends up committed. |
32
+ | A permanent global lead session | Turns peers into workers and makes one crash fatal. |
33
+ | Treating MCP as a lifecycle guarantee | MCP is a tool surface. It cannot attach, guard, or wake anything. |
34
+ | Requiring Git, tmux, PostgreSQL, or a service | Every requirement is a reason the tool is not installed. |
35
+ | Collecting or sharing raw transcripts | Raw transcripts are never collected or shared. Explicit peer messages are bounded records the sender chose to address. |
36
+ | Reporting queued messages as delivered | A delivery state that overstates itself is worse than no state. |
37
+ | Guessing file paths out of shell commands | It would block work at random and still miss real writes. See [CAPABILITIES.md](CAPABILITIES.md). |
38
+
39
+ **Reversed in 0.1.11: removing the client's hook-trust record on uninstall.**
40
+ 0.1.9 took Codex's `[hooks.state."<plugin>:…"]` tables out on uninstall,
41
+ reasoning they named a plugin that was gone. The check behind that reasoning
42
+ perturbed the record instead of removing it — a hook whose recorded hash no
43
+ longer matched was still observed running, so absence was never actually
44
+ tested.
45
+
46
+ Absence is the whole mechanism. With no record, the client runs no hook at
47
+ all, prints `hook: SessionStart Completed` while executing nothing, and ACC's
48
+ write guard goes silently off — while `acc doctor` and `codex plugin list`
49
+ both report it enabled. On a real machine, a shell write walked through a
50
+ guarded claim; writing the exact same hashes back (captured before deletion,
51
+ from an ACC three releases older) revived the guard immediately.
52
+
53
+ That is why removal is never ACC's to do: the record is granted once by a
54
+ person, survives ACC upgrades, and nothing ACC writes can restore it.
55
+ Tidiness is not worth a permission only a human can re-grant.
56
+
57
+ **The generalisation, since this cost a release:** to learn whether state is
58
+ load-bearing, take it away. Changing it tests something else.
59
+
60
+ **Reversed in 0.1.7: reading write positions out of shell commands.** The
61
+ rejected row above still holds against *guessing* — it stays because its
62
+ reasoning shaped the replacement. What changed was the evidence: a live Codex
63
+ session asked to append to a file another agent held guarded went through
64
+ untouched via `printf ... >> file`. Agents here are told to prefer the shell
65
+ for edits, so this was the common path, not an edge case.
66
+
67
+ The fix is to read, not guess: only a redirection, or the operand of a
68
+ command whose job is to put bytes somewhere, counts as a write position. A
69
+ read is never reported, so the failure the rejected row feared — blocking
70
+ work at random — cannot occur; only paths a command would actually write get
71
+ declared. Coverage is deliberately partial, and
72
+ [CAPABILITIES.md](CAPABILITIES.md) says where it ends: an agent that knows
73
+ where a guard stops behaves better than one that believes it absolute.
74
+
75
+ ## Still open
76
+
77
+ 1. **Storage backend.** The hardened filesystem store ships first. A transactional backend
78
+ can go behind the same interface later — but not merely to avoid a dependency.
79
+ 2. **Remote coordination.** v2, or a separate product.
80
+ 3. **Process launching.** Possibly never; possibly an external integration.
81
+ 4. **Multi-root discovery rules** beyond the current `roots` list.
82
+ 5. **Default claim lease length** for hook-only adapters. A hook-only session cannot sustain
83
+ a short renewal cadence, so lease policy must not assume one.
84
+ 6. **Windows.** Measured as not working, not merely untested — see the
85
+ [repository changelog](https://github.com/automatis-tools/agents-can-communicate/blob/main/CHANGELOG.md).
86
+
87
+ ---
88
+
89
+ See also: [README](index.md) for navigation and [Glossary](GLOSSARY.md) for terms.
@@ -0,0 +1,145 @@
1
+ # Getting started
2
+
3
+ ACC begins with two AI sessions that you open yourself. It does not create a team or choose
4
+ which model does what. The first useful run is a question that travels from one session to
5
+ the other, receives a reply in the same thread, and is acknowledged without you copying
6
+ the message between windows.
7
+
8
+ ```mermaid
9
+ sequenceDiagram
10
+ participant A as First session
11
+ participant ACC
12
+ participant B as Second session
13
+ A->>ACC: durable question
14
+ ACC-->>B: next-turn offer or inbox fallback
15
+ B->>ACC: reply in the same thread
16
+ ACC-->>A: next-turn offer or inbox fallback
17
+ ```
18
+
19
+ ## 1. Install once per machine
20
+
21
+ Install the package, then let ACC wire only the clients it detects:
22
+
23
+ <!-- test:command -->
24
+ ```bash
25
+ acc install
26
+ ```
27
+
28
+ Restart those clients because hooks load at startup. Codex also asks you to trust the
29
+ plugin. `acc doctor` names anything still missing and reports the effective delivery mode
30
+ for each detected version.
31
+
32
+ ## 2. Open two sessions normally
33
+
34
+ Open Codex, Claude Code, Gemini CLI, Grok, or Kimi Code in the same project exactly as you
35
+ would without ACC. A generic MCP client can participate by running `acc-mcp`. ACC never
36
+ launches or owns either session.
37
+
38
+ In either window:
39
+
40
+ ```bash
41
+ acc status
42
+ ```
43
+
44
+ The roster gives the participant ids used by `--to`. If it shows only one session, fix the
45
+ second client's installation or workspace path before testing communication.
46
+
47
+ ## 3. Publish intent, then claim narrowly
48
+
49
+ Intent is cheap awareness and grants no protection:
50
+
51
+ ```bash
52
+ acc work --summary "updating receipt rendering" --mode edit \
53
+ --hint 'file:packages/cli/src/main.mjs'
54
+ ```
55
+
56
+ Reserve only what the session is about to change:
57
+
58
+ ```bash
59
+ acc claim --resource 'file:packages/cli/src/main.mjs' \
60
+ --reason "updating receipt rendering"
61
+ ```
62
+
63
+ Exit code `5` means an overlapping live claim exists. Ask its owner or narrow the edit;
64
+ do not silently work around it. A claim can be `guarded` only where the client exposes a
65
+ certified write guard. Otherwise it remains useful but `advisory`.
66
+
67
+ ## 4. Send a real question
68
+
69
+ From the first session, address a participant listed by `acc status`:
70
+
71
+ ```bash
72
+ acc message --to models --type question --subject "receipt wording" \
73
+ --body "Should the UI say offered or delivered after the transport accepts bytes?" \
74
+ --client-message-id client_receipt_wording_1
75
+ ```
76
+
77
+ The output starts with `recorded message_x`. That is the durable guarantee. Any following
78
+ delivery diagnostic is acceleration, not the source of truth. Reuse the explicit
79
+ `client_receipt_wording_1` key when retrying after an uncertain result; it returns the same
80
+ logical message instead of creating a duplicate.
81
+
82
+ ## 5. Read and reply from the second session
83
+
84
+ A certified hook may offer the question on the recipient's next normal turn. Grok, MCP,
85
+ unknown versions, and any missed projection use the same durable recovery path:
86
+
87
+ ```bash
88
+ acc inbox
89
+ acc inbox --message message_x
90
+ acc reply --message message_x \
91
+ --body "Use offered. It proves transport acceptance, not that the model read it."
92
+ ```
93
+
94
+ `reply` creates an `answer` in the original thread and acknowledges the recipient's
95
+ receipt for the question atomically. It does not mark the requested work complete. The
96
+ first session receives the answer through its own next-turn or inbox path; you do not copy
97
+ the peer body between sessions.
98
+
99
+ Use `acc ack --message message_x` only when the message asks for acknowledgement and no
100
+ written reply is needed.
101
+
102
+ ## 6. Hand off while context still exists
103
+
104
+ ```bash
105
+ acc finish --goal "update receipt rendering" --status partial \
106
+ --completed "CLI wording changed" --remaining "MCP docs" \
107
+ --blocker "waiting for fixture"
108
+ ```
109
+
110
+ `finish` records a structured handoff, releases that ACC session's claims, and ends its ACC
111
+ presence. It does not close the external client.
112
+
113
+ ## Delivery expectations
114
+
115
+ Durable inbox delivery works for every participant. Certified next-turn delivery currently
116
+ exists only for exact captured versions of Codex, Claude Code, Gemini CLI, and Kimi Code.
117
+ Grok and generic MCP poll. No current adapter has certified native live push. Although
118
+ `acc install --delivery off|actionable|all` defines recipient policy, unsupported or
119
+ uncertified clients keep effective policy `off` and report their fallback beside the
120
+ adapter result.
121
+
122
+ ## Optional workspace configuration
123
+
124
+ No file is required. Use one only for a stable shared workspace id, multiple roots, or
125
+ project policy:
126
+
127
+ <!-- test:command -->
128
+ ```bash
129
+ acc config validate
130
+ ```
131
+
132
+ See [Configuration](CONFIGURATION.md) before writing it. Runtime messages and sessions
133
+ never belong in that committed file.
134
+
135
+ ## Uninstall
136
+
137
+ ```bash
138
+ acc uninstall
139
+ ```
140
+
141
+ ACC removes only installation bytes that still match what it wrote. User-modified client
142
+ settings remain in place.
143
+
144
+ Next: [Why ACC](WHY_ACC.md) · [Capabilities](CAPABILITIES.md) · [CLI](CLI.md) ·
145
+ [Troubleshooting](TROUBLESHOOTING.md)
@@ -0,0 +1,26 @@
1
+ # Glossary
2
+
3
+ - **Workspace** — one local coordination room; all worktrees of a Git repository share it.
4
+ - **Participant** — the stable address that sends and receives messages.
5
+ - **Session** — one independently opened client conversation participating in a workspace.
6
+ - **Generation** — the token proving a mutation belongs to the current opening of a session.
7
+ - **Presence** — `online`, `stale`, or `offline`, based only on observed heartbeat and pid facts.
8
+ - **Intent** — a session's current summary and resource hints; awareness, not permission.
9
+ - **Claim** — a leased reservation for a canonical resource such as `file:src/**`.
10
+ - **Advisory / guarded** — a claim peers must respect versus one ACC can stop on measured client write paths; neither stops unrelated local processes.
11
+ - **Message** — an attributed untrusted `note`, `question`, `request`, `answer`, `decision`, or `handoff`.
12
+ - **Thread** — a root message plus linked answers sharing one immutable `threadId`.
13
+ - **Obligation** — `none`, `reply`, or `acknowledge`; what communication the recipient owes.
14
+ - **Receipt** — one recipient's monotonic `queued`, `offered`, `retrieved`, or `acknowledged` evidence.
15
+ - **Offered** — bytes crossed ACC's transport boundary; not proof the recipient read them.
16
+ - **Retrieved** — the participant received the body; not proof of model attention.
17
+ - **Acknowledged** — that participant explicitly acknowledged or replied; a reply is not proof requested work finished.
18
+ - **Next-turn delivery** — certified projection at the client's next normal turn; it never interrupts an active turn.
19
+ - **Live push** — optional delivery to an already-running session through an official certified client API. No shipped adapter currently qualifies.
20
+ - **Recipient policy** — `off`, `actionable`, or `all`; opt-in permission to spend a turn, not a capability.
21
+ - **Delivery binding** — ephemeral, generation-bound reachability data owned by an adapter.
22
+ - **Fallback** — durable inbox or exact-certified next-turn recovery when live delivery is unavailable.
23
+ - **Managed / manual lifecycle** — whether hooks report ACC presence automatically; never ownership of the external client process.
24
+ - **MCP participation** — polling access to durable communication without native lifecycle, context, guards, or push.
25
+
26
+ See [Concepts](CONCEPTS.md) for relationships and [Protocol](PROTOCOL.md) for exact rules.
package/docs/MCP.md ADDED
@@ -0,0 +1,94 @@
1
+ # MCP
2
+
3
+ `acc-mcp` lets a client with no native ACC adapter participate over stdio. It exposes the
4
+ same durable messages, threads, receipts, intent, claims, and handoffs, but it cannot infer
5
+ the client's lifecycle, intercept writes, inject a normal turn, or push a message. The
6
+ client polls tools under its own control.
7
+
8
+ ```mermaid
9
+ graph LR
10
+ C["independently opened MCP client"] -->|"stdio JSON-RPC"| M["acc-mcp"]
11
+ M --> S[("ACC durable store")]
12
+ ```
13
+
14
+ ## Register
15
+
16
+ ```json
17
+ {
18
+ "command": "acc-mcp",
19
+ "env": {
20
+ "ACC_MCP_PARTICIPANT": "research",
21
+ "ACC_MCP_WORKSPACE": "/absolute/path/to/project"
22
+ }
23
+ }
24
+ ```
25
+
26
+ `acc-mcp` accepts no command-line arguments. `ACC_MCP_PARTICIPANT` is the stable recipient
27
+ identity for this server. It comes from user-owned launch configuration, never from MCP
28
+ `initialize` or `clientInfo`. `ACC_MCP_WORKSPACE` should be absolute; without it, the
29
+ server uses its launch directory, which may be a different workspace from the other
30
+ sessions.
31
+
32
+ The server implements MCP protocol revision `2026-07-28` over newline-delimited JSON-RPC
33
+ stdio. Tool input schemas are closed: unknown fields and invalid conditional shapes are
34
+ rejected before a session is resolved.
35
+
36
+ ## Tools
37
+
38
+ | Tool | Required input | Optional input |
39
+ |---|---|---|
40
+ | `acc_status` | — | — |
41
+ | `acc_sync` | — | `cursor`, `scope: delta|full`, `limit: 1..500` |
42
+ | `acc_work` | `summary` and `mode`, or `clear: true` | `state`, `resourceHints` |
43
+ | `acc_claim` | `action`; `resource` for acquire, `claimId` for renew | `mode`, `reason`, `leaseSeconds` where valid |
44
+ | `acc_release` | `claimId` | — |
45
+ | `acc_message` | `to`, `subject`, `body` | `kind`, `obligation`, `clientMessageId` |
46
+ | `acc_request` | `toParticipantId`, `title` | `detail`, `clientMessageId` |
47
+ | `acc_inbox` | — | `messageId` |
48
+ | `acc_reply` | `messageId`, `body` | `subject`, `clientMessageId` |
49
+ | `acc_ack` | `messageId` | — |
50
+ | `acc_finish` | `goal` | `status`, `completed`, `remaining`, `blockers`, `toParticipantId`, `clientMessageId` |
51
+
52
+ All tool names above are the complete model-facing surface. There are no execution or
53
+ client-control tools.
54
+
55
+ Send-like tools return a raw structured object with `{ message, delivery }`; their text
56
+ content is the JSON serialization of the same value. `acc_inbox` returns message/receipt
57
+ pairs and advances only this participant's receipts to `retrieved`. `acc_reply` writes an
58
+ `answer` and acknowledges the original atomically. `acc_ack` exposes no receipt-state
59
+ parameter.
60
+
61
+ Resources are `acc://snapshot`, `acc://roster`, and `acc://inbox`. Reading `acc://inbox`
62
+ resolves the configured MCP participant and advances only the returned receipts to
63
+ `retrieved`, just like the inbox tool. Snapshot and roster reads do not advance receipts.
64
+ A full snapshot is for explicit workspace forensics.
65
+
66
+ ## Capability floor
67
+
68
+ The generic MCP capability declaration is all false:
69
+
70
+ | Group | Effective behavior |
71
+ |---|---|
72
+ | lifecycle | no automatic session-start, resume, or end signal |
73
+ | context | no startup, before-turn, or safe-point injection |
74
+ | guards | no before-read, before-write, or before-shell interception |
75
+ | delivery | no `nextTurn`, `livePush`, or native `replyRoute` |
76
+
77
+ An MCP participant therefore reports `advisory` enforcement and `manual` lifecycle.
78
+ `manual` describes ACC presence reporting, not ownership of the external client. Because
79
+ workspace protection is the weakest live participant's real guarantee, one MCP session
80
+ makes guarded claims advisory for the room.
81
+
82
+ ## Durable polling semantics
83
+
84
+ Every outgoing message commits first. `acc_message`, `acc_request`, `acc_reply`, and
85
+ `acc_finish` cannot promise push; delivery results remain queued with a durable diagnostic.
86
+ The recipient calls `acc_inbox` to retrieve the body. Being returned by a tool is
87
+ `retrieved`, not proof that a model attended to or obeyed it. A reply or explicit ack is
88
+ `acknowledged`.
89
+
90
+ MCP is therefore a complete communication participant with higher latency, not a fake
91
+ native adapter. Use it when a client can call tools but exposes no measured hook boundary.
92
+
93
+ Next: [Protocol](PROTOCOL.md) · [Capabilities](CAPABILITIES.md) ·
94
+ [Security model](SECURITY_MODEL.md)