chat-with-your-data-solution-accelerator
Copilot instructions1.2k starsChanged 2 years agoMITView on GitHub
These instructions are always loaded. Read them before doing anything else. You may fetch and read these for architectural patterns. Never copy code wholesale — adapt with attribution in a code comment when the pattern is non-trivial. Specifically:
- Reads credentials
We split this copilot-instructions.md into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 35
Test-first contract: Every new method/class lands with at least a pytest (Python) or vitest/jest (TS) test file in the same turn.
- Very specific: line 38
Multi-agent ready: All orchestrators implement the same async interface (src/backend/core/providers/orchestrators/base.py).
- Distinctive: line 69
Use the dedicated agents for any non-trivial v2 work.
- Very specific: line 91
[console]::beepis reserved for these two signals: Do not call it from any other tool invocation, do not bury it inside another command, …
≈ “Common” is an estimate: at least 1 in 5 of the 3,669 Copilot instructions files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Chat With Your Data (CWYD) — Repository Instructions
These instructions are always loaded. Read them before doing anything else.
Repository layout (truth)
cwyd-v1/— v1 (legacy, frozen). Flask + Streamlit + Semantic Kernel + Prompt Flow + direct Azure OpenAI SDK. Do not extend. Only touch v1 to perform documented removals listed in v2/docs/development_plan.md §2.1. All v1 code, infra, docker, scripts, and tests live undercwyd-v1/.- Repo root (
src/,infra/,docker/,scripts/,tests/,azure.yaml,pyproject.toml,package.json) — v2 (active development). FastAPI + LangGraph + Agent Framework + Foundry IQ, promoted from the oldv2/subtree to the repo root. All new work goes here. infra/(root) — v2 Bicep. The v1 Bicep lives undercwyd-v1/infra/.tests/(root) — v2 tests (shared gates, backend, frontend, functions, infra, integration, smoke). The v1 e2e/integration tests live undercwyd-v1/tests/.v2/docs/— the only tree still underv2/: v2 development plan, pillars, ADRs, bugs registry, and worklog.
Mandatory references — consult before editing
- v2/docs/development_plan.md — phase ordering, file paths, scope, removals, additions. Source of truth for what to build and when. Always read §0 Status snapshot + the head of §0.1 debt queue before proposing a task. As of 2026-05-11 the active phase is Phase 6 — Functions blueprints / modular RAG indexing pipeline (
batch_start,batch_push,add_url,search_skillundersrc/functions/; ingestion-only extensions undersrc/functions/core/). Phases 1–5 + 5.5 are closed; #35d (FE admin merge) and #24 partial (FE SSE polish) are open and explicitly non-blocking for Phase 6. #35g (per-tenant overrides) is withdrawn as out of scope — the deployment is single-tenant, so per-tenantRuntimeConfigkeying is a no-op; see ADR 0024. - v2/docs/pillars_of_development.md — every new core element must declare its pillar (Stable Core, Scenario Pack, Configuration Layer, or Customization Layer) in the file/class docstring. Read-only product policy — never edited by agents.
- Repo memory
cwyd-tech-stack.md— current stack truth (versions, services, package managers, test counts).
External pattern sources — read-only
You may fetch and read these for architectural patterns. Never copy code wholesale — adapt with attribution in a code comment when the pattern is non-trivial.
- Content Generation Solution Accelerator: https://github.com/microsoft/content-generation-solution-accelerator
- Multi-Agent Custom Automation Engine (MACAE): https://github.com/microsoft/Multi-Agent-Custom-Automation-Engine-Solution-Accelerator
Specifically:
- MACAE → managed-identity + RBAC + no-Key-Vault env-var pattern; agent-to-agent message bus; SSE streaming pattern.
- CGSA → React/Vite + FastAPI plug-and-play surface; admin merged into frontend; reasoning visualization patterns.
Hard rules
- Step 0 — sync agent guidance before any change. Before any reorganization, refactor, or error fix, first read the agent instructions and prompt files that scope the change (this file + the relevant
.github/instructions/v2-*.instructions.md). If the guidance is stale, contradicts the requested change, or is silent on a decision the change implies, propose an instruction update first and wait for user approval before touching code or other docs. Out-of-date guidance is the root cause of re-work, throwing away decisions, and re-introducing removed concepts. - One unit per turn. Implement exactly one class OR one method per implementation turn. No "and while I'm here…" edits. Do not create multiple files of production code in a single turn unless they are a class + its test stub.
- Test-first contract. Every new method/class lands with at least a
pytest(Python) orvitest/jest(TS) test file in the same turn. Tests must execute (pass or fail with a clear assertion), not just exist. - Pillar awareness (no docstring header). Agents still classify every new module/class by its pillar (Stable Core, Scenario Pack, Configuration Layer, or Customization Layer) when reasoning about where a change belongs — but the classification is no longer emitted as a
Pillar:/Phase:docstring header; that header requirement is retired. The pillars file (v2/docs/pillars_of_development.md) is read-only product policy — agents reference it, never edit it. Any proposed change to pillars must be raised with the user as a separate request. - Plug-and-play via registry. Backend must run headless (no frontend dependency). Frontend must accept
VITE_BACKEND_URLand consume the generated OpenAPI client. All swappable concerns (credentials, llm, embedders, parsers, search, chat_history, orchestrators) live undersrc/backend/core/providers/<domain>/and self-register via@registry.register("key")against the genericRegistry[T]insrc/backend/core/registry.py. Caller code doesdomain.create(key, ...)— neverif/elifprovider dispatch, never lazy in-function imports of provider classes. - Multi-agent ready. All orchestrators implement the same async interface (
src/backend/core/providers/orchestrators/base.py). All emit events on the typed reasoning channel — never bury reasoning inside the answer string. - Reasoning feed. SSE channels:
reasoning,tool,answer,citation,error. The frontend rendersreasoningin a collapsible panel; o-series output flows there. - No banned tech / no removed features. Do not introduce: Streamlit, Prompt Flow, Semantic Kernel, Poetry, direct
openai/AzureOpenAISDK calls in v2, Key Vault for app secrets, one-click "Deploy to Azure" ARM button (v2 isazd-only), Azure Bot Service, Teams extension. The full removal list lives in v2/docs/development_plan.md §2.1 and is binding — never re-add a removed feature. Use Foundry IQ + RBAC + Managed Identity. - Every phase ends green.
azd up(or localdocker compose up) must succeed at the end of each phase. Never leave a half-wired phase. - Clean, modular, plug-and-play — anchored to dev_plan + pillars. v1 is spaghetti and is being replaced, never imitated. Every addition (file, package, container, sidecar, abstraction, config format) must cite (a) a task # in v2/docs/development_plan.md §3.4 or §4, and (b) a pillar in v2/docs/pillars_of_development.md. v1 (
code/,docker/,infra/) is a reference only for §2.1 removals; do not copy v1 patterns. CGSA/MACAE are read-only architectural references — adapt, never wholesale-copy. Defaults: one runtime per container, no invented sidecars, no premature abstractions, plug-and-play preserved (backend-only and frontend-only profiles must both boot). - Ask before changing structure. Any new top-level folder, new package in
pyproject.toml/package.json, new module layout undersrc/**, or rename across the tree requires explicit user confirmation before the planner emits a Work Order or the implementer touches a file. Structural decisions are not for agents to make unilaterally. - Naming-convention stability across languages. Once a symbol is named in source code, do not rename it casually — renames break diffs, history, and downstream references. Conventions (always followed; never invent a third style):
- Bicep —
camelCasefor params, vars, modules, resources, outputs (e.g.containerAppsEnvName,acaWorkloadProfileName). Module symbolic names arecamelCasenouns (backendContainerApp). Hoist any string literal repeated 2+ times to avarat the top of the section that uses it. - Python —
snake_casefor functions, methods, variables, modules;PascalCasefor classes;UPPER_SNAKE_CASEfor module-level constants;_leading_underscorefor private. Match PEP 8 exactly. Closed-set string literals must beenum.StrEnum, not module constants. Whenever ≥2 related string literals form a closed set (type discriminators, modes, channels, status values, sibling partition keys), defineclass Foo(StrEnum)(Python 3.11+) and reference members instead of bare_FOO = "foo"/_BAR = "bar"constants.StrEnumsubclassesstr, so wire serialization (JSON, SQL params, dict keys) is unchanged and round-trip equality with raw strings still holds. Single-value constants (URLs, SQL templates, lone sentinels with no siblings) stay asUPPER_SNAKE_CASE. PydanticLiteral[...]type annotations on model fields are not affected — they are types, not runtime values. Registry-driven carve-out (added 2026-06-02 for entry-point discovery). When a settings field is typed as aStrEnumwhose members are first-party keys of aRegistry[T]provider domain (Hard Rule #4 dispatch surface) and that registry accepts third-party extensions viabackend.core.discovery.load_entry_points("cwyd.providers.<domain>")at app startup, the field type MAY be widened to<MyEnum> | strso an operator can select a third-party-registered key via env var. Discipline: (a) theStrEnumstill defines the well-known first-party set and every internal branch / comparison usesMyEnum.MEMBER— thestrarm exists only so Pydantic accepts unknown registered keys; (b) validation happens at the registry boundary —<domain>_registry.registry.get(value)raisesKeyErrorlisting every registered key (first-party + third-party); (c) branches that fan out on the field membership usevalue in {MyEnum.A, MyEnum.B}(set-of-enum-members) — never a chain of equalities against bare strings; (d) closed-set fields that do not flow throughRegistry.getdispatch (env discriminators, SSE channels, status enums, partition keys, anything the codebase fully controls and that has no plugin extension point) remain hardStrEnum-only with nostrarm — the carve-out applies only to settings fields whose values are registry keys. Today's registry-driven fields under this carve-out:DatabaseSettings.db_type: DbType | str(registry:providers.databases),SearchSettings.index_store: IndexStore | str(registry:providers.search). Future registry-driven settings inherit the same widening without re-amending this rule — the carve-out is structural, not field-by-field. Types are always available at runtime —if TYPE_CHECKING:andfrom __future__ import annotationsare banned inv2/. All imports go in the regular import block; all annotations resolve to real symbols at class-definition time. No string-quoted forward references — usetyping.Self(PEP 673) for self-refs, and import every type a module annotates with. Rationale: lazy / quoted annotations created two recurring failure modes during cleanup audit batch 2 — (a) silent drift where the runtime symbol disappeared but the string annotation kept type-checking green; (b) Pydantic v2 + LangGraph wiring that introspects__annotations__at runtime and crashes on unresolved forward refs. No exceptions. If a genuine circular import surfaces (the only legitimate historical use case), fix it structurally by extracting the shared type to a leaf module (e.g.src/backend/core/types.pyor a newsrc/backend/core/contracts/) — never reach for the guard. Such an extraction is a structural change and triggers Hard Rule #10 (ask the user first). The v2-wide invariant is enforced bytests/shared/test_no_type_checking_or_future_annotations.py(AST walk over every*.pyin the code tree). Static type-checker enforcement is wired via CI (pyright --strictforsrc/backend/**+src/functions/core/**; see v2/docs/development_plan.old.md §0.1 Q13 for the original wiring trail; the live status tracker lives in v2/docs/development_plan.md §2.3).Anyonly at boundaries.pyright --strictis configured onsrc/backend/**+src/functions/core/**; CI fails on any drift from0 errors / 0 warnings / 0 information. ExplicitAnyannotations are permitted only at three boundary classes: (a) third-party SDK responses whose shape we deliberately don't narrow (dict[str, Any]rows fromasyncpg/cosmosdb/azure_search, openai/agent-framework Protocol stubs returningAny); (b) Pydanticmetadata: dict[str, Any]fields onChunk/*Event/ConversationRequestetc. where extensibility is the design; (c)**kwargs: Anyon SDK Protocol stubs only — never in internal plumbing. Everycast(...)and every# pyright: ignore[...]/# type: ignore[...]must either (i) have an inline comment naming the SDK boundary it crosses, or (ii) map to a tracked debt row in v2/docs/development_plan.md §0.1. See also Hard Rule #15 (closed-set dict returns must be typed models) — together #11 and #15 are the type-discipline pair: #11 governs closed-set string literals (useStrEnum) and internal plumbing (noAny); #15 governs closed-set dict returns (use aBaseModel). The same boundary carve-outs (third-party SDK responses, externally-defined protocol payloads) apply to both. - TypeScript —
camelCasefor variables, functions, methods;PascalCasefor types, interfaces, classes, React components;UPPER_SNAKE_CASEfor module-level constants; noI-prefix on interfaces. File names: all first-party files undersrc/frontend/src/andtests/frontend/use.tsxregardless of JSX content (camelCase.tsxfor utilities / hooks / api clients / models;PascalCase.tsxfor React components). Tooling configs (vite.config.ts,tsconfig.json, etc.) stay at their tool-pinned names. Rationale + the consuming ADR are at v2/docs/adr/0013-frontend-strict-ts-and-tsx-everywhere.md. - Cross-cutting — environment variables are
UPPER_SNAKE_CASEand prefixed (AZURE_*,VITE_*,CWYD_*). Azure resource names follow<type-abbrev>-<solutionSuffix>perinfra/abbreviations.json. Names of public APIs (HTTP routes, OpenAPI operationIds, SSE event types, OrchestratorEvent fields) require user confirmation to rename once shipped.
- Bicep —
- No mid-phase back-fills. Debt items discovered while working on Phase N are appended to v2/docs/development_plan.md §0.1 Debt Queue, not implemented inline. The queue is cleared in a single dedicated audit turn at the end of each phase. Within a phase, tasks execute in numeric order from §4 — no "and while we're here" additions, no out-of-order pulls from later phases. The only exception: a current task literally cannot proceed without the missed item; in that case a single back-fill turn is allowed and must be annotated in §0.1 with reason. Defect-versus-debt split (paired with Hard Rule #19). §0.1/§0.2 hold phase debt and tasks — deferred work, refactors, scoped follow-ups on the end-of-phase audit cadence. A defect (wrong or broken runtime behavior) is recorded in v2/docs/bugs.md, the canonical defect registry, not in §0.1; when a defect needs phase-audit visibility, §0.1 keeps a one-line pointer row referencing its
BUG-####id and the full detail stays inbugs.md. There is one source of truth per concern, never two. __init__.pyis a package marker. The only permitted content is the module docstring (with thePillar:/Phase:header). Forbidden: class/function definitions, instantiations (noregistry = Registry(...)),__all__lists, re-export imports (from .x import Y), side-effect imports (from . import concrete_a), module-level constants. Anything that needs that location (theRegistry[...]instance for a provider domain, the eager imports that fire@registry.register(...), genuine domain helpers likecredentials.select_default) lives in a sibling module — by conventionregistry.pyfor provider domains. Callers import the submodule explicitly:from backend.core.providers.<domain> import registry as <domain>_registry, then<domain>_registry.registry.get(key)(**kwargs). Nocreate(key, **kwargs)sugar — it added zero behavior overRegistry.getand was removed on 2026-05-20. Enforced bytests/shared/test_init_files_are_marker_only.py(AST walk; only allowed top-level node isast.Expr(ast.Constant(str))). Rationale + migration plan + per-domain ledger live in v2/docs/development_plan.md §2.4 — that section is the single source of truth for this invariant.- SDK boundary resilience. Every external SDK call (
AzureErrorumbrella for Azure SDKs,openai.APIError,asyncpg.PostgresError,httpx.HTTPError,azure.core.exceptions.HttpResponseError) crossed inside a provider, pipeline, tool, router, or Functions blueprint must be wrapped intry/except <SDK error umbrella>with three obligations: (a)logger.exception(...)with structuredextra={"operation": "<verb>", "provider": "<key>", ...domain-specific snake_case keys}; (b) re-raise the original exception (or wrap in a domain error that preserves__cause__); (c) never silently swallow — silent excepts are forbidden under all conditions and enforced bytests/test_no_silent_excepts.py. Cleanup paths (finally,async with __aexit__) own resource release; they do not own error reporting. Status checks (health, diagnostics) classify failures aspass | degraded | failpersrc/backend/models/health.pyand never let the SDK exception escape the router. Functions triggers have type-specific contracts: queue triggers returnNoneand re-raise so the host's retry → poison policy engages (@log_queue_errorsinsrc/functions/core/); HTTP triggers always returnfunc.HttpResponsevia@map_function_exceptionswhich owns theValidationError→ 422 /AzureError→ 502 /Exception→ 500 ladder. See .github/instructions/v2-backend-core.instructions.md §Resilience for the canonical code pattern. - Closed-set dict returns must be typed models. When a function returns a dict (or
list[dict]) whose keys are a fixed, known-at-author-time schema, define a Pydantic v2BaseModel(frozen,extra="forbid") and return that, notdict[str, object]/dict[str, Any]. Wire-shape conversion happens at the SDK boundary viamodel.model_dump(...)— the model is the source of truth for the schema, the dict is a transport detail. Trigger heuristic: "if you can write the keys as a literal at the call site, the keys are fixed" —{"id": chunk.id, "content": chunk.content, "title": chunk.source, "content_vector": vector}is a struct;{header_name: header_value for header_name in dynamic_headers}is a dict. Even arity 1 earns a model — there is no "one field doesn't need a model" carve-out, because that door always becomes "two fields don't either." Boundary exceptions (no model required): (a) third-party SDK responses —dict[str, Any]rows fromasyncpg,azure.cosmos,azure.search.documentsper Hard Rule #11(a); (b) externally-defined protocol payloads whose shape is owned by another party — Easy Authx-ms-client-principalclaims blob, JWT payloads, OpenAPI extension dicts; (c) stdlib / SDK structural arguments typedMapping[str, object]—logging.Logger.<level>(..., extra=...),azure.functions.HttpResponse(headers=...)— when the receiver requires a Mapping AND the caller spreads with**to merge ad-hoc per-call fields; (d) test capture buffers —captured: dict[str, object] = {}accumulators in test stubs are not "returns" and are not covered. Helpers under boundary (c) must either be a single-call inline literal, or a constructor-style helper whose docstring cites this rule + the SDK boundary it crosses. Enforced bytests/shared/test_no_anonymous_dict_returns.py(AST walk oversrc/**/*.py): everyFunctionDef.returnswhose annotation matchesdict[str, ...](or wrappers likelist[dict[...]],dict[...] | None) must either appear in the allow-list (registry of(module_path, function_qualname)tuples maintained alongside the gate, each with a one-line justification) or trigger a failing test. The allow-list grows only via a tracked debt-queue row in v2/docs/development_plan.md §0.1. No process narrative in production code. Comments and docstrings under
src/**describe what the code is — not how it got there, what unit shipped it, what phase it lives in, or what work lands next. The repo's process state lives in v2/docs/development_plan.md, commit history, and tracked debt rows — not in source files that rot the moment a phase advances. Forbidden in production-code comments + docstrings: (a) forward-looking unit IDs and "next-work" pointers ("U11 lands next","X lands in Phase 7","future smoke / e2e tests can assert"); (b) bare unit IDs in any role (the token\bU\d+[a-z]?\b—U7g,U10cetc. — even inside a Phase header tail, even as a cross-module pointer parenthetical); (b2) dev_plan §4 task numbers (the token\btask\s+#\d+\b—task #20,task #41etc. — even inside a Phase header tail, even as a parenthetical next to a live symbol name); (c) phase roll-forward narrative ("the Phase 6 blueprint set landed so far","as of <date>","so far"adjacent toPhase); (d) dev_plan section citations ("per [v2/docs/development_plan.md] §4.6.1"— the dev_plan is the work-tracker, not API docs); (e) self-narrative ("added in this turn","removed in CU-009b"); (f) process date stamps ("2026-05-28","REFACTOR-B (2026-05-06)") — git blame is the source of truth. Permitted (carve-outs):- inline
# pyright: ignore[...]debt citations carrying a<DEBT-ID>token (e.g.# Debt (dev_plan §0.1 U8i-EMBEDDER-CTOR-DEBT): ...) — the gate carves out any line containing the substring-DEBT, anchoring the comment to a tracked debt row (Hard Rule #11/#15 contract). - standing-policy anchors (
"per Hard Rule #15","per Hard Rule #11(a)") — these cite live, stable policy that lives in a stable doc, not transient process. - architectural cross-module pointers naming live symbols (
"Companion to functions.add_url.blueprint","Consumed by the HTTP trigger in blueprint.py") — these describe relationships between symbols that still exist, with no unit-ID tag attached. - Azure SDK API version literals (
"2024-12-01-preview","api version 2025-04-01") — these are technical content the SDK pins on, not process dates; the gate distinguishes them by the trailing-preview/-gasuffix or by anapi versioncontext phrase anywhere in the surrounding docstring or comment block.
Enforced by
tests/shared/test_no_process_narrative_in_src.py(per-file gate; AST-walks docstrings +tokenize-walks comments undersrc/, runs a fixed regex set, applies the carve-outs above at line granularity except for the API version carve-out which is block-scoped). The gate has no growable allow-list — fix the comment, do not exempt the file. If a genuinely new carve-out class surfaces, raise it as a Hard Rule #16 amendment request before adding it to the gate.- inline
- All imports at module top. All
import/from X import Ystatements must live at the top of the module, before any non-import statement (the only allowed prelude is the module docstring + thePillar:/Phase:header it carries per Hard Rule #3). Forbidden: (a) imports insidedef/async def/classbodies — no lazy imports of any kind, stdlib or third-party, even for "dev-ergonomics" profile splits (every package the v2 backend or functions can hit is already declared inpyproject.tomland installs unconditionally); (b) imports inside module-levelif/elseortry/exceptbranches — no soft-dependencytry/except ImportErrorshims, no profile-conditionalif backend_only: import …branches; (c)if TYPE_CHECKING:blocks (already banned by Hard Rule #11; reiterated here so the two import rules read together); (d)from __future__ import annotations(also banned by #11). Imports follow PEP 8 grouping (stdlib → third-party → first-party) with a blank line between groups; ordering within a group follows the codebase's existing tooling defaults (ruff/isort). Circular imports are not a carve-out — fix them structurally by extracting the shared type/protocol to a leaf module per Hard Rule #11 precedent (src/backend/core/types.pyor a new per-domain leaf undersrc/backend/core/), then top-import from both call sites. Such an extraction is a structural change and triggers Hard Rule #10 (ask the user first). Absolute rule with zero carve-outs — the gate's_EXEMPTIONSset isfrozenset()and stays that way. Enforced bytests/shared/test_imports_at_top_only.py(AST walk over every*.pyundersrc/+scripts/+tests/; everyast.Import/ast.ImportFromnode must haveModuleas its enclosing scope AND be preceded in module body only by other imports or by the module docstring). The gate has no growable allow-list — fix the import site, do not exempt the file. Cross-references: Hard Rule #11 (theTYPE_CHECKING/__future__half of the same import discipline); tracked debt rowIMPORTS-AT-TOP-DEBTin v2/docs/development_plan.md §0.1 (records the gate-landing and one-file-per-turn cleanup of pre-existing in-function imports acrosstests/). - No environment-specific content in tracked files. Tracked files (source, tests, docs, ADRs, runbooks, Bicep / Terraform comments, fixtures, CI workflows) contain only generic development and deployment guidance. Forbidden in any tracked file: Azure subscription IDs, tenant IDs, UAMI client / principal IDs, Entra object IDs, user UPNs, resource group names, azd env names, deployment suffixes, individual resource names that embed the suffix, real internal IP addresses, env-specific FQDNs (Container Apps Environment domains, OpenAI account hostnames, etc.), local OS user-profile paths, and any SAS / connection-string / token that ties to a real account. Real values live exclusively in
.azure/<AZD_ENV_NAME>/.env(gitignored) and the operator'saz/azdsession — discoverable viaazd env get-values. Examples in docs / fixtures use the placeholder convention defined in v2/docs/adr/0019-no-env-specific-content-in-tracked-files.md:<AZURE_SUBSCRIPTION_ID>,<AZURE_TENANT_ID>,<AZURE_PRINCIPAL_UPN>,<AZURE_PRINCIPAL_OBJECT_ID>,<AZURE_UAMI_CLIENT_ID>,<AZURE_UAMI_PRINCIPAL_ID>,<RESOURCE_GROUP>,<AZD_ENV_NAME>,<SUFFIX>,<DATA_SUFFIX>,<REGION>,<ACA_ENV_DOMAIN>,<APPI_NAME>,<APPI_RESOURCE_GROUP>,<SAMPLE_STORAGE_ACCOUNT>,<INTERNAL_IP>. Carve-outs (allowed unchanged): RFC 1918 / IANA-reserved IP literals (10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1,0.0.0.0,169.254.0.0/16); AVM / SDK example placeholders inherited from upstream docs; all-zero / built-in role-definition GUIDs; synthetic test-fixture identifiers that obviously cannot be real (e.g. thecwyd001suffix intests/**, hard-coded mock UUIDs); public Microsoft sample infrastructure owned by the upstream repo (e.g.cwydcontainerreg.azurecr.io); API version literals (already carved out by Hard Rule #16 — the Azure SDK API version literals carve-out). Local per-developer artifacts (IDE-generatedbicep-errors.txt, transient logs) must be added to.gitignore, not deleted-and-re-added. See ADR-0019 for the full rationale, exclusion list, and audit recipe. - Durable file-based tracking — plans, daily work, and bugs never live in agent memory alone. Three repo-tracked artifacts are the canonical record; agent session memory is a scratchpad, never the system of record (history trapped in memory is lost when the session ends — this rule exists because that happened). (a) Daily worklog —
v2/docs/worklog/YYYY-MM-DD.md, one file per working day named by the real current date (verify the date before naming the file; append to the same file as the day progresses, never open a second file for the same date). It captures the day's plan, completed work, bugs found/fixed, decisions, and next steps. The convention lives in v2/docs/worklog/README.md. (b) Defect registry — v2/docs/bugs.md, the canonical log of every observed defect (wrong or broken runtime behavior) with sequential zero-paddedBUG-####ids, root cause, and fix; closed-setArea/Severity/Statusfields. See the defect-versus-debt split in Hard Rule #12. (c) Plans / Work Orders — any non-trivial plan, including acwyd-plannerWork Order, is written to the day's worklog in addition to any memory note, so the plan survives the session. The placeholder rule (Hard Rule #18) applies to all three. Whenever a plan is produced, a working day begins, or a bug is found/fixed, the corresponding repo file is created or updated in the same turn — not deferred to memory. - Shared, standardized citation-format contract — scales to N orchestrators (ADR 0026). The orchestrator set is open (today
langgraph+agent_framework; more register per Hard Rule #4), so the grounding prompt and the citation-response format are shared infrastructure defined once, never re-authored per orchestrator — registering the Nth orchestrator must add zero new prompt text and zero new formatter. Three invariants. (R1) One prompt input point. Every orchestrator grounds throughresolve_cwyd_instructions(...)over the sharedCWYD_DEFAULT_BODY; the fixedCWYD_GUARDRAILowns the citation-format directive and the no-context fallback string. An orchestrator MUST NOT define its own grounding / system prompt or its own citation instruction — there is one prompt source for all N orchestrators. (R2) One response-format point. All citation shaping lives insrc/backend/core/tools/citations.py—format_sources_block(client-side[docN]injection) andnormalize_kb_citations(native【N:M†source】rewrite) — and both emit the same inline[docN]marker +Citationmodel on the typedcitationSSE channel (Hard Rule #6). An orchestrator'srun()produces(answer, citations)and delegates formatting tocitations.py; it never formats markers inline, never invents a citation shape, never adds a second formatter. (R3) Backend-agnostic formatting; retrieval keyed by storage. Retrieval is dispatched byindex_storethrough the registry (Hard Rule #4), but the emitted citation format is identical across Azure AI Search and pgvector. Every orchestrator/store cell is served:agent_framework+ pgvector grounds app-side overBaseSearch.search(no Foundry IQ KB) through the same shared seam (ADR 0027 supersedes the ADR 0022 rejection rule), never given a divergent formatter or a silent fallback. Rationale: minimal maintenance — one prompt, one formatter, N orchestrators. Any new-orchestrator change that introduces a second prompt source or a second citation formatter violates this rule. Editing-surface detail (concrete function names + file paths) lives in .github/instructions/v2-backend-core.instructions.md §Orchestrator contract → Citations.
Workflow contract
Use the dedicated agents for any non-trivial v2 work. They enforce the rules above:
cwyd-planner— research + produce a one-unit work order (read-only).cwyd-implementer— write exactly one unit + test stub.cwyd-tester— fill the test, run it, report.
For trivial single-line edits, you may proceed directly — but still respect the test-first rule.
Local development
- Python:
uv syncfrom the repo root. - v2 dev stack:
docker compose -f docker/docker-compose.dev.yml up. - v2 backend-only:
docker compose -f docker/docker-compose.dev.yml --profile backend-only up. - v2 frontend-only:
docker compose -f docker/docker-compose.dev.yml --profile frontend-only up(setVITE_BACKEND_URL). - CI validation image:
docker build -f docker/Dockerfile.ci-validate -t cwyd-ci .then run.
Session conventions
- End-of-turn beep is the agent's responsibility. GitHub Copilot does not execute Claude Code-style
~/.claude/settings.jsonStophooks, so the agent must emit the chime as its final tool call before handing the conversation back to the user. One call per turn, no exceptions, no duplicates:- Windows (default):
run_in_terminal(sync, ~500ms) with[console]::beep(880,200); [console]::beep(1175,250)— two ascending tones.
- Windows (default):
- Mid-turn waits for user input require a different beep. Whenever the agent is about to block on the user before the turn ends (calling
vscode_askQuestions, sending an interactive prompt to a terminal viasend_to_terminal, or otherwise pausing for a human reply mid-task), the agent must first emit a single low beep:- Windows (default):
run_in_terminalwith[console]::beep(660,250)(sync, ~250ms, distinct from the two-tone end-of-turn chime).
- Windows (default):
[console]::beepis reserved for these two signals. Do not call it from any other tool invocation, do not bury it inside another command, and do not skip it when wrapping up.
Trending
Quiet since March.thin dataabout the whole repository
Who's talking about Azure-Samples/chat-with-your-data-solution-accelerator
- @github-trending.bsky.social“📦 Azure-Samples / chat-with-your-data-solution-accelerator ⭐ 521 (+3) 🗒 Python A Solution Accelerator for …”Bluesky · May 18, 2024 · 1 likes
- codes4humanity/NL2SQL-ENGINE“Combine data-api-builder, chat-with-your-data, and nlp-sql-in-a-box into a unified NL2SQL-ENGINE template”GitHub · Mar 20, 2026
- Azure/Azure-Verified-Modules“[Module Proposal]: `avm/ptn/sa/chat-with-your-data`”GitHub · Sep 17, 2025
- microsoft/AI-Pex-for-SDC“Some images in README.md are not loading properly”GitHub · May 26, 2025
- Azure-Samples/ai-rag-chat-evaluator“Question - RAG Evaluation for Chat With Your Data Solutions Accelerator.”GitHub · Jan 8, 2025
The biggest 5 of 12 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 12
Talked about on GitHub and Bluesky (12 times).
On GitHub · 11
- Mar 20, 2026Combine data-api-builder, chat-with-your-data, and nlp-sql-in-a-box into a unified NL2SQL-ENGINE template — codes4humanity/NL2SQL-ENGINE0 reactions
- Sep 17, 2025[Module Proposal]: `avm/ptn/sa/chat-with-your-data` — Azure/Azure-Verified-Modules0 reactions · 5 comments
- May 26, 2025Some images in README.md are not loading properly — microsoft/AI-Pex-for-SDC0 reactions · 2 comments
- Jan 8, 2025Question - RAG Evaluation for Chat With Your Data Solutions Accelerator. — Azure-Samples/ai-rag-chat-evaluator0 reactions · 3 comments
- Nov 14, 2024infra(CI): skip required CI steps in merge_queues — faker-js/faker0 reactions · 2 comments
6 more on GitHub
- Sep 26, 2024fix: Fix for the issue encountered when updating the .env file and modifying model configurations. — Fr4nc3/chat-with-your-data-solution-accelerator0 reactions
- Sep 13, 2024[S2] - Create Copilot Chatbot — Azure-Samples/modern-data-warehouse-dataops0 reactions
- Apr 12, 2024Where does this project fit in? — Azure/agent-landing-zone0 reactions · 2 comments
- Apr 8, 2024Adding `Chat With your Data` — Azure/awesome-azd0 reactions · 3 comments
- Feb 11, 2024[Module Proposal]: `avm/ptn/chat-with-your-data-solution-accelerator` — Azure/Azure-Verified-Modules0 reactions · 4 comments
- Jan 17, 2024SciTonic : Chat UI & Interface Logic — Josephrp/scitonic0 reactions
On Bluesky · 1
- May 18, 2024📦 Azure-Samples / chat-with-your-data-solution-accelerator ⭐ 521 (+3) 🗒 Python A Solution Accelerator for the RAG pattern running in… — @github-trending.bsky.social1 likes and repost
Where files are headingNew Copilot instructions files have more rules about branches and pull requests, and fewer about code style.
Of the Copilot instructions files we read, the 2,297 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

