Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 43 additions & 7 deletions .github/workflows/backend-prisma-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
paths:
- "apps/backend/**"
- "packages/shared-types/**"
- "packages/analysis-task-protocol/**"
- "pnpm-lock.yaml"
- "package.json"
- "scripts/check-backend-capability-boundaries.ts"
Expand All @@ -15,6 +16,7 @@ on:
paths:
- "apps/backend/**"
- "packages/shared-types/**"
- "packages/analysis-task-protocol/**"
- "pnpm-lock.yaml"
- "package.json"
- "scripts/check-backend-capability-boundaries.ts"
Expand Down Expand Up @@ -66,6 +68,15 @@ jobs:
- name: Prisma generate
run: pnpm --filter @text2sql/backend run prisma:generate

- name: Prepare canonical PostgreSQL schema
env:
PGPASSWORD: postgres
run: |
if ! psql -h localhost -U postgres -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname='text2sql_ci'" | grep -q 1; then
psql -h localhost -U postgres -d postgres -c "CREATE DATABASE text2sql_ci"
fi
pnpm --filter @text2sql/backend exec prisma migrate deploy

- name: Backend lint
run: pnpm --filter @text2sql/backend run lint

Expand All @@ -75,16 +86,39 @@ jobs:
- name: Backend build
run: pnpm --filter @text2sql/backend run build

- name: Backend test
run: pnpm --filter @text2sql/backend run test
- name: Backend test with coverage
run: pnpm --filter @text2sql/backend exec jest --coverage --runInBand

- name: Text2SQL v2 focused coverage report
run: pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate:strict

- name: Text2SQL accuracy contracts and composite gates
run: |
pnpm run text2sql:no-legacy-compat:check
pnpm run governance:terminology:check
pnpm --filter @text2sql/backend run collect:text2sql-v2-eval-gate
pnpm --filter @text2sql/backend exec jest --runInBand \
test/integration/text2sql-accuracy-gate.spec.ts \
test/integration/text2sql-accuracy-replay-parity.spec.ts
TS_NODE_TRANSPILE_ONLY=1 pnpm --filter @text2sql/backend exec ts-node \
--project tsconfig.json \
scripts/collect-text2sql-accuracy-gate.ts \
> /tmp/text2sql-accuracy-gate.json
jq -e '.rollout.releaseDecision == "HOLD"' /tmp/text2sql-accuracy-gate.json
jq -e '.summary.realOutcomePairCount == 0' /tmp/text2sql-accuracy-gate.json

- name: Data Agent composite release manifest
run: |
pnpm --filter @text2sql/backend exec jest \
--coverage \
--runInBand \
text2sql-v2-focused-coverage-gate.spec.ts
pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate
pnpm --filter @text2sql/backend exec jest --runInBand \
test/integration/data-agent-release-gate.spec.ts
TS_NODE_TRANSPILE_ONLY=1 pnpm --filter @text2sql/backend exec ts-node \
--project tsconfig.json \
scripts/collect-data-agent-release-gate.ts \
> /tmp/data-agent-release-gate.json
jq -e '.version == "data-agent-release-manifest/v1"' /tmp/data-agent-release-gate.json
jq -e '.rollout.releaseDecision == "HOLD"' /tmp/data-agent-release-gate.json
jq -e '.rollout.gatePass == false' /tmp/data-agent-release-gate.json
jq -e '.topology.mode == "single_workflow"' /tmp/data-agent-release-gate.json

- name: R6 scenario package tests
env:
Expand Down Expand Up @@ -148,6 +182,8 @@ jobs:

jq -e '.status == "success"' /tmp/health.json
jq -e '.data.dependencies.postgres.configured == true' /tmp/health.json
jq -e '.data.dependencies.text2sqlAccuracy.mode == "shadow"' /tmp/health.json
jq -e '.data.dependencies.text2sqlAccuracy.capabilities.parser == "available"' /tmp/health.json

