Commit Graph

451 Commits

Author SHA1 Message Date
ThearchyHelios 5d4d1fdc15 审批质询遮罩收口(第 2 轮复核):算式边界、套了 CAST / 汇总的列、换个写法的数、两头不是整数、范围再排除一头都认得出;只装着标签的列才不收标签;截断片段整段去掉
复核留下的三条 major 和两条次要问题:

- 范围的一头是算式(age <= 25 + 0、buyer_phone BETWEEN 13900000000 + 1 AND 13900000009 - 8):夹住的值认得出,算式里的数
  却照原样留着,一算就是那个号码。现在几个写死的数的加减乘除按算出来的那一个值认(_lifts):夹住某一个值的边界、等值、
  IN 里的算式,里面的数都换;选出列里算出来的号码按值换;没夹住的算式阈值和写成一个数的阈值一样照原样,正文里复述它
  (连同算出来的值)不遮,算出来的值在别处换掉了也不留。原有两条用例(BETWEEN 13900000001 AND 13900000002 - 1、
  … AND 13900000001 + 0)的期望随之改成算式里的数都换(多换一个 1、0,号码照样不露)
- 几种找值写法以前认不出:被比较的一边套了 CAST、汇总(CAST(age AS INTEGER) = 25、HAVING MAX(age) BETWEEN 25 AND 25)
  改按它的值取自哪些列认(_columns_of);同一个数换个写法(25.0、025、2.5e1、013900000001)按规范写法和遮罩值比
  (_canonical);两头不是整数的范围(age > 24.5 AND age < 25.5、BETWEEN 25 AND 25.9)在整数上隔开紧挨着的两个整数;
  范围再用不等、NOT IN 去掉一头(buyer_phone >= 13900000001 AND buyer_phone <= 13900000002 AND buyer_phone <> 13900000002,
  以前号码被当成阈值、回答正文跟着不遮):等值一类只在同一个条件里和范围合起来看,整数上紧挨着的被排除的数越过去接着
  看(age <= 30 时 27 照样成立,不算夹住),跨条件配对仍只看范围比较,不等、IN 单拿出来不当「写出了这个值」
- 算式求值改成不递归(_constants):visits <= 1+1+…写到 1500 项时以前超过递归深度,整条 SQL 退回按词认,同一句里夹住的
  年龄照原样封存
- 分档标签不收进遮罩值的规则太宽(第 1 轮引入):改了名字的遮罩列(vip_level AS 等级)的 1、2、3 撞上同一条 SQL 里按
  条件数个数的 THEN 1 ELSE 0,1 就不算遮罩值,WHERE vip_level = 1 照原样封存。现在只跳过只装着标签的列的格子
  (_label_columns:选出项本身是结果全为常量的 CASE / IIF,或者经别名、子查询、CTE 原样传下去的,没起别名的按位置认;
  同一个名字在哪一处装着别的就照收)
- SQL 检查结果的说明:码值表里的码值和别的字一样按值换,说明照实写(多遮,不漏),补测试钉住
- 截断的片段停在带空格的遮罩文字值中间(地址):以前只去掉最后一段,前半截还留着;现在从没闭合的引号、注释起整个去掉
- 模块说明的已知局限照实更新:两个产品取舍保持;夹住的认法补上不等、NOT IN、两头不是整数和越过排除数的规则;新增一条
  列出认得出的找值写法和仍认不出的(值藏进和列一起算的算式、拼接、函数拼出来的值)

测试:单元补算式边界、套了 CAST / 汇总、换个写法、两头不是整数、排除一头、不该夹住的几种(范围加不等仍不只一个值、
IN 列表旁的阈值、选出列里的等值和 WHERE 的范围)、上千项连加、改了名字的遮罩列撞上标签、标签列经子查询 / CTE / 没起
别名、截断片段、码值表;端到端补长号码的五种写法(算出来的边界、算出来的等值、两头不是整数、范围再排除一头、补零)、
年龄的六种写法和改了名字的等级列。每处实现都逐个去掉验证过测试变红
2026-10-06 15:08:56 +08:00
ThearchyHelios dde0927460 审批质询遮罩收口(第 1 轮复核):「夹住某一个值」在整条 SQL 里认,只有分档的几种写法各算各的;分档标签不当遮罩值;SQL 检查结果的片段、说明照整条 SQL 换
- 夹住:上一轮只在同一个条件里配对,把找值拆到 ON 和 WHERE、WHERE 和 HAVING、INTERSECT / EXCEPT 两支、包在 CASE / 函数 / 算式里、子查询和 CTE 里,完整手机号就照原样封存、回答正文也跟着不遮。现在整条 SQL 里配对,只有 CASE 的不同分支、IIF 的真假两支、SELECT 里不筛行的不同项(选出列、GROUP BY、ORDER BY)、UNION 的不同支各算各的(_apart,看最近公共祖先);同一个条件里照旧按合起来的真假细看。整数上 <= v、>= v 也隔开相邻的整数(age <= 24 OR age >= 26 就是 age <> 25);BETWEEN v AND v、>= v AND <= v、> v OR < v 条件里哪一层这样写都算(被更宽的范围吸收、旁边有矛盾的条件、隔着别的条件写也认得出),整数的半开区间仍只看整个条件,成百个相邻分档照旧不遮。条件的各层摊开一次反复用,600 档的耗时和上一轮相当
- 分档标签:CASE / IIF 结果全是写死常量的,标签文字是 agent 写在 SQL 里的,不收进遮罩值,规格原句的 SQL、回答里的档名照原样;当分组键(每一档一行)或套在汇总里按条件数个数(SUM(CASE … THEN 1 ELSE 0 END))不算派生值,格子照常显示,分得清哪一档几笔;逐行的标签列、汇总遮罩列本身的值照旧整列遮
- 质询工件的 SQL 检查结果:片段是检查器重新写出的表达式,单拿出来认不出在找哪一个值,改为按整条 SQL 里整个换掉的字面量换(简单 CASE、行值、BETWEEN v AND v 里的短的数也换掉,阈值照原样);说明里照引的取值(「没有码值「3」」)一样换;截断处半截的号码去掉
- 同一个短的数在别处换掉时,别的列上的阈值、LIMIT 照原样:一律换会回退第 2 轮起的「age = 25 AND amount > 25 … LIMIT 25」,写进已知局限并补测试钉住
- 模块说明的已知局限照实改写(分档拆进两个 CTE / FROM 子查询、同一选出列里两档汇总相除会多遮,拆进 CASE 分支 / 不同选出列认不出,运行详情的工件页签不经这里的遮罩)
- 测试:端到端改回规格原句(文字档位、SUM(CASE …)、年龄段 CASE),补 ON/WHERE、WHERE/HAVING、INTERSECT、包在 CASE 里、CTE、相邻整数的端到端用例,单元补拆分写法、被吸收的 BETWEEN v AND v、分组标签、检查结果片段与说明;每处去掉实现都验证过变红
2026-10-06 14:05:52 +08:00
ThearchyHelios 898bd8a276 审批质询遮罩收口:模块说明和取质询工件的说明写上 SQL 检查结果的片段照 SQL 换
上一处改动(f0e97f6)只在接口说明和 _masked_checks 里写了,模块说明的「读取」一条和 inquiry_artifact 的说明补上,免得读的人以为工件里的 checks 原样给。
2026-10-06 12:34:55 +08:00
ThearchyHelios 8ca750d7ee 审批质询遮罩收口:说明跟上实现——「夹住」越过的连接词含异或、条件长到细看不过来时多遮几个阈值写进已知局限
- 模块说明的已知局限补一句:条件长到细看不过来(PIN_WORK)时,两边都隔开的一律按夹住算,会多遮几个阈值
- 测试说明对齐:同一个条件里夹住的那组用例越过的连接词含异或(XOR 用例),HAVING 的用例已挪到自己那条测试;年龄段那条
  补上说明
2026-10-06 12:32:48 +08:00
ThearchyHelios f0e97f614f 审批质询遮罩收口(后端):质询工件里的 SQL 检查结果字段照证据面板,片段里的遮罩值照 SQL 换掉
做项 3 时发现的同一类缺口:agent 的查询快照带着 SQL 检查结果(数据源查询工具对照数据目录查出的问题,checks),质询工件接口
原样带出——sql_excerpt 是从这条 SQL 摘的片段(按遮罩列筛选的那个条件,例如 buyer_phone = '13900000001'),for_model 是给模型
的改法、也照抄了片段。事件和工件里的 content.sql 已经换掉遮罩值,旁边的片段没换,等于从旁边把值露出来;证据面板对报告快照
本来就只给约定的几个字段、不给 for_model。

- inquiry_artifact 里的 checks 经 _masked_checks:字段照证据面板的 _query_checks(不交 for_model),sql_excerpt 照查询清单的
  SQL 换(_scrub_sql,和遮罩列做等值比较的短的数、日期这样的字也认得出)
