feat(harness): add readonly mysql tool
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user