ThearchyHelios
|
b6a33b4ee2
|
合入期 5 前置修复 K3b:工具边界遮罩收口——分析出意外、(表达式).* 展开、把 SQL 或表名写成字符串参数的函数、记着别的会话 SQL 的系统视图与 SHOW / EXPLAIN、当一张表用的 VALUES 读到遮罩列时整份遮;按值遮只换文字格、数值证据原样并记下换过的格子;分档标签一档一行时照常显示;交给核查 agent 的证据摘录先遮,反方理由加最后一道关;长 CTE 链的分析有缓存与步数上限
|
2026-10-12 13:12:10 +08:00 |
|
ThearchyHelios
|
9344cb9232
|
M3 复核修正(第 2 轮):紧挨着核对过的数字的字按码点分类收紧,列表缩进有上限、表格只排有格的列
复核发现「紧挨着」只认一部分字:隔着 DEL、U+FFF0 这类显示时不占位置的字补一位数,或者前面加一个 U+2010 这类和负号
长得一样的横线,读的人看到的数已经变了,页面仍「全部通过」;伪造的列表缩进写成十万级,核对通过的数字被挤出屏幕仍判
通过。
- 紧挨着的字按码点分几类(kindOf):数字;负号(横线类标点全算、波浪形的除外,减号类符号,Unicode 易混字符表里映射到
「-」「ー」的字,在 Chrome 常用字体里逐个画出来是一道横线的字);分隔(半角逗号、句点和易混字符表里长得一样的窄标点,
全角的不算);不占位置的格式字符、默认不显示的字、变体选择符照旧跳过;控制字符(制表、换行等空白除外)、未分配和私用
区的字、孤立的代理项、组合附加符号、可选连字符、发丝空格、对象替换符和在 Chrome 里量出来几乎不占宽度的几个字算「说不
准」:隔着它们照样往外找数字、负号,找不到的也判无法核对、原因另写。只跳过不标记的话,叠在空格上的组合横线、Chrome
画成短横的 C1 控制字符照样能在数字前面显示出一个「负号」
- 同一句里有从右往左书写的文字(希伯来文、阿拉伯文这类)和方向控制字符一样判无法核对:Chrome 里实测,一个希伯来字母
就能把逻辑上在数字后面的「5」显示到数字紧前面(读作 574,613.65元),按字的先后看不出来
- 代理对只在真成对时拼成一个字:不成对的前半不再把后面的「1」吞进去;分在两个文字片段里的一对页面上照样显示成数学字母
区的数字,也拼起来看
- 列表缩进最多显示 8 级,负数按 0 级:十万级的缩进把数字挤到 140 万像素以外,负的连滚动都滚不到;表格只排有格的列:列号
写成十万时不再建几十万个空格、把那一格挤到右边,写成 2^32 时整段核对也不再出错。核对和显示共用 listItems / tableCells
- 真数据(两份数据目录里 39 份报告文档、1591 处数字和取值、45 个列表、70 张表格)里新旧规则都一处没有触发
- 测试:test_bundle_shown.py 补 DEL、U+FFF0、U+2010、U+2013 等紧挨着的写法,说不准的字、从右往左的文字、缩进和列号的
用例,逐项去掉实现都会变红;check-bundle 在经营月报上补四种紧挨着的伪造(从右往左那条先量出「5」确实显示在数字紧前
面),缩进写成十万级和负数(宽屏、窄屏)、表格列号写成十万的伪造
|
2026-10-12 10:52:09 +08:00 |
|
ThearchyHelios
|
ab2173c665
|
M3 复核修正(第 1 轮):单位带尾随空白的真报告不再被判不通过;运行输入也核对显示文字;出处面板的长整数一位不差;核对通过的字要原样显示在正文里
- 显示文字比对两边都只去首尾空白:口径卡单位写成「元 」(单位输入框不去空白、指标节点照存)时,服务端照原样接在数
后面,正文是「74,613.65元 」。以前只去正文一边,原样导出的真报告被判不通过,出处面板里两行字看起来一模一样,读者
会以为文件被改过
- 运行输入([[i:…]])不随文件附带,照旧无法核对;正文显示的字拿引用的值按服务端的写法(不分组、不接单位、可带换算)
重新渲染比对,只改显示文字(统计周期、地区这类)的判不通过
- 出处面板:DECIMAL 落成数字文本的格子,「快照里的值」照快照原文写;快照那一行的数照 JSON 原文写。超过 2^53 的订单号
不再在「通过」的条目里和一位不差的「引用的值」并排、自相矛盾
- 正文的排法核对和显示共用一套函数(unitPlan / flowsOf / checkLayout),读的人看到的数要就是核对过的那个:伪造的链接
把数字塞进不显示的链接地址时,整句按未排版的原文显示;正文里根本不显示的(分隔线里、表格行列之外的格)服务端导出时
不会出现,判不通过;紧挨着补数字、负号(隔着零宽字符、显示时藏起来的排版标记也算)或同一句里有方向控制字符的判无法
核对,两个数之间的区间连字符照常通过。正文按片段本身找核对结果:文字片段冒用数字的 id 借不到「通过」(以前会显示成
绿色下划线的可点数字)。真数据 71 份报告文档、3266 处已解析的数字和取值里,新规则一处都没有触发
- 「无法核对显示文字」的几条原因改成读者看得懂、知道怎么办的说法,不再提 BigInt、正则、ASCII
- check-bundle:真导出上断言没有「无法核对显示文字」(显示规则漏了真实写法时这里先报);订单号连同快照那一行一位不差;
新样本页 formats-unit(单位带尾随空白,原样导出全部通过);经营月报上链接藏数、补一位数、整段改成分隔线、文字片段冒用
数字的 id 四种伪造各自断言
|
2026-10-07 01:34:32 +08:00 |
|
ThearchyHelios
|
169c500526
|
K3b 复核修正(第 1 轮):数值格按位置认、(表达式).* 带外括号也整份遮、同名 CTE 按作用域认、认不全的写法名单合一、整份遮不再把每一格收成遮罩值、证据摘录分段遮、反方最后一道关只看正文
- 同名列(回退):column_types 按列名记,同名的几列只留得下后一列的类型,文字的备注被当成数值列,号码不再按值换、
原样交给模型并落库。现在只在列名唯一时按列类型认数值列(_typed_numbers),同名的按格子本身认:整数、小数才算数,
写成字符串的数按文字照换、记进 masked_cells;列名唯一、列类型是 number 的 NUMERIC / DECIMAL 字符串照原样
- (表达式).* 外面套了括号、起了别名(((p.card).*)、(p.card).* AS x,Postgres 实测照样展开):以前只遮第一列。选出项
先去掉外括号、别名再认(_unwrapped),(s).*、(s.*) AS x 照旧当 s.*
- WITH 里和数据源里的表同名的一段(WITH sales AS (SELECT * FROM sales WHERE …)):不带 RECURSIVE 的一段看不见它自己和
排在后面的段(_scoped_cte),同名的按数据源里的表认;以前认成它自己,* 展开什么都不带出,整行引用的号码原样交出
- 认不全的写法:和可验证报告合成一份名单(masking 的 OPAQUE_SQL、INDIRECT_FUNCTIONS、INDIRECT_NAMES,bundle 引用后另加
系统 schema),补上 MySQL 会执行的注释、U&"…"、pg_stat_get_activity、逻辑解码、MySQL 的 column_statistics /
general_log / PROCESSLIST / performance_schema、MariaDB 的 column_stats、Oracle 的直方图 / *_tab_columns / V$SQL 一族;
去掉注释再认一遍(函数名和括号之间夹注释);去掉 DuckDB、SQL Server 的函数(query 误伤同名 CTE、字符串);没有 * 的
一支选出项和结果列数对不上的、Postgres 解析不了的整份遮
- 整份遮只收确定取自遮罩列的那几列的值(_derived_masks 的 collect,报告快照收值同一规则):以前每一格都收,区域名、
列名在同一次核查里处处被换掉,封存的 SQL 也被改写。快照另记 masked_whole,格子引用照实说写法认不全
- 证据摘录分段遮(inquiry.ExcerptMask,judge.prepare 的 mask 取代 kinds):SQL 照封存 SQL 的办法换,范围阈值、LIMIT 照
原样,和遮罩列做等值、IN、LIKE 比较的字面量不论收没收到都换;格子逐格遮,数值格照原样;质询把被问的那句(连同表格)
当作已经摆在眼前,摘录、查询工具、回答里都不换
- 反方审稿:理由文档的目录列名照快照换(同质询的 _renamed_entry),agent 自己 SQL 里照原样留着的阈值、行数在正文里
不换(_shown),最后一道关只看正文和原文,不再把 agent 起的列名、阈值当成露了遮罩值整句改判
补测试:同名列一文一数、DECIMAL 字符串(含端到端引用取值),外括号 × 复合类型 / 记录函数 / 匿名 ROW × 最外层 /
UNION 前后支 / 和 * 写在一起,同名 CTE 四种写法和 RECURSIVE 对照,十七种认不全的写法和三种不该误伤的写法,整份遮后的
收值与封存 SQL,Postgres 解析不了的整行引用,摘录的阈值、数值格、IN / NOT IN 字面量、被问那句(反方、质询各端到端),
反方别名里的阈值(经受住、被推翻各一条)、找某个值的别名、正文里的阈值。逐项去掉实现,对应的测试都变红。
改了文件所有权以外的 bundle/build.py:_OPAQUE_SQL、_INDIRECT_READS 改为引用 masking 的同一份名单(另加系统 schema,
覆盖面不小于原来)。
|
2026-10-07 01:09:36 +08:00 |
|
ThearchyHelios
|
6ff9d7155b
|
M3 可验证报告核对正文显示的字:按服务端的显示规则把引用的值重新渲染、逐字比对
验收发现:页面只核「引用的值 = 口径卡的值或快照的格子」,不核正文显示的字。只改显示文字(74,613.65元 改成
84,613.65元、华南改成华东)、引用值不动、重算全部哈希的伪造页照样「全部通过」,读者看到的数和核过的数不是同一个。
- verifier.js 移植 engine/evidence.py 的 render_number / render_cell:千分位、不分组、小数位(含负数位)、比率显示成
百分数、万 / 亿换算、pct、int、.N、单位后缀、负数、0,文字压成一行(按 Python 的空白),竖线换成 ¦,ISO 日期时间按
文档记下的单元格显示规则版本。数照 Python 的 Decimal 算:系数用 BigInt,ROUND_HALF_UP,浮点取最短写法,整数取 JSON
原文(新写的 numberTokens 读出每个数的原文,超过 2^53 的订单号一位不差)
- ⑤ 在引用的值对上之后再核显示文字(只去掉首尾空白):对不上判不通过,原因点名「正文显示「X」,引用的值是「Y」」,
数字另写按显示规则应显示的字;渲染不出来的(不认识的换算、显示规则版本、对象和列表、非 ASCII 数字、缺 BigInt 的
浏览器)判「无法核对显示文字」,不判通过。出处面板改成列出按显示规则应为的字,一致时注明,页脚说明同步
- 在 node 里载入时(没有 document)交出核对用的纯函数,tests/test_bundle_shown.py 拿服务端的渲染逐条对照约八万个
组合,并在 node 里整份核对:经营月报样本每种格式原样通过,只改显示文字的伪造逐个变红并点名
- 样本页加经营月报(formats);check-bundle 在真导出上只改一个数字(有文字取值时也改一个)的显示文字,在经营月报上
改文字取值、数字、换算成万的口径卡引用,各自变红并点名,原样导出照旧全绿
|
2026-10-07 00:17:22 +08:00 |
|
ThearchyHelios
|
e7fb8f6c1c
|
可验证报告复核修复(第 2 轮):SQL 解析不了的快照,口径卡同样整张只给 id;整行引用补全函数记法、按表函数的先后认;拒绝名单补别的会话的 SQL 原文
复核查出三处:口径卡和快照对 SQL 解析不了的结论仍不一致;整行引用的函数记法名单不全,表函数参数里「先按列认」不看先后;
拒绝名单里「别的会话的 SQL 原文」一类不全。逐条修:
- 口径卡和快照按同一个结论判(复核的第一条):SQL 每种读法都解析不了时快照只给哈希,卡这条路以前退回按 SQL 认遮罩列的
那一套(inquiry._derived_hidden)。那一套解析不了时只看 SQL 里写没写着遮罩列,没写就只认遮罩列本身,卡上取自整行的值
照样整张嵌入。例如 PG17 起的 JSON_QUERY(to_jsonb(m), '$.*' WITH WRAPPER) AS tel,以及 ORDER BY … USING < 这类 sqlglot
读不了的写法,号码就这样原样进了文件。现在 _derived_columns 对不是合并查询的快照,没有一种读法读得通时整份的列都算,
整张卡只给 id。没有 SQL、SQL 是空的也一样处理:这时快照同样只给哈希。合并查询照旧不看 SQL。
- 整行引用:
- 函数记法的名单补上 record_out、record_send、any_value、json_agg_strict、jsonb_agg_strict。另照 PG 18 的 pg_proc
逐个对过,补上 max、min:m.max 就是 max(m),交回最大的那一整行,复核没点到,本地实测号码在里面。补了 max、min 之后,
写了表名的名字同样先按列认:派生来源明写出了叫 max 的列,t.max 就是那一列,按地区取最大值的子查询不受影响。数据源里
的表有哪些列这里看不到,碰巧叫 max、min 的列宁可多挡。
- 没写表名的名字写在表函数的参数里时,「先按列认」只看排在这个表函数前面的派生来源(_holder)。
FROM members m, jsonb_each_text(to_jsonb(m)), (SELECT 1 AS m) s 里,s 对函数不可见,m 是整行,以前按列认,快照照常嵌入。
没有改成「表函数参数里一律不按列认」:排在前面的派生来源明写出了同名列时,那确实是列,补了对照用例。
- 拒绝名单(不点列名也读得出表里内容的写法):
- 别的会话的 SQL 原文:Postgres 的 pg_stat_get_activity、pg_stat_get_backend_activity、pg_stat_statements、
pg_prepared_statements(asyncpg 连接池里的连接留着前几次查询的原文,本地 PG 18 实测);MySQL sys 库的 session、
processlist、innodb_lock_waits、schema_table_lock_waits 及各自的 x$ 版本(只认这几张,Oracle 常写的 sys.dual 不受
影响,补了对照用例),企业版的 audit_log_read;Oracle 的 V$OPEN_CURSOR 和审计记录(*_AUDIT_TRAIL、
UNIFIED_AUDIT_TRAIL、AUD$、FGA_LOG$)。
- 复核脚本里同样照常嵌入、和已拦的写法读的是同一份数据的,顺手补上:pageinspect 按索引名读页的 bt_page_items、
pg_walinspect 的 pg_get_wal_block_info、SQLite 的 readfile、Oracle 直方图和列统计的底表 histgrm$、hist_head$、
MariaDB 的 column_stats。大对象(lo_get、pg_largeobject)里存的不是表里的数据,没有加。
测试:口径卡补 SQL 解析不了(三种 sqlglot 读不了的真实写法)、没有 SQL、SQL 为空的用例,卡上取 tel 和 spend 都只给 id;
另补函数记法 record_out、表函数后面同名派生来源两种整行写法。查询快照补七个函数记法、WITH 里 * 加函数记法、两种表函数
先后的写法,以及二十项拒绝名单。对照组补派生来源明写出 max 列、表函数前面的派生来源明写出同名列、sys.dual,这三种照常
附带。夹具里的 SQL 都在本地 PG 18.6 上跑过,结果和用例说的一致。逐处去掉实现,相关测试都变红:
- 解析不了的退回那一套 4 项,没有 SQL 的 1 项;
- 名单不补 9 项,只去掉 max、min 2 项;
- 写了表名的不先按列认 1 项;
- 表函数参数不看先后 3 项,一律不先按列认 1 项;
- 别的会话的 SQL 不补 14 项,原始数据、统计信息不补 6 项;
- sys 整个拦掉时 sys.dual 对照变红。
后端全量 10238 项通过、11 项跳过;check-all bundle 183 项通过;check-copy 通过。
|
2026-10-06 19:21:23 +08:00 |
|
ThearchyHelios
|
8c0c3b8eeb
|
可验证报告复核修复:遮罩源上的查询快照再堵几条带出号码的路,口径卡和快照按同一个结论判
复核查出,上一轮放开「没碰遮罩列的快照照常附带」之后,有几种写法 SQL 里不写 phone、结果列名也对不上,结果里照样是
号码,快照原字节和查询事件的预览会随文件附带出去。这一轮逐条堵上:
- 整行引用认全(复核的两个阻断项):Postgres 的 FROM 里的表函数不写 LATERAL 也看得见前面的来源,
`FROM members m, jsonb_each_text(to_jsonb(m))` 这类逐列画像的写法(逗号、CROSS JOIN、JOIN … ON TRUE、LEFT JOIN、
ROWS FROM、不带别名的 UNNEST、套在 FROM 的子查询里)以前按看不见算,整行引用认不出。现在 FROM、JOIN 里只有真的
子查询和 WITH 里的一段看不见同一层;括号括起来的一组连接((members m CROSS JOIN f(m)))也摊开按同一层认。另外认
函数记法 m.to_jsonb、m.row_to_json(等于 to_jsonb(m)),自己建的函数认不出。
- 不点列名也读得出表里内容的写法(_INDIRECT_READS):SQL、表名写在字符串里交给函数执行或整表导出(table_to_xml、
query_to_xml 一族、ts_stat、crosstab、DBMS_XMLGEN、XQuery 的 ora:view),统计信息里的采样值(pg_stats、
sqlite_stat4、column_statistics、Oracle 的直方图和 *_tab_columns),按页按文件读的原始数据(get_raw_page、
pg_read_file、LOAD_FILE、sqlite_dbpage、逻辑解码),别的会话的 SQL 原文(pg_stat_activity、general_log、V$SQL),
系统 schema(pg_catalog、information_schema、performance_schema)。SQL 原文里出现就只给哈希;函数名要跟着左括号,
列名碰巧叫 crosstab、pg_status 的不受影响。
- 这次运行里查到过的遮罩值写进了别的查询的字面量(模型拿看到的号码去查别的表):导出时收齐封存范围内每份快照里
取自遮罩列的格子(inquiry._Secrets 的按值认得出的写法),只看 SQL 的字面量,碰上就只给哈希、查询事件也只给哈希。
这次运行里没查到过的值(提问人写进问题的)认不出。
- MariaDB 会执行的注释 /*M! … */ 和 /*! … */ 一样按语法树认不准处理。
- 口径卡和快照按同一个结论判:快照因列名表、整行引用、不照原名展开的 *(UNION 一支里按位置对上列名的、装进一列
的)、吃进遮罩列的表函数、语法树认不准或不点列名也读得出内容而只给哈希时,卡上取自这份快照任一列的输入都按遮罩列
算,整张卡只给 id。以前卡这条路只认改了名字的遮罩列,快照只给哈希,卡上记着的号码却原样进了文件。最外层直接写的 *
照原名展开,按名字认就够,卡照常嵌入。
- check-bundle 的 masked-source 样本点数字之前先看有没有核对通过的数字,没有就记一项不通过、不去点:以前点空了要
等满 30 秒抛错,同一节后面的 nan、stray 样本都不跑了。换回改动前的 build.py 实测,现在只多记两项不通过,后面照常跑。
有意没改的一条:SQL 写到遮罩列、结果里却没有号码的(COUNT(DISTINCT phone)、phone IS NOT NULL)照旧只给哈希,比规格
的四条更严。FROM 里的表函数吃进遮罩列时(unnest(ARRAY[phone]))它交出的列取自哪一列认不出,只能看 SQL 写没写到;
补了这一例的测试,说明写在 _untouched 和测试里。
测试:新增整行引用(表函数、括号里的一组连接、函数记法)、不点列名的读法、字面量里的遮罩值、MariaDB 注释、口径卡
七种认不出来历的写法各自的用例,以及对照组(列名像函数名的、表函数只吃没设遮罩的列的、括号连接按名字取列的、最外层
* 的卡)。合并查询那一条判断补了只带认得的键的夹具,结果列名那一条补了按 SQL 认遮罩列的那一套什么都没认出来时的
用例,两条现在都能单独证明——上一轮提交说明里「每一条规则都做过去掉实现测试变红」对这两条不成立。这一轮 15 处改动
逐一去掉实现,相关测试都变红。
|
2026-10-06 18:33:02 +08:00 |
|
ThearchyHelios
|
02e9bcd908
|
可验证报告:理顺 _contained 的说明(派生来源的列外层只能按名字取,或者再用一个 * 展开,那个 * 照样要过这一关)
|
2026-10-06 17:15:13 +08:00 |
|
ThearchyHelios
|
8ede152b6f
|
可验证报告:口径卡取的列是 SQL 里改了名字的遮罩列时,整张卡同样只给哈希
口径卡上记着每个输入的值和代入式,有输入取自遮罩列的整张卡只给哈希;但以前只按列名认:查询写 phone AS tel、经子查询
或 WITH 转一道、套个函数,卡上取 tel 那一格就是号码,卡照样原样嵌进要发给别人的文件。现在那几列算不算遮罩列另按 SQL
认改了名字的(_Store.hidden → _derived_columns,用 inquiry._derived_hidden,和质询、双盲复算同一个认法;SQL 按每种
读得通的读法各认一遍合起来,都读不通的写着遮罩列就整份的列都算,出错时整份的列都算)。同一条查询里没取自遮罩列的
列照常嵌入。新测试覆盖别名、子查询、WITH 加函数三种改名,以及没改名的列、认的过程出错;每处都做过去掉实现测试变红的
验证。
|
2026-10-06 17:11:41 +08:00 |
|
ThearchyHelios
|
02883dea7b
|
可验证报告:查询快照只给哈希时照实说明原因,样本页和浏览器检查补「遮罩源上的汇总查询可核对」
核对页对只给哈希的查询快照原来写「含遮罩列,未随文件附带」。现在没碰遮罩列的快照照常附带,只给哈希的是这条查询
用到或可能用到设了遮罩的列(条件里写到的、解析不了的也算),原文改成「这条查询用到或可能用到设了遮罩的列,快照未随
文件附带,只能核对到哈希」;口径卡的说法不变。核对逻辑不变,只是按工件种类挑说法(verifier.js 的 maskedQuery);
内联脚本的 CSP 哈希由 render_html 按脚本现算,不用另改。顺手改正 verifier.js 开头一句过时的注释:口径卡现在会因遮罩
只给哈希,导出时不会出现的是报告文档标着遮罩。
tests/bundle_samples.py 加样本页 masked-source:会员库设了号码遮罩(查询当时记下了、数据源现在也设着),报告引用会员
按地区汇总的查询和选出了号码的那份。check-bundle 断网打开它:汇总快照在 ③ 通过、引用它的两个数字在 ⑤ 通过、点开看得
到汇总的 SQL 和被引用的那一行;选出了号码的快照和引用它的数字无法核对并写明原因;总览「可核对的项全部通过」,页面里
找不到号码。另在这一页上篡改:汇总快照改一个字节 ③ 变红,改它的数字的引用值并重算全部哈希 ⑤ 变红。base 页上的原因
文案跟着改。test_bundle_build 守住样本页的形状。
|
2026-10-06 17:11:41 +08:00 |
|
ThearchyHelios
|
faf21894a3
|
可验证报告:数据源设了遮罩时,能证明没碰遮罩列的查询快照照常随文件附带
以前只要查询当时记下了数据源的遮罩列,或者数据源现在设了遮罩,整份快照就只给哈希——哪怕这条查询只按地区汇总了
金额。数据源里只要有一列设了遮罩(客户手机号),报告里引用查询格子的数字就全成了「无法核对」,对外几乎没法核。
现在 build._untouched 全部满足才嵌入,任何一条不满足、判断过程出错都照旧只给哈希:
- 认得这份快照:数据源查询工具落的那种、哈希对得上;不是合并查询;没有不认识的键(以后核查 agent 在查询时就遮过、
另记下遮了哪些列的快照,照现有规则只给哈希);
- 结果的列名对不上遮罩列;
- SQL 原文里没写到遮罩列,条件里、COUNT 里也不行:SQL 随快照一起附带,WHERE phone = '…' 的字面量就是遮罩值;
MySQL 会执行的注释、Postgres 的 Unicode 转义名字这类语法树认不准的写法也不行;
- SQL 解析得了(不知道是哪种库,按每种支持的库的读法各解析一遍,读得通的每一种都要过关),没有认不出结果里哪一列
取自哪一列的写法:列名表、整行引用、可能展开出遮罩列的 *(展开了数据源里的表,又不在只按名字往外传的派生来源、
EXISTS / IN 子查询里);按 SQL 认遮罩列的那一套(inquiry._derived_hidden,双盲复算、质询同一个)也认不出哪个
结果列取自遮罩列。
查询事件(tool.end)的规范字符串跟着快照走:快照随文件附带的,事件也带内容。新测试覆盖按地区汇总(查询时记下的、
数据源现在设的遮罩各一种)、WITH / 子查询 / LATERAL / EXISTS 里的 *、反引号,以及选出遮罩列、别名、子查询、CTE、
SELECT *、函数包着、只在条件里、整行引用、列名表、解析不了、改过的、不认识的键、合并查询、判断出错;每一条规则都做过
去掉实现测试变红的验证。
|
2026-10-06 17:04:45 +08:00 |
|
ThearchyHelios
|
b080302e77
|
可验证报告复核修正(第 1 轮):只给 id 的遮罩工件,服务端的文件和 id 对不上的标 mismatch、解析不出来的标 unparsable,核对页对不上的判不通过、解析不出来的照实说认不出是否含遮罩列
上一轮让被改过、解析不出的口径卡不再原样嵌入(号码不进文件),可这样一来它在页面上和正常的遮罩卡一模一样:「? 无法核对 含遮罩列,未随文件附带」,总结论从「有 1 项不通过」变成「可核对的项全部通过」,篡改的证据丢了;截断的卡服务端其实认不出输入,却被说成「含遮罩列」。现在 _Artifacts.add 对只给 id 的遮罩工件(口径卡、查询快照都算,带遮罩的快照被改过原来就有同样的问题)照实带上服务端看到的:store.intact 为假标 mismatch,解析不出对象标 unparsable。verifier.js 在遮罩分支认这两个标记:mismatch 判不通过,原因「导出时服务端的这份文件与工件 id(哈希)不一致,可能被改过;按含遮罩列处理,未随文件附带」;unparsable 是正常的无法核对,原因「导出时服务端的这份文件无法解析,认不出是否含遮罩列,按含遮罩列处理,未随文件附带」,引用它的数字跟着用这句。pytest 补被改过、截断、不是对象、哈希对得上却解析不出的卡和被改过的遮罩快照;check-bundle 在 masked-card 样本上补两条篡改检查。
|
2026-10-06 13:43:04 +08:00 |
|
ThearchyHelios
|
eccde61c05
|
可验证报告里被改过、解析不出的口径卡不再原样嵌入:遮罩按卡上记的输入认,不看哈希
- bundle/build.py 的 _Store.card_masked 以前先看哈希:服务端的卡文件被改过(哈希对不上)时当它没有输入,
不算带遮罩,_Artifacts.add 随后把原字节 base64 嵌进页面,卡上记着的遮罩列号码进了文件;解析不了的卡同样原样
嵌入。这和同一文件里快照的做法相反(content 不看哈希,读不出来的快照按带遮罩算)。现在卡按解析出来的内容认
遮罩,不看哈希;读得出字节、解析不出一张卡的(截断的 JSON、不是对象)认不出输入,整张按带遮罩算、只给 id。
改过但没有遮罩列的卡照旧原样嵌入,浏览器自己算出哈希对不上。
- 补用例:改了口径版本、哈希对不上的卡只给 id、页面里没有号码;改过但不带遮罩列的照常嵌入;截断的 JSON、
不是对象的卡只给 id。恢复成先看哈希时这三条变红。
|
2026-10-06 12:13:49 +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
|
59f1868dac
|
可验证报告的运行结果按封存范围内真正截止的那条结束事件核对
早期运行先失败、经继续运行跑到成功的,封存范围里留着中途那条运行失败,成功结束的那条在范围外(run.finished 落库之前封存)。
以前 checkMeta 拿范围内最后一条结束类事件去对,把运行结果改成「已失败」也标「已核对」。现在只认范围内最后一条、且是结束类
事件的那一条;没有这样一条时,早期运行成功结束照旧说无法核对,别的说法写明那条失败之后运行又继续了、没有事件印证,判不通过,
页面顶上显示「—」而不是把文件里写的当成核对出来的。
样本页加一份 continued(先失败、继续运行到成功的早期运行),check-bundle 断言它原样时无法核对、运行结果改成已失败或已取消时不通过。
|
2026-10-05 19:06:32 +08:00 |
|
ThearchyHelios
|
e7c8d2a1f3
|
可验证报告复核修正(第 1 轮):运行信息拿已核对的事件对照,报告徽标连同数字一起算,遮罩判定宁严勿宽,各分支在浏览器里有确定的检查
- 页面核对加 ⑥ 运行信息:运行结果看封存范围内最后一条结束类事件的类型,运行类别看运行开始事件记下的运行参数,
出具档位认最后一条出具判定(不再信元信息指的那一条);页面显示事件里的值,元信息写得不一样算不通过、计入总览。
工作流名、版本、起止时间、节点名称绑不进封存,单列一组写明取自运行记录,封存说明里也写明要到系统里一并对照
- 报告标题旁的徽标连同正文里的数字一起算,旁边写分项:重算全部哈希的伪造只在 ⑤ 露馅,徽标不能还写着通过。
分块条目多时不通过和无法核对的都列在外面,有无法核对的显示「部分无法核对」和分项计数;⑤ 改叫「数字与取值」并分开数,
读屏分别读作数字、取值,「显示格式由服务端渲染」只附在带出处的数字上;无出处数字的说法改成未使用引用标记
- 服务端不会给出的状态算不通过:被引用的工件不在清单里、非查询快照标着遮罩、工件既没内容也没说明;报告文档导出时
已不在服务端,总览不再是绿色的通过,写「有 N 份报告未能核对」,报告处写明是服务端已没有这份文档
- 认 json.dumps 写出的裸 NaN / Infinity,没被改过的文件不再误判不通过;哈希对得上但读不懂的照实写「无法核对」,
和哈希不一致分开说
- 宽屏打开出处面板时正文让出右边一栏,表格里右对齐的数字不再被面板盖住;补上斜体(不用后行断言,较早的 Safari 也能执行)
- 封存哈希、运行 ID、工作流名直接写进页面,不执行脚本时写「尚未核对」而不是一直「正在核对」;脚本挪进 head,
执行后核一遍页面顶部写出的封存哈希和数据里核对用的一致
- 成果节点和运行结束事件的规范字符串,只在封存范围内每次数据源查询都对得上无遮罩的快照(或确实没交回数据)时才给:
升级前的运行从工具快照认出查询快照,协作团队成员的查询认不出就按带遮罩算,数据源现在设了遮罩的按工具名就挡
- 封存核对不一致的 409 改成一句固定的话,不再叠冒号、让人去本来就在的记录页;失败结束的运行在页面封存说明和导出提示里
写明之后继续运行会重新封存;记录页上左边写着「已封存」却不能导出时,原因写在屏幕上
- tests/bundle_samples.py 用虚构数据真实生成九份样本页(遮罩快照、两份报告、早期运行、失败结束、两条出具判定、
服务端缺文件、裸 NaN、别的运行的文档),check-bundle 断网打开逐项断言,在上面篡改引用链、运行信息、拿掉被引用的口径卡,
量宽屏面板,看不执行脚本的样子;把核对改成恒通过、徽标不看数字等七种改坏法都会变红。pytest 补遮罩判定的三种形状、
事后设遮罩(去掉接线即变红)、页面静态内容和样本页本身
|
2026-10-05 05:30:50 +08:00 |
|
ThearchyHelios
|
183814d2c1
|
可验证报告页面补全:列出参与清单核对的原文供页面外自行重算,写明运行结果,自查认法与服务端一致,打印时收起面板
- 封存清单一项可展开参与核对的每一行(序号|类型|节点|内容哈希),读的人不信页面脚本也能复制出去用别的工具算;
check-bundle 在页面之外用 node 重算这段原文,等于封存哈希
- 元信息加「运行结果」(已完成 / 已失败 / 已取消):失败的运行报告照样导得出去,读的人要知道它没跑完
- 报告节点认最后一次记下了文档的自查,和服务端、证据接口同一个认法,后面多一条没记文档的自查不再误报不通过;
运行记录里有自查、文件里却没附带文档的报告照实报不通过
- 核对下不了结论(数据块坏了、内置 SHA-256 自检不过)时也标上核对结束,等结果的一方不必干等;打印时收起出处面板
- check-bundle:拿不到导出页面时,依赖它的几节跳过并注明原因,不再一个原因报五次
|
2026-10-05 04:04:06 +08:00 |
|
ThearchyHelios
|
a0016493de
|
可验证报告服务端:GET /api/runs/{id}/bundle.html 把已封存运行的报告导出成自包含的 HTML,浏览器断网也能核对
- bundle/build.py(纯函数):封存范围内每条事件带 seq、类型、节点和 data_sha256(与 runner 封存同一算法),浏览器据此重算清单;
白名单事件(运行开始、报告自查、口径卡升版、出具判定、报告和口径卡的节点完成、数据源没有遮罩的查询返回)另带规范字符串,
运行里有带遮罩的快照时,成果节点和运行结束事件的预览可能带出查询结果,也只给哈希;报告文档和它引用的口径卡、查询快照按原字节
base64 嵌入,遮罩快照(查询时记下的或数据源现在设的)只给 id;封存之后追加的事件单列、不进清单
- template.html + verifier.js:样式和脚本内联、零外链,内容安全策略按哈希只放行核对脚本;数据块转义 < > & 和 U+2028/2029。
浏览器逐项核对事件内容、封存清单、工件哈希、引用链、报告里每个数字(照搬 cell_value / same_value 判等),
crypto.subtle 拿不到时用自检过的纯 JS SHA-256;醒目写出封存哈希,并写明只证明内部一致、真伪要去系统里对照
- 接口复用证据接口的封存判定:未封存、或运行还没结束(接着跑的运行留着旧封存,跑完会换掉清单哈希)回 409,封存核对不一致回 409;
附件名「<运行名>-可验证报告.html」按 RFC 5987 编码;只读,不追加事件
- artifact_store 加 read_bytes:原样取回工件字节,默认复验哈希,verify=False 交给浏览器去核
|
2026-10-05 03:58:02 +08:00 |
|