Tracking issue for Contract-API findings from an adversarial review (Jun 2026) that were not fixed in the first hardening pass. The three highest-severity, freeze-irreversible items (JSONSchemaValue integer fidelity, ToolResult.ErrorKind escape hatch, BackendCapabilities tolerant decode) are handled in the feat!: harden Contract wire types before 1.0 freeze PR. The items below survived red-team scrutiny but were judged lower-severity or design-trade decisions.
Each item notes whether it is freeze-blocking (must land before the 1.0 vocabulary freeze because it can't be fixed non-breakingly after) or deferrable (can ship post-1.0).
Freeze-relevant (decide before 1.0)
Deferrable (post-1.0 safe)
Reviewed and dismissed (no action — recorded for traceability)
Source: adversarial Contract review + red-team verification pass, Jun 2026.
Tracking issue for Contract-API findings from an adversarial review (Jun 2026) that were not fixed in the first hardening pass. The three highest-severity, freeze-irreversible items (
JSONSchemaValueinteger fidelity,ToolResult.ErrorKindescape hatch,BackendCapabilitiestolerant decode) are handled in thefeat!: harden Contract wire types before 1.0 freezePR. The items below survived red-team scrutiny but were judged lower-severity or design-trade decisions.Each item notes whether it is freeze-blocking (must land before the 1.0 vocabulary freeze because it can't be fixed non-breakingly after) or deferrable (can ship post-1.0).
Freeze-relevant (decide before 1.0)
EmbeddingBackendis thinly specified vsInferenceBackend(fix: stable reverse-scroll when prepending older messages #15). Nocapabilities, no thread-safety doc,dimensionsundefined beforeloadModel, andembed(_:)has no stated guarantee that output vector count matches input count.EmbeddingError.dimensionMismatchpartially mitigates. For a third-party-implementable protocol this contract is under-defined. Freeze-blocking if we want to addcapabilitiesto the protocol later.GenerationConfig(Replace NSLock + DispatchQueue.main.async with actor and @MainActor Task #1). The rule is principled (capability-gated guarantees likegrammarthrowunsupportedGrammar; advisory hints likeseed/minP/jsonModedegrade silently) but is only discoverable by reading individual field docs. State the rule once at the type level. Deferrable (doc-only).GenerationConfig(Add XCTSkipIf hardware gates to hardware-dependent tests #2).llamaDRY/llamaXTC/llamaMirostatV2(llama.cpp-only),yieldEveryNTokens(MLX-only),streamPrefillProgress(OpenAI-compat-only) are frozen into the "shared across all backends" type. Consider abackendSpecificside-channel before freeze. Freeze-blocking — can't relocate frozen public fields after 1.0.Deferrable (post-1.0 safe)
GenerationConfigCodable round-trip is silently lossy (Add XCTMeasure performance baselines for hot paths #3).jsonMode/thinkingMarkers/structuredOutputare intentionally runtime-only and dropped on decode (tested), but aCodabletype that drops fields on round-trip is a footgun for new callers. Add a prominent type-level doc note, or split aPersistedGenerationConfig.GenerationStreamidle-timeout throwsCloudBackendError.timeout(chore(main): release 1.0.0 #9) from a wrapper usable by local backends too — leaky name. Consider a backend-neutral timeout error. Opt-in (idleTimeoutdefaults nil), so low urgency.BackendCapabilitieshas two public names for one capability (chore: pin release-as 0.1.1 to bootstrap Release Please versioning #11):streamsToolCallArguments+ the computed aliasstreamsToolCallArgumentDeltas, both frozen. Consider deprecating one.Message(wire enum) can't represent tool/image turns (chore(main): release 0.1.1 #12). Intentional thin one-shot wire shape; richer turns go through the value/@Modeltypes. Documenting it as a known scope boundary may suffice; a multimodal one-shot path would be a feature.Reviewed and dismissed (no action — recorded for traceability)
BackendContractChecksenforces it.stopGenerationis tested;secureWipeno-op is correct for backends with no KV residue; the status-getter TOCTOU is defused by the single-generatequeue + MainActor; themaxToolIterationstriple-clamp is correct defense-in-depth).Source: adversarial Contract review + red-team verification pass, Jun 2026.