跳转至

技术规格:脚本事实投影(Issue 1)

分支文档快照 · 同步于 2026-09-09 · 来源:feat/evidence-projection @ 91a7d1c · 原路径:docs/project/current/IK6EG0-tech-spec.md。正文描述的是该分支的方案或进展,合入与验收状态以当前看板为准。

关联 issue 文稿: IK6EG0-issue-draft.md 状态: 已落地(feat/evidence-projection;P-0~P-6 完成) 验证基线: 0730 gcsdb_0009 + .tmp/token-sim-0730/ + files/0625/.../table_ctx_cache/ 仓库路径: skills/sql-dis-opt/(已同步 .opencode/skills/ 镜像) 离线回归: python3 scripts/test_evidence_projection.py

0. 执行约束

  • 只做 Issue 1:事实投影出口 + SKILL 消费约定;不顺手做 Issue 2/3/4。
  • 不截断落盘行集;不改 compare_result_rows 算法(Issue 4)。
  • 先改 skills/sql-dis-opt/,再同步 .opencode/skills/ 对应文件。

1. 分层契约

┌─ 完整证据(disk)─────────────────────────────────────┐
│ baseline.json / table_ctx.json / execute_result.json   │
│ table_ctx/{db.table}/{ddl,indexes,partitions,...}      │
│ 含 result.rows —— execute 比较唯一来源                 │
└────────────────────────────────────────────────────────┘
        │ output_json(..., stdout_data=projection)
        ▼
┌─ 事实投影(stdout → 模型上下文)──────────────────────┐
│ schema_version: sqlopt-evidence/v1                     │
│ kind / evidence_ref / facts / omitted_from_context     │
│ known_unknowns / blocked_decisions / claim_constraints │
│ agent_space(提示可发挥范围,非强制字段清单剧本)      │
└────────────────────────────────────────────────────────┘
        │
        ▼
┌─ agent 策略 ───────────────────────────────────────────┐
│ 选 skill、改写、索引列序、风险叙述、是否下一轮          │
│ 禁止改写 facts;缺字段 → read(evidence_ref)            │
└────────────────────────────────────────────────────────┘

1.1 stdout 投影最小骨架

{
  "schema_version": "sqlopt-evidence/v1",
  "kind": "baseline_facts | table_ctx_facts | execute_facts",
  "evidence_ref": "round_N/xxx.json",
  "facts": {},
  "omitted_from_context": [],
  "known_unknowns": [],
  "blocked_decisions": [],
  "claim_constraints": [],
  "agent_space": []
}

模拟样例(契约对照):

kind 样例路径 tok≈
baseline_facts .tmp/token-sim-0730/projected_baseline.json 949
table_ctx_facts .tmp/token-sim-0730/projected_table_ctx.json 2,227
execute_facts .tmp/token-sim-0730/projected_execute.json 965

2. 卡片

P-0:确认范围 — 完成

  • 认可「钉死证据 / 放开策略」;不采用 LLM 自由摘要接力作主路径
  • 认可 E3 模拟数量级作为验收参照
  • 确认先改 skills/sql-dis-opt 再同步 .opencode

P-1:扩展 _lib.output_json — 完成

改 skills/sql-dis-opt/sql-distributed/scripts/_lib.py

def output_json(data, output_path=None, stdout_data=None):
    if output_path:
        # 始终写全量 data
        ...
    printable = stdout_data if stdout_data is not None else data
    print(json.dumps(printable, ensure_ascii=False, indent=2, default=str))

落地规则:

条件 磁盘 stdout
有 --output 且传入 stdout_data 全量 data 投影
有 --output 未传 stdout_data 全量 全量(兼容旧调用)
无 --output 但入口已传 stdout_data 无 投影(baseline / table_ctx / execute 当前行为)
无 --output 且未传 stdout_data 无 全量

已增投影 helper(同文件):

  • project_baseline_facts(full, evidence_ref) -> dict
  • project_table_ctx_facts(full, evidence_ref) -> dict
  • project_execute_facts(full, evidence_ref) -> dict
  • _load_tables_schema_from_disk(tables, table_ctx_dir):优先从落盘 ddl.sql / indexes.json / table_stats.json 填 tables_schema

P-2:baseline.py — 完成

  • 落盘不变(含完整 result.rows、完整 explain、sql;max_rows=None)
  • 调用:output_json(out, path, stdout_data=project_baseline_facts(...))
  • facts 含:baseline_mode / execution_time / row_count / error / fallback_reason / result_schema.columns / explain
  • omitted:sql、result.rows