- 界面不读 checks,只是接口上不再带原值
- 补单元测试和端到端测试(把 SQL 检查换成会摘出遮罩值片段的假检查)。做过去掉实现、测试变红的验证
2026-10-06 12:30:52 +08:00
ThearchyHelios 32c3119086 审批质询遮罩收口(后端):质询工件里文字格夹着的遮罩值按子串换掉,回答一路照旧整份不交
第 1 轮起留着的缺口:备注列(没设遮罩)一格写着「客户13900000001来电改址」,手机号设了遮罩、被报告取数选中。agent 引用这一格,
回答被正确拦下(「回答中含有设了遮罩的值……已不予展示」),可事件的 inquiry_artifacts 照样记着这份快照,
GET /api/runs/{id}/inquiries/artifacts/{artifact_id} 返回原样的格子、masked 为空,等于在「不予展示」旁边一点就能看到原值。

- _masked_view 加 embedded:没设遮罩的列里,一格文字(JSON 列按界面画出来的样子)夹着按值认得出的遮罩值,把那一截换成
  「已遮罩」,这一格别的字、别的格子照原样;门槛同整格(_Secrets.scrub:够长的数、两个字以上的文字,提问人自己写的、报告
  列出的指标和运行输入的值不换)。这一列不记进 masked:界面把记进去的列整列画成「已遮罩」,这一列在数据源里也没设遮罩
- 只有取质询工件这一路按子串换,而且只换要取的那一份(_plan 的 embedded 是工件 id 的集合);回答一路不动,渲染出来露了
  照旧整份不交
- 接口说明写清 masked 的含义:有格子整格被遮掉的列;一格文字里夹着的只换那一截,列不记进去
- 补单元测试(文字格、字典形状的行、JSON 列、整格照旧整格换、回答一路照旧)和端到端测试(回答整份不交,工件里那一格变成
  「客户已遮罩来电改址」、其余格子照原样、masked 为空)。做过去掉实现、测试变红的验证
2026-10-06 12:25:48 +08:00
ThearchyHelios 4690063f5d 审批质询遮罩收口(后端):「夹住某一个值」只在同一个条件里、按条件合起来的真假认;阈值只在同一个数在这条 SQL 别处确实换掉时才不留
复验留下的两条多遮回归(遮得太多,不漏):
- _pinned 收全句所有范围比较一起配对,列名认不出的(SUM(amount)、函数)还和哪一列都配:分档的两个 WHEN 分支、两个选出列、
  UNION 两支、WHERE 和 HAVING 各写一边,共用的边界被当成「夹住了某一笔」遮掉,回答里「以 20000 元为界」也跟着遮。改成从每个
  比较往上只越过且、或、非、异或、括号,走到同一个条件根的才放在一起看;同一个条件里两边都被隔开了,再按条件合起来的真假看
  是不是真只认这一个值(条件里别的部分当成不知道真假,有一种取法夹住就算)。BETWEEN v AND v、>= v AND <= v、> v OR < v、
  整数的半开区间照旧认得出;age > 31 AND age <= 25 AND 25 < age AND age NOT BETWEEN 25 AND 31 这种谁也找不着的不算,第 2 轮的
  原输入恢复并通过。列名认不出的只和写得一样的表达式配
- 夹住的值另记下来:两头都不是那个值的整数开区间(age > 24 AND age < 26)按夹住的 25 换,不再留着 24、26 等于写出 25
- 几百个条件连成一长串:条件改成不递归地算(以前上千层会超过递归深度,退回按词认,短的数就漏了);细看夹没夹住按步数设了
  上限(PIN_WORK),看不过来的两边都隔开就按夹住算
- _literals 的「别处出现过同一个数」从所有非保留字面量里抽数字片段,日期里的 31、天数修饰里的 30、标签里的 30、没设遮罩的
  列上的 amount = 30 都算,阈值就改记成等值遮掉,可那些地方一个字没换,回答正文又照样写着它。改成和真去换的同一套判断
  (_swap_literal,_scrub_sql 也照它换):只有同一个数在这条 SQL 别处确实被换掉了(等值、别处的长数整个换掉,字符串里按值
  换掉的遮罩数)才不留;换掉的是文字标签不牵连阈值。查询之间的正文免遮(_shown_literals)同理,按查询各自认遮罩列的比较
- 模块说明补上已知局限:按值认的门槛两头都有误差(短的数在正文里遮不住、5 位以上的数会误遮巧合的数)、遮罩数值列的
  SUM/AVG/MIN/MAX 和按遮罩列分档的 CASE 标签算派生值(产品取舍,保持现状)、「夹住」只在同一个条件里认(拆进子查询或 CTE 的
  认不出)、遮罩值收集有上限
- 补单元测试和端到端测试:重叠的分档边界(两个 WHEN 分支、两个选出列、UNION 两支、年龄段)、日期、天数、标签、未遮罩列的
  等值照原样封存、正文不遮;同一条件里夹住一个值的几种写法(旁边有别的条件、CASE WHEN、HAVING 里同一个汇总值、整数开区间、
  XOR)和别处确实换掉的同一个数照旧遮。每处改动都做过去掉实现、测试变红的验证
2026-10-06 12:24:54 +08:00
ThearchyHelios 833d206fb2 证据接口测试跟上期 4 合并:反方审稿节点的产出带着 unreviewed(没能反查的句数),句子的 challenge 照样带上,两条整句比对的期望补上这个键 2026-10-06 11:37:22 +08:00
ThearchyHelios cc166fefb8 合入期 4 审批质询(前端):报告句末与划选原文浮出「质询」,问答串与提问框挂在审批卡和运行详情,回答按片段与出处渲染;同一张卡挂两处、换了审批、报告改写前的问答各归其位;时间线解读 approval.inquiry,等待中来质询阶段仍是等待 2026-10-06 11:32:20 +08:00
ThearchyHelios c549b15150 合入期 4 期 3 收尾:核查缺口分「核查未通过」「核查未完成」两组,时间线认得核查类日志代码;双盲复算写目录的预告和真写逐字一致(被目录挡下的那一边也说清原因,几个指标落到同一项时按组合预告);反方审稿说清「根本没反查」和「到底降不降档」;字段叫法挪到 labels.py;记录页的核查工件有名字和说明 2026-10-06 11:31:11 +08:00
ThearchyHelios bef11d76ca 合入期 4 证据面板核查状态与打磨:证据接口带上双盲复算、反方审稿的状态,指标步骤里遮罩列的输入只写「已遮罩」;可验证报告里输入取自遮罩列的口径卡只给 id;推演与口径卡共用取整;运行对比离开后晚到的答复不再跳走 2026-10-06 11:31:02 +08:00
ThearchyHelios 6a9570f045 合入期 4 定时任务 × 运行对比:定时运行结束后自动和同一定时任务上一次成功的运行对比,结果存成工件记在触发记录上;触发历史和通知只给计数摘要与对比页链接,附封存哈希前 12 位;运行详情页头的定时任务来源改成键盘可达的链接 2026-10-06 11:30:56 +08:00
ThearchyHelios ad745a930a 合入期 4 审批质询(后端):运行停在审批时针对报告里的一句话提问,只读 agent 现查现答,问答写进运行、随运行封存;遮罩按 SQL 认出改了名字的遮罩列再按值遮,SQL 只换在找某一个值的字面量;质询进行中批准、驳回、继续运行回 409 2026-10-06 11:30:56 +08:00
ThearchyHelios a17c822d57 审批质询复核修正(第 3 轮,后端):SQL 里的字面量按语法树认用在哪,数字照原样留着的只有没夹住某一个值的范围边界和 LIMIT 行数;SQL 里留着的阈值只在回答正文里不遮,格子照旧按值遮;质询工件的免遮接线补上端到端核对
复核提出的问题和改法:
- 第 2 轮为了不误遮阈值,把范围边界、字符串的范围边界和选出列、函数参数里的数从正文和格子的按值遮里一并免掉;而按词认用法时,
  简单 CASE 的 WHEN、IN (VALUES …)、行值、= ANY(ARRAY[…])、IS NOT DISTINCT FROM、套了括号的值这几种在找某一个值的写法被当成「别处」,
  两头相同的范围(BETWEEN v AND v、>= v AND <= v)被当成阈值,遮罩值就留在封存的 SQL、回答正文和质询工件里,最后一道关也放行:
  - 字面量改按语法树认用在哪:越过括号、负号、CAST、行值、VALUES、ARRAY、ANY / ALL 这些外壳再看上一层,上面几种都认作在找某一个值,
    被比较的是哪一列也认得出(短的数照旧只在和遮罩列比较时换)
  - 同一列上同一个值两边都被隔开的范围按在找这个值换:BETWEEN v AND v、>= v AND <= v、> v OR < v、整数的 >= v AND < v + 1,一头是几个数
    算出来的(13900000002 - 1)也算;只从一边隔开的(>= v,或按 v 分成两段)照旧是阈值
  - 数字照原样留着的只剩没夹住某一个值的范围边界和 LIMIT / OFFSET 的行数,而且同一个数在这条 SQL 别的字面量里没被换掉;选出列、函数参数、
    算式里够长的遮罩值照第 1 轮换;字符串的范围边界照第 1 轮按值换。名字、注释里写着阈值不牵连阈值本身(AS 超过30000的笔数)
  - SQL 里照原样留着的数只在回答正文里不遮,格子、列名、SQL 里照旧按值遮;同一个数在别的查询里被换掉了,正文里也遮。组装后的最后一道关
    只放过正文里的这些数,渲染进单元格引用里的照旧拦下
  - SQL 解析不了时认不准哪个数是阈值,一律不免,只按词认简单的等值比较
