dsh-bailinghub 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/PRIVACY.md +62 -12
  3. package/README.md +50 -20
  4. package/SECURITY.md +47 -6
  5. package/docs/AGENT_CLIENT_CONTRACT.md +201 -16
  6. package/docs/CAPABILITY_FEEDBACK.md +199 -0
  7. package/docs/COMPATIBILITY.md +63 -5
  8. package/docs/CROSS_SYSTEM_CONVERSATIONS.md +138 -0
  9. package/docs/GENERATED_ARTIFACTS.md +77 -0
  10. package/docs/GETTING_STARTED.md +37 -11
  11. package/docs/GETTING_STARTED.zh-CN.md +32 -12
  12. package/docs/INVOCATION_RECOVERY.md +182 -0
  13. package/docs/MIGRATION_VNEXT.md +78 -7
  14. package/docs/PROJECT_BOUNDARIES.md +4 -1
  15. package/docs/README.zh-CN.md +59 -18
  16. package/docs/RELEASE_NOTES_v0.5.0.md +79 -0
  17. package/docs/RELEASE_NOTES_v0.6.0.en.md +39 -0
  18. package/docs/RELEASE_NOTES_v0.6.0.md +39 -0
  19. package/docs/SESSION_TOOL_REUSE.md +213 -0
  20. package/docs/TASK_CONTROL.md +183 -0
  21. package/docs/UPGRADE_v0.6.0.en.md +71 -0
  22. package/docs/UPGRADE_v0.6.0.md +73 -0
  23. package/lib/artifact-store.js +56 -0
  24. package/lib/artifacts.js +132 -0
  25. package/lib/authorizations.js +23 -8
  26. package/lib/capability-feedback.js +138 -0
  27. package/lib/conversation-archive-store.js +2 -2
  28. package/lib/conversation-outbox.js +37 -7
  29. package/lib/index.js +7 -1
  30. package/lib/invocation-journal.js +223 -0
  31. package/lib/invocation-store.js +275 -0
  32. package/lib/runtime.js +1126 -174
  33. package/lib/session-scope-store.js +2 -2
  34. package/lib/session-scope.js +146 -30
  35. package/lib/session-task-store.js +275 -0
  36. package/lib/session-task.js +237 -0
  37. package/lib/session-tool-cache.js +168 -0
  38. package/lib/session-tools.js +240 -0
  39. package/lib/subject-display.js +39 -0
  40. package/lib/system-info.js +76 -0
  41. package/lib/tool-catalog.js +38 -0
  42. package/lib/transport.js +34 -0
  43. package/package.json +14 -3
@@ -1,17 +1,187 @@
1
1
  # Agent Client Host Adapter Contract
2
2
 
