寒 DATA VAULT数据仓
EN / 中
CAP XXII · № 022
DATA WAREHOUSE · AI · SYSTEM
— · — UTC
DATA VAULT
CAPITULUM · XXII

On Opening the Books一次只读体检 · 三批修复与上线

№ 022 · 2026.11.03 · AI · SYSTEM · 2,712 字 · 10 MIN

一笔充值已经退回了卡上, 钱包里相应的钱也扣掉了, 账本却还记着它。给 GGBOYS 做资金体检时, 查出过这样一笔账。我下午问:「这个账是怎么丢的呢?」查下来, 钱没丢, 漏的是记录。

一个平台能收钱, 能把钱退回去, 日常看着便像是在正常运转。直到把钱包和账本逐一摊开, 才看见两边说的并非同一回事。若只等一笔交易失败了再去查, 这笔已经退成功的钱, 大抵还轮不到被问起。

体检时, GGBOYS 上线收真钱还不到一个月, 做的是游戏饰品交易。买家付钱后, 款项先留在托管里; 交易有撤回的可能, 卖家的钱要等保护期满才能放。2026 年 10 月 20 日, 我让 Claude Code 全面查一遍, 起因便是想确认这些约束在正式站上到底有没有兑现。

先不动账

体检开始前, 得先弄清楚查的是哪一版。主控把正式站实际运行的代码和仓库里的版本作了核对, 再只读查询正式数据, 检查报告中的判断是否有现实依据。桌上摆着一份代码, 不能就当它是店里正在用的那份。这个差别听来琐碎, 后来准备第二批上线时, 又碰到了。

检查分了 9 个方向, 覆盖买卖和租赁的放款, 也查提现、充值、权限及账本。18 个 Opus 模型子任务分头工作, 每个方向有人找问题, 另有人专门反驳和复核。体检本身用了 31 分钟, 没改代码, 也没动数据或配置; 后面的修复和上线, 则铺开了好几天。

这半小时里有个颇值得记下的重合: 6 个子任务各自碰到了同一处争议裁决问题。裁决给卖家的那份钱, 在交易风险尚未结束时就能提出去。更早的一次审查也看过这里, 当时从条款允许扣留的角度判断, 没再追问款放出去以后交易又被撤回怎么办。

查的人多, 固然容易让人安心, 然而重复发现同一处, 还不能代替把它查实。主控继续核对有分歧的判断, 既改过偏轻的评级, 也改过偏重的。对我而言, 那 6 份发现比较有用的地方, 是把注意力拉回到了同一个业务后果上。是否写过一条规矩, 和钱最终如何流动, 中间仍隔着实现。

报告也要再查一遍

报告出来后, 问题分成两堆。一堆已有明确规矩, 只是实现漏了, 或者纯属技术错误, 可以先修; 另一堆会改变钱何时放、损失由谁承担, 得由我定。分之前还查了已有的规则, 免得把早就答过的题重新递回来。我不用替每一处代码错误拍板, 但也不能让写代码的人顺手替平台作出赔付承诺。

第一批在 10 月 20 日当天开修, 当晚上线。开头那笔漏账就在里面。钱是从支付服务商后台退的, 通知回来后, 钱包扣对了, 账本没跟着记; 从平台自己后台发起的退款, 原本会同时处理两边。这次把漏掉的路径也改成一起完成, 补账经过预演再执行, 随后逐一核对, 钱包和账本重新相符。

若把这件事搬到一个想象中的旧账房, 便像是银钱已付, 柜上的账册也划掉了, 另一册却还留着原数。账房先生大概不会因钱已付妥就把后一本合上。如今几份记录各自更新, 看上去省去了抄账的功夫, 漏掉的那一笔却仍得有人翻出来。

同一批还有一次对报告本身的纠正。报告说, 一批权限过宽的内部操作没有后台页面在调用, 可以一并收紧。修复会话动手前重新查了调用方, 发现后台有些按钮确实还在用。照报告直接改, 按钮就会失效。于是按实际用途分别处理: 内部专用的限制调用来源, 后台确实需要的补上相应权限。

报告写错一句话, 并不稀奇。让我在意的是, 修复会话没有把这句话当作查证的终点。它已经拿着一份声称查过的报告, 仍得回到按钮和调用关系里去看。第一批也补齐了拒付后的放款约束等已有规则, 但「已有规则」只回答该做什么, 具体改在哪里, 依旧得核。

该由我答的题

需要定规则的部分被写成了选择题, 每题附推荐项和理由。我答完, 第二批才开工。争议裁决那件事, 定下的是买家该退的部分先退, 卖家分得的款继续托管, 满足放款条件后再放。裁决解决双方如何分配这笔钱, 并不能顺带让尚在延续的交易风险消失。

另一题是赔偿。卖家应赔却付不起时, 平台是否先替他垫上, 这已经超出了程序算得对不对的范围。我定了按实际从卖家处收回的款补偿买家, 欠款继续追, 而不由平台先垫。实现时又遇到补付的细节, 会话停下来再问, 答清楚才往下写。

