Files
SuperBizAgent-java/openspec/changes/archive/2026-07-21-single-react-mysql-readonly-tool/proposal.md
T

55 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Proposal: single-react-mysql-readonly-tool
## Problem
阶段 1 已冻结 `query_mysql` 的逻辑请求和有界结果契约,但当前仓库没有一个能把 SQL 安全地转换为可执行查询的实现。直接把 Agent 生成的 SQL 交给 JDBC 会允许写操作、元数据探测、通配符泄漏、allowlist 绕过和无界结果。
## Proposed change
- 引入 JSqlParser 4.6,解析单条 SQL 并对保守的 SELECT 子集执行 fail-closed AST 校验。
- 增加逻辑数据源定义和静态 `schema -> table -> column` 精确 allowlist;Agent 只能传逻辑数据源 ID。
- 增加参数绑定、占位符数量校验、函数 allowlist、显式列校验、JOIN/过滤/分组/排序字段校验和受控 LIMIT。
- 增加 JDBC 只读执行器:只使用配置映射的 DataSource,设置 `readOnly`、`PreparedStatement`、`setMaxRows`、查询超时,并在 Run 取消时中止执行。
- 增加 MySQL 结果 projector:限制行数、单元格和总 UTF-8 字节,脱敏敏感列,产生 `MysqlToolResult` 和 `NO_EVIDENCE`。
- 通过阶段 3A `ToolBoundary` 接入 canonical invocation store、Run budget、生命周期、`evidence_status` 和框架 `tool_call_id`。
- 把 `scripts/query_mysql.py` 收敛为仅允许 SELECT/受控 SHOW 的只读查询脚本,移除默认外部连接参数和 commit 分支;凭据与连接信息全部从环境变量读取。
## Scope
### In scope
- SQL AST validator and validated query plan.
- Static logical data-source/allowlist model.
- JDBC read-only executor abstraction and implementation.
- MySQL result projector and ToolBoundary adapter.
- Security, truncation, timeout/cancellation, no-evidence and boundary tests.
- Query script safety cleanup required by the ISS-014 security prerequisite.
### Out of scope
- Diagnosis Agent cutover or public Chat/AIOps/SSE changes.
- Querying the application's own persistence database through the Agent-facing Tool.
- Metadata discovery (`SHOW TABLES`, `SHOW COLUMNS`, `DESCRIBE`, `information_schema`).
- Tenant/row-level authorization, dynamic allowlists, arbitrary SQL functions, real production business datasource provisioning.
## Frozen SQL subset
- One `SELECT` statement only.
- Explicit projection columns; `COUNT(*)` is the only star exception.
- `INNER JOIN` and `LEFT JOIN`, normal predicates, `GROUP BY`, `HAVING`, `ORDER BY` and parameter placeholders.
- No `WITH`, subquery, `UNION`, window function, `CROSS JOIN`, write statement, metadata query, transaction control, dangerous function, or unknown AST node.
## Constraints and risks
- Parser acceptance is not authorization: every table and column used by projection, predicates, joins, grouping and ordering must pass the independent allowlist.
- Unknown data source, schema, table, column, function, placeholder mismatch or parser failure fails closed before JDBC execution.
- JDBC row/cell/byte limits are enforced in addition to ToolBoundary limits; oversized results are projected with `truncated=true` or become a safe error when no valid bounded result can be produced.
- The adapter is not wired into the existing public runtime in this stage; later Diagnosis Agent work will select it through the internal Harness application use case.
## Acceptance direction
- Valid explicit-column SELECT and `COUNT(*)` pass AST and allowlist validation.
- Write statements, metadata, wildcard projection, nested/compound queries, unknown AST, allowlist bypass and placeholder mismatch are rejected without executor invocation.
- JDBC executor uses read-only prepared statements, max rows, timeout and cancellation.
- Agent receives only bounded `MysqlToolResult`; raw JDBC rows remain Harness-only canonical data.