@yanlinglabs/winter-runtime-sdk 0.0.1

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +249 -0
  3. package/dist/directory/directory.d.ts +55 -0
  4. package/dist/directory/entries.d.ts +82 -0
  5. package/dist/directory/recovery.d.ts +49 -0
  6. package/dist/door.d.ts +247 -0
  7. package/dist/errors.d.ts +104 -0
  8. package/dist/index.d.ts +25 -0
  9. package/dist/index.js +6679 -0
  10. package/dist/messaging/attribution.d.ts +47 -0
  11. package/dist/messaging/dispatch.d.ts +78 -0
  12. package/dist/messaging/handlers.d.ts +56 -0
  13. package/dist/messaging/inbound.d.ts +110 -0
  14. package/dist/messaging/index.d.ts +39 -0
  15. package/dist/messaging/official-adapter.d.ts +36 -0
  16. package/dist/messaging/router.d.ts +101 -0
  17. package/dist/messaging/sessions.d.ts +49 -0
  18. package/dist/messaging/winter-adapter.d.ts +47 -0
  19. package/dist/native-args.d.ts +76 -0
  20. package/dist/official/adapter.d.ts +88 -0
  21. package/dist/official/aliases.d.ts +48 -0
  22. package/dist/official/auth.d.ts +117 -0
  23. package/dist/official/branding.d.ts +31 -0
  24. package/dist/official/callbacks.d.ts +143 -0
  25. package/dist/official/containment.d.ts +130 -0
  26. package/dist/official/env-allowlist.d.ts +237 -0
  27. package/dist/official/env-registry-rule.d.ts +12 -0
  28. package/dist/official/env-registry.d.ts +3 -0
  29. package/dist/official/errors.d.ts +250 -0
  30. package/dist/official/index.d.ts +31 -0
  31. package/dist/official/mcp-descriptors.d.ts +130 -0
  32. package/dist/official/options-template.d.ts +110 -0
  33. package/dist/official/spawn-proxy.d.ts +144 -0
  34. package/dist/official/spool.d.ts +80 -0
  35. package/dist/official/supervision.d.ts +49 -0
  36. package/dist/official/sweep.d.ts +65 -0
  37. package/dist/sdk.d.ts +214 -0
  38. package/dist/seams/context.d.ts +26 -0
  39. package/dist/seams/directory-store.d.ts +274 -0
  40. package/dist/seams/directory.d.ts +46 -0
  41. package/dist/seams/global-messaging.d.ts +30 -0
  42. package/dist/seams/handoff.d.ts +77 -0
  43. package/dist/seams/index.d.ts +11 -0
  44. package/dist/seams/keychain.d.ts +11 -0
  45. package/dist/seams/materialized-resume.d.ts +46 -0
  46. package/dist/seams/messaging-contract.d.ts +29 -0
  47. package/dist/seams/official-adapter.d.ts +125 -0
  48. package/dist/seams/official-sdk-shapes.d.ts +126 -0
  49. package/dist/seams/stubs.d.ts +34 -0
  50. package/dist/selection/child-runtime.d.ts +81 -0
  51. package/dist/selection/runtime-selection.d.ts +217 -0
  52. package/dist/selection/select-runtime.d.ts +213 -0
  53. package/dist/store/handoff-barrier.d.ts +238 -0
  54. package/dist/store/index.d.ts +11 -0
  55. package/dist/store/materialized-resume.d.ts +100 -0
  56. package/dist/store/pinned-probes.d.ts +17 -0
  57. package/dist/store/reconcile.d.ts +157 -0
  58. package/dist/store/temp-continuity.d.ts +92 -0
  59. package/dist/store/wiring.d.ts +250 -0
  60. package/dist/vendor-paths.d.ts +21 -0
  61. package/dist/version-matrix.d.ts +84 -0
  62. package/docs/conformance-rows.md +195 -0
  63. package/package.json +65 -0
