diff --git a/.github/instructions/vector-search-constitution.instructions.md b/.github/instructions/vector-search-constitution.instructions.md new file mode 100644 index 000000000..16b38e0d6 --- /dev/null +++ b/.github/instructions/vector-search-constitution.instructions.md @@ -0,0 +1,353 @@ +--- +applyTo: "samples/features/vector-search/**" +--- + +# Azure SQL Vector Search — Sample Constitution + +**Status:** ACTIVE +**Version:** 1.7 +**Scope:** `samples/features/vector-search/**` in this repository +**Canonical scenario:** Vector search (the first canonical scenario for this sample family) +**Canonical implementation:** [`vector-search-query-typescript`](/samples/features/vector-search/vector-search-query-typescript), merged via microsoft/sql-server-samples#1479 +**Purpose:** This is technical/sample governance for future implementation, review, and expansion of Azure SQL vector search samples in this repository. It is **not** a Microsoft Learn editorial style guide — it does not define article prose, Learn metadata, or Mosaic/editorial conventions. Editorial rules belong to the Microsoft Learn content pipeline, not here. + +This file uses `applyTo` frontmatter so GitHub Copilot and other tooling that honor `.github/instructions/*.instructions.md` automatically scope it to this sample's path. + +--- + +## 0. Governance + +- **0.1 (MUST)** Every requirement below has a stable ID (`ASV-CORE-#`, `ASV-VS-#`, `ASV-LANG-*-#`). Do not renumber or reuse an ID; superseded requirements are marked `SUPERSEDED` and kept for history, not deleted. +- **0.2 (MUST)** A requirement is binding only if it is traceable to one of the evidence sources in [§7 Evidence and source log](#7-evidence-and-source-log). Requirements without a source citation are marked `OPEN` and are not enforceable until resolved. +- **0.3 (MUST)** Layer inheritance is top-down: [§2 Article 1 — Program-wide requirements](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) binds every scenario and language. [§3 Article 2 — Vector search scenario](#3-article-2-vector-search-scenario-canonical-scenario-1) binds every language implementing vector search. [§4 Article 3 — Language-specific requirements](#4-article-3-language-specific-requirements) binds one language at a time. A more specific article may narrow or add to a broader one but MUST NOT contradict it; any conflict is a documentation defect, not an implicit override — raise it as a new row in [§6 Conflicts and open decisions](#6-conflicts-and-open-decisions). +- **0.4 (MUST)** Amending this constitution requires: (a) a stated rationale, (b) the evidence source for the new claim, (c) a version bump, (d) a dated changelog entry in [§8 Changelog](#8-changelog). +- **0.5 (MUST NOT)** Do not claim a language, platform, dataset, or index type is "implemented" or "supported" in this repository unless a merged, runnable sample under `samples/features/vector-search/` proves it. Planning documents, Teams meeting notes, and product announcements are directional, not implementation evidence. + +--- + +## 1. Reality snapshot (read this first) + +As of this constitution's authoring date (2026-09-15), the **only implemented language** in this sample tree is **TypeScript** (`vector-search-query-typescript/`), covering **Azure SQL Database** only, using the **50-hotel `HotelsData_Vector.json` dataset**, with **exact (kNN) search as the default** and **DiskANN as an opt-in that requires ≥1,000 rows and falls back to exact automatically below that threshold**. Every other platform (SQL Server 2025, SQL database in Fabric, Azure SQL Managed Instance) named in the source plan is **not yet implemented** in this repository — treat every platform reference below as a target for future work, not a current capability. + +**Languages are different: they are determined, not merely planned.** [§4 Article 3](#4-article-3-language-specific-requirements) fully specifies TypeScript, .NET, Python, Java, and Go as target contracts — runtime/package versions, authentication pattern, configuration, vector parameter binding, bulk-insert pattern, the DiskANN row-count gate, package-manager convention, sample folder naming, and CI shape are all decided below. TypeScript's contract is `Evidence: implemented` (the merged reference sample); .NET, Python, Java, and Go are determined but not yet built. A contributor can start implementation directly from those sections without first resolving open architecture questions; only real execution evidence, and a small number of explicitly flagged version-pin confirmations, remain outstanding per language. **Go remains explicitly out of scope for this v1 scenario by decision, not for lack of a specified contract** — the source plan marked it "future/optional," and having a determined contract below does not itself authorize starting a Go sample (see [ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)). + +--- + +## 2. Article 1 — Program-wide requirements (all Azure SQL vector work) + +These requirements apply to every current and future Azure SQL vector sample in this repository, regardless of scenario or language. + +### Platform scope + +- **ASV-CORE-1 (MUST)** State the platform(s) a sample targets explicitly in its README "applies to" section. Do not imply a platform works by omission. +- **ASV-CORE-2 (Evidence: implemented)** The only platform with a merged, runnable sample is **Azure SQL Database** (`infra/sql-database.bicep`, `Microsoft.Sql/servers` + `Microsoft.Sql/servers/databases`). +- **ASV-CORE-3 (OPEN — source: plan PDF p.1–2)** The source plan named four target platforms: SQL Server 2025, Azure SQL Database, SQL database in Fabric, Azure SQL Managed Instance, with Fabric Data Warehouse and Synapse explicitly out of scope. Only Azure SQL Database has shipped. Adding SQL Server 2025 (local Docker box), Fabric SQL database, or Managed Instance requires its own infra path (Fabric has no ARM path per the plan; box SQL Server 2025 may need instance-level `sp_configure`) and its own PR — do not fold multi-platform support into a single sample's scope without an explicit platform-switch design. + + The plan itself captured a per-platform comparison it called "the whole quickstart in one table" (PDF p.9–10, drafted against the .NET build-out; the plan notes Python mirrors the same steps via `pyodbc`). It is reproduced here verbatim as supporting evidence for why a platform switch is not a drop-in change — provisioning, auth, and cleanup all differ per platform even when the T-SQL vector surface (exact and approximate search) does not: + + | Concern | Azure SQL Database | Azure SQL Managed Instance | SQL Server 2025 (local Docker) | SQL database in Fabric | + |---|---|---|---|---| + | Provision | Bicep/azd (clean) | Bicep/azd (heavy, ~hours, needs vnet) | Local Docker (`mcr.microsoft.com/mssql/server:2025-latest`, or VM/ACI) | Fabric workspace + SQL database item via Fabric REST (no ARM) | + | Auth (as drafted for .NET; Python mirrors it via `pyodbc`) | Active Directory Default (managed identity/Entra) | Active Directory Default (managed identity/Entra) | SQL auth (`sa`/password) — no Entra in local Docker | Entra only — exact connection form unconfirmed | + | Enable preview | `ALTER DATABASE SCOPED CONFIGURATION SET PREVIEW_FEATURES = ON` | Same (per-database) | May also need instance-level `sp_configure` | Unconfirmed — may be on by default | + | Exact kNN (`VECTOR_DISTANCE`) | Yes | Yes | Yes | Yes | + | Approximate ANN (`VECTOR_SEARCH`/DiskANN) | Yes (preview) | Yes (preview) | Yes (preview) | Yes (preview) | + | Cleanup | `azd down` | `azd down` (slow) | `docker rm -f ` (no Azure resource) | Delete the Fabric item via REST/portal (no `azd down`) | + + Per the plan's own resolved-questions section (PDF p.16, comment `Commented [PK8]`), Managed Instance now supports ANN like the other flavors — "only SQL 2025 will have the older index and syntax" — which the table above reflects for `VECTOR_SEARCH`/DiskANN, but this remains unconfirmed by any merged sample (see [CONF-4](#6-conflicts-and-open-decisions)). + +- **ASV-CORE-31 (MUST, Decision: this constitution, synthesized from [ASV-CORE-2](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-3](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) and [§4 Article 3](#4-article-3-language-specific-requirements))** Current platform-by-language support status — keep this table in sync whenever a platform or language status changes elsewhere in this constitution: + + | Platform | TypeScript | .NET | Python | Java | Go | + |---|---|---|---|---|---| + | Azure SQL Database | `Evidence: implemented` (microsoft/sql-server-samples#1479) | Target contract specified ([§4.2](#42-net-not-yet-implemented-fully-specified-target-contract)) — not yet built | Target contract specified ([§4.3](#43-python-not-yet-implemented-fully-specified-target-contract)) — not yet built | Target contract specified ([§4.4](#44-javajdbc-not-yet-implemented-fully-specified-target-contract-reference-priority)) — not yet built | Target contract specified ([§4.5](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) — not yet built; Go itself stays out of scope for v1 regardless ([ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) | + | Azure SQL Managed Instance | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | + | SQL Server 2025 (local Docker) | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | + | SQL database in Fabric | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | Not yet in scope for any language | + + No language's contract in this constitution currently extends beyond Azure SQL Database, and no language contract may be assumed to transfer unchanged to another platform — the table immediately above ASV-CORE-3 documents concrete auth/provisioning/cleanup differences per platform (SQL auth instead of Entra for local Docker SQL Server 2025; an unconfirmed connection/auth form for Fabric). Extending any language to another platform requires updating this table, its own platform-specific auth/config section in [§4](#4-article-3-language-specific-requirements), and its own infra path per [ASV-CORE-3](#2-article-1-program-wide-requirements-all-azure-sql-vector-work). + +- **ASV-CORE-4 (MUST)** Fabric Data Warehouse and Synapse remain explicitly out of scope for this sample family. Do not add them without superseding this requirement. + +### Data provenance and CELA gate + +- **ASV-CORE-5 (MUST)** Every dataset shipped in `data/` MUST have a traceable, reusable-for-public-samples lineage. The current dataset (`data/HotelsData.JSON`, `data/HotelsData_Vector.json`) is the standard "Stay-Kay City Hotel"-style hotels dataset already used across other public Microsoft sample repositories (for example, Azure Cognitive Search and Cosmos DB/DocumentDB vector quickstarts). This lineage is evidence of prior reuse, **not** a substitute for an explicit CELA sign-off record. +- **ASV-CORE-6 (OPEN — source: plan PDF p.4, p.14; PR #914 evidence precedence)** No explicit CELA approval record for this specific dataset copy was found in the PDF, in PR #914, or in PR #1479. Before extending the dataset (adding rows, replacing it, or hosting it externally per the plan's "durable hosting" open question), confirm CELA/legal sign-off explicitly and record the approver and date here. Do not assume prior reuse elsewhere constitutes approval for this repository. +- **ASV-CORE-7 (MUST)** Do not depend on a PG-owned or team-owned public storage account for dataset hosting (per the plan's Derek/William concern about sandbox and storage takedown history). Prefer shipping the dataset in-repo (as the TypeScript sample does) or a durably-owned, CELA-cleared location. +- **ASV-CORE-8 (MUST)** Precomputed embeddings shipped in a dataset MUST record the exact embedding model and dimension count used to generate them (current: `text-embedding-3-small`, 1536 dimensions) so future language samples reproduce identical vectors rather than silently regenerating with a different model. + +### Authentication and security + +- **ASV-CORE-9 (MUST, Evidence: implemented)** Default to Microsoft Entra / managed-identity authentication (`DefaultAzureCredential` or language equivalent) against `https://database.windows.net/.default`. No sample may ship a default connection string containing a password. +- **ASV-CORE-10 (MUST, Evidence: implemented)** Provision the Azure SQL server with **Azure AD-only authentication** (`azureADOnlyAuthentication: true` in `infra/sql-database.bicep`) — no SQL-auth passwords in the default provisioning path. +- **ASV-CORE-11 (MUST)** A `.gitignore` scoped to each language sample MUST exclude `.env`, `.env.local`, `.env.*.local`, build output, and `node_modules`/equivalent language dependency caches. Follow the pattern in `vector-search-query-typescript/.gitignore`, **except** that the committed expected-output reference file required by [ASV-CORE-32](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) MUST NOT be excluded — do not gitignore the sample's entire `output/` directory wholesale; ignore only its ephemeral contents (see [ASV-CORE-32](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) and [CONF-6](#6-conflicts-and-open-decisions)). +- **ASV-CORE-12 (SHOULD)** Document a SQL-auth or key-based fallback only as a clearly labeled alternative for constrained environments (for example, local Docker SQL Server 2025 has no Entra path) — never as the default. +- **ASV-CORE-13 (SHOULD, source: plan PDF p.16)** Document least-privilege database permissions (`db_datareader`, `db_datawriter`, and `db_ddladmin` only if the sample creates/drops the vector index at runtime) alongside the broader-permissions convention used for learner-friction reduction, so a least-privilege reference exists even when the sample opens things up for learners. + +### Infrastructure and configuration + +- **ASV-CORE-14 (MUST, Evidence: implemented)** Provision via Azure Developer CLI (`azd up`) with Bicep templates under `infra/`. A sample's `azure.yaml` MUST document how to retrieve deployment outputs into the language sample's `.env` file (`azd env get-values`). +- **ASV-CORE-15 (MUST, Evidence: implemented)** The vector index (`CREATE VECTOR INDEX` / `DROP INDEX`) is a **data-plane** T-SQL DDL operation, not a control-plane/ARM resource. Do not model index creation/removal in Bicep; script it in the sample's own setup/query code. +- **ASV-CORE-16 (MUST)** Every environment variable a sample requires or accepts MUST be documented in a `sample.env` file with inline comments, and validated at startup with a clear error message naming the missing variable (see `vector-search-query-typescript/src/config.ts`). +- **ASV-CORE-17 (SHOULD, Evidence: implemented)** Azure OpenAI region selection is constrained by embedding-model availability; pin the allowed region list in Bicep (`@allowed([...])`) rather than allowing arbitrary regions, and document the quota-failure remediation steps (region change, SKU change, quota increase request). + +### Sample layout and naming conventions + +These conventions exist so multiple language samples can share the vector search scenario without colliding on folder names, table names, or CI scope — they apply to every current and future language, including the ones specified in [§4 Article 3](#4-article-3-language-specific-requirements). + +- **ASV-CORE-29 (MUST, Decision: this constitution)** Each language's sample lives in its own folder directly under `samples/features/vector-search/`, named `vector-search-query-` — the folder name encodes both the scenario (`query`, this constitution's one vector search scenario — see [§3 Article 2](#3-article-2-vector-search-scenario-canonical-scenario-1)) and the language, not the language alone. `` is one of: `typescript` (implemented), `dotnet`, `python`, `java`, or `go` (fully specified as a target contract but currently excluded from this scenario by decision — see [ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)). The required folder name per language is therefore `vector-search-query-` (for example `vector-search-query-typescript`, matching the merged reference implementation). Do not nest a language sample inside another language's folder, and do not create a shared multi-language folder. +- **ASV-CORE-30 (MUST, Decision: this constitution)** Each language's default table name is `hotels_` (for example `hotels_typescript`, `hotels_dotnet`, `hotels_python`, `hotels_java`), overridable via `AZURE_SQL_TABLE_NAME`, so several languages' samples can run against the same provisioned database without colliding on table or derived index names. + +### Configuration and environment-variable mechanism per language + +- **ASV-CORE-33 (MUST, Decision: this constitution, informed by the sibling Azure-Samples/cosmos-db-vector-samples repo's per-language convention — verified live on 2026-09-15)** There is no single universal configuration-file format across all five languages; each language sample uses its own idiomatic mechanism. This mirrors confirmed precedent from the sibling Cosmos DB vector search sample repo, which ships samples for the same five languages: its TypeScript, Python, Java, and Go samples all load configuration from a `.env` file (with a committed `sample.env` template); its .NET sample instead loads configuration from a committed `appsettings.json` via `Microsoft.Extensions.Configuration`, with a gitignored local-override layer for anything sensitive. This constitution adopts the same split for Azure SQL samples: + + | Language | Config mechanism | Committed template | Gitignored local/secret layer | + |---|---|---|---| + | TypeScript | `.env` (Node.js native `--env-file` loading) | `sample.env` | `.env`, `.env.local`, `.env.*.local` | + | .NET | `appsettings.json` bound via `Microsoft.Extensions.Configuration` | `appsettings.json` itself (placeholder values only — no secrets, since auth is Entra/managed-identity, see [ASV-CORE-9](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)) | `appsettings.local.json`, `appsettings.Development.json` | + | Python | `.env` (loaded via a `.env`-parsing library) | `sample.env` | `.env`, `.env.local` | + | Java | `.env` (loaded via a `.env`-parsing helper/library) | `sample.env` | `.env`, `.env.local` | + | Go | `.env` (loaded via a `.env`-parsing library) | `sample.env` | `.env`, `.env.local` | + + Every language's configuration MUST represent the same set of semantic values — SQL server, database, table name, OpenAI endpoint, embedding deployment, vector search algorithm, and drop-table-on-exit flag (the required/optional list defined in [ASV-LANG-TS-3](#41-typescript-implemented-reference-implementation)). The file mechanism and exact key/variable naming convention differ per language ([§4 Article 3](#4-article-3-language-specific-requirements) defines each), but the values and defaults MUST NOT. +- **ASV-CORE-34 (MUST)** A `.gitignore` scoped to a language sample MUST exclude that language's local/secret-bearing configuration files per the [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) table, in addition to the shared exclusions in [ASV-CORE-11](#2-article-1-program-wide-requirements-all-azure-sql-vector-work). For .NET specifically, do not gitignore `appsettings.json` itself — it is the committed template and carries no secrets under the Entra/managed-identity default; only `appsettings.local.json` and `appsettings.Development.json` are gitignored. + +### Service-query, identity, and embedding package requirements per language + +Every approved/specified language names an explicit package for each of three distinct roles below — do not conflate them into one "Azure SDK" umbrella. Terminology is used precisely, per role: a **driver** (implements the TDS/ODBC/JDBC wire protocol against SQL Server — none of the five SQL drivers below is part of the official Azure SDK family, even though some are Microsoft-published); an **Azure SDK client library** (published under the `azure-sdk-for-*` umbrella — Azure Identity and Azure AI OpenAI packages); and the **OpenAI client library** (the `openai` package, published by OpenAI, not Microsoft — it includes built-in Azure OpenAI support via an `AzureOpenAI` client class/export, but is not itself an Azure SDK package). Do not call a driver or the OpenAI client library "the Azure SDK." + +- **ASV-CORE-35 (MUST)** Role 1 — SQL query driver (executes T-SQL against Azure SQL, including `VECTOR_DISTANCE`/`VECTOR_SEARCH`): + + | Language | Package/artifact | Type | Canonical URL | Status | Version policy | Locator | + |---|---|---|---|---|---|---| + | TypeScript | `tedious` | Driver (pure-JS TDS implementation) | https://www.npmjs.com/package/tedious | `Evidence: implemented` (`package.json`) | Pinned `^19.0.0` | Plan PDF p.3 named `mssql`/`tedious` as deferred candidates; merged sample (#1479) selected `tedious`. | + | .NET | `Microsoft.Data.SqlClient` | Driver (official ADO.NET data provider) | https://www.nuget.org/packages/Microsoft.Data.SqlClient | `Decision: plan PDF` (not yet implemented) | Pin ≥ 7.0 (see [ASV-LANG-NET-2](#42-net-not-yet-implemented-fully-specified-target-contract) for the v7.0+ auth-package implication) | Plan PDF p.2 ("Library: Microsoft.Data.SqlClient (NuGet). Speaks TDS directly."); reference URL repeated in comment `Commented [PK3]`. | + | Python | `pyodbc` | Driver (DB-API 2.0 ODBC wrapper) | https://pypi.org/project/pyodbc/ | `Decision: plan PDF` (not yet implemented) | Pin ≥ current stable | Plan PDF p.2–3 ("Library: pyodbc (most common path for Azure SQL)."); reference URL repeated in comment `Commented [PK4]`. Also requires the separate, non-PyPI **ODBC Driver 18 for SQL Server** system driver — see [ASV-LANG-PY-2](#43-python-not-yet-implemented-fully-specified-target-contract). | + | Java | `com.microsoft.sqlserver:mssql-jdbc` (Maven) | Driver (Microsoft JDBC Driver for SQL Server) | https://learn.microsoft.com/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server | `Decision: plan PDF` (not yet implemented) | Pin ≥ `12.10.0.jre11` (latest on Maven Central, verified live 2026-09-15) | Plan PDF p.3 ("Library: Microsoft JDBC Driver for SQL Server (pure Java)."); reference URL repeated in comment `Commented [PK5]`. | + | Go | `github.com/microsoft/go-mssqldb` (+ its `azuread` subpackage for auth) | Driver (pure Go `database/sql` driver) | https://pkg.go.dev/github.com/microsoft/go-mssqldb | `Decision: this constitution` (no PDF evidence — see [ASV-LANG-GO-3](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) | Pin ≥ `v1.11.0` (latest tag, verified live 2026-09-15) | Not in the plan PDF — Go has zero PDF package evidence. Verified live 2026-09-15 against the driver's own repository and `pkg.go.dev`. | + +- **ASV-CORE-36 (MUST)** Role 2 — Authentication (Azure Identity; acquires the Microsoft Entra/managed-identity token used by both the SQL driver and the embedding client): + + | Language | Package/artifact | Type | Canonical URL | Status | Version policy | Locator | + |---|---|---|---|---|---|---| + | TypeScript | `@azure/identity` | Azure SDK client library | https://www.npmjs.com/package/@azure/identity | `Evidence: implemented` (`package.json`) | Pinned `^4.9.1` | Not named in the plan PDF (PDF only states "Managed Identity is supported," p.2); sourced from the merged sample. | + | .NET | `Azure.Identity`, plus `Microsoft.Data.SqlClient.Extensions.Azure` for connection-string Entra auth keywords | Azure SDK client library (`Azure.Identity`); driver companion extension package (`Extensions.Azure`) | https://www.nuget.org/packages/Azure.Identity ; https://www.nuget.org/packages/Microsoft.Data.SqlClient.Extensions.Azure | `Decision: plan PDF` for `Azure.Identity`; `Decision: this constitution` for the extension package (a currency finding, not in the plan) | Pin ≥ current stable for both | Plan PDF p.2 names `Azure.Identity` parenthetically ("or Azure.Identity"). The `Extensions.Azure` companion requirement is **not** in the plan — verified live 2026-09-15: as of `Microsoft.Data.SqlClient` v7.0+, connection-string keywords such as `Authentication=Active Directory Default` require this separate package. | + | Python | `azure-identity` | Azure SDK client library | https://pypi.org/project/azure-identity/ | `Decision: plan PDF` (not yet implemented) | Pin ≥ current stable | Plan PDF p.3 ("azure-identity + access token"). | + | Java | `com.azure:azure-identity` (Maven) | Azure SDK client library | https://learn.microsoft.com/java/api/overview/azure/identity-readme | `Decision: this constitution` (not named in the plan PDF for Java) | Pin ≥ `1.16.2` (latest on Maven Central, verified live 2026-09-15) | Not named in the plan PDF — the plan's Java bullet (p.3) does not name an auth library. Selected as the only Microsoft-published Java Azure Identity library; verified live against Maven Central 2026-09-15. | + | Go | `github.com/Azure/azure-sdk-for-go/sdk/azidentity` | Azure SDK client library | https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity | `Decision: this constitution` (no PDF evidence) | Pin ≥ current stable | Not in the plan PDF. Used internally by `go-mssqldb`'s `azuread` subpackage — see [ASV-LANG-GO-4](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required). | + +- **ASV-CORE-37 (MUST)** Role 3 — Embeddings (calls Azure OpenAI to generate the single query-time embedding; never used for the bulk dataset, which ships pre-embedded — see [ASV-VS-1](#3-article-2-vector-search-scenario-canonical-scenario-1)): + + | Language | Package/artifact | Type | Canonical URL | Status | Version policy | Locator | + |---|---|---|---|---|---|---| + | TypeScript | `openai` (its `AzureOpenAI` export) | **OpenAI client library** — published by OpenAI, not an Azure SDK package, though it includes built-in Azure OpenAI support | https://github.com/openai/openai-node | `Evidence: implemented` (`package.json`) | Pinned `^6.34.0` | Not named in the plan PDF; sourced from the merged sample. | + | .NET | `Azure.AI.OpenAI` (depends on the official `OpenAI` NuGet package) | Azure SDK client library | https://www.nuget.org/packages/Azure.AI.OpenAI | `OPEN — decision required`: only the embedding **model** name is in the plan (p.16: `text-embedding-3-small`); no .NET package is named anywhere in the PDF | **Currency flag:** the latest published version is prerelease/beta (installed with a `--prerelease` flag, verified live 2026-09-15) — confirm whether a public sample may depend on a prerelease Azure SDK package, or pin an older GA release, before implementation | Not in the plan PDF. `Azure.AI.OpenAI` is the only Microsoft-published .NET package for this role — named here from official NuGet documentation, not guessed; the prerelease status is the open decision. | + | Python | `openai` (its `AzureOpenAI` class) | **OpenAI client library** — not an Azure SDK package | https://pypi.org/project/openai/ | `Decision: this constitution` (not named in the plan PDF; the PDF only names the model) | Pin ≥ current stable | Not in the plan PDF. Selected as the only official client exposing an `AzureOpenAI` class for Python; verified live against PyPI 2026-09-15. | + | Java | `com.azure:azure-ai-openai` (Maven) | Azure SDK client library | https://learn.microsoft.com/java/api/overview/azure/ai-openai-readme | `OPEN — decision required`: not named in the plan PDF; the PDF only names the model | **Currency flag:** the latest published version is still beta (`1.0.0-beta.16`, verified live 2026-09-15 against Maven Central) — no GA release exists yet; confirm before implementation whether beta is acceptable for a public sample | Not in the plan PDF. Named from the official Maven Central listing, not guessed; the no-GA-yet status is the open decision. | + | Go | `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai` | Azure SDK client library | https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai | `Decision: this constitution` (no PDF evidence) | Pin ≥ `v0.9.0` (latest verified live 2026-09-15) | Not in the plan PDF. Verified live 2026-09-15 — see [ASV-LANG-GO-5](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required). | + +- **ASV-CORE-38 (MUST)** A sample's dependency manifest (`package.json`, `.csproj` package references, `requirements.txt`/`pyproject.toml`, `pom.xml`, or `go.mod`/`go.sum`) and its actual source-code imports MUST match the package identity (name, canonical URL, and role) recorded in [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) / [ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) / [ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) for that language. A PR that introduces, removes, or replaces a SQL driver, Azure Identity, or embedding-client package for a language MUST update the corresponding table row in the same PR — do not let the constitution and the shipped manifest silently drift apart. This extends the manifest/import-matching bar already implied by [ASV-CORE-25](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)'s contribution acceptance criteria. + +### Cross-language parity + +- **ASV-CORE-18 (MUST)** Every language implementation of the same scenario MUST use the same dataset, the same embedding model/dimension, and the same canonical search query so results are comparable across languages. Do not let one language's implementation silently diverge on any of these three. +- **ASV-CORE-19 (OPEN — source: plan PDF p.13, p.15)** The source plan calls for one fixed canonical query with a defined expected top result, to be used as the cross-language result-parity anchor (mirroring the Cosmos/DocumentDB "top result matches expected hotel name" pattern) with a defined tolerance for approximate-vs-exact ordering differences. No such canonical query/expected-result record exists yet in this repository. A future language sample MUST NOT invent its own expected-result contract; it must either reuse an existing one or add it here with an approver. +- **ASV-CORE-20 (MUST)** Approximate (DiskANN/ANN) search MAY return a different result ordering than exact (kNN) search for near-ties. Document this divergence per language rather than treating it as a bug, and do not assert bit-identical ordering between exact and approximate modes. + +### Validation, expected output, and cleanup + +- **ASV-CORE-21 (MUST, Evidence: implemented)** A sample's README MUST include a captured "Expected output" section from a real run, and MUST NOT present invented/hypothetical output as if it were captured. The same captured output MUST also be persisted as a committed reference file, not only as README prose — see [ASV-CORE-32](#2-article-1-program-wide-requirements-all-azure-sql-vector-work). +- **ASV-CORE-22 (MUST, Evidence: implemented)** Provide at least 3 troubleshooting entries grounded in real failure modes (see [§3](#3-article-2-vector-search-scenario-canonical-scenario-1) for the current set); do not include speculative troubleshooting entries without a verified cause/fix pair. +- **ASV-CORE-23 (MUST, Evidence: implemented)** Provide explicit cleanup instructions for both sample-created data (`DROP INDEX` / `DROP TABLE`) and provisioned Azure resources (`azd down` or platform-specific deletion steps, for example Azure OpenAI resource deletion). +- **ASV-CORE-24 (MUST, Evidence: implemented)** CI for a language sample MUST run on `pull_request` and `push` scoped by `paths:` to that language's folder, use pinned action SHAs, skip fork PRs for any workflow that would need secrets, and cancel superseded runs via `concurrency`. Follow `.github/workflows/vector-search-typescript-ci.yml` as the reference pattern. CI MUST NOT provision live Azure resources merely to type-check/build a sample; that remains a manual/local verification step (see [§3, ASV-VS-8](#3-article-2-vector-search-scenario-canonical-scenario-1)) unless a future PR explicitly adds an approved live-integration CI path. +- **ASV-CORE-32 (MUST, source: plan PDF p.13; gap in the current merged sample — see [CONF-6](#6-conflicts-and-open-decisions))** The expected-output text required by [ASV-CORE-21](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) MUST also be committed as a plain-text reference file under the sample's own `output/` subfolder — for example `vector-search-query-/output/sample-output.txt` — matching the plan's own instruction to "populate from a real run and commit to `output/sample-output.txt` for the verification script to assert against." A sample's `.gitignore` MAY still ignore other, genuinely ephemeral contents of `output/` (temporary run logs, debug dumps that could contain live data), but MUST NOT ignore this committed reference file wholesale (see [ASV-CORE-11](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). **This is not yet evidenced anywhere in this repository:** the merged TypeScript sample's `.gitignore` ignores `output/` in its entirety and no reference file is committed under `vector-search-query-typescript/` today — the only captured output lives as README prose. Treat this as a forward-looking requirement for every language, including a follow-up fix to the TypeScript sample, not as something already satisfied. + +### Contribution acceptance criteria + +- **ASV-CORE-25 (MUST)** A PR adding or changing a vector search sample in this tree is acceptable only if it: (a) does not silently expand platform/language claims beyond what it actually implements and runs, (b) updates `samples/features/vector-search/README.md`'s language table when adding a language, (c) includes a real captured "Expected output" from a run against the shared dataset and canonical query, (d) passes the scoped CI workflow for its language, (e) does not commit `.env` or other secret-bearing files, and (f) does not modify another language's sample as an unrelated side effect. +- **ASV-CORE-26 (MUST)** A PR that changes this constitution file MUST update [§8 Changelog](#8-changelog) and MUST NOT silently delete a requirement; supersede it instead (see [§0.1](#0-governance)). + +--- + +## 3. Article 2 — Vector search scenario (canonical scenario 1) + +This article narrows Article 1 to the specific "vector search" learner scenario: create a vector-capable table, load embeddings, run a similarity search, display results. + +- **ASV-VS-1 (MUST, Evidence: implemented)** The scenario's end-to-end path is: create a table with a `VECTOR(n)` column → bulk-load precomputed embeddings → generate one fresh query embedding at search time → run a similarity search → display top-N results with score. Do not add embedding generation for the loaded dataset at sample runtime — embeddings are precomputed and shipped (per the source plan's explicit "embeddings are provided" scope decision and the current implementation's `data/HotelsData_Vector.json`). +- **ASV-VS-2 (MUST, Evidence: implemented)** Generating embeddings inside/outside the database for the bulk dataset, using external AI models beyond the one pinned embedding model, and chunking strategies are explicitly **out of scope** for this scenario (per plan PDF p.1, preserved in the current implementation, which only calls Azure OpenAI for the single query embedding, not the bulk dataset). +- **ASV-VS-3 (MUST, Evidence: implemented)** The dataset is the 50-row hotels dataset (`data/HotelsData_Vector.json`). Do not present this scenario as validated against a different or larger dataset unless that dataset is actually shipped and used by the sample under review. +- **ASV-VS-4 (MUST — dataset-size / algorithm gate, Evidence: implemented)** Two algorithms exist for this scenario: + - **Exact (kNN) via `VECTOR_DISTANCE`** — works on any row count, no index required, 100% recall, is the default (`VECTOR_SEARCH_ALGORITHM=exact`). + - **Approximate (ANN) via `VECTOR_SEARCH` with a `DiskANN` index** — requires **at least 1,000 rows with non-null vectors** to create the index. This is a hard product requirement, not a sample-imposed limit. + - **With the current 50-row hotel dataset, DiskANN cannot be exercised as a genuinely successful end-to-end path.** The implemented sample detects this at runtime (row count `< 1000`), emits a warning, and **automatically falls back to exact search** even when a caller explicitly sets `VECTOR_SEARCH_ALGORITHM=diskann`. Do not describe DiskANN as "working" against the shipped 50-row dataset; describe it accurately as "falls back to exact below 1,000 rows," and do not claim an end-to-end DiskANN success path exists until an approved larger (≥1,000-row) dataset is loaded — see [ASV-VS-5](#3-article-2-vector-search-scenario-canonical-scenario-1). +- **ASV-VS-5 (OPEN)** No approved ≥1,000-row dataset exists yet for this scenario. Before any future PR claims a validated DiskANN path, it MUST: (a) load an approved (CELA-cleared, per [ASV-CORE-6](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)) dataset of at least 1,000 rows with non-null embeddings, (b) capture a real run's output showing the DiskANN index actually created and used (not the fallback path), and (c) update this requirement from OPEN to an evidence-backed status with the dataset's source and row count cited. +- **ASV-VS-6 (MUST, Evidence: implemented)** When an ANN index exists but its `METRIC` does not match the query's requested metric, the query silently falls back to exact kNN. Samples MUST keep the index `METRIC` and the query `METRIC` identical (current: `cosine` for both) and MUST document this failure mode in troubleshooting. +- **ASV-VS-7 (MUST, Evidence: implemented)** The table schema for this scenario MUST include an application-level primary key/id, display fields (name/content, category, rating or equivalent), and one `VECTOR(n)` column. The current reference shape (TypeScript) is: + ```sql + CREATE TABLE dbo. ( + id NVARCHAR(50) PRIMARY KEY, + name NVARCHAR(200) NOT NULL, + description NVARCHAR(MAX) NOT NULL, + category NVARCHAR(100) NULL, + rating FLOAT NULL, + embedding VECTOR(1536) NULL + ); + ``` + A future language sample MAY use idiomatic naming but MUST preserve the same conceptual columns and the same `VECTOR(1536)` dimension to stay comparable with the TypeScript reference (see [ASV-CORE-18](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-VS-8 (MUST)** A live end-to-end run (provision → load → query → cleanup) against a real Azure SQL Database is the acceptance bar for "this scenario works" for a given language; a type-check/build-only CI pass is necessary but not sufficient to claim the scenario is validated. +- **ASV-VS-9 (SHOULD, Evidence: implemented)** Minimum verified troubleshooting entries for this scenario (do not remove without a replacement of equal or better specificity): + 1. Login/auth failure — Entra admin not configured on the SQL server, or stale `az login` session. + 2. Azure OpenAI authentication error — missing `Cognitive Services OpenAI User` role, or wrong endpoint/deployment name. + 3. SQL firewall error — client IP not allowlisted. + 4. `DiskANN index requires at least 1,000 rows` — expected on the 50-row dataset; sample falls back to exact automatically (see [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1)). + 5. Vector dimension mismatch — precomputed embeddings must match the column's `VECTOR(n)` dimension (1536 for `text-embedding-3-small`); regenerate embeddings if the model changes. + +--- + +## 4. Article 3 — Language-specific requirements + +Each language section inherits Article 1 and Article 2. A language section for a language with no merged sample is a **target contract**, not a description of existing code — do not write it as if the code exists. + +### 4.1 TypeScript — IMPLEMENTED (reference implementation) + +- **ASV-LANG-TS-1 (MUST, Evidence: implemented)** Runtime: Node.js 20.6+ (native `--env-file` support), ESM (`"type": "module"`), executed directly via `tsx` (no separate compile-then-run step for `npm start`); `npm run build` / `npm run check` run type-checking only (`scripts/typecheck.js`). +- **ASV-LANG-TS-2 (MUST, Evidence: implemented; package identity — see [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Driver: `tedious` for SQL Server/Azure SQL connectivity; `@azure/identity` (`DefaultAzureCredential`, `getBearerTokenProvider`) for both SQL and Azure OpenAI auth; `openai` SDK's `AzureOpenAI` class for embeddings. Pinned in `package.json`: `@azure/identity ^4.9.1`, `openai ^6.34.0`, `tedious ^19.0.0`. +- **ASV-LANG-TS-3 (MUST, Evidence: implemented)** Configuration is centralized in `src/config.ts`, which validates required vs. optional environment variables at startup and throws a descriptive error naming the missing variable and pointing to `sample.env`. Required: `AZURE_SQL_SERVER`, `AZURE_SQL_DATABASE`, `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_EMBEDDING_DEPLOYMENT`. Optional with defaults: `AZURE_SQL_TABLE_NAME` (default `hotels_typescript`), `VECTOR_SEARCH_ALGORITHM` (default `exact`), `SQL_DROP_TABLE` (default `false`). +- **ASV-LANG-TS-4 (MUST, Evidence: implemented)** Table name is validated against `^[a-zA-Z_][a-zA-Z0-9_]{0,114}$` before use (max 115 chars, to leave room for the derived index name `ix_{name}_embedding` under SQL Server's 128-char object-name limit). Any future language sample accepting a configurable table name MUST apply an equivalent validation, not string-concatenate untrusted input into DDL. +- **ASV-LANG-TS-5 (MUST, Evidence: implemented)** Bulk insert uses a single transaction with parameterized `INSERT` statements and an explicit rollback-on-error path; it does not use string-concatenated SQL for row values. +- **ASV-LANG-TS-6 (MUST, Evidence: implemented)** Algorithm selection and the DiskANN row-count gate are implemented exactly as specified in [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1): row count is checked before attempting `CREATE VECTOR INDEX`; below 1,000 rows the code logs a warning and executes the exact-kNN code path regardless of the requested algorithm. +- **ASV-LANG-TS-7 (MUST, Evidence: implemented)** Package manager is `npm` (`package-lock.json` committed); do not introduce `yarn`/`pnpm` lockfiles for this sample. +- **ASV-LANG-TS-8 (MUST, Evidence: implemented)** CI (`.github/workflows/vector-search-typescript-ci.yml`) type-checks on Node 22 with `npm ci` + `npm run build`, scoped to `samples/features/vector-search/vector-search-query-typescript/**`, with pinned action SHAs and a same-repo fork-PR guard. + +### 4.2 .NET — NOT YET IMPLEMENTED (fully specified target contract) + +The plan's "8.0 LTS vs 9.0" framing (PDF p.10) predates the current .NET release cycle as of this constitution's authoring date and is superseded by the pin below. + +- **ASV-LANG-NET-1 (MUST, Decision: this constitution — supersedes plan PDF p.10's stale framing)** Target framework: `net10.0` (the current .NET LTS release; .NET 9 is Standard-Term-Support and is not the LTS baseline for a new sample). Console application using top-level statements (no explicit `Program` class), consistent with a simple runnable quickstart. +- **ASV-LANG-NET-2 (MUST, source: plan PDF p.6 verified-against-Learn snippet; package identity — see [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Package: `Microsoft.Data.SqlClient` (NuGet) for the SQL driver — no separate ODBC install required. Pin a specific minimum version in the `.csproj`; do not float on a wildcard version. **Currency finding (verified live 2026-09-15, not in the plan):** as of `Microsoft.Data.SqlClient` v7.0+, connection-string Entra auth modes (`Authentication=Active Directory Default` and similar) require the companion `Microsoft.Data.SqlClient.Extensions.Azure` NuGet package to also be installed — see [ASV-LANG-NET-3](#42-net-not-yet-implemented-fully-specified-target-contract). +- **ASV-LANG-NET-3 (MUST, source: plan PDF p.6, p.11 verified-against-Learn snippet; package identity — see [ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Authentication: Microsoft Entra / managed identity via the driver's built-in `Authentication=Active Directory Default` connection-string mode, which requires `Microsoft.Data.SqlClient.Extensions.Azure` installed alongside `Microsoft.Data.SqlClient` (see [ASV-LANG-NET-2](#42-net-not-yet-implemented-fully-specified-target-contract)) — no explicit token-acquisition call is required for the SQL connection itself (unlike TypeScript's `tedious`, which needs a manual `DefaultAzureCredential` token). For Azure OpenAI, use `Azure.Identity`'s `DefaultAzureCredential` with a bearer-token provider passed to `Azure.AI.OpenAI`'s client, mirroring [ASV-LANG-TS-2](#41-typescript-implemented-reference-implementation). `Azure.AI.OpenAI`'s package selection is `OPEN — decision required` per [ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) (currently prerelease/beta on NuGet); confirm before implementation. No sample may ship a default SQL-auth connection string with a password. +- **ASV-LANG-NET-4 (MUST, source: Azure-Samples/cosmos-db-vector-samples `nosql-vector-search-dotnet` `Program.cs`/`appsettings.json`, verified live 2026-09-15 — see [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Configuration: unlike the other four languages, .NET does **not** use a `.env` file. Build an `IConfiguration` with `new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).AddEnvironmentVariables().Build()`, then bind it to a strongly typed configuration record/class (`configuration.Bind(appConfig)`) — do not read raw environment variables ad hoc. `appsettings.json` MUST use nested sections, not flat `AZURE_*` keys, for example: + ```json + { + "AzureSql": { "Server": ".database.windows.net", "Database": "", "TableName": "hotels_dotnet" }, + "AzureOpenAI": { "Endpoint": "https://.openai.azure.com", "EmbeddingDeployment": "text-embedding-3-small" }, + "VectorSearch": { "Algorithm": "exact" }, + "Cleanup": { "DropTableOnExit": false } + } + ``` + `AddEnvironmentVariables()` lets CI or containerized runs override any value using the ASP.NET Core double-underscore convention (for example `AzureSql__Server`); document both the `appsettings.json` keys and their environment-variable override form in the sample's README. Required (must resolve to a non-empty value from either source): `AzureSql:Server`, `AzureSql:Database`, `AzureOpenAI:Endpoint`, `AzureOpenAI:EmbeddingDeployment`. Optional with defaults: `AzureSql:TableName` (default `hotels_dotnet`, see [ASV-CORE-30](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)), `VectorSearch:Algorithm` (default `exact`), `Cleanup:DropTableOnExit` (default `false`). A missing required value MUST raise a clear, named error at startup, not a generic connection failure. +- **ASV-LANG-NET-5 (MUST)** Table-name validation: apply the same identifier pattern as [ASV-LANG-TS-4](#41-typescript-implemented-reference-implementation) (`^[a-zA-Z_][a-zA-Z0-9_]{0,114}$`) before using a configurable table name in DDL. +- **ASV-LANG-NET-6 (MUST, source: plan PDF p.7 verified-against-Learn snippet)** Vector parameter binding: default to the JSON-string pattern verified in the plan — serialize the embedding with `System.Text.Json.JsonSerializer.Serialize` and bind as `CAST(@e AS VECTOR(1536))`. Native `SqlVector` parameter binding MAY replace this once the maintainer confirms the pinned `Microsoft.Data.SqlClient` version supports it (see [ASV-LANG-NET-12](#42-net-not-yet-implemented-fully-specified-target-contract)); either binding MUST produce the same `VECTOR(1536)` column contract. +- **ASV-LANG-NET-7 (MUST, source: plan PDF p.7 verified-against-Learn snippet)** Bulk insert: a single `SqlTransaction`, parameterized `INSERT`, executed in chunks of roughly 1,000–5,000 rows, with an explicit rollback on any row failure — mirrors [ASV-LANG-TS-5](#41-typescript-implemented-reference-implementation). +- **ASV-LANG-NET-8 (MUST)** DiskANN row-count gate: before `CREATE VECTOR INDEX`, query the non-null embedding row count; below 1,000, log a warning and execute the exact-kNN (`VECTOR_DISTANCE`) code path regardless of the requested algorithm — identical logic to [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1)/[ASV-LANG-TS-6](#41-typescript-implemented-reference-implementation). Do not implement a .NET-specific exception to this gate. +- **ASV-LANG-NET-9 (MUST)** Package manager: NuGet via `dotnet add package`; commit only the resulting `.csproj` package references, not a manual `packages.config`. +- **ASV-LANG-NET-10 (MUST)** Sample folder name: `vector-search-query-dotnet` (see [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-LANG-NET-11 (MUST)** CI: add `.github/workflows/vector-search-dotnet-ci.yml` mirroring [ASV-LANG-TS-8](#41-typescript-implemented-reference-implementation) — `pull_request`/`push` triggers scoped by `paths:` to `samples/features/vector-search/vector-search-query-dotnet/**`, pinned action SHAs, a same-repo fork-PR guard, `concurrency` cancel-in-progress, and a `dotnet build` step as the gate. CI MUST NOT provision live Azure resources (see [ASV-CORE-24](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-LANG-NET-12 (OPEN)** The exact minimum `Microsoft.Data.SqlClient` version that supports native `SqlVector` parameter binding is unresolved. This does not block implementation — [ASV-LANG-NET-6](#42-net-not-yet-implemented-fully-specified-target-contract) already specifies the JSON-cast default. Resolve and record the version here only if/when native binding is adopted. + +### 4.3 Python — NOT YET IMPLEMENTED (fully specified target contract) + +- **ASV-LANG-PY-1 (MUST, Decision: this constitution — plan PDF p.2 left "Python version TBD")** Runtime: Python 3.13 minimum (current stable CPython release at this constitution's authoring date). +- **ASV-LANG-PY-2 (MUST, source: plan PDF p.2–3 verified-against-Learn snippet; package identity — see [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Driver: `pyodbc`, requiring **ODBC Driver 18 for SQL Server** installed on the host (document per-OS install steps: Windows, macOS, Linux). `pymssql` is an explicitly rejected default for this sample — the plan flagged it as "less standard for Azure SQL + managed identity" and requiring separate evaluation; do not substitute it without superseding this requirement (see [ASV-LANG-PY-12](#43-python-not-yet-implemented-fully-specified-target-contract)). +- **ASV-LANG-PY-3 (MUST, source: plan PDF p.3, p.6 verified-against-Learn snippet; package identity — see [ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Authentication: Microsoft Entra / managed identity via the ODBC connection string's `Authentication=ActiveDirectoryDefault` mode (through ODBC Driver 18), or `azure-identity`'s `DefaultAzureCredential` plus an explicit access token. For Azure OpenAI, use `azure-identity`'s `DefaultAzureCredential` passed to the `openai` package's `AzureOpenAI` client class, mirroring [ASV-LANG-TS-2](#41-typescript-implemented-reference-implementation). No sample may ship a default SQL-auth connection string with a password. +- **ASV-LANG-PY-4 (MUST)** Configuration: centralize environment-variable loading and validation in one module (for example `config.py`), reading from a `.env` file per [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) — same required/optional variable set and defaults as [ASV-LANG-TS-3](#41-typescript-implemented-reference-implementation) (not .NET, which uses `appsettings.json` instead, see [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract)), with `AZURE_SQL_TABLE_NAME` defaulting to `hotels_python`. +- **ASV-LANG-PY-5 (MUST)** Table-name validation: same identifier pattern as [ASV-LANG-TS-4](#41-typescript-implemented-reference-implementation), enforced before use in DDL. +- **ASV-LANG-PY-6 (MUST, source: plan PDF p.6 verified-against-Learn snippet)** Vector parameter binding: serialize the embedding with `json.dumps` and bind as `CAST(? AS VECTOR(1536))` — the ODBC driver's confirmed VECTOR handling path per the plan. +- **ASV-LANG-PY-7 (MUST, source: plan PDF p.6 verified-against-Learn snippet)** Bulk insert: `cursor.fast_executemany = True` with `executemany()` over parameterized rows, chunked consistently with [ASV-LANG-NET-7](#42-net-not-yet-implemented-fully-specified-target-contract); wrap in an explicit transaction with rollback on error. +- **ASV-LANG-PY-8 (MUST)** DiskANN row-count gate: identical logic to [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1) — check the non-null embedding row count before `CREATE VECTOR INDEX`; fall back to exact kNN with a logged warning below 1,000 rows. +- **ASV-LANG-PY-9 (MUST)** Package manager and dependency pinning: `pip` with a `requirements.txt` pinned using `>=` lower bounds (not exact `==` pins), so security/bugfix updates aren't blocked; required packages: `pyodbc`, `azure-identity`, `openai`. +- **ASV-LANG-PY-10 (MUST)** Sample folder name: `vector-search-query-python` (see [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-LANG-PY-11 (MUST)** CI: add `.github/workflows/vector-search-python-ci.yml` mirroring [ASV-LANG-TS-8](#41-typescript-implemented-reference-implementation) — scoped by `paths:` to `samples/features/vector-search/vector-search-query-python/**`, pinned action SHAs, fork-PR guard, concurrency cancel, and a syntax/type-check step (for example `python -m py_compile` or `mypy`) as the gate. Because ODBC Driver 18 is a host dependency, CI MUST either install it explicitly in the runner or scope the gate to syntax/type-checking only — do not silently skip the check. +- **ASV-LANG-PY-12 (OPEN)** Whether `pymssql` should ever be documented as a secondary, clearly labeled alternative (per the plan's "evaluate before recommending" note) remains unresolved; [ASV-LANG-PY-2](#43-python-not-yet-implemented-fully-specified-target-contract) already establishes `pyodbc` as the required default, so this does not block implementation. + +### 4.4 Java/JDBC — NOT YET IMPLEMENTED (fully specified target contract; reference priority) + +The plan marked Java "reference — not v1 priority" (PDF p.3) — sequence it after TypeScript, .NET, and Python if resourcing requires it, but the contract below is fully determined now so no design decision blocks starting it. + +- **ASV-LANG-JAVA-1 (MUST, Decision: this constitution — the plan did not specify a Java runtime)** Runtime: Java 21 (current LTS release); Maven 3.9+ as the build tool. +- **ASV-LANG-JAVA-2 (MUST, source: plan PDF p.3; package identity — see [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Driver: Microsoft JDBC Driver for SQL Server (`com.microsoft.sqlserver:mssql-jdbc`, pure Java) — no ODBC install required. Pin a specific minimum version as a Maven dependency; do not use a version range. +- **ASV-LANG-JAVA-3 (MUST, Decision: this constitution — no Java code sample exists in the plan; generalized from the driver's documented Azure AD authentication modes; package identity — see [ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Authentication: Microsoft Entra / managed identity via the driver's documented Azure AD authentication connection property (for example `authentication=ActiveDirectoryDefault` in recent `mssql-jdbc` releases). **The exact property name and minimum driver version MUST be verified against the pinned `mssql-jdbc` version's own documentation at implementation time** (see [ASV-LANG-JAVA-9](#44-javajdbc-not-yet-implemented-fully-specified-target-contract-reference-priority)) — do not ship an assumed property name without confirming it. For Azure OpenAI, use `com.azure:azure-identity`'s credential classes for the SQL connection property value and, for the embedding call, `com.azure:azure-ai-openai` — the latter's package selection is `OPEN — decision required` per [ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) (no GA release exists yet; currently beta-only). No sample may ship a default SQL-auth connection string with a password. +- **ASV-LANG-JAVA-4 (MUST)** Configuration: centralize environment-variable loading and validation (for example a `Config` record or class), reading from a `.env` file per [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) — same required/optional variable set as [ASV-LANG-TS-3](#41-typescript-implemented-reference-implementation) (not .NET, which uses `appsettings.json` instead, see [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract)), with `AZURE_SQL_TABLE_NAME` defaulting to `hotels_java`. +- **ASV-LANG-JAVA-5 (MUST)** Table-name validation: same identifier pattern as [ASV-LANG-TS-4](#41-typescript-implemented-reference-implementation), enforced before use in DDL. +- **ASV-LANG-JAVA-6 (MUST, Decision: this constitution — generalized from the JSON-cast pattern verified for .NET/Python in the plan; no Java-specific snippet exists in the source)** Vector parameter binding: default to serializing the embedding as a JSON array string and binding via `PreparedStatement.setString(...)` with `CAST(? AS VECTOR(1536))` in the SQL text, mirroring [ASV-LANG-NET-6](#42-net-not-yet-implemented-fully-specified-target-contract)/[ASV-LANG-PY-6](#43-python-not-yet-implemented-fully-specified-target-contract). Verify against the pinned driver's actual parameter-binding API at implementation time. +- **ASV-LANG-JAVA-7 (MUST)** Bulk insert: `PreparedStatement` batching (`addBatch()`/`executeBatch()`) over parameterized rows, chunked consistently with [ASV-LANG-NET-7](#42-net-not-yet-implemented-fully-specified-target-contract), wrapped in an explicit transaction (`setAutoCommit(false)`) with rollback on error. +- **ASV-LANG-JAVA-8 (MUST)** DiskANN row-count gate: identical logic to [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1) — check the non-null embedding row count before `CREATE VECTOR INDEX`; fall back to exact kNN with a logged warning below 1,000 rows. +- **ASV-LANG-JAVA-9 (OPEN)** The exact minimum `mssql-jdbc` version and its documented Azure AD connection-property name ([ASV-LANG-JAVA-3](#44-javajdbc-not-yet-implemented-fully-specified-target-contract-reference-priority)) must be confirmed against current driver documentation before merging. This is the one item in this section that would block a correct auth implementation and MUST be resolved during Build, not guessed. +- **ASV-LANG-JAVA-10 (MUST)** Sample folder name: `vector-search-query-java` (see [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-LANG-JAVA-11 (MUST)** CI: add `.github/workflows/vector-search-java-ci.yml` mirroring [ASV-LANG-TS-8](#41-typescript-implemented-reference-implementation) — scoped by `paths:` to `samples/features/vector-search/vector-search-query-java/**`, pinned action SHAs, fork-PR guard, concurrency cancel, and `mvn compile` (or `mvn verify` without live Azure calls) as the gate. + +### 4.5 Go — NOT YET IMPLEMENTED (fully specified target contract; not currently required) + +The plan marked Go "future/optional... out of scope for v1" (PDF p.3) and provided no driver, auth, or code evidence for it — unlike .NET/Python/Java, nothing here traces to the plan PDF's verified-against-Learn snippets. Every requirement below instead traces to the actual Go SQL Server driver's public documentation, fetched and verified on 2026-09-15 (see [§7 Evidence and source log](#7-evidence-and-source-log)). This section exists so a Go sample can be implemented later from a determined contract, matching .NET/Python/Java, even though Go coverage is not currently required. + +- **ASV-LANG-GO-1 (MUST, source: plan PDF p.3)** Go remains explicitly out of scope for the v1 vector search scenario. Specifying the target contract below does **not** itself authorize starting a Go sample — bringing Go into scope requires a separate, explicit decision recorded here with an owner and date, superseding this requirement. +- **ASV-LANG-GO-2 (MUST, source: github.com/microsoft/go-mssqldb README, fetched 2026-09-15)** Runtime: Go 1.25 or later — the minimum version the driver itself requires. +- **ASV-LANG-GO-3 (MUST, source: github.com/microsoft/go-mssqldb README + pkg.go.dev, fetched 2026-09-15; latest tagged release `v1.11.0`, 2026-08-24; package identity — see [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Driver: `github.com/microsoft/go-mssqldb` (pure Go `database/sql` driver for SQL Server/Azure SQL), pinned to `v1.11.0` or later. For Entra/managed-identity auth, additionally import the `github.com/microsoft/go-mssqldb/azuread` subpackage, which registers a second driver name for `database/sql`. +- **ASV-LANG-GO-4 (MUST, source: `github.com/microsoft/go-mssqldb/azuread/driver.go` and `configuration.go` at tag `v1.11.0`, fetched 2026-09-15; package identity — see [ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Authentication: open the database with `sql.Open("azuresql", dsn)` (the `azuread` subpackage's registered driver name), where the DSN includes `fedauth=ActiveDirectoryDefault` — this triggers the same default-credential-chain behavior as the other languages' `DefaultAzureCredential` usage. Do not use a SQL-auth (`user id`/`password`) DSN as the default. For Azure OpenAI, use `azure-sdk-for-go`'s `azidentity` package (`github.com/Azure/azure-sdk-for-go/sdk/azidentity`), mirroring [ASV-LANG-TS-2](#41-typescript-implemented-reference-implementation). No sample may ship a default SQL-auth connection string with a password. +- **ASV-LANG-GO-5 (MUST, source: pkg.go.dev, `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai`, fetched 2026-09-15; current version `v0.9.0`; package identity — see [ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work))** Azure OpenAI client library: `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai` for generating the query embedding. Do not hand-roll raw HTTP calls to the Azure OpenAI REST API. Confirm the exact embeddings-client method name and request/response shape against the pinned SDK version at implementation time (see [ASV-LANG-GO-14](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)). +- **ASV-LANG-GO-6 (MUST)** Configuration: centralize environment-variable loading and validation in one file (for example `config.go`), reading from a `.env` file per [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) — same required/optional variable set and defaults as [ASV-LANG-TS-3](#41-typescript-implemented-reference-implementation) (not .NET, which uses `appsettings.json` instead, see [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract)), with `AZURE_SQL_TABLE_NAME` defaulting to `hotels_go`. +- **ASV-LANG-GO-7 (MUST)** Table-name validation: same identifier pattern as [ASV-LANG-TS-4](#41-typescript-implemented-reference-implementation), enforced before use in DDL. +- **ASV-LANG-GO-8 (MUST, source: no VECTOR-type-specific driver support was found in `go-mssqldb`'s README or package documentation as of the 2026-09-15 research cited above)** Vector parameter binding: no native Go VECTOR binding type is confirmed to exist. Default to the same JSON-string pattern used for the other not-yet-implemented languages — serialize the embedding (for example with `encoding/json`) and bind it as a string parameter, casting in the SQL text with `CAST(@p1 AS VECTOR(1536))` (`go-mssqldb` uses positional `@p1`, `@p2`, ... parameter placeholders, not named parameters like `tedious`/`pyodbc`/`Microsoft.Data.SqlClient`). Do not assume a native binding type without re-confirming against current driver documentation. +- **ASV-LANG-GO-9 (MUST)** Bulk insert: batched parameterized `INSERT` statements inside an explicit `*sql.Tx`, chunked consistently with [ASV-LANG-NET-7](#42-net-not-yet-implemented-fully-specified-target-contract), with `tx.Rollback()` on any error (checked, not ignored) and `tx.Commit()` on success. +- **ASV-LANG-GO-10 (MUST)** DiskANN row-count gate: identical logic to [ASV-VS-4](#3-article-2-vector-search-scenario-canonical-scenario-1) — query the non-null embedding row count before `CREATE VECTOR INDEX`; fall back to exact kNN with a logged warning below 1,000 rows. Do not implement a Go-specific exception to this gate. +- **ASV-LANG-GO-11 (MUST)** Package manager: Go modules (`go.mod`/`go.sum` committed); pin exact dependency versions via `go.sum`, not floating pseudo-versions. +- **ASV-LANG-GO-12 (MUST)** Sample folder name: `vector-search-query-go` (see [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)). +- **ASV-LANG-GO-13 (MUST)** CI: if/when Go is brought into scope per [ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required), add `.github/workflows/vector-search-go-ci.yml` mirroring [ASV-LANG-TS-8](#41-typescript-implemented-reference-implementation) — scoped by `paths:` to `samples/features/vector-search/vector-search-query-go/**`, pinned action SHAs, fork-PR guard, concurrency cancel, and `go build ./...` plus `go vet ./...` as the gate. +- **ASV-LANG-GO-14 (OPEN)** Whether `go-mssqldb` (or any Go SQL Server driver) has confirmed, native VECTOR-type support beyond the JSON-cast fallback in [ASV-LANG-GO-8](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) is unresolved as of this constitution's research date; driver capabilities can change between releases, so re-verify against the pinned driver version's current documentation before implementation. The exact `azopenai` embeddings-client API surface ([ASV-LANG-GO-5](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) is similarly unconfirmed beyond the package's existence and version. + +### 4.6 Adding a new language — process requirement + +- **ASV-LANG-NEW-1 (MUST)** .NET ([§4.2](#42-net-not-yet-implemented-fully-specified-target-contract)), Python ([§4.3](#43-python-not-yet-implemented-fully-specified-target-contract)), Java ([§4.4](#44-javajdbc-not-yet-implemented-fully-specified-target-contract-reference-priority)), and Go ([§4.5](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) already have fully specified target contracts above — implement directly against those sections; do not re-derive requirements from the plan PDF or driver documentation, or invent new ones, for those four languages. Note that having a contract does not by itself put Go in scope — see [ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required). +- **ASV-LANG-NEW-2 (MUST)** For any language beyond the five named in the source plan (TypeScript, .NET, Python, Java, Go): (a) read Articles 1 and 2 in full, (b) confirm the dataset/embedding-model/canonical-query parity requirements in [ASV-CORE-18](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-19](#2-article-1-program-wide-requirements-all-azure-sql-vector-work), (c) add a new `4.N` subsection following the same structure as [§4.2](#42-net-not-yet-implemented-fully-specified-target-contract)–[§4.5](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) (runtime/package, auth, config, vector binding, bulk insert, DiskANN gate, package manager, folder naming, CI), citing verified driver/product documentation rather than guessing, and (d) update [§1 Reality snapshot](#1-reality-snapshot-read-this-first) and `samples/features/vector-search/README.md`'s language table in the same PR once a sample is merged, changing its status from "fully specified target contract" to `Evidence: implemented`. + +--- + +## 5. Cleanup and lifecycle + +- **ASV-CORE-27 (MUST, Evidence: implemented)** Data-only cleanup: `DROP INDEX IF EXISTS ix__embedding ON dbo.
; DROP TABLE IF EXISTS dbo.
;`. +- **ASV-CORE-28 (MUST, Evidence: implemented)** Resource cleanup: `azd down` for Azure SQL Database + Azure OpenAI provisioned via this sample's `infra/`. Platforms without an `azd`-managed lifecycle (local Docker SQL Server 2025, Fabric SQL database) MUST document their own explicit teardown steps once implemented (`docker rm -f `; Fabric REST/portal deletion) rather than instructing a learner to run `azd down` against resources it didn't provision. + +--- + +## 6. Conflicts and open decisions + +Document a conflict here instead of silently resolving it by guessing. Do not delete a row; mark it resolved with an owner and date once actually decided. + +| ID | Conflict | Source A | Source B | Status | +|---|---|---|---|---| +| CONF-1 | Language priority order | Plan PDF (p.2): .NET and Python are priority; TypeScript is "deferred to backlog" pending Pooja Kamath's confirmation of vector + managed-identity support in the Node.js ecosystem. | Actual shipped implementation (PR microsoft/sql-server-samples#1479): **TypeScript** is the only merged, canonical sample; .NET and Python have no merged sample. | **Open — documented, not resolved.** This constitution records the plan's stated priority and now fully specifies .NET and Python as target contracts in [§4.2](#42-net-not-yet-implemented-fully-specified-target-contract)/[§4.3](#43-python-not-yet-implemented-fully-specified-target-contract), and records reality in [§1](#1-reality-snapshot-read-this-first) and [§4.1](#41-typescript-implemented-reference-implementation). Do not silently reclassify TypeScript as having always been the priority language; if the team now intends TypeScript-first, record that decision explicitly with an owner and date. | +| CONF-2 | TypeScript VECTOR/managed-identity support | Plan PDF comment `Commented [PK1]` (Pooja Kamath, page 2): TypeScript/Node.js was **not** part of the original VECTOR driver onboarding effort (which covered .NET, JDBC, ODBC); VECTOR support in TypeScript was therefore unvalidated and "should not be treated as committed." A reply comment `Commented [DB2R1]` (Dina Berry) marks this "Fixed" without further detail in the extracted text. | The merged TypeScript sample (PR #1479) demonstrably uses native `VECTOR(1536)` columns and both `VECTOR_DISTANCE` and `VECTOR_SEARCH`/DiskANN successfully via `tedious`. | **Resolved by implementation evidence.** TypeScript VECTOR support is confirmed working as of the merged sample; the earlier PDF caveat is superseded by [ASV-LANG-TS-1 through ASV-LANG-TS-8](#41-typescript-implemented-reference-implementation). | +| CONF-3 | Dataset CELA/hosting approval | Plan PDF (p.4, p.14): dataset choice pending "OK to use" + CELA/hosting confirmation; two candidates discussed (Cosmos vector samples data, ZavaTax), neither the shipped hotels dataset by name. | Merged sample ships `data/HotelsData.JSON` / `data/HotelsData_Vector.json` in-repo with no CELA approval citation found in the PDF, PR #914, or PR #1479. | **Open.** See [ASV-CORE-5](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-6](#2-article-1-program-wide-requirements-all-azure-sql-vector-work). Do not treat the dataset's presence in the repo as proof of CELA sign-off; confirm explicitly before extending or re-hosting it. | +| CONF-4 | Managed Instance DiskANN support | Plan PDF resolved-questions section (p.16), comment `Commented [PK8]` (Pooja Kamath): "It will be supported in MI now. Only SQL 2025 will have the older index and syntax" — i.e., MI now supports ANN like the other flavors. | No Managed Instance sample has been merged in this repository to confirm this in code. | **Open — unimplemented.** Record the plan's stated resolution here, but do not claim MI DiskANN support is validated in this repository until a merged MI sample provides evidence. | +| CONF-5 | Platform priority if not all four ship | Plan PDF comment `Commented [PK7]` (Pooja Kamath, p.16): "We should ship all. First pref to Azure SQL Hyperscale, followed by the others. If MI is too complex to setup, [minimum is] Azure SQL Hyperscale (PaaS) + SQL Server 2025 local docker." | Shipped implementation covers Azure SQL Database only (not explicitly Hyperscale-tier); no SQL Server 2025 local Docker sample exists yet. | **Open.** Confirm whether "Azure SQL Database" as provisioned (`sku: S0/Standard` in `infra/sql-database.bicep`) satisfies the "Hyperscale first" preference, or whether a future PR must change the provisioned SKU/tier to match this stated priority. | +| CONF-6 | Committed expected-output reference file | Plan PDF (p.13): "Populate from a real run and commit to `output/sample-output.txt` for the verification script to assert against." | Merged TypeScript sample's `.gitignore` ignores `output/` in its entirety; no `output/sample-output.txt` (or equivalent) is committed anywhere under `vector-search-query-typescript/`. The only captured output today lives as prose in the README. | **Open — the plan's intent was not carried into the merged implementation.** [ASV-CORE-32](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) now requires the committed file going forward for every language, plus a carve-out in [ASV-CORE-11](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) so `.gitignore` stops excluding it wholesale. Do not treat the current TypeScript `.gitignore`'s blanket `output/` entry as the template for this specific pattern; a follow-up PR to TypeScript itself is needed to close this gap. | + +--- + +## 7. Evidence and source log + +| Locator | What it is | How it was used | +|---|---|---| +| `plan-2026-07-01-0842-azure-sql-vector-search-quickstart.pdf` (16 pages, exported from Word with visible comments) | Source plan from a 2026-07-01 Teams meeting ("Azure SQL + Vector DB quickstarts"), author Dina Berry via Copilot, with reviewer comments `Commented [PK1]`–`[PK8]` (Pooja Kamath) and `Commented [DB2R1]` (Dina Berry, reply) | Extracted in full with PyMuPDF (text + comment balloons render as inline page text in this export — no native PDF annotation objects were present). Every plan-derived requirement above cites a page number; every comment is quoted verbatim in [§6](#6-conflicts-and-open-decisions). | +| diberry/project-dina#914 ("(ignore) Plan Azure SQL vector constitutions") | Prior Plan-phase lifecycle record; recorded that the original SharePoint Word source was inaccessible (auth-blocked) and that Build never started | Confirmed this constitution supersedes that blocked attempt; reused its three-layer framing (program-wide / scenario / language) as the article structure here, adapted to a single repo-local file per the current task's explicit instruction. | +| microsoft/sql-server-samples#1479 ("Add Azure SQL vector search TypeScript quickstart sample"), merged 2026-08-31, into `samples/features/vector-search/` | The only canonical, implemented Azure SQL vector search sample | Read directly from `upstream/master` (tip `beaab06e`, fetched 2026-09-15) at: `samples/features/vector-search/README.md`, `vector-search-query-typescript/README.md`, `src/config.ts`, `src/index.ts`, `sample.env`, `.gitignore`, `package.json`, `azure.yaml`, `infra/main.bicep`, `infra/sql-database.bicep`, `data/HotelsData.JSON`, `.github/workflows/vector-search-typescript-ci.yml`. Every `Evidence: implemented` requirement above traces to one or more of these files. | +| `github.com/microsoft/go-mssqldb` (README, and `azuread/driver.go` + `azuread/configuration.go` at tag `v1.11.0`), and `pkg.go.dev` for `github.com/microsoft/go-mssqldb`, `github.com/microsoft/go-mssqldb/azuread`, and `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai` | Public, independently verifiable documentation for Microsoft's official Go SQL Server driver and the Azure OpenAI Go SDK — used because the plan PDF provides no Go evidence at all | Fetched live on 2026-09-15. Confirmed: minimum Go version (1.25+); latest driver release `v1.11.0` (tagged 2026-08-24); the `azuread` subpackage registers driver name `azuresql` and reads a `fedauth` DSN parameter (`ActiveDirectoryDefault` among its accepted values); `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai` exists at version `v0.9.0`. No mention of a native VECTOR parameter-binding type was found in any of these sources — [ASV-LANG-GO-8](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) and [ASV-LANG-GO-14](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) reflect that absence rather than asserting a capability that wasn't found. | +| github.com/Azure-Samples/cosmos-db-vector-samples (sibling Cosmos DB vector search sample repo, ships the same five languages) — `nosql-vector-search-dotnet/Program.cs`, `appsettings.json`, `.gitignore`; `nosql-vector-search-python/sample.env`; `nosql-create-index-java/src/.../Config.java`; file-tree search for `appsettings`/`.env`/`sample.env` across all language folders | Confirmed, working precedent for how a real, published Microsoft sample repo splits configuration mechanism by language, cited because the source plan PDF does not address this at all | Fetched live on 2026-09-15 via the GitHub API/raw content. Confirmed: the .NET sample uses a committed `appsettings.json` (nested JSON, placeholder values, no secrets) bound through `ConfigurationBuilder().AddJsonFile(...).AddEnvironmentVariables()`, with `appsettings.local.json`/`appsettings.Development.json` gitignored as the sensitive-override layer; the TypeScript, Python, Java, and Go samples all instead use a `.env` file with a committed `sample.env`/`.env.example` template. [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-34](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) and [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract) adopt this same split for Azure SQL samples. | +| User directive, 2026-09-15: "the constitution should state and link to the SDK package that the language will use to query the service - this should also be in the pdf/word doc" | Instruction to add an explicit, per-language service-query package/driver requirement (package/artifact name, canonical URL, role, status, version policy, PDF locator), separating the SQL driver from Azure Identity and Azure OpenAI packages, using technically correct terminology (driver vs. SDK client library vs. OpenAI client library) | Verified against the PDF first (see the next row), then against live official package sources: `nuget.org` (`Microsoft.Data.SqlClient`, `Microsoft.Data.SqlClient.Extensions.Azure`, `Azure.Identity`, `Azure.AI.OpenAI`), `pypi.org` (`pyodbc`, `azure-identity`, `openai`), `search.maven.org` (`com.microsoft.sqlserver:mssql-jdbc`, `com.azure:azure-identity`, `com.azure:azure-ai-openai`), and the already-cited Go sources. Produced [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-38](#2-article-1-program-wide-requirements-all-azure-sql-vector-work). Two currency findings surfaced that are **not** in the plan: (1) `Microsoft.Data.SqlClient` v7.0+ requires the separate `Microsoft.Data.SqlClient.Extensions.Azure` package for connection-string Entra auth keywords; (2) both `Azure.AI.OpenAI` (.NET) and `com.azure:azure-ai-openai` (Java) are currently distributed only as prerelease/beta on their respective package registries (no GA release exists for either), which is flagged `OPEN — decision required` rather than silently pinned. | +| `nuget.org` package pages for `Microsoft.Data.SqlClient`, `Microsoft.Data.SqlClient.Extensions.Azure`, `Azure.Identity`, `Azure.AI.OpenAI`; `pypi.org` for `pyodbc`, `azure-identity`, `openai`; `search.maven.org` Solr API for `com.microsoft.sqlserver:mssql-jdbc`, `com.azure:azure-identity`, `com.azure:azure-ai-openai`; `learn.microsoft.com` for the JDBC driver's canonical Learn page | Official, first-party package registries and Microsoft Learn documentation used to verify current package identity, existence, and version currency for every SQL driver, Azure Identity, and Azure OpenAI package named in [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) | Fetched live on 2026-09-15. Confirmed: `Microsoft.Data.SqlClient` supports .NET Framework 4.6.2+/.NET 8.0+ and requires `Microsoft.Data.SqlClient.Extensions.Azure` for connection-string Entra auth keywords as of v7.0+; `com.microsoft.sqlserver:mssql-jdbc` latest is `12.10.0.jre11`; `com.azure:azure-identity` (Maven) latest is `1.16.2`; `com.azure:azure-ai-openai` (Maven) latest is `1.0.0-beta.16` (no GA); `Azure.AI.OpenAI` (NuGet) is installed with `--prerelease` (no GA); `azure-identity` (PyPI) and `openai` (PyPI) both confirmed current and actively published. | + +--- + +## 8. Changelog + +- **1.7 (2026-09-15)** Added an explicit per-language service-query package/driver requirement per the user's directive: "the constitution should state and link to the SDK package that the language will use to query the service - this should also be in the pdf/word doc." New [ASV-CORE-35](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-36](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-37](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) give three separate tables — SQL query driver, Azure Identity (auth), and embeddings (Azure OpenAI/OpenAI) — each with package/artifact name, canonical URL, status, version policy, and a PDF page/comment locator; [ASV-CORE-38](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) requires a sample's manifest and imports to match. **What the PDF actually says (verified first, per the directive):** it names `Microsoft.Data.SqlClient` (.NET, p.2, comment `Commented [PK3]`), `pyodbc` (Python, p.2–3, comment `Commented [PK4]`), and the Microsoft JDBC Driver for SQL Server (Java, p.3, comment `Commented [PK5]`) as SQL drivers; it names `Azure.Identity` only parenthetically for .NET (p.2) and `azure-identity` explicitly for Python (p.3); it never names a specific Azure OpenAI package for any language, nor any package at all for Go (out of scope) — only the embedding model name (`text-embedding-3-small`, p.16). Every package not named in the PDF was instead verified live against the package's own official registry (NuGet/PyPI/Maven Central/pkg.go.dev) on 2026-09-15, per the directive's "identify the selected package only if the PDF or authoritative product evidence supports it" bar — none were guessed. Two currency findings surfaced that are absent from the plan and did not exist in this constitution before this version: `Microsoft.Data.SqlClient` v7.0+ requires the separate `Microsoft.Data.SqlClient.Extensions.Azure` package for connection-string Entra auth; `Azure.AI.OpenAI` (.NET) and `com.azure:azure-ai-openai` (Java) are both prerelease/beta-only with no GA release, so both are marked `OPEN — decision required` rather than silently pinned. Also corrected terminology throughout: SQL drivers (`tedious`, `Microsoft.Data.SqlClient`, `pyodbc`, `mssql-jdbc`, `go-mssqldb`) are called drivers, not "Azure SDK"; the `openai` package (TypeScript/Python) is called the OpenAI client library, not an Azure SDK package, since it is published by OpenAI, not Microsoft. +- **1.6 (2026-09-15)** Added an explicit configuration/environment-variable mechanism section per the user's request that TypeScript's `.env` and .NET's `appsettings.json` conventions each be called out specifically. New [ASV-CORE-33](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) states there is no single universal config-file format across the five languages and gives a per-language mechanism/template/gitignore table; new [ASV-CORE-34](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) states the corresponding `.gitignore` rule, including that `appsettings.json` itself must not be excluded. This is grounded in live-verified precedent from the sibling `Azure-Samples/cosmos-db-vector-samples` repo (fetched 2026-09-15; see the new row in [§7](#7-evidence-and-source-log)), which ships the same five languages and splits configuration the same way. Rewrote [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract) from a generic "centralize env-var loading" statement (which wrongly implied .NET should mirror the other languages' `.env` approach) into a fully specified `appsettings.json` + `Microsoft.Extensions.Configuration` contract, with nested JSON keys and the ASP.NET Core double-underscore environment-variable override convention. Updated [ASV-LANG-PY-4](#43-python-not-yet-implemented-fully-specified-target-contract), [ASV-LANG-JAVA-4](#44-javajdbc-not-yet-implemented-fully-specified-target-contract-reference-priority), and [ASV-LANG-GO-6](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) to cross-reference [ASV-LANG-TS-3](#41-typescript-implemented-reference-implementation) (the shared `.env`-based parity anchor) instead of [ASV-LANG-NET-4](#42-net-not-yet-implemented-fully-specified-target-contract), since .NET is no longer a valid parity anchor for a `.env`-based mechanism. +- **1.5 (2026-09-15)** Added [ASV-CORE-32](#2-article-1-program-wide-requirements-all-azure-sql-vector-work): the captured "Expected output" required by [ASV-CORE-21](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) must also be committed as a plain-text reference file under the sample's own `output/` subfolder (for example `output/sample-output.txt`), matching the source plan's own instruction (PDF p.13) to commit that file "for the verification script to assert against." Added a carve-out to [ASV-CORE-11](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) so a sample's `.gitignore` no longer excludes this reference file wholesale. Added [CONF-6](#6-conflicts-and-open-decisions): the merged TypeScript sample's `.gitignore` currently ignores `output/` in its entirety and commits no such file — the plan's intent here was not carried into the implementation, so this is a forward-looking requirement (including a follow-up fix needed for TypeScript itself), not something already evidenced as implemented. +- **1.4 (2026-09-15)** Reworded [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) so the sample-folder naming rule explicitly names the scenario as well as the language: the folder name `vector-search-query-` encodes both `vector-search` (feature area) and `query` (this constitution's one vector search scenario), not the language alone. Removed forward-looking speculation about a hypothetical future second scenario (and any parallel to the sibling Cosmos DB repo's `create-index` scenario) from [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) and from the document preamble's **Canonical scenario** line — this constitution covers the first vector search scenario only; a future scenario can be added to this document later rather than speculated about now. +- **1.3 (2026-09-15)** Two fixes/additions in this round: + 1. Corrected an omission in [§1 Reality snapshot](#1-reality-snapshot-read-this-first): the summary sentence listed .NET, Python, Java, and Go as the languages Article 3 specifies but omitted TypeScript — the one language that is actually implemented. Now lists all five and clarifies TypeScript's contract is `Evidence: implemented` while the other four are determined-but-not-yet-built. (This fix previously shipped without its own changelog entry; recorded here for completeness per [§0.4](#0-governance).) + 2. Added [ASV-CORE-31](#2-article-1-program-wide-requirements-all-azure-sql-vector-work), a platform-by-language current-status matrix, plus the plan's own per-platform "flavor matrix" (PDF p.9–10, reproduced verbatim under [ASV-CORE-3](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)) showing that provisioning, auth, and cleanup differ per platform even though the T-SQL vector surface does not. No literal platform×language grid exists in the source plan — every cell in [ASV-CORE-31](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) is a synthesis of already-cited facts ([ASV-CORE-2](#2-article-1-program-wide-requirements-all-azure-sql-vector-work)/[ASV-CORE-3](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) and [§4](#4-article-3-language-specific-requirements)), not new evidence, and is explicitly labeled `Decision: this constitution` rather than `Evidence: implemented`. The result: every language's contract in this constitution is currently scoped to Azure SQL Database only; no platform besides Azure SQL Database has any language in scope yet. +- **1.2 (2026-09-15)** Added a fully specified Go target contract ([ASV-LANG-GO-2 through ASV-LANG-GO-14](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required)) at the user's explicit request, even though Go coverage is not currently required — matching the depth of the .NET/Python/Java sections. Unlike those three, none of the plan PDF covers Go, so every requirement instead cites live, independently verified `github.com/microsoft/go-mssqldb` and `azopenai` driver/SDK documentation (fetched 2026-09-15; see the new row in [§7](#7-evidence-and-source-log)) rather than the plan. No native Go VECTOR parameter-binding type was found in that research, so [ASV-LANG-GO-8](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) specifies the same JSON-cast fallback used elsewhere, and [ASV-LANG-GO-14](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) flags that absence as `OPEN` rather than asserting a capability that wasn't confirmed. [ASV-LANG-GO-1](#45-go-not-yet-implemented-fully-specified-target-contract-not-currently-required) is preserved and clarified: having a determined contract does not itself bring Go into scope for this v1 scenario. Updated [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work), [§1](#1-reality-snapshot-read-this-first), and [§4.6](#46-adding-a-new-language-process-requirement) accordingly, and fixed a stale internal anchor link in [ASV-CORE-29](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) left over from the 1.1 heading rename. +- **1.1 (2026-09-15)** Expanded [§4 Article 3](#4-article-3-language-specific-requirements) so .NET, Python, and Java are fully specified target contracts rather than open placeholders — runtime/package version pins, authentication pattern, configuration and env-var contract, vector parameter binding, bulk-insert pattern, the DiskANN row-count gate, package-manager convention, sample-folder naming, and CI shape are determined for each. Added [ASV-CORE-29/30](#2-article-1-program-wide-requirements-all-azure-sql-vector-work) (sample folder and default table naming conventions) to Article 1. Rationale: the constitution must determine language requirements before samples are produced, not defer them; version pins with no plan evidence (.NET target framework, Python/Java runtime) are recorded as constitution-author decisions, distinct from implementation evidence, and the two remaining true unknowns (native `SqlVector` binding version for .NET; exact `mssql-jdbc` Azure AD property/version for Java) are flagged `OPEN` without blocking the rest of each contract. Go is unchanged — still explicitly out of scope, since the source plan provides no driver/auth evidence to specify a Go contract from. +- **1.0 (2026-09-15)** Initial constitution authored from the approved plan PDF and reconciled against the merged TypeScript sample (microsoft/sql-server-samples#1479) and the prior blocked hub plan (diberry/project-dina#914). Documents five source conflicts in [§6](#6-conflicts-and-open-decisions) rather than silently resolving them; leaves DiskANN end-to-end validation, multi-platform expansion, and .NET/Python/Java/Go implementations as `OPEN` per [§4](#4-article-3-language-specific-requirements).