- 质询工件里两处免遮接线没有测试守住:报告指标、运行输入的值那一处,单笔目标那条端到端测试补上取质询工件,核对别的列里正好是这个数的
  格子在回答、工件里都照常显示;SQL 里阈值那一处随上面的改法拿掉了(格子不再免阈值),补上「格子正好等于阈值」的端到端测试,核对回答和
  工件里这一格一样遮住、两边对得上;阈值那条端到端测试补上取等值查询的质询工件,核对 SQL 和事件里一字不差
- 上面每种写法都补了单元测试和端到端测试(手机号存成整数、文字两种),另补开头带换行的 SQL 位置对得上、名字里的阈值不牵连阈值的测试。
  查询清单的 SQL 现在要解析,改在线程里换(同 _plan)。每处改动都在副本上做过去掉实现、测试变红的验证
2026-10-06 11:02:10 +08:00
ThearchyHelios eb71513924 审批质询(前端)复核整改(第 1 轮):同一张卡挂两处、换了审批、报告改写前的问答各归其位,句末入口不再挤动正文
- 提问框记下打开它的那一处(host)和那张审批:画布的审批浮层和右栏同时挂着同一张卡时,提问框只画在点的那一处,焦点不跳到另一处;另一处写明「提问框已在另一处打开」,可「在这里继续」;浮层关了由右栏接过去,不抢焦点。换了审批(同一份报告的下一级审批、驳回改写后再审)旧的提问框不再显示,提交一律带页面此刻的审批 id,不会再拿旧 id 一直 409
- 问答串按每条问的是哪一稿报告分开:别的审批里问的,按审批列表里那张审批审的文档对一下,对上了才按句子编号挂;改写前的、对不上的单独一组「报告其他版本上的质询」,不拿当前报告同编号的句子当抬头,回答里引用报告出处的数也不去当前这一稿里找。运行详情同理(封存之后问的认封存的那一稿)
- 句末的「质询」改成固定宽度的淡色图标,悬停、聚焦只换颜色和描边,不再从宽 0 撑开:后文不右移、表格列不跳;表格格子不挂(问表里的数划选或就整份报告提问)
- Esc、「取消」之后焦点回到那一句的「质询」并滚回视野(页面和限高的报告框都滚)
- 回答期间另开的提问框不再被失败的那一条覆盖:失败的问题和原因挂在原来那一句下面,提问框关着时可以放回提问框重问
- 写进运行记录后:画布正显示这次运行、流已收尾时按已有的最大序号补接一次;运行详情补拉一次事件(pages/runs/useRunDetail.ts 订阅一个计数)。时间线因此出现「审批人质询」
- 运行详情对所有运行只读列出已有问答(正式运行审批时问过的随运行封存,审批处理后也看得到查过的 SQL、行数、快照),入口仍只给封存了的探索运行;设置里关了审批质询就不给入口,已有问答照列并写明已关闭
- 小项:读屏连续两次回答都播报;「已等待 N 秒」挪出播报区;花费照 runCostText 写(估不出不写 $0);查询列表收着时也写有几次被截断;报告没有逐段证据时提示只说可以就整份报告提问;列表取回来之前不出「还没有问答」的提示;回答里核对不了的名称、猜测的来源照报告的线型画;回答期间批准 / 驳回下面那句原因在浅色主题下对比度够了
- RunPanel 改传这张卡的审批 id 和是否待处理(处理过的卡也认得哪几条问的是卡上这一稿);check-all 里 check-inquiry 的预计时长按实测改成 60 秒
- check-inquiry 补上各项:悬停前后正文和表格不移位、焦点回去后在视野里、同一张卡挂两处、先后两张审批、改写前的问答单独一组、失败不覆盖新写的、连续播报、花费、截断、无文档、设置关闭、遮罩原值不外露(含导出的 CSV)、补接事件流;新增预览用例 inquiry-approval-twice / -steps / -steps-same / -nodoc
2026-10-06 09:57:34 +08:00
ThearchyHelios a641bf5fb9 审批质询复核修正(第 2 轮,后端):和 * 写在一起、子查询里没起别名的遮罩列表达式认得出;SQL 只换在找某一个值的字面量,范围比较的边界、LIMIT 照原样;报告口径卡里的指标、SQL 里留着的阈值不当遮罩值;带前缀的字符串、名字、列名里的遮罩值也换
复核提出的问题和改法:
- 遮罩列的表达式和 SELECT * 写在同一支里、又没起别名(SELECT *, SUBSTR(buyer_phone, 4)),原值的一截出现在回答正文和质询工件里:
  按位置认,* 前面的从头数、最后一个 * 后面的从结果末尾倒着数(结果的列一个不少、按顺序,重名也照留)。同一个根子的几种也一起补上:
  子查询、WITH 里没起别名的表达式(外层的 * 原样带出来,列名各数据库起法不同)、两个 * 之间的项认不出落在哪一列,整份快照遮掉;
  派生来源里 UNION 的另一支、带列名表的 UNION 按位置对上第一支或列名表的名字;LATERAL、多套几层括号照样认
- 和遮罩列做范围比较时的阈值、5 位以上的数不看上下文就被换成「已遮罩」,封存的 SQL 不是实际执行的那条:SQL 只换在找某一个值的
  字面量(等值、不等、IN、LIKE、SQLite 的 IS)——和遮罩列比较的是遮罩值就换,和别的列比较的够长的遮罩值也换;范围比较的边界、
  BETWEEN、LIMIT / OFFSET、选出列和算式里的数照原样(字符串的范围边界同样)
- 回答正文里复述 SQL 里照原样留着的阈值(「金额不低于 30000 元」)被遮:这些值本来就随 SQL 摆在读者眼前,正文、快照按值遮时免掉
  (只免按值认的,SQL 里和遮罩列做等值比较的照旧换)
- 报告口径卡里的指标恰好是遮罩值时(单笔目标 20000),引用它的回答整份交不出去、换个问法也绕不过:报告列出的指标和运行输入的值
  像问题里的数一样不当遮罩值,回答时和取质询工件时一样
- 带前缀的字符串(N''、E''、U&''、$$…$$)、带引号和不带引号的名字(AS "13900000001 的单"、张伟的单数)里的遮罩值原样封存:所有
  字符串类的词只换引号里的内容,名字按值换;快照的列名、回答文档目录里的列名同样换,引用原列名的标记里的列名跟着换,正好对上
- 回答原文的标记里写着遮罩值时,单元格引用「Q1.r0.」后面的长号码会被当成小数的一截认不出来:标记按段换,单元格引用只换列名那一截;
  遮罩值在组装之前就换掉,不再组装两遍,组装出来还认得出遮罩值的照旧不交出去
- 新加的接线没有测试守住:补上问题里写了遮罩列的短数时 SQL 原样保留、质询工件按报告快照里的遮罩值遮别的列,以及上面每一种情形
  的单元测试和端到端测试。每处改动都做过去掉实现、测试变红的验证
