Files
SuperBizAgent-java/devflow/projects/2026-07-21-single-react-mysql-readonly-tool/decisions.md
T

109 lines
6.3 KiB
Markdown

# Decisions: single-react-mysql-readonly-tool
## Discover status
- Checkpoint: Discover
- Capability source: `sm-flow` with local ISS-014, OpenSpec contracts, existing JDBC dependency/configuration and JSqlParser 4.6 already present in the local Maven cache.
- Scale: complex, because this stage combines AST policy, authorization, JDBC resource limits, projection, and security cleanup.
## Evidence-driven findings
1. `MysqlToolRequest` and `MysqlToolResult` are already frozen under `harness.tool.contract`; no public DTO change is needed.
2. The project already has MySQL JDBC/JPA dependencies, but no Agent-facing external read-only executor or SQL policy.
3. JSqlParser 4.6 is available in the local Maven cache and exposes `CCJSqlParserUtil`, `Select`, `PlainSelect`, `Table`, `Column`, `Function`, `JdbcParameter` and visitor adapters compatible with Java 17.
4. The current application datasource points to the Agent persistence database; the new Tool must use an independently configured logical datasource map and must not reuse that datasource implicitly.
5. `scripts/query_mysql.py` currently defaults host/port/user values and contains a non-SELECT commit branch. This violates the ISS-014 security prerequisite and will be changed to read-only, environment-only behavior.
## Question pool
| Dimension | Question | Mode | Conclusion | Status |
|---|---|---|---|---|
| SQL language | Which SQL subset is executable? | evidence-driven | One SELECT, explicit columns, INNER/LEFT JOIN, predicates/group/order, parameter placeholders and allowlisted aggregates. | resolved |
| Security | How is authorization decided? | evidence-driven | Independent exact schema/table/column allowlist; parser acceptance alone is insufficient. | resolved |
| Data source | Can the Agent pass JDBC coordinates? | evidence-driven | No. Only logical data_source IDs are accepted; connection properties remain configuration/Secret data. | resolved |
| Execution | Which JDBC controls are mandatory? | evidence-driven | PreparedStatement, readOnly connection, setMaxRows, query timeout and Run cancellation. | resolved |
| Metadata | Can the Tool discover tables/columns? | evidence-driven | No. SHOW/DESCRIBE/information_schema are rejected. | resolved |
| Compatibility | Does this cut over public runtime now? | evidence-driven | No. Add internal adapter/executor; Diagnosis Agent integration is stage 4. | resolved |
## User-confirmed direction
- Use the frozen `MysqlToolRequest`/`MysqlToolResult` contract.
- Reuse the existing ToolBoundary and canonical invocation store.
- Keep stage boundaries serial: archive and commit 3C before stage 4.
- Do not pause for routine apply/archive/commit confirmation.
## Pre-apply research
### Existing implementations and dependencies
- `src/main/java/com/superbiz/agent/harness/tool/contract/MysqlToolRequest.java`
- `src/main/java/com/superbiz/agent/harness/tool/contract/MysqlToolResult.java`
- `src/main/java/com/superbiz/agent/harness/tool/boundary/ToolBoundary.java`
- `src/main/java/com/superbiz/agent/harness/tool/adapter/QueryLogsToolAdapter.java`
- `src/main/resources/application.yml`
- `pom.xml` (`mysql-connector-j` already present; add JSqlParser 4.6)
- `scripts/query_mysql.py`
### New classes
- `MysqlToolLimits`
- `MysqlDataSourceDefinition` / allowlist value objects
- `MysqlQueryPlan`
- `MysqlSqlValidator`
- `MysqlReadOnlyExecutor` and JDBC implementation
- `MysqlResultProjector`
- `MysqlToolAdapter`
### Risk controls
- Do not create a generic plugin/DSL layer.
- Do not use regex or `startsWith` as SQL authorization.
- Fail closed on parser/visitor uncertainty.
- Keep raw result canonical-only and expose only bounded projection.
## Commit checkpoint preparation
- Proposal scope, design choices, frozen SQL subset, security script cleanup and acceptance scenarios are ready for Commit artifact generation.
## Commit audit
- Capability source: `sm-flow` and local OpenSpec CLI.
- OpenSpec strict validation: passed for `single-react-mysql-readonly-tool`.
- Cross-artifact alignment:
- brief goals/non-goals -> proposal scope: aligned.
- proposal SQL/security boundaries -> design architecture: aligned.
- design validator/executor/projector decisions -> spec requirements: aligned.
- spec scenarios -> tasks for dependency, policy, JDBC, projection, adapter and verification: aligned.
- Interface impact: L2 internal Harness tool/adapter plus JSqlParser dependency and query-script behavior; no public protocol changes.
- Preflight risk accepted: parser ambiguity, datasource isolation, driver cancellation behavior and sensitive result values all fail closed or remain Harness-only.
## Commit gate
- [x] proposal, design, specs and tasks exist.
- [x] strict OpenSpec validation passes.
- [x] all evidence-driven questions are resolved.
- [x] no unresolved interface decision remains.
- [x] `.committed` marker created for Apply.
## Apply result
- Added JSqlParser 4.6 and fail-closed `MysqlSqlValidator`.
- Added immutable logical datasource/allowlist/limit/query-plan/raw-result models and independent `MysqlToolProperties` binding.
- Added `JdbcMysqlReadOnlyExecutor` with read-only connection, PreparedStatement binding, query timeout, max rows, cell/result limits and Run cancellation callback.
- Added `MysqlResultProjector` with sensitive-column redaction, row/cell/total UTF-8 bounds and `NO_EVIDENCE`.
- Added `MysqlToolAdapter` through the existing ToolBoundary; invalid SQL is rejected before database execution.
- Replaced `scripts/query_mysql.py` with environment-only, read-only transaction behavior and pre-connect write/metadata rejection.
## Apply conflicts and corrections
- `COUNT(*)` is represented by JSqlParser as an `AllColumns` parameter in this version; the visitor was corrected to permit only the explicit `COUNT(*)` exception.
- JDBC metadata access cannot be used as a checked-exception stream method reference; the implementation uses an explicit column loop.
- No OpenSpec/design conflict was found; both corrections were implementation details.
## Archive result
- Apply tasks complete and `.archive-ready` created.
- OpenSpec archived at `openspec/changes/archive/2026-07-21-single-react-mysql-readonly-tool`.
- Main capability specification added at `openspec/specs/mysql-readonly-tool/spec.md`.
- Stage 4 may consume the internal adapter only after this stage is committed.