session_json=$(curl -sS -X POST http://127.0.0.1:3100/api/v1/sessions \
-H "content-type: application/json" \
Expand Down
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
/data/*
/vibe/*
/docs/*
!/docs/text2sql-project-architecture-business-flow-review.md
!/docs/standards/
/docs/standards/*
!/docs/standards/text2sql-accuracy-gate-spec.md
!/docs/standards/data-agent-autonomous-analysis-spec.md
!/docs/runbooks/
/docs/runbooks/*
!/docs/runbooks/data-agent-task-recovery-and-release.md
# Node / monorepo artifacts
node_modules/
dist/
Expand All @@ -20,4 +28,4 @@ __pycache__/
.env.*.local
.omx/
.enter/*
graphify-out/*
graphify-out/*
54 changes: 54 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,24 @@ CI 参考:
- `RAG 配置` 健康检查需同时覆盖 `dry-check`(草稿)与 `persisted-check`(已保存),并校验返回 `checkedAgainst=draft|persisted`、`reasonCode` 可解释,且检测失败不应清空草稿输入。
- 网关 smoke:`node tests/smoke/nginx-dev-gateway-smoke.mjs` 可区分 frontend/backend/stream 三类上游失败。
- 健康检查:`GET http://localhost:3002/health` 应可用(后端内部端口检查),且 `dependencies.ragConfig.embedding/rerank` 应可见当前激活 provider+model+configSource 摘要。
- Text2SQL accuracy 健康摘要还需包含 `dependencies.text2sqlAccuracy.mode/supportedSlices/supportedDialects/guidelineDigest/capabilities`,不得暴露连接、授权明细或真实 Fixture 路径。
- 自治分析健康摘要还需包含 `dependencies.analysisRuntime.canonicalStore/durableWorkflow/commandOutbox/telemetry`;telemetry 不得含 Prompt、SQL rows、网页正文、token、URL secret、PII 或高基数 metric label。
- 若本次改动涉及流式/工具调用:需关注 stream 与 tool 相关字段一致性(细节见 LLM 迁移规范)。
- 若本次改动涉及 Text2SQL v2 read-model/delivery hard-cut:执行
- `pnpm --filter @text2sql/backend run collect:text2sql-v2-eval-gate`
- (发布阻断)`pnpm --filter @text2sql/backend run collect:text2sql-v2-eval-gate:strict`
- `pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate`
- `pnpm run text2sql:no-legacy-compat:check`
- 并核对 `rollout.recommendedStage` 与 `rollout.rollbackSuggested`。
- 若本次改动涉及 Text2SQL 准确率、Receipt、修复或 replay parity:执行
- `pnpm --filter @text2sql/backend run collect:text2sql-accuracy-gate`
- `pnpm --filter @text2sql/backend run collect:text2sql-v2-eval-gate`
- `pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate`
- 发布阻断使用 `collect:text2sql-accuracy-gate:strict`;没有受信 real Outcome Receipt 时必须保持 `HOLD`,不得以现有 focused/eval 全过替代。
- 若本次改动涉及自治 AnalysisTask、Deep Search、Evidence/Claim、Memory/Skill 或 ReleaseManifest:执行
- `pnpm --filter @text2sql/backend run collect:data-agent-release-gate`
- 核对每个 component 的 exact version/scope/freshness/evidence refs/owner approval,以及 `topology.mode`。
- 发布阻断使用 `collect:data-agent-release-gate:strict`;缺真实签名 Text2SQL Outcome 或代表性 analyst Outcome 时必须保持 `HOLD`。
- 若本次改动涉及 modeling parity 指标:执行 `pnpm --filter @text2sql/backend run collect:modeling-parity-shadow-gate`,确认 `relationshipPlatform/semanticSpine/modelingWorkspace` 三维输出可生成。
- 若本次改动需要发布门禁(go/no-go):执行 `pnpm --filter @text2sql/backend run collect:modeling-parity-shadow-gate:strict`,并检查 `rollout.recommendedStage` 与 `rollout.rollbackSuggested`。

Expand Down Expand Up @@ -142,6 +153,8 @@ CI 参考:
- `pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate` 输出需包含 scoped coverage、关键文件门槛、A-M flow blockers 与 eval fixture 行为测试追溯。
- strict-completion 语义补齐后,focused coverage 输出还需包含 `strictCompletionRows` 评估结果(metadata grounding / correction grounding / context-pack parity)。
- runtime-intelligence 生效后,focused/eval 输出还需覆盖 `runtime-plan-consistency`、`artifact-ref-compaction`、`smart-defaults-evidence`、`plain-general-no-sql`、`large-context-compaction`、`validation-diagnostics`、`correction-grounding`、`execution-preview`、`all-stage-stream-lifecycle`;focused coverage 还需包含 `runtimeArtifactProducerRows` 与 `streamLifecycleRows`。
- accuracy closure 生效后,runtime artifact producer 还必须覆盖 `accuracy_receipts`;sync/stream/run view/save view/replay 共享安全 accuracy summary,correction 固定为 allowlisted AST Patch、最多两次并回到完整 validation。
- `TEXT2SQL_ACCURACY_MODE=shadow` 只记录候选证据摘要,不得阻断现有 baseline 用户链路或贡献 `GO`;`enforce` 才要求 trusted policy/schema、七层 passed Receipt 与 final ValidationReceipt 后交付。
- `pnpm run text2sql:no-legacy-compat:check` 必须通过。

### D. Governance 术语硬切规范
Expand Down Expand Up @@ -182,6 +195,47 @@ CI 参考:
必跑检查:
- `pnpm run backend:capability-boundary:check`(落地后)

### F. Text2SQL 准确率门禁规范
来源:`docs/standards/text2sql-accuracy-gate-spec.md`

适用范围:
- Text2SQL QueryContract、版本元组、Receipt chain、结果 Oracle、有界 AST 修复与 replay parity。
- `apps/backend/src/modules/conversation/runtime/evaluation/**`
- `apps/backend/scripts/collect-text2sql-accuracy-gate.ts`

关键 MUST:
- 合成评测只能证明 closeout,不能替代真实、受信、签名的 Outcome Receipt。
- `shadow` 不阻断 baseline;`enforce` 才以七层 Receipt、Execution Permit 与 final ValidationReceipt 为硬条件。
- 修复最多两次,只允许 AST 等价 allowlist,且每次修复后回到完整 validation。
- 最终发布决策只允许 `GO/HOLD/NO_GO/ROLLBACK`;无真实证据时必须 `HOLD`。

必跑检查:
- `pnpm --filter @text2sql/backend run collect:text2sql-accuracy-gate`
- `pnpm --filter @text2sql/backend run collect:text2sql-accuracy-gate:strict`(发布阻断)

### G. Data Agent 自治分析规范
来源:`docs/standards/data-agent-autonomous-analysis-spec.md`

适用范围:
- `apps/backend/src/modules/conversation/analysis/**`
- `apps/backend/src/modules/platform/{durable,artifacts,observability}/**`
- `apps/backend/src/modules/knowledge/{research,assets}/**`
- `apps/frontend/src/{app,components}/analysis/**`
- `apps/backend/scripts/collect-data-agent-release-gate.ts`

关键 MUST:
- PostgreSQL Analysis Ledger 是 Task/Revision/Attempt/Event/Artifact/Receipt/Manifest 权威;Temporal、UI、SSE 与 OTel 都是 orchestration/projection。
- Worker 只能提出 candidate,Commit Guard 才能提交;Correction 追加 Revision 并传播 stale/invalidated,旧 replay 保留。
- 网页内容始终 untrusted;Report 只能从 Claim projection 生成;生产 Memory/Skill 只能来自治理后的 active KnowledgeAsset。
- ReleaseManifest 的 required evidence 若 unknown/stale/failed 不得 GO;缺真实签名 Outcome 固定 HOLD;安全失败给出 NO_GO/ROLLBACK。

必跑检查:
- `pnpm --filter @text2sql/backend run collect:data-agent-release-gate`
- `pnpm --filter @text2sql/backend run collect:data-agent-release-gate:strict`(发布阻断)

恢复与回滚:
- `docs/runbooks/data-agent-task-recovery-and-release.md`

说明:
- 以上仅为执行摘要,细节规则以 standards 原文为准。

Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This project is not a prompt-only SQL generator. It is a Text2SQL platform proto
- Before SQL generation, the agent retrieves schema, glossary terms, historical examples, and semantic assets.
- Generated SQL must pass read-only, safety, permission, dialect, and execution checks.
- Each run has a `runId` for tracing, RAG evidence, delivery artifacts, and replay.
- Long-running autonomous analysis uses a durable `AnalysisTask` ledger, bounded workers, evidence/claim lineage, correction revisions, and a composite release manifest.
- Frontend and backend stay aligned through shared types and an SSE protocol package for sync responses, streaming responses, and run details.

## Problems Solved
Expand All @@ -35,6 +36,9 @@ This project is not a prompt-only SQL generator. It is a Text2SQL platform proto
5. **End-to-end demos across multiple datasource types**
The project supports SQLite, MySQL, PostgreSQL, CSV, and Excel datasources, with frontend workbench pages such as `/data-sources`, `/chat`, `/settings`, and `/modeling` for demos and continued extension.

6. **Durable autonomous analysis without unverifiable autonomy**
`/analysis` turns a decision goal into a versioned WorkGraph. PostgreSQL owns task truth, Temporal owns durable orchestration, and deterministic commit guards decide which Evidence, Calculation, Claim, Conflict, and Report artifacts may become visible. Missing signed business or analyst Outcome evidence keeps release status at `HOLD`.

## Feature Preview

### Semantic Modeling Workbench
Expand Down Expand Up @@ -85,6 +89,7 @@ apps/backend NestJS API, Text2SQL runtime, governance, knowledg
apps/frontend Next.js frontend workbench
packages/shared-types Shared frontend/backend types
packages/chat-stream-protocol SSE envelope, parser, terminal guard, and UI projection helpers
packages/analysis-task-protocol Durable task event, replay, and terminal-state contracts
infra Local PostgreSQL, Redis, and Nginx orchestration
data Local uploads, SQLite files, and runtime data
docs Solutions, standards, troubleshooting, and understanding documents
Expand Down Expand Up @@ -118,7 +123,7 @@ flowchart LR

| Domain | Directory | Responsibility |
| --- | --- | --- |
| `conversation` | `apps/backend/src/modules/conversation` | Chat entry points, Text2SQL workflow, LangGraph runtime, delivery contract |
| `conversation` | `apps/backend/src/modules/conversation` | Chat entry points, Text2SQL workflow, autonomous analysis, LangGraph runtime, delivery contract |
| `governance` | `apps/backend/src/modules/governance` | Workspaces, datasource binding, table permissions, users, and settings governance |
| `knowledge` | `apps/backend/src/modules/knowledge` | RAG retrieval, semantic assets, glossary, memory, graph, and modeling context |
| `platform` | `apps/backend/src/modules/platform` | Persistence, query execution, cache, configuration, observability, and read-model guards |
Expand Down Expand Up @@ -241,6 +246,7 @@ Default URLs:

- Gateway: `http://localhost:3000`
- Datasource entry: `http://localhost:3000/data-sources`
- Autonomous analysis: `http://localhost:3000/analysis`
- Frontend direct debugging: `http://localhost:3001`
- Backend health check: `http://localhost:3002/health`

Expand All @@ -267,6 +273,14 @@ node tests/smoke/nginx-dev-gateway-smoke.mjs
- `/modeling`: datasource modeling, relationships, and semantic views
- `/prompts`: prompt template management

### Autonomous Analysis

1. Open `/analysis` in a selected workspace.
2. Create a Goal Contract with objective, decision use, datasource scope, deliverables, risk, and budgets.
3. Start the task and inspect the versioned WorkGraph, mandatory obligations, live event cursor, budget, Evidence, Conflict, and Report projections.
4. Pause, resume, cancel, revise, or reconnect without treating a closed browser tab as task cancellation.
5. Use `taskId` replay and ReleaseManifest for audit; UI progress and telemetry are projections, not Outcome truth.

## Quality Gates

Repository-wide:
Expand Down Expand Up @@ -303,8 +317,12 @@ pnpm run text2sql:no-legacy-compat:check
pnpm --filter @text2sql/backend run collect:text2sql-v2-eval-gate
pnpm --filter @text2sql/backend run collect:text2sql-v2-focused-coverage-gate
pnpm --filter @text2sql/backend run collect:modeling-parity-shadow-gate
pnpm --filter @text2sql/backend run collect:text2sql-accuracy-gate
pnpm --filter @text2sql/backend run collect:data-agent-release-gate
```

`collect:data-agent-release-gate:strict` is the final release blocker. Without fresh, signed, owner-approved Text2SQL and representative analyst Outcome evidence, the expected decision is `HOLD`, even when synthetic, focused, and eval gates pass.

## Important Rules

- Prisma schema changes must start in `apps/backend/prisma/schema.prisma`, then migrations must be generated by the Prisma CLI.
Expand All @@ -325,3 +343,5 @@ pnpm --filter @text2sql/backend run collect:modeling-parity-shadow-gate
- `docs/standards/llm-stream-tool-migration-spec.md`: LLM stream and tool calling migration standard
- `docs/standards/governance-terminology-spec.md`: governance terminology hard-cut standard
- `docs/standards/backend-business-capability-topology-spec.md`: backend capability topology standard
- `docs/standards/data-agent-autonomous-analysis-spec.md`: autonomous AnalysisTask, Evidence/Claim, KnowledgeAsset, telemetry, and ReleaseManifest standard
- `docs/runbooks/data-agent-task-recovery-and-release.md`: task recovery, replay, correction, release, and rollback runbook
45 changes: 45 additions & 0 deletions apps/backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@ NODE_ENV=development
SQLITE_PATH=../../data/sqlite/text2sql.db
SQLITE_ALLOWED_DIRS=../../data/sqlite,../../data/uploads/datasources
CORS_ALLOWED_ORIGINS=http://localhost:3000
# Local/test compatibility only. Production defaults to oidc_bearer and refuses
# to start with dev_headers.
AUTH_MODE=dev_headers
AUTH_POLICY_VERSION=trusted-principal-v1
# Required when AUTH_MODE=oidc_bearer. OIDC subject must equal PlatformUser.id.
AUTH_OIDC_ISSUER=
AUTH_OIDC_AUDIENCE=
AUTH_OIDC_JWKS_URL=
AUTH_OIDC_ALLOWED_ALGORITHMS=RS256
AUTH_OIDC_CLOCK_TOLERANCE_SECONDS=5
ANALYSIS_ARTIFACT_MAX_BYTES=262144
ANALYSIS_TASK_ARTIFACT_MAX_BYTES=8388608
ANALYSIS_DURABLE_PROVIDER=temporal
TEMPORAL_ADDRESS=127.0.0.1:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_ANALYSIS_TASK_QUEUE=text2sql-analysis-v1
TEMPORAL_CONNECTION_TIMEOUT_MS=5000
ANALYSIS_EVENT_POLL_INTERVAL_MS=500
ANALYSIS_MULTI_WORKER_MODE=off
# Bounded Deep Search is fail-closed until both a versioned workspace policy
# and a provider key are configured. Provider-generated answers stay disabled.
ANALYSIS_RESEARCH_ENABLED=false
ANALYSIS_RESEARCH_PROVIDER=tavily
ANALYSIS_RESEARCH_ALLOWED_DOMAINS=
ANALYSIS_RESEARCH_SEARCH_TIMEOUT_MS=10000
ANALYSIS_RESEARCH_EXTRACT_TIMEOUT_MS=20000
ANALYSIS_RESEARCH_MAX_CONTENT_BYTES=262144
ANALYSIS_RESEARCH_RETENTION_DAYS=30
KNOWLEDGE_ASSET_LEGACY_FIXTURE_MODE=false
TAVILY_API_KEY=
TAVILY_API_BASE_URL=
DATASOURCE_UPLOAD_DIR=../../data/uploads/datasources
DATASOURCE_UPLOAD_MAX_BYTES=10485760
DATASOURCE_CONNECT_TIMEOUT_MS=5000
Expand Down Expand Up @@ -67,6 +98,20 @@ R1_GATE_MIN_SUCCESS_RATE=0.95
R1_GATE_MAX_REJECTION_RATE=0.2
R1_GATE_MAX_HARD_FAILURE_RATE=0.05

# Text2SQL accuracy release evidence. Real fixture data and signing private keys
# stay outside the repository; this service only reads a controlled root and
# verifies public keys supplied as a JSON object keyed by key id.
TEXT2SQL_ACCURACY_FIXTURE_ROOT=../../data/text2sql-accuracy
TEXT2SQL_ACCURACY_TRUSTED_PUBLIC_KEYS_JSON={}
TEXT2SQL_ACCURACY_EVIDENCE_MAX_AGE_MS=3600000
TEXT2SQL_ACCURACY_MODE=shadow
TEXT2SQL_ACCURACY_SUPPORTED_SLICES=sanitized-sqlite-reference
TEXT2SQL_ACCURACY_GUIDELINE_DIGEST=data-agent-system-design-2026-07-17
TEXT2SQL_EXECUTION_TIMEOUT_MS=10000
TEXT2SQL_EXECUTION_MAX_ROWS=200
TEXT2SQL_EXECUTION_MAX_BYTES=2097152
TEXT2SQL_EXECUTION_MAX_AST_NODES=20000

LANGSMITH_TRACING=false
LANGSMITH_API_KEY=
LANGSMITH_ENDPOINT=https://api.smith.langchain.com
Expand Down
2 changes: 2 additions & 0 deletions apps/backend/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const config: Config = {
coverageDirectory: "coverage",
testEnvironment: "node",
moduleNameMapper: {
"^@text2sql/analysis-task-protocol$":
"<rootDir>/../../packages/analysis-task-protocol/src",
"^@text2sql/chat-stream-protocol$":
"<rootDir>/../../packages/chat-stream-protocol/src",
"^@text2sql/chat-stream-protocol/(.*)$":
Expand Down
Loading
Loading