@agen-ai/provider-acp 0.4.0 → 0.4.2

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 (81) hide show
  1. package/README.md +515 -12
  2. package/dist/capabilities.d.ts +3 -1
  3. package/dist/capabilities.js +5 -4
  4. package/dist/configuration/catalog.js +0 -2
  5. package/dist/configuration/errors.js +0 -1
  6. package/dist/connection/contracts.d.ts +24 -1
  7. package/dist/connection/errors.js +0 -1
  8. package/dist/connection/initialize.d.ts +7 -3
  9. package/dist/connection/initialize.js +64 -19
  10. package/dist/connection/negotiation.d.ts +3 -1
  11. package/dist/connection/negotiation.js +22 -1
  12. package/dist/contracts.d.ts +3 -0
  13. package/dist/driver.d.ts +1 -1
  14. package/dist/driver.js +6 -39
  15. package/dist/driverFactory.d.ts +8 -0
  16. package/dist/driverFactory.js +48 -0
  17. package/dist/host/interactions.d.ts +6 -1
  18. package/dist/host/interactions.js +42 -17
  19. package/dist/host/leases.js +0 -1
  20. package/dist/host/router.d.ts +3 -2
  21. package/dist/host/router.js +23 -21
  22. package/dist/host/terminals.js +0 -2
  23. package/dist/index.d.ts +1 -0
  24. package/dist/instance.d.ts +7 -2
  25. package/dist/instance.js +113 -28
  26. package/dist/node/contracts.d.ts +6 -0
  27. package/dist/node/execution/errors.d.ts +11 -0
  28. package/dist/node/execution/errors.js +17 -0
  29. package/dist/node/execution/owner.d.ts +34 -0
  30. package/dist/node/execution/owner.js +162 -0
  31. package/dist/node/execution/types.d.ts +20 -0
  32. package/dist/node/execution/types.js +0 -0
  33. package/dist/node/index.d.ts +3 -1
  34. package/dist/node/index.js +16 -6
  35. package/dist/node/launch.d.ts +5 -8
  36. package/dist/node/launch.js +13 -1
  37. package/dist/permissions/contracts.d.ts +22 -0
  38. package/dist/permissions/contracts.js +0 -0
  39. package/dist/permissions/mapping.d.ts +13 -0
  40. package/dist/permissions/mapping.js +99 -0
  41. package/dist/permissions/selection.d.ts +5 -0
  42. package/dist/permissions/selection.js +96 -0
  43. package/dist/session/continuation.d.ts +33 -0
  44. package/dist/session/continuation.js +185 -0
  45. package/dist/session/create.d.ts +7 -1
  46. package/dist/session/create.js +3 -1
  47. package/dist/session/descendants.d.ts +29 -0
  48. package/dist/session/descendants.js +97 -0
  49. package/dist/session/errors.js +0 -1
  50. package/dist/session/mapping.d.ts +6 -0
  51. package/dist/session/mapping.js +5 -26
  52. package/dist/session/native.d.ts +1 -0
  53. package/dist/session/native.js +8 -0
  54. package/dist/session/opening.d.ts +1 -0
  55. package/dist/session/opening.js +3 -1
  56. package/dist/session/queue.js +0 -1
  57. package/dist/session/requests/elicitation.d.ts +1 -1
  58. package/dist/session/requests/elicitation.js +1 -1
  59. package/dist/session/requests/forms.js +0 -2
  60. package/dist/session/requests/grokWithdrawals.d.ts +28 -0
  61. package/dist/session/requests/grokWithdrawals.js +135 -0
  62. package/dist/session/requests/pending.d.ts +17 -4
  63. package/dist/session/requests/pending.js +63 -8
  64. package/dist/session/requests/resolution.js +4 -2
  65. package/dist/session/resources.js +5 -3
  66. package/dist/session/session.d.ts +12 -1
  67. package/dist/session/session.js +197 -47
  68. package/dist/session/turn.d.ts +6 -1
  69. package/dist/sessionInteractions/broker.d.ts +50 -0
  70. package/dist/sessionInteractions/broker.js +193 -0
  71. package/dist/sessionInteractions/contracts.d.ts +3 -0
  72. package/dist/sessionInteractions/contracts.js +0 -0
  73. package/dist/sessionInteractions/extensions.d.ts +4 -0
  74. package/dist/sessionInteractions/extensions.js +37 -0
  75. package/dist/sessionInteractions/grokFolderTrust.d.ts +42 -0
  76. package/dist/sessionInteractions/grokFolderTrust.js +106 -0
  77. package/dist/sessionInteractions/grokPlanReview.d.ts +16 -0
  78. package/dist/sessionInteractions/grokPlanReview.js +63 -0
  79. package/dist/sessionInteractions/request.d.ts +46 -0
  80. package/dist/sessionInteractions/request.js +173 -0
  81. package/package.json +4 -4
package/README.md CHANGED
@@ -1,17 +1,23 @@
1
1
  # @agen-ai/provider-acp
2
2
 
3
3
  An optional provider for the AgenAI coding-agent runtime. It translates the stable
4
- Agent Client Protocol wire version 1 into the existing Agent Protocol V10 session
5
- API at coordinated SDK version `0.4.0`.
4
+ Agent Client Protocol wire version 1 into the existing Agent Protocol V12 session
5
+ API. The coordinated source candidate is unpublished `0.4.2`; published `0.4.1` qualification remains
6
+ historical evidence for its exact V11 artifacts.
6
7
  The package is ESM, MIT licensed, side-effect-free on import and requires Node.js
7
8
  22 or newer. It depends only on the public transport, runtime and protocol packages;
8
9
  the core packages remain independent of ACP.
9
10
 
10
11
  The provider pins the transport's `schema-v1.23.0` stable profile. It translates
11
- ACP into existing V10 capabilities and rejects unsupported semantics explicitly.
12
+ ACP into current V12 capabilities and rejects unsupported semantics explicitly.
12
13
  Connection negotiation, configured host facilities, and mapping policy fix one
13
14
  capability envelope per instance; every later connection must match it.
14
15
 