第二批涉及托管和账本的改动, 除了 Opus 审查, 还请 Codex 用 GPT-6 Astra 作只读的第二意见。审查者按「这里可能有错」去找证据。钱的分配规则写得通, 实际执行仍可能卡住; 这类地方让另一份判断进来, 比让我看着一长段「已完成」安心些。

代码在 10 月 21 日凌晨前后完成, 审查和测试也已通过, 并没有随即上线。等到准备部署, 主干已经被另一批工作改过, 数据库变更也有冲突。于是另开会话重新合并, 审合并处并重跑全量测试, 到 10 月 22 日才上正式站。

第三批, 把问题重新摆回桌上

第三批开工前, 候选项重新对着当时的代码核过, 我从清单里挑了这一批要做的。原路退款的规则也在这里改定。最初按整个钱包计算可退额度, 后来改成按卡核, 再核时仍发现口径没有覆盖全。我说的要求很朴素: 用哪张卡充的, 就回哪张卡。落到最终规则, 每张卡能退的是它自己充入、按规则核算后还没算花掉的部分。

「原路」这两个字, 单看似乎已经够明白, 真到钱包里混着不同来源的余额, 才发现得把归属说清楚。这里不展开核算办法。改过的退款规则随第三批在 10 月 24 日上线, 不能因为前一版已经写进代码, 就把它当作我的本意已经表达完整了。

这一批也处理了取消订单与发货同时发生的情形。退款要执行时, 重新核对订单状态, 条件不符就不动钱, 不能只凭较早那次读取下判断。检查又往监测覆盖上补了一步: 应当检查的交易都得被覆盖, 不能因排在处理范围之外便默默漏掉。

人工核实放行的效力也收紧了, 一次核实不能成为长期豁免。至于账不相符而无法放款的情形, 拦住款是应该的, 但还得有人收到告警, 不能仅在后台留下一行记录。钱没有误放, 并不意味着这笔钱就已被照料妥当。第三批分两次上正式站, 都在 10 月 24 日完成。

上线前, 旧告警还在那里

回头说第二批上线时的一件事。那次加严了放款前的检查: 无法确认交易状况, 就暂缓放款。上线清单却提醒, 正式数据里有尚未关闭的历史告警, 新规则会把它们当成当前仍有异常的依据。若只把代码推上去, 正常到期的款也会被一起拦住。

这里不能为了让新代码跑起来, 把告警随手抹掉。得先确认有关交易后来已重新核实, 没有撤回, 才能处理旧记录。实际执行前, 修数据的动作在测试环境和正式环境都作了不落盘的预演, 确认演练没留改动, 反向操作也备好, 然后才执行并上线。

这件事比改一段判断更像收拾账桌: 新规矩已经写好, 旧纸条却仍压在下面。纸条记的是过去发生过什么, 程序读到的则可能是现在还应拦什么。同样一条记录, 放进新的判断里, 意思就变了。第二天核查, 上线后首笔到期款按时放出, 没有被这次加严误拦。

三批各自在隔离的工作区实现。新测试先放回改动前的代码运行, 看它是否真的能抓到原来的错误; 合并后再跑全量, 两部分合计上万条测试通过才上线。每次上正式站仍由我单独确认, 各步留回滚点, 回退方法写进交付记录。数据库变更只加不删, 回滚只退代码, 动过数据的地方另留反向操作。上线后的日志也要继续看, 才算走完这趟。

这几天的另一笔账

体检本身只花了那 31 分钟, 到第三批两部分都上线, 已经是 10 月 24 日夜里。相关用量记录跨到 10 月 25 日, 四千多次模型调用, 绝大部分是 Opus 5.5, 少量工作用了 Sonnet 5.5, Codex 的 GPT-6 Astra 参与了第二批审查。按 API 标价算约 400 到 500 美元。

把缓存读取也算进去, 日志累计是十多亿 token, 其中绝大部分是反复读取已有上下文, 不能当作模型新写了十多亿字。记录到的输出是百万 token 量级, 早期部分子任务的输出又没记全。会话里还混有拆不开的发布工作, 所以这笔折算只能作粗账, 并非资金体检的精确成本。

模型究竟替我省了多少功夫, 这笔粗账还答不出来。翻回开头那处退款, 钱包和账本已经对上。那一笔, 可以先划掉了。

写作记录:这篇由 Codex 在 2026-11-03 16:09 到 16:16(美东)写成。主线程用 GPT-6 Astra(gpt-6-astra),推理努力程度 ultra;它自己另派了 2 个子线程,一个核对有没有越过脱敏的线、一个复核文风,都沿用 GPT-6 Astra 和 ultra。这 3 个线程合计读入 1,611,249 token(其中读缓存 1,498,240),输出 17,303 token(其中推理 4,374)。素材由 Claude Code(Claude Opus 5.5)事先整理,不算在这个数里。

「那一笔, 可以先划掉了。」

BASTION NOTE · 022
Xinghan's Memory · Written by Codex
— end of cap. XXII —