2026-10-06 09:52:47 +08:00
ThearchyHelios 4c3ba8bc1b 期 4 复核修正(第 1 轮,前端):核查缺口分「核查未通过」「核查未完成」两组并补上证据页、印章的检查,写目录预告推断时算上被挡下的同项指标,反方审稿概况的说法与排布改准
- 出具缺口:双盲复算的「指标无法复算」是没核成,不再和两路不一致、结论被推翻一起叫「核查未通过」——splitIssuanceGaps 分成 failed「核查未通过」、unfinished「核查未完成」两组,时间线那一行、证据页、成果节点印章的悬停说明都按先未通过、再未完成、最后校验不完整排。check-decode 按服务端 GAP_* 和 _refuted_gap 的原话加出具契约的前缀拼出缺口再分组,服务端改了说法先变红;新预览用例 verify-gaps 画真的 EvidencePane 和成果节点卡片,check-verify 断言两组各列各的、横幅的「校验未全部完成」里没有它们、印章说明的先后,以及 390px 深浅色不溢出、可读(以前去掉这两处的实现所有检查照样全绿)
- 时间线:无法复算那一行只说「已记为缺口」,不再一律说「按缺口计入出具」(探索运行不出具,接在侧枝上的缺口进不了出具);dual_check_catalog 带值的写法补上检查,和审批卡「会记为」用同一个函数、一字不差
- 双盲复算审批卡:工件里没有合并预告时(老工件、组合超上限、还没取到),被目录挡下、带着写到哪的同项指标也算进来——业务日期、去重规则说法不同就说都不记(服务端先归拢、轮不到对目录),有效记录条件同项上有被挡下的只说可能记、也可能不记;推出来的条目标 data-inferred,结尾换成「实际写入以时间线上的记录为准」。check-verify 用新夹具 time_rejected 断言销售额不再说「会记为」
- 反方审稿审批卡:「没能」改「未能」,提示不再说「没有真正查询数据」(触顶的查过),原因补上报告未引用数据库查询,时间线的下一步不再建议调高上限(这一条不含触顶的);「N 句未能反查」挪到降档说明后面,不再插在「出具会降档」标记和它的说明中间,句数不超过「无法判断」;不在出具路径上的那句写明是反方审稿节点(审批卡上的「本节点」读着像审批节点)。ChallengeSummary 收 runClass,给了就照它、不另取;check-challenge 的夹具改成和服务端约定一致(未能反查 2 句、无法判断 3 句),另断言给了运行类别时另取失败也照样写降档、不发请求
2026-10-06 09:31:28 +08:00
ThearchyHelios 62b9361d88 期 4 复核修正(第 1 轮,后端):预告组合先算个数再列、上限按每项算,核查 agent 的两个日志代码归类,未能反查的句数守住不多于无法判断
- preview_joint 以前先把每一项的全部组合列成列表才和 JOINT_LIMIT 比,二十个指标落到同一项上就是几十亿种,在服务进程里(asyncio.to_thread)能把整个服务拖死;现在先按 ∏(1+k)−1−Σk 算出个数(超过上限即停),超了整项跳过、不列。上限也改成每一项各算各的:以前几项共用一份额度,前一项用掉以后,后面没超上限的项也被悄悄跳过,和文档说的「超过的那一项不预告」对不上。补两条测试:二十个指标落到同一项上时一个组合都不多列,两项各 72 种都预告
- review.py 认得核查 agent(双盲复算、反方审稿共用)发的两条:verify_unpriced 同 judge_unpriced 只是配置提醒,不再叫复核模型、给答案加降级说明;verify_limit 记成它自己的 kind(步数上限只有它说),不再落成笼统的 warn
- 反方审稿测试补上「未能反查的句数不多于无法判断」的断言(审批卡上的两个数靠这个约定对得上),模块说明改写准:触顶没给出结论的可能查过几次,原因里也有报告未引用数据库查询
- 双盲复算夹具加一种组合 time_rejected:业务日期被驳回过的那一列由退款率采纳(被挡下,带着写到哪),销售额采纳另一列;服务端先归拢、说法不同一项都不写(夹具测试按 record_choices 真写核对),审批卡没有合并预告时的推断按它检查
2026-10-06 09:31:00 +08:00
ThearchyHelios 6e30e2fcd6 证据面板复核整改:反方审稿的概况照实、不预告出具,点句中的数字也看得到;双盲复算写明报告里的数没换、已记为缺口
反方审稿:那一块复用审批卡的展示(只读 ChallengeSummary 的导出),概况改用服务端给的整份报告的计数,不再凭这一句拼出「被推翻
1 句、其余 0 句」;不给它运行 id,就不再写「出具会降档」「本次正式运行将降档出具」这类审批时的将来时预告——运行已经结束,降没
降档看报告的出具横幅(驳回、不予出具、反方审稿不在成果节点上游时那句预告都是错的)。没给计数的判断不画。片段面板(点句中的
数字)同样画这一块:没开结论句裁判的报告没有句末徽标,以前被审过的句子在正文里无处可看。

双盲复算一行:状态词换成时间线上的说法(与盲算结果一致 / 不一致、未能完成),和同一节里按代入式重算的「复算一致 / 无法复算」
分开;标签悬停、读屏说明是什么(另起一路独立计算)。审核人的选择照审批卡的选项原名写(审核人选择「采用盲算的结果」),选了
盲算、两边都不对、没选的写明「报告中的数仍取自原流程,这个指标已记为出具缺口」(探索运行写缺口),未能完成的同样写已记为缺口;
跳过的原因按指标说(节点或设置中已关闭 / 这个指标没有来自查询的输入 / 不在复算范围内),认不出的原因代码不写进句子,标签不再
说两遍「双盲复算」。

遮没遮核对不了的输入(快照读不出来)和遮罩列一样写「已遮罩」,悬停、输入来源里写明原因,不算进底下的遮罩列。

check-evidence:六种状态的文字和颜色、标签说明、和「复算」分得开、第二轮的几种跳过原因和「两边都不对」;正式运行写出具缺口;
整句面板的计数等于服务端给的、没有出具预告的几行、被削弱的那一句不出现「被推翻 0 句」;片段面板、没开裁判的报告点数字看得到
判断;没给计数的不画;核对不了的输入。把计数改回拼的、给回运行 id、片段面板不画、去掉后果那句,对应各项变红。
2026-10-06 09:20:29 +08:00
ThearchyHelios 5e6742b905 可验证报告里有输入取自遮罩列的口径卡只给 id,核对页把它当正常的无法核对
口径卡上记着每个输入的值和代入式:cell() 取的遮罩格、按位置取的 vars.res.rows[0][1],以前原样嵌进这份要发给别人的文件,
证据面板上已经遮住的号码在这里照样看得到。现在口径卡有一个输入取自遮罩列(遮没遮核对不了的也算),整张卡和带遮罩的快照一样
只给 id——没法只拿掉几个值,拿掉了哈希就对不上。认法和证据面板、推演同一个(recompute.input_origin):按定位里的列认,按位置
取的一格顺着取值链从写变量的节点在口径卡那次执行之前的产出起走;快照或产出读不出来、结果没存快照只带着数据源名的宁可多挡。

核对页(verifier.js)把带遮罩的口径卡当成正常的无法核对(「含遮罩列,未随文件附带,只能核对到哈希」),引用它的数字同样无法
核对;只有报告文档标着遮罩才判被改过。check-bundle 原来那项「口径卡标成遮罩判不通过」相应改成「报告文档标成遮罩判不通过」,
另加样本页 masked-card:口径卡在 ③ 无法核对、引用它的数字无法核对、总览通过、页面里找不到那个号码。去掉核对页的改动,这几项变红。
2026-10-06 09:20:29 +08:00
ThearchyHelios be164bd5c1 证据接口复核整改(后端):反方审稿带整份报告的真实计数、跑停运行的审稿照样认得,双盲复算的跳过原因按指标说,遮罩核对不了的宁可多遮
反方审稿:unit.challenge 带上节点产出里整份报告的计数(counts)和没能反查的句数(unreviewed,产出里有才带)。证据面板借审批卡的
展示画这一句,以前凭这一句拼出「被推翻 1 句、其余 0 句」,读着像整份报告的结果。节点设为「报错并停止运行」、句子被推翻时节点报错、
没有 node.finished,以前证据接口认不出这次审稿;现在按审完那一刻的 challenge_done 日志认(只认审稿记录存上了的,处置写 fail),
运行因此失败了也看得到被推翻的是哪几句。

双盲复算:节点以 no_inputs 直通时,那句说的是整张卡。以前原样套到卡上每个指标,配了「复算的指标」子集时,明明取自查询、只是没被
选上的指标也写成「口径卡上没有来自查询的输入」。现在按这个指标自己说:不在子集里、值不是数的是 not_targeted,自己没有来自查询的
输入的才是 no_inputs,关闭了的照旧 disabled;节点跑了、没复算的指标同样这样分。

遮罩:认哪个输入取自哪份查询结果的哪几列抽成 recompute.input_origin,证据面板、推演(之后还有可验证报告)同一个认法。核对不了的
宁可多遮,和推演、可验证报告的原则一致:cell()、Agent 字段落在的快照读不出来;按位置取的一格(以 .rows[行][列] 结尾)取值链上的
产出读不出来;那份结果没存快照、只带着数据源名。证据面板不给值,mask_unverified 写原因、不进遮罩列;推演按读不出来处理,不给值、
不推演。既没带快照 id 也没带数据源名的结果(数据整形改过形状)认不出出处,照常显示,写进交付说明。

recompute.recompute 给双盲复算的预检和盲值用,整个指标重算不了时原因不再说「推演」(_Plan.stuck,判断同 blocked,只换措辞)。
按位置的遮罩接进 recompute 之后,双盲复算的预检对「cell() 输入 + 按位置取自遮罩列的一格」的指标判无法复算(以前照常盲算,遮着的
号码还会作为字面量进盲算模型的计算式),运行对比里这种输入两边都不给值:各补一个用例钉住。

一个指标里同一件工件只读一次:按位置取了好几格时,写变量的节点那份可能几 MB 的产出以前每格重读一遍。

