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.
- package/README.md +112 -91
- package/SECURITY.md +8 -5
- package/bin/acc-bootstrap.mjs +5 -54
- package/bin/acc-claude-channel.mjs +8 -175
- package/bin/acc-hook.mjs +4 -133
- package/bin/acc-mcp.mjs +4 -59
- package/bin/acc-update-worker.mjs +8 -0
- package/bin/acc.mjs +5 -39
- package/bin/entrypoints/acc-bootstrap.mjs +47 -0
- package/bin/entrypoints/acc-claude-channel.mjs +149 -0
- package/bin/entrypoints/acc-hook.mjs +58 -0
- package/bin/entrypoints/acc-mcp.mjs +70 -0
- package/bin/entrypoints/acc.mjs +51 -0
- package/bin/entrypoints/claude-channel-stdio.mjs +29 -0
- package/bin/entrypoints/hook-output.mjs +73 -0
- package/docs/ADAPTER_AUTHORING.md +62 -24
- package/docs/ARCHITECTURE.md +79 -20
- package/docs/CAPABILITIES.md +52 -30
- package/docs/CLI.md +164 -35
- package/docs/CONCEPTS.md +97 -93
- package/docs/CONFIGURATION.md +66 -45
- package/docs/DESIGN_DECISIONS.md +24 -15
- package/docs/GETTING_STARTED.md +124 -118
- package/docs/GLOSSARY.md +12 -6
- package/docs/HOW_IT_WORKS.md +136 -229
- package/docs/MCP.md +98 -31
- package/docs/PROTOCOL.md +76 -14
- package/docs/RELEASING.md +128 -86
- package/docs/SECURITY_MODEL.md +52 -15
- package/docs/TROUBLESHOOTING.md +88 -18
- package/docs/UPGRADING.md +119 -0
- package/docs/WHY_ACC.md +19 -16
- package/docs/index.md +40 -24
- package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/plugin/skills/acc/SKILL.md +112 -9
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/install.mjs +6 -6
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/native-delivery.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-codex/certification.json +38 -13
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/certification-provenance.json +220 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-current-binding-product-evidence.json +1549 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-current-binding-product.json +27 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-product-evidence.json +1549 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-product.json +27 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-transport-evidence.json +259 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.152.1-local-daemon-transport.json +21 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-current-binding-product-evidence.json +1549 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-current-binding-product.json +27 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-product-evidence.json +1549 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-product.json +27 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-transport-evidence.json +259 -0
- package/node_modules/@agents-can-communicate/adapter-codex/fixtures/delivery/codex-cli-0.153.4-local-daemon-transport.json +21 -0
- package/node_modules/@agents-can-communicate/adapter-codex/package.json +14 -2
- package/node_modules/@agents-can-communicate/adapter-codex/plugin/skills/acc/SKILL.md +111 -8
- package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +26 -44
- package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +70 -17
- package/node_modules/@agents-can-communicate/adapter-codex/src/config-block.mjs +231 -0
- package/node_modules/@agents-can-communicate/adapter-codex/src/hooks.mjs +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/install.mjs +71 -63
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +107 -103
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-endpoint.mjs +96 -0
- package/node_modules/@agents-can-communicate/adapter-codex/src/ws-json-rpc.mjs +3 -2
- 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 +111 -8
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/install.mjs +2 -2
- 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 +111 -8
- package/node_modules/@agents-can-communicate/adapter-grok/src/install.mjs +2 -2
- 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 +111 -8
- package/node_modules/@agents-can-communicate/adapter-kimi/src/hooks.mjs +1 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/src/install.mjs +2 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +5 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/context-projector.mjs +26 -4
- package/node_modules/@agents-can-communicate/adapter-sdk/src/decision-text.mjs +19 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +5 -3
- package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +1 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-delivery.mjs +9 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-vocabulary.mjs +2 -6
- package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +29 -9
- package/node_modules/@agents-can-communicate/adapter-sdk/src/toml-block.mjs +8 -6
- package/node_modules/@agents-can-communicate/cli/package.json +4 -2
- package/node_modules/@agents-can-communicate/cli/src/args.mjs +49 -22
- package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +11 -4
- package/node_modules/@agents-can-communicate/cli/src/git-probe.mjs +9 -3
- package/node_modules/@agents-can-communicate/cli/src/help.mjs +109 -14
- package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +66 -18
- package/node_modules/@agents-can-communicate/cli/src/main.mjs +35 -12
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/activation.mjs +110 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/command.mjs +63 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/download.mjs +71 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/entry.mjs +110 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation.mjs +167 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/install.mjs +73 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +60 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/leases.mjs +60 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/location.mjs +55 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/mutex.mjs +145 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/policy.mjs +4 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/refresh.mjs +40 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/schedule.mjs +21 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/state.mjs +122 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/worker.mjs +65 -0
- package/node_modules/@agents-can-communicate/cli/src/session-owner.mjs +33 -108
- package/node_modules/@agents-can-communicate/cli/src/update-command.mjs +25 -7
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- package/node_modules/@agents-can-communicate/core/src/attention.mjs +3 -0
- package/node_modules/@agents-can-communicate/core/src/claims.mjs +13 -8
- package/node_modules/@agents-can-communicate/core/src/conversations.mjs +48 -24
- package/node_modules/@agents-can-communicate/core/src/decision-changes.mjs +36 -0
- package/node_modules/@agents-can-communicate/core/src/decision-state.mjs +42 -0
- package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +11 -4
- package/node_modules/@agents-can-communicate/core/src/inbox.mjs +48 -17
- package/node_modules/@agents-can-communicate/core/src/intents.mjs +35 -15
- package/node_modules/@agents-can-communicate/core/src/materialisation.mjs +7 -5
- package/node_modules/@agents-can-communicate/core/src/message-pages.mjs +75 -0
- package/node_modules/@agents-can-communicate/core/src/next-turn-delivery.mjs +31 -0
- package/node_modules/@agents-can-communicate/core/src/session-opening.mjs +128 -0
- package/node_modules/@agents-can-communicate/core/src/sessions.mjs +58 -132
- package/node_modules/@agents-can-communicate/core/src/sync.mjs +31 -2
- package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
- package/node_modules/@agents-can-communicate/delivery-router/src/refresh-binding.mjs +38 -0
- package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +86 -10
- package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
- package/node_modules/@agents-can-communicate/hook-runner/src/client-version.mjs +1 -0
- package/node_modules/@agents-can-communicate/hook-runner/src/native-binding.mjs +6 -4
- package/node_modules/@agents-can-communicate/hook-runner/src/native-retirement.mjs +48 -0
- package/node_modules/@agents-can-communicate/hook-runner/src/process-table.mjs +1 -1
- package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +175 -67
- package/node_modules/@agents-can-communicate/hook-runner/src/session-lifecycle.mjs +13 -0
- package/node_modules/@agents-can-communicate/installer/package.json +4 -2
- package/node_modules/@agents-can-communicate/installer/src/apply.mjs +17 -2
- package/node_modules/@agents-can-communicate/installer/src/bootstrap-runtime.mjs +11 -5
- package/node_modules/@agents-can-communicate/installer/src/detect.mjs +1 -1
- package/node_modules/@agents-can-communicate/installer/src/index.mjs +1 -0
- package/node_modules/@agents-can-communicate/installer/src/live-policy.mjs +21 -0
- package/node_modules/@agents-can-communicate/installer/src/native-activation.mjs +20 -6
- package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +10 -4
- package/node_modules/@agents-can-communicate/installer/src/plan.mjs +3 -3
- package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
- package/node_modules/@agents-can-communicate/mcp-server/src/protocol.mjs +85 -0
- package/node_modules/@agents-can-communicate/mcp-server/src/resources.mjs +3 -2
- package/node_modules/@agents-can-communicate/mcp-server/src/server.mjs +59 -57
- package/node_modules/@agents-can-communicate/mcp-server/src/tools.mjs +47 -33
- package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
- package/node_modules/@agents-can-communicate/protocol/src/conversations.mjs +3 -0
- package/node_modules/@agents-can-communicate/protocol/src/decision-changes.mjs +15 -0
- package/node_modules/@agents-can-communicate/protocol/src/index.mjs +3 -1
- package/node_modules/@agents-can-communicate/protocol/src/schema.mjs +14 -5
- package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
- package/node_modules/@agents-can-communicate/storage-filesystem/src/atomic-json.mjs +5 -1
- package/node_modules/@agents-can-communicate/storage-filesystem/src/deadline.mjs +7 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index.mjs +2 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/session-read.mjs +25 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +28 -25
- package/package.json +2 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Workspace-free MCP fallback shared by composition and managed admission failure.
|
|
2
|
+
import { createInertChannel } from "@agents-can-communicate/adapter-claude-code/channel";
|
|
3
|
+
|
|
4
|
+
export function startInertChannel({ write = payload => process.stdout.write(JSON.stringify(payload) + "\n") } = {}) {
|
|
5
|
+
const inert = createInertChannel({ write });
|
|
6
|
+
pump(inert.handleLine, () => process.exit(0));
|
|
7
|
+
return inert;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** One line-delimited JSON pump, for the bound server and the unbound one alike. */
|
|
11
|
+
export function pump(handleLine, shutdown) {
|
|
12
|
+
let buffer = "";
|
|
13
|
+
process.stdin.setEncoding("utf8");
|
|
14
|
+
process.stdin.on("data", async chunk => {
|
|
15
|
+
buffer += chunk;
|
|
16
|
+
let newline = buffer.indexOf("\n");
|
|
17
|
+
while (newline !== -1) {
|
|
18
|
+
const line = buffer.slice(0, newline).trim();
|
|
19
|
+
buffer = buffer.slice(newline + 1);
|
|
20
|
+
newline = buffer.indexOf("\n");
|
|
21
|
+
if (line !== "") await handleLine(line);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
process.stdin.on("end", shutdown);
|
|
25
|
+
process.once("SIGTERM", shutdown);
|
|
26
|
+
process.once("SIGINT", shutdown);
|
|
27
|
+
// Keeps the child answerable for as long as Claude holds the transport open.
|
|
28
|
+
process.stdin.resume();
|
|
29
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export const writeOutput = (stream, output, { deadlineAt } = {}) => {
|
|
2
|
+
if (output === "") return Promise.resolve();
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
let settled = false;
|
|
5
|
+
let timer;
|
|
6
|
+
const finish = error => {
|
|
7
|
+
if (settled) return;
|
|
8
|
+
settled = true;
|
|
9
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
10
|
+
if (error === undefined || error === null) resolve();
|
|
11
|
+
else reject(error);
|
|
12
|
+
};
|
|
13
|
+
if (deadlineAt !== undefined) {
|
|
14
|
+
const remaining = deadlineAt - Date.now();
|
|
15
|
+
if (remaining <= 0) {
|
|
16
|
+
finish(new Error("hook budget exhausted before stdout write"));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
timer = setTimeout(() => finish(
|
|
20
|
+
new Error("hook budget exhausted waiting for stdout callback")), remaining);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
stream.write(output, finish);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
finish(error);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const DIAGNOSTIC_BYTES = 512;
|
|
31
|
+
|
|
32
|
+
function boundedDiagnostic(label, error) {
|
|
33
|
+
const detail = String(error?.message ?? error).replace(/[\u0000-\u001f\u007f]/g, " ");
|
|
34
|
+
let line = `acc: ${label}: ${detail}`;
|
|
35
|
+
while (Buffer.byteLength(`${line}\n`, "utf8") > DIAGNOSTIC_BYTES && line.length > 0) {
|
|
36
|
+
line = line.slice(0, -1);
|
|
37
|
+
}
|
|
38
|
+
return `${line}\n`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function tryWrite(stream, output) {
|
|
42
|
+
if (output === "") return;
|
|
43
|
+
try {
|
|
44
|
+
stream.write(output, () => {});
|
|
45
|
+
} catch {
|
|
46
|
+
// A broken diagnostic stream must not turn a failed-open hook into a crash.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function completeHookOutput(result,
|
|
51
|
+
{ stdout = process.stdout, stderr = process.stderr } = {}) {
|
|
52
|
+
if (result.failed || result.timedOut) {
|
|
53
|
+
// Hook failures can include arbitrary payload or filesystem text. Report
|
|
54
|
+
// degradation without reflecting those details into the client's output.
|
|
55
|
+
tryWrite(stderr, "acc: coordination unavailable; hook continued without context\n");
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
await writeOutput(stdout, result.stdout ?? "", { deadlineAt: result.deadlineAt });
|
|
59
|
+
} catch (error) {
|
|
60
|
+
tryWrite(stderr, boundedDiagnostic("stdout write failed", error));
|
|
61
|
+
return { exitCode: 0, wroteStdout: false, committedOffers: false };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let committedOffers = true;
|
|
65
|
+
try {
|
|
66
|
+
await result.commitOffers?.();
|
|
67
|
+
} catch (error) {
|
|
68
|
+
committedOffers = false;
|
|
69
|
+
tryWrite(stderr, boundedDiagnostic("offer commit failed", error));
|
|
70
|
+
}
|
|
71
|
+
if (result.stderr) tryWrite(stderr, `${result.stderr}\n`);
|
|
72
|
+
return { exitCode: 0, wroteStdout: true, committedOffers };
|
|
73
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Writing an adapter
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Use this page to add one client without leaking vendor behavior into core. Start with the
|
|
4
|
+
[identity contract](PROTOCOL.md#identity), then compare the shipped evidence under
|
|
5
|
+
[certified support](CAPABILITIES.md#certified-support). The [documentation map](index.md)
|
|
6
|
+
links the surrounding concepts and runtime architecture.
|
|
7
7
|
|
|
8
8
|
```mermaid
|
|
9
9
|
graph LR
|
|
@@ -14,7 +14,7 @@ graph LR
|
|
|
14
14
|
R --> H
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Define the manifest
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
export function createExampleAdapter() {
|
|
@@ -28,6 +28,7 @@ export function createExampleAdapter() {
|
|
|
28
28
|
|
|
29
29
|
detect, install, uninstall, doctor,
|
|
30
30
|
planInstall, // what install would write
|
|
31
|
+
preflightUninstall, // optional read-only removal validation
|
|
31
32
|
normalizeHook, // client payload -> normalised event
|
|
32
33
|
renderContext, // SyncResult -> text
|
|
33
34
|
renderContextResult, // text + ids of complete rendered groups
|
|
@@ -36,9 +37,14 @@ export function createExampleAdapter() {
|
|
|
36
37
|
}
|
|
37
38
|
```
|
|
38
39
|
|
|
40
|
+
`preflightUninstall(context)` is optional and read-only. Throw to refuse unsafe
|
|
41
|
+
removal before the installer deactivates native integration or deletes recorded
|
|
42
|
+
artifacts. `uninstall` should retain its own validation for direct adapter callers;
|
|
43
|
+
recorded artifact fingerprint checks still determine the `keep` paths it receives.
|
|
44
|
+
|
|
39
45
|
`renderContextResult` is required wherever an adapter renders peer messages. It returns
|
|
40
|
-
`{ text,
|
|
41
|
-
lifecycle](PROTOCOL.md#
|
|
46
|
+
`{ text, offeredMessageIds, includedAttentionIds }`, and the [receipt
|
|
47
|
+
lifecycle](PROTOCOL.md#receipt-lifecycle) advances only from those ids — never by searching
|
|
42
48
|
`text` for one, because peer text is untrusted and can imitate another message's header.
|
|
43
49
|
`projectContextResult()` implements this contract; `projectContext()` remains the text-only
|
|
44
50
|
convenience API for adapters that don't need it. An adapter with only the older
|
|
@@ -46,6 +52,12 @@ convenience API for adapters that don't need it. An adapter with only the older
|
|
|
46
52
|
instead: repeating an untracked body every turn would be quieter in code and dishonest about
|
|
47
53
|
what was actually delivered.
|
|
48
54
|
|
|
55
|
+
The hook also supplies `reminderMessageIds`, derived from this participant's `offered` or
|
|
56
|
+
`retrieved` receipts with unresolved obligations. The standard projector combines those
|
|
57
|
+
reply/acknowledgement attention items into counts after new bodies. A missing body alone
|
|
58
|
+
is not evidence for compaction. Counts add no ids to `offeredMessageIds` or
|
|
59
|
+
`includedAttentionIds`; complete inbox and status results remain available.
|
|
60
|
+
|
|
49
61
|
`client.command` does double duty. `detect.mjs` uses it as the version-probe binary, and
|
|
50
62
|
presence liveness separately walks the hook's process ancestry for the first ancestor whose
|
|
51
63
|
executable basename matches it, to learn the client's own pid. Declare the binary the client
|
|
@@ -53,7 +65,7 @@ actually runs as — `command: "claude"` for a client that really runs as `node`
|
|
|
53
65
|
nothing, and the failure is silent: the session gets `pid: null` and falls back to reading
|
|
54
66
|
presence by age alone, with nothing telling you why.
|
|
55
67
|
|
|
56
|
-
##
|
|
68
|
+
## Declare only proven capabilities
|
|
57
69
|
|
|
58
70
|
Fourteen booleans in four groups, declared in the manifest's `capabilities` object:
|
|
59
71
|
|
|
@@ -68,7 +80,8 @@ Fourteen booleans in four groups, declared in the manifest's `capabilities` obje
|
|
|
68
80
|
`defineAdapter` enforces the method — declaring `guards.beforeWrite: true` without
|
|
69
81
|
`guardWrite()` is a usage error at construction. It also requires a passing entry in the
|
|
70
82
|
validated `certification.json`; method existence is never evidence. What each shipped
|
|
71
|
-
client was actually observed doing against this list is
|
|
83
|
+
client was actually observed doing against this list is under
|
|
84
|
+
[certified support](CAPABILITIES.md#certified-support).
|
|
72
85
|
|
|
73
86
|
`lifecycle.heartbeat` is deliberately not a flavour of `delivery.nextTurn`. Next-turn
|
|
74
87
|
delivery happens only when the client reaches a normal turn boundary; heartbeat fires on a
|
|
@@ -118,24 +131,48 @@ The rules `defineAdapter` enforces, and the ones the runtime applies:
|
|
|
118
131
|
when numerically newer. `knownBad` names exact versions or inclusive intervals.
|
|
119
132
|
- Exact-version certification still governs every non-native capability;
|
|
120
133
|
`effectiveCapabilities()` is unchanged. The native rule is used for live delivery alone.
|
|
121
|
-
-
|
|
134
|
+
- Native methods return closed facts (`validateNativeActivationPlan()` closes the
|
|
122
135
|
activation plan) and never put vendor data - endpoints, sockets, raw errors - into core.
|
|
123
136
|
|
|
124
|
-
|
|
137
|
+
`nativeDelivery.policySource` defaults to the session environment. An adapter may
|
|
138
|
+
declare `"installation-record"` when hooks and senders must read current recorded
|
|
139
|
+
recipient consent independently of the vendor process environment. Installation
|
|
140
|
+
records the requested policy even when current activation is unavailable. An absent
|
|
141
|
+
or invalid record means `off`; a previously published binding cannot override it.
|
|
142
|
+
|
|
143
|
+
The optional `refreshNativeSession()` method may revalidate an expired lease before
|
|
144
|
+
an offer. It returns the same closed handshake shape as `bindNativeSession()` and
|
|
145
|
+
must preserve the exact endpoint and protocol identity. The router rechecks the
|
|
146
|
+
current session, generation, retirement, uniqueness and policy before publishing
|
|
147
|
+
the refreshed lease. Refresh is not a heartbeat and cannot extend presence beyond
|
|
148
|
+
its own expiry. Optional `retireNativeSession()` cleans adapter-owned endpoint state
|
|
149
|
+
after confirmed core retirement; it must remain bounded and fail open for hooks.
|
|
150
|
+
|
|
151
|
+
A package-shipped passing Codex installed-hook capture additionally references its
|
|
152
|
+
complete real product matrix through the selected provenance record's
|
|
153
|
+
`productEvidence: { fixture, sha256 }`. Package verification checks the actual file,
|
|
154
|
+
raw digest and client/version/platform/package identity. A transport-only capture
|
|
155
|
+
cannot certify the installed product route. `historicalFixtures` may retain hashed
|
|
156
|
+
earlier failures without duplicating a certification tuple.
|
|
157
|
+
|
|
158
|
+
## Choose the integration depth
|
|
125
159
|
|
|
126
160
|
| Tier | You register | You get | You do not get |
|
|
127
161
|
|---|---|---|---|
|
|
128
162
|
| 0 | nothing — humans run `acc` | durable messages, status, claims | anything automatic |
|
|
129
163
|
| 1 | the MCP server | attach on first call, read, claim, message | guards, session end |
|
|
130
|
-
| 2 | hooks + skill |
|
|
131
|
-
| 3 | +
|
|
164
|
+
| 2 | hooks + skill | only the lifecycle, context, guard, and next-turn behaviors separately captured for this client | uncaptured hook behaviors |
|
|
165
|
+
| 3 | + native delivery surface | only captured live-push and reply-route modes | safe-point injection or child sessions unless separately captured |
|
|
132
166
|
|
|
133
|
-
Installed hook wiring may reach tier 2, but
|
|
134
|
-
|
|
135
|
-
2.1.258 and Codex 0.152.1 on
|
|
136
|
-
|
|
167
|
+
Installed hook wiring may reach tier 2, but each effective hook capability still
|
|
168
|
+
requires exact client/version/platform evidence. Tier 3 has separate native
|
|
169
|
+
contracts: Claude Code Channel from 2.1.258 and Codex LocalDaemon from 0.152.1 on
|
|
170
|
+
macOS arm64, with current probes and exact session handshakes. Codex's earlier
|
|
171
|
+
remote-wrapper failure remains historical evidence. Ordinary launch now preserves
|
|
172
|
+
workspace identity; the full installed product matrix, including negative controls
|
|
173
|
+
and fallback, backs its native claim.
|
|
137
174
|
|
|
138
|
-
##
|
|
175
|
+
## Normalize hook input
|
|
139
176
|
|
|
140
177
|
Whitelist, never a filter. Every client hands hooks the prompt, the transcript path, or the
|
|
141
178
|
tool output; none of it may survive.
|
|
@@ -151,7 +188,7 @@ return normalizedEvent({
|
|
|
151
188
|
Refuse an unrecognised payload. Inventing a session attaches the wrong one, or a new one
|
|
152
189
|
every hook, and looks like it is working.
|
|
153
190
|
|
|
154
|
-
##
|
|
191
|
+
## Measure response contracts
|
|
155
192
|
|
|
156
193
|
Measure them. Every client differs, and a wrong shape fails **silently**:
|
|
157
194
|
|
|
@@ -166,10 +203,11 @@ Measure them. Every client differs, and a wrong shape fails **silently**:
|
|
|
166
203
|
`denyOutcome(reason)` returns `{ stdout, stderr, exitCode }`, so the runtime never has to
|
|
167
204
|
know which client it is talking to. This table is only the shape each shipped adapter
|
|
168
205
|
actually uses; the full experimental grid — every candidate shape tried against every
|
|
169
|
-
client, including which ones are silently ignored — is
|
|
170
|
-
|
|
206
|
+
client, including which ones are silently ignored — is recorded in each adapter's
|
|
207
|
+
`COMPATIBILITY.md` and certification fixtures. The cross-client summary is under
|
|
208
|
+
[guard limitations](CAPABILITIES.md#guard-limitations).
|
|
171
209
|
|
|
172
|
-
##
|
|
210
|
+
## Preserve install ownership
|
|
173
211
|
|
|
174
212
|
```mermaid
|
|
175
213
|
graph TB
|
|
@@ -188,7 +226,7 @@ Rules that are not negotiable:
|
|
|
188
226
|
`planInstall` must use the same path helpers as `install`. A conformance test compares
|
|
189
227
|
them, because a plan that drifts makes `--dry-run` a decoration.
|
|
190
228
|
|
|
191
|
-
##
|
|
229
|
+
## Run conformance
|
|
192
230
|
|
|
193
231
|
```bash
|
|
194
232
|
node --test tests/conformance/*.test.mjs
|
|
@@ -198,7 +236,7 @@ node --test tests/process/hook-wiring.test.mjs
|
|
|
198
236
|
The second one *executes* what your install wrote. Three adapters once shipped a hook
|
|
199
237
|
command that did not exist anywhere; every test was green.
|
|
200
238
|
|
|
201
|
-
## Record
|
|
239
|
+
## Record the evidence
|
|
202
240
|
|
|
203
241
|
One `COMPATIBILITY.md` per adapter: client version, event names, payload fields, the deny
|
|
204
242
|
matrix, and what you could **not** observe. The next person's alternative is guessing.
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Architecture
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Use this page to trace a communication fact from an independently opened client through
|
|
4
|
+
core, storage, and an optional delivery adapter. ACC is the local control plane; the AI
|
|
5
|
+
clients remain independent execution planes. Core records the truth before an adapter is
|
|
6
|
+
asked to make it arrive sooner.
|
|
6
7
|
|
|
7
8
|
```mermaid
|
|
8
9
|
flowchart LR
|
|
@@ -41,7 +42,7 @@ The order is part of the public guarantee:
|
|
|
41
42
|
|
|
42
43
|
1. validate and commit the message plus one `queued` receipt per resolved recipient;
|
|
43
44
|
2. resolve the recipient's current delivery bindings;
|
|
44
|
-
3. check recipient policy
|
|
45
|
+
3. check recipient policy and the current binding's reachability and offered native mode;
|
|
45
46
|
4. ask one adapter to cross its transport boundary;
|
|
46
47
|
5. only after acceptance, commit `offered` and an immutable success event.
|
|
47
48
|
|
|
@@ -71,16 +72,21 @@ lease without exposing the endpoint.
|
|
|
71
72
|
|
|
72
73
|
## Certified capability versus current reachability
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
Ordinary hook capabilities say an exact client version on an exact platform passed a
|
|
76
|
+
captured behavior. Native live delivery uses a separate contract: installation checks the
|
|
77
|
+
captured minimum, platform, and current feature probe, then each session publishes a binding
|
|
78
|
+
only after a generation-bound handshake. The router trusts that admission and verifies the
|
|
79
|
+
binding, recipient policy, declared adapter capability, and adapter response; it does not add
|
|
80
|
+
a third exact-version certification check. A binding says what that current generation
|
|
81
|
+
exposes and whether its lease is current, while recipient policy says whether it may spend a
|
|
82
|
+
turn.
|
|
83
|
+
|
|
84
|
+
Claude Code Channel has installed-client evidence on 2.1.258 and 2.1.260; Codex
|
|
85
|
+
LocalDaemon has it on 0.152.1 and 0.153.4. Both use a captured platform minimum,
|
|
86
|
+
current probe and exact session handshake. Codex preserves the ordinary client
|
|
87
|
+
launch and verifies its registered thread and workspace; ACC owns no vendor daemon
|
|
88
|
+
lifecycle. Gemini CLI and Kimi Code have exact-version next-turn evidence only;
|
|
89
|
+
Grok and generic MCP use inbox polling.
|
|
84
90
|
|
|
85
91
|
## Storage and workspace identity
|
|
86
92
|
|
|
@@ -90,20 +96,34 @@ lexically, so a cursor is simply the last sequence returned.
|
|
|
90
96
|
|
|
91
97
|
Workspace discovery checks an explicit config first, then the Git common directory, then
|
|
92
98
|
the plain directory. Multiple worktrees share a workspace id while each session records
|
|
93
|
-
its checkout and branch.
|
|
99
|
+
its checkout and branch. Runtime state never lands inside those roots; the only project
|
|
100
|
+
file ACC writes is an optional `acc.workspace.json` explicitly requested through
|
|
101
|
+
`acc config init`.
|
|
94
102
|
|
|
95
103
|
A lone session can remain ephemeral. Durable state materialises when a second live session
|
|
96
|
-
appears or the first claim, message, or handoff is committed.
|
|
97
|
-
|
|
104
|
+
appears or the first claim, message, or handoff is committed. Solo presence therefore
|
|
105
|
+
does not require durable workspace history. Native turn hooks still supply the session's
|
|
106
|
+
own CLI arguments, so a peer joining later in the same turn does not require reattachment.
|
|
107
|
+
Without relevant coordination context, that identity header is the only projected content.
|
|
98
108
|
|
|
99
109
|
## Inbox, attention, and projection
|
|
100
110
|
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
Public inbox discovery uses core `listInbox`: bounded, read-only message summaries
|
|
112
|
+
addressed to the current participant. Exact body reads use `readInbox` and advance only
|
|
113
|
+
that participant's receipt to `retrieved`; the embedded core API still supports bulk
|
|
114
|
+
retrieval. History sync reads message records without receipt changes, using the same
|
|
115
|
+
summary pager or one exact id. Reply validates ownership, creates an `answer` in the
|
|
103
116
|
same thread, and acknowledges the original atomically. No participant can advance another
|
|
104
117
|
participant's receipt.
|
|
105
118
|
|
|
106
|
-
|
|
119
|
+
Decision lifecycle is derived from immutable message links, without a new record kind
|
|
120
|
+
or mutable decision store. Read copies carry bounded status; raw forensic snapshots stay
|
|
121
|
+
unchanged. Non-head decisions leave pending inbox, bulk delivery, and attention while
|
|
122
|
+
exact reads retain them. Replacement/withdrawal records inherit recipients before commit,
|
|
123
|
+
so offline readers receive the change without a forged acknowledgement. See
|
|
124
|
+
[the protocol contract](PROTOCOL.md#decision-lifecycle).
|
|
125
|
+
|
|
126
|
+
Attention is computed from six explicit rules for current obligations:
|
|
107
127
|
|
|
108
128
|
| Priority | Kind | Observable trigger |
|
|
109
129
|
|---|---|---|
|
|
@@ -121,6 +141,14 @@ Adapters project peer bodies in an attributed untrusted frame. If a complete bod
|
|
|
121
141
|
fit, the projection keeps the message id and points to `acc inbox --message <id>` instead
|
|
122
142
|
of silently truncating it.
|
|
123
143
|
|
|
144
|
+
For this participant's unresolved messages already `offered` or `retrieved`, the standard
|
|
145
|
+
projector combines reply and acknowledgement reminders into a compact count after new
|
|
146
|
+
message bodies. Queued obligations and claim conflicts remain individual attention items.
|
|
147
|
+
All pending headers stay discoverable through `acc inbox` pages; owned `acc status` retains
|
|
148
|
+
its complete attention list. Full bodies require an exact inbox read; projection
|
|
149
|
+
does not acknowledge or delete records. Explicit decision links, rather than the
|
|
150
|
+
projector or message age, retire old decision obligations.
|
|
151
|
+
|
|
124
152
|
## Hooks fail open
|
|
125
153
|
|
|
126
154
|
Hook execution is bounded. If coordination state cannot be read or a decision cannot be
|
|
@@ -129,3 +157,34 @@ it, but a coordination tool must not be the reason a session stops working.
|
|
|
129
157
|
|
|
130
158
|
Next: [Protocol](PROTOCOL.md) · [Capabilities](CAPABILITIES.md) ·
|
|
131
159
|
[Security model](SECURITY_MODEL.md)
|
|
160
|
+
|
|
161
|
+
## Managed runtime activation
|
|
162
|
+
|
|
163
|
+
The CLI owns installation generations under `<dataHome>/acc/runtime`, outside workspaces.
|
|
164
|
+
All five launch paths select a generation and publish an actual-process lease under one
|
|
165
|
+
admission mutex before loading workspace-capable code. Immutable launcher modules and
|
|
166
|
+
runtime directories preserve in-progress imports. Leases survive `main()` returning and
|
|
167
|
+
are removed only after confirmed process death. Parsed help, version, and update recovery
|
|
168
|
+
remain available when workspace admission is unavailable.
|
|
169
|
+
|
|
170
|
+
An independent worker downloads npm packages with lifecycle scripts disabled, checks exact
|
|
171
|
+
stable package identity and the discovered integrity, and health-checks the staged runtime.
|
|
172
|
+
Installer detection and planning happen before exclusive admission. The worker then checks
|
|
173
|
+
ACC process leases and native binding PIDs, records `activating`, applies every integration,
|
|
174
|
+
and only publishes the new active pointer after all applications succeed. Partial refresh
|
|
175
|
+
remains fenced and repairs forward, with the old active pointer retained but normal
|
|
176
|
+
workspace admission unavailable until recovery completes. Native bindings cease holding
|
|
177
|
+
after observed SessionEnd cleanup or confirmed process death; the vendor daemon may remain
|
|
178
|
+
running. Unknown PIDs remain holds until lifecycle cleanup. Presence TTL, `acc finish`,
|
|
179
|
+
and delivery off alone do not prove native lifecycle end. ACC never manages the daemon.
|
|
180
|
+
|
|
181
|
+
Lock ownership never expires by age. Retained nonempty tombstones prevent delayed observers
|
|
182
|
+
from reclaiming a successor. Under an acquired lock, maintenance removes historical
|
|
183
|
+
bookkeeping only when no live or unknown contender could still reference it; a stopped
|
|
184
|
+
contender postpones cleanup. Admission also removes confirmed-dead process leases. None of
|
|
185
|
+
this metadata is agent conversation history or injected context.
|
|
186
|
+
|
|
187
|
+
The first upgrade from an unmanaged binary still requires a restart. ACC cannot fence old
|
|
188
|
+
direct binaries or external applications importing core. Native trust and client-side cache
|
|
189
|
+
activation remain vendor responsibilities; refreshed files do not establish observed
|
|
190
|
+
capabilities.
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Capabilities
|
|
2
2
|
|
|
3
|
+
Use this page to set expectations after installation. Integration means ACC can introduce
|
|
4
|
+
peer awareness and coordination instructions; it does not guarantee what a model will do
|
|
5
|
+
with them. Delivery also varies independently from awareness. The durable inbox works for
|
|
6
|
+
every participant, supported exact versions may add next-turn delivery, and the
|
|
7
|
+
experimental Codex LocalDaemon and Claude Code Channel paths can deliver while a session is idle.
|
|
8
|
+
|
|
3
9
|
Capability honesty separates four questions that are easy to collapse:
|
|
4
10
|
|
|
5
11
|
1. **Certified support** — did this exact client version and platform pass a shipped
|
|
@@ -10,8 +16,12 @@ Capability honesty separates four questions that are easy to collapse:
|
|
|
10
16
|
kind?
|
|
11
17
|
4. **Fallback** — what durable path remains when any earlier answer is no?
|
|
12
18
|
|
|
13
|
-
A source method or vendor documentation is not certification.
|
|
14
|
-
platforms degrade to false. No weaker session inherits a stronger peer's capability.
|
|
19
|
+
A source method or vendor documentation is not certification. Uncaptured hook versions and
|
|
20
|
+
unsupported platforms degrade to false. Native minimum-based eligibility is separate. No weaker session inherits a stronger peer's capability.
|
|
21
|
+
|
|
22
|
+
Run `acc doctor` in the project when observed behavior differs from this page. It reports
|
|
23
|
+
the installed client version, platform, effective capability, and fallback instead of
|
|
24
|
+
assuming that a newer or differently packaged client behaves like a captured one.
|
|
15
25
|
|
|
16
26
|
## Certified support
|
|
17
27
|
|
|
@@ -32,22 +42,23 @@ Passing evidence currently ships for these exact versions on `darwin-arm64`:
|
|
|
32
42
|
Every other capability in the closed shape defaults to false, including session resume,
|
|
33
43
|
child sessions, startup or safe-point injection, and before-read guards.
|
|
34
44
|
|
|
35
|
-
The
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
The native rows remain `no` for the older exact hook versions in this matrix.
|
|
46
|
+
Separate installed-client captures establish Codex `livePush` on 0.152.1 and
|
|
47
|
+
0.153.4, and Claude Code `livePush` plus `replyRoute` on 2.1.258 and 2.1.260.
|
|
48
|
+
Native eligibility uses the captured platform minimum, a current feature probe,
|
|
49
|
+
and an exact per-session handshake. It is experimental and requires recipient
|
|
50
|
+
opt-in. Codex replies through `acc reply`; its native `replyRoute` remains false.
|
|
40
51
|
|
|
41
52
|
The limitations belong next to the adapters they affect:
|
|
42
53
|
|
|
43
54
|
| Adapter | Exact limitation and evidence |
|
|
44
55
|
|---|---|
|
|
45
|
-
| Codex | 0.147.0 next-turn
|
|
56
|
+
| Codex | Exact 0.147.0 next-turn context requires plugin trust. The observed stock 0.153.4 upgrade from ACC 0.3.1 to 0.4 required fresh review of five modified hook definitions; a subsequent restart retained all five active (activation evidence, not new event certification). LocalDaemon native delivery was captured through the installed package on 0.152.1 and 0.153.4, darwin-arm64; minimum 0.152.1, recorded opt-in, current feature probe and exact thread/cwd/process/version/protocol checks are required. Ordinary launch preserves the receiver workspace without ACC arguments or daemon ownership. Embedded or unreachable sessions keep their inbox. Native `replyRoute` remains false. |
|
|
46
57
|
| Claude Code | 2.1.233 next-turn delivery waits for the next user prompt. A 2.1.258 Channel capture proved idle offer, busy queue-after-turn, explicit reply, duplicate suppression, and durable fallback, so `delivery.livePush` and `delivery.replyRoute` are live capabilities behind the native contract (experimental, off until opted in; Claude's development-channel warning is vendor-owned and visible). |
|
|
47
58
|
| Gemini CLI | Only 0.57.0 has package-shipped next-turn certification. Its TUI has no captured external wake or queue interface and `--acp` changes launch ownership, so native delivery is fallback-only; live push and reply routing remain false. |
|
|
48
59
|
| Grok | Documentation-shaped payloads do not count as real captures. The public leader surface exposed no proven addressed injection into an ordinary TUI session, so native delivery is `awaiting_compatibility_capture`; all capabilities remain false. |
|
|
49
60
|
| Kimi Code | 0.36.1 has next-turn and guard evidence, plus a 60-second heartbeat. Its server/queue APIs do not prove a transparent binding to an independently opened session, so native delivery is fallback-only. |
|
|
50
|
-
| Generic MCP |
|
|
61
|
+
| Generic MCP | As a receiver, tool polling is not next-turn injection, live push, or a native reply route. It has no write guard or client-lifecycle evidence. Outgoing messages may use an eligible recipient's opted-in native adapter. |
|
|
51
62
|
|
|
52
63
|
`certification.json` beside each adapter is machine-readable. `COMPATIBILITY.md` records the
|
|
53
64
|
captured client behavior, including what could not be observed.
|
|
@@ -59,23 +70,28 @@ would publish a generation-bound binding with `availableModes`, `clientVersion`,
|
|
|
59
70
|
`livePolicy`, and `leaseUntil`. `acc status --json` reports these as `deliveryBindings`
|
|
60
71
|
with a computed `reachable` boolean while keeping the opaque endpoint private.
|
|
61
72
|
|
|
62
|
-
The router requires exactly one current eligible generation. No binding,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
inbox
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
The router requires exactly one current eligible generation. No binding, several live
|
|
74
|
+
sessions for one participant, and an adapter refusal keep delivery on the durable
|
|
75
|
+
fallback. An expired lease may be revalidated by an adapter's optional refresh method;
|
|
76
|
+
failure leaves the message queued. Busy behavior belongs to the transport: Claude's Channel can accept a
|
|
77
|
+
message while the target is busy and queue it until the current turn finishes; an adapter
|
|
78
|
+
that instead refuses with `recipient_busy` leaves the message on the durable path.
|
|
79
|
+
|
|
80
|
+
An endpoint may renew its lease, or an adapter may revalidate that exact endpoint on
|
|
81
|
+
demand without a client heartbeat. Retirement is final: neither route may revive a
|
|
82
|
+
retired binding, a closed session or an old generation. Delivery lease refresh does
|
|
83
|
+
not renew participant presence.
|
|
84
|
+
|
|
85
|
+
On darwin-arm64, Codex LocalDaemon and Claude Code Channel have captured
|
|
86
|
+
experimental live delivery. Other adapters retain their separately certified
|
|
87
|
+
next-turn paths or inbox polling. Linux and other uncaptured platforms retain
|
|
88
|
+
the durable inbox; these captures establish no new hook capabilities there.
|
|
89
|
+
|
|
90
|
+
Codex's 120-second delivery lease can refresh on demand for the same live endpoint;
|
|
91
|
+
it does not extend the 24-hour participant presence limit. A TUI exit can leave its
|
|
92
|
+
daemon thread loaded and able to execute opted-in messages. Actual thread teardown,
|
|
93
|
+
including explicit archive, runs `SessionEnd` and retires the binding. Turning ACC
|
|
94
|
+
delivery off prevents new offers even while that thread remains loaded.
|
|
79
95
|
|
|
80
96
|
## Recipient policy
|
|
81
97
|
|
|
@@ -88,10 +104,16 @@ policy:
|
|
|
88
104
|
| `actionable` | questions, requests, answers, decisions, and addressed handoffs may use live push; notes wait for the next turn |
|
|
89
105
|
| `all` | every addressed message kind may use live push |
|
|
90
106
|
|
|
91
|
-
The default is `off`. `acc install --delivery actionable|all`
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
The default is `off`. `acc install --delivery actionable|all` records recipient consent.
|
|
108
|
+
Current activation remains off when the platform, captured minimum or feature probe
|
|
109
|
+
does not qualify; that temporary failure does not erase the requested policy. Each
|
|
110
|
+
session must pass its own generation-bound handshake. An adapter using the installation
|
|
111
|
+
record rereads consent at hooks and before offers, so a long-running vendor process
|
|
112
|
+
cannot retain permission through an old environment value or binding snapshot.
|
|
113
|
+
|
|
114
|
+
For an adapter using recorded consent, `--delivery off` and uninstall prevent new
|
|
115
|
+
native offers. They cannot withdraw a submission already accepted by the vendor queue. Ordinary hook capabilities still
|
|
116
|
+
require exact-version certification. Room messages are never live-push candidates.
|
|
95
117
|
|
|
96
118
|
## Fallback
|
|
97
119
|
|