Cosmos: native driver distribution design + ADRs - #4651
Conversation
Add a design doc and a numbered ADR set describing how the native Cosmos driver (azurecosmosdriver cdylib/staticlib + C header) is distributed to language SDKs. Core model: separate provenance from distribution. One Rust build produces all signed platform binaries as an internal-only hand-off artifact (ADR 0001/0008); distribution is per-language native packages on each language's existing internal + external feed (ADR 0009) -- NuGet NativeAssets + meta for .NET (0002), cgo prebuilt header+lib via the Go feed (0003), JAR for Java (future). ABI handshake (0004), bytes-in/bytes-out copy-out (0005), opt-in transport (0006), and platform matrix (0007) round out the set. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Since these ADRs are unpublished (no PR, no accepted record), the immutability/supersession discipline does not yet apply, so the pre-publication editing history was scrubbed for a clean first cut: - Drop ghost "supersedes the earlier canonical-bundle" scaffolding from 0001 and 0002 and the design doc; no reviewer ever saw that draft, so referencing it is noise. - Reorder per-language-feed distribution from 0009 to 0002 so the keystone distribution decision sits next to the build-once provenance decision (0001); renumber the former 0002-0008 to 0003-0009. Provenance (0001) and distribution (0002) stay as two decoupled records so either can be superseded independently later. - Re-point all in-text and link cross-references to the new numbers; reorder the index and design-doc decision tables to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The generic "distribution" name was ambiguous; "native-distribution" makes clear these docs cover distributing the native (FFI) driver artifact to the language SDKs. Pure directory rename — all internal links are relative and unaffected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This documentation-only PR adds a design document plus nine Architecture Decision Records (ADRs) describing how the future Rust-built native Cosmos driver (azure_data_cosmos_driver_native → azurecosmosdriver.{dll,so,dylib} + cbindgen C header) will be distributed to the .NET, Go, and (later) Java SDKs. The core idea is to separate provenance (one signed build → internal hand-off artifact) from distribution (per-language packages on each language's existing feed). No code, build, or pipeline behavior changes; everything is marked "proposed for review."
Changes:
- Adds
distribution-design.md— the discussion doc (purpose, goals, model, per-consumer link model, platform matrix, rollout, open questions). - Adds ADRs
0000–0009capturing each decision (build-once hand-off, per-language feeds, .NET NuGet NativeAssets, Go cgo, ABI handshake, marshalling ownership, opt-in native, platform matrix, build/sign pipeline). - References an existing/planned
NATIVE_WRAPPER_SPEC.mdas the owner of the C-ABI surface.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
docs/native-distribution/distribution-design.md |
Main design discussion; links to ADRs and to a non-existent NATIVE_WRAPPER_SPEC.md; introduces many domain terms not in the cSpell dictionaries. |
docs/native-distribution/adr/0000-index.md |
ADR index/template overview; links resolve correctly. |
docs/native-distribution/adr/0001-build-once-internal-handoff.md |
Decision: single build → internal-only hand-off artifact. |
docs/native-distribution/adr/0002-per-language-feed-distribution.md |
Decision: distribute via each language's existing feeds. |
docs/native-distribution/adr/0003-dotnet-nuget-nativeassets.md |
Decision: .NET per-RID NuGet NativeAssets + meta-package. |
docs/native-distribution/adr/0004-go-cgo-prebuilt.md |
Decision: Go consumes prebuilt header+lib via cgo. |
docs/native-distribution/adr/0005-abi-version-handshake.md |
Decision: lib exports cosmos_abi_version(); hosts check before use. |
docs/native-distribution/adr/0006-binding-owns-marshalling.md |
Decision: bindings own marshalling/copy-out; links to non-existent NATIVE_WRAPPER_SPEC.md. |
docs/native-distribution/adr/0007-native-is-opt-in.md |
Decision: native is opt-in until GA, then default-with-fallback. |
docs/native-distribution/adr/0008-platform-matrix.md |
Decision: bounded platform matrix; clear error on unsupported targets. |
docs/native-distribution/adr/0009-build-and-signing-pipeline.md |
Decision: one build, sign once, fan-out; jobs never rebuild. |
The two notable issues are CI-blocking: a broken relative link to NATIVE_WRAPPER_SPEC.md (referenced from the design doc and ADR 0006, but the file doesn't exist) which verify-links will fail, and numerous new domain terms missing from the cSpell dictionaries (with no per-file <!-- cspell:ignore --> comment that sibling specs use) which the ContinueOnError:false spell check will fail.
Resolve the 9 review findings on PR #4651: - #1 CI: drop broken NATIVE_WRAPPER_SPEC.md links (lives in #4461); add cSpell terms (cbindgen, Authenticode, ESRP, manylinux, etc.) - #2 ADR 0001/0009: require RID-keyed hand-off + both .so/.a + C-only header - #3 ADR 0009: enforce build-once via checksum+signature verification - #4 ADR 0005: u32 is a monotonic ABI revision; add MaxSupported (reject too-new) - #5 promote Q5 to new ADR 0010 (single version fan-out) - #6 ADR 0000 template: Status under the title - #7 reciprocal Pairs-with note in ADR 0001 - #8 ADR 0008: name glibc floor 2.17 (manylinux2014) - #9 ADR 0007: silent-fallback for benign causes vs fail-loud for integrity/ABI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fabian Meiswinkel (FabianMeiswinkel)
left a comment
There was a problem hiding this comment.
Rust/Native as opt-in is a no-go in my mind.
Nalu Tripician (NaluTripician)
left a comment
There was a problem hiding this comment.
Design review — native driver distribution
Read the whole set (design doc + ADRs 0000–0010). Overall this is a strong, well-structured design and the ADR hygiene is clean. I spot-checked the external references and they hold up: the SkiaSharp / Microsoft.Data.SqlClient.SNI per-RID runtimes/<rid>/native/ + runtime.json meta-package pattern, manylinux2014 ⇔ glibc 2.17, the cgo CFLAGS -I / LDFLAGS -L -l mechanics, cbindgen C-only header, and crate-type = ["cdylib","staticlib"] are all described correctly.
A few things I'd want resolved before these move from "proposed" to "accepted". Inline comments cover the independent ones; the three below overlap with Fabian's open CHANGES_REQUESTED, so I'm reinforcing rather than restating.
Blocking
- Opt-in / "pure-managed users" premise (ADR 0007 + G4, ADR 0003). If the next .NET major requires the native package (as Fabian notes), then "never force-migrated" / "opt-in" mis-frames the rollout, and ADR 0003's rejected-alternative argument ("bloats the flagship for pure-managed users") rests on a user class that won't exist. Independently: a NuGet
<PackageReference>is not "opt-in" — it always restores transitively. Please state the actual mechanism (flagship has no dep + consumer adds the meta-package, OR hard dep that's inert behind a client flag) and reconcile 0003/0007 with "mandatory at next major." - Linux has no signature for the integrity gate (ADR 0009 / 0007). See inline.
- ABI range vs single-version lockstep (ADR 0005
[Min,Max]vs ADR 0010 "never forked"). These two read as contradictory; if fan-out is always one coordinated version, the acceptance range only grows the test matrix. Collapse to a single targeted revision (Min==Max) or explain how a range coexists with 0010.
Important — see inline on ADR 0004 (public-Go delivery + static link flags), ADR 0010 (atomic fan-out on immutable feeds), and distribution-design.md §8 (now stale vs ADR 0009).
Also: design-doc §10 ("fallback on load failure") contradicts ADR 0007's fail-loud-on-integrity rule — §10 should mirror the benign-vs-integrity split. And the heavy §5–§11 restatement of the ADRs is what's producing these drifts (the §8 one is a concrete example); consider trimming the design body to discussion/alternatives and linking out for decisions.
Nits: status convention split (0010 "Proposed" while dependents are "Accepted"); the "Pairs with" note is on 0001/0002 only — either add it to the template or to the other coupled pairs; dangling NATIVE_WRAPPER_SPEC.md refs (add "forthcoming, #4461") and a pointer to the cosmos_free-style dealloc export behind ADR 0006's "frees the native buffer"; "download only your RID" is unconditional-sounding but differs for framework-dependent builds.
Nothing here is a showstopper for the idea — it's a genuinely good design. These are about closing the seams before downstream teams build against it.
| ## Decision | ||
| - Go consumes the prebuilt **`include/` header and `lib/` library via cgo** (`#cgo CFLAGS -I…` to parse the header into `C.*` symbols; `#cgo LDFLAGS -L… -lazurecosmosdriver` to link), **not NuGet**. | ||
| - Prefer the **static `.a`** for a self-contained Go binary; dynamic linking is supported as an option. | ||
| - The header + lib are delivered through the **azure-sdk-for-go feed** — an Azure Artifacts Universal Package fetched at build, or a vendored "binaries" Go module with per-OS build tags (delivery shape is open Q3). Either way it derives from the ADR 0001 hand-off artifact. |
There was a problem hiding this comment.
Both delivery options here are problematic for public Go consumers. Azure Artifacts Universal Packages are internal-only, so an external go get user can't fetch them — that option only really covers the internal/dogfood phases. And a vendored "binaries" Go module means committing ~7 platforms of multi-MB native libs into a module the proxy pulls wholesale on every go get; that's exactly why the canonical cgo libraries (e.g. go-sqlite3) ship C source rather than prebuilt binaries. Related: Go has no package "feed" — modules resolve from VCS via the module proxy, so describing azure-sdk-for-go as a "feed" (also ADR 0002 / §6.2) is misleading. Can we add a concrete public-Go answer (GitHub Releases + a small fetch shim, or build-tag selection of a per-RID .a)? This feels bigger than Q3's internal-only "Universal Package vs vendored module" framing.
|
|
||
| ## Consequences | ||
| - Go reuses the exact same signed binaries as .NET — no Go-specific build of the driver. | ||
| - cgo + static lib means `CGO_ENABLED=1` and a C toolchain on the Go build host; cross-compilation needs a cross C toolchain. |
There was a problem hiding this comment.
One -lazurecosmosdriver won't be enough to statically link a Rust staticlib through cgo. A Rust staticlib isn't self-contained at link time — it pulls in the Rust std/panic/unwind runtime plus system libs (typically -lpthread -ldl -lm, often -lgcc_s/-lunwind), and static-cgo on musl is notoriously fiddly. Since linux-musl-x64 is in the GA matrix and this ADR prefers the static .a by default, worth noting the per-OS LDFLAGS must include the transitive system libs and flagging musl-static-cgo as a known-hard case (it bears on whether "static by default" is realistic on every matrix row — Q4).
| - Ship per-RID **`Microsoft.Azure.Cosmos.NativeAssets.<rid>`** packages, each carrying one platform's dynamic lib under `runtimes/<rid>/native/`. | ||
| - Front them with a thin **meta-package** whose `runtime.json` resolves the consumer's RID to the right per-RID package. |
There was a problem hiding this comment.
We should run this by the .NET/NuGet teams and see if there are any unexpected consequences to this choice.
There was a problem hiding this comment.
Makes sense. The ADR stays at the packaging-shape level, but we should validate the NuGet consequences with the .NET/NuGet folks before treating the layout as final.
Heath Stewart (heaths)
left a comment
There was a problem hiding this comment.
Keep changes to sdk/cosmos and you won't need my sign-off.
Resolve the 9 review findings on PR #4651: - #1 CI: drop broken NATIVE_WRAPPER_SPEC.md links (lives in #4461); add cSpell terms (cbindgen, Authenticode, ESRP, manylinux, etc.) - #2 ADR 0001/0009: require RID-keyed hand-off + both .so/.a + C-only header - #3 ADR 0009: enforce build-once via checksum+signature verification - #4 ADR 0005: u32 is a monotonic ABI revision; add MaxSupported (reject too-new) - #5 promote Q5 to new ADR 0010 (single version fan-out) - #6 ADR 0000 template: Status under the title - #7 reciprocal Pairs-with note in ADR 0001 - #8 ADR 0008: name glibc floor 2.17 (manylinux2014) - #9 ADR 0007: silent-fallback for benign causes vs fail-loud for integrity/ABI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
a6ee645 to
7e72641
Compare
…ry, discuss pure-Go-port alternative Go distribution (ADR 0004) is marked WIP on its delivery shape while the core model is stated firmly: Go links a PACKAGED native binary via cgo (CGO_ENABLED=1) through the C.* FFI stubs from the cbindgen header. Explicitly rules out a pure-Go shim that downloads the native library at build/run time — the binary is packaged and linked, never fetched by a stub. Also expands the pure-Go-reimplementation alternative with the findings from the time-boxed spike (a working CGO=0, zero-dependency vertical slice validated behavior-for-behavior against the real Rust driver via a differential harness), and records why it stays rejected for distribution (abandons build-once single provenance). Adds a narrative 'Alternative considered — a pure-Go port' section and tightens the Go-delivery open question to encode the no-shim constraint. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align the non-Go native-distribution ADRs with the current review direction so the docs answer the outstanding comments without changing the still-open Go delivery decision. Update the ADR index and design summary to match the accepted cutover and versioning model, clarify that build-once means one coordinated provenance event even if multiple platform jobs feed it, make UTF-8 explicit at the binding boundary, add the win-x86 platform case, and describe Linux authenticity plus roll-forward handling for public fan-out failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a focused ADR for the Go v2 implementation direction. The decision record keeps the SDK-level FFI choice separate from the packaging mechanics already covered by the native distribution ADRs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f7d60272-a96c-48e4-9a85-6e918db6ac26
This reverts commit 16f1bd7.
|
|
||
| ## 1. Purpose | ||
|
|
||
| The crate `azure_data_cosmos_driver_native` compiles to a native library — `azurecosmosdriver.{dll,so,dylib}` (and a static `.a`) plus a cbindgen-generated C header — wrapping the schema-agnostic driver core (see `NATIVE_WRAPPER_SPEC.md`, introduced in #4461). It is the single reuse point for **every non-Rust language SDK**. This doc defines how that compiled artifact reaches those SDKs: |
| - Go consumes the prebuilt **`include/` header and `lib/` library via cgo** with **`CGO_ENABLED=1`**: `#cgo CFLAGS -I…` parses the header into the `C.*` **FFI stubs**, and `#cgo LDFLAGS -L… -lazurecosmosdriver` links the library. **Not** NuGet, and **not** a pure-Go build. | ||
| - The native library is **packaged inside the delivered artifact** and linked at `go build`. It is **not** a pure-Go shim that downloads the library at build/run time — customers link a real binary through the FFI stubs; they are not handed a downloader stub. | ||
| - Prefer the **static `.a`** for a self-contained Go binary; dynamic linking is supported as an option. | ||
| - The header + lib are delivered through the **azure-sdk-for-go feed** — an Azure Artifacts Universal Package fetched at build, or a vendored "binaries" Go module with per-OS build tags (delivery *shape* is open Q3; in every shape the binary is **packaged**, not fetched by a shim). Either way it derives from the ADR 0001 hand-off artifact. |
| - Native transport is introduced in a **new SDK major version**. Adopting that major **is** adopting native: there is no per-client / per-call opt-in switch, and no managed transport kept in parallel *inside the same major*. | ||
| - Existing majors keep their current managed / pure transport unchanged. No consumer is **force-migrated by a routine (minor/patch) bump** — they move to native deliberately, by choosing to take the new major. | ||
| - The supported surface is bounded by the platform matrix (ADR 0008). On an unsupported platform/RID the native major fails with a **clear, actionable error**; it does **not** silently fall back to a managed path. If a pure-managed / pure-Go audience must be served long-term, that is a **separate, explicitly limited package**, not a hidden fallback inside the flagship. |
| ## Decision | ||
| - A single coordinated release pipeline next to the Rust build produces the per-platform binaries (ADR 0001), potentially across multiple platform-specific jobs, then joins them into one hand-off artifact. It **signs each binary once** where platform-native signing exists (Authenticode on Windows; codesign + notarization on macOS), records checksums for every artifact, and publishes the internal hand-off artifact. | ||
| - Per-language publish jobs **consume the already-signed hand-off** and emit NuGet / Go-consumable / JAR packages; they **never rebuild or re-sign the native binary** (they may sign their own package wrapper, e.g. the `.nupkg`/`.jar`, in that language's existing ESRP flow). | ||
| - Build-once is **enforced by verification, not just discipline**: before repackaging, every per-language publish job **verifies the hand-off's checksums and platform authenticity material** against the values published by the build job, and **fails the publish** on any mismatch — so a job physically cannot ship a rebuilt, altered, or unsigned native binary. On Windows/macOS this means verifying the binary signatures; on Linux, where the binary itself has no equivalent platform code-signing convention, this means verifying the checksum plus the build's provenance attestation / signed manifest for that RID. |
| "amqp", | ||
| "asyncoperation", | ||
| "authenticode", | ||
| "azcosmos", |
|
|
||
| ## Decision | ||
| - Ship per-RID **`Microsoft.Azure.Cosmos.NativeAssets.<rid>`** packages, each carrying one platform's dynamic lib under `runtimes/<rid>/native/`. | ||
| - Front them with a thin **meta-package** whose `runtime.json` resolves the consumer's RID to the right per-RID package. |
| | [0004](adr/0004-go-cgo-prebuilt.md) | Go consumes via **cgo against a prebuilt header + lib** delivered through the azure-sdk-for-go feed (Universal Package / vendored module). | Go has no NuGet; cgo links a C header + lib at build time. | | ||
| | [0005](adr/0005-abi-version-handshake.md) | The native lib exports **`cosmos_abi_version()`**; every host checks it before first use. | Independent cadences drift; fail fast, not corrupt. | | ||
| | [0006](adr/0006-binding-owns-marshalling.md) | Each binding **owns its marshalling and buffer copy-out**; the ABI stays bytes-in/bytes-out. | Keeps the ABI schema-agnostic. | | ||
| | [0007](adr/0007-native-is-opt-in.md) | Native transport ships in a **new SDK major**; no parallel managed transport, no silent fallback. | A major-version cutover, not a per-call opt-in. | |
| ## Decision | ||
| - A given native release (one build + signing, ADR 0001) is **fanned out to all language feeds simultaneously** from that single hand-off — .NET, Go, and (later) Java publish the *same* native version together. | ||
| - Each language SDK **pins the exact native version** from that fan-out and may cut its *own* managed/SDK releases independently between native releases; what it must not do is float onto a *different* native build. | ||
| - The native SemVer is the **one source of truth** for "which driver"; per-language package versions map to it but never fork it. Hosts enforce this at load by accepting only that exact ABI revision (ADR 0005) — there is no compatibility *range*, which keeps the test matrix a single point. |
| - Go consumes the prebuilt **`include/` header and `lib/` library via cgo** with **`CGO_ENABLED=1`**: `#cgo CFLAGS -I…` parses the header into the `C.*` **FFI stubs**, and `#cgo LDFLAGS -L… -lazurecosmosdriver` links the library. **Not** NuGet, and **not** a pure-Go build. | ||
| - The native library is **packaged inside the delivered artifact** and linked at `go build`. It is **not** a pure-Go shim that downloads the library at build/run time — customers link a real binary through the FFI stubs; they are not handed a downloader stub. | ||
| - Prefer the **static `.a`** for a self-contained Go binary; dynamic linking is supported as an option. | ||
| - The header + lib are delivered through the **azure-sdk-for-go feed** — an Azure Artifacts Universal Package fetched at build, or a vendored "binaries" Go module with per-OS build tags (delivery *shape* is open Q3; in every shape the binary is **packaged**, not fetched by a shim). Either way it derives from the ADR 0001 hand-off artifact. |
| - For each release, **one coordinated Rust release build/pipeline** produces all platform binaries (cdylib + staticlib), the cbindgen C header, an `ABI_VERSION`, and checksums, and **signs the binaries**. This may fan out across platform-specific jobs, but they join back into one hand-off governed as a single provenance event. | ||
| - These are published as an **internal-only hand-off artifact** (e.g. an Azure Artifacts Universal Package or a pipeline artifact) that is the **single source of truth for provenance**. | ||
| - This artifact is **not consumer-facing and not language-shaped.** Consumers never download it; per-language publish jobs consume it (distribution is ADR 0002; the pipeline that produces and fans it out is ADR 0009). | ||
| - The hand-off is **RID-keyed** (one subtree per `<os>-<arch>`/libc target) and carries **both link forms per RID** — the dynamic `.dll`/`.so`/`.dylib` *and* the static `.a` — plus a single **C-only header** (no C++ constructs). This layout is a hard requirement so any language, including a future Java JAR (ADR 0002), can repackage straight from the hand-off with **no redesign and no rebuild**. |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Proposed (for design review) | ||
|
|
||
| ## Context |
Move the native distribution design and ADRs under docs/native-driver-distribution so related language-specific distribution decisions can share a common root. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f7d60272-a96c-48e4-9a85-6e918db6ac26
|
|
||
| ## 1. Purpose | ||
|
|
||
| The crate `azure_data_cosmos_driver_native` compiles to a native library — `azurecosmosdriver.{dll,so,dylib}` (and a static `.a`) plus a cbindgen-generated C header — wrapping the schema-agnostic driver core (see `NATIVE_WRAPPER_SPEC.md`, introduced in #4461). It is the single reuse point for **every non-Rust language SDK**. This doc defines how that compiled artifact reaches those SDKs: |
| - Native transport is introduced in a **new SDK major version**. Adopting that major **is** adopting native: there is no per-client / per-call opt-in switch, and no managed transport kept in parallel *inside the same major*. | ||
| - Existing majors keep their current managed / pure transport unchanged. No consumer is **force-migrated by a routine (minor/patch) bump** — they move to native deliberately, by choosing to take the new major. | ||
| - The supported surface is bounded by the platform matrix (ADR 0008). On an unsupported platform/RID the native major fails with a **clear, actionable error**; it does **not** silently fall back to a managed path. If a pure-managed / pure-Go audience must be served long-term, that is a **separate, explicitly limited package**, not a hidden fallback inside the flagship. |
| - For each release, **one coordinated Rust release build/pipeline** produces all platform binaries (cdylib + staticlib), the cbindgen C header, an `ABI_VERSION`, and checksums, and **signs the binaries**. This may fan out across platform-specific jobs, but they join back into one hand-off governed as a single provenance event. | ||
| - These are published as an **internal-only hand-off artifact** (e.g. an Azure Artifacts Universal Package or a pipeline artifact) that is the **single source of truth for provenance**. | ||
| - This artifact is **not consumer-facing and not language-shaped.** Consumers never download it; per-language publish jobs consume it (distribution is ADR 0002; the pipeline that produces and fans it out is ADR 0009). | ||
| - The hand-off is **RID-keyed** (one subtree per `<os>-<arch>`/libc target) and carries **both link forms per RID** — the dynamic `.dll`/`.so`/`.dylib` *and* the static `.a` — plus a single **C-only header** (no C++ constructs). This layout is a hard requirement so any language, including a future Java JAR (ADR 0002), can repackage straight from the hand-off with **no redesign and no rebuild**. |
|
|
||
| ``` | ||
| Rust release build — ONE coordinated provenance event | ||
| produces .dll/.so/.dylib/.a + azurecosmosdriver.h + ABI_VERSION |
| - A single coordinated release pipeline next to the Rust build produces the per-platform binaries (ADR 0001), potentially across multiple platform-specific jobs, then joins them into one hand-off artifact. It **signs each binary once** where platform-native signing exists (Authenticode on Windows; codesign + notarization on macOS), records checksums for every artifact, and publishes the internal hand-off artifact. | ||
| - Per-language publish jobs **consume the already-signed hand-off** and emit NuGet / Go-consumable / JAR packages; they **never rebuild or re-sign the native binary** (they may sign their own package wrapper, e.g. the `.nupkg`/`.jar`, in that language's existing ESRP flow). | ||
| - Build-once is **enforced by verification, not just discipline**: before repackaging, every per-language publish job **verifies the hand-off's checksums and platform authenticity material** against the values published by the build job, and **fails the publish** on any mismatch — so a job physically cannot ship a rebuilt, altered, or unsigned native binary. On Windows/macOS this means verifying the binary signatures; on Linux, where the binary itself has no equivalent platform code-signing convention, this means verifying the checksum plus the build's provenance attestation / signed manifest for that RID. |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Accepted (proposed for review) | ||
|
|
||
| ## Context |
|
|
||
| **Status:** Proposed (for design review) | ||
|
|
||
| ## Context |
What this is
A design doc + ADRs (documentation only — no code or pipeline changes) proposing how the Rust-built native Cosmos driver (
azure_data_cosmos_driver_native→azurecosmosdriver.{dll,so,dylib}plus the cbindgen C header) is distributed to the language SDKs (.NET first, Go near-term, Java later).The design doc carries the discussion — context, alternatives, and the "why". The ADRs record each decision in short, numbered, immutable form (Context · Decision · Consequences · Alternatives · Status). If the two ever disagree, the ADR wins.
These are proposed for design review — nothing here changes build or release behavior yet.
TL;DR of the design
NativeAssetspackages + a thin meta-package (the SkiaSharp / SqlClient.SNI model) — download only your RID.cosmos_abi_version(); every host checks it before first use and fails fast on mismatch instead of corrupting memory.Contents
docs/native-distribution/distribution-design.md— the discussion doc: purpose, goals/constraints, the model, per-consumer link model, platform matrix, rollout phases, and open questions.docs/native-distribution/adr/0000-index.mdand0001–0009— one decision per record.Status & open questions
Status is provisional ("proposed for review"). The main open questions the doc captures for reviewers: the internal hand-off shape (Universal Package vs pipeline artifact), packaging-pipeline ownership and its security boundary, the Go delivery model, version-mapping across the three feeds, and SBOM / component-governance ownership for the Rust crate graph.