补测:遮罩列上 Agent 字段、cell() 对不上时 model_value / snapshot_value 不在答复里;代入式重新代不出来时整条不给。
test_recompute 的夹具补上数据整形节点 parse 的产出:以前缺着,按位置取的那一格现在会因此核对不了。
去掉实现后新用例各自变红(计数、跑停的审稿、子集的跳过原因、两处宁可多遮、推演、预检措辞、按位置遮罩、只读一次)。
2026-10-06 09:20:09 +08:00
ThearchyHelios 7a6a8283aa 合入 SQL 差异说明收尾:判等价只用保持语义的规范化(去掉依赖表约束的改写),解析保真守卫拦下已知会被读错的写法(MySQL 反斜杠转义、特殊数字写法、比较 / 按位 / 前缀 NOT 没加括号地混用、PostgreSQL 符号运算符与 || 混用等),具体说法只在简单形状上说四类,其余给兜底并附逐行对照;回归语料与执行比对守住等价结论 2026-10-06 09:18:35 +08:00
ThearchyHelios 2eddd8236a SQL 差异说明收尾:前缀的 NOT 后面同一段里既有谓词、又有算术 / 拼接 / 按位运算时(NOT status IN (…) * amount),SQLite 里 NOT 最松、sqlglot 读成 (NOT …) * amount,不在语法树上判等价、只给兜底;48 种组合两种方言都不再判等价,常见的 NOT … IN、NOT … = 照样认得出等价改写。模块说明照实列出仍做不到的几类说明准确度问题(Unix 秒的时间列、带 time 的时长列、被函数定死的列) 2026-10-06 09:18:10 +08:00
ThearchyHelios 778fb8b83e 审批质询复核修正(第 1 轮,后端):遮罩改按 SQL 认出改了名字的遮罩列、再按值遮,按值认有门槛、SQL 只换字面量;没写进记录的回答照样点得开;数据源核对是不是运行用过的那一个;报错和回答末尾的说明给提问人看得懂
复核提出的问题和改法:
- 遮罩列起了别名(本仓库查询的惯例是中文别名)、套了函数、经子查询或 CTE 转一道,原值会出现在回答正文、事件和质询工件里,第二遍组装也拦不住:按 SQL 认出改了名字的遮罩列(COUNT 只数个数、窗口的分区键只决定次序,不算;解析不了又写着遮罩列的,整份快照遮掉),快照另按值遮(别的列里写着遮罩值的格子);组装两遍之后正文里还认得出遮罩值的回答不交出去;提示词写明遮罩列不要选出原值、不要起别名
- 按值遮罩范围过宽:年龄这类短的遮罩值会把阈值、天数、日期、LIMIT 换成「已遮罩」,封存的查询清单不再是实际执行的 SQL。纯数字至少 5 位才按值认,日期、小数、时间、千分位里的一截不算;SQL 只换字面量和注释里的值,短的数只在直接和遮罩列(含别名)比较时才换;问题、选中原文里提问人自己写的值不换
- 提问人写的阈值在回答里被标「无出处」:问题、选中原文里的数作为 allow_numbers 交给两遍组装
- 同一条 SQL 事件里遮了、质询工件接口里没遮:工件接口直接用事件里记下的那条,遮罩值照回答时收(含报告自己的查询快照)
- 没写进运行记录的回答交回了工件 id,质询工件接口却一律 404:这样的回答在进程里留一小时(最多 200 条),这段时间里照样认它引用的工件
- 回答里引用的报告指标(m:)点不开:质询工件接口认回答文档目录里的口径卡
- 遮罩值上万个时每次回答、每次取工件都在事件循环里编一个上万分支的正则,卡住进程一秒上下:先按词、按开头几个字和长短筛出正文里真有的几个值再编;收值、解析 SQL、逐格比对放进线程
- 按名字认源:同名重建的源会被当成运行用过的去查,没固定版本的上传表格还会被悄悄补固定进已封存的运行。按运行里查询快照记的源 id、运行固定的版本核对,对不上的、没固定过的不交给 agent
- 封存之后的追问查的是现在的数据,读者分不清是口径差异还是数据更新:任务里给报告生成的时间,回答末尾注明
- 模型轮数用完被说成查询次数到顶,引用一个都解析不了照样算回答完成:轮数用完 limit 记 null;轮数用完、查询执行失败、引用解析不了都在回答末尾注明
- 报错透出核查 agent 的内部说法(「交结果」「按结构」、裸写的字段名):按情形换成发生了什么加下一步,原话只进日志
- 运行在执行时的说法对正式运行不成立、对过时的审批卡也没说清:带着审批卡来的叫人刷新,没带的按运行类别说什么时候能问
- 回答文档的工件引用 meta 记下问题的前 40 字,运行的工件列表据此认得出是哪个问题的回答
- 测试补上证明接线的用例:两道审批的竞态(approval_id 守卫)、上传表格按运行固定的版本查、设置里的上限和 data_versions 交到 agent 手里、开放途中运行被继续了、报告文档不属于这次运行;新增遮罩的单元测试。每条都做过去掉实现、测试变红的验证
2026-10-06 08:52:16 +08:00
ThearchyHelios 5e8d2c9c36 定时任务自动对比复核整改(前端):页头的定时任务链接在窄窗口里不再被挤没、带日历图标、任务删了写纯文本;触发历史的对比入口改叫「与上一次对比」并写出有几个指标有变化
- 运行详情页头:元信息这一行改成可换行,定时任务链接至少留 7 个字宽。以前这一行不换行、只有链接能缩,820 宽的探索
  运行只剩「由…」,768 宽为 0,Tab 停在看不见的链接上,「2 条事件」被压成竖排。链接前加和「定时」标记一样的日历
  图标,平时看得出能点。取回的定时任务列表里没有这个任务(已删除)时写成纯文本「由定时任务「X」发起(已删除)」,
  不再链到「不存在」页;列表取不到时不算删除
- 触发历史:「对比上一次」改成和运行详情「更多」菜单同一个叫法「与上一次对比」(复用 RUN_COMPARE_TEXT.menu),旁边
  写「N 个指标有变化」,触屏和键盘也看得到变化的规模,悬停照旧写各类个数。基准不是紧挨着的上一次(服务端给
  previous: false)时悬停写明是哪一次,也不再带「默认基准:同一定时任务的上一次运行」的来历
- 「通知中的运行链接」改成「通知中的链接」,说明里写清对比页链接也靠这个地址
- check-schedules:对比入口的叫法、计数、previous 为 false 时的悬停和来历;页头链接在 768、820 宽(含「提取为草稿」
  的探索运行、署名的立即运行)写得下「由定时任务」且「条事件」不竖排、Tab 到时看得见;图标;定时任务删除后的纯文本
  和列表取不到时照旧是链接;390 宽深浅色下计数在屏幕里、对比度够