3
- Status: native Agent Client contract for `dsh-bailinghub@0.4.0`, paired with
4
- `bailinghub-mcp-server@0.4.0` and recommended BailingHub Core `0.6.1` (minimum API version
5
- `0.6.0`). This contract is separate from the legacy static `0.1.x` path. Version 0.3.0 supported user-managed connections but did not include
3
+ The additive [session tool reuse contract](SESSION_TOOL_REUSE.md) is explicitly
4
+ enabled with `createAgentClientPlugin({ toolLifecycle: 'session', ... })`. It uses
5
+ lazy current-turn target preparation for one or many selected authorizations,
6
+ and retains bounded declarations between messages. The lifecycle descriptions
7
+ below remain the default `active_turn` behavior unless that option is enabled.
8
+ Neither mode changes fixed scope, business approval or original-invocation recovery.
9
+
10
+ ## Authorization subject display (0.5.0)
11
+
12
+ The business backend may supply `subject_display: { name }` for the subject actually approved by
13
+ the user. A subject can be an organization, account, project, department, workspace or another
14
+ business entity; the upstream contract does not prescribe a store or any particular product.
15
+ The name is display data, separate from both trusted authorization identity and `system_info`
16
+ (the product's purpose). Only the trusted business backend supplies this name; the DSH model,
17
+ local alias, device label and principal identifiers are not sources for it.
18
+
19
+ The matched SDK exposes these additive fields on `login`, `status` and every `connectionsList`
20
+ entry, and the plugin passes them to its host:
21
+
22
+ | Field | Meaning |
23
+ | --- | --- |
24
+ | `subjectDisplay` | `{ name: string }`, or `null` when unavailable |
25
+ | `subjectDisplayStatus` | `provided`, `missing`, `unsupported` or `unavailable` |
26
+ | `subjectDisplaySource` | `verified` after the SDK reads the original Session, `cache` for display-only local data, otherwise `none` |
27
+ | `subjectDisplayCacheStatus` | SDK auxiliary cache outcome: `saved`, `storage_error` or `not_cached` |
28
+ | `displayLabel` | Plugin presentation label: the provided name, otherwise `Authorization name pending sync` |
29
+
30
+ Names are trimmed, nonempty, at most 120 UTF-16 code units, with C0/C1 controls and Unicode line
31
+ separators U+2028/U+2029 and unpaired surrogate code units rejected. Valid Unicode emoji are
32
+ preserved. Only the `name` field enters model assembly. A matching name
33
+ does not establish an identity or a business relationship. Cached display data proves no current
34
+ authorization; a real identity-validation failure still blocks the complete original scope.
35
+ An old SDK without these fields yields `unsupported`; a supported response without a name yields
36
+ `missing`. Neither condition prevents the existing authorized tools from working. A display-cache
37
+ write error stays auxiliary and cannot replace a scope/archive `storage_error` or `recovery_gap`.
38
+
39
+ Custom hosts may omit a user-entered remark/name field and render the returned business name.
40
+ Keep the internal `connectionName` selector and fixed `connectionKey` independently; do not rename,
41
+ merge or recreate credentials because two subjects have the same name or an existing subject is
42
+ renamed. A host may combine a separately trusted product name with this subject name for display.
43
+ When unavailable, localize the generic pending-name message; never guess the name from a product
44
+ description, local alias, principal identifier or list order. Older hosts can keep their current
45
+ connection-management UI unchanged.
46
+
47
+ `setSessionScope`, `getSessionScope` and `restoreSessionScope` add `subjectDisplay`,
48
+ `subjectDisplayStatus` and `subjectDisplaySource` to each visible authorization. The legacy `label`
49
+ is the frozen historical value: newly selected scopes capture the supplied name (or the generic
50
+ pending-name label), while existing stored labels remain byte-for-byte unchanged. Hosts should
51
+ render the new display fields for current names, not reinterpret an old `label` as verified metadata.
52
+
53
+ After the whole scope is validated, current display fields are held separately in coordinator
54
+ memory. They do not enter binding comparisons, persisted v1/v2 scope records or archive identity.
55
+ Single, same-system and cross-system model directories include `subject_display`,
56
+ `subject_display_status` and `subject_display_source`, separately from `system_description` and
57
+ `metadata_status`. The current directory `label` and attributed tool-result label use this display
58
+ projection; the original `authorization_ref` remains the only model target selector.
59
+ Scope revalidation refreshes current names without changing the selected members, original Agent
60
+ Sessions, frozen scope revision, historical labels, visible events or archive context. Normal archive
61
+ ACK writes continue their existing CAS sequence; display refresh itself writes no archive record.
62
+
63
+ ## System descriptions (0.5.0)
64
+
65
+ Core 0.7.0 and SDK 0.5.0 add optional `transport.getSystemInfo({ connectionKey,
66
+ workspace, expectedBinding, signal })`. After the entire selected scope has passed identity
67
+ validation and before first model assembly, the adapter reads one description for each original
68
+ selected member. Requests include the original Hub/Client/workspace/Agent Session binding and
69
+ never user text, tools, or a run identifier. They do not create business runs or load business
70
+ context. Single, same-system multi-authorization and cross-system conversations use the same
71
+ description projection. The existing same-system first-turn run policy remains unchanged.
72
+
73
+ The response schema is `bailing.agent-system-info.v1`. Only `system.name`, `summary`, `domains`,
74
+ and `boundaries`, their metadata status/revision, and availability enter the model directory.
75
+ System references derive from the verified binding, including for a single authorization or
76
+ same-system group. Product purpose describes typical use; it does not grant an action or prove
77
+ that any tool is enabled. `not_loaded` means not yet loaded, not no capabilities. Product purpose,
78
+ authorization limits, tool loading and availability remain separate fields.
79
+
80
+ Descriptions are data, not executable model instructions. Missing configuration, an absent SDK
81
+ method, an unsupported old Core or a temporary metadata failure degrades description fields to
82
+ unknown without changing existing capability search. A 401/403 or changed response binding
83
+ blocks the original whole scope. Scope storage errors retain their existing priority. No description
84
+ is persisted in the scope, Session events or archive outbox; each turn reloads against the original
85
+ complete binding, so mutable labels or another runtime cannot supply stale system identity.
86
+ Cancelled or superseded requests cannot publish late metadata or reactivate business tools.
87
+
88
+ An exact HTTP 404 `route_unavailable` is different from unknown metadata: the selected target
89
+ remains in the directory with `metadata_status: "unknown"`, `availability: "unavailable"` and
90
+ directory-only `availability_reason: "route_unavailable"`. It is not old-version unsupported or
91
+ an authorization grant/revocation. Other ambiguous failures stay unknown. The Core wire's
92
+ `unavailable_reason` still accepts only the documented runtime/direct-switch reasons. A later
93
+ turn retries the same original binding and clears the directory reason after successful lookup.
94
+
95
+ Hosts keep the existing scope/restore/archive interfaces. The scope view now consistently includes
96
+ `clientAppId` and `systemRef` for all selected authorizations; this is additive and does not change
97
+ stored v1/v2 records. No local hard-coded product dictionary or extra body-reporting channel is
98
+ required. A host may keep a separately controlled fallback when metadata is unavailable, but must
99
+ not infer identity from local labels or expand the selected scope.
100
+
101
+ ## Cross-system extension (0.5.0)
102
+
103
+ This extension requires SDK 0.5.0 and Core 0.7.0 with migration 058 applied. Subject display
104
+ additionally requires migration 059. Existing same-system behavior, signatures and v1 records
105
+ remain supported; old selected scopes never expand to include newly available targets.
106
+
107
+ The host selects fixed connection keys from one normalized Hub. Different Client Apps or
108
+ workspaces form different capability sources. Each target must have a distinct original Agent
109
+ Session; two selected routes sharing a Session are rejected. A scope never expands to another Hub,
110
+ registry default, newly added connection, or surviving subset after one member is lost.
111
+
112
+ Cross-system scope uses persisted `bailing.agent-session-scope.v2` with shared `binding: { hubUrl }`
113
+ and `authorizations` containing `{ connectionKey, sessionId, label, workspace, clientAppId }`.
114
+ The host view keeps `bailing.agent-session-scope.v1` and adds `targetMode: "multi_system"` and
115
+ per-authorization `clientAppId`/`systemRef`. Existing `authorizationRef`, key and lifecycle fields
116
+ retain their meaning. System references are opaque identifiers for capability sources; labels
117
+ remain descriptive data, not business identity or object mappings. The subject-display extension
118
+ above separates current business names from historical local labels.
119
+
120
+ Selection/restoration verifies the whole original group and calls SDK
121
+ `getConversationArchiveCapabilities({ members })`. Support requires
122
+ `schema: "bailing.agent-conversation-audit-capabilities.v1"`, `cross_binding_members: true`
123
+ and `member_bindings: "session-client-route.v1"`. Missing support produces
124
+ `CROSS_SYSTEM_SCOPE_UNSUPPORTED` and no cross-system business run. Temporary discovery failures
125
+ remain retryable under the original selection; confirmed authorization replacement remains blocked.
126
+
127
+ Initial prompt assembly registers the target directory, capability search and known-invocation
128
+ recovery tools, without starting any business run. In this mode `search_business_capabilities`
129
+ requires `{ authorization_ref, query, limit? }`. Its bounded query (up to 500 characters) is the
130
+ task projection passed as `userInput` to that target's first `startTurn` in the current turn.
131
+ The original visible user text stays in the independent archive. Subsequent searches reuse that
132
+ target's run. Omission/unknown target fails before dispatch; another selected target is not
133
+ started merely because its authorization is available. Authorization and archive membership checks
134
+ may still inspect the full original set.
135
+
136
+ Tools are grouped only by capability-source binding and complete declaration. Host-issued
137
+ `bh_...` aliases keep same-named tools from different sources separate, even with identical schemas.
138
+ Each alias enumerates only its own `authorization_ref` values and wraps unchanged business
139
+ `arguments`. The server receives the original tool name. Revisions, invocation IDs, argument
140
+ snapshots and original target bindings remain fixed on replay. The SDK receives host-only
141
+ `expectedBinding: { hubUrl, clientAppId, workspace, sessionId }` together with an explicit key
142
+ on status and all business calls. Model arguments cannot replace these fields.
143
+ Explicit search prioritizes that target's results inside the twelve-schema window while retaining up to 64 callable tools;
144
+ same-named capabilities on earlier targets cannot permanently crowd it out.
145
+
146
+ Recovery accepts only a known original invocation. When needed in a later live turn, it opens
147
+ only that original target's run with a recovery-specific input and resumes the original invocation;
148
+ it does not create a replacement invocation. The [durable recovery journal](INVOCATION_RECOVERY.md)
149
+ can restore original binding metadata after process restart; scope or archive restoration alone
150
+ cannot. Explicit Core resume may continue the original approved operation.
151
+ Cancellation and superseding turns cannot register tools or dispatch a new write from a late start.
152
+ Each cross-system turn owns an AbortSignal combined with the host's signal. SDK dispatch checks
153
+ that signal after local IO and before HTTP; an in-flight write with an unknown outcome keeps its
154
+ original invocation identity. Completion summaries and archive upload are separate from business
155
+ dispatch cancellation and may still synchronize after a turn ends.
156
+
157
+ Cross-system archives use `bailing.agent-conversation-outbox.v2`. Context binding is `{ hubUrl }`;
158
+ each member retains `{ connectionKey, hubUrl, clientAppId, workspace, expectedSessionId, label }`.
159
+ Event/ACK schemas, random archive identity, source hashes, ordering, local capture-gap reporting
160
+ and CAS semantics remain unchanged. The SDK uses explicit cross-binding create v2 and each
161
+ member's own credential to confirm; the Core verifies each original app/route/Session and run link.
162
+ The full transcript remains available only through the management audit read boundary.
163
+
164
+ Query minimization, object mapping and step planning are Agent responsibilities. The runtime
165
+ enforces target/tool/invocation authority; it does not establish a deterministic dependency DAG,
166
+ cross-system transaction, automatic rollback or field-level data-transfer policy. Business systems
167
+ continue owning their capabilities, permission checks, approvals and data semantics. See the
168
+ [user and host guide](CROSS_SYSTEM_CONVERSATIONS.md).
169
+
170
+ Status: native Agent Client contract for `dsh-bailinghub@0.5.0`, paired with
171
+ `bailinghub-mcp-server@0.5.0` and BailingHub Core `0.7.0`. The same-system scope and archive
172
+ baseline was introduced in plugin/SDK 0.4.0 and Core 0.6.0 (recommended historical Core 0.6.1).
173
+ This contract is separate from the legacy static `0.1.x` path. Version 0.3.0 supported user-managed
174
+ connections but did not include
6
175
  explicit conversation scope, multi-authorization tool selection, or the visible conversation archive.
7
176
 
8
177
  ## Same-System Authorization Selection
9
178
 
10
- This increment supports multiple independently authorized identities for one public
11
- `Hub + clientAppId + workspace` binding in one DSH conversation. It does not combine different
12
- systems or routes, alter business capability declarations, or change Core authorization rules.
179
+ The retained same-system path supports multiple independently authorized identities for one
180
+ public `Hub + clientAppId + workspace` binding in one DSH conversation. It uses the existing v1
181
+ records and shared capability declarations. The cross-system v2 path above handles different
182
+ sources; neither path changes Core authorization or business approval rules.
13
183
 
14
- Version 0.4.0 changes the default: a new conversation with no selected scope, or an explicitly
184
+ Version 0.4.0 changed the default: a new conversation with no selected scope, or an explicitly
15
185
  empty `connectionKeys: []`, is ordinary chat. It starts no BailingHub run and exposes no BailingHub
16
186
  business tools. Browser authorization, the registry's current connection, and the four bootstrap
17
187
  fields do not select a conversation's scope. There is no automatic discovery-and-enable fallback.
@@ -57,7 +227,7 @@ attribution; all injected context still shares the local Agent/model boundary de
57
227
  Business definitions with the same name, description, input schema, and governance are registered
58
228
  once.
59
229
  Conflicting declarations are not merged for execution. Availability remains specific to each
60
- authorization, and the conversation's total active business-tool limit remains 12. In a
230
+ authorization, and the conversation's retained business-tool limit is 64, with at most 12 full schemas shown at once. In a
61
231
  multi-authorization session, each shared definition wraps its unchanged business schema:
62
232
 
63
233
  ```json
@@ -80,9 +250,10 @@ invocation known to this conversation and uses the original binding; it accepts
80
250
  authorization selector. Pending approval and unknown dispatch outcomes follow the same
81
251
  exact-invocation recovery rules as the baseline. Removing or selecting another default must not
82
252
  retarget an existing invocation.
83
- The local invocation map survives later turns of the same live conversation. It is not persisted
84
- across process restarts or copied into new conversations, and unknown invocation ids fail closed.
85
- This increment does not provide durable task recovery across those boundaries.
253
+ The local invocation map survives later turns of the same live conversation. The
254
+ [durable recovery journal](INVOCATION_RECOVERY.md) can restore trusted original binding metadata
255
+ across process restarts, never into another conversation. Unknown IDs fail closed. This is
256
+ original-invocation recovery, not durable automatic continuation of a whole task.
86
257
 
87
258
  On multi-authorization completion, the adapter freezes one deterministic summary of each run's
88
259
  own governed calls and synchronizes that run separately. It does not send the combined visible
@@ -125,8 +296,10 @@ frozen scope unchanged. The host must open a new conversation, not treat that re
125
296
  successful selection of the requested keys. Revision values may advance more than once
126
297
  during selection; always use the returned value for the next compare-and-swap request.
127
298
 
128
- Each returned `authorizations` entry has exactly the public host-facing fields
129
- `{ authorizationRef, connectionKey, label, workspace }`. The selection accepts at most 64 unique
299
+ Each `authorizations` entry retains the public host-facing fields
300
+ `{ authorizationRef, connectionKey, label, workspace }`. Version 0.5.0 consistently adds
301
+ `clientAppId`, `systemRef` and the current display fields documented above for single, same-system
302
+ and cross-system scopes. The selection accepts at most 64 unique
130
303
  connection keys. The trusted host owns `sessionId`: it must remain stable when reopening the same
131
304
  conversation and be unique within that store's namespace. Do not let the model or an untrusted
132
305
  client choose another conversation's id, edit scope records, or control the storage namespace.
@@ -184,8 +357,10 @@ Restoring a scope does **not** restore an invocation, approval, pending completi
184
357
 
185
358
  ### Independent visible conversation archive
186
359
 
187
- The visible archive requires SDK `0.4.0` and Core APIs introduced in `0.6.0`; the recommended
188
- Core release is `0.6.1`. Earlier `0.3.0` SDK/plugin packages do not provide this contract.
360
+ The original same-system visible archive uses SDK APIs introduced in `0.4.0` and Core APIs
361
+ introduced in `0.6.0`; the historical recommended Core release is `0.6.1`. For this release,
362
+ use SDK `0.5.0` with Core `0.7.0`, including cross-system member support. Earlier `0.3.0` SDK/plugin
363
+ packages do not provide this contract.
189
364
  After a nonempty scope is frozen, the adapter captures claimed user text, every durable `assistant/message` text block, turn start/end, and verified original run links. It ignores
190
365
  `assistant/chunk`, hidden reasoning, attachments, raw provider requests, and arbitrary tool payloads.
191
366
  The archive is one record for the complete fixed authorization set; per-authorization run summaries
@@ -357,7 +532,8 @@ exactly `bailing.agent-turn-context.v1`. Its runtime result is:
357
532
  }
358
533
  ```
359
534
 
360
- At most 12 active tools are accepted. Each tool must use the Core tool-name grammar, an
535
+ At most 12 active tools are accepted per Core response. Further searches can accumulate
536
+ up to 64 retained tools in this active turn; see [discovery lifecycle](CAPABILITY_FEEDBACK.md). Each tool must use the Core tool-name grammar, an
361
537
  object-rooted input schema, and complete governance metadata (`scope`, `risk`,
362
538
  `approval_required`, `readonly`, and `idempotent`).
363
539
  Both revision fields are required lowercase 64-character SHA-256 values; shorter labels or
@@ -503,3 +679,12 @@ Missing/invalid configuration, missing SDK, failed authorization, failed Core co
503
679
  collision, or unsupported DSH Code Mode removes the Core business tools and inserts a concise
504
680
  status section. The local Agent may continue using unrelated local tools, but it is explicitly
505
681
  told not to claim a BailingHub business action was executed.
682
+
683
+
684
+ ## Original invocation recovery after reopening
685
+
686
+ See [the durable recovery contract](INVOCATION_RECOVERY.md) for the additive
687
+ `invocationStore`, `getSessionInvocationStatus(sessionId)` and
688
+ `restoreSessionInvocations(sessionId)` host interfaces. They do not replace the fixed
689
+ scope, original visible-event archive, or attachment store. A host using its own scope
690
+ store must explicitly provide durable invocation storage to support full reopening.
@@ -0,0 +1,199 @@
1
+ # Discover capabilities and recover the right operation
2
+
3
+ DSH 0.6.0 improves the information the Agent receives. Use the paired SDK 0.6.0 and Core 0.8.0 for authoritative counts and feedback. Existing authorization, approval, fixed conversation scope and archive rules still apply.
4
+
5
+ ## What users should notice
6
+
7
+ For example, an Agent checks warehouse stock and then updates a shop product.
8
+
9
+ - A currently loaded shop tool can be called directly for its selected account.
10
+ - The Agent can discover product creation, create a product, discover a query tool,
11
+ check the result, and return to product creation without another search. Searching
12
+ warehouse tools also retains valid shop tools within the current turn.
13
+ - Only 12 full schemas are shown at a time; up to 64 discovered business tools remain
14
+ registered and directly callable with their original target and known parameters.
15
+ This is a tool-type budget, not a limit on operations, products or task duration.
16
+ - Hosts can opt into [cross-turn declaration reuse](SESSION_TOOL_REUSE.md) with
17
+ `toolLifecycle: 'session'`. A cached tool is prepared with current target context
18
+ before use in a new turn. The default remains `active_turn`.
19
+ - If the shop request was sent but its response is unconfirmed, recover only its
20
+ original invocation. A new search or tool name must not produce another write.
21
+
22
+ Business systems still define their own product fields, validation and approvals.
23
+ This change adds no stock synchronization, cross-system transaction or rollback.
24
+
25
+ ## Search result meanings
26
+
27
+ The default `search_business_capabilities` keeps its existing parameters. Opt-in
28
+ session mode adds `tool_name` for exact cached declaration preparation and retrieval;
29
+ a broad `query` without `tool_name` still discovers capabilities. Cross-system search
30
+ requires the original `authorization_ref` and a minimal target-specific query.
31
+ Single-account and same-system selection continue to work.
32
+
33
+ | Field | Meaning |
34
+ | --- | --- |
35
+ | `discovery.returned_count` | Candidates actually returned for this search target |
36
+ | `discovery.authorized_total` | Tools in the same authorization-filtered catalog; `null` when unknown |
37
+ | `discovery.matched_total` | `null`: ranked candidates do not establish an exact match count |
38
+ | `discovery.truncated`, `has_more` | Whether authorized catalog candidates were omitted by the search limit; `null` when unknown |
39
+ | `discovery.truncation_scope` | `authorized_catalog` when reported, otherwise `unknown` |
40
+ | `discovery.mode` | `ranked_candidates`, or `unknown` for older/malformed optional metadata |
41
+ | `discovery.pagination` | `unsupported`; the result does not promise complete paging |
42
+ | `active_tools` | Business tools ready for dispatch in the current turn, with their target references where applicable; session-mode cached preparation guards are listed separately in `cached_tools` |
43
+ | `toolset.active_count`, `limit` | Current registered business-tool count and shared ceiling of 64; search/resume/local tools do not consume this budget |
44
+ | `visible_tools`, `toolset.visible_count`, `visible_limit` | Current full-schema presentation window, capped at 12 across targets; absence here does not mean unloaded |
45
+ | `toolset.retained_outside_window_count` | Registered tools outside that window, still callable using the exact schema already discovered |
46
+ | `toolset.lifetime` | `active_turn`: one user message through its completion/cancellation, including all intermediate searches and operations |
47
+ | `toolset.reuse`, `cache.lifetime` | `session_runtime` only when the host opted into cross-turn declaration reuse; does not change the current-run execution lifetime |
48
+ | `toolset.generation` | Local collection generation, separate from Core's capability revision; compare only within the same runtime/session |
49
+ | `toolset.omitted_tool_count` | Compatible cached candidates omitted by the shared budget, not all unreturned Core capabilities |
50
+ | `toolset.conflicting_tool_count` | Excluded shared declaration conflicts plus per-target contradictory catalog entries |
51
+ | `toolset.catalog_conflict_count` | The per-target contradictory catalog portion of that count |
52
+
53
+ Multi-account results place `discovery` under each searched `authorizations[]`
54
+ entry. The top-level `toolset` covers the whole conversation, not just that target.
55
+ The existing top-level `omitted_tool_count` remains as a compatibility alias for
56
+ the shared-budget count. `toolset.update=merge` describes the registration policy, consistently for one or
57
+ many accounts. Per-target `candidate_update=merge` means the new results were added
58
+ under the same authoritative catalog revision; `reset` with
59
+ `invalidation_reason=capability_revision_changed` invalidates that target's old
60
+ cache before retaining the new response. Tools from other targets keep their own
61
+ revisions. `evicted_count` counts candidates removed by the per-target cache cap
62
+ in this update; it is not a catalog total.
63
+
64
+ If the same target, revision and tool name claim different declarations, that
65
+ name is quarantined for the revision. `conflicting_tools` and structured
66
+ `feedback.category=capability_changed` explain the exclusion. Other valid tools
67
+ remain available. The runtime never silently reinterprets old arguments under the
68
+ new declaration. An authoritative new revision can remove the quarantine.
69
+
70
+ An unrelated query can still return ranked candidates. Neither an empty result
71
+ nor a transport failure proves that the entire business system lacks a feature.
72
+ Optional metadata from older components is unknown, never a fabricated zero.
73
+
74
+ ## Long-task lifecycle and safety
75
+
76
+ Discovery merges only tools actually returned for selected authorizations; it does
77
+ not preload a system's whole catalog. An empty successful search with an unchanged
78
+ revision or a temporary search failure preserves prior valid candidates. A new
79
+ revision clears that target's old candidates even if the new response is empty.
80
+ Core still checks the original identity, allowed surface and revision before each
81
+ new invocation; local retention does not extend permission or skip approval.
82
+
83
+ In the default `active_turn` mode, each target retains up to 64 recently
84
+ discovered/used declarations. The shared
85
+ registry also caps at 64, favoring recently searched/used tools; the schema window
86
+ favors the latest search and subsequent use. Candidates outside the registry cap
87
+ need discovery again. Tools merely outside `visible_tools` do not. This keeps
88
+ memory and prompt costs bounded without forcing a search for every call.
89
+
90
+ With `toolLifecycle: 'session'`, the declaration cache instead shares a total
91
+ budget of 64 target-tool pairs and 2 MiB of JSON across the living Session. Its
92
+ 12-schema presentation window remains separate. New turns prepare only targets
93
+ actually needed, using new context and runs; exact valid cached declarations
94
+ avoid an extra search request. Core's existing `startTurn` may still perform
95
+ bounded internal discovery. See the [session lifecycle contract](SESSION_TOOL_REUSE.md)
96
+ for `cached_tools`, target readiness and preparation-only call handling.
97
+
98
+ The registry applies differences rather than clearing all registrations on every
99
+ search. Unchanged definitions keep their registration; changed schemas or target
100
+ enumerations are retired individually. Searches are serialized within the turn;
101
+ independent calls keep their original invocation bindings while discovery runs.
102
+ An invocation already issued keeps its original arguments, revision, authorization
103
+ and ID regardless of cache eviction. Resume never creates a replacement write.
104
+
105
+ Completion, cancellation, scope failure and a new user turn retain their existing
106
+ boundaries: ended turns cannot accept late search results or reactivate tools.
107
+ The default cache ends with the active turn. Opt-in session-mode declarations
108
+ can survive between turns in the same living runtime; they are never reused as
109
+ authorization or old run context, and are not persisted across restarts. Archive
110
+ events, original run links, ACK/CAS and attachment upload identities are unchanged.
111
+ Original invocation metadata can be persisted separately by the
112
+ [durable recovery](INVOCATION_RECOVERY.md); it does not restore the old tool cache.
113
+
114
+ ## Structured failure feedback
115
+
116
+ Failures carry `bailing.agent-feedback.v1` with `category`, `code`, `origin`,
117
+ `operation`, `dispatch`, `retryable`, `next_action`, a controlled `message`, and the
118
+ original `invocation_id` when one exists. SDK-defined feedback is projected through
119
+ a safe allowlist; raw transport messages and arbitrary extra fields are omitted.
120
+
121
+ `retryable` refers only to `next_action`. It never grants permission to issue a new
122
+ business invocation. `dispatch=not_dispatched` is used only for a known stage; a
123
+ transport failure after invoking cannot establish that the request was not sent.
124
+
125
+ | Category | Intended next step |
126
+ | --- | --- |
127
+ | `tool_not_loaded` | Rediscover the same selected target, unless an existing invocation needs recovery |
128
+ | `capability_changed` | Check the current declaration; an original recovery stays bound to the original invocation |
129
+ | `transport_unavailable` | Retry discovery or original identity validation/recovery as indicated |
130
+ | `authorization_unavailable` | Restore/confirm the original scope or reauthorize; do not use defaults or a surviving subset |
131
+ | `unsupported` | Check the supported component combination; arbitrary 404/503 errors are not version evidence |
132
+ | `invocation_outcome_unknown` | Resume or inspect the original invocation; never create a replacement write |
133
+ | `cancelled`, `invalid_request`, `unknown_failure` | Follow the explicit action; do not guess a business retry |
134
+
135
+ Core's `reconciliation_required` result remains a non-auto-retry result. Its
136
+ feedback says `inspect_original`; ordinary resume may only replay the recorded
137
+ uncertainty and can require an operator to verify the result.
138
+
139
+ An authoritative original-record lookup failure also requires inspection:
140
+ `code=invocation_not_found`, `category=invocation_outcome_unknown`,
141
+ `next_action=inspect_original`, `retryable=false`, `original_outcome=unverified`.
142
+ The plugin stops the current recovery poll and preserves the original invocation ID.
143
+ For example, a host may have saved a shop listing's dispatch fence before it crashed,
144
+ while the request never reached Core. That is only one possible cause: a missing
145
+ record does not prove that the listing was never performed. Do not recreate it from
146
+ the conversation or switch accounts. Generic 404/network errors cannot establish
147
+ this condition. See [recovery failure rules](INVOCATION_RECOVERY.md#failure-and-compatibility-rules).
148
+
149
+ ## Client host integration
150
+
151
+ Standard native DSH uses the existing `tools/execute` hook. Error results retain
152
+ `isError=true` and the original host error information, while carrying the same
153
+ safe feedback in `result.meta.bailinghub.feedback` and JSON text content
154
+ `{"feedback": ...}`. Ordinary multi-target search can succeed overall while a
155
+ target entry contains `state=unavailable` plus its own `feedback`.
156
+
157
+ Only BailingHub-owned tool failures are decorated. Host `UNKNOWN_TOOL` is classified
158
+ as retired only for a previously registered business name in that conversation
159
+ which is no longer registered. Other plugins, unknown names, currently registered
160
+ tools hidden by host presentation, and reserved tools are not reclassified.
161
+
162
+ Two read-only runtime methods support hosts which intercept dispatch earlier:
163
+
164
+ ```js
165
+ runtime.getSessionToolState(sessionId)
166
+ // { state, toolset, active_tools, visible_tools }; no HTTP requests or new business run
167
+
168
+ runtime.getToolDispatchFeedback(sessionId, {
169
+ toolName, callId, errorCode: 'UNKNOWN_TOOL',
170
+ })
171
+ // feedback or null; call only after the host registry actually rejects lookup
172
+ ```
173
+
174
+ Pass the original call ID. If that call already has an invocation, feedback points
175
+ to that original ID instead of suggesting a new operation. These methods do not
176
+ execute or restore tools and must not be used to bypass normal scope validation.
177
+ Do not filter dispatch against `visible_tools` or the latest search response: the
178
+ native registry and `active_tools` determine retained availability. Do not cache a
179
+ stale copy of the registry or demand discovery before every call. Keep all new
180
+ fields in model-facing search results. Custom hosts which only allow names in the
181
+ current schema window need to support retained native registry dispatch; otherwise
182
+ their presentation layer can still produce an artificial `UNKNOWN_TOOL`.
183
+ No new user/assistant message upload path is needed.
184
+
185
+ Session-mode hosts must also preserve `targets`, `cached_tools`, `contexts`,
186
+ `tool_schemas` and the preparation result's `business_operation_performed=false`.
187
+ An unprepared cached tool name can return preparation and schema without performing
188
+ the requested operation. The model must read current context and issue a new call
189
+ before a new business operation; replaying the preparation's call ID does not
190
+ convert it into an operation. Do not gate these native preparation guards against
191
+ `active_tools` alone. Read-only tool-state methods do not prepare targets.
192
+
193
+ Tested with the public native registry `@deepseek-ai/dsh-tools@0.1.1-rc.2` and real
194
+ Cordis/DSH Sessions. A custom host must verify the hook and preserve the feedback
195
+ carrier through its own model loop. Simply adding properties to a thrown Error is
196
+ insufficient: the host may discard them. Older SDK/Core combinations retain their
197
+ business flows, but may lack precise counts or authoritative error detail.
198
+
199
+ These discovery and tool-lifecycle changes require no credential, scope or archive conversion. Follow the [release upgrade guide](UPGRADE_v0.6.0.en.md) for the complete release, including Core migrations for attachments, limits and task controls.
@@ -1,6 +1,59 @@
1
+ # Current 0.6.0 pairing
2
+
3
+ Use Core 0.8.0, SDK 0.6.0 and DSH 0.6.0 for attachments, original receipts and task controls. Existing unenrolled flows retain their earlier protocol minima. Task enrollment persists: older hosts cannot omit task binding. See [upgrade](UPGRADE_v0.6.0.en.md).
4
+
1
5
  # Compatibility
2
6
 
3
- ## Native Agent Client 0.4.0
7
+ ## Capability feedback
8
+
9
+ The additive [capability feedback contract](CAPABILITY_FEEDBACK.md) requires the paired
10
+ Core 0.8.0 / SDK 0.6.0 / DSH 0.6.0 release set for complete counts and error detail. Older unenrolled combinations keep their existing business behavior with unknown optional metadata.
11
+
12
+
13
+ ## Native Agent Client 0.6.0
14
+
15
+ | Component | Release pairing / requirement |
16
+ | --- | --- |
17
+ | DeepSeek Harness | `0.1.1-rc.2`; real Session and native Cordis lifecycle |
18
+ | Node.js | `^22.19.0` or `>=24.0.0` |
19
+ | DSH tool presentation | Native Tool Mode; Code Mode deliberately degraded |
20
+ | Generic Agent Client SDK | Exact `bailinghub-mcp-server@0.6.0` via `./sdk` |
21
+ | BailingHub Core | `bailinghub@0.8.0`, with outstanding migrations through 062 applied |
22
+ | Selected scope | Single account, same-system multiple accounts, or different Client Apps/workspaces on one Hub and audit domain |
23
+ | Original authorization | A distinct original Agent Session for every selected target |
24
+ | Persistence | Existing same-system v1 scope/outbox and cross-system v2 records |
25
+
26
+ Install `dsh-bailinghub@0.6.0`; its ordinary dependency installs the exact SDK automatically.
27
+ Core 0.6.1 and SDK/plugin 0.4.0 remain the historical same-system baseline, not an alternative
28
+ pairing for new cross-system features. See the [upgrade steps](MIGRATION_VNEXT.md) and
29
+ [release scenario](RELEASE_NOTES_v0.5.0.md).
30
+
31
+ ### Authorization subject display
32
+
33
+ Core 0.7.0, SDK 0.5.0 and plugin 0.5.0 support business-supplied authorization names. New
34
+ names are optional: an old SDK reports `unsupported`, a missing business name reports `missing`,
35
+ and neither blocks the existing tools. A list may show cached display data without claiming it
36
+ is fresh identity evidence. Current names and cache-write status remain separate from scope,
37
+ credential, archive and business errors. Existing v1/v2 records need no conversion or new labels;
38
+ names never replace their original key, binding or Session. See the
39
+ [display contract](AGENT_CLIENT_CONTRACT.md#authorization-subject-display-050).
40
+
41
+ ### Cross-system scope
42
+
43
+ Requires Core 0.7.0, SDK 0.5.0 and plugin 0.5.0. Core must advertise
44
+ `cross_binding_members: true` and `member_bindings: "session-client-route.v1"` through
45
+ `bailing.agent-conversation-audit-capabilities.v1`, with its additive target-member migration ready.
46
+ The SDK must implement `getConversationArchiveCapabilities` and the `expectedBinding` dispatch guard.
47
+ Cross-system selection refuses missing support before creating any business run. Existing
48
+ same-system scope and archive interfaces continue using their v1 behavior.
49
+
50
+ One Hub may contain different Client Apps and workspaces; every target must have a distinct
51
+ original Agent Session. Multiple routes sharing a single Agent Session and cross-Hub conversations
52
+ are outside this release. Hosts using custom stores must preserve scope/outbox v2 records with
53
+ their original bindings and CAS revisions; do not convert v2 into v1 or reconstruct missing state.
54
+ See [the cross-system guide](CROSS_SYSTEM_CONVERSATIONS.md) for usage and limits.
55
+
56
+ ## Historical native Agent Client 0.4.0
4
57
 
5
58
  | Component | Release pairing / requirement |
6
59
  | --- | --- |
@@ -15,7 +68,7 @@
15
68
  Core `0.6.0` is the minimum API version for this contract. Use Core `0.6.1` for the
16
69
  recommended release pairing; the patch does not change these business APIs.
17
70
 
18
- Install only `dsh-bailinghub@0.4.0`; its ordinary dependency installs the exact SDK. A release
71
+ For this historical pairing, install `dsh-bailinghub@0.4.0`; its ordinary dependency installs the exact SDK. A release
19
72
  requires a registry-generated lockfile and a clean package/profile check. Local source and
20
73
  synthetic HTTP verification are compatibility evidence, not evidence of an organization's
21
74
  production use. The older 0.3 baseline is retained below for existing users, not as a claim that
@@ -25,7 +78,10 @@ New conversations need explicit scope selection before the first message. Custom
25
78
  and display selection, preserve the stable conversation id, and restore the original scope before
26
79
  sending on reopen. Missing started-session snapshots stay blocked. Saved drafts require fresh
27
80
  confirmation. Scope restoration and archive synchronization do not recover business invocations,
28
- approvals, or task execution after a process restart.
81
+ approvals, or task execution after a process restart. The
82
+ [invocation recovery journal](INVOCATION_RECOVERY.md) supplies a separate durable journal
83
+ for explicit recovery of original calls. Custom scope-store hosts must explicitly provide
84
+ `invocationStore`; existing calls remain available if they have not enabled that feature.
29
85
 
30
86
  Temporary network failure during reopening is retryable on the same runtime under the complete
31
87
  original scope. Confirmed revocation, replaced identity, or storage/CAS conflict stays blocked.
@@ -133,11 +189,13 @@ BailingHub Core release is compatible only after a separate clean legacy profile
133
189
 
134
190
  Compatibility requires independent evidence for both paths:
135
191
 
136
- 1. Native 0.4: clean install of only the exact plugin package, browser authorization, workspace
192
+ 1. Native 0.5: clean install of only the exact plugin package, browser authorization, workspace
137
193
  discovery, same-identity replacement, different-identity isolation, read, permitted mutation,
138
194
  approval/resume, visible completion, and Hub trajectory. Additionally verify explicit single/multiple
139
195
  scope selection, full-set archive authorization, offline reopen/retry, revocation, and no business
140
- replay after a lost archive acknowledgement.
196
+ replay after a lost archive acknowledgement. Verify cross-system routing and same-named tools,
197
+ unselected-target isolation, metadata before tool search, and duplicate/renamed subject displays.
198
+ Metadata reads must create no business run; subject names must not change identity or scope.
141
199
  2. Legacy 0.1.1: clean static profile, fixed Client Token route, one submit, and same-job follow-up
142
200
  through the unchanged public Client API.
143
201