@@ -0,0 +1,217 @@
1
+ import type { CredentialRef, ModelFamilyListing } from "@yanlinglabs/winter-agent-sdk";
2
+ import { RuntimeSdkError } from "../errors.js";
3
+ /**
4
+ * The two runtimes, spelled exactly as the Winter runtime's own messaging layer spells them
5
+ * (`packages/runtime/src/messaging/adapter.ts`, which Task 0 moves to
6
+ * `@yanlinglabs/winter-agent-sdk/messaging`).
7
+ *
8
+ * ONE DECLARATION, and this is it while Task 0 is in flight: when the messaging subpath lands, this
9
+ * line becomes a re-export of the SDK's own `RuntimeKind` (see `src/seams/messaging-contract.ts`,
10
+ * which carries the same note for the messaging shapes). The two unions are character-identical, so
11
+ * the swap is type-identical and no lane's code moves.
12
+ */
13
+ export type RuntimeKind = "winter-agent" | "claude-agent";
14
+ /**
15
+ * WS-15 §1's persisted-choice contract, populated by the D13 selector at session creation.
16
+ *
17
+ * `sdkVersion` vs `engineVersion` are WS-02 §3's two separate identities: the wrapper's and the
18
+ * runtime engine's. `reason` is a human-readable sentence naming the rule that fired — it is what a
19
+ * host renders when a user asks "why is this session on that runtime", and what a support log needs
20
+ * when a persisted selection looks surprising a month later. `decidedAt` is ISO-8601.
21
+ */
22
+ export interface RuntimeSelection {
23
+ runtimeKind: RuntimeKind;
24
+ providerId: string;
25
+ /**
26
+ * The provider-qualified catalog **row key** (`anthropic/claude-opus-5`) — this session's model
27
+ * IDENTITY, never the raw model id.
28
+ *
29
+ * READ IT AS AN IDENTITY, NOT AS A WIRE VALUE. The id a runtime actually sends is derived from the
30
+ * row, never from this field: handing `modelRef` straight to a runtime's `model` option sends the
31
+ * provider prefix with it, and that fails at the endpoint rather than at compile time. WS-17 row 17
32
+ * is why the field is qualified at all — `claude-opus-5` is six catalog rows behind six providers,
33
+ * and two sessions on two of them must not persist byte-identical records.
34
+ */
35
+ modelRef: string;
36
+ family: string;
37
+ authFamily: "api-key" | "cloud-credential-chain" | "claude-oauth" | "console-oauth" | "local-none" | "custom";
38
+ sdkVersion: string;
39
+ engineVersion?: string;
40
+ reason: string;
41
+ decidedAt: string;
42
+ }
43
+ /** The auth families a `RuntimeSelection` can record, as a name (the union is pinned inline above). */
44
+ export type SelectionAuthFamily = RuntimeSelection["authFamily"];
45
+ /**
46
+ * What the host knows about one provider BEYOND "a credential ref exists" — the two facts the D13
47
+ * branch is actually taken on.
48
+ *
49
+ * WHY THIS EXISTS. `CredentialPresence.byProvider` carries a `CredentialRef["kind"]`, which says
50
+ * WHERE a credential is stored (`keychain` | `env` | `file` | `inline` | `aws-default-chain` |
51
+ * `none`). D13 branches on something else entirely: WS-13 §9's own words are "routing decisions use
52
+ * the persisted runtime profile/AUTH SOURCE — never a raw model-ID substring", and R-7b-1 spells the
53
+ * official branch's served set as "API key, cloud credential chain, or an approved Claude OAuth". A
54
+ * storage location cannot express any of those three, and it certainly cannot express the difference
55
+ * between an Anthropic API key and a Claude OAuth credential, which is the difference between D13's
56
+ * row 2 and its row 1. So the host — which has the provider descriptor — declares them.
57
+ *
58
+ * `protocols` is WS-13 §5's wire-dialect list (`ProviderProtocol` in the catalog: `anthropic-messages`,
59
+ * `openai-chat-completions`, `bedrock-converse`, …), copied verbatim from the provider descriptor.
60
+ * The selector reads exactly one bit out of it: does this backend speak the Anthropic dialect —
61
+ * which is WS-13 §9's "Anthropic-protocol backend" test, and the thing that separates a Claude model
62
+ * served by its vendor from the same Claude model resold through an OpenAI-shaped gateway.
63
+ *
64
+ * KEPT A BARE `string[]`, deliberately: the dialect vocabulary belongs to the catalog package, and
65
+ * this package must not grow a dependency on it to spell one comparison.
66
+ */
67
+ export interface ProviderAuthView {
68
+ /** The auth family this provider's CONFIGURED credential belongs to (WS-14 §12's own table). */
69
+ authFamily: SelectionAuthFamily;
70
+ /** The wire dialects the provider speaks, verbatim from its catalog descriptor. */
71
+ protocols?: readonly string[];
72
+ }
73
+ /**
74
+ * Which providers have a credential REF configured — never any credential material.
75
+ *
76
+ * WS-13c §4's filter step ("filter by configured credential ref") and WS-14 Execution amendments'
77
+ * "a pinned alias resolves to the `anthropic` provider ONLY when a credential ref for it is
78
+ * configured, and never by ambient environment scan" are both decided from this map. The value is the
79
+ * ref's KIND (the SDK's own `CredentialRef["kind"]`), because the auth family follows from it and
80
+ * nothing else here needs more.
81
+ *
82
+ * LANE D AMENDMENT — `byProvider` REMAINS THE FILTER, `authByProvider` REFINES IT. Presence of a
83
+ * provider's key in `byProvider` is what admits its rows (unchanged, and it is the only admission
84
+ * test: an absent key means "no configured credential ref", never "probe the environment"). What the
85
+ * kind cannot do is name the auth FAMILY, so `authByProvider` carries it where the host knows it. A
86
+ * provider with no entry there falls back to `authFamilyFromRefKind` in `./select-runtime.ts`, whose
87
+ * one rule is that an OAuth family is NEVER inferred — `claude-oauth` and `console-oauth` are
88
+ * reachable only by declaration, so the D14 ship gate can never be tripped by a guess.
89
+ */
90
+ export interface CredentialPresence {
91
+ readonly byProvider: Readonly<Record<string, CredentialRef["kind"]>>;
92
+ /** Per-provider auth family + wire dialects, where the host knows them. See `ProviderAuthView`. */
93
+ readonly authByProvider?: Readonly<Record<string, ProviderAuthView>>;
94
+ }
95
+ /**
96
+ * The version identities stamped into a selection (WS-02 §3: "the runtime engine and wrapper carry
97
+ * separate version identities — `sdkVersion` vs `engineVersion`").
98
+ *
99
+ * A PURE FUNCTION CANNOT READ THEM. `RuntimeSelection.sdkVersion` is required and its value depends
100
+ * on which runtime the table picked, so the caller supplies both candidates and the selector stamps
101
+ * the one it chose. Absent → `UNKNOWN_VERSION`, which is an honest record rather than a plausible
102
+ * lie; `selectionVersionsFrom(sdk.versions)` in `./select-runtime.ts` builds this from the
103
+ * constructor's own matrix report, which is where a host already has the answer.
104
+ */
105
+ export interface SelectionVersions {
106
+ /** The Winter SDK's own version — stamped when the table picks `winter-agent`. */
107
+ winterSdkVersion?: string;
108
+ /** The official SDK's version — stamped when the table picks `claude-agent`. */
109
+ claudeSdkVersion?: string;
110
+ /** The runtime ENGINE's version, when the host knows it (WS-02 §3's second identity). */
111
+ engineVersion?: string;
112
+ }
113
+ /** The D13 decision's inputs. See this file's header for why no raw model id decides the branch. */
114
+ export interface SelectionInput {
115
+ mode: "code" | "dispatch" | "chat";
116
+ requested: {
117
+ slot?: string;
118
+ model?: string;
119
+ provider?: string;
120
+ };
121
+ families: ModelFamilyListing;
122
+ credentials: CredentialPresence;
123
+ hasClaudePeer: boolean;
124
+ /**
125
+ * D14's ship gate. `false` IS THE SHIPPED DEFAULT (`D14_CLAUDE_OAUTH_APPROVED_DEFAULT` in
126
+ * `./select-runtime.ts`): WS-14 §12 — "built but publicly ship-gated pending written Anthropic
127
+ * approval… until approval exists, the shippable branch uses API-key/cloud/gateway auth only".
128
+ * Required rather than optional on purpose — a host must say it, and saying nothing is not consent.
129
+ */
130
+ claudeOauthApproved: boolean;
131
+ persisted?: RuntimeSelection;
132
+ /** Stamped into the produced record. Absent → `UNKNOWN_VERSION`. */
133
+ versions?: SelectionVersions;
134
+ /** The ISO-8601 instant to record as `decidedAt`. Absent → now. Present makes a decision reproducible. */
135
+ now?: string;
136
+ }
137
+ /**
138
+ * A typed refusal — never a substitution and never a different family (WS-13c §4's own words).
139
+ *
140
+ * `slot-unservable`: no candidate survived slot resolution (no configured credential ref, or the
141
+ * slot names a family this catalog cannot serve). `claude-oauth-not-approved`: the D14 ship gate is
142
+ * closed and the only route to this selection was Claude OAuth. `runtime-unavailable`: the runtime
143
+ * the rule selected is not present (e.g. a `claude` slot that must run official, with no official
144
+ * peer injected). `mode-forbids-runtime`: the mode×runtime matrix has no cell for this pair —
145
+ * WS-15 §2's "Claude OAuth is Code-only even after D14 approval. Unsupported combinations are
146
+ * explicit capabilities in the matrix, never silent fallbacks."
147
+ *
148
+ * THE FOURTH MEMBER IS LANE D'S ADDITION and it is the one that keeps a rule from becoming a
149
+ * fallback: without it, Claude OAuth in Dispatch or Chat has exactly two expressible answers, and
150
+ * both are wrong — route to the official runtime (violating D4's "Dispatch and Chat → Winter-only,
151
+ * in-daemon") or route to Winter (violating D28's "Claude oAuth never routes to winter").
152
+ */
153
+ export interface SelectionRefusal {
154
+ refused: true;
155
+ reason: "slot-unservable" | "claude-oauth-not-approved" | "runtime-unavailable" | "mode-forbids-runtime";
156
+ /** One sentence naming what was missing, for the host to surface verbatim. */
157
+ detail: string;
158
+ }
159
+ /**
160
+ * Narrows the union without a `"refused" in x` incantation at every call site.
161
+ *
162
+ * GENERIC IN THE NON-REFUSAL HALF, because every door in `src/selection/` returns "the answer OR the
163
+ * same refusal": `RuntimeSelection | SelectionRefusal` from the two selectors, `ChildRuntimePairing |
164
+ * SelectionRefusal` from the pairing door. One guard for all of them is the point — a second guard
165
+ * per return type is a second place for the discriminant to be spelled, and the discriminant is the
166
+ * whole contract.
167
+ */
168
+ export declare function isSelectionRefusal<T extends object>(value: T | SelectionRefusal): value is SelectionRefusal;
169
+ /**
170
+ * The refusal, thrown — how `RuntimeSdk.selectRuntime` reports one.
171
+ *
172
+ * THE PLAN PINS TWO SIGNATURES THAT DISAGREE, and this class is the reconciliation. The pure module
173
+ * function above returns `RuntimeSelection | SelectionRefusal` (a refusal is data — the D13 table has
174
+ * an answer for every input, and a caller doing capability discovery wants it as a value). The
175
+ * `RuntimeSdk.selectRuntime` METHOD is pinned as returning `RuntimeSelection` alone, so on that door
176
+ * a refusal has to leave some other way: it is thrown, carrying the refusal verbatim. A host that
177
+ * wants the value calls the exported function; a host that wants the method catches this.
178
+ */
179
+ export declare class SelectionRefusedError extends RuntimeSdkError {
180
+ readonly refusal: SelectionRefusal;
181
+ constructor(refusal: SelectionRefusal);
182
+ }
183
+ /**
184
+ * A child's own request, resolved independently of the parent's runtime (R-7b-1).
185
+ *
186
+ * ONE OBJECT WHERE THE PLAN WRITES TWO ARGUMENTS. The plan's Task 5 line is
187
+ * `selectChildRuntime(parent, child: { slot?; model?; provider? }, input)`; the spine pinned the
188
+ * two-argument form the barrel and the seams already import. They describe the same information, so
189
+ * this shape carries both halves: the `slot`/`model`/`provider` the spawn requested, and the context
190
+ * the D13 table needs. `slot` is optional here for the same reason it is optional in
191
+ * `SelectionInput.requested` — a spawn may name a model or a provider instead, and a child that names
192
+ * nothing takes its session's active slot set, exactly like a top-level session.
193
+ *
194
+ * WHAT IS DELIBERATELY ABSENT: anything from the parent. `selectChildRuntime` reads its `parent`
195
+ * argument for ONE purpose only — reporting whether the resulting pair is cross-runtime (Lane B's
196
+ * routing bit) — and never as an input to the decision. That is R-7b-1's whole content, and making
197
+ * the parent structurally absent from this type is what makes it true rather than merely intended.
198
+ */
199
+ export interface ChildSelectionInput {
200
+ /** The child's slot name (WS-13c §4 resolves it to a canonical model id). */
201
+ slot?: string;
202
+ /** A canonical model id or a catalog row key, when the spawn names a model instead of a slot. */
203
+ model?: string;
204
+ /** A pinned provider id (WS-13c §4's "a pinned `provider`"). */
205
+ provider?: string;
206
+ mode: "code" | "dispatch" | "chat";
207
+ families: ModelFamilyListing;
208
+ credentials: CredentialPresence;
209
+ hasClaudePeer: boolean;
210
+ claudeOauthApproved: boolean;
211
+ /** Stamped into the child's own record. */
212
+ versions?: SelectionVersions;
213
+ /** The ISO-8601 instant to record as the child's `decidedAt`. */
214
+ now?: string;
215
+ }
216
+ export { selectRuntime } from "./select-runtime.js";
217
+ export { selectChildRuntime } from "./child-runtime.js";
@@ -0,0 +1,213 @@
1
+ import type { CredentialRef, ModelFamilyListing } from "@yanlinglabs/winter-agent-sdk";
2
+ import type { VersionMatrixReport } from "../version-matrix.js";
3
+ import type { CredentialPresence, ProviderAuthView, RuntimeSelection, SelectionAuthFamily, SelectionInput, SelectionRefusal, SelectionVersions } from "./runtime-selection.js";
4
+ /** The family id the D13 table names. The catalog's own id (WS-13c §1, `CLAUDE_FAMILY_ID`). */
5
+ export declare const CLAUDE_FAMILY_ID = "claude";
6
+ /** WS-13 §5's Anthropic wire dialect, as the catalog's provider descriptors spell it. */
7
+ export declare const ANTHROPIC_PROTOCOL = "anthropic-messages";
8
+ /**
9
+ * The provider ids treated as Anthropic-protocol backends when the host declares no `protocols`.
10
+ *
11
+ * A FALLBACK, NOT A POLICY. When `CredentialPresence.authByProvider[id].protocols` is present it is
12
+ * authoritative and this list is not consulted. It exists because the alternative — treating an
13
+ * undeclared backend as Anthropic-protocol — would route a Claude model resold through an
14
+ * OpenAI-shaped gateway to the official runtime, which is precisely WS-13 §9's third row inverted.
15
+ * The conservative direction is the safe one: an undeclared, unlisted backend goes to Winter, which
16
+ * serves every family, rather than to a runtime that speaks one wire protocol.
17
+ *
18
+ * ONE ENTRY, and that is not an oversight: Bedrock and Vertex reach the official branch through their
19
+ * AUTH FAMILY (`cloud-credential-chain`, WS-14 §12's own table rows), not through this list — their
20
+ * catalog dialects are `bedrock-converse` and `google-generate-content`, and claiming otherwise here
21
+ * would be a false statement about the catalog.
22
+ */
23
+ export declare const ANTHROPIC_PROTOCOL_PROVIDER_FALLBACK: readonly string[];
24
+ /**
25
+ * D25's reserved slot names, which resolve into the `claude` family from any active set (WS-13c §3's
26
+ * acceptance order, mirrored from the catalog's `CLAUDE_RESERVED_SLOT_NAMES`).
27
+ */
28
+ export declare const CLAUDE_RESERVED_SLOT_NAMES: readonly string[];
29
+ /**
30
+ * D14's ship gate, as the shipped default.
31
+ *
32
+ * WS-14 §12: Claude OAuth is "built but publicly ship-gated pending written Anthropic approval…
33
+ * Until approval exists, the shippable branch uses API-key/cloud/gateway auth only." A host that has
34
+ * approval passes `claudeOauthApproved: true` deliberately; everything that does not say so gets this.
35
+ */
36
+ export declare const D14_CLAUDE_OAUTH_APPROVED_DEFAULT = false;
37
+ /** What a `RuntimeSelection` records when the caller supplied no version identity for that runtime. */
38
+ export declare const UNKNOWN_VERSION = "unknown";
39
+ /**
40
+ * The auth families the official branch serves (R-7b-1 as clarified 2026-09-08), before any per-rule
41
+ * gate.
42
+ *
43
+ * THE ONE HOME FOR THE SET. `officialServesBackend` DERIVES from this list rather than restating it —
44
+ * the alternative was two places to edit, and review r1's I1 was the first time that cost something
45
+ * real (a family was added to the rule and the constant said otherwise, with nothing failing).
46
+ */
47
+ export declare const OFFICIAL_SERVED_AUTH_FAMILIES: readonly SelectionAuthFamily[];
48
+ /**
49
+ * Every branch this selector can take, with the sentence a host renders.
50
+ *
51
+ * IDS RATHER THAN PROSE MATCHING. `RuntimeSelection.reason` is `"<id>: <text>"`, so a test asserts on
52
+ * `D13-1` while a user reads the sentence, and rewording the sentence never breaks a test (nor does
53
+ * a test pin prose a product person should be free to improve).
54
+ */
55
+ export declare const SELECTION_RULES: {
56
+ readonly "D13-1": "a Claude OAuth credential always routes to the official runtime (WS-13 §9, D13 row 1)";
57
+ readonly "D13-2": "a Claude-family model on an Anthropic-protocol backend in Code mode routes to the official runtime (WS-13 §9, D13 row 2)";
58
+ readonly "D13-3-endpoint": "a Claude-family model reached through a backend the official branch does not serve routes to the Winter runtime (WS-13 §9, D13 row 3)";
59
+ readonly "D13-3-mode": "Dispatch and Chat run in-daemon on the Winter runtime (WS-13 §9 row 3, D4)";
60
+ readonly D28: "a non-Claude family routes to the Winter runtime (WS-13c §0, D28)";
61
+ readonly "R-7b-1-no-peer": "this router holds no official runtime, so the Claude-family slot resolves through WS-13c §4's order onto the Winter runtime (R-7b-1)";
62
+ readonly persisted: "the selection persisted at session creation wins; a change is the certified handoff or a visible fork, never a silent rewrite (WS-00 §2, D13)";
63
+ };
64
+ export type SelectionRuleId = keyof typeof SELECTION_RULES;
65
+ /** `"<id>: <sentence>"` — the exact string a produced record carries in `reason`. */
66
+ export declare function reasonFor(rule: SelectionRuleId): string;
67
+ /**
68
+ * The rule id a produced record was decided by, recovered from its `reason`.
69
+ *
70
+ * `Object.hasOwn`, NOT `in` — `in` walks the prototype chain, so a persisted record whose `reason`
71
+ * began `toString:` would have come back as a `SelectionRuleId` and `SELECTION_RULES[id]` would have
72
+ * handed the caller a `Function` where it expects a sentence. A `RuntimeSelection` arrives off a
73
+ * host's durable store, so it is exactly the kind of input that must not be trusted to be one of ours.
74
+ */
75
+ export declare function ruleIdOf(selection: RuntimeSelection): SelectionRuleId | undefined;
76
+ type FamilyEntry = ModelFamilyListing["families"][number];
77
+ type ModelEntry = FamilyEntry["models"][number];
78
+ /** One catalog row as the listing publishes it: the provider-qualified `key` is the identity (row 17). */
79
+ export type ModelRow = ModelEntry["rows"][number];
80
+ /** A row that survived WS-13c §4's filter, with the family it belongs to. */
81
+ export interface SelectionCandidate {
82
+ family: string;
83
+ canonicalModelId: string;
84
+ row: ModelRow;
85
+ auth: ProviderAuthView;
86
+ }
87
+ /**
88
+ * The auth family implied by a credential ref's STORAGE KIND, for a provider the host did not describe.
89
+ *
90
+ * THE ONE RULE THAT MATTERS HERE: an OAuth family is never inferred. `keychain`, `env` and `inline`
91
+ * are where an API key lives and are also where a subscription credential could live, and guessing
92
+ * `claude-oauth` from a keychain entry would let an ambient credential trip D14's ship gate — the
93
+ * exact shape WS-14's Phase 6 amendment forbids ("never by ambient environment scan"). `file` is
94
+ * genuinely undeterminable (the ref's `format` distinguishes an AWS credentials file from a raw key,
95
+ * and the kind alone does not carry it), so it reports `custom`, which no rule routes to the official
96
+ * runtime. Everything unknown therefore lands on Winter, which serves every family.
97
+ */
98
+ export declare function authFamilyFromRefKind(kind: CredentialRef["kind"]): SelectionAuthFamily;
99
+ /** The host's view of a provider, or the conservative one derived from its ref kind. */
100
+ export declare function providerAuthView(providerId: string, credentials: CredentialPresence): ProviderAuthView | undefined;
101
+ /** WS-13 §9's "Anthropic-protocol backend" test: the declared dialects, else the fallback list. */
102
+ export declare function speaksAnthropicProtocol(providerId: string, auth: ProviderAuthView): boolean;
103
+ /**
104
+ * Can the OFFICIAL branch serve this backend at all? (R-7b-1's served set, WS-14 §12's table.)
105
+ *
106
+ * MEMBERSHIP FIRST, THEN THE PROTOCOL GATE. A family outside `OFFICIAL_SERVED_AUTH_FAMILIES` is not
107
+ * served, full stop; a family inside it is served either unconditionally or only on a backend that
108
+ * speaks the Anthropic dialect, and which of the two it is follows from what the family means:
109
+ *
110
+ * `claude-oauth` — served (and gated separately, because it is D13's own row 1).
111
+ * `cloud-credential-chain` — served. These are WS-14 §12's Bedrock and Vertex rows: their catalog
112
+ * dialects are NOT `anthropic-messages`, and the official runtime
113
+ * speaks them itself, so the auth family is the honest test there.
114
+ * `api-key`, `console-oauth` — served ONLY on an Anthropic-dialect backend. Both are token-priced
115
+ * bearer credentials the official runtime accepts through its bearer
116
+ * variable (R-7b-1 as clarified 2026-09-08), so neither is a reason to
117
+ * route away from the official branch — but a Claude model resold over
118
+ * an OpenAI-shaped endpoint still is, which is WS-13 §9's row 3 and the
119
+ * one place the protocol test does the work.
120
+ *
121
+ * `console-oauth` was excluded here until review r1's I1. The reasoning had been WS-13c §6's "the
122
+ * `anthropic` provider first (api-key or Console OAuth credential)" — but that sentence sits inside
123
+ * §6's WINTER-ALONE paragraph, and the router leg is the next sentence ("With the runtime SDK present:
124
+ * `claude` slots prefer the official SDK per D13"). The exclusion was never required by the spec, and
125
+ * it contradicted D28's "anthropic models always prefer claude agent sdk".
126
+ */
127
+ export declare function officialServesBackend(providerId: string, auth: ProviderAuthView): boolean;
128
+ /**
129
+ * WS-13c §4, end to end: what the session asked for → the one row it will run on.
130
+ *
131
+ * ORDER OF PRECEDENCE: an explicit slot, else an explicit model, else the session's active slot set —
132
+ * whose slots are tried in the order the listing publishes them, because that order IS §4's
133
+ * deterministic order (vendorProviders, subscription before token, `settings.preferredProviders`, then
134
+ * `admission.tier`). This package re-sorts nothing: the listing is produced by the code that owns
135
+ * those rules, and a second ordering here would be a second answer.
136
+ */
137
+ /** A candidate list that is non-empty BY TYPE, so a caller never has to guard an impossible empty. */
138
+ export type NonEmptyCandidates = [SelectionCandidate, ...SelectionCandidate[]];
139
+ /**
140
+ * EVERY candidate row for an explicitly named model or catalog row key, in the listing's own order.
141
+ *
142
+ * `resolveCandidate` below takes the first of these and is what a fresh decision uses. A RESUME needs
143
+ * the whole list instead (`resumeChildSelection`): its question is not "which row would we pick now"
144
+ * but "is the row this child is RECORDED on still servable", and those differ the moment one provider
145
+ * serves two rows for one canonical model. Review r1's M1 is exactly that difference — the old code
146
+ * compared against the first row and called it a provider check, which the provider pin had already
147
+ * guaranteed.
148
+ */
149
+ export declare function resolveCandidateRows(input: SelectionInput & {
150
+ requested: {
151
+ model: string;
152
+ };
153
+ }): NonEmptyCandidates | SelectionRefusal;
154
+ export declare function resolveCandidate(input: SelectionInput): SelectionCandidate | SelectionRefusal;
155
+ /**
156
+ * The D13/D28 table itself, over an already-resolved candidate.
157
+ *
158
+ * Exported because both entry points evaluate the SAME table — R-7b-1's "a child runs on the runtime
159
+ * its OWN slot's family selects under D13/D28" is implemented by calling this with the child's own
160
+ * candidate, not by a second table that would drift from this one.
161
+ */
162
+ export declare function decideRuntime(candidate: SelectionCandidate, input: SelectionInput): RuntimeSelection | SelectionRefusal;
163
+ /**
164
+ * D13/D28, pure — the router's runtime selection.
165
+ *
166
+ * Returns the PERSISTED record untouched when there is one, otherwise the row this session resolves
167
+ * to plus the runtime the table picks, otherwise a typed refusal.
168
+ */
169
+ export declare function selectRuntime(input: SelectionInput): RuntimeSelection | SelectionRefusal;
170
+ /**
171
+ * What a fresh decision would say about a session that already has a persisted selection.
172
+ *
173
+ * `unchanged` — the table still picks the same runtime, provider and model. `handoff-required` — it
174
+ * would pick something else: WS-00 §2's D13 says that change "is the certified handoff or a visible
175
+ * fork, never a silent rewrite", so this is reported to the host (which renders the choice, R-7b-3)
176
+ * and the persisted record is returned untouched either way. `fresh-refused` — the session's
177
+ * persisted selection is no longer servable at all (a credential removed, a row withdrawn); the
178
+ * record still stands, and the refusal says why a fresh decision could not be made.
179
+ */
180
+ export type SelectionReview = {
181
+ kind: "unchanged";
182
+ selection: RuntimeSelection;
183
+ fresh: RuntimeSelection;
184
+ } | {
185
+ kind: "handoff-required";
186
+ persisted: RuntimeSelection;
187
+ fresh: RuntimeSelection;
188
+ changed: Array<"runtimeKind" | "providerId" | "modelRef" | "family" | "authFamily">;
189
+ detail: string;
190
+ } | {
191
+ kind: "fresh-refused";
192
+ persisted: RuntimeSelection;
193
+ refusal: SelectionRefusal;
194
+ };
195
+ /**
196
+ * Compares a session's persisted selection against what the table would decide today.
197
+ *
198
+ * NEVER RETURNS A REWRITTEN RECORD. Every branch carries the persisted object itself; `fresh` is
199
+ * offered beside it as the *proposal* a handoff (WS-05 §12) or a visible fork would realise. The
200
+ * host, not this function, decides what to do with a `handoff-required`.
201
+ */
202
+ export declare function reviewPersistedSelection(input: SelectionInput & {
203
+ persisted: RuntimeSelection;
204
+ }): SelectionReview;
205
+ /**
206
+ * The version identities the constructor already measured, in the shape a selection stamps.
207
+ *
208
+ * `RuntimeSdk.versions` is a `VersionMatrixReport`; `SelectionInput.versions` is what the record
209
+ * needs. This is the one-line bridge, so a host does not hand-copy two fields and get the second one
210
+ * wrong for the runtime it did not test.
211
+ */
212
+ export declare function selectionVersionsFrom(report: VersionMatrixReport): SelectionVersions;
213
+ export {};