2026-10-06 08:49:10 +08:00
ThearchyHelios 45fe01effe 定时任务自动对比复核整改(后端):只比成功的运行、按发起先后挑上一次成功的基准、和两边的封存绑定,对比挪到认领之前在锁外做并限时限并发;失败通知的处理行不再重复原因
- 只比成功结束的运行,基准也只取成功的:失败、取消的运行指标不全,和上一次比只会得出「移除 N 个」,拿失败的那次当
  基准每个指标都成了「新增」。基准改成自己查同一定时任务、同一工作流、比这次先发起的运行里成功并封存的最近一次,
  不再用对比接口的 default_base(按结束时间挑:老的失败运行事后被接着跑完,会拿后一次触发当它的「上一次」)。
  中间隔着失败、取消的运行时,通知写「与上一次成功的运行(#短编号,日期)相比」,Fire.compare 多一个 previous
- 和封存绑定:运行的封存要盖住最后一条结束事件才算封存完(sealed_now)。runner 先写终态、再另起会话封存,失败后
  接着跑完的运行在两步之间还带着失败时的清单哈希,以前这一拍会直接认领、按旧封存比、通知里写旧的清单哈希;现在
  等新的封存,等不来就照常推送但不比、不写哈希。停在审批上的通知也不再写失败时留下的哈希。对比工件连同两边的清单
  哈希一起存,触发历史发现任何一边不在终态或清单哈希变了就给 null;对比途中封存变了不记(条件写)
- 时机和时限:锁里只挑出状态有变化的触发,认领挪到对比之后、锁外按条件 UPDATE 做。对比最多等 20 秒(含排队),
  同一时刻最多 2 个;超时只记警告,通知不带对比照常推送。停机时扫描在对比途中被取消,这次触发还没认领,下次照常
  比、照常推(以前先认领、后比,这条通知会永远丢掉)。同一份封存已经比过的直接用记下的结果
- 失败通知:从没开始执行的,原因刚写过,处理行不再让人「查看原因」,任务在排期上写「下一次触发会照常发起」,停用
  的写怎么重新发起;开始执行过的改成「请在 AgentLab 的「记录」中查看失败原因」,和挂起那句指向同一个导航入口
- 新增 test_scheduler_compare_guards.py(封存绑定、时限、取消、并发、复用),test_scheduler_compare.py 补真实缺
  指标的失败运行、上一次失败、补跑老运行几种用例;去掉实现逐项验证过会变红
2026-10-06 08:48:56 +08:00
ThearchyHelios 11d44ebc8a check-verify 补一节:记录页的工件列表里双盲复算对照、反方审稿记录有名字和说明
期 3 新加的两种工件此前没登记叫法,工件列表里露的是键名 dual_check、challenge,说明一栏只有一句「工件」。叫法表(pages/runs/model.ts 的 ARTIFACT_KIND_LABEL)已补上,这里守住:种类的叫法、说明(双盲复算带指标个数,没有 meta 的老数据也有一句),两种都算证据。按页面自己加载的那一份取,同 check-evidence 的工件一节
2026-10-06 08:25:23 +08:00
ThearchyHelios b0cf23ddda 双盲复算审批卡的写目录预告和服务端逐字一致,盲算的理由按理由文档画(前端)
- 预告逐条说:会写的说「哪张表的哪一项会记为……」,不写的照服务端的原话说「不会记入:原因」(和裁决后时间线上跳过的原因一字不差),不再只有一句「不记」看不出为什么。三条分行列出,原因再长窄屏也不撑宽
- 被目录挡下的一边(已确认、驳回过、和已有条件合不起来)服务端照样带着写到哪,卡上据此认出几个指标是不是落到同一项上
- 同一次裁决里几个指标按当前的选择落到同一项上时,照完整对照里服务端算好的合并预告(catalog_joint)说:会写的是合起来的值、写明和哪几个指标一起记入,不写的照原因说;选择一变跟着换成那一组合的结果。工件里没有(老服务端、组合太多、工件还没取到)或认不出时,回到按其余指标当前的选择有条件地推
- 盲算的理由:对照工件带了 rationale_doc(核查 agent 组装、裸数字已标出)时按文档画,和反方审稿的理由同一种画法:有出处的数字画实线、挂盲算自己的查询编号,裸数字画点状线、挂「无证据」,下面再醒目地说一句;老工件只有正文,照旧纯文本
- 夹具 dual_check.json 补 catalog_blocked(目录里已有人工确认的业务日期时的真实预告)、merges 各组合的 catalog 与 joint(服务端按那一组合的目录算的真实输出)、filters_rejected(驳回过的条件),盲算理由换成 compose_doc 的真实输出;test_dual_check_fixture 核对预告与服务端一字不差、joint 里按选择取出的那一条就是真写的结果
- check-verify 补三节:被目录挡下的一边、照合并预告说并和真写核对、合并预告认不出时回退;理由文档的实线、裸数字、提醒和老工件的纯文本
- dual_check_facts._write 的返回标注改成和 _record 一致(写进去的说法或 None)
2026-10-06 08:11:02 +08:00
ThearchyHelios 095cc4c8ab SQL 差异说明收尾(第 2 轮):PostgreSQL 符号运算符和 || 混用不判等价;条件写在聚合里、时间窗口、反连接、经主键定死的列不再说错
- 保真守卫(_misread):PostgreSQL 写成符号、sqlglot 却当成 LIKE 那一级来读的运算符(~、~*、~~、~~*、@@、-|-、@> 等)
  和别的二元运算混用时拦下(PostgreSQL 里它们和 ||、& 同级、从左往右,status ~ 'p' || 'x' 是 (status ~ 'p') || 'x');
  另拦 PostgreSQL 的前缀 @、|/、||/、COLLATE 后面的 ::;不知道是哪种库时拦块注释里套着的 /*、紧跟着字的 --、#、双引号
  括起来的名字(MySQL 默认的 sql_mode 里是字符串)。都只给兜底,附原文的逐行对照。
- 条件写在聚合的参数里(SUM(status = 'paid')、COUNT(… OR NULL)、COUNT(NULLIF(…))、SUM(amount * (1 - is_deleted)))
  算作这一边对这一列有条件(_Usage 的 case),另一边多出同一列上的 WHERE 条件时不再说「这一边没有这个条件」,只给兜底。
- 时间:timed 认 BETWEEN 和时间列上 LIKE 像日期的模式(paid_at LIKE '2026-09%'),时间窗口不再被说成有效行过滤;
  「另一边没有按时间筛选」之前看另一边可能是时间窗口的条件(聚合参数里的时间比较、date_key、stat_month 这类列、
  20260901 / 202609 这类整数、上下界一对),有就不说;认不准是不是时间列的窗口(_window_like)不说成有效行过滤。
  两边的时间列在不同的表上时写成「表.列」。
- 反连接:用到 LEFT JOIN 可空一侧的列的条件(WHERE r.id IS NULL、r.order_id IS NULL)不说成有效行过滤,时间列在
  可空一侧时也不说按它筛时间。
- 给了表结构时,聚合参数所在的表的键在组里定死了(按 u.id 分组时的 u.city),MAX 对 MIN、AVG(DISTINCT) 对 AVG 不说。
- 另一边原文也 LEFT JOIN 了、规范化因为结果不怕重复去掉了的表,不说「另一边没有关联」。
- 回归语料:收尾第 1 轮之后复验报的全部 blocker / major 收进 sql_pairs(_DIFF_R5、_DIFF_TIME_R5、_SAME_HARD_R5、
  _SAME_SCHEMA_R5 执行;REGRESSIONS_R5、EXPLAIN_TRAPS_R5 只查结论),新增对应的测试。
- 模块说明照实补上:新增的守卫、时间条件的认法、只给兜底的情况、收窄换来的代价、MySQL 按默认 sql_mode 读的假设。

认出等价的比例:语料(SQLite,给表结构)169 对里 157 对,和改动前一样;PostgreSQL、MySQL 也不变;不知道是哪种库时
少认 1 对(same:quoted-names,双引号括起来的名字)。
2026-10-06 08:10:41 +08:00
ThearchyHelios f8adbaa463 核查类节点检查器的通用控件合成一份:选画布节点、三态开关、核查模型选择只留在 verifyFields.tsx
期 3 两个工作包各写了一份:双盲复算在 DualCheckFields.tsx(选口径卡、启用三态、盲算模型),反方审稿在 verifyFields.tsx(选报告、启用三态、反方模型),说法和细节各不相同、修一处漏一处。现在双盲复算改用 verifyFields 的 NodePick、TriState、ProviderPick、ModelInput,只给自己的文案;它特有的选指标、口径说明、相对误差留在 DualCheckFields.tsx。写进配置的值不变(留空写回 undefined,三态只认真布尔)。

- NodePick 加可选的分组(上游的一组、画布上其余同类的一组,选了不在上游的照样能选、下面提醒连到上游)、下拉项和缺省名的写法;写着的卡被删了、写的不是口径卡(助手改图、导入 JSON 会写出这种配置)时双盲复算也照实列出、说一句,不再只认「不在画布上」
- TriState 可选在「跟随设置」后面写出设置里现在是开是关(双盲复算用,每次打开检查器重取设置);设置的取法 useVerifyDefaults 挪到这里共用,用不上的控件不发请求
- 画布节点、连线的类型收窄成两边都给得出的 CanvasNode、CanvasEdge,节点卡片摘要和检查器共用 upstreamOf、resolvePick
- check-verify 跟着改:提示、三态、按模型名找接入的标记换成共用控件的;字段叫法从 engine/labels.py 读(期 4 从 schema.py 挪过去);补写着的卡不在画布上、不是口径卡两种情形
2026-10-06 08:10:10 +08:00
ThearchyHelios 0726a97512 审批质询(前端):报告排版变了时浮出的「质询」跟着选区走,check-inquiry 去掉一处时序竞争
- 浮出的「质询」原来只在选区变化、滚动、窗口变化时重新量位置。悬停一句时它的「质询」出现、那一段多折一行,下面的字整体下移,既不滚动也不改选区,按钮却停在原处、压到字上。改为同时用 ResizeObserver 看文档自身的尺寸,变了就重新量
- check-inquiry 加一段:选区上面的内容变高(不滚动、不改选区),按钮仍贴在选区下方;先确认没有这处改动时变红(按钮落后 24px)
- 「贴着报告框底边」那段:Esc 之后焦点下一帧才回到原文起头那一句的「质询」,它一出现那一段多折一行、量好的那一行被挤出框外,负载高时偶发超时(三遍里挂两遍,诊断确认是这个次序)。改为等焦点落定再量,并先把报告框放进视口;四道并行连跑三遍全过
2026-10-06 08:08:06 +08:00
ThearchyHelios 20c24fcf8c 反方审稿审批卡说清「根本没反查」和「到底降不降档」,运行类别取不到时不说出具(前端)
- 服务端给了 unreviewed(核查模型不可用、触顶、数据源不在了等没能反查的句数)就另起一行「N 句没能反查,已记为无法判断」:这几句混在「无法判断」里,分不出是查了数据不够还是一条都没查
- 「出具会降档」只在正式运行、有被推翻的结论、服务端的 degrades 为真时写(老服务端没给时照旧按「不是只标注」算);按降档处置却不在带出具契约的成果节点上游的,说一句为什么不影响出具档位,不再让审核人以为会降档
- 运行类别取不到时一句和出具有关的话都不说:以前写「暂时无法确认运行类别;如为正式运行……会降档」外加重试,卡顶却按审批自带的运行类别写着正式运行,两处打架。窗口重新拿到焦点时照旧再取,取到正式运行后降档提示才出现
- 理由文档的画法(RationaleDoc)导出给双盲复算的审批卡用:没给跳转时有出处的数字不是按钮,只画实线、挂查询编号、读屏念出处
- 检查器帮助里「结论被推翻时」的选项名照下拉写(出具降档 / 只标注 / 报错并停止运行),和服务端报错里点的名字一致
- 预览用例补没能反查、不在出具路径上两种;check-challenge 补这两段、改写取不到运行类别那一段,并新增一节逐项比对 engine/labels.py 的 CHALLENGE_LABEL、CHALLENGE_ON_REFUTED_LABEL 和检查器的字段名、下拉选项
2026-10-06 07:53:47 +08:00
ThearchyHelios e35d19d014 出具缺口里核查报上来的另起一组「核查未通过」,时间线认得期 3 留下的三个核查日志代码(前端)
- 时间线的出具那一行、成果节点卡片的出具印章、证据页的出具横幅:双盲复算、反方审稿报上来的缺口(「双盲复算「节点名」:」「反方审稿:」开头,按节点类型的前缀认,名字里带这几个字的别的节点不算)归在「核查未通过」下,不再和「校验不完整」混在一起——它们是核查查出来的问题(两路结果不一致、结论被推翻、指标无法复算),不是校验没做完。分组只有 run/decode.ts 的 splitIssuanceGaps 一处,三个地方共用
- 时间线解读 dual_check_unchecked(哪几个指标无法复算、各自的原因)、challenge_unreviewed(几句没能反查、第一句的原因)、challenge_sources_lost(几句只查了部分数据源、没查成的源):以前认不得,只能照原话显示;记入数据目录那一行带上写进去的值,写法同审批卡的预告
- 反方审稿的时间线文案从 DUAL_CHECK_TEXT.challengeLog 挪到 CHALLENGE_TEXT.log(各节点的文案放在各自的块里),decode.ts 跟着改引用
- 工件种类叫法补上 dual_check(双盲复算对照)、challenge(反方审稿记录),工件列表不再显示键名
- check-decode 补一节:三个日志代码、出具缺口的分组和顺序、前缀不重复节点类型、缺字段的老日志不崩
2026-10-06 07:53:18 +08:00
ThearchyHelios 35ec307baf 运行对比前端打磨:离开运行详情后晚到的答复不再跳走,下一步只指向真走得通的路
查找基准期间离开运行详情:以前只靠组件卸载时取消请求。路由按过渡渲染换页,地址已经换了、新页面还没画出来的那一下
答复回来,组件还在、请求也没取消,照样把人拽到对比页。现在答复回来时再比一次地址(只比路径,换视图、改筛选不算离开),
人已经不在点菜单时的那个运行详情上就不跳,找不到基准时也不弹提示。

换基准的下一步:409、422、缺基准的 404、找不到默认基准,都先看下拉里有没有能换的运行(已封存、不是本次、也不是当前的
基准,409 时出问题的可能正是它),没有就照实说没有其他可换作基准的已封存运行,不再叫人去上方选;还不知道时先不说。
本次的运行记录不存在时,换基准的位置只说列不出同一工作流的运行,不给重试几次都一样的「重试」。

check-compare:「离开之后答复才回来」改成去定时任务列表(进去之后不再自己换地址,/data 会再换成 /data/databases,
晚到的跳转能被盖住),等那一页落定、运行详情卸下再放行,断言走过的地址里从没出现过对比页;另加「立刻放行」:只换地址、
先不通知路由,把空当撑住再放行,找到基准的不跳、找不到的不弹提示。再加下拉里没有能换的运行时 409、422、缺基准 404 的
下一步,和本次记录不存在时换基准的位置不给重试。去掉实现后这些检查各自变红(两轮,共 8 项)。
2026-10-06 07:44:49 +08:00
ThearchyHelios f8ac8dc1d6 定时任务自动对比收尾:基准那一次不在终态或被删时不给对比、对比工件读不出来时触发历史照常打开;检查脚本按实际底色量对比度
- 触发历史的 compare:以前只看这一次的运行在不在终态。基准那一次被强制删除、失败后被继续执行时,对比页比不了,
  「对比上一次」链过去只会报错——基准一侧同样要在终态,否则给 null
- 对比工件读不出来(权限、磁盘出错)时记一条警告、给 null:以前 OSError 直接抛出,整页触发历史回 500。被改过
  (内容与哈希不符)的以前就给 null,这次补上用例
- check-schedules:页头的定时任务链接、触发历史的「对比上一次」改成量 WCAG 对比度(≥ 4.5),底色顺着祖先叠到
  不透明为止。以前比的是「字色不等于页头的底色」,页头本身透明,那样比永远成立;深色也补上同样的检查。另加一项
  署名的立即运行配长名字:署名照写、链接截断、页头不横向溢出
2026-10-06 07:43:01 +08:00
ThearchyHelios a4e0043985 审批质询(前端):划选原文浮出的「质询」挂在报告文档里,画布审批浮层里点它不再把浮层收掉
- 原来浮出的按钮挂到页面末尾(fixed)。画布节点上的审批浮层(canvas/NodeCard)在 document 上按捕获阶段听 pointerdown,按在浮层外面就收起:一点浮出的「质询」,浮层连同报告一起收掉,划选原文问不成
- 改成挂在文档里一个高度为 0 的定位锚点下面(absolute,坐标按锚点算),按下的位置就在审批卡里;挂在文档里会被限高滚动的报告框裁切,所以按可见范围摆:视口和每一层会裁切的祖先取交集,下方放不下放到选区上方,左右收进文档宽度(不把报告框撑出横向滚动),选区整个滚出可见范围时不留按钮
- check-inquiry 加一段:模拟浮层「按在外面就收起」的监听,点浮出的「质询」不算外面;报告框压矮、一句的第一行贴着框的底边时划选,按钮看得见(不被框裁掉)。两项都先确认在旧写法 / 去掉上下翻转时变红
2026-10-06 07:40:43 +08:00
ThearchyHelios 98eb9436a1 审批质询(前端)收尾:问答串的时间排序与焦点交接改稳,check-inquiry 的耗时按实测登记
- 问答串按提问时间排序改用 lib/format 的 parseServerTime(不带时区的服务端时间按 UTC 认,秒级时间戳照认),不再自己拼一套
- 焦点交接改成按「这一次提问」记:提交时焦点丢了才接到正在回答的那一条,回答回来、条数确实多了才播报并接到回答上;没问成(提问框带着报错重新打开)不抢焦点,列表重新取回来也不误报「已收到回答」
- 报告文档在有问答、开着提问框或正在回答时就取:回答引用报告已有出处时要靠它在报告里找到那一处,不再只在问答带句子时取
- check-all 的 ESTIMATE 里 inquiry 按四道并行的实测改成 22 秒
2026-10-06 07:34:26 +08:00
ThearchyHelios ddc95ccbad 证据面板显示核查状态:指标步骤的双盲复算一行,整句的反方审稿判断,遮罩列的输入只写「已遮罩」
指标步骤多一行双盲复算的结果:一致(带盲算值)、不一致(带盲算值和审核人选了什么,没选的照实说)、无法复算(带原因)、
已跳过(关闭了、口径卡上没有来自查询的输入、这个指标不在复算范围内)。结果都写成字,颜色只表达要不要多看一眼。
点开一整句时,反方审稿的判断复用审批卡上的展示(run/ChallengeSummary,只读它的导出),只列这一句,点开看反方的理由和查询。
取自遮罩列的输入,标签照查询表格里遮罩格的样子写「已遮罩」,输入来源里核对不一致时只说不一致、不写两边的值。
接口字段的类型就近写在面板里,不动 types.ts;界面文案放 EVIDENCE_TEXT。

check-evidence 加一节:六种双盲状态的文字和颜色、深浅色对比度、没复核过的不画;遮罩输入的标签、代入式、遮罩说明、输入来源;
整句面板的反方审稿判断、降档说明、点开取审稿记录看理由、没审到的句子不画、390px 不横向溢出。
2026-10-05 19:15:14 +08:00
ThearchyHelios 3dd5216af2 审批质询(前端):报告上的入口、问答串与提问框、回答渲染,审批卡与运行详情的挂法,check-inquiry 换成真检查
- run/Inquiry.tsx:质询的 store(列表按运行与报告缓存、一次运行同一时刻只有一条在回答、请求不随组件卸载作废)、ReportInquiry(问答按句子归拢、同一句下按时间排,进入时按列表接口恢复;就整份报告提问;正在回答的那一条)、提问框(显示被问的那句或划选的原文,Esc 关掉、焦点回到点开它的「质询」,Ctrl+回车提交,字数上限 1000、原文 500,409/422 照服务端的中文说明显示、问题留着)、回答渲染(数字的出处同报告:质询自己的查询点开按质询工件接口取快照、标出那一格;引用报告已有出处的交给页面在报告里打开证据面板;裸数字点状线)、查询列表(SQL、行数、截断、遮罩)、recorded 为假时醒目说明
- EvidenceDoc.tsx 只加入口:父组件传入 inquiry(是否可问与 approval_id)。每句结论后的「质询」平时宽 0、透明,悬停或焦点在这一句上时出现,只在焦点在这一句上时进 Tab 顺序,整份报告不多出一串 Tab 位;没有可点内容的句子,「质询」本身进方向键的顺序;触屏一直显示。划选原文浮出「质询」,原文按选区克隆、去掉徽标和小标签,证据面板里的字不算
- ApprovalReport.tsx:报告核对概况下面挂问答串,逐段证据带上入口;回答里引用报告已有出处时展开逐段证据、在那一处打开证据面板
- 文件所有权之外的两处最小改动(交付说明里写明):RunPanel.tsx 把待处理审批的 id 传给 ApprovalReports,回答期间批准 / 驳回停用并说明原因;pages/runs/EvidencePane.tsx 对封存了的探索运行给入口并挂问答串(判断用 Inquiry.tsx 导出的 inquiryOpen),正式运行不给
- 预览用例 dev/fixtures/inquiry.tsx 与夹具 inquiry.json(报告文档、回答文档由后端 build_catalog + compose_doc 真实组装,虚构数据);check-inquiry.mjs 用 page.route 假接口逐项断言入口、请求体、回答期间停用、问答串恢复、数字取质询工件、报告出处、recorded 为假、409/422、已处理审批与正式运行封存后无入口、390px 与深浅色
2026-10-05 19:13:07 +08:00
ThearchyHelios 59f1868dac 可验证报告的运行结果按封存范围内真正截止的那条结束事件核对
早期运行先失败、经继续运行跑到成功的,封存范围里留着中途那条运行失败,成功结束的那条在范围外(run.finished 落库之前封存)。
以前 checkMeta 拿范围内最后一条结束类事件去对,把运行结果改成「已失败」也标「已核对」。现在只认范围内最后一条、且是结束类
事件的那一条;没有这样一条时,早期运行成功结束照旧说无法核对,别的说法写明那条失败之后运行又继续了、没有事件印证,判不通过,
页面顶上显示「—」而不是把文件里写的当成核对出来的。

样本页加一份 continued(先失败、继续运行到成功的早期运行),check-bundle 断言它原样时无法核对、运行结果改成已失败或已取消时不通过。
2026-10-05 19:06:32 +08:00
ThearchyHelios 4b52cccc75 证据接口带上核查状态,指标步骤不再露出遮罩列的值
核查状态:口径卡指标那一步多一个 dual_check(一致、不一致带审核人的选择和盲算值、无法复算带原因、跳过带原因),
读双盲复算节点封存的产出和台账条目,按台账里记的指标集工件认它复核的是口径卡的哪一次结果,直通的按画布上它复算的卡
和那一刻卡的最后一次结果认;句子多一个 challenge(判断、节点、审稿记录、实际生效的处置、报告名),只认审的就是正文
这一份报告文档的,记录没存上时按画布上审的报告和它那一刻的文档认、判断取产出里列的那几句。没有双盲复算、反方审稿的
运行没有这两个键,老运行的答复一字不差。

遮罩:以前只有查询步骤的结果窗口遮着,指标步骤的输入标签和代入式照样写着原值。现在 cell() 的格、Agent 字段按定位里的列认,
vars.res.rows[0][2] 这种按位置取自查询结果的标量顺着取值链认出是哪一列(recompute.positional_cell),遮的列和查询步骤
同一套;取自遮罩列的输入值写「已遮罩」并带上是哪几列,代入式里那几处同样写「已遮罩」,遮罩列进 redacted.columns。
推演用同一个认法,按位置取自遮罩列的输入同样不给值、不推演,证据面板和推演说的一致。
2026-10-05 19:02:52 +08:00
ThearchyHelios a7333368f1 审批质询测试补全:封存之后的追问途中运行被继续了不写进记录、/verify 接口核对一致、批准和驳回都在回答期间被拦;接口说明写明质询工件的形状
- 失败的探索运行封存后追问,回答途中被继续运行:回答照样交回,recorded 为假,继续运行重新封存后核对一致
- 停在审批时质询、批准、封存之后,经 /api/runs/{id}/verify 核对,封存范围盖住这条质询
- 质询期间批准、驳回都回 409 inquiry_busy
- api/inquiry.py 的说明补上质询工件的返回形状 {id, content, masked[, mask_note]},以及回答文档原样给
2026-10-05 19:00:36 +08:00
ThearchyHelios 2db83a69e8 审批质询:只有空串算没指明句子、审批卡,0、false 这类照样报格式不对;结果相同的两次查询共用一份快照,引用列表里只记一次 2026-10-05 18:58:41 +08:00
ThearchyHelios 863b0b2894 定时任务前端:触发历史加「对比上一次」,运行详情页头的「由定时任务「X」发起」改成键盘可达的链接
- 触发历史:服务端给了 compare 的那次触发,在运行链接前加「对比上一次」,链到对比页(本次是这次触发的运行、
  基准是服务端自动对比时取的同一任务上一次),带上来历让对比页写「默认基准:同一定时任务的上一次运行」。悬停写
  各类指标的个数,和 Webhook 通知那一行同一个写法(三类总写、其余有才写、两边都没有指标时不写一串 0 个),读屏
  当说明念;只有个数。compare 为 null、老服务端不给时不显示
- 运行详情页头:定时任务发起的运行,「谁发起的」那一段换成到 /schedules/:id 的真链接(Tab 到得了、回车能开,
  有焦点环)。到点发起的(署名是「定时任务:X」)整句换成「由定时任务「X」发起」,不再写两遍;有人署名点了
  立即运行的,署名照写、后面接「来自定时任务「X」」。名字取定时任务现在的名字,取不到用署名里记的;长名字截断,
  全名在悬停里。记录页「定时」标记的说明同步改成指向这里
- types.ts 定时任务那一段加 ScheduleFireCompare 和 ScheduleFire.compare;文案进 SCHEDULE_TEXT
- check-schedules:触发历史的对比链接(地址、悬停的计数、只在有 compare 的行出现、Tab 到得了、回车打开对比页)、
  运行详情页头的链接(现在的名字、真链接、不重复署名、Tab 到得了且有焦点环、回车去定时任务、署名的立即运行、
  手动运行没有、长名字截断不撑宽、浅色可读),390px 深浅色下对比链接在屏幕里、看得清
2026-10-05 18:58:25 +08:00
ThearchyHelios f62d6bf9d6 审批质询测试:署名照请求头记;写过的核查设置和花费账在测试结束时清掉,不留给同一进程里后面的测试文件 2026-10-05 18:57:57 +08:00
ThearchyHelios 9eeb11d29e 双盲复算写目录的预告和真写逐字一致:被目录挡下(已确认、驳回过、和已有条件合不起来)的那一边也带上写到哪张表哪一项、本来要写什么和原因;几个指标落到同一项上时,preview_joint 按真写的办法(归拢、拿掉驳回的、对目录)把每种选择组合算一遍放进对照工件的 catalog_joint,组合太多的那一项不预告;真写的日志 written 带上写进去的值。对照工件里盲算的输入另带 rationale_doc(核查 agent 组装的理由文档,裸数字已标出);补图级测试,按审批卡的认法断言预告与实际写入一致 2026-10-05 18:56:04 +08:00
ThearchyHelios e6dfe18c83 审批质询自查修正:封存后的追问不一定来自审批人,提示词改成中性的「提问人」;告诉 agent 哪几列设了遮罩;组装回答出错照样记一条
- 任务里列出可查询的数据源现在设了遮罩的列,让 agent 不写出原值(系统的替换仍兜底)
- 回答原文没能组装成文档时不交出原文(引用没换成值、遮罩没做),记成失败,查过的和用量照记
- 第二次读状态时运行已被继续:不按旧封存追加,回 409
- 不指明句子、不在审批卡上问时,unit / approval_id 写空串等同于 null
- 只列有值的报告指标和运行输入:没有值的引用了也解析不了
2026-10-05 18:54:54 +08:00
ThearchyHelios 7df224106d 审批质询(后端):运行停在审批时,审批人针对报告里的一句话提问,只读 agent 现查现答,问答写进运行、随运行封存
- engine/inquiry.py:开放条件(停在审批且问的是待处理的那张卡;或已封存、核对一致的探索运行,追加在封存之后;
  正式运行封存后、设置关闭、还在执行一律 409);同一运行同时只答一条(进程内登记);回答交给 run_verify_agent
  (不传 emit,数据版本取运行记录,上限和模型按核查设置),任务里给被问的那句、照 judge.prepare 取的证据摘录
  (遮罩照旧、原报告编号标明)、选中的原文和问题,数据源取这次运行用过的查询工具;回答由 compose_doc 组装成文档
  落工件,数字可以引用自己的查询格子或报告已有的指标、运行输入,裸数字被标出;引用到遮罩列的格子渲染成「已遮罩」,
  回答正文和查询清单里出现的遮罩列的值换成「已遮罩」;写入走 append_events,运行在回答期间变了就不写、照实说明,
  触顶和失败照样记一条
- api/inquiry.py:POST 提问、GET 列表(按报告、句子筛选)、GET 质询工件(只认质询引用过的,遮罩照证据面板);
  输入不合法回 {detail, field}
- api/runs.py:质询正在回答时,审批回复(批准 / 驳回)和继续运行回 409 inquiry_busy,拦在记签批人之前
2026-10-05 18:51:51 +08:00
ThearchyHelios 528b70af0d 推演重算与口径卡共用取整函数,补推演两处测试缺口
metrics.py 抽出 round_metric(只取整浮点、小数位须是整数),口径卡计算、代入式复算、推演重算和变化量都用它:
以前推演在 recompute.py 里另写一份取整,靠「真卡重算一致」的测试兜着,口径卡哪天换了取整方式,推演会对着同一张卡算出另一个数。现有的真卡重算一致测试保留。

补两处测试缺口:一个输入既嵌在下标里、又直接参与计算时,包着它的引用给了新值,排除行后它仍说不准(_doubt 里 moot 的那一支);
决定取哪一格的单格照给行段,勾掉它确定是排除后无法计算。两处都做过去掉实现、测试变红的验证。
2026-10-05 18:50:34 +08:00
ThearchyHelios 375f7165e5 反方审稿说清「根本没反查」和「到底降不降档」:产出和审批卡的概况加 unreviewed(模型不可用、触顶、数据源不在了等没能反查的句数,触顶但按查到的收了尾的不算)和 degrades(按降档处置、又接在带出具契约的成果节点上游时才为真,侧枝上、成果节点没带契约时为假);升级前的产出不带这两项,审批卡照旧规则说 2026-10-05 18:48:35 +08:00