P-3:table_ctx.py — 完成

  • 落盘不变(table_ctx.json + 每表目录全文;table_info 仍为拼接文本供磁盘审计)
  • stdout 投影:
  • distributed_context 原样
  • column_selectivity 结构化;去掉 column_selectivity_text
  • tables_schema[table].{columns, indexes[{name,columns,unique}], stats} —— 优先读磁盘目录,dict 形 table_info 作回退
  • 不把 table_info 分区逐行 dump 打进 stdout
  • claim_constraints 含:禁止把 has_cross_shard=true 写成 has_full_shard_scan=true
  • blocked_decisions:shard_key_source=missing 禁伪造分片键;index_scope=local_unknown 禁默认全局索引

P-4:execute.py — 完成

  • 落盘不变(含双边 rows)
  • stdout 投影:时间 / improvement_percent / result_identical / comparison_detail / 索引审计五字段 / optimized_explain / verdict / comparison_strength
  • 省略 org_result.rows / optimized_result.rows / SQL 回显
  • comparison_strength 字段已输出;语义纠正属 Issue 4

P-5:SKILL 消费约定 — 完成

  • sql-distributed/SKILL.md:总述「证据投影」+ 步骤 4 / 5 / 9 / 10
  • 子技能已补投影消费约定:optimization-generation / ddl-index / optimization-review
  • 缺索引列序 / selectivity / distributed_context → 证据不足,不得伪造;按 known_unknowns 回读

P-6:同步与回归 — 完成

  • 已同步 .opencode/skills/ 下对应 scripts/{_lib,baseline,table_ctx,execute}.py 与 SKILL
  • 离线回归入口:scripts/test_evidence_projection.py(0625 真实磁盘 happy path + 0730 envelope + execute)

3. 验证链

E1 0730 官方曲线          → 已证问题存在
E2 output_json 双写       → 已落地
E3 离线事实投影模拟       → 已完成(步骤 5.5 前 cum≈33k)
E5 生产改动后离线回归     → scripts/test_evidence_projection.py
E6 可选:27 服务器重跑    → 待环境

3.1 证据索引

ID 内容 位置
E1 官方 input 曲线 session-export-dis-test0730.json;结论见 issue 文稿
E2 双写 + project_* skills/sql-dis-opt/sql-distributed/scripts/_lib.py
E2b baseline 不截断拉行 baseline.py max_rows=None
E3 模拟报告 .tmp/token-sim-0730/flow_token_report.md
E3b 恢复的全量载荷 .tmp/token-sim-0730/seq16_full.json, seq23_full.json
E3c 投影样例 .tmp/token-sim-0730/projected_*.json
E3d 模拟器 .tmp/token-sim-0730/simulate_fact_projection_flow.py
E5 生产离线回归 scripts/test_evidence_projection.py
E4 自由摘要不安全 对话结论:compact 有损;试跑误判全扫

3.2 验收命令

# 1) 语法
"$PYTHON_BIN" -m py_compile \
  skills/sql-dis-opt/sql-distributed/scripts/_lib.py \
  skills/sql-dis-opt/sql-distributed/scripts/baseline.py \
  skills/sql-dis-opt/sql-distributed/scripts/table_ctx.py \
  skills/sql-dis-opt/sql-distributed/scripts/execute.py

# 2) 离线投影回归(不连库)
python3 scripts/test_evidence_projection.py

# 3) 可选:原模拟器数量级
python3 .tmp/token-sim-0730/simulate_fact_projection_flow.py

4. 落地改动量(约)

文件 说明
_lib.py output_json + 3×project_* + disk tables_schema 加载
baseline.py / table_ctx.py / execute.py 接线 stdout_data=
SKILL.md ×4(主 + generation + ddl-index + review) 消费约定
.opencode/skills/ 镜像同步
scripts/test_evidence_projection.py 离线回归

5. 与后续 Issue 的边界

Issue 关系
Issue 1(本规格) 脚本事实投影;解除 5.5 主阻塞 — 已落地
Issue 2 规则预筛 再省 ~6k pending;本规格验收不依赖
Issue 3 SKILL 瘦身 最多再省 ~2k;低优先
Issue 4 comparison_strength 投影已带字段;语义修复另卡

全量子 skill 同载时投影路径峰值仍可能 ~60k(E3)——属 agent 按需加载 策略问题,不在本 issue 用字段表写死。