16
+ Tool approvals default to once-only scoped consequences. Both constructors accept an explicit
17
+ `permissionMapping` selection for completely described provider-managed remembered choices.
18
+ Native option labels or kinds alone never establish their consequences. See
19
+ [Remembered tool approvals](#remembered-tool-approvals) for mapping admission and qualification limits.
20
+
15
21
  ## Unknown extensions
16
22
 
17
23
  Both `createAcpProviderDriver` and `createNodeAcpProviderDriver` default to
@@ -46,10 +52,10 @@ under a different policy.
46
52
 
47
53
  | Surface | Supported behavior and requirements |
48
54
  | --- | --- |
49
- | Turns and requests | Default text turns, streamed assistant/reasoning text, tool progress, cancellation and once-only exact-action permissions. One execution retains the original native prompt across request waits and answers. |
55
+ | Turns and requests | Default text turns, streamed assistant/reasoning text, tool progress, cancellation and once-only exact-action permissions by default, with opt-in complete remembered-choice mappings. One execution retains the original native prompt across request waits and answers. |
50
56
  | Resume | Exact persisted binding using advertised `session/resume`, otherwise advertised `session/load`. Load history is bounded and suppressed from new-turn output. No automatic recreation after failure. |
51
57
  | Configuration | Managed by default. Explicit `configuration: 'selectable'` maps observed boolean/select catalogs, with a session-mode fallback when config options are absent. Unknown metadata differs from observed empty metadata. |
52
- | Forms | Canonical boolean/single-select/multi-select forms that fit V10 constraints. An intent stage preserves decline separately from cancel, followed by answers on the same native waiter. Explicit host form facilities can handle broader native forms. |
58
+ | Forms | Canonical boolean/single-select/multi-select forms that fit V12 constraints. An intent stage preserves decline separately from cancel, followed by answers on the same native waiter. Explicit host form facilities can handle broader native forms. |
53
59
  | Images | Inline base64 PNG/JPEG/WebP only when the peer advertises image input, within image and total turn budgets. No implicit local-file read or URL fetch. |
54
60
  | Plans | Complete replacements of observed turn plans. A mode called “plan” does not establish enforced planning behavior or approval authority. |
55
61
  | File changes | Partial structured observations from native tool diffs. Canonical paths contained by the working directory become sorted relative display paths without filesystem reads. Unfinished tools remain unknown at ordinary turn completion. No final workspace diff or Review artifact is inferred. |
@@ -57,12 +63,13 @@ under a different policy.
57
63
  | Authentication | Explicit method-to-flow selection and host interaction facilities. Agent methods retain the authenticated connection; terminal methods require a host facility and fresh verified initialization afterward. |
58
64
  | Files and terminals | Explicit host callbacks, correlated to the bound native session. Terminal support requires the complete output/wait/kill/release lifecycle; embedded terminal transcript references remain unsupported. |
59
65
  | MCP setup | Static host-approved `mcpServers` and optional owned `sessionMcpBinding` factory for creation/resume. HTTP/SSE require advertised peer support. Configuration is not observed tool exposure. |
66
+ | Session decisions | Opt-in `grok-folder-trust-v1` on the Node constructor, with a required host execution boundary and handler registered before create. This outside-turn mapping has its own exact support and qualification scope below. |
60
67
 
61
68
  Through-turn branching, same-turn steering, enforced plan mode, persistent
62
- permission grants, context usage/compaction, account quota, effective skill/rule
69
+ SDK-owned tool-approval grants, context usage/compaction, account quota, effective skill/rule
63
70
  inventory, collaboration, generated resources and artifact publication remain
64
71
  unsupported. ACP usage counters can decrease without confirmed compaction and
65
- cannot satisfy V10's context continuity contract. Unsupported media output fails
72
+ cannot satisfy V12's context continuity contract. Unsupported media output fails
66
73
  explicitly rather than disappearing from an otherwise successful transcript.
67
74
  Embedded terminal references also fail explicitly: a mutable, possibly truncated
68
75
  terminal snapshot does not provide an ordered append-only transcript. Agents can
@@ -75,7 +82,7 @@ over other conversations or account state.
75
82
 
76
83
  ## Operational failures and uncertainty
77
84
 
78
- The provider maps supported standard `schema-v1.23.0` prompt errors into V10 `AgentError` values.
85
+ The provider maps supported standard `schema-v1.23.0` prompt errors into V12 `AgentError` values.
79
86
  Standard `-32000` reports `authentication` with an `authenticate` user-action hint; `-32602` reports
80
87
  `invalid_request`; `-32603` reports `provider`; standard parse/request/method errors report `protocol`.
81
88
  Other remote codes remain `unknown` with unknown recovery. Mapping uses the standard error code,
@@ -219,7 +226,7 @@ the host must retain ownership and establish native-process quiescence.
219
226
 
220
227
  The root entrypoint exports `createAcpProviderDriver`. Its constructor accepts
221
228
  `providerKey`, `createConnection`, and optional `limits`, `configuration`,
222
- `authentication`, `host`, `mcpServers`, and `sessionMcpBinding`. The connection factory receives the public
229
+ `authentication`, `host`, `mcpServers`, `sessionMcpBinding`, and `permissionMapping`. The connection factory receives the public
223
230
  `instanceId` and an initialization `signal`. Return fresh, exclusive Node
224
231
  `stdout`, `stdin`, and optional `stderr` streams for every invocation, with one of:
225
232
 
@@ -256,6 +263,502 @@ The built-in launcher rejects Windows before spawning with
256
263
  supervisor, such as a Windows Job Object; the SDK does not supply a native Windows
257
264
  process-tree launcher in `0.4.0`.
258
265
 
266
+ ## Remembered tool approvals
267
+
268
+ `permissionMapping` is constructor configuration on both `createAcpProviderDriver` and
269
+ `createNodeAcpProviderDriver`. It is captured when the driver is created and is absent from the
270
+ empty serialized `driverConfiguration`. Omission or `{ mapping: 'once-only-v1' }` retains the
271
+ conservative once-only subset of each menu and advertises `providerManagedRemembrance: false`.
272
+ A remembered-only native menu is unsupported under that default.
273
+
274
+ For a peer whose complete permission behavior you have inspected and qualified, declare its exact
275
+ initialized identity and complete ordered menus:
276
+
277
+ ```ts
278
+ import type { AcpPermissionMappingSelection } from '@agen-ai/provider-acp';
279
+
280
+ const permissionMapping = {
281
+ mapping: 'declared-complete-consequences-v1',
282
+ agentInfo: { name: 'example-agent', version: '1.2.3' },
283
+ menus: [{
284
+ toolKind: 'edit',
285
+ options: [
286
+ { optionId: 'allow-once', kind: 'allow_once' },
287
+ { optionId: 'remember-allow', kind: 'allow_always' },
288
+ { optionId: 'deny-once', kind: 'reject_once' },
289
+ { optionId: 'remember-deny', kind: 'reject_always' },
290
+ ],
291
+ }],
292
+ } as const satisfies AcpPermissionMappingSelection;
293
+ ```
294
+
295
+ Pass that value with your ordinary connection or Node launch options. The example identities are
296
+ illustrative. Selecting this mapping is your attestation that every listed option has only its
297
+ current allow/deny decision and once-only or provider-managed remembered consequence. A choice
298
+ that also changes mode, clears context or grants another authority needs a different complete
299
+ mapping; this API cannot discover hidden effects or authenticate the implementation from its name.
300
+
301
+ Declarations contain 1–16 menus, each with 1–16 options. Native IDs must be canonical strings of
302
+ 1–256 characters and unique within each menu. Menu signatures must be unique. Peer names are
303
+ bounded to 256 characters and versions to 160; edge whitespace and control/format characters are
304
+ rejected. Tool kinds use the pinned ACP standard vocabulary. Selection uses exact identity, tool
305
+ kind and the complete ordered ID/kind list; native labels are display data. There are no predicates,
306
+ regular expressions, native payload bags or custom mapping callbacks.
307
+
308
+ The capability reflects the selected declarations. Remembered-only menus advertise no precise
309
+ modes and `providerManagedRemembrance: true`; combined menus advertise once/exact-action as well.
310
+ A remembered option has the neutral label “Allow and remember” or “Deny and remember” and an
311
+ explanation that duration and future matching are unspecified. Native wording is omitted from its
312
+ optional description. An offered choice never promises that a provider actually saved a rule.
313
+
314
+ The SDK keeps distinct offered IDs, including several options with the same immediate decision.
315
+ Resolve one exact public option ID on the original execution. The live callback returns its exact
316
+ original native ID once. Deny-once, deny-and-remember and cancellation remain distinct. Continue
317
+ reading the original execution outputs through terminal settlement; a delivery receipt establishes
318
+ local callback acceptance, not native persistence, later matching or successful tool execution.
319
+
320
+ Malformed constructor selection throws `TypeError` before acquisition. A selected peer identity
321
+ mismatch fails initialization with `acp_permission_profile_mismatch`; retain any failed cleanup
322
+ owner as usual. Declared menu mismatches or unqualified option/request metadata fail with
323
+ `acp_permission_consequence_unsupported`. Duplicate IDs are rejected across the entire native menu
324
+ before any filtering. Invalid menu size fails with `acp_permission_options_invalid`. The default's
325
+ remembered-only refusal remains `acp_permission_persistence_unsupported`.
326
+
327
+ The built-in `{ mapping: 'grok-build-1.0.50-edit-remembrance-v1' }` selects the narrowly inspected
328
+ Grok Build 1.0.50 edit behavior. Its peer must report `_meta.agentVersion: '1.0.50'`. It recognizes
329
+ only the inspected `SearchReplace` edit input with `replace_all: false` and the ordered native menu
330
+ `allow-edits-session`/`allow_always`, `allow-once`/`allow_once`, `reject-once`/`reject_once`.
331
+ Other action categories retain the once-only subset with an explicit warning on the original
332
+ output stream; unsupported remembered-only menus fail. Native terminal remembrance and remembered
333
+ denial are not qualified by this edit profile. Duration and applicability remain unknown despite
334
+ native wording or observed same-session behavior.
335
+
336
+ The selected constructor and your host-owned installation/launch attest to the exact inspected
337
+ native executable; the reported version does not authenticate its bytes. The inspected candidate
338
+ is Linux x86_64 Grok Build 1.0.50 (`c58f321264ba`), SHA-256
339
+ `c80de0155706ff2d995623887b102f2d0abd2c62b2643dea3a0cebaf7dd724d5`, launched with
340
+ `agent --no-leader stdio`. Controlled mapping tests prove exact reply behavior; the installed
341
+ native fixture proof below separately establishes the selected edits' actual effects and cleanup.
342
+
343
+ This turn-level selection is independent of session-lifetime folder trust, host filesystem/terminal
344
+ facilities and unknown-extension policy. It creates no SDK permission database, automatic answer
345
+ cache, revoke operation or private Workspaces execution authority.
346
+
347
+ ### Qualified remembered-edit scope (SDK03)
348
+
349
+ Two final native fixture attempts used the genuine executable above, the selected
350
+ `grok-build-1.0.50-edit-remembrance-v1` mapping, modern stable `schema-v1.23.0` and a matching
351
+ installed seven-package `0.4.1`/Agent Protocol V11 set. The recorded tuple is Linux x86_64 kernel
352
+ `7.0.0-38-generic`, Node `24.18.0`, pnpm `11.7.0`, systemd `259.5`, Bubblewrap `0.11.1` and owned
353
+ tmpfs state. An isolated loopback model fixture drove actual native tool calls without real account
354
+ credentials or paid/backend inference. The SDK owned the only ACP reader and responder; a passive
355
+ observer independently checked exact native choices and actual fixture effects.
356
+
357
+ The first attempt used one public/native session and six turns:
358
+
359
+ | Turn | Observed request and effect |
360
+ | --- | --- |
361
+ | Once-only edit | One request; exact once-only native choice delivered once; edit performed. |
362
+ | Repeat after once-only | Asked again; exact once-only choice delivered once; edit performed. |
363
+ | Remembered edit | One request; exact remembered native choice delivered once; edit performed. |
364
+ | Exact repeat after remembrance | No new request; edit performed. |
365
+ | Neighboring owned file | No new request; edit performed. |
366
+ | Uncovered terminal action | Asked again; effect occurred after its exact once-only approval. |
367
+
368
+ The second attempt reopened the verified retained owned state with both a fresh native process
369
+ and a distinct native session. Its first edit asked again and performed the expected edit after
370
+ one exact once-only answer. This combined restart/new-session observation does not isolate the
371
+ effect of either change or define a general expiry or storage contract. Same-process second-session
372
+ behavior was observed only in separate native discovery, outside this installed Node composition.
373
+
374
+ For both attempts, successful public `session.close()` preceded an independent empty checkpoint
375
+ of the same physical workload cgroup while the controller remained alive, before registry or host
376
+ disposal. No earlier external cleanup intervention or OOM kill occurred. Native effects, answer
377
+ correlation and SDK cleanup were checked independently.
378
+
379
+ The exact retained report SHA-256 identities are
380
+ `4ea3ea5b9fac16761b32919ac476ec9b4621f2e99434c441d9eefadb469c5a6b` (six-turn attempt) and
381
+ `bd93b95c3fdba51b0f7f03eaea0393e796a4626298eaedb2a9ebf1ce9bb36730` (retained-state restart).
382
+ The native-used package archives have these SHA-256 identities:
383
+
384
+ | Package at `0.4.1` | Native-used archive SHA-256 |
385
+ | --- | --- |
386
+ | `@agen-ai/validation` | `84d97191d2175be1c7d83e86a007157b80c303088b94be0c05ec6961e2a41729` |
387
+ | `@agen-ai/agent-protocol` | `5a647b2fa504ec3175d58075f503f5e9e435186ec0e8c0758e74ea37741ad192` |
388
+ | `@agen-ai/agent-runtime` | `81dc5ed8940d96bc5f3ae3f0fdb2ad862af87a087e57032db41995a29dacf4b4` |
389
+ | `@agen-ai/agent-orchestration` | `914ad78cdac3ee6af1fe6a7d8522e5c216a3de670816462a082f5c0bde0988fa` |
390
+ | `@agen-ai/acp-transport` | `81314926f24fa428e910c0256671add61f525cac036d5b2841185a7c3e953894` |
391
+ | `@agen-ai/provider-acp` | `2a68df821134fc0af48ab850c1a48ad33be74b8e42e64a6d916bfe2eb84acf6a` |
392
+ | `@agen-ai/acp-registry` | `ab317cc347bf53dcd0045aff4a6d74cb429fc6781c336ea6ed128ced13bdaa07` |
393
+
394
+ Later documentation or packing can change archive bytes; the same version is not an identity
395
+ check. Reuse of this evidence requires comparison of the exact installed dependency closure,
396
+ runtime/declaration members, mapping and host composition. The earlier SDK02 folder-trust proof
397
+ below used different `0.4.1`/V10 artifacts and establishes a separate session-lifetime behavior.
398
+
399
+ Duration and applicability remain unknown. This fixture proof does not qualify arbitrary path
400
+ matching, separate projects/profiles, remembered denial, terminal remembrance, revocation,
401
+ worktree/account/distributed behavior, real-model inference or other native/runtime pairings.
402
+ It does not publish packages, integrate a consumer application or enable private execution.
403
+
404
+ ## Session-lifetime folder decisions
405
+
406
+ The `0.4.1` release includes the opt-in mapping on
407
+ `createNodeAcpProviderDriver`:
408
+ `sessionInteractions: { mapping: 'grok-folder-trust-v1' }`. Supply an explicit
409
+ `executionBoundary` at construction and the generic `interactions.onRequest`
410
+ handler on each `createSession` input before opening. Materialization itself
411
+ remains noninteractive. The mapping is absent by default, and ordinary standard
412
+ unknown-extension handling never enables it implicitly.
413
+
414
+ The selected launch arguments are exactly `['agent', '--no-leader', 'stdio']`.
415
+ The adapter exposes the exact `sessionInteractions.mappings` tuple
416
+ `{ openingOperation: 'create', requestKind: 'decision' }`, exclusive producer
417
+ ownership and, in current 0.4.2 source, `humanWait: ['bounded', 'until_withdrawn_or_closed']`. The handler receives a neutral workspace
418
+ decision and can keep its response capability after opening returns, before
419
+ any model turn. Use the generic
420
+ [runtime lifecycle](../agent-runtime/README.md#session-lifetime-interactions)
421
+ for presentation, exact offered choices, receipt handling and cleanup. The core
422
+ [runnable example](../../examples/lifecycle-interactions.ts) requires no ACP
423
+ dependency, native account or network.
424
+
425
+ | Phase or surface | Selected mapping support |
426
+ | --- | --- |
427
+ | Create a session with an early handler | Workspace decision may remain pending after opening returns. |
428
+ | Grant or decline the offered decision | One bound response, with a local delivery receipt separate from native effect. |
429
+ | Close while unanswered | Retires eligibility, joins the native producer and callback, and refuses a late response. |
430
+ | Interactive materialization | Unsupported; no materialization handler is added. |
431
+ | Resume or branch in this selected profile | Unsupported. Generic ACP resume remains a separate unselected capability. |
432
+ | Injected/shared root connections | Unsupported for this mapping; the Node-only execution boundary is required. |
433
+ | Session forms or authentication questions | Unsupported by this outside-turn decision mapping. Existing turn/form and adapter authentication APIs remain separate. |
434
+
435
+ The grant consequence covers current and future configuration for the workspace
436
+ and is provider-managed persistent trust that can affect other sessions using
437
+ that profile. Detected configuration categories do not narrow it. Decline leaves
438
+ configuration gated without revoking old grants or proving a persisted denial.
439
+ Do not expose native request IDs or use a parallel transport responder. Only
440
+ the offered neutral response capability may answer the request.
441
+
442
+ `delivered` establishes acceptance by the local provider handler. It does not
443
+ universally prove native receipt, loaded configuration or stored trust. An
444
+ entered delivery failure or timeout is uncertain and fences further mutation;
445
+ close without resending the choice. A request's terminal promise or aborted
446
+ presentation signal cannot replace full producer/callback cleanup. Retain the
447
+ session, opening cleanup receipt and dependent host/installation owners when
448
+ cleanup fails.
449
+
450
+ ### Qualified session-lifetime scope (SDK02)
451
+
452
+ The earlier SDK02 native qualification covers Grok Build `1.0.50` (`c58f321264ba`),
453
+ executable SHA-256 `c80de0155706ff2d995623887b102f2d0abd2c62b2643dea3a0cebaf7dd724d5`,
454
+ direct no-leader stdio, this selected mapping, modern stable `schema-v1.23.0`,
455
+ its retained installed public SDK `0.4.1`/Agent Protocol V10 artifacts, API-key authentication,
456
+ Linux x86_64 kernel
457
+ `7.0.0-38-generic`, Node `24.18.0`, and the exact retained reference,
458
+ toolchain, network and dependency inputs. It is local qualification, with no
459
+ package publication or consumer-repository integration implied. These exact earlier artifacts
460
+ are distinct from the SDK03 V11 remembered-edit artifacts above despite sharing version `0.4.1`.
461
+
462
+ Three separate native runs established grant, decline and pending close. Grant
463
+ additionally observed the vendor-written isolated workspace trust file. Decline
464
+ established local acceptance and absence of a grant; no further hidden native
465
+ acknowledgment was attested. Pending close sent no choice before close, joined
466
+ the handler and rejected the stale grant as unavailable. Each run independently
467
+ enrolled the genuine target and observed the same stable cgroup empty after SDK
468
+ close with the consumer alive, before registry or host disposal, without external
469
+ intervention. The trusted host was retired afterward.
470
+
471
+ Native wire reply correlation and prompt-frame counts remain unobserved. Zero
472
+ SDK turn invocations is a frozen-consumer-source claim. Separate installed
473
+ controlled peers prove exact wire correlation, no prompts and failure ownership;
474
+ the real Linux controlled lane proves descendant containment and negative
475
+ close-checkpoint behavior. Neither substitutes for native effect evidence.
476
+ The bounded native runs fit the reference's 64-task/512 MiB/180-second limits
477
+ for these setup scenarios only. They establish no general model-turn sizing,
478
+ other builds/platforms, browser login, native durable recovery, SDK-managed
479
+ remembered permissions or private execution support. The earlier failed native
480
+ ownership attempt remains unqualified.
481
+
482
+ The current V12 decision descriptor omits `expiresAt` because this native mapping reports no
483
+ provider-owned expiry. The bounded host timer remains a separate policy boundary;
484
+ `humanWait: { kind: 'until_withdrawn_or_closed' }` omits that human timer and
485
+ rejects an explicitly supplied `limits.requestTimeoutMs`. Initialization,
486
+ response observation, authentication and cleanup keep their finite bounds.
487
+ Responses require `{ kind: 'decision', choiceId }`. Generalized runtime terminal/deadline and
488
+ exact support declarations apply to this mapping: an answered terminal records
489
+ `{ kind: 'answered', response: { kind: 'decision', choiceId } }`, and host timeout records
490
+ `{ kind: 'expired', source: 'host_policy' }`. A validated consumer handle exposes the effective
491
+ `deadline` separately from the provider descriptor. Raw driver instances return candidate adapters
492
+ whose interaction callback receives `kind: 'direct'`; registry materialization installs the
493
+ validated consumer facade. Session forms, plan reviews and native continuations
494
+ remain unsupported by `grok-folder-trust-v1`. The retained SDK02 native evidence
495
+ above remains specific to its original finite waiting configuration.
496
+
497
+ ## Restored plan requests in current 0.4.2 source
498
+
499
+ The Node constructor accepts a separate explicit selection:
500
+ `sessionInteractions: { mapping: 'grok-build-1.0.60-session-requests-v1' }`.
501
+ It requires an exclusive descendant-owning `executionBoundary`, exact direct
502
+ arguments `['agent', '--no-leader', 'stdio']`, modern stable ACP
503
+ `schema-v1.23.0`, and initialized native `_meta.agentVersion: '1.0.60'`.
504
+ The version observation is checked on every connection; it does not authenticate
505
+ an executable or its publisher. The host owns executable selection and byte verification.
506
+
507
+ This source mapping declares exactly `resume / plan_review` and
508
+ `resume / plan_review / after_open_return` continuation timing. It uses
509
+ `session/load` for the selected restoration. Install `interactions.onRequest`
510
+ and `nativeContinuations.onExecution` before resuming. The continuation handler
511
+ must begin pulling its sole `execution.outputs` iterator before an approval or
512
+ revision response can enter native work. A caller turn and a native continuation
513
+ share the same execution slot and continuous output validation.
514
+
515
+ The exact `_x.ai/exit_plan_mode` callback supplies a bounded complete plan
516
+ snapshot and three offered choices. Approval maps to `{ outcome: 'approved' }`;
517
+ revision maps to `{ outcome: 'cancelled', feedback }`; abandonment maps to
518
+ `{ outcome: 'abandoned' }` and needs no execution reservation. A revised response
519
+ must identify the offered plan revision and carry its bounded feedback. Missing
520
+ or null plan content cannot become a fabricated review snapshot.
521
+
522
+ Approval and revision continue the native request without sending
523
+ `session/prompt`. The existing session turn/queue owner accepts a fresh
524
+ `_x.ai/queue/changed.runningPromptId` beginning `plan-resume-`, correlates live
525
+ output to that exact prompt, and completes only on its matching
526
+ `_x.ai/session_notification` `turn_completed` update. Normal completion requires
527
+ `stop_reason: 'end_turn'` and observed live output. Exact `stop_reason: 'cancelled'`
528
+ uses the existing admitted cancellation reason to report `canceled`, or `expired`
529
+ for a timeout, including cancellation after promotion before any assistant output.
530
+ An unsolicited native `cancelled` terminal also reports `canceled`, without
531
+ asserting that a caller requested interruption.
532
+ The original execution reader retains that terminal and cleanup. The pinned
533
+ [Grok cancellation source](https://github.com/xai-org/grok-build/blob/2bdd1d6a6369de0e8c68132ea4539e9abd9e14a8/crates/codegen/xai-grok-shell/src/session/acp_session_impl/cancel.rs#L842)
534
+ emits this exact cancellation terminal; historical `interrupted` is not an active
535
+ cancellation alias. Errors and foreign prompt/session identities remain failures.
536
+
537
+ Historical replay, a generic interaction-resolved notification and the local
538
+ response receipt establish no continuation completion. Prompt identities observed
539
+ in historical or replayed queue, output and terminal channels remain retained
540
+ under the existing shared queue/state budget, preventing later reuse as a fresh
541
+ promotion. Repeated notifications for the already owned current prompt remain
542
+ valid and do not reserve the same identity twice. Wrong, reused or competing
543
+ identities fail the owned session. Ordinary caller turns remain available after
544
+ that execution and its reader settle.
545
+
546
+ The selected 1.0.60 mapping also isolates direct native child-session observations.
547
+ Only a root-channel `_x.ai/session_notification` `subagent_spawned` announcement
548
+ with exact parent, child and subagent identities records that relationship.
549
+ Announced child queue notifications, stable session updates and native terminal
550
+ observations are validated and discarded before parent metadata, output,
551
+ continuation prompt tracking or completion. Unknown extensions, tool text and
552
+ permission metadata cannot announce a child. Arbitrary foreign sessions,
553
+ conflicting identity reuse and nested child announcements fail the owned session.
554
+
555
+ Each retained relationship shares the existing session queue's count and byte
556
+ budget; each identity is bounded to 256 UTF-8 bytes. Exact repeated announcements
557
+ reserve no extra state. Relationships remain reserved until session stop because
558
+ a child's prompt terminal does not establish child-session retirement. Historical
559
+ relationships are replay-only and cannot become live; discarded load-time child
560
+ observations still consume the opening replay budget. This observation scope adds
561
+ no public collaboration capability or child permission, filesystem, terminal or
562
+ form authority. Parent-addressed permission requests retain their existing root
563
+ session routing, and child-addressed requests remain rejected.
564
+
565
+ For an announced live child with an exact attempt identity, this mapping recognizes
566
+ one ordered native permission cancellation sequence. The child's
567
+ `pending_interaction` must first identify a permission tool. Its exact root-routed
568
+ `session/request_permission` callback must then identify that child through
569
+ `toolCall._meta['x.ai/requestingSessionId']` and the same tool ID. A subsequent
570
+ child `interaction_resolved` followed by a root `subagent_finished` with the exact
571
+ child/subagent/attempt identities and `status: 'cancelled'` withdraws only that
572
+ original callback. The existing request owner queues `request.unavailable` for a
573
+ displayed request before rejecting its reverse callback with `-32800`; an unseen
574
+ queued callback is removed without publishing its ID. A child `turn_completed`
575
+ notification supplies no permission cancellation authority.
576
+
577
+ An `interaction_resolved` notification alone cannot establish withdrawal because
578
+ it also covers answered and failed interactions. If its exact callback has not
579
+ already accepted an answer, new answer entry waits for corroboration under the
580
+ existing finite `cancellationTimeoutMs`; duplicate observations do not refresh
581
+ that deadline. Missing or contradictory corroboration fails and quiesces the
582
+ owned session without manufacturing withdrawal. An already entered answer keeps
583
+ its original receipt. Native callback reservations remain retained until actual
584
+ transport settlement and entered host work finish. Child/tool census entries,
585
+ including retired identities and their possible answer-wait state, share the
586
+ session count and byte budgets until stop. Pre-admission, prior-turn and replayed
587
+ facts cannot attach to or withdraw a future callback. This mapping consumes
588
+ observed native facts; it adds no child cancellation command or child-addressed
589
+ request authority.
590
+
591
+ The selected lifecycle request queue retains at most
592
+ `min(maxPendingRequests, 16)` native turn callbacks and 1 MiB of request material,
593
+ within the existing shared session budget. Lower configured limits still win.
594
+ Queued, displayed, response-entered and canceled callbacks remain counted until
595
+ their actual transport settlement and any entered host callback finish. Generic
596
+ ACP compositions retain the existing configurable request ceiling of 1–256
597
+ and default 16; the selected request-material ceiling does not replace the
598
+ 8 MiB default output budget.
599
+
600
+ Exact standard `$/cancel_request` disables only its correlated reverse callback.
601
+ A displayed turn request emits one `request.unavailable` with reason `withdrawn`
602
+ on its original execution before the next surviving FIFO request opens. A queued
603
+ canceled callback stays unseen. The protocol cancellation response is separate
604
+ from a human denial, and an already entered local delivery receipt keeps its
605
+ truth even if cancellation or a later write failure occurs. Output continues
606
+ through the original reader.
607
+
608
+ Both finite and `until_withdrawn_or_closed` human waiting are accepted for these
609
+ selected session requests. Actual provider expiry remains independent. This
610
+ mapping adds no create/branch session review, outside-turn form, remembered
611
+ approval, durable native recovery or private Hostd authority. Folder-trust
612
+ selection and its create-only restriction remain independent.
613
+
614
+ Controlled public-constructor and pipe-boundary proof establishes generic FIFO,
615
+ queued withdrawal, exact continuation admission and resource bounds. Final MS009
616
+ installed-native proof separately qualifies Grok Build 1.0.60 on Linux x86_64 /
617
+ Node 24.18.0 with modern stable `schema-v1.23.0`: exact active A withdrawal with
618
+ zero A answers, later B once-only delivery/effect, the original output terminal,
619
+ fresh retained approve/revise continuations with no caller prompt, and no-work
620
+ abandonment during its bounded observation. Each selected case independently
621
+ observes the original workload empty after first SDK close while the consumer
622
+ remains alive, before disposal.
623
+
624
+ That current Grok composition explicitly sets `GROK_AUTO_WAKE=0`,
625
+ `GROK_WORKER_THREADS=1`, `GROK_SUBAGENT_WORKER_THREADS=1` and
626
+ `GROK_GIX_STATUS_THREADS=1`. Automatic parent wake remains unqualified. Native
627
+ permission forwarding is observed to serialize; simultaneous live Grok callbacks
628
+ into the SDK FIFO queue remain unqualified under the user-accepted MS009 amendment.
629
+ Generic ACP FIFO and the separate Claude diagnostic's native FIFO proof do not
630
+ extend that Grok claim. The selected human-wait observation is 250 ms, which proves
631
+ that mapping's bounded observation rather than arbitrary native waiting duration.
632
+
633
+ The campaign uses isolated scripted model responses and a constant fake credential;
634
+ it qualifies no real backend authentication, inference or billing. The separate
635
+ Grok 1.0.50 remembered-edit regression retains its historical launch environment
636
+ and recorded task-limit warnings; it makes no capacity-headroom claim. Existing
637
+ Grok 1.0.50 qualification and the legacy `v0.11.4` transport profile retain their
638
+ original scope. The [0.4.2 migration guide](../../MIGRATING-TO-0.4.2.md) identifies
639
+ the executable examples, supported tuples and unsupported native paths.
640
+
641
+ ## Reserved execution ownership
642
+
643
+ This surface is included in the `0.4.1` release.
644
+
645
+ The Node constructor also accepts an explicit `executionBoundary`. This host-owned
646
+ port is useful when native descendants can create their own sessions or process
647
+ groups. It is required when selecting
648
+ `sessionInteractions: { mapping: 'grok-folder-trust-v1' }`; omission fails at
649
+ constructor admission before materialization. The root injected constructor does
650
+ not accept this Node-only option. Ordinary unselected Node drivers keep the
651
+ process-group launcher described above.
652
+
653
+ Import the types from `@agen-ai/provider-acp/node`. A boundary synchronously
654
+ reserves one fresh, inert owner for each immutable launch recipe:
655
+
656
+ ```ts
657
+ interface NodeAcpExecutionBoundary {
658
+ reserve(input: NodeAcpExecutionInput): NodeAcpExecutionReservation;
659
+ }
660
+ ```
661
+
662
+ The recipe contains the exact absolute executable, literal arguments, working
663
+ directory, explicit environment and `shutdownTimeoutMs`. `reserve` must acquire
664
+ no resources and start no asynchronous work. The SDK retains its bound `start`
665
+ and `release` methods before entering startup. `start(context)` establishes the
666
+ operating-system boundary before executing native code and returns ACP streams;
667
+ it receives the current initialization signal. `release()` must synchronously
668
+ fence further startup, initiate termination, and join entered startup, streams
669
+ and the complete descendant workload. It must work before, during and after
670
+ startup. Late startup results remain owned by that same reservation.
671
+
672
+ A supplied object is an ownership contract, not containment proof. The host must
673
+ prevent the workload from leaving its boundary or controlling its supervisor.
674
+ A changing PID list or killing one process group cannot establish that guarantee.
675
+ The standalone [Linux reference](../../examples/execution/linux/README.md) uses
676
+ explicit cgroup delegation and isolated supervisor controls. Its platform and
677
+ host prerequisites are separate from the portable SDK API; there is no automatic
678
+ privilege escalation or fallback to weaker ownership for the selected mapping.
679
+
680
+ For the qualified Linux composition, retain the external host before starting
681
+ it, then give its boundary to the Node driver. The host supplies the physical
682
+ installation, workspace and each writable profile/runtime/temp mount plus an
683
+ explicit native environment:
684
+
685
+ ```ts
686
+ import { createNodeAcpProviderDriver } from '@agen-ai/provider-acp/node';
687
+ import { createLinuxExecutionHost } from '../../examples/execution/linux/boundary.mjs';
688
+
689
+ const host = createLinuxExecutionHost({
690
+ network: 'host',
691
+ networkInputs: {
692
+ resolver: '/etc/resolv.conf',
693
+ hosts: '/etc/hosts',
694
+ certificates: '/etc/ssl/certs',
695
+ },
696
+ mounts: [
697
+ { path: installationRoot, writable: false },
698
+ { path: workspaceRoot, writable: true },
699
+ ...ownedProfileMounts,
700
+ ],
701
+ });
702
+ await host.start();
703
+ const driver = createNodeAcpProviderDriver({
704
+ providerKey,
705
+ sessionInteractions: { mapping: 'grok-folder-trust-v1' },
706
+ executionBoundary: host.executionBoundary,
707
+ launch: { executable: approvedExecutable, args: ['agent', '--no-leader', 'stdio'],
708
+ cwd: workspaceRoot, env: explicitNativeEnvironment, shutdownTimeoutMs: 2_000 },
709
+ });
710
+ ```
711
+
712
+ Construct a registry with that driver and register the generic handler on
713
+ session opening. On success, close the session, dispose the registry, then
714
+ dispose the host. Retain the host if `start()` rejects. When qualifying cleanup,
715
+ keep the exact empty boundary for an independent checkpoint after SDK close
716
+ and before registry/host disposal. Networking and confinement remain explicit
717
+ host authority; the SDK does not create this Linux host automatically.
718
+
719
+ If initial materialization fails and cleanup remains incomplete, the `/node`
720
+ entrypoint exposes `NodeAcpExecutionCleanupError` and
721
+ `isNodeAcpExecutionCleanupError`. Through `createAgentProviderRegistry`, this
722
+ error remains the registry error's `cause`. Keep that original object and its
723
+ bound `retryCleanup()` callback until cleanup succeeds. Its `cause` preserves the
724
+ original startup failure and `cleanupError` records the failed cleanup attempt.
725
+ The callback retains the full acquired resource lifetime, including native work,
726
+ streams and entered provider callbacks. Serializing the error cannot preserve
727
+ this cleanup authority.
728
+
729
+ For example, a failed registry construction can be inspected without replacing
730
+ the callable owner:
731
+
732
+ ```ts
733
+ import { AgentProviderRegistryError } from '@agen-ai/agent-runtime';
734
+ import { isNodeAcpExecutionCleanupError } from '@agen-ai/provider-acp/node';
735
+
736
+ if (error instanceof AgentProviderRegistryError && isNodeAcpExecutionCleanupError(error.cause)) {
737
+ const retained = error.cause;
738
+ await retained.retryCleanup();
739
+ // Only now may the host release resources that depended on this native owner.
740
+ }
741
+ ```
742
+
743
+ If this retry rejects, keep `retained` and the external host owned for explicit
744
+ recovery. A late cleanup success cannot change the original opening failure or
745
+ authorize another native action. Host intervention during qualification keeps
746
+ the original verdict failed even if recovery eventually succeeds.
747
+
748
+ Each cleanup attempt has one observation window of `2 * shutdownTimeoutMs`
749
+ (default four seconds, maximum sixty seconds). A timeout preserves actual pending
750
+ work. A retry gets a fresh observation window and joins the same work; it never
751
+ starts a second process or overlaps an unfinished release. Only a release that
752
+ actually settled with failure may be called again. A shorter runtime deadline
753
+ can return first while the same cleanup remains owned.
754
+
755
+ Once an instance exists, an unsuccessful session opening uses the existing exact
756
+ `AgentProviderSessionCleanupError` receipt. A returned session keeps its normal
757
+ `close` retry path. Retain the corresponding instance, registry and host supervisor
758
+ until all dependent cleanup succeeds. A successful session close establishes
759
+ native quiescence under the supplied owner's contract; independent qualification
760
+ must verify that the concrete owner fulfills it.
761
+
259
762
  ## Session-scoped MCP bindings
260
763
 
261
764
  `sessionMcpBinding: { transport, create }` pairs a host-certified `http` or `sse` transport
@@ -418,8 +921,8 @@ close ends that handle's ownership. The host retains control over its process po
418
921
  Canonical forms preflight the whole schema before presenting a request. They
419
922
  support at most 16 ordinary fields and 100 choices per selection. Free-text fields,
420
923
  nested objects, numeric fields, defaults, patterns/formats, and constraints without
421
- a V10 representation are rejected. Native free text permits blank/whitespace values
422
- and measures length in Unicode code points; V10 text answers use nonblank/UTF-16
924
+ a V12 representation are rejected. Native free text permits blank/whitespace values
925
+ and measures length in Unicode code points; V12 text answers use nonblank/UTF-16
423
926
  bounds. The provider does not narrow those native semantics silently. Enumerated
424
927
  string values can map through opaque canonical selection IDs.
425
928
  A required multi-select must require exactly one minimum selection; an optional
@@ -440,7 +943,7 @@ binding grants no interaction authority. Their host callbacks receive a turn
440
943
  lifetime signal that ends on cancellation, settlement or close.
441
944
 
442
945
  Image input allows at most 16 images, 375,000 decoded bytes per image and 750,000
443
- decoded bytes total, subject to the stricter 1 MiB V10 turn-content bound. Declared
946
+ decoded bytes total, subject to the stricter 1 MiB V12 turn-content bound. Declared
444
947
  media type, dimensions, base64 encoding and byte counts are validated. The provider
445
948
  does not decode pixels or publish generated bytes; hosts needing image-content
446
949
  inspection must perform it before submitting input.
@@ -1,4 +1,6 @@
1
1
  import { type AgentAuthenticationFlow, type AgentCapabilities, type AgentProviderKey } from '@agen-ai/agent-protocol';
2
2
  import type { AcpNegotiatedAgent } from './connection/contracts.js';
3
- export declare function acpProviderCapabilities(providerKey: AgentProviderKey, negotiated: AcpNegotiatedAgent, configuration?: 'managed' | 'selectable', authenticationFlows?: readonly AgentAuthenticationFlow[]): AgentCapabilities;
3
+ import type { AcpSessionInteractionSelection } from './sessionInteractions/contracts.js';
4
+ import type { AcpPermissionMappingSelection } from './permissions/contracts.js';
5
+ export declare function acpProviderCapabilities(providerKey: AgentProviderKey, negotiated: AcpNegotiatedAgent, configuration?: 'managed' | 'selectable', authenticationFlows?: readonly AgentAuthenticationFlow[], sessionInteractions?: AcpSessionInteractionSelection, permissionMapping?: AcpPermissionMappingSelection): AgentCapabilities;
4
6
  //# sourceMappingURL=capabilities.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { parseAgentCapabilities } from "@agen-ai/agent-protocol";
2
+ import { acpPermissionCapability } from "./permissions/selection.js";
2
3
  function freezeCapabilities(value) {
3
4
  if (value && typeof value === "object") {
4
5
  for (const child of Object.values(value)) freezeCapabilities(child);
@@ -6,14 +7,14 @@ function freezeCapabilities(value) {
6
7
  }
7
8
  return value;
8
9
  }
9
- function acpProviderCapabilities(providerKey, negotiated, configuration = "managed", authenticationFlows = []) {
10
+ function acpProviderCapabilities(providerKey, negotiated, configuration = "managed", authenticationFlows = [], sessionInteractions, permissionMapping = { mapping: "once-only-v1" }) {
10
11
  return freezeCapabilities(parseAgentCapabilities({
11
- protocolVersion: 10,
12
+ protocolVersion: 12,
12
13
  providerKey,
13
- sessions: { create: true, resume: negotiated.agentCapabilities.loadSession === true || negotiated.agentCapabilities.sessionCapabilities?.resume != null, branch: { kind: "unsupported" } },
14
+ sessions: { create: true, resume: sessionInteractions?.mapping !== "grok-folder-trust-v1" && (negotiated.agentCapabilities.loadSession === true || negotiated.agentCapabilities.sessionCapabilities?.resume != null), branch: { kind: "unsupported" } },
14
15
  turns: { interactionModes: ["default"], interrupt: true, steer: { kind: "unsupported" } },
15
16
  requests: {
16
- approval: { kind: "supported", modes: [{ persistence: "once", scopeKinds: ["exact_action"] }] },
17
+ approval: acpPermissionCapability(permissionMapping),
17
18
  elicitation: { kind: "supported", fieldKinds: ["single_select", "multi_select", "boolean"], maxFields: 16, sensitiveFields: false }
18
19
  },
19
20
  context: { usage: { kind: "unsupported" }, compaction: { kind: "unsupported" } },
@@ -127,8 +127,6 @@ class AcpConfigurationCatalogState {
127
127
  this.maxSnapshotBytes = maxSnapshotBytes;
128
128
  this.capability = capability;
129
129
  }
130
- maxSnapshotBytes;
131
- capability;
132
130
  snapshot;
133
131
  bindings = /* @__PURE__ */ new Map();
134
132
  fingerprint;
@@ -4,7 +4,6 @@ class AcpConfigurationError extends Error {
4
4
  this.reasonCode = reasonCode;
5
5
  this.name = "AcpConfigurationError";
6
6
  }
7
- reasonCode;
8
7
  }
9
8
  function invalidConfigurationCatalog() {
10
9
  throw new AcpConfigurationError("acp_configuration_catalog_invalid", "ACP configuration cannot be represented faithfully within the declared bounds.");