Fullseye 设计判断集(由源码中的 ★ 注释生成)
日本語 · English · 简体中文 · 繁體中文 · 한국어 · Deutsch
本仓库把「为什么是这样」写在源码注释里。其中标了 ★ 的是真正管用的部分——测出来的结论、踩过的坑、这样做的理由。本页由它们机械汇集而成,正本在源码一侧,因此两者不会走样。
翻译进度:610 / 681 条。未翻译的条目照原文(日语)显示——悄悄回退到原文会看着像已翻译,所以没译就明说没译。
accel_match.py
- L170 — ★窗口必须比模板大,否则完全重叠的位置数会变为零 → r = T//2 + f(粗误差) + win。
acoustics.py
- L1173 — ★
med == 0 一律当作 inf 处理——连 peak 也为 0 时(静音、频带内什么都没有)也报告”无限突出的峰”。正如 docstring 所述,这两个数本是对”即使什么都没有也会返回峰频率”的诚实性指标,却偏偏朝最会说谎的方向摆动。0/0 的答案是 0.0。(2026-09-05:在 Linux / numpy 2.5.2 上暴露。旧版只是滤波残差略有残留使 med > 0,缺陷一直就在。)
- L1181 — ★全局中位数在收窄频带时会颠倒顺序(纯噪声 11375 对真正的缺陷 9433。2026-09-06 实测,见 _local_prominence 的表)。做与带宽无关的判定时用这个。既有的两个保持含义不变而保留——同名而内容改变,比增加一个更危险。
- L1789 — ★
med == 0 一律当作 inf 处理——连 peak 也为 0 时(静音、频带内什么都没有)也报告”无限突出的峰”。正如 docstring 所述,这两个数本是对”即使什么都没有也会返回峰频率”的诚实性指标,却偏偏朝最会说谎的方向摆动。0/0 的答案是 0.0。(2026-09-05:在 Linux / numpy 2.5.2 上暴露。旧版只是滤波残差略有残留使 med > 0,缺陷一直就在。)
annotate.py
- L3095 — ★标点(。、)本应不旋转而是靠向右上,但这里不靠——与其默默近似做不到的事,不如写进 docstring 留存。竖排中靠向右上的字(标点)。横排时位于字左下的点,竖排时来到右上——排版之道是移动位置而非旋转。Windows 的
@ 前缀字体(GDI 按 face 名选择的竖排字面)在字体侧做了这件事。Pillow 以文件路径打开字体,够不到 @ 字面,HarfBuzz 的 direction="ttb" 也会因是否安装 Raqm 而结果不同(本机 Pillow 12.3.0 的 features.check("raqm") 为 False)。遵循选择跨平台一致者的方针,这里用合成来靠位。
api.py
- L587 — ★
annotate.overlay_mask 有意不暴露到顶层。同名的 imgio.overlay_mask 已作为 fs.overlay_mask 公开,其参数与含义都不同(imgio = 原始 RGB、mask>0.5、fill/margin / annotate = 角色名的颜色、也可用权重 [0,1]、拒绝形状不匹配)。在同名上加载不同的约定,调用方收到的不是异常而是看似合理却不同的图。公开 API 的破坏性变更不擅自做,故带角色的那个用 fs.annotate.overlay_mask 取用。
- L1346 — ★ 目前对彩色图像没有正确的调用方式:整批传入会混色,按通道调用 3 次会让自归一化的 op 把每个通道除以各自的最大值,破坏通道间的比值(灰度边缘法的角度误差从自建 Sobel 的 1.03 度 -> 每图 4.17 度 -> 每通道 27.86 度,零点 29.14 度)。倒向哪一边是契约的决定,所以这里不改动任何一个默认数值,仅在
on_error="raise" 时拒绝,默认则记入台账使其可见。详情与选项见 docs/KNOWN_ISSUES.md。
astrostack.py
- L156 — ★假设检验:我们预测「只要能装进一条缓存行(64B)就不值得搬移」,但猜错了。float32 的临界点在 K≈17-19,接近 64B(K=16),但 float64 的实际临界点是 K≈23-25(约 200B),而预测是 K=8。决定它的是元素个数而非字节数 —— 每个元素的取出开销占主导。数量少时搬移反而更慢(float64 K=5 时慢 1.4 倍),所以临界点必不可少。
-
| L379 — ★MAD 塌缩为 0 但图像并不平坦 = 量化(2026-09-08,poc_thermal_radiometry 踩到的)。整数 DN 下 |
x-med |
也是整数,所以能返回的 sigma 只能是 1.4826 的倍数 —— σ=0.5 的实拍等效返回 0.0,σ=1.0 与 σ=1.983 都给出同一个 1.4826。悄悄返回 0 会让阈值与背景相同,下游(star_detect)什么都找不到。这里是返回数值的入口,所以不 raise 而是发出提示(调用者可以选 method=”clip”)。refuse 是出答案一侧 = star_detect 的职责。 |
- L586 — ★ 散粒噪声的唯一入口。photons_per_unit=1 时「期望值 = lambda」。
- L675 — ★ field_seed 固定(同一片天空),只变动 seed(不同的观测)。
- L746 — ★在 2026-09-08 之前这个门的注释写着「完全平坦 = 无法测量噪声」。错的是前提 —— σ 变成 0 还有另一条路径,即整数 DN 下 MAD 塌缩的情况(σ=0.5 等效的实拍为 0.0)。对不平坦的图像返回空并非保守的答案,而是错误的答案;实际上植入 200x200 整数帧的 2 个点目标被返回为 0 个。于是分开路径:平坦则返回空(没有星),不平坦则拒绝。
- L1606 — ★平局时选择原始票数更多的 bin。3x3 平滑从真峰的左右两侧看都得到相同的和,所以只用平滑值取 argmax 可能选中「峰旁边的空 bin」—— 实测正是如此:真实位移 (-0.087, +0.996) 的 7 + 4 票在 bin 边界被一分为二,而其中心偏了一个 bin 变成0 票(frame_align 误以为「没有重叠」而 fail-closed)。1e-6 的权重远小于平滑值的步长(1/9),所以在真有差异时不会改变排序。
- L1629 — ★2026-09-08:同时返回第二高峰的高度。星野只有一个峰,但重复结构(网点、光栅、织物)中,等高的峰会沿格矢方向平移排列,无论选哪个都会「全体赞成」= inlier_ratio 变成 1.00。赞成率并不是「答案正确的概率」,所以用另一个数来给出是否只有一个峰(0 = 单峰,接近 1 = 还有其他等价候选)。
backend_safe.py
- L436 — ★feature op 返回的是 numpy 标量而非 ndarray,所以上面的分支从未见到它:NaN/Inf 的测量值(例如对退化帧调用 sk_blur_effect 内部的 0/0)会直接从 api.apply 流出。把非有限标量也洗到 sort 回退,使所声明的”有限、sort 有效”保证对 feature/contour 标量也真正成立。
backends.py
- L23 — ★
_safe 回退是最后手段,并且可能掩盖已死的 op。当 out_sort==”image” 时 backend_safe.fallback 返回裁剪后的输入,于是一个对任何输入其库调用都会抛异常的 wrapper,在进化 / difftest / coverage 看来就像一个能工作的恒等 op 而非失败。运行时的健壮性得以保留,但退化是可检测的:每一个被吞掉的异常都记录到共享的回退台账,strict 模式下则改为重新抛出。2026-09-02:把台账 / strict 开关下移到 backend_safe,使其他 23 个 backend 文件(各有私有的 _safe)都向同一处报告——在此之前,24 个 wrapper 族中只有本模块会记录任何东西。下面的名字作为供从此处导入的调用方与测试使用的薄别名保留。
- L812 — LBP 编码。★在 2026-09-08 之前
b 其实什么都没做,method 固定为 'default'(非旋转不变)。在实拍纹理(brick / grass / gravel)上测量,各向异性材料在旋转下移动的量是材料间距离的 9.64 倍,换成 'uniform' 后降到 1.72 倍(examples/poc_real_texture_invariance.py)。不能选就无从降低,所以分配了 b。做成阈值表是当同一轴上分支增多时的规约(不用嵌套 if)。b=0.5(默认)照旧为 'default'。
- L1028 — ★向 cv2 传入 bool 数组会让
cv2.Laplacian 破坏堆,进而在后续无关的 op 处让进程崩溃(2026-09-05 Fable 评审,我在 Windows 上 100 次内自行复现了 SIGSEGV,exit 127)。facade 会把 dtype 对齐到契约,但 op.fn 直接路径(测试、coverage、进化循环)是直通的。在族的入口对齐为 float64。
backends_auto.py
- L594 — ★不改变画布(reshape=False)+ 边框外镜像(mode=”reflect”)。角度为 -45°..+45°(a=0.5 时为 0°)。四角会折返映入原图,所以对像单据纠偏(deskew)那样「想用背景色填充框外」的用途,直接用并不合适(这是已知的设计判断而非 bug — 详情与取舍见
ops._rotate_img 的 docstring)。
- L617 — ★但返回值的 shape 要保持在与输入相同的画布上。这个 registry 的 image 有「段间无条件衔接」的契约,改变 shape 会让评估器无法与目标图像对齐而崩溃(实测:目标尺寸版返回 (70,50) 的瞬间,
test_evolve_is_reproducible_given_seed 以 “operands could not be broadcast together with shapes (70,50) (64,64)” 失败)。于是把重采样到 Ht x Wt 的像放在画布左上角,边距填 0,超出部分裁掉 —— 「图像现在是 Ht x Wt 像素」这一点照旧可见。
- L1111 — ★2026-09-02:它返回的是
np.where 的整数像素坐标本身,虽自称 sub_pix 却没有亚像素精度。新增了通过抛物线拟合沿法线方向的精化(与 core ops._edges_sub_pix 相同的共享辅助函数。同名 op 在注册表中后者胜出,所以实际运行的是这个 —— 只改 core 无效)。实测(真实位置在列 20.37 的合成阶跃边缘,a=0.2):旧实现返回的列为 {20.0, 21.0},平均绝对误差 0.500 px,精化后为 {20.324, 20.370},0.0228 px(约 22 倍改善)。点的个数与连通分量的划分不变(坐标只移动不到 1 px)。
- L1270 — ★当 b >= 0.75 时取 4 个方向(0/45/90/135 度)的平均。默认 b=0.5 照旧只有 0 度,所以现有结果一个 bit 都不会变。是否有效取决于 a(共生距离)(poc_real_texture_invariance 第 6 节,3 种实拍素材):对各向同性素材在中短距离有效,对各向异性的 brick 仅在距离 4 有效(摆幅/分辨率 3.13 -> 1.54)。距离 1 时 brick
- L1275 — 反而恶化(0.30 -> 0.56)。★根源在于拉长距离会让分辨率本身塌缩,0.0328 -> 0.0122。
- L1482 — ★2026-09-02:这两个共享
{"kind": "zoom"},因此是完全相同的实现,而且两者都没有用 b(实测:同一输入的最大差 0.0,b=0 与 b=1 之差 0.0)。在 HALCON 中 factor 版取两个倍率,size 版取目标尺寸,是不同的东西,所以拆分 kind,让实态与名称相符。
- L1555 — ★2026-09-02:旧规格是 out_sort=feature / metric=”area”,实体是
np.mean(mask) = 在图像中所占的面积比。由于 HALCON 的 area_center 是返回 (Area, Row, Column) 的 op,存在双重不一致:(1) 不返回中心 (2) 面积是比率而非像素数(= 依赖分辨率)。单个标量无法满足这个名字,所以像 ncc_locate 一样做成 match sort 的 1-D 向量,返回 (面积比, 行, 列)。match / feature 都是终端 sort(候选仅为 identity),所以基因组->op 的映射不动。
backends_decomp.py
- L142 — ★把 BLAS 的线程上限在循环外只施加一次。这里是把限制在 work_max=64 的方阵最多 SVD 60 次的地方,占用本 repo 分解时间的大半(一次套件 30.7 秒 / 分解合计 31.4 秒,svd 23,987 次 = 98%)。64x64 的 SVD 用 24 线程比 1 线程慢 3.9 倍 —— 因为分解中的 GEMM 太小,同步开销超过计算量(表见 fsthreads 的 docstring)。每次都包裹会把机制的 2.4us 付 60 次,所以放在循环外。
- L206 — ★
ev[0] 是代数上最大的特征值,而非绝对值最大的。在明亮的脊上主曲率为负,所以 ev[0] 是绝对值较小的那个,给出脊上为 0、两侧为 1 的相反响应(2026-09-05 Fable 评审,实测 [1, .64, 0, 0, 0, 0, .64, 1])。按说明取绝对值最大者。
backends_r3.py
- L46 — ★在 2026-09-05 之前用
except Exception: out = None 吞掉了异常。注册时外层施加了 backend_safe.guard,但在内层消除异常后外层什么都看不到 —— 即使 strict mode 也不抛异常,台账里也不留痕。这是 2026-09-02「24 族中只有 1 族到达台账」审计的漏网(Fable 的对抗评审作为第 5 族指出)。让异常原样向外抛出:外层 guard 记录它,落到符合 sort 的值,strict 则重新抛出。
backends_scipy.py
- L198 — ★当 lambda >= ~12 时 scipy 抛出「boundary conditions did not converge」,guard 的 fallback 变成了恒等(旧的 1+40a 在 a>=0.3、含默认 0.5 有 7 成为恒等。2026-09-05 Fable 评审)。说明也对齐到 1〜11。
backends_typed.py
- L505 — ★在 2026-09-05 之前通过操作 sys.path 读取
tools/chain_fuzz(未随附)。在 wheel 中会失败,而下面的 build() 悄悄返回 [],所以 tb_* 143 个 op 消失了。
blob2d.py
- L287 — ★注意符号:顶点按 (row, col) 顺序排列,所以
_monotone_chain 返回的朝向是(把 row 视为 x 的)逆时针 = 屏幕上为顺时针。内侧是叉积非负的一侧(写成 <= 0 会让所有物体 solidity 为 0)。
- L587 — ★仅靠腐蚀只会出现一侧。编号较小的物体,即使旁边来了编号较大的物体,邻域最小值仍是自己,因而被判为「内部」(2026-09-06 实测:在 1 与 2 相接的列,1 一侧的轮廓消失了)。同时看膨胀就得到「邻域中有与自己不同的编号」这一对称判定。
calib.py
- L178 — ★2026-09-06 实测了这个门在实机相机上不会触发。在无畸变的合成数据上按设计工作(倾斜 0 度时比 3.8e-14,0.05 度时 8.6e-10,均拒绝)。但加入现实的桶形畸变 k1=-0.18 后,平面单应模型本身就不再吻合,比值与倾斜无关地钉在 1.9e-06 附近(0 度 1.916e-06 / 0.05 度 1.935e-06 / 0.2 度 2.005e-06)。
- L184 — ★仅当两个条件同时满足时:存在畸变,以及视点间板子横向移动。只要满足其一,门就按设计鸣响(切分见 tests/test_calib.py 的 3 条)。而实际的标定会话是手持移动板子拍摄的,所以两者必然同时满足。也不是提高阈值就能解决 —— 有畸变时,完全退化 1.92e-06 与倾斜 2 度 4.42e-06 之差只有 2.3 倍,画不出分界线。因此:* 阈值保持不变(对已去畸变的点能正确生效)* 把比值本身作为
orientation_rank_ratio 返回 * 让实际拦截的后段门说出「请倾斜板子」(下)。无法修复,那就把判断材料交给使用者。
caltab.py
- L188 — ★这个门抓不到的东西:对单张平面靶标的内参误差(尤其是 fx/fy 之比)。单个平面的 homography 只对内参施加两个约束(Zhang 2000),所以错误的 fy 大多被这里求解的位姿 6 自由度吸收,残差可能留在阈值之下。实测 2026-09-05:即使把 fy 从 500 -> 300 弄错,Linux/scipy 1.18 上 RMS 也只有 0.90 px(正确 K 则为 0.14 px)。同样的输入在 Windows/旧 scipy 上变成 6.39 px,仅凭优化收敛点的不同就「能检测到或检测不到」。若想验证内参,请取 3 个以上视点或使用非平面靶标。这里有效的是「位姿无法吸收」的不一致(对应关系错误、非平面板)。
champion_to_macro.py
- L193 — ★强制执行招牌式的诚实主张(“DNA op 只在锁定的 holdout 上胜过手工基线时才添加”)——此前这个标志只是打印出来却从不设门,于是比手工更差的宏也能被注册,并被下一轮进化选中。除非显式覆盖,门会拒绝它。
- L87 — ★不保证位一致(2026-09-05 更正)。数学上按行独立,但
U @ w 是 BLAS 的 GEMM,所以规约的划分与向量化路径会随行数 M 变化,舍入可能改变。实测:一旦给 CI 的 py3.11 作业加入 torch(= 一旦载入了另一个 OpenMP 运行时),分块与否结果就不一致。保证的是数值上的一致(数个 ULP),而非 bit 一致。
demops.py
- L97 — ★不提供用中位数等填补的选项。填补会造出不存在的平原,不抛异常地放水通过。但效果的大小要如实写下。在同一份实测数据(东京湾岸 1024x1024,缺测 3.83%)上比较 3 种方式的最大汇水单元数:出流口 312,108 (29.8%) / 中位数填补 338,188 (32.3%) / 墙 315,023 (30.0%)。填补大约夸大 8%,但「一个单元汇聚全体的 3 成」这件事本身就是此地形的实际(平坦的填海地确实会汇向一处)。最初只看填补就写「这个数字是填补的产物」是夸张,取了对照后效果就缩小了。不放填补选项,是因为会无法区分哪里是真实地形、哪里是填补,而非因为数字会以数量级变化。
- L605 — ★这个慢是在 PoC(examples/poc_dem_terrain.py)中 513^2 的天空可视率花了 41.9 秒才第一次注意到。测试只用了小格子,确认了「能动」但没确认「能用」。
- L686 — ★2026-09-08 修正(
poc_stockpile_volume 发现)。当视线的采样经 np.rint 舍入到目标单元自身时,就会把该单元的高度当作「途中地形」来与自己比较。由于 t < 1,分母 dist*t 很小,(z-eye)/(dist*t) > (z-eye)/dist 在 z > eye 时必为真 —— 高于视线的单元几乎都自遮挡了。实测(修正前):平地上高 10 m 的柱子在 25 m 外、视线 2 m 处返回「看不见」,只有低于视线的 1 m 柱子「看得见」。凸立体的最高点从外部必然可见,所以这在几何上是错的。采样落在目标单元上的那次不计入。
- L746 — ★台账声明
points = (N, 3)。传入标量会变成 (3,),与声明不符,所以总是折叠为 (N, 3)(2026-09-06 由 fuzzer 的 TYPEMISS 暴露。加入 6 个地心坐标 op 后没有跑 fuzzer)。若想保持格子形式的 (H, W, 3),请用 :func:dem_geocentric_grid。
-
| L795 — ★渐屈线内侧的大地纬度不唯一 -> 不悄悄返回超出范围的纬度,而是拒绝。椭圆 x²/a² + z²/b² = 1 的渐屈线为 (a·x)^(2/3) + (b·z)^(2/3) = (a²-b²)^(2/3)。只有等号外侧才是「法线唯一确定」的区域(2/3 次幂非负,所以符号取 |
z |
)。 |
evis_fullseye_bridge.py
- L152 (ja) — ★The sky is “infinitely” far (measured: 998 in a world whose animal is 0.3 across), and with the sky in view the 3rd/92nd percentiles straddle it, so the panel collapses to two flat colours — sky and everything-else. depth_max cuts the band at a distance that means something for this body, so the scene gets the colour range instead of the sky.
- L171 (ja) — ★ego_camera(モデル自身の目)でも eye パネルを出す。ここを ego>=0 だけで見ていたので、 ハエの複眼から描いたのに複眼の絵がコマに入らなかった(2026-09-14 実測)。
- L180 (ja) — ★drop frame 0: the event panel has no previous frame to difference against, so it is blank by construction. Keeping it makes the first thing a reader sees a black panel, which reads as “the events never fired” (measured: frame 0 has 960 lit pixels, frame 20 has 35,550). The stats below still count every frame that was rendered.
- L189 (ja) — ★distances carry the MODEL’s unit, not metres: the fly world is cm/g/s, so reporting “6.96m” for a 7 cm walk is a lie the caller cannot see.
unit names it honestly.
examplefig.py
- L139 — ★
colorize_depth 返回 float [0,1]。用 np.asarray(..., np.uint8) 接收会把所有 0.x 截断为 0,变成全黑(2026-09-06 踩到)。
- L171 — ★不要丢掉示例的正文。图出不来固然遗憾,但数字必须给出。
- L210 — ★这里不能甩给 :func:
_to_rgb8。它把 (H,W) 传给 colorize_depth,但在其中会逐帧归一化,所以全为 0 的帧和全为 1 的帧会出同样的颜色(2026-09-09 被测试抓到)。只有显式传入值域,尺度才会统一为一个。
- L275 — ★Pillow 会把与前一帧完全相同的帧折叠为一帧(那部分时间会加到前一帧的显示时间上,所以动作速度不变)。写完后计数,若与传入的数不同就在台账里两者都留下 —— 以免把嘴上说「72 帧的 GIF」而内容只有 40 帧的情况悄悄放过。
- L339 — ★2026-09-08:面板小时标题放不下,
annotate_figure_grid(正确地)拒绝,于是有一张图悄悄消失了。29×19 的 core 格子或 24×24 的缩小图在 PoC 里很常见,可错误却说「把标题缩短」—— 实际的修法是「把面板放大」。两位负责人独立地掉进同一个坑(有过看板的 scene 图消失一张的例子),所以不让每个调用者各自写放大,而在这里只做一次最近邻放大。用最近邻是为了在放大时不造出值(插值会在图上产生并不存在的中间值,伪彩会说谎)。
examples/acoustic_condition_monitoring.py
- L467 — ★抛物线插值仍残留向整数拉的偏差(因为峰是 sinc 状的,无法用二次完全逼近)。从 0 扫到 1 实测偏差,展示它呈 S 形 —— 若止步于「读到了亚样本」,这个偏差就会悄悄搭在结果里。
examples/annotate_paper_tour.py
- L51 — ★EXTEND:把 text 和 path 替换为你自己图的文字与折线 (x, y)
examples/blas_thread_budget.py
- L117 — ★这是要点。96x96 并不是”因为小所以快”,而是一个正因为小才使多线程反而吃亏的尺寸。在循环外放置一次(若每次迭代都包裹,就要把限流机制本身的开销付 30 次)。
examples/blob_split_tour.py
- L98 — ★实测(honest):高度 2 < h 的条上也会立起种子。blob_seeds 以残差
f - R > 0 作为种子,但若对每个分量以背景 0 重建,峰高 M < h 的分量得到 R = M - h < 0,于是残差在该分量的全部像素乃至背景 1 px 的边缘都为正(skimage 的 h_maxima 以 残差 >= h 剔除)。不修改实现,仅作报告。此处去掉条的种子,验算”无种子团块”的路径。
- L129 — ★实测(honest):割缝并不落在交线上,而是编号较大的种子一侧沿谷底吃进。blob_split 逐级膨胀,将”同时被两个区域触及的像素”赋给 grey_dilation 的 max(=较大编号),因此经 8 连通的斜向链式传播,编号较大的区域沿谷线侵入数列。互换种子编号,侵入方向也随之互换(是编号的偏置,而非几何)。不修改实现,仅作报告。
- L153 — ★实测(honest):若按教科书的 h-maxima,当 h 超过”较低山峰的凸起(16 - 鞍部 10.07 = 5.93)”时,两个种子就会融合为一。blob_seeds 以残差 > 0 作为种子,故残差 = min(h, 凸起) > 0 恒成立,较低山峰的种子不会在该 h 处消失。融合发生在 h 超过”较高山峰 - 鞍部(22 - 10.07 = 11.93)”时——它所参照的山峰正好相反。
examples/coherence_scanning.py
- L166 — 6) ★ 与相移法的对照 # —————————————————————— #
examples/dem_geodesy_tour.py
- L49 — ★若不把仓库根目录加入路径,就找不到
demops(本例不 import fullseye,因此路径钩子不生效)。
- L61 — ★EXTEND: 替换为你自己瓦片的西北角(此处在东京附近)。
- L131 — ★诚实的分解:Bowring 的单次迭代在椭球面上为 1e-9 m,但高度越高误差越大(实测 8848 m 处 8e-7 m,20 km 处 4e-6 m)。docstring 中的”1e-12 度 / 1e-7 m”是近地表值,在平流层高度并不成立。用于地形(高程 < 9 km)时为 1e-6 m,此处将阈值设为 1e-5 m。
- L160 — ★EXTEND: 将 dem 替换为真实数据(第 0 行为北)。此处为已知的斜面。
examples/dem_terrain_analysis_tour.py
- L46 — ★若不把仓库根目录加入路径,就找不到
demops(本例不 import fullseye,因此路径钩子不生效)。
- L59 — ★EXTEND: 单元尺寸 [m]。真实数据用 dem_cell_size_webmercator(zoom, 纬度) 求得。
- L158 — ★诚实的观察:当斜面中途存在缺测时,其正北的邻元即便是 outlet 也不落向缺测,而是流向西南(有有限落差的方向)。实现是”仅当别无下降去处时才落向缺测”,比 docstring 的”允许流向缺测”更窄。此处仅打印,不 assert。
examples/piv_flow_from_particles.py
- L27 — ★由于要 import repo 根目录下的模块(pivops),把 repo 根目录放到最前,使其从 checkout 直接运行即可通过。与其他示例相同的做法。没有它,
py -3.11 examples/<name>.py 会因 ModuleNotFoundError 而失败(2026-09-09 实测:在缺少运行门的 83 本中,失败的仅此类型的 2 本)。
examples/poc_allsky_cloud_cover.py
- L104 — ★最后 3 个是薄云(光学厚度不同)。提高阈值时,越薄的越先掉落——第 4 节的阶梯即由此产生。
- L142 — ★立体角权重。dΩ/dA = sinθ/(f²θ) —— 等距投影的雅可比。
- L524 — ★2026-09-08:”equidistant” 变得会命中一维的
create_funct_1d_array(从等间隔样本构建函数)——这是让 ops1d 可经 op_find 检索的副作用,与投影模型无关。仅仅是词相同,空缺并未填补,因此改为查看”不在投影族中”的形式(不以词的匹配来判定)。
examples/poc_asbuilt_wall_deviation.py
- L497 — ★遗漏的不是倾倒而是鼓胀。predict_bulge 以闭式返回的一次系数量,会原封不动地变成伪倾倒与伪平面内偏摆。
- L555 — ★向闭式传入包含被鼓胀吸收的部分(§6)的有效倾倒。若不包含,则仅 f=0 的单点偏差 1.2 mrad,看似预测失准。
- L660 — ★仅噪声的地板。在鼓胀为零的壁面上以同样方式读取,就得到这个。
examples/poc_astro_photometry.py
- L322 — ★ 这里曾错过一次:以为”scale=2 所以亮度也是 1/4”,写成 flux/4,得出 -74.89 %。守恒律(上文 6.1e-14)把它剔除了。每像素亮度变为 1/4,但星的总和不变。
- L423 — ★ 这里曾放弃过一次 assert:上表的 rms(1 次合成、孤立星 8 个)给出良 6 帧 0.306 % vs 良 12 帧 0.324 % = 0.947 倍。这并非对理论 1.414 的反证,而是意味着那个 rms 是”逐星的系统偏差”与”噪声”之和,8 个样本无法单独取出噪声。与第 1 段相同,累积迭代并减去逐星均值后,才只剩噪声。
examples/poc_barcode_1d.py
- L806 — (d) ★measure_pos 的边缘数量对 sigma 非单调依赖。
examples/poc_battery_ct_degradation.py
- L316 — ★
sdf_offset 仅为标量,故要按场偏移就需扭曲格点后再评估。
- L334 — ★为避免叠层穿透罐体,将其局部压缩到挠曲端板所允许的高度(真实电芯中电极也会被加压而收缩)。若不这样做,在较高的气体空隙处,端部层会被罐体吞蚀,层数比较失效(最初就是这样)。
- L612 — ★以”上升边的数量”来数层。若按
vol_wall_thickness 的成对(上升 -> 下降)来数,只要在罐内表面紧内侧多出 1 条下降边,配对就错位,健全电芯也会从 17 -> 16 掉落。
examples/poc_battery_electrode_tortuosity.py
- L136 — ★不在公开路径上的处理:体素空间的 6 邻接图。fullseye 拥有 3-D 的 # 连通分量(vol_label)与距离变换(vol_distance_transform),但 # 没有处理”穿过空隙的路径”的入口(测地距离、输运)。 # ————————————————————————— #
- L248 — ★若直接传入 64 voxel 的切片,面板宽度仅 64 px,标题文字放不下,整幅图就会失败(examplefig 不会默默放弃)。
- L269 — ★若把固相保持为 0,则 log10(耗散) 为负,于是固相被涂得最亮(2026-09-08 曾这样出过一次)。将固相对齐到空隙的最低 2 %。
examples/poc_beam_modal_video.py
- L629 — ★冲突:在 fps 48.5 时,照明的混叠正好落在 f_1 = 3.00 Hz 上
examples/poc_bev_sensor_fusion.py
- L135 — 已放置。★这并非装饰:* 若把面放在单元边界上,面的回波会因噪声向邻元溢出一半,仅靠 discretisation 就使拟合率跌到 0.5。* 若把面放在单元中心,这次轮到真值因浮点舍入而时进时出(确实踩到:侧壁回波所在列偏离真值,133 个伪占据单元中大半即为此)。放在两者之间则两种情况都不发生。
h 避开 0.2 m 的倍数——以显示高度的量化。lx/ly 取 0.1 m 的奇数倍。
- L564 — ★误差是绕世界 z 轴(=与 place 相同)。写成
R_wc @ rz 就变成绕光轴的 roll,重投影误差会化为 1/5(2026-09-07 踩到:得出 0.98 px,与几何预测 f·tanθ 不符而暴露)。
examples/poc_bilateral_asymmetry.py
- L585 — ★保持为可直接通过孔 D 之门的形式(margin 先塌陷,角度随后跳变)。
examples/poc_bump_coplanarity.py
- L147 — ★真实的低阶缺陷(die-attach 空洞 = 中央平缓下沉)。故意不做成严格的二次——若为二次,拟合按定义会吸收 100 %,”能被吸收多少”这一问题便变得自明。
-
| L306 — ★先以 ±SPEC_UM 进行 clip 再传入。examplefig 的发散配色按每个面板以 max |
v |
归一化,若不 clip,3 幅的颜色含义就不一致。 |
- L445 — 6. ★过度扣除之害 —— 会吸收真实的低阶缺陷 # ————————————————————————— #
- L540 — (e) ★经台账的 surface_form_error 只返回 PV 的 float
examples/poc_cad_scan_deviation.py
- L434 — ★台账的 out 适配器把 dict 截断为 (R, t),故 rmse 传不到
- L893 — 第 6 章:★缺陷牵动配准 —— 以向刚体 6 维的投影来预测 # ————————————————————————— #
- L1099 — ★不加入缺陷 —— 若加入,第 6 章的 datum 偏移(0.107 mm)会成为点位移的基垫,与”因初始角度而破坏的量”混在一起。
- L1252 — ★对真值为 0 的对照组给出”%”,会因除以 0 而得到无意义的巨大数值。面积仍以 mm^2 并列,仅在真值有意义时才附上 %。
- L1263 — ★不要把单次运行的差异读作”起效了” —— 变动种子并与离散度比较
- L1353 — ★缺口一旦被填补就会触发的 assert。它确实在 2026-09-07 触发,于是重写了这一行:在收到“无法构建圆柱孔、倒角与圆角”的意见后,添加了 plane / cylinder / torus / capsule。意见改变了工具,所以留下记录后继续前进。
examples/poc_camera_calibration.py
- L150 — ── 校正(自制的最小捆绑调整。★ 缺口 (e))──────────────────────────────────── #
- L176 — ★ 缺口 (d):camera_calibration 的图像点是 (row, col)。project_points 是 (x, y)。
- L304 — ★ 缺口 (b):reprojection_error 不知道畸变。即使传入真值也不会变成 0。
- L525 — 2. ★ 主角:重投影 RMS 几乎相同,但 fx 误差却相差一个数量级以上
- L533 — 3. ★ 抵消机制:fx 的比值与 Z 的比值一致
- L539 — 4b. ★ 诚实的失败记录:在窄视场 + 0.30 px 噪声下,将主点固定在图像中心的零点 B 比去估计它更正确(确实存在无法超越的条件)
- L555 — ★ 缺口 (c):由于是畸变点,拦下它的不是退化门,而是后段的非有限 K 门。还要确认其文案中包含“请倾斜标定板”(2026-09-06 添加)。
- L563 — 5b. ★ 缺口 (c3):闭式解会因畸变而系统性偏离(仅用作初值)
- L567 — 6. ★ 缺口 (b):reprojection_error 不知道畸变 -> 即使传入真值也很大
- L573 — 7. ★ 缺口 (a):内参估计从外观层(facade)看不到
examples/poc_cell_counting.py
- L853 — ★可指定的最小 h 为 0.05 x max(距离变换)。图像中只要有一个大细胞,就会抬高整幅图像的 h 下限(由 op 规格造成的耦合)。
- L1041 — ★这个 PoC 的标题。在偏差曲线穿过 0 的位置,分割误差并不是一个谷。
- L1330 — ★过度合并与漏检是两回事 —— 即使粘连也并未“消失”
- L1358 — ★最优 h 随密度变化(在偏差准则或一对一准则中必有其一会变化)
- L1361 — (5) ★确实存在计数正确但分割全错的点:偏差不到 3 %,但仍残留大量分割误差,一对一对应也远离最佳。
- L1387 — ★可指定的最小 h 随尺寸比一同上升(由工具规格造成的尺度耦合)
- L1427 — (10) ★用机器确认工具的缺口“仍然存在”(一旦修好就会失败 = 好的失败方式)(a) 进化 op 的距离变换按最大值归一化
examples/poc_change_detection_misreg.py
- L947 — ★一张图:残余偏移 vs 假阳性(扫掠曲线 + 配准结果的点)
examples/poc_cold_chain_excursion.py
- L568 — ★寻找峰值的窗口只到下一次门开合之前。若取得过宽,在 τ 较大处会捕捉到下一个脉冲的上升沿,看起来像“悬崖不会到来”(2026-09-08 用 200 分钟的窗口踩过:y=53 的实测拉长到了 153 分钟)。
- L947 — ★把视线方向(D 轴)设为宽度。若保持 (t, y, x) 直接投影,D = 时间 720,只会得到细长的 (H, W) = (60, 12) 图像。
- L1006 — ★区分“命中”是靠约定还是偶然:将每个点扰动 ±1 m 后计数。
examples/poc_colocalization_crosstalk.py
- L355 — ★拖尾损失的预测:阈值 T 以下的 Gaussian 尾部不会进入区域。峰值 p 的点中,区域内的荧光为 1 − (T − 基座)/p(2-D Gaussian 体积的闭式解)。基座 = 细胞质 + 背景(+ 渗入部分),p 会被 PSF 压缩为 σ_ves²/(σ_ves²+σ_psf²) 倍。
examples/poc_colormap_readability.py
- L343 — ★从台阶列中能读出的差是 Δ + 1 个像素宽的斜坡 —— 忘了这一点就会把悬崖高估 2 倍(最初这样写,得到 0.57 vs 实测 0.30)
- L406 — ★用真实梯度去除。不除的话,就会把“场变化陡峭的地方”当作边界来计数
- L657 — ★超过颜色数会被默认拒绝(本 PoC 指出后当天变为 fail-closed)。这里的目的是测量“循环会怎样”,所以显式设置 cycle=True —— 强制显式本身就是对策。
- L732 — ★因本 PoC 的指出当天修复。名单的判据仅为“明度的单调性”,所以明度虽单调但色差步进粗糙的 cividis 却自称“安全”。现在色差的均匀性也纳入判据,cividis 已移至 CVD_SAFE。
examples/poc_compound_eye.py
- L301 (ja) — ★PoC の門(tests/test_poc_scripts_run.py)は exit 0 に加えて “PASS” の印字を 要求する(合否を計算したのに捨てる門を防ぐ規約)。以前は “OK:” と書いていて、 台帳に登録した瞬間に「exit 0 だが PASS を印字していない」で落ちた。
examples/poc_crop_phenotyping.py
- L209 — ★随机数务必以 (n_plant, NESTED_MAX) 的形状预先抽取。若按叶数改变抽取数量,随机序列会错位,n_leaf 仅加 1 就会变成另一片群落(2026-09-07:植被率相对叶数不再单调,无法测量悬崖)。
- L525 — ★
grid_coords 放置的是体素中心(中心间距 = span/res,而不是 span/(res-1))。最初乘以 span/(res-1),在球上产生了 +12 % 面积、+18 % 体积的误差 —— 单位弄错会“错得很像模像样”。
- L971 — ★真值和叶角分布都取自本节所观察的群落本身。若沿用基准条件(7 片叶)的 k,就会因上层叶越发直立的梯度而使真值偏移。
- L980 — ★最大的平面未必是地面(群落郁闭后,冠层的一部分会成为最大)。将第一个平面直接当作地面的版本给出了 1.69 m 的高程(2026-09-07 踩过)。只有加入取最低平面的规则后才稳定下来。
- L1007 — ★对照组:将同一公式应用于真实法线(缓冲区所持有的)。
- L1136 — ★
occupancy_grid 的轴是 (x, y, z)。render_volume_projection 会以轴 0 作为视线方向进行压缩,所以若想要天顶图,需交换为 (z, y, x)。不交换就调用会得到“本想当侧视图的天顶图”(默默出错的类型)。
examples/poc_ct_fidelity.py
- L342 — ★这个 PoC 的标题。可以用眼睛看到 FBP 与零点 A(水平线)和零点 B 相交的地方。横轴是投影数(左侧稀疏)。横轴取 log —— 相交发生在稀疏一侧(12~45 条),线性轴下会挤到左端,关键处读不出来。
- L407 — ★2026-09-06 已填补。以前固定的是损坏行为 =“检测器加倍会使质量亏损改善 2 倍以上”。现在固定两点:(1) 质量本来就是守恒的 (2) 不随检测器数量变化(因为 n_detectors 是检测器的宽度,而非采样的精细度,所以只要目标能容纳,增加的部分只是多出空 bin)。
examples/poc_ct_void_morphology.py
- L233 — ★用晶粒占据来替代时,在粗体素下 50 µm 厚的晶粒会落在体素中心之间,基准本身消失(在 60 µm、相位 2/3 时实际变成了 0 个)。
- L558 — ★把全 nan(任何相位都无法测量)传给 np.nanmean 会发出警告。“无法测量”不是求平均的对象,所以在此显式设为 nan。
- L634 — ★绘制前先剔除 nan(无法测量的点)—— 折线 op 会拒绝非有限值。
- L808 — ★缺口填补后就会触发。2026-09-07 触发,于是重写了本节 —— 在收到“esdf 接受长度为 3 的 voxel_size,但绘制其输出的一侧却仅限立方”的意见后,query_distance(和 occupancy_grid)改为接受按轴的 res。
- L917 — ★体积率即使在粗体素下也得以保持,先失效的是形状指标(预测落空的一侧)
examples/poc_datacenter_thermal_field.py
- L221 — ★2026-09-08:此 PoC 记录了「没有从散乱点构建场的入口」,因此加入了
fs.interp_scattered。落在凸包之外的点由 op 以掩码返回,因此无需用 isfinite 去猜测(即使把 fill_value 设为有限值也不会出错)。
- L862 — ★破坏门来验证「假峰 0」是否真的在计数。
examples/poc_dem_terrain.py
- L42 — ★若不把仓库根目录加入路径,就找不到
demops(本例不 import fullseye,因此路径钩子不生效)。
examples/poc_dfm_thickness_overhang.py
- L284 — ★朝向(正反面)由缠绕顺序决定,但 marching cubes 的缠绕顺序会随输入的符号约定而翻转。若是闭合网格,则由带符号体积唯一确定 —— 用公式而非目视来决定。
- L379 — ★不要把格点原点对齐到墙面。在 3.0 处切割会使墙面正好落在 voxel 边界上,8 个扫掠点全部误差 0.000 mm,得出「不会发生量化」的错误结论(2026-09-07 曾经这样写过)。实际的网格划分器不会把格点对齐到零件的面,因此采用不对齐的原点。
- L455 — ★不要只在「T/h 为整数」的点上扫掠 h。整数比时占用体素的数量恰好为 T/h 个,误差 0.000 mm 排成一列,看起来像「不会发生量化」(2026-09-07 曾经这样写过)。要连续地扫掠 h。
- L705 — ★不要纳入正好 45 度的倾斜方向 —— 板背面 2349.7 mm^2 自身也会贴附到阈值上,「哪个朝向更好」的表格会被台阶的问题所劫持。
- L824 — ★当孔被填塞时触发的 assert。它在 2026-09-07 触发,于是重写了这一行 —— 因收到「没有逐面的面积」的指摘,加入了 face_areas / mesh_volume / boundary_vertices。记录下已被填塞并继续前进。
examples/poc_dic_strain.py
- L104 — ★用从基准图像确定的单一常数进行归一化。若按每幅图像的最大值来除,只要形变使最大值稍有移动,整体亮度就会改变,从而给假设亮度不变的估计器(Lucas-Kanade / Horn-Schunck)叠加无关的误差。
- L211 — ★固定所见:由于形变不是插值而是斑点的重绘,整数移位应当严格一致。若此处崩溃,则第 2 节及以后的「真值」将不再是真值,也就分不清测量的是估计器还是我们自己的插值器。
- L247 — ★固定所见:三者都必须以数量级取胜于仅回答「没有移动」的零点。哪怕有一个跌破 10 倍,该估计器在此场景下就不堪用。
- L282 — ★固定所见。(1)piv 的偏差在扫掠全域内都小于 lk / hs。※「小一个数量级」只在第 2 节 u=0.37 的单点成立(0.0002 vs 0.0042 = 21 倍),而扫掠的最大值之间约为 6 倍(piv 0.0015 / lk 0.0088)。这里把最大值之间保守地固定为 2 倍。
- L365 — ★固定所见。(1)lk 与 piv 将 100 µε 以 ±30 µε 的精度回收(实测 +9.1 / +0.4)。
- L369 — (2) ★hs 对 100 µε 只返回 22 µε —— 上面的「符号和数量级会出来」不适用于 hs(正则化把均匀应变本身抹平了)。由于主张与实测不符,故以实测为准固定下来。
- L413 — ★固定所见。(1)2 度的旋转在微小应变下如理论所料成为约 -609 µε 的谎言(材料并未伸长)。相当于钢的屈服应变 2000 µε 的三成。
- L438 — ★在均匀梯度(ε 关于 x 为一次)下不会变钝 —— 因为对称窗的最小二乘会严格返回一次函数的斜率。要看到窗的效果,需要带曲率的应变场。切口尖端的应变集中正是如此,因此植入高斯形的集中。
- L484 — ★固定所见。(1)lk 的峰值随窗宽单调下降(正是空间分辨率的极限)。
- L522 — ★只切一个角来计数,会随窗的取法变动 2 倍。使用全部窗的平均。
- L577 — ★固定所见:把斑点加粗后偏差单调减小。第 3 节看到的 lk 偏差并非只是估计器的性质,散斑的采样不足占了一半。若此处不再单调,「0.01 px」主张的依据便会崩掉一根。
examples/poc_die_tilt_tsv_overlay.py
- L167 — 格点的展布。★若不包含 erf 的尾部(±4σ),在倾斜的裸片上外周的通孔会在每个 z 上被以不同方式切割,产生虚假的倾斜。
- L241 — ★经由台账的 vol_label 与 docstring 不同,只返回 labels(
(labels, n) 的 n 被丢掉了。第 9 节的 (f))。
- L297 — ★这里不要减去 MU_SI。探针在通孔之外穿过的是空气(0),因此原始值直接与材料的占有率成正比。若减去并 clip,边缘平缓的部分会被压到 0,长度从 100.0 -> 98.1 µm(-1.9 %)。
- L484 — ★减去对照组,只提取「倾斜所增加的部分」(消除估计器的系统误差)。
- L634 — (f) ★同一个 op 会因调用路径不同而返回值的内容不同。
examples/poc_dimensional_inspection.py
- L521 — ★rms 是否可信 —— 对抗性地只把一个点向外移动。
- L1553 — ★2026-09-06「被埋没」的状态得到解决。以前是
n_reach == 0(固定其到达不了)。现在固定其能够到达。
examples/poc_document_scan.py
- L271 — ★直接把 sobel_dir 作用于二值掩码,会把梯度方向量化到 0/90 度,一点一票的带方向 Hough 就会坍缩到那两条线上(实测:4 条线中有 2 条正好是 0.00 / 90.00 度)。先模糊再测方向。
examples/poc_fabric_defect.py
- L83 — ★掩码的面积故意调成大致相同。合并后的 AUC 接近以阳性像素数加权的平均,因此若其中一方大一个数量级,「合并后被隐藏」就不会发生。
- L119 — ★掩码半径按 σ 的倍率分别设定 —— 为了让面积相当。若面积相差一个数量级,就会变成「合并后的 AUC 即面积较大者的 AUC」,本 PoC 想测的「合并后被隐藏」就被偷换成「面积大的一方获胜」这另一回事。
examples/poc_fiber_orientation.py
- L376 — 第 2 节。★★朴素的平均在 180 度周期下崩溃 # ————————————————————————— #
- L469 — 第 4 节。★★不选择权重的话,取向度必定偏小 # ————————————————————————— #
- L499 — ★由于角度是周期量,用 colorize_depth 上色会使 0 度与 179 度成为完全相反的颜色。fullseye 中没有循环 LUT 的名字,但把 (cos2θ, sin2θ) 传给 colorize_flow 就能得到二倍角的循环 LUT(见末尾「工具的漏洞」(f))。
- L693 — ★存在「coherence」这个名字,但那是信号处理中的双信号相干性(另一回事)。
- L724 — (e) ★同一族的两个在输入检查上不一致。
examples/poc_fly_vision.py
- L623 (ja) — ★ラミナ段(DC 落とし)を省くと相関が落ちる、を固定する。落ちなくなったら fly_emd_response の側で DC が消えている(仕様変更)なので、この対照を見直す。
- L650 (ja) — ★PoC の門(tests/test_poc_scripts_run.py)は exit 0 に加えて “PASS” の印字を 要求する(合否を計算したのに捨てる門を防ぐ規約)。
examples/poc_focus_stacking.py
- L491 — 1. 图是有效的。★阈值为 +3 dB——半导体实拍图像大部分是平滑金属(芯片、引线),这些区域单帧就已合焦,因此 AIF 的提升不如全面高频的合成图案那么大(这是现场的真实情况;旧的全面纹理场景曾得到 +14 dB)。
examples/poc_forensics_roc.py
- L396 — ★漏洞 (a) 是「常数图」,因此画成图就无需去读数字。
- L523 — ★本 PoC 的标题。最强检测器的曲线,只按一次保存按钮就跌到对角线(乃至更低)。
- L677 — (4) ★漏洞 (a):op 的 argmin 读出,对再保存过的图像实质上是常数图。AUC 恰好为 0.5 = 与随机无法区分。
- L704 — (9) ★漏洞 (b):8 像素格。仅当差为 8 的倍数时才猜中(无再保存)。
examples/poc_gear_tooth_metrology.py
- L199 — 成像系统的模糊。★2-D 高斯模糊没有直接传 σ 的入口,因此从进化 op 的旋钮 a 反算 σ = 0.3 + 2.7 a 后传入(见末尾「工具的漏洞」(c))。
examples/poc_geodetic_height_frames.py
- L408 — ★往返无法排除「两者朝同一方向出错」。要与独立实现相互对照。
-
| L437 — ★预测(在测量前打印):坡度为 atan |
∇H |
。使用 h 则为 atan |
∇H+∇N |
。 |
- L464 — ★把预测与实测的最大差异区分为「模型误差」还是「离散化」。把网格单元细化。
-
| L584 — ★预测(闭式):下坡方向转过 90 度以上 ⇔ ∇H·(∇H+∇N) < 0 ⇔ |
∇H |
^2 + ∇H·∇N < 0。测量前先算出比率。 |
-
| L644 — ★第二个(才是真正关键的)闭式。视线由两端的 h 连成,所以 N 的线性部分在视线和地面上叠加量相同而抵消。剩下的是 N 偏离弦的量 = |
N’’ |
d^2 / 8。此处 N’’ 为 2C(cos^2θ - sin^2θ),所以 |
N’’ |
<= 2C。 |
- L1106 — ★只有
vertical 时 op_find 返回 5 条。没有一条相关(如 boundary_vertices 的词干匹配)—— 不能靠数量就说「存在」。
examples/poc_interferometry_step.py
- L159 — 3) ★重复测量 — 区分偏差与离散 # —————————————————————— #
- L202 — 4) ★与零点(包络线的最大采样)的比较 # —————————————————————— #
- L274 — 6) ★噪声扫描 — 在何处无法测量 # —————————————————————— #
- L314 — ★离散小并不能证明正确
examples/poc_leak_localization.py
- L591 — ★预测 C 的检验 —— 细密地变动漏水位置,把小数部分打散
- L726 — ★对照组 —— 只把反射左右对调。若偏差方向反转,就能说原因是「较远的接头决定偏差方向」。
examples/poc_lidar_terrain_change.py
- L406 — ★无法测量的 core 面积完全不计入土方量。也返回按有效率反除后的值 —— 不反除就会把「悄悄缺失的土方量」当成正确值。
- L694 — ★接近真值的数字未必「正确」—— 把方向相反的两个误差分开计数
- L823 — ★有效 core 太少时,LoD 不算作「已测量」(2 个点的标准差能算出数字但没有意义)。
- L826 — ★若在此处抽稀,C2C 就会去测「抽稀后的点间距」,密度依赖随之消失(最初写成统一到 6000 点时,任何密度下都成了恒定的 0.42 m)。
- L946 — — ★ 对齐掉多少,变化就消失多少 ————————————– #
examples/poc_lightfield_depth.py
- L594 — 2b. ★ 缺口 (d):docstring 说是 0-d,实际是 (1,)
- L610 — 6. ★ 缺口 (a):默认 linear 会把 1.15 拉向 1.0,cubic 不会
- L634 — 10. ★ 缺口 (e) 已于 2026-09-06 堵上。已改写为固定住已堵上的状态这一侧(以前是 assert「会发出警告」)。
examples/poc_livestock_body_volume.py
- L1032 — ★3 台与 6 台的切线集合完全一致(平行投影下相对的 2 台相同)
- L1040 — ★奇数的 13 台胜过偶数的 16 台
- L1054 — ★3-D 凸包无法替代「截面的凸包」(会把胸围大幅偏离)
- L1057 — ★2 倍律:胸围误差随体重翻倍(残差为 2 次项)
examples/poc_machine_condition_fusion.py
- L184 — (联轴器, 轴承A, 轴承B, 整机) 的发热 [W]。★正常、不平衡、松动是故意做成相同的 —— 从原理上无法用热区分的 3 种模式。
- L202 — ★和轴承一样热。不同的只有扩散范围(两个轴承 + 整机)。
- L1028 — ★2026-09-08:这里原本自己手写了 numpy 的 rfft —— 因为读到「台账里没有单边幅值谱的入口」,但
fs.spectrum 一直都在(只是没在台账里出现)。这是只看一层就断定「没有」的例子,故改为使用 op 的写法。
- L1162 — ★2026-09-08:这里原本写着「台账里没有 spectrum」,但
fs.spectrum 从一开始就在(dsp 的 1-D 层)。缺的只有「在台账(fs.ledger)里出现」和「每个 op 的笔记」;这个 PoC 只查了一层就断定「没有」,自己手写了 numpy 的 rfft。现在把 ops1d 接入台账后,两边都能查到。
examples/poc_mesh_quality_repair.py
- L602 — ★让它饱和显示。原始差异最大 %.2f mm,直接上色会使 99 %% 的像素为 0 而全黑,成为「跑了但什么都没出来」的图。
- L816 — ★用双对数绘制。线性轴下误差会挤到粗糙一侧的 1 个点,斜率(=误差律)完全无法读出(2026-09-07 曾这样画过一次)。
- L832 — ★直接叠加累积分布会使 4 条都挤在 0.9 以上而无法读取。移动的是上尾,故以分位点 0.5〜0.99 为横轴,纵轴画「该分位点的曲率」(逆累积的上半)。
- L568 — ★实测比这更慢。掩膜上实际被抹去的晶界像素比例 f_eff 小于 f(模糊会把相邻的黑漏到缝隙两端各 1 px,局部阈值将其拾取),故与用 f_eff 重新推得的预测 ΔG0 + 6.64 log10(1-f_eff) 对比。
examples/poc_multibeam_bathymetry.py
- L518 — 合成回波的部分角数目。★把它设为 61 时,在 70 度处相邻部分角的到达时间相差 330 µs,超过脉冲宽 64 µs,于是包络变成梳齿,幅度检测会拾取其中一个齿(检测偏差为 -1131 µs)。用直方图构建到达时间的密度并与脉冲卷积更正确。
- L546 — ★不要把下限裁到 0 —— 正下方波束会只剩一侧,照亮的带宽减半(曾以脚印减半的形式踩过一次坑)。
- L703 — ★把横轴除以该波束自身的回波长度。以原始 µs 叠加会让 70 度(21 ms)独占坐标轴,使正下方与 45 度挤成一条竖线。
- L706 — ★
plot_series 会拒绝 xlim 之外的点(因为它们贴在边框上,看着像真数据)。裁剪是调用方的职责,故先裁剪。
- L1125 — ★不要看重叠的正中间 —— 那里两条测线的摆角相同,误差叠加量相同而差为零。要取整个带内的最大值。
- L1196 — ★纵轴取高度(= −深度)。直接用深度绘制会上下颠倒,使「微笑」形状看起来像「愁眉」。
- L1267 — ★纵轴为 −深度。直接用深度绘制会得到海面在下、海底在上的颠倒图。
- L1301 — ★
op_find 以词干部分匹配来命中,所以即便数量不为 0,内容也可能无关(“footprint” → sk_median_disk)。要看到最上层的名字再说「没有」。
- L1428 — ★全路径的悬崖比预测更靠前。差异来自幅度检测的偏差(闭式中没有的量)
examples/poc_nuclei_ploidy.py
- L686 — ★确实存在方向相反的两个失误相互抵消、伪装成「与真值完全一致」的行
examples/poc_pallet_load_utilization.py
- L232 — ★甲板上的点会因噪声上浮到 +3σ,所以用地板阈值截断。不加这一步,即使是零溢出的货物也会出现 0.006 m3 的“溢出”。
- L479 — ★g = w 正好相等时,就变成了“格子是否碰巧对齐”的赌局。
examples/poc_panorama_drift.py
- L108 — ★缺口 (a):以下 4 个在 fs 门面和 fs.op 中都没有出现
examples/poc_particle_sizing.py
- L213 — ★只用一个种子时,这条曲线的起伏就只是波动。用 4 个种子把均值和离散度分开后,再说它“越过”了。
- L428 — ★对照组 —— 只把既未融合也未断裂的团块,与该团块所成像的那个粒子本身一对一地比对。若真值一侧用全部粒子,“越大的粒子越容易融合”这种选取偏差就会混入,与采样偏差无法区分(起初就是这么写的,弄错了)。
examples/poc_particle_tracking.py
- L702 — ★返回的不是掩膜,而是 (N, 3) 的 (z, y, x) 坐标(2-D 的
local_max / sk_local_maxima 返回图像,所以族内不一致。第 10 节的缺口 (g))。起初用 count_nonzero 计数,把数量级搞错了。
- L777 — ★为把向上 3.4 倍、向下 0.93 倍装进一张图,纵轴取 log10 比值。0 表示“正好是真值”。若保持线性,向下的偏差会被压扁而看不见。
- L792 — ★叠加原始 MSD 时,4Dτ 的直线支配一切,看不出差异。改用除以真值的比值后,偏离 1.0 的方式(=损坏方式)就能从形状上读出。
examples/poc_photoelasticity.py
- L160 — ★固定所见:这是对 fullseye 的 Mueller op 的严格验算,即使让 δ 以 15 度步长走一圈、θ 取 5 种,也在机器精度上一致(实测 2.2e-16)。若此处松动,第 3 节之后测的就不是“读取流程”,而是 op 的 bug。
- L181 — ★也固定应力场本身的验算。若积分得到的力与载荷不一致,就不是“真值”;中心值应在代数上等同于闭式 8P/(πDh)。
- L207 — ★固定零点的水平。之后所有的“◯倍”都以这 1.09 MPa 作分母,所以此处一动,比较的含义就变了。
- L231 — ★固定所见:从单张暗场图只读整数条纹的朴素方法,连零点的 2 倍都赢不了。因为分辨率被 fσ/h = 1.78 MPa 的步长所限。与第 4 节相移(误差降到机器精度)的对比是本 PoC 的骨架。
- L286 — ★因为在零噪声下从同一强度公式反解,θ 应严格还原(从 4 张平面偏振求 4θ 的代数本身就是逆映射)。
- L308 — ★固定所见。(1) 一致率超过 95 %,但达不到 100 %。其余是被 (δ,θ) ↔ (-δ,θ+90°) 二义性翻转符号的像素,单波长单次测量原理上无法消除。就把“既非几乎吻合,也非完全吻合”这个所见原样固定下来。
- L371 — ★固定所见。(1) 没有退偏(Stokes 幅值严格为 1)。这是第 5 节主张“调制下降的不是光量,而是相位灵敏度”的依据。
- L377 — (2) ★★实测说的恰恰是“传入掩膜就能修好”这一朴素期待的反面:无掩膜 97.0 % / 排除欠采样 97.1 % / 连低调制也排除则降到 81.9 %。因为抽掉低调制像素会使区域被割裂,skimage 的 unwrap 会为每个岛选取不同的 2π 偏移。“两者都可用掩膜排除”作为预报正确,作为处方却错误。固定实测值。
- L442 — ★固定所见。(1) 若既无噪声也无量化,δ 从明场/暗场之比中严格还原。
- L445 — (2) ★“仅” 8 bit 量化的误差,与“仅”噪声 σ=0.002 的误差同量级(实测 0.00277 vs 0.00305)。相机的位深与噪声一样重要。
examples/poc_pigment_unmixing.py
- L860 — ★“不要归结为一个数字”的根据本身。同一行中 1.000 与 0.013 并列。
- L1082 — ★把没能取胜这件事也留在图里。没有任何一条复原落在零点线以下。
examples/poc_pipe_wall_loss.py
- L423 — ★健全区要选“没有任何缺陷落入的 z”。起初我把 z=20..60 写成健全区,但那正好在管底腐蚀的正上方(壁厚 4.5 mm)。
- L471 — ★r_in/r_out 以像素(体素)为单位。若按 mm 传入,会采样到视野之外,返回值全为 0(无声无息。起初就因此出了一张全黑的图)。
- L817 — ★由于按每个面板归一化,先裁到同一范围再传入(不裁的话只有 E0 按 ±4 mm、其余按 ±1 mm 上色,无法比较)。
- L1040 — ★缺口一被堵上就会响。2026-09-07 响了,于是重写了本节 —— 因收到“按 mm 传入会毫无异常地全返回 0”的指摘,当环落在视野之外时改为 fail-closed。记录它从“返回空并沉默”变为“拒绝并告知”。
examples/poc_print_registration.py
- L151 — 网点线数 [lpi](商业印刷的惯用值)。★故意避开整数比:取 1200/150 = 8.00 px 时,所有网点都落在相同的小数位置,采样相位对齐,合成器就出现伪影(实测重心每个小数偏移跳动 1.4 px)。实际扫描中,分辨率也几乎不会是线数的整数倍。
- L405 — ★台账的入口会为匹配声明的 out 类型而丢弃 info,所以要用
.raw(这个坑在 fullseye/init.py 的注释里带实测记着)。
- L855 — ★FM 一侧不收窄搜索范围(收窄也不改变结果,但为了堵住“AM 的折返是因为搜索范围”这种借口)。
- L1242 — ★两级失效的点,必定是粗略值超过单元半径的点(固定包含关系)
- L1277 (ja) — ★2026-09-13: ‘lattice’ だけ例外を 1 つ許す。flyvision 族の
fly_hex_lattice(複眼の六角格子)が この語を含んで CI で鳴った(run 34751219513)。あれは網点の格子ではないので印刷の穴は 残ったまま —— 例外は名指しで 1 件に限り、それ以外が現れたら今までどおり鳴る。 「語で引く穴の固定」は、無関係の族が同じ語を使った瞬間に偽陽性になる、という実例。
- L1316 — ★基准也加入噪声 —— 零噪声图像会让 star_detect 因“0 颗星”而抛出 ValueError(这本身就是正确的 fail-closed)。
- L1339 — ★2026-09-08:因本 PoC 的指摘而修正了 op 一侧。在 docstring 中带实测数字写明“不能用于重复结构”,并让它把投票的第二高峰 / 最高峰作为
vote_margin 返回。用赞成率无法区分的两者,用这个数就能区分。
examples/poc_print_warpage_risk.py
- L364 — ★新生成的层被放在“当时已经翘曲的面上”(单元的诞生在变形后的构型中进行)。若忘了在此初始化,只有后长出的层保持零位移,用列平均测得的翘曲变成 1/4(2026-09-07 踩过)。力学(K 与 f)在公称格子上,故不变。
- L808 — ★颈部整个消失。部件会分成两块,所以不能求解。
examples/poc_pv_thermal_survey.py
- L381 — ★MOD_SHELTER 是一个健全但吹不到风的模块。在第 3 节,它在全局平均基准下会变成“故障”。
- L482 — ★模块编号要按每个编号的面积比决定。对编号取平均再取整,会使边界像素变成相邻编号(或 0),从而破坏逐模块处理。
- L711 — ★模块中位数的代价 —— 对整个模块的异常盲目
- L1169 — ★
apply_cmap 若不传 vmin/vmax,就会按该数组的 min/max归一化(导致每个条件下颜色含义不同),所以务必传入。
examples/poc_real_coin_metrology.py
- L136 — ★即使数目相符,也未必数的是同一样东西。要确认 1 个圆恰好落入 1 个成分(一对一)—— 不做这一步,“24 = 24”也会碰巧成立(1 个两片粘连的团块 + 1 个杂点,仍是 24)。
examples/poc_real_deblur_honesty.py
- L199 — ★要守护的不是“谁获胜”,而是获胜者随度量而不同这件事。若把方法名固定,就会变成“仅因实现变好”就失败的门。
examples/poc_real_defect_floor.py
- L156 — 振幅的步长。★它本身就是一个旋钮。若太粗,极限会被舍入到同一格点,从而把“σ 越大差距越大”这类由步长制造的差异误读为真实(2026-09-09,在 34 级时 σ=1.5 与 σ=3.0 的中位数都舍入到 3.20)。
examples/poc_recycling_sorting.py
- L520 — ★在扫描之前,先从代数给出预测并打印出来。
examples/poc_registration_basin.py
- L656 — ★当用户认为“法线明明是有的”而显式传入
estimate_normals 时。这里是缺口的残余,比默认值差 14 个数量级。
- L836 — ★缺口 1 已于 2026-09-06 封堵。此 assert 已改写为固定已封堵的状态一侧(以前固定的是损坏状态:
d_fixed < 1e-6 < d_default = 已损坏)。若损坏方式回归,这里会失败。
- L847 — ★缺口 2 已于 2026-09-06 封堵。以前是
< 0.9 * len(ka)(固定损坏状态)。现在固定的是保持默认即可完全一致。
examples/poc_rotation_invariance_audit.py
- L115 — ★HALCON 风格的区域矩不变量。与用于 3-D 点云的
moment_invariants 不同(仅凭名称选择会要求 (N,3) 而失败)。
- L208 — ★当分母接近 0 时,相对偏差失去意义。对于接近圆形的形状,Hu[1] 的真值接近 0,因此若默默用 % 来表述,就会变成“偏差 30 %”。
- L220 — ★预测落空之处。写的时候我以为“对灰度插值后再二值化会更粗糙”,但在周长方面结果相反。
- L262 — ★由于背景是单色,轮廓用有彩度的颜色绘制。灰色没有彩度,因此有彩度的颜色能靠色相与任何灰阶区分——比反色更可靠,而且一眼就能看出“这是叠加的线”。反色真正发挥作用是在背景为彩色、“无论选哪种颜色都可能冲突”的时候。
examples/poc_safety_clearance.py
- L114 — ★躯干由并排放置两个胶囊体构成。若用单个圆柱体,截面会变成圆形,肩部(距躯干中心 ±0.19 m)会脱离躯干的阴影——真实躯干的截面是宽 0.50 m / 深 0.30 m 的扁平形状,伸出的手臂从背后看会被躯干遮住。
- L126 — ★X0 与速度经过挑选,使得“每次试验中真实分离距离始终为正(不接触)”且“在危险带停留足够长的时间”——若让其快走,会在数帧内穿过危险带,用于统计漏检的样本就不够。
- L673 — ★若在保留遮挡的情况下改变密度,遮挡偏差(+0.12 m)会叠加到每一行上,使密度的影响看不出来。逐个关闭因素正是对照组的作用。
- L683 — ★噪声与抽稀只抽一次时,漏检率会上下波动几个 %。跑 3 次取平均。
- L840 — ★按行批量评估(逐个单元格的 Python 循环会跑 15000 次)。
- L1079 — ★体积 op 是 (depth,row,col)。grid_coords 是 (nx,ny,nz),所以要转置。
examples/poc_scan_to_bim_asbuilt.py
- L658 — ★施加 trim 会持续只挑选“拟合良好的点”,落入 RMSE 0.13 mm 的另一个解(实测:trim=0.9 时吸入角为 0.17 mrad,无 trim 时为 0.62 mrad)。在 as-built 检查中,缺陷本身就是较大的残差,所以 trim 会把缺陷丢弃。
- L950 — ★把标题主张放进一张图:完好无损的天花板,仅因对齐方式就显得倾斜
examples/poc_sea_ice_concentration.py
- L232 — 2. ★零基准 vs 线性混合分解 # ————————————————————————— #
- L252 — 3. ★★团块大小(周长)决定偏差 # ————————————————————————— #
- L291 — 4. ★★偏差的符号随密接度反转(抵消点) # ————————————————————————— #
- L353 — 6. ★当端元偏移 5 % 时 # ————————————————————————— #
- L380 — 7. ★★第 3 成分(薄冰) # ————————————————————————— #
- L490 — (b) spec_unmix 是存在的(★在写“没有”之前查了 3 层)
examples/poc_search_sweep_width.py
- L829 — ★形状的作用方式因搜索类型而异。统一扫描宽度,只比较曲线形状。
- L869 — ★用漏检率 1-P 来绘制。若用 P 本身,会贴在右上角、被图例框挡住而看不见(实际上就曾被挡住一次才察觉)。图要先看“是否读得出来”再定——即使数字正确,被挡住就传达不了。
- L1089 — ★可重现性检查:由于种子和帧数都与 §3 不同,看在相同条件下会变动多少。
- L1266 — ★要超过零基准(在假阳性率对齐的前提下)。增益是保守的——“即便零基准也能达到 174 m”才是本节的发现,因此固定的是这一点。
- L1272 — ★落空的预测:减去整体背景是仿射变换,因此实质上等同于零基准
- L1286 — ★落空的预测:在实测的 p 下,平行搜索在 C=1 时达不到 1.000
- L1290 — ★形状只对平行搜索有效:统一扫描宽度后,随机一致而平行分裂
- L1293 — ★落空的预测:本以为平坦的曲线更强,结果反而更弱(因为拖尾长)
- L1296 — (6) ★W 加倍 与 t 加倍 等价
- L1304 — (8) ★看守者:误检集中在正下方。仅凭阈值 W 就会大幅变动
- L1322 — ★填补缺口一侧的门(2026-09-08)。由于给 op_find 加了日文段,并在 star_detect 的 docstring 中写了领域中立的描述词,因此固定在日文查询中能排在前列。若退化,这里会报警。
- L1327 — ★唯独“点 检测”至今仍不出现——单字“点”也必然出现在 cv_canny / frei_amp 这类轮廓 op 的说明中,因此同分并列把它挤了出去。不掩盖这一局限:日文段只有在“两字及以上的词起作用”时才拾取得到。
examples/poc_solar_el_inspection.py
- L366 — ★校正线也要通过同一成像系统(模糊)。未经模糊直接贴上的校正线,其响应比真实裂纹强 2.4 倍,使陡崖偏向粗的一侧(2026-09-07 踩到过)。
examples/poc_solar_limb_darkening.py
- L317 — 2. ★零基准(50 % 法)vs 梯度最大 vs 减光模型 # ————————————————————————— #
- L367 — 3. ★★扫描减光系数 u —— 不是成比例而是折弯 # ————————————————————————— #
- L391 — ★对照组——关闭模糊后,剩下的只有几何(50 % 面的位置)
- L427 — 4. ★★模糊的作用符号随阈值改变(抵消点) # ————————————————————————— #
- L488 — 5. ★黑点 —— 3 % 的离群点会使半径变动 # ————————————————————————— #
examples/poc_star_astrometry.py
- L264 — 图像合成(★ 缺口:fullseye 中没有在指定坐标放置星点的公开 op) # ————————————————————————- #
- L1243 — ★ “每次小”和“总体小”是不同的主张。
- L1348 — ★「均匀·孤立」的偏差为 0.0000 是理所当然的 —— 板解正是用那 24 个拟合的,所以最小二乘让残差的均值为 0。要看未使用的星上的误差,需逐个剔除后重新求解。
examples/poc_stockpile_volume.py
- L698 — ★度量不同,胜者会互换:体积用水平底面,重心用平面拟合
- L714 — ★落空的预测:插值不是偏小而是偏大
- L717 — ★相互抵消:含插值的外周使误差看起来小,只用可见点时又回来
- L726 — ★工具的漏洞。dem_viewshed 修好后这里会报警(这正是目的)
- L728 — ★2026-09-08:因这个 PoC 的指摘修好了 op,所以现在可见才是正确的。固定它与自建的视线判定一致、且接近闭式解(若再坏则报警)。
examples/poc_strain_history.py
- L507 — ★闭式预测。中央 = (w²-1)/24 x d²(速度)/dt²(平滑化的钝化),因果 = 返回延迟 (w-1)/2 的过去速度。
- L578 — ★不制作把历史本身叠加的图 —— 真值·累积·直接用肉眼无法区分(误差为真值的 0.1〜3 %),只会成为看起来「吻合得很好」的图。只输出能看见所测量之物的图。
examples/poc_structure_4d_deterioration.py
- L349 — ★遮蔽以设计形状(
p_nom)判定。当数 mm〜数十 mm 的劣化使 surface 进入自遮蔽的盒子内侧时,缺损最深处会整体缺测,制造出「越深的缺损越看不见」的虚假场面(2026-09-07 踩到:缺损谷 -21 mm 的 core 全变成 NaN)。
- L437 — ★
fit_plane_3d 的法线符号是任意的。对齐到真正的外向(扫描器一侧)。
- L507 — ★经由台账只返回声明的 out 类型(pose),所以用
.raw 全部接收。
- L696 — ★实际尝试「若密度不同是问题,那就统一它」(voxel_grid_downsample)
- L1257 — ★直接从点云统计可观测的信息量本身(正规方程的对角分量)
- L1299 — ★先取测量方法本身的地板 —— 无劣化、无姿态误差,只测两次。
examples/poc_surface_roughness.py
- L272 — ★真值要 在声明频带之后 定义。真值不是粗糙度成分本身,而是「用 λc 截取之后的粗糙度成分」。若这里用原始的 rough_true,即使按正确步骤测量也会偏 -23%,那 23% 会与采样误差混在一起。不含频带的「粗糙度真值」并不存在 —— 这也是第 2 节的主张。
examples/poc_template_tracking.py
- L93 — ★ 漏洞 (a):没有返回相关图的公开 op,所以借用 private。在第 0 章检验其与公开 op
fs.op.ncc_locate 一致后再使用。
- L326 — ★ 漏洞 (d):若是公开 op,这里会静默返回 [0,0,0]。改为明确返回失败。
- L1138 — (2) 零点存在地板 —— 整数坐标的量化(★ 漏洞 b)
- L1168 — (9) ★ 主题:置信度的强项与弱项会随条件反转
- L1172 — ★ 各自擅长的崖是相反的 = 无法把其中任一个选作置信度
examples/poc_thermal_radiometry.py
- L507 — ★前向是直接积分,逆向是校正表。用同一张表往返会平凡地得到误差 0,就不算测到了地板。
- L528 — ★Case-0 之所以严格为 0,是因为 350.0 K 恰好落在表的节点上。偏离节点就能看到插值误差 —— 把 0 称作地板就是谎言。
- L757 — ★横轴是相对周围的升高。若保持 T_obj,发散会塌缩成左端的一条竖线,读不出关键的「从哪里开始跳」。
- L767 — ★
plot_series 会拒绝框外的点(因为它们会贴在框上,看起来像真实数据)。发散的一侧由调用方先行裁掉。
- L821 — ★横轴是绝对的 Δε。若用相对 Δε/ε 作图,三条会完全重合(因为如 §2 所述 ε 从式中消去)—— 作为图什么也说不出。
- L1154 — ★guard band 用的是上侧的伸出。因为我们想判为合格的是「真值不在阈值之上」,所以在区间的上端裁切。若用下侧 off[0],会裁得过浅(分布右偏多少就浅多少)—— 曾这样写过一次,因误合格没有减少才察觉。
- L1257 — ★同样的取错,在 ε=0.10 的面上 L_obj 会跌为负而抛出异常。也就是说「停下还是静默出错」不是由取错决定,而是由场面决定。
- L1331 — ★发热部要做成平台。若做成山峰,「螺栓与周围同温」不成立,就无法区分表观的谷是因发射率还是因温度。
- L1378 — ★校正消除了偏差,但把噪声放大 1/ε 倍。这就是图 (d) 中只有螺栓发糙的原因。
- L1450 — ★
op_find 以词干的部分匹配来抓取。blackbody 返回 4 条,但内容是 cv_blackhat 等形态学,与热辐射毫无关系。看数量就判「有」会出错。先看到开头的名字再说。
- L1600 — 3. ★落空的预测:绝对误差温度越高越大
- L1602 — ★即使改变度量,发射率的误差也不会随上升比发散(在 Δε/ε 处封顶)
- L1605 — ★发散的是反射表观温度这一侧(升高越小越跳)
- L1618 — 6. ★★覆盖率。在地板(ρ=0)处 RSS 与 MC 都是 95 %,加入相关后 RSS 会下降
- L1622 — ★MC 一侧稳定在 94.4〜94.6 %(并非恰好 95 %)。区间端点由 40000 次试验的百分位决定,故有采样误差,现实中还混有量化。把这些都包含在内地说「MC 是准的」。
- L1638 — 7. ★漏判偏向一侧(对称的 ±k·u 会漏掉偏斜的分布)
- L1642 — 8. ★★guard band:误合格为 忽略 > RSS > MC,误不合格则相反
- L1662 — ★校正消除偏差,代价是把噪声放大 1/ε 倍(接近 ε 之比 9.5)
examples/poc_thermography_ndt.py
- L61 — ★观测时间要取得足够长——超过健全部的 t* (6.8 s)。太短的话健全部的膝会跑到窗外,TSR 会把健全部答成「窗边缘的深度」(实测中卡在 2.82 mm)。
- L126 — ★仅此处为近似。由于一维解不含横向扩散,故在每个时刻以扩散长 σ(t)=√(2αt) 的高斯在面内做模糊。物理的标度律是对的,但不满足边界处的质量守恒。
- L142 — TSR 搜索 t* 的范围。★排除两端不是装饰 —— 高次多项式的 2 阶导数在端点必然发散(Runge)。不排除的话 argmax 会贴在第一帧或最后一帧,深度贴在窗口两端的 2 个值上(实测,2026-09-06)。次数扫过 4–11,最终定为 8(4–5 时 1.5 mm 以深会贴在端点,8 以上与 9/11 给出相同答案)。
- L177 — ★把 t* 舍入到格点步长会让深度呈阶梯状量子化(64 点时为 5 % 步长)。用 3 个点拟合抛物线,求出 ln t 的亚格点位置。
- L235 — ★固定所见。这里是近似零的验算,一旦崩坏就说明实现坏了。
- L249 — ★估计器本身的偏差。完全不经过图像,对严格的 1 维曲线施加
tsr_depth。这里产生的误差就是「多项式拟合的下限」,从第 3 节以后的偏差中减去它,剩下的才是横向扩散与噪声的贡献。
- L267 — ★固定所见:下限不为零但很小。从两侧夹住 —— 若变为零,第 3 节的重新解读(「即使不经过图像的曲线也会偏差数 %」,±5 % 与下限几乎相同)就不成立;若变大,就无法把第 3 节以后的偏差归因于横向扩散。
- L302 — ★固定所见。这 2 行同时成立正是本节的主张本身。(1) 把 16 个归并成 1 条平均后,TSR 输给「始终回答 1.50 mm」的零点基线。
- L332 — ★固定所见。(1) 直径为深度 4 倍以上的右下三角在数 % 内命中(与第 1 节的下限几乎相同)。
- L362 — ★对照组:关闭横向扩散的同一场景。这样就能区分「横向扩散的锅」和「像素不足/取不到掩膜的锅」。只看一边就归咎于物理,是这类实验最常见的错误。
- L409 — ★固定对照组的所见:关闭横向扩散后,16 个全部落入 ±8 %。这 1 行就是「坏掉的原因只有横向扩散一个,既不是像素粗糙也不是取掩膜的方式」的依据。放松它,第 3 节的结论就会退回到『提高分辨率就能修复』的误读。
- L419 — ★如果上面的推理(窗口末端的扩散长度起作用)正确,那么截断窗口就能修复。立下假设后,务必安排 1 个能证伪它的实验。 —————————————————————— #
- L440 — ★固定这个 PoC 最重的所见 ——「纵横比的极限」不是物理,而是拟合时间窗口的选法。(1) 窗口 4 秒时,8 个小的全部落入 ±20 %(实测最差 -14 %)。
- L528 — ★固定所见:若加热均匀,原始单帧检出最多,而 TSR 的 2 阶导数一个也检不出。「对深度估计有效但不适合检测」= 同一工具未必对两者都有效,正是本节的主张本身。
- L575 — ★灯的映入。带有与缺陷同尺度结构的正是这一个。
- L602 — ★固定所见。(1) 会破坏它的只有 (c) 的与缺陷同尺度的不均匀。(b) 的平缓倾斜几乎不破坏原始单帧 —— 这里正是「预料落空」之处,所以明确确认 (b) 不低于 (a)。
- L683 — ★也给默认的 cube 加入 NETD。噪声为零时,健全区的面内起伏严格为 0,SNR 会变成 1e9 这样无意义的数(实测后修正)。
examples/poc_timelapse_growth.py
- L472 — ★把格子相位振 5 种,把偏差(均值)与离散(幅度)分开计数。
- L610 — 2) ★Y 字 —— 沿着穿过合体组中心的行切割体积
examples/poc_traffic_counting.py
- L256 — ★在画面左右被截断的行,其重心会被拉偏。也测量剔除它们的版本。
examples/poc_tree_ring_dendro.py
- L229 — ★斜着读像素图时,边界处的编号会以 k, k+1, k, k+1 抖动(最近邻的阶梯)。少于 5 个样本(1.25 px)的短游程被吸收进前一个值 —— 放任不管的话真值边界会多出 1–2 条,变成「年数吻合方向 18 + 不吻合 13 = 31 > 24」。
- L336 — ★用 threshold=0 全取,台阶高度自己测。measure_pos 的 amplitude(梯度瓣两端之差)在木纹使梯度不再单调时会停在台阶中途,把 0.14 的台阶返回成 0.05(在第 8 节计数)。
- L345 — ★用于换算回 px 的外缘半径取自测量的那一行。若用整个 15° 扇形的中位数,偏心生长会让外缘在扇形内移动 10 px 以上,于是外侧的年轮全部错位(最初就那么写,把年轮 18–35 整段丢掉了)。
- L543 — ★即使在年数弄错的方向,宽度相关性是否仍高 —— 年数与宽度的相关是不同的量
examples/poc_vegetation_cover.py
- L320 — 所以这里降到绿、红 2 个波段来求解。★工具的漏洞。
- L543 — ★是否落在对角线上,正是「能否以分数形式作答」本身。二值方法的线会变成阶梯,在混合像素的带上大幅偏离对角线。
- L755 — ★用图展示「只有数字对上了」。第 3 张和第 2 张几乎没有共同像素,却只有白色像素的数量是平衡的。
- L953 — (7) ★PPI 在噪声下崩坏 —— 即使纯像素占 6 成以上也拾取不到叶子。而噪声为零时在同一场景命中 = 断崖的原因不是纯像素不足。
- L993 — (11) ★这个 PoC 发现并在 fullseye 0.1.10 中修复的漏洞。三个 Otsu 对同一输入返回了不同答案 —— 仅把同一图像乘以 4095,判定就偏移了 otsu 13.34 pp / cv_otsu 13.92 pp,只有 sk_otsu 是仿射不变的。原因是
ops._otsu 和 backends._u8 中的 np.clip(v, 0, 1)(0..255 的 float 会使全部像素饱和而变成「全部前景」)。现在三者都不随倍率而变。cv_otsu 残留的 0.5 pp 是因为 OpenCV 内部量子化为 8 bit,这是与 docstring 一致的行为。门是 tests/test_value_range_saturation.py。
- L1007 — (12) ★工具的漏洞:spec_unmix 拒绝 B=3(彩色图像)= 没有求解 RGB 的路径
- L1013 — (12b) ★确实存在只有覆盖率数字对上、而一个像素都没命中的场景。这 1 行就是「不要归约成 1 个数字」最强的依据。
examples/poc_veiling_glare.py
- L229 — ★fullseye 侧的核对:艾里斑 → psf_to_mtf 是否与闭式一致
examples/poc_vessel_network.py
- L263 — ★涨落要在模糊之后加。先加的话 PSF 会把它抹平,阈值边界仍保持干净(最初就那么写,即使把振幅提高到 0.35 也一根毛刺都没出现)。
- L452 — 节 2-3. ★★毛刺从何而来 / 修剪阈值依赖于分辨率 # ————————————————————————— #
- L560 — 节 4. ★★直径的估计 —— 在分叉附近必然过大 # ————————————————————————— #
- L620 — 节 5. ★★Murray 指数 —— 直径的 1 成会变成指数的 1 # ————————————————————————— #
- L751 — 节 6. ★交叉的对照组 / 因分辨率而丢失的枝 # ————————————————————————— #
- L890 — (c) ★skeleton_prune3d 不是「修剪短枝」,而是「把所有枝都缩短」
- L903 — (d) ★fs.skeleton_nodes 的 docstring 说是「坐标」,却只返回端点
examples/poc_warehouse_flow.py
- L145 — ★「等人」4 件 x (7.5 + 缓行 2.5) 与「通道干扰」8 件 x (2.5 + 缓行 2.5) 都向零点加上 40.0 秒 —— 是故意凑齐的。未必与现实一致,但「相同数字出自不同原因」可用 1 例展示。
- L160 — 零点的「静止」阈值 [m/s]。★若不放得远高于噪声制造的表观速度(σ√2/Δt = 0.085 m/s @ Δt=0.25 秒),就会把静止的人误判为移动,使零点减少(取 0.15 m/s 时,Δt=0.25 秒下零点减半,得出「拍得越细滞留越少」的假结论)。
- L239 — ★只要有任意 1 台能看到就算可见,所以进入盲区是所有摄像头都被遮挡的高度 = 各摄像头极限的最大值。这里我取成了 min,导致预测偏差 0.5 m。
- L329 — ★排队者的到达时刻要从实际开始作业的时刻来确定(用估算来定就偏差了 20 秒,等待的柱与作业的柱没有重叠)。
- L342 — ★相遇的位置必须在货架列的正旁边。不在货架与货架之间的交叉通道两侧敞开、空余宽度有 1.9 m,不会被归类为「窄通道」(最初的实现让他们在主通道的高度相遇,10 件中有 4 件落入「其他」)。
- L435 — ★做成了合并而非交换(swap)—— 交换不会破坏「在同一根柱中,较晚开始的一方是等待方」这一时间嵌套(只是角色互换,两个角色都被正确填入)。会被破坏的是当两个人看起来像一个人时。
- L594 — ★只保留静止的芯。柱由两人份的足迹构成,有 1.8 m,因此穿行者的中心也会有 2〜3 帧落入柱内(实测中这制造出「只有一个人的干涉」,10 件中落掉了 8 件)。将持续停留在距中位数 :data:
CORE_R 以内的最长连续段作为芯。
- L846 — ★按多人成分来计数会使「通道上有 10 人通过的列」变厚而混杂,所以在同一个人内部比较「等待期间」与「行走期间」。
- L1257 — 标记的大小。★由于在同一货架前会发生「等待补货」与「缺货」,所以从大的标记开始画,把小的标记叠在上面。若以相同大小绘制,后画的会完全遮住先画的,图上 5 件看起来只有 2 件。
examples/poc_water_level.py
- L346 — 2. ★零点 vs 单应性 # ————————————————————————— #
- L389 — 3. ★符号会随锚点(anchor)的位置而改变 # ————————————————————————— #
- L422 — 4. ★波动 —— 稳健(robust)只在存在离群值时才有效 # ————————————————————————— #
- L459 — 5. ★★反射 —— 系统性地偏低 # ————————————————————————— #
- L622 — (d) 卡尺(caliper)是存在的(★正要写「没有」时,翻了 3 层后找到了)
examples/poc_web_roll_periodicity.py
- L123 — ★第 1 nip 与第 2 nip 的周长差故意只有 15.7 mm(为了第 6 节的悬崖)。
- L158 — 只对第 6 节(悬崖)提高试验次数。★在 24 次试验时,报告率在 12000 mm 为 100 %、在 14000 mm 为 88 %,出现了非单调,「检测悬崖」的位置随小样本波动而移动(在 120 次试验时 12000 mm 稳定在 93 %,能保持 100 % 的是 17000 mm 以上)。只有主张悬崖位置的那一节,用地板不晃动的试验次数来测量。
- L253 — ★op 不做取整地返回顶点(超过 ±0.5 就是「那里不是极大」的信息)。由于这个 PoC 也评估梳状的谐波 bin,所以在这里显式取整。
- L802 — ★地板不是 0。在 24 次试验中,最长的 2 个点偶然为 0 %,使得「保持 0 % 的最短 L」这一判定通过了,但在 120 次试验中,即便最长 20000 mm 也残留 2 %。先测量地板,再决定以地板的多少倍称为悬崖(不把 0 % 用于判定)。
- L1057 — ★改为 120 次试验后就不再正好是 100 % 了(97 / 98 %)。24 次试验的「100 %」只是分母小而已。看着地板把它设在 95 %。
examples/poc_weld_bead_scan_angle.py
- L485 — ★候选是「回到母材面高度的点」,因此沟槽之外平坦的母材也都会成为候选。只有确认在内侧 CHECK_IN mm 处存在焊缝金属(自母材面起有 CHECK_DEV 以上的凹陷)后,才认定为趾 —— 没有这道门,候选就会滑落到母材上,脚长会向外飞出 1.7 mm。
- L489 — ★门的深度要取得比最深的沟槽还深。最初设为 -0.6 mm 时,深度 0.45 mm(垂直方向为 0.74 mm)的沟槽穿过了门,16 个断面中有 1 个偏离了 2.2 mm。
- L572 — ★仅存活断面的真值均值。查看聚合中漏掉了什么。
- L999 — ★只有凸起(余高)偏离了预测。原因是趾部的蔓延(因为 τ 是绝对值阈值)。
- L1193 — ★沟槽随角度逐渐消失的样子(以自母材面的凹陷来看)
examples/profile_shape_inspection.py
- L25 — ★由于要 import repo 根目录下的模块(profileops),把 repo 根目录放在最前,使其从 checkout 直接运行也能通过。与其他示例做法相同。没有它,
py -3.11 examples/<name>.py 会以 ModuleNotFoundError 失败(2026-09-09 实测:在没有运行门的 83 个中,失败的只有这种类型的 2 个)。
examples/representation_roundtrip.py
- L175 — (c) 高斯 -> voxel 的质量。★曾经弄错过的数字
examples/shape2d_morph_descriptor_tour.py
- L64 — ★EXTEND: 替换为你自己的轮廓提取结果(
{"shape": (H,W), "cs": [ (N,2) (row,col), ... ]})
examples/shapestat_landmark_tour.py
- L71 — ★EXTEND: 把你自己的地标 (N,3) 放入 s(点的排列须一一对应)
- L123 — ★EXTEND: 把你自己的群 (K,N,3) 放入 scrambled(位置、朝向、大小可以各不相同)
- L221 — ★EXTEND: 把你自己的地标按「先全部左边,再以相同顺序放右边」排列并放入 lm
- L276 — ★EXTEND: 把 surf 设为你自己的曲面点(网格顶点、点云),normals 设为其带朝向的法线
- L299 — ★EXTEND: 替换为你自己的群 (K,N,3)(点的排列须在个体之间一一对应)
examples/voxel_labels_color.py
- L81 — 1) ★颜色的稳定性 —— 这个族存在的理由 # —————————————————————— #
- L152 — 4) ★各向异性 spacing # —————————————————————— #
examples_3d/alpha_shape_topology.py
- L149 — ★判别性断言:alpha shape 保留孔洞 = 几乎不包含轴探针。null 方法(凸包)以包含率 ≈1 在此条件下 FAIL(= 具判别性)。
examples_3d/ct_hand_radiograph.py
- L34 — 实际调用来确认。★直到 2026-09-05,这个示例写着「若 azimuth=elevation=0 则与 np.sum(axis=0) 一致」,却一次也没确认过。而且由于 op → example 的索引把 hasattr 的字符串误认作调用,「一个示例都没有的 op」被隐藏在 100% 覆盖率之中。
examples_3d/geometry_metrology.py
- L186 — ★以数字给出与无限直线版本的差异(同样的 2 条线段)
examples_3d/hull_bounds.py
- L237 — — 面板 C: ★新增 min_enclosing_sphere(贴合)vs 朴素球(过大)—
- L272 — ★(1) 新增 op — min_enclosing_sphere: 已知球上半径复原 + 包含所有点 + 近乎最小 ============================================================
- L296 — ★(2) 新增 op 的 beat-null — 在非对称点云上比朴素球更小、近乎最小、偏安全侧 ============================================================
examples_3d/mesh_props.py
- L404 — ★把绕序翻转,体积的符号就反转 = 符号本身就是朝向的检验
examples_3d/metrics_eval.py
- L234 — ★最近邻距离说谎,是在「变化为零只是重新测了一遍」的时候。把同一斜面以不同密度、不同位置重新采集,最近邻会沿着表面抓住相邻的点,于是产生约为点间距量级的伪变化。M3C2 向法线方向投影,所以那个分量被去掉了。(写这个 PoC 之前的预测「C2C 在法线偏移下也会偏大」是错的 —— 只是把平行面沿法线方向移动的话,最近邻距离也几乎是真值。说谎出现在沿表面重新采集这一侧。)
examples_3d/sdf_csg.py
- L167 — ★陷阱:即使
res 是标量,它也是每个轴的体素数,所以当 bounds 非各向同性时体素就不是立方体(这里 x,y 为 0.125、z 为 0.0625)。用 h**3 计算体积会正好差 2 倍 —— 实际在本例中给出 295.00,相对闭式解 148.03 有 99 % 的误差,下面的 assert 报警了。
examples_3d/space_carving.py
- L117 — ★使用
carve_look_at(2026-09-08)。与 look_at 是相同实现,但能从公开层引用的名字是这个 —— fs.look_at 是 render3d 的 gluLookAt 版本(4x4、−Z 朝前),是另一回事,传入其 M[:3,:3], M[:3,3] 会使所有点落到相机后方,不抛异常地返回空的 hull。
examples_3d/structured_light_scan.py
- L122 — ★ 座标系陷阱:
look_at 以 gluLookAt 约定(相机朝向 -Z,+Y 向上)构建位姿,但 render_mesh 先把该 Vc 改写为 (x, -y, -z) 再乘以 K(= 与 depth_to_points / K 相同的 CV 约定,depth 为 +Z 朝前)。三角测量是在 CV 约定这一侧闭合的,所以位姿也要先施加 FLIP 再合成。跳过这一步,投影器就会朝向相机背后,而 depth 会保持在「看似合理的量级」却全部错误(第一次运行正是如此:RMSE 78 mm = 与零点无法区分)。
fast.py
- L254 — ★不要发布 uint8 的 gaussian。
cv2.GaussianBlur 的 8U 路径使用 8 bit 定点内核,因此与 float64 core 的差异为 1.174/255(实测,本 module 的 6 张门图 x PARITY_AB 5 点的最大值),不满足「一致到 1/255」。box 为 0.494/255,median / 形态学为 0.000/255,故只发布这些。若需要快速的 uint8 gaussian,请以「到 2/255」的另一契约明确地追加。
- L294 — ★此处列出的全部都是通过了 :func:
parity 门的项。追加时务必遵守「实现 -> 跑门 -> 通过则收录」的顺序。
- L320 — ★不收录
edges_image(作为 HALCON 名与 canny 相同)。registry 中的这个名字是 backends_auto 的 skimage canny(带真正的 hysteresis),与 core 的 canny 是不同的算法。不一致率 1.0(实测)。 – HALCON 名的 twin(在 registry 中以相同实现、别名登记的 op)———- 与 accel._TWIN_ALIASES 同一思路。门是针对 registry 中该名字的实现来跑的,因此实现一旦偏离就会落榜而不被收录。
- L372 — ★不可用「观测到的输出是否为 {0,1}」来判定 – 即便是连续 op,在常数图像上输出也会全为 0,从而被误判为二值、使基准擅自变严(实现过程中踩到过)。判定要用 registry 中声明的 out_sort。
feat_fpfh.py
- L304 — ★2026-09-07:位姿计算是 numpy(FPFH、RANSAC、Kabsch 都是 numpy),torch 仅用于包裹返回值。因此在不装 torch 的 CI(py3.10 / 3.12)上,这个 op 会整体 ImportError,PoC 随之失败。若有 torch 则一如既往返回 Tensor,没有则返回相同数值的 numpy(数值不变)。
flyvision.py
- L187 (ja) — ★ The cap is on the product, not on either factor, because the accident it prevents is the cross term: a modest 900-ommatidium eye and a modest 512x512 image are each unremarkable and together are 236M float64 = 1.9 GB.
fscript.py
- L1269 (ja) — ★2026-09-14: ここは
FsTypeError だけを捕まえていた。逆さの区間と未知の feature を契約どおり FsValueError(= FS_E_INVALID_ARG)にした結果、 fscript の利用者には Python の生の例外が漏れるようになっていた —— 例外の種類を増やしたら、それを言語境界で受けている場所を必ず一掃する ([[feedback_same_bug_class_recurs_check_siblings]])。
fslib.py
- L559 (ja) — ★2026-09-14: ここは長らく borderType 既定 =
BORDER_REFLECT_101 (d c b | a b c d — 境界の画素を重複させない折り返し)だった。numpy backend の ndi.gaussian_filter の既定は mode='reflect' = d c b a | a b c d (境界の上で折り返す)で、同じ「reflect」という語が別物を指す。 実測(512x512, sigma=1.0, 乱数): 内部は 4.6e-08 まで一致するのに、端の画素だけ 最大 0.13 = 値域の 13% ずれていた。内部しか見ない検査では原理的に出ない。 connection の 4/8 連結と同じクラスの欠陥(兄弟コードを一掃した 2 件目)。 契約は numpy 側(既存の進化レシピのオラクル)に合わせて BORDER_REFLECT。
- L615 (ja) — ★2026-09-14: ここは長らく
ndi.label(mask) = 4 連結の既定だった。 cv2 backend は connectedComponentsWithStats(..., 8, ...) で 8 連結なので、 同じ op が backend によって違う物体数を返していた —— 8x8 の市松模様で numpy 32 個 / cv2 1 個。レシピの答えが「どちらの backend が選ばれたか」で 変わるという、いちばん静かな壊れ方。C ABI を Rust で 2 度目に実装して 突き合わせたときに見つかった(fullseye_abi.h の fs_connection に 8 連結と明記した)。回帰は tests/test_fslib.py が backend 横断で見る。
- L630 (ja) — ★2026-09-14: ここは
(mask, 8, cv2.CV_32S) と位置引数で書いてあった。 読むと「8 連結を明示している」ように見えるが、cv2 5.0.0 で実測すると connectedComponentsWithStats(a, 4, CV_32S) も (a, 8, CV_32S) も同じ答え を返す —— 位置引数は connectivity として解釈されておらず、既定の 8 に たまたま一致していただけ。既定が変われば黙って 4 連結になる。 コードが主張している意図を API が守っていない形なので、キーワードで固定する。 (差分ファジングの変異解析で 4 連結を注入したのに一切検出されず、掘ったら 注入のほうが効いていなかった、という経路で見つかった。)
- L723 (ja) — ★契約 R-1(fullseye_abi.h): 失敗した演算子は「何も見つからなかった」演算子と 区別できなければならない。逆さの区間は呼び手の間違いであって、「空を寄こせ」 という正当な指定ではない —— 黙って空の Region を返すと、しきい値の計算を 間違えたレシピが「不良ゼロ」として通る。2026-09-14、同じ契約の Rust 実装が FS_E_INVALID_ARG を返すのにこちらは空を返す、という差分で見つかった。
- L743 (ja) — ★契約 R-1:
threshold で直したのと同じ欠陥が兄弟に残っていた。逆さの区間は 呼び手の間違いであって「空を寄こせ」という指定ではない —— 黙って 0 個を返すと、 面積の下限と上限を取り違えたレシピが「該当なし = 良品」として通る。 2026-09-14、Rust 実装が FS_E_INVALID_ARG を返すのにこちらは 0 個を返す差分で発見。
fsruntime.py
- L284 — ★判定 recipe 在每一种 profile(不限于工业)下都只能使用精选的、以 fslib 为后端的 builtin。其他任何调用都是通过
fscript._call_registry_op → api.RT 解析的 650-op 进化注册表 op,其 _safe wrapper 是 fail-OPEN(吞掉 op 失败并返回无害的”无缺陷”值)。这个面绝不能作为 recipe 的算子——studio / 参考运行时也会判定部件——所以使用它的 recipe 在加载时被拒绝(docs/FSCRIPT_DECISION.md 1.6b)。
fullseye/__init__.py
- L531 — ★与声明 out 类型对齐的 adapter,会丢弃返回元组的 op 的第 2 项及以后(
drizzle_resample 的 wht、piv_cross_correlate 的 info)。当被丢弃的一侧需要用到时,从台账入口就够不着。2026-09-06,某超分辨率 PoC 写成 flow, info = fs.ledger.piv_cross_correlate(...),沿第 1 轴拆开 (2,R,C),把 dy 的第 2 行当作 dx 使用,使偏移估计从 0.12 -> 0.74 像素(不抛异常)。用 .raw 可够到原始返回:fs.ledger.piv_cross_correlate.raw(a, b)。
fullseye/mcp/catalog.py
- L104 (ja) — ★5 層。最初は 4 層で組み、「索引にもレジストリにも facade にも無いノート」が 480 枚残った。残骸かと思ったら 480 / 480 が
fullseye.ledger で解決した (型付き台帳。レジストリでは tb_project、台帳では project のように接頭辞が 違う)。「無い」と言う前に全層を引く —— 4 層目まで引いて止めていたら、実在する 480 個の機能を残骸と呼んでいた。
- L318 (ja) — ★同点の割り方は
api.find_op と同じにする: 別名を複数 op が共有するとき name == halcon の正典を先に。次に層が多い(実行もノートもある)方。 実測 2026-09-15: “gauss” で gauss_filter(正典)と gaussian が同点になり、 名前順だと _ < i で前者が先に来た —— 偶然そうなっていたのを規則にした。
fullseye/mcp/diagnose.py
- L87 (ja) — ★順序が答えを変える(2026-09-15 実測):
ones + inf は有限部の std が 0 なので 「定数」が先に当たり、0..715 の配列は 99.9 % が ≥ 1 なので「飽和」が先に当たった。 より根本的な異常を先に言う: 非有限 → 定数 → 範囲外 → 飽和 → 平坦。
- L106 (ja) — ★飽和・平坦は image / color だけ。region は 0/1 が契約なので「飽和」ではない —— リファクタで region を含めてしまい、
--demo で otsu の出力が「飽和」と判定されて 小図が昇格した(2026-09-15 実測)。region の定数(空 / 全面)は上で拾う。
fullseye/mcp/handles.py
- L47 (ja) — ★thumb_dir を渡されたときに作っていなかった(mkdtemp のときだけ存在する)。 小図の保存が FileNotFoundError で落ち、テスト 4 件で発覚(2026-09-15)。
g1_policy_bridge.py
- L33 — ★不要把本地绝对路径烧进发布物(2026-09-05 的审计中,非公开的兄弟项目名出现在了 PyPI 的 wheel 里)。默认值通过环境变量给出。Unitree G1 的场景 XML。指向 MuJoCo Menagerie 的
unitree_g1/scene.xml。
- L61 — ★安全边界。
pickle 在 load 期间可调用任意 callable,因此若让 find_class 直接放行,则仅仅打开检查点就会执行代码。RL 的检查点是以从他人处获取为前提的产物,所以这是现实的威胁。(2026-09-05 实测:放行版会直接返回 os.system / subprocess.Popen / builtins.eval,并能在 load() 期间实际创建文件。)此处列出的仅是 brax PPO 检查点实际引用的数值类。出现缺失时加入本列表(异常消息会打出模块名)。
honest_summary.py
- L58 — ★把未通过功能门的 auto op 从招牌数字中排除——此前它们只是被 [warn] 打印却仍被计入,用门所拒绝的 op 虚增了”已过功能门”的 parity 数。
- L77 — ★2026-09-08:这一行原本写着 – “= %d evolvable registry ops + %d n-ary capability ops (disjoint).” 实测为 979 + 17 = 979,即 n-ary 的 17 个是
reg_counted 的子集(nary_names - reg_counted 为空)。标题的 979 是正确的,但唯独这条明细行看起来像「加法」,读者一加就成了 996。数字虽对,但形式上说明在撒谎,故已修正。明细能否作为和成立,由 tests/test_honest_summary_arithmetic.py 每次检查。
imgevolve.py
- L50 — ★不要吞掉它(2026-09-06 的对抗性评审)。
imgops_nary 是只需 numpy 和 scipy 的一级 module,因此 import 失败意味着「损坏的 checkout」,而非「该环境没有的功能」。以前是 except Exception: pass,又因为这个函数同时兼任生成器和检查器,CI 可以在保持绿色的情况下发布一个整整消失了 17 个 op 的索引。
imgio.py
- L99 — ★判定有两个(2026-09-08,当天内已修正)。最初只用「CIE L* 的折返为 0 次」来选,但
poc_colormap_readability 实测到 cividis 折返 0 次却立起了色差的脊。即便明度单调,若色差步进不均匀,平滑的场中也会看见不存在的分界 – 它以片面的基准自称「安全」。实测(512 级,相邻色差的 max / median,以及超过中位数 1.6 倍的局部最大的个数): ========== ========== ============== ========== 映射 / L* 折返 / dE max/median / 脊的条数 ========== ========== ============== ========== gray 0 1.33 0 viridis 0 1.38 0 plasma 0 1.38 0 magma 0 1.48 0 inferno 0 1.50 0 cividis 0 2.23 1 turbo 1 1.78 1 ========== ========== ============== ========== 剔除 cividis 是因为本 repo 的近似 LUT 过粗,而非公开的 cividis 本身的问题(其 6 个控制点在逐次映射中最少)。为希望顾及色觉特性来选择的人,准备了 :data:CVD_SAFE。tests/test_pseudocolour_family.py 每次都测量两个基准。
- L124 — 据称即便有色觉特性(P/D 型)也能读出顺序的映射。★
cividis 的近似 LUT 只有 6 个控制点,色差步进过粗,不满足 :data:PERCEPTUAL_SAFE 的基准(实测 dE max/median 2.23)。增加控制点即可同时进入两者 – 由于手抄一手资料的数值有笔误的前科,故在能核实出处前暂缓。
matappear.py
- L167 — ★传入 0 维(标量)时,
r.shape[-1] 会抛出裸的 IndexError(在 2026-09-04 的对抗性审计中被揪出)。分光反射率至少带有波长轴 – 标量不是「每个波长的值」,因此在守卫处明确拒绝。
- L296 — ★真实光栅会向两侧衍射(若沟槽对称,+/-m 的效率几乎相同)。此处若不把 +/- 两侧都放进去,则视光源与视线的位置关系,解可能全为负,「只保留正 lambda」的滤波器就会全部丢弃而漆黑一片。实测:与沟槽正交照射的 CD(delta-sin = -0.55),m=+1,+2 在 lambda<0 处全部消失,m=-2 的 440 nm 才是正解。
match3d.py
- L297 — ★2026-09-07:改用 numpy 的 FFT。式子相同(float32 的 fftn -> 仅相位 -> ifftn 的实部 -> argmax),没有任何地方需要用 torch。在不装 torch 的 CI(py3.10 / 3.12)上,这个 op 会变成 ImportError,PoC 随之失败。
- L1633 — ★2026-09-07:把主体改写为 numpy。这个 ICP 是最近邻搜索用 cKDTree、位姿更新用 3x3 的 SVD,没有一件事需要 torch,却把 torch 设为必需。在不装 torch 的 CI(py3.10 / 3.12)上,4 个 PoC 以
ImportError: this operator needs the optional 'torch' backend 落败而暴露(本地有 torch 所以没能察觉 – 「门要立在事故发生的地方」的实例)。数值是相同的 float64 式,因此结果不因环境而变。返回类型为兼容而保留:有 torch 则 torch.Tensor,没有则 numpy.ndarray(数值相同)。若请求 “cpu” 以外的 device 则 fail-closed。
- L1848 — ★2026-09-07:把主体改写为 numpy。最近邻搜索、6x6 的正规方程、Rodrigues 都是 CPU 上的小型线性代数,本无需 torch,却被设为必需。在不装 torch 的 CI(py3.10 / 3.12)上,PoC 以 ImportError 落败而暴露。式子是相同的 float64,故结果不变(实测与 torch 版之差在 R/t 上为 0、RMSE 上为 0)。
- L2810 — ★2026-09-07:若环在图像之外则 fail-closed。
r_in/r_out 以像素为单位,故若按 mm 传入,会读到视野之外,并无异常地返回全部 0(在 poc_pipe_wall_loss 输出一张漆黑的图后暴露)。若没有一个半径小于从中心到图像四角的最大距离,则返回值只可能为空。
- L2821 — ★2026-09-07:把 grid_sample(bilinear, align_corners=True, zeros padding)替换为 scipy 的 map_coordinates(order=1, mode=”constant”, cval=0) – 同样的双线性插值,在不装 torch 的 CI(py3.10 / 3.12)上也能跑。实测差异最大为 6.0e-06(值域 0..1 的随机图像;float32 与 float64 的舍入之差)。
- L2866 — ★2026-09-07:出于与 polar_unwrap 相同的理由,替换为 map_coordinates(双线性、范围外 0)。无 torch 也能跑。实测差异最大为 7.6e-06。
- L3117 — ★2026-09-07:把 affine_grid + grid_sample(align_corners=False, zeros padding)替换为 numpy 的坐标计算 + scipy 的 map_coordinates(order=1)。torch 仅用于双线性重采样,在不装 torch 的环境(CI 的 py3.10 / 3.12)中这个 op 会变成 ImportError。约定原样照抄:输出体素 (d,h,w) 的归一化坐标为 ((i+0.5)/N)2-1,旋转后用 (g+1)/2N-0.5 换回输入的像素坐标(align_corners=False 的定义)。grid 的最末轴为 (x, y, z) = (W, H, D) 的顺序。与 torch 版的实测差异最大为 7.6e-06。
- L624 (ja) — ★ここを「もう片端が次数 3 以上」と書いていた最初の版は、実測で 一度も発火しなかった: ヒゲの根元が枝の端点クラスタと 26 近傍で 融合して次数 2 になる配置が普通にあり、その場合に素通りしていた (「刈った」と報告しながら 0 本という、いちばん静かな失敗)。
occupancy.py
- L223 — ★2026-09-07:让
res 接受逐轴的值(也可长度 3)。若限定为立方,则像鸟瞰格(薄 z x 宽 xy)这样扁平的体积,连不需要的轴也被强制用同一步进(poc_bev_sensor_fusion 实测:409.6 万体素中只用了 8.1 %)。同族的 grid_coords 一开始就接受逐轴的 res – 对齐了入口与出口契约宽度不同的问题。传入标量的既有调用方不变。
- L317 — ★2026-09-07:让
res 接受逐轴的值(也可长度 3)。此前用 int(res) 只允许立方格,而 esdf 接受长度 3 的各向异性 voxel_size,可用 world 坐标去引其输出的这一侧却限定为立方,成了只有一侧狭窄的契约。在像 CT 的薄接合层 (30,180,180) 这样的格子上会直接卡住(在 poc_ct_void_morphology 中实测)。传入标量的既有调用方不变。
opassist.py
- L50 — ★2026-09-08:ops1d(dsp 16 + funct1d 23)已注册,却既未出现在 docs,也未出现在 op_run / op_assist / op_find – 「注册了」和「查得到」是两回事。加入 opdocs 后,这道门便对查不到的一侧鸣响。
- L242 — ★设计(2026-09-04,用户「能处理各种容器类型固然更好,但统一感也很重要」):最初在
kind 里混入了 “seq” 和 “matrix” – 即值的类型(数值、整数还是选项)与容器的形状(1 个、向量还是矩阵)在同一个字段里相互竞争。从 UI 看,「int 的 3 向量」无法表达,而唯独矩阵的结构位于 seq 键之下,处理各不相同。将此处正交化,kind 只放值类型,容器一律放入 container。标量也不作例外({"form": "scalar", "shape": ()}),因此 UI 可以把分支写成一条。
- L357 — ★最长匹配。若按从短到长看,
sigma_per_mm 会命中 _mm 而变成 “mm”(实际是 1/mm)。单位一错,UI 的数字就会悄悄变成别的东西。
- L454 — ★要点在此:有些参数其默认值并非以 tuple 给出。
center=None(可省略的 (row,col))、必需的 trans(3 向量)、k_cam(3x3 矩阵)… 只看默认值就会看成「一个数值」,UI 便只出一个 spin box 而崩溃。用名字补足结构。
- L610 — ★实测发现:向
prism_min_deviation_deg 的波长输入传入 0..1 的通用 signal,会被「波长须为正值」拒绝,变成一个样例跑不动的 op。若已知单位,以该量的合理范围作种,更接近「一按就动」。
- L730 — 日文(CJK)的连缀。★
_WORD_RE 为 [a-z0-9]+,因此日语查询一个词都取不到(对日语输入而言 _WORD_RE.findall(...) == [])。词干那一段失效,而部分匹配是连空白一起去找字符串,所以日语的多词查询在结构上必定 0 命中 – 在一款 docstring 大半为日语、以 6 种语言分发的产品里。2026-09-08 由 poc_search_sweep_width 踩到而查明(经 op_find 查「点检出」/「光斑检出」/「小目标」的日语查询均为 0 命中,而带亚像素质心的点目标检出只有 star_detect,却无法从日语抵达)。
- L783 — 视为词干一致的公共前缀长度。★取 4 会把 “median”/”medial” 及 “contrast”/”contour” 连到一起;切在 5,则 “correlation”/”correlate”(8)、”segmentation”/”segment”(7)、”rotation”/”rotate”(5)、”gaussian”/”gauss”(5) 能被拾取,而上述两组不会。
- L793 — 公共前缀之后允许的词尾。★仅凭前缀长度判定会把 “median”/”medial” 连起来(共有 5 个字符的 “media”)。看词尾是否像屈折词尾,则 “correlation”/”correlate”(ion / e)通过,而 “median”/”medial”(n / l)与 “corner”/”cornea”(r / a)落选。
- L889 — ★下限。没有它时,”zzz-nothing-matches” 会返回
histogram_match(因为 “matches” 与 match_* 词干一致)。若命中词的权重不足整条查询的 15 %,则视为「未命中」。实测:”digital image correlation” 为 0.19(通过),”zzz-nothing-matches” 为 0.10(丢弃)。
ops.py
- L628 — ★端点用端点值填充。以前是
np.convolve(x, k, "same"),它会把两端的 w 个点与零平均 – 轮廓的起点和终点被朝原点 (0,0) 方向拖动最多 50 px 以上,形成一幅 140 条轮廓的红色条纹向左上收敛的图(2026-09-06,第一次逐 op 作图时发现;数值测试中平均偏差 0.3 px,看不出来)。
- L1498 — ★记录在退化输入下会连整个进程一起崩溃的原生侧 op 的台账(2026-09-05)。
guard 只能捕获 Python 的异常。一旦在 C/C++ 内部越界写入,就到此为止,并连用户的整条流水线一起消失 – fail-soft 最糟的破法。除了在入口拦截别无他法,故带理由列在此处,并在注册时设卡。各平台行为不同正是此台账存在的理由。下面 3 个在 Linux(Ubuntu 24.04 / Python 3.12 / PyPI 的 wheel)上会崩,但在 Windows 上以相同输入一件都未复现。原生构建不同,边界的破坏方式也不同,所以「这类输入就没事」的精细划线不可信 – 对退化输入一律拒绝。不是「修好就删」,而是在能确认上游已修复后再删(这不是我们自己的代码,故删除条件不同)。
ops3d.py
- L375 — ★out 不是 image2d 而是 rgbimage(2026-09-02 实测)。docstring 与实现都是「RGB (size, size, 3) float [0,1]」,唯独这一行自称是 2-D 的亮度图。直到放入 mesh 的种子,这个 op 才被执行,类型谓词以 TYPEMISS「declared ‘image2d’ but returned ndarray(512,512,3)」将其暴露(在此之前,因把 (V,F) 拆成 2 个位置参数的形式,它一次都没被执行过)。其余 3 个 render_* op(ambient_occlusion / cast_shadow / supersample_mesh)如实测为 2-D,故保持 image2d 即可 – 撒谎的仅此一行。
- L465 (ja) — ★新しい sort は作らない: ノード表と枝表は「単位も意味も違う 2 つの表」で、 タプルで返して adapter に
r[0] と書くと 枝表を黙って捨てる (pose_error / m3c2_distance で繰り返した失敗の型)。1 つの dict に 両方を入れれば宣言 ‘table’ が実返りと一致し、捨てるものが無い。
- L616 — ★2026-09-08 追加。此前用于雕刻的位姿辅助(visualhull.look_at)从任何公开层都引不到,而抓到同名的 render3d.look_at(gluLookAt、-Z 朝前)就会无一例外地得到空的 hull(poc_livestock_body_volume)。
- L637 (ja) — ★ out は image2d ではなく keypoints(2026-09-15 実測)。実返りは 像面上の (N,2) 画素座標で、入力 (160,3) に対し (160,2) が出る —— 画像ではない。同じ型の嘘を “render” 節の
project_points で 2026-09-02 に既に直しているのに(「旧宣言 ‘image2d’ は型の嘘で、 pnp3d 側の ‘image2d’ 宣言と噛み合って PnP を壊していた」)、 この 1 行だけが兄弟一掃から取り残されていた。 例外にならないのは _sort_ok が image に ndim == 2 しか求めず、 (N,2) が「幅 2 の画像」として黙って通るから。値域も画素座標 (実測 16.0 .. 47.9)で [0,1] ではなく、image を名乗る限り 下流の閾値 op に渡ると意味を失う。
- L727 — ★曾搁置的理由(a)「points 候选列表变短而悄悄改写既有 champion」,已随 backends_typed.TYPE_TO_SORT 把 coordgrid -> points 折叠而消失:2-D 桥的 tb_sphere_sdf / tb_box_sdf 带有 INPUT_ADAPTERS._points_to_grid,确实会从点云生成坐标场,所以那边的 “points” 声明并非谎言(实测:传入 (64,3) 会返回 (16,16,16) = 是活的)。撒谎的只是 3-D 台账那一侧。
- L882 — ★axis=1。
pairs 的正典是 (N,2)(实测:消费侧 6 个 op 明确拒绝 (2,N))。当谓词还是 lambda v: True 时,这里生成的是 (2,n),把「任何消费侧都无法接收的形状」当作声明类型来自称
- L920 — ★position 的正典是 [z, y, x] 的 3 个分量。不是靠多数表决,而是运行消费侧来定的:refine_translation_lk / refine_lm 在传入 4 个分量时,会以 “init_pos must have exactly 3 components [z, y, x] (got 4)” fail-closed(实测)。生成器也是 (8.0, 8.0, 8.0) 的 3 分量。然而 match_* 系列按 docstring 返回 [score, d, h, w] 的 4 个分量,若声明 out 仍为 “position” 就放行,后段的精化 op 会全军覆没 = 类型的谎言。由于 score 本身是诚实信息,函数一侧不删(get() 保持 4 分量),而在自称台账类型的 call() 一侧只取出坐标(与 project_points 同样处理)。
opsastrostack.py
- L85 — ★ 作为替代,我们明确拒绝原始的 (N,H,W) ndarray。无论是 video (T,H,W) / voxel (D,H,W) / histcube (H,W,T) / zscan,3-D 数组都能通过同一结构检查,即使弄错也不会抛异常,而是返回一个“看似合理却错误的合成结果”——这与 photon 族将 histcube 从 voxel 中分离是完全相同的危险。但这里并非增加类型,而是通过要求它“必须是 list”来获得同样的防御。一旦写成 list(volume),调用方就声明了“首轴是帧轴”。 * image2d —— 合成结果、drizzle 输出、单帧。均为 2-D 的 float64,现有的 2-D op(滤波、阈值、morphology、psf_to_mtf)可保持语义不变地使用。它甚至并非非负(会出现 κ-σ 合成的残差以及样条插值的负值边缘),所以自称为 counts 反而是谎言。 * keypoints ——
star_detect 的返回是 (N, 2) 的 (row, col)。TYPE_CHECKS 中的 keypoints 是“(N,3) 或任意 2-D 数组”,故直接适用,并由 psf_fit / aperture_photometry 消费。
-
L101 — ★ 这里不是 pairs:pairs 的正典是 reprconv 侧的 6 个 op 所确定的“(x, y) 对”,而这里是图像坐标的 (row, col),与 fit_transform / mosaic 是同一规约。混用会导致行与列互换(与本 repo 已知的陷阱同形:features.match_keypoints 返回 (x,y),而 fit_transform 要求 (row,col))。自称 keypoints 至少能共享“图像上的点”这一约定。 * indices —— lucky_select 返回的采用帧的下标(1-D int)。就是既有词汇本身。[frames[i] for i in idx] 即可还原为 images。 * measurement —— noise_sigma 是单个实标量。 * matrix —— frame_align 的 (3,3) 齐次变换。与 transforms / fit_transform / mosaic 所处理的是同一物,没有理由另造专用词。 * table —— dict / list of dict(质量、PSF 拟合、测光)。TYPE_CHECKS 中的 table 为 list |
dict,故两者都适用。不分离的代价(honest):若非天体图像序列进入 images 池,frame_align 找不到星,会以 ValueError 停止。由于这是 fail-closed,所以不是“发现为零”,而是“到达了但被正确拒绝”,但从链式 fuzzer 的角度看,align 系的 2 个 op 可能只沦为 CONTRACT。由于会出现与 photon 族分离 counts 的原因相同的症状(7/17 从未被执行),若实测确实如此,那时将“含点像的图像序列”另立一池的判断才被正当化——不预先增加类型(在本 repo,顺序是:只有在出现“混用会变成谎言”的证据之后才增加类型)。 |
opsdem.py
- L35 — ★ 诚实的局限:
depth 池也可能纳入相机透视投影产生的深度。透视深度中,1 px 在地面上对应多少米会随深度而变,所以用恒定的 cell_size 计算的坡度会看似合理却错误。那为何不分类型——这并非类型弄错,而是与错误给定 cell_size 同一类的错误,而 cell_size 已被设为必需参数(不设默认值)。增加类型也无法防止非正射深度(谓词最多只能看到“2-D 的实数数组”),反而会造出一个没有任何 op 持有种子的 dem 池,使全部 13 个 op 永久未被执行。与其假装用类型防住了防不住的东西,不如用必需参数与 docstring 明示,并选择在 fuzzer 中真正运行它。 * 只有 dem_fill_sinks 的输出是 depth —— 填洼的结果仍是高程栅格,直接进入 dem_flow_direction。此处若声明为 image2d,则族内的链(填 → 流)会因类型而断开。 * dem_flow_direction 是 labels —— 返回是 int8 的 0-7 与 -1(无流出方向),是无序意义的编号。自称 mask 会被当作二值,自称 image2d 会使 3 与 4 的平均具有意义。它直接符合 labels 谓词(整数 dtype,1-3 维)。 * dem_stream_network 是二值但为 image2d —— 内容是 float64,除 0.0/1.0 外还带有缺测的 nan,不满足 mask 谓词(bool 或整数 dtype)。若设为 bool,则“非河道”与“本就无值”将无法区分,故让类型迁就实现。 * 其余全部为 image2d —— 坡度[度]、坡向[度]、曲率[1/m]、山体阴影[0,1]、起伏[m]、地平线仰角[度]、天空可视因子[0,1]、可视[0/1]。均为 2-D 的实数场,现有的 2-D op(平滑、阈值、morphology、伪彩色、图注)可保持语义不变地使用。值域未必是 [0,1],但这与 astrostack 的合成结果处境相同:在本 repo,image2d 并非亮度的约定,而是“2-D 的实数场”的约定。类别 → [(op 名, module, [输入类别], 输出类别)]
opsflyvision.py
- L62 (ja) — ★ 重みは公開しない:
fly_hex_resample の個眼×画素の重み行列は functools.lru_cache で内部にだけ保持し、op の入出力型には現さない —— 出すと「画素座標系に依存する巨大な派生物」が型プールを汚し、下流の 2-D op が それを画像と取り違えて黙って処理してしまう(zscan を video に渡すと通る、と 同じ事故の型)。出さないことでこの取り違えを構造的に不可能にする。
opsimgforensics.py
- L206 — ★
phash 的谓词中,看 dtype 才是本体。若只用 ndim == 1,就与既有的 signal 完全重叠,分离的意义随之消失。
- L208 — ★
fingerprint 的谓词在形状上无法与 image2d 区分。只能靠零均值性来切分,而那是运行时的统计式猜测,所以谓词也带有同样的弱点(因此才用类型来分离)。请把这一弱点留在谓词的注释里。
- L224 — ★
fingerprint 的种子必须始终经由 sensor_fingerprint 生成。若直接放 rng.standard_normal((H, W)),那是白噪声而非指纹,比对将永远返回“无关联”=以为增加了检验面,实则未增加。
- L227 — ★
images 的种子必须是相同 shape 且2 张以上。只有 1 张时,sensor_fingerprint 会持续 fail-closed 而一次也不运行。
- L242 — ★
jpeg_ghost_quality 的 qualities=None 假定为“40..95 步长 5 的 12 个”,所以若 images 的种子不是 12 张,必然抛 ValueError。这是有意的 fail-closed(不返回下标与品质错位的图),故请在 fuzzer 侧对齐张数。
- L246 — ★
watermark_* 的 bits 必须不超过容量(LL 的 8x8 块数)。64x64 的 image2d + level 1 的 LL 为 32x32 = 16 块。
opsinterferometry.py
- L96 — ★ 未搭载到既有
signal 上,是实测的结果。最初判断“csi_signal_simulate ([] -> signal) 会把真正的干涉信号注入池中,故可到达”,但用该配线跑链式 fuzzer 时,在 600 条链(300x长度6 + 300x长度8)中 csi_peak_position 与 chromatic_confocal_height 一次也没有被执行(记录仅有 7 条 CONTRACT)。原因是 signal 种子是带负值的正弦波,入口 op 在同一链中被先抽到的概率很低。这与 opsphoton 在 counts 上踩过的陷阱完全一致,作为 fail-closed 完美生效的结果,“发现为零”看起来像稳健。在以 sweep 为专用池的同条件重测中,9 个 op 全部被执行。混用 2 种类型也不会让弄错悄然通过,这一点由各自专用的判别来保障(两者都以闭式测得阈值):- 把频谱传给 csi_peak_position → carrier_tolerance。干涉信号的载波立于 2/λ(Nyquist 的 0.333),而共焦峰为 0.010。实测中同一检查也能捕获 1000 倍的单位错误。- 把干涉信号传给 chromatic_confocal_height → max_carrier_fraction。共焦响应的 AC 分量只有低频(实测 0.010 / 0.010 / 0.015),而干涉信号是 0.333。入口 = csi_signal_simulate / chromatic_confocal_simulate(两者均无参数即可产生),出口 = csi_envelope (-> signal) 与 2 个 measurement op。
opsoptics.py
- L125 (ja) — ★ pupil_blur は「画像 × カーネル」の一般畳み込み(filters_freq.convol_fft) ではない —— PSF の標本間隔 λN/oversample を検出器ピッチへ面積積分して から畳む、その単位合わせが本体。だから PSF を作る側に置く。
- L140 — ★ 不是 normals(点云的 (N,3) 法线),而是 normalmap。二者形状相似,但传入 (N,3) 会被 _normal_map 以 ValueError 拒绝。此处若声明为 normals,便是“可以传入点云法线”的谎言,链式 fuzzer 每次都会以 CONTRACT 结束,从而一次也不执行此族(=化为发现为零)。
opsphoton.py
- L85 — ★ 需注意:由于 counts 是 1-D 的 float64 数组本身,所以“调用”dsp / funct1d 毫无妨碍(类型词汇是为链式 fuzzer 的 pool 分离,而非 Python 的可调用性)。反向桥 = 将 signal 非负化为 counts 的路径,参见下方的“桥”注记。 * countrate —— SPAD 的计数率序列(Hz)(1-D,非负)。与 counts 同为“非负的 1-D”,但是不同的量,故另立一池。理由有两点,都基于实测:(a) 单位相差 7 个数量级。counts 池的值域约为 0-250 计数,把它传给 spad_deadtime_apply(dead_time_ns=50) 得 250 Hz x 50 ns = 1.25e-5 → 无一例外返回无限接近恒等映射的值。op 虽“到达”,但死时间的物理(饱和、1/tau 的 fail-closed、麻痹型的非单射性)从未被踏及。这与把 histcube 搭载到 voxel 上时相同,是“看似合理却错误的通过”,既不出 CONTRACT 也不出 TYPEMISS。(b) 物理不同。死时间作用于检测器的率流,而非对 TCSPC 的时间 bin 直方图逐 bin 作用(对直方图正确的畸变模型是 Coates = tcspc_coates_correct)。若归为同一词汇,进化搜索会把“对直方图施加死时间校正”这一物理上错误的链学作正当的类型连接。countrate 是明知只有 apply <-> correct 2 个 op 的狭窄 sort(与 jones 有 2 op、stokes 有 3 op 同级)。不过这 2 个 op 互为严格逆,故池内有往返不变量在循环。 * histcube —— 逐像素的到达时刻直方图立方体 (H, W, T),时间轴在最后。既有的
voxel 是“3-D 数组”,TYPE_CHECKS 也仅 ndim == 3,故结构上会通过。但 voxel 是 (D, H, W) 的空间格,轴义不同:把 (D,H,W) 的体积当作 histcube 传入,dtof_cube_depth 会把 W 读作时间轴,返回的不是异常而是“看似合理却错误的深度图”(实测:均匀体积下全像素 0.0075 m)。此外,扁平的 histcube 在 dtof_cube_depth 侧也会被判为 empty 而静默不通过(双重防御)。桥(针对狭窄 sort 的对策,实现未竟=待亲判断):可成为 signal -> counts 之桥的是“把任意实数 1-D 视为非负的光子率轮廓并作 Poisson 采样”的 op(photon_sample 的 1-D 版)。将负值的处理设为显式参数便不成为静默整流,也不破坏纪律。既有的非负输出 1-D op(funct1d.abs_funct_1d 实测 min 0.0023,dsp.envelope 实测 min 0.749,两者均保证非负),若该桥存在,则是 signal -> counts 的自然前段。详见报告。
opspiv.py
- L25 — * ★ 我们新设了
flow2d。既有的 flow_dense 的谓词是 ndim == 4 and shape[0] == 3(3-D 场景流),故 2-D 的 (2, h, w) 本就不适用。借用其名,就等于台账一边声明“返回 3 个分量”一边返回 2 个分量,使声明成谎言。它满足本 repo 增加类型的条件(“若没有持有种子的 op,将永久未被执行”):生成为 7 个 op(cross_correlate / multipass / deform_pass / ensemble_correlate / replace_outliers / to_velocity / sample_at_windows),消费为 13 个 op(含场量 8、可视化 2、检定 2、评估 3 的重叠),族内的生成与消费是闭合的。
- L35 — ★ 我们必给它一个出口(
visualise 的 2 个 op)—— 能造却看不见的类型会在链中途成为死路,产生“狭窄 sort”。双向的 fail-closed 也已实测确认:把 2-D 流传给 reprconv.flow_magnitude 会抛 ValueError(点名以“取 (3, D, H, W)”拒绝),把 3-D 场景流传给 piv_vorticity 会抛 ValueError。 * 输入的图像对是 image2d —— 粒子图像本身就是 2-D 的实数场,现有的 2-D op(平滑、阈值、背景差、图注)可保持语义不变地使用。不保证亮度落在 [0,1],但这与 astrostack 的合成结果处境相同。 * piv_outlier_mask 是 mask —— bool 的 2-D,与谓词一致。与因带 nan 而无法自称 mask 的 dem_stream_network 不同,这里已把缺测折叠到 True(外点)一侧,故以 bool 闭合。 * 统计是 table(dict)。piv_error_stats / piv_peak_locking。 * 转速度的 piv_to_velocity 的输出也是 flow2d —— 单位从 px/frame 变为 m/s 但类型相同。此处诚实写明:类型守不住单位。故把两种尺度都设为必需参数(与 demops 的 cell_size 同一判断)。也曾考虑按单位分类型,但那会成为只有 1 个 op 生成 m/s、无一 op 消费的类型——违反“出证据后再增加”的顺序,故未采纳。
opsrangedoppler.py
- L108 — ★ 订正的记录:本模块初稿写作“在 real 中速度的符号会丢失”,但那是错的(仅对只有距离轴的 1-D 实信号成立,两轴齐全后符号会被保留)。测试先破而发觉。真正丢失的是“一对中哪一个是真的”、振幅的一半,以及无模糊测距范围的一半。
_as_beat_cube 在 dtype 阶段拒绝,并点名修法(显式构造解析信号)。 ————————————————————————– 为避免狭窄 sort 的入口与出口(对已实测教训的应对) ————————————————————————– 本 repo 实际踩过 2 个陷阱:① 无 op 产生的类型永久不可达(score 是 434 op 中唯一 1 件 blocked 的那件),② 搭载到既有池会每次 fail-closed 被弹,看起来像“发现为零”(photon 族 7/17 未被执行的那件)。beatcube 对两者都作了处置:入口(产生 beatcube 的 op):fmcw_beat_simulate(仅参数,无输入类型)fmcw_window_apply(beatcube -> beatcube)出口(返回既有 sort 的 op):range_doppler_map -> image2d(最大池)fmcw_range_profile -> signal beamform_delay_sum -> signal beamform_doa -> table 入口是“仅参数之源”这一点与 tcspc_simulate(无输入类型 -> counts)同形,故链式 fuzzer 需要与 counts 相同的专用生成器(对亲的交办事项;生成器的实体已在报告中经执行确认载明)。出口落入 image2d 与 signal,是本 repo 最大级的 2 个池,故不会成为 jones(2 op)或 countrate(2 op)那样闭合的狭窄 sort。
opsreprconv.py
- L257 — ★
flow 无法用单一谓词写就。因密 (3,D,H,W) 与散在 (N,3) 同名共存,若谓词同时放行两者则什么都守不住,若定于一方则既有 4 op 中必有其一成为 TYPEMISS。分离才是正确的(与将 video 从 voxel 分离同一判断),但那是改写既有 op 声明的工作,超出本模块职责,故此处仅留提案。
opsvolcolor.py
- L63 — ★ 但既有的
labels 谓词为 ndim >= 1,2-D 的标签图像与 3-D 的标签体积同居。本模块的 11 个 op 被传入 2-D 时全部抛 ValueError(fail-closed),故弄错绝不会悄然通过。危险在于相反面:在只有 2-D 种子的池中,会在一次也不执行的情况下看起来像“发现为零”—— 与 opsphoton 在 counts 上踩过的陷阱同形。配线侧务必注入 3-D 标签种子(参见下方“亲配线时”)。 * voxel —— vol_label_overlay 叠加的原灰度体积,以及 vol_label_color_flicker 接收的二值体积。二者都是 (D,H,W) 的既有 voxel 词汇本身,没有理由另造新词。 * rgbimage —— 断面与投影的返回 (H,W,3)。既有的 rgbimage 消费 op(镜面分离、色变换、保存)可保持语义地使用。这里是 rgbvolume 词汇的出口,故新词汇不成死胡同。 * matrix —— vol_label_palette 的返回 (n+1, 3)。就是 2-D 的实矩阵本身。 * table —— 形状统计 / 图例 / 闪烁测量 / 带色网格的集合。
- L77 — ★ 未为“带色网格的集合”另造新词,是实测的结果。最初打算加
colormeshes,但把既有的 table 消费 op 全部过一遍,将 vol_labels_to_meshes 的返回传入(2026-09-02 实测,横跨 ops3d / ops1d / opsmath / opsoptics / opslightfield / opsphoton / opsacoustics / opsinterferometry / opscadmap),能吃 table 的 op 只有 3 件(abcd_matrix / wavefront_stats / istft),且 3 件都以 ValueError fail-closed。即不满足“混用会悄然出错”的条件。给不满足者添词,只会多出一个消费者为零的新词汇 = 多一个死胡同(docs/OP_COMBINATION_MATRIX.md 的判断基准)。此外,若想把单个网格作为 mesh sort 流向下游,用 [(m["vertices"], m["faces"]) for m in result] 剥出 —— 因这是丢弃颜色的操作,故不在 adapter 中隐式进行。 ————————————————————————– 一个新词汇及其理由(基于实测) ————————————————————————– * rgbvolume —— (D, H, W, 3) 的带色体积。既有 lightfield 的谓词只是 ndim == 4,故色体积完全满足 lightfield。实测(2026-09-02,将 (8, 16, 16, 3) 的色体积传给 lightfield 的 op):- lf_refocus / lf_subaperture / lf_epi / lf_depth_from_focus 这 4 个 op 既不出异常也不出 NaN,返回有限的 (16, 3)(各自自称“重聚焦像”“部分开口像”“EPI”“深度”)。是把 z 轴读作角度轴 V、y 轴读作角度轴 U 而得的无意义有限值。- 只有 lf_all_in_focus 因参数不足给出 TypeError(不是类型问题)。反向(把光场传给 vol_label_slice_rgb)会因 shape[3] != 3 而 fail-closed。安全的只有一侧,故不能依赖运行时检查。与将 zscan 从 video 分离同一判断。入口 = vol_colorize_labels (labels -> rgbvolume) 与 vol_label_overlay (voxel + labels -> rgbvolume),出口 = vol_label_slice_rgb / vol_label_mpr_rgb (-> rgbimage)。产 2、吃 2,故不成死胡同。
pcseg.py
- L448 — ★
full_matrices=True(默认)会分配 (N, N) 的 U 并丢弃。2026-09-06 实测:20000 点为 3.73 s / 3.2 GB,而 full_matrices=False 为 0.876 ms(4263 倍),且 Vt 逐位一致。10 万点则会因 80 GB 而崩。同型也存在于 pcseg.fit_plane / measure / ops / camera / pnp3d(都在丢弃 U)。静态门是 tests/test_svd_full_matrices.py。
pivops.py
- L470 — ★ 相关峰立不起来的窗(无纹理、全面一样)返回 nan —— 不返回 0 是为了不把“未动”与“不明”混同。但有几成是 nan 只能从返回值得知,此前的形态是等到
flow.mean() 变为 nan 才察觉(2026-09-06)。在此计数。实测:均匀背景上只有 16x16 方块的图像,98 窗中仅 16 窗为有限(0.163)。全面纹理则为 1.000。
ppf.py
- L126 — ★ 素朴的 PCA 法线符号任意,旋转后有四成的点会翻转。由于 PPF 的特征是法线之间的角度,翻转则键会改变。实测(400 点,绕 z 轴):用素朴法线时键的一致率在 0/37/90/143 度为 100 / 73.6 / 69.4 / 67.2 %,用定向法线则全部 100 %。与
pointcloud.fpfh 踩过的同一个洞,在同一天一并修好。
problems.py
- L147 — ★一个确定性的全局洗牌(基点固定,因此 train/holdout/locked 索引同一个置换),按 seed 的角色分成三个互不相交的带(evolve.run 取 train=seed、holdout=seed+10000、locked=seed+20000,于是 seed//10000 mod 3 选出带)。旧的
off = seed % pool 在 pool 整除 10000 时总是把三个窗口塌缩到同一批帧——一个静默的 train↔holdout↔locked 泄漏,使过拟合 train 的 champion 看起来”在纯 holdout 上胜过手工”。纯粹的三分需要 pool >= 3n;更小的 pool 无法给出干净的 holdout,所以我们拒绝而非静默泄漏。
profileops.py
- L269 — ★ 最初写作“曲率较大的一侧”,在 NACA 2412 上把后缘判成了前缘。三点圆的曲率,在上下面几乎相切的后缘处会比前缘的圆度更大——“前缘是圆的”这一直觉,用轮廓上的 3 点来测时会逆转。
- L276 — ★ 后缘张开时,最远的 2 点会拾取后缘的某一角而使弦倾斜。改在缝隙的中点重取,再把前缘定为“离该中点最远的点”。不这样做,即使对称翼也会出现相当于后缘半缝隙的弯度(实测 0.001257)。
- L642 — ★ 比对前用同一取法重取。弦的框架(尤其是后缘中点)会略依赖点的放置方式,故把生轮廓与重取轮廓相互对照时,即使同一形状也会引入 0.02 度的旋转与 7.8e-4 的平移——这本身就成了偏差的地板(实测 rms 6.05e-4)。要比较的东西须置于同一擂台。
- L653 — ★ 不作点对点,而作点对折线测量。即便按等弧长重取,两者的相位也不一致,故若以编号取对应,则相位错移会直接成为偏差(实测:拿同一形状与自身比,rms 为 6.05e-4——与想检测的缺陷同一数量级)。
realdata.py
- L38 — ★ 只有
public 列为真者,方可用于公开发布的图。仅限研究、教育目的且需注明引用者,带有 cite。
- L90 — ★ skimage 只持有随附的子集,其余在运行时经 pooch 去取。取不到的在本 repo 中不使用(PoC 若依赖网络,出问题时便分不清是实现还是网络所致)。
reprconv.py
- L149 — ★ 转为整数 dtype 时,须在转换前检查生值。敌对检查发现的洞(2026-09-02):
np.asarray(nan, dtype=int64) 不出异常而返回 INT_MIN,转换后 dtype.kind == 'i',故会跳过下面的非有限检查。像 3.7 这样的非整数也会被静默截为 3——下标偏了 1 的结果,无异常地返回。这正是转换 op 的谎言本身。
- L1080 — ★ 真实 bug 的回归点。最初此处为
np.maximum(sigma, finfo.tiny)。在重复点处 sigma = 2.2e-308,gaussians_to_voxel 的 sigma ** 3 下溢为 0,导致 0 除 -> NaN。本想“避开 0”,却替换成了会在下游产生 NaN 的值(体积的一部分在无异常下变为 NaN = 典型的静默出错)。重复点意味着“间隔无法测量”,故不以哨兵填补,而是 fail-closed。
rust/fullseye_core/examples/python_ctypes.py
- L42 (ja) — ★第 5 引数 fs_dtype_t。2026-09-14 までヘッダにだけ在って実装と FFI 宣言に 無かった引数。ctypes は引数の数を検査しないので、抜けても黙って動く。
sample_data.py
- L147 — ★ 加入的理由:在展示 111-113 中再次出现“合成只能造出自己已知的坏法”(有 6 张实拍出现 9 件不良的前例)。PoC 保持离线闭合,只把替换为实数据的入口置于台账。commercial=”check” 及以上者,须先读源的页面再用。
scene_registry.py
- L19 (ja) — ★配布物にローカル絶対パスを焼き込まない。ここは自分のマシンの作業物を指していた ので、他人が pip install した環境では黙って落ちる(しかも「場面が無い」ではなく 「その場面だけ静かに欠ける」形で)。環境変数で受け、未設定ならその場面を登録しない = 在ると偽らない。
loco_mujoco は入っていれば自分で在り処を知っているので探す。
sdf_ops.py
- L293 — ★ 加入的理由基于实测:
poc_dfm_thickness_overhang 与 poc_cad_scan_deviation 报告称 # “机械部件由圆柱孔、倒角、圆角构成,但基元只有球与 # 长方体,故无法用 CSG 拼装”,两者都各自手写了逐面的解析式。此处的 4 个全部为闭式且严格(外侧为到最近表面的 # 欧氏距离,内侧为到最近面的负值),故此后可仅用 CSG 拼出带真值的合成部件。 # ————————————————————————— #
specops.py
- L810 — ★ 这是一个同时依赖染色与成像系统的值,并非万能常数——若在自家载玻片上定量,请拍单染载玻片并用 :func:
stain_vectors_from_patches 重新测量。
- L842 — ★ 第 3 根是“余量”。仅 2 根时 2x3 无逆矩阵,用伪逆则残差会被静默分配给这 2 根。立起正交的第 3 根,把无处可去的密度汇集到那里(=日后可作为残差读取)。
studio.py
- L273 — ★ 直接右键点击图本身(用户 2026-09-06:“若能右键把作为图显示的东西复制到剪贴板就好了”)。这是本 repo 的 Studio UI 规约——显示系也须能从右键完成一整套。可与下方按钮列做同样的事(不要二者取其一)。
- L6119 — ★ 图的承接盘。示例经
examplefig 往此处写 PNG。不传环境变量的运行(CLI)中一张都不写,故只有从画廊运行时才出图(示例的数值与速度不变)。
- L6275 — ★ 图的承接盘。示例经
examplefig 往此处写 PNG。不传环境变量的运行(CLI)中一张都不写,故只有从画廊运行时才出图(示例的数值与速度不变)。
tests/conftest.py
- L28 — ★ 把 Studio 的设置在整个会话内逃逸到一次性 ini。 # ————————————————————————— #
QSettings("Fullseye", "Studio") 会写入原生存储库(Windows 上为注册表 HKCU\Software\Fullseye\Studio)。我们此前把隔离放在各个测试文件里,故被遗漏的文件污染了用户的真实注册表。2026-09-05 的审计确认了实害:10 个 recent_files 中有 8 个是 pytest 的临时路径,system\operator_timeout_ms 等实值也残留着。(隔离只在 3 个文件中的 2 个里,test_studio_params.py 是素通的。)不再逐个添加,而是作为会话 autouse 在此只放一个。环境变量是 studio._settings() 唯一查看的入口,故此举覆盖全部测试。
- L44 — ★ 需要 optional backend 的测试的声明。 # ————————————————————————— # CI 的注记长期写着“不安装 torch/kornia(对应测试 graceful skip)”,但 2026-09-05 的实测显示那并非事实——目标测试并未 skip,而是以
ImportError: this operator needs the optional 'torch' backend 失败(14 件)。只有注记,却没有用机器核实它的机制。此处把声明汇入单一入口。目标是双向:* 无 backend 的环境 → skip(让注记成为事实)* 理应有 backend 的环境 → 不许 skip,令其失败(FULLSEYE_REQUIRE_OPTIONAL=1。CI 的 py3.11 作业会立起它)只有单向时,真正的回归会悄然化为 skip(与 feedback_failsoft_hides_permanently_dead_ops 同形)。
- L192 (ja) — ★2026-09-14 追加。ここまで探針バンクは 6 sort しか無く、901 op のうち 151 本 (16.8 %)が契約ゲート 3 本(例外を投げない / 非有限を出さない / 決定的)を 一度も実行されていなかった ——
PROBELESS_OPS_BUDGET = 151 というラチェットで 本数だけ凍結し、「本来の直しは BANKS を全 in_sort へ広げること」と自分で書いて あった。その本来の直しをここで入れる。 形の出どころは推測ではない: backends_bridge._EMPTY_OF が 12 sort すべての 正準の最小値を宣言しており(そこが sort の定義そのもの)、problems.py の _points_stack / _signal_stack などが実データの作り方を持っている。 各バンクは既存の作法に合わせ、普通の値・定数 0・定数 1・退化形を混ぜる (定数と退化形が「走った」と「意味のある出力」を分ける —— [[feedback_ran_is_not_meaningful_output]])。 ————————————————————————— #
- L215 (ja) — ★点群は連結なものと非連結なものの両方を置く。
tb_geodesic_distances が 不達を inf で表すのは契約どおりで、ops.NONFINITE_IS_MEANINGFUL に 「1.0 に潰すと『届かない』が『近い』に化ける」と宣言済み。 ここで一度 normal をわざと連結にして有限性ゲートを緑にしかけたが、 それは欠陥を隠す方向だった —— 直すべきは門が台帳を見ていないこと。 normal は橋でつないだ現実的な形、two_clusters は非連結を撃つ探針。
- L263 (ja) — ★特異行列は必ず置く。 一度ここから外しかけたが、それは誤りだった ——
tb_mat_cond が特異行列で inf を返すのは契約どおりで、ops.py の NONFINITE_IS_MEANINGFUL に「厳密に特異な行列は s_min=0 なので inf が 正しい答え。有限に潰すと『十分に良条件』と読めてしまう」と既に宣言済み だった。落ちていたのは op ではなく、有限性ゲートがその台帳を見ていない こと。探針を削って緑にするのは、欠陥を隠す行為。 (同じ註に 2026-09-05 の教訓が書いてある ——「自分の probe では特異行列を 作っていなかったので tb_mat_cond を取りこぼした」。探針から外すのは その取りこぼしをわざと再現することになる。)
- L381 (ja) — ★新規(2026-09-14): ここまで探針が無く、契約ゲートを一度も通っていなかった 5 sort = 101 op。残る 6 sort(video / qimage / cimage / lightfield / beatcube = 50 op)は形が複素・4-D で退化形の設計に手間が要るため、 一度に全部入れて切り分け不能にしないよう次の段で足す。
tests/test_abi_apply.py
- L78 (ja) — ★target dir は 別に切る。最初は
target/release(既定)に建ててそこから直接ロードして いたが、同じプロセスで後に走る test_rust_abi_parity.py が cargo build --release (feature なし)で同じ DLL を書き換えようとし、ロード済みでロックされているので ビルドに失敗 → 36 件が黙って SKIP になった([[feedback_zero_findings_may_mean_never_executed]])。 建てる場所を分け、ロードは tmp へのコピーから行う。
- L49 (ja) — ★このパーサは「タグから最初の
; まで」を宣言とみなす。だからタグと 宣言のあいだに ; を含む散文があると、宣言が見つからず collection 中に 死ぬ —— そして pytest はファイル 1 つの collection エラーで スイート全体を中断する(2026-09-14 実測: Interrupted: 1 error during collection で 12,000 件が 1 件も走らず、それでも runner の exit code は 0)。 [[feedback_test_import_kills_collection]] と同じ族なので、何が悪くて どう直すかをここで言う。黙って「malformed」とだけ言うと、壊した本人が ヘッダの書式規則に気づけない。
- L234 (ja) — ★2026-09-14:
FsValueError を足した。それまで例外は 2 種しか無く、 種の違う失敗が同じ status に潰れていた —— 逆さの区間は契約では FS_E_INVALID_ARG なのに FsTypeError(= FS_E_TYPE)を投げていた。 差分テストが「どちらも拒否した」までしか見ていなかったので素通りした。
tests/test_abi_signatures_match.py
- L82 (ja) — ★
[A] + [B] * 3 のような式で書かれた argtypes がある。最初この形を 数えられず fs_measure_all を「1 引数」と誤読して門が 3 件赤になった —— 門のパーサが弱いのを実装の欠陥と読まない。 行末までを 1 宣言として 取り、[...] の各塊の要素数に * N の倍数を掛けて合計する。
- L180 (ja) — ★
cl に .h を直接渡してはいけない —— MSVC は拡張子で言語を決めるので 「ソースファイルの種類は認識できません」と警告だけ出して rc=0 を返す。 検査が 1 行も走っていないのに緑になる、最悪の形 ([[feedback_ran_is_not_meaningful_output]]。2026-09-14 に実際そう読みかけた)。 #include する小さな .c / .cpp を作って /Zs(構文検査のみ)を掛ける。
- L190 (ja) — ★引用は 1 段も挟まない。
subprocess にリストで渡すと Python が 引数を再クォートし、内側の " が \" に化けて cmd に届く (実測のエラー: '\"C:\Program Files...\vcvars64.bat\"' は認識されて いません)。バッチファイルに書き出して、それを叩くのが確実。
tests/test_annotate_bold_italic.py
- L59 — ★ 叠打只会横向变粗。上下变粗的描边会把和文字的内白填满(2026-09-09 实测:11pt 的“量 值 面积”变成了黑块)。
tests/test_astrostack.py
- L1053 — ★ 2026-09-08:新增了第 3 个返回值 vote_margin(第 2 高的峰 / 第 1 高)。若为星野,峰只有一个,故应当小——这一点也在此固定。
tests/test_backends_typed_liveness.py
- L57 — ★ 就这一件而言,记录有3 处——此处、
gen_op_figures.DOMAIN_MISMATCH,以及 op 自身 0/60 的实测。即便如此,“已注册却一次也不运行”的状态仍在持续。知道某事与在判定中使用它是两回事(KNOWN_ISSUES §42)。
tests/test_blob2d.py
- L442 — ★三个物体必须都是不同的形状。把相同形状排列起来的种子会让 circularity 和 holes 都返回相同的值,从而漏掉「无论转哪个旋钮都返回相同数值的 op」。
tests/test_caltab.py
- L121 — ★门是否触发依赖于环境,所以不作断言。只检查值未被隐藏地返回。
tests/test_ci_wheel_check_paths.py
- L68 — ★不看 returncode。这项检查的对象是参数的解析,而不是 wheel 的内容。内容的判定依赖于环境 —— 实测 2026-09-05:在通过 PYTHONPATH 暴露源码的环境中,由于脚本会把 repo 根目录从 sys.path 移除,部分模块无法 import 而报 NG(在 pip install 的环境中不会发生)。因为这里看了 returncode,在 Linux 上这项检查以「路径解析问题」的形式落败。
tests/test_collection_sizes.py
- L64 — ★OPS3D 是 {op 名: 元数据 dict} 的扁平表。用
sum(len(v) for v in values()) 计数会得到各 op 元数据键数的总和(2,492),差点把一个没有意义的数字刻进台账(2026-09-08,在写入前查看结构时发现)。
- L85 — ★2026-09-08 新增:两个用于积累说明的台账。说明最容易悄悄减少,所以在这里计数(docs/CAPABILITIES.md 与 docs/HARDENING.md 的来源)。
- L260 — ★这里棘手的是,这个测试所守护的缺陷在 Windows 上不会重现。实测 2026-09-05:在 Linux(Ubuntu 24.04 / py3.12 / PyPI wheel)上 3 个 op 对退化输入 SIGSEGV。把相同的输入送到 Windows 上一个也没崩溃。所以「本地是绿的」不能作为依据,必须保持在一种能在两个环境上验证台账是否正确生效的形式。 ————————————————————————— #
- L267 — ★
ops.NATIVE_CRASHES_ON_DEGENERATE 的对照。它必须与本体 1:1 一致。只改一边就会落败 —— 从本体删除,或往本体添加,都要求在这里同时改写(= 由人确认意图)。为什么需要对照:在门的变异测试(2026-09-05)中,即使从本体删除 cv_cc_count,检查「台账里的 op 都拥有关卡」的测试依旧通过。从台账删掉的 op 也会从循环的对象中消失,所以整条检查路径连同它一起消失。所守护的 SIGSEGV 仅限 Linux,在 Windows 上碰巧会返回像样的值,所以最后一道防线也不起作用。只有与独立信息源(这一组)的等价,才能在 Windows 上也捕捉到两个方向。与 test_the_two_nonfinite_ledgers_agree 同形。
tests/test_demops.py
- L440 — ★返回始终是 (N, 3)。即使传入标量,得到的也是 (1, 3) 而非 (3,) —— 因为台账声明 points = (N, 3)(2026-09-06,fuzzer 的 TYPEMISS 暴露了不一致,于是把实现对齐到声明)。
tests/test_docs_index_numbers.py
- L37 — ★op 集合随环境变化(Linux CI 没有 torch/kornia/mahotas/xfeatures2d,共 859 op;本地是 885)。把本地生成的文档与活的 registry 比对的检查,只有在满配环境下才有意义 —— 与 test_opdocs 相同的约定,未齐全就 skip(原因里会给出缺少的 backend 名)。在 2026-09-07 的 CI 上,有 22 项在这里落败。与环境无关的检查(文件的存在、内容的量、图的存在)照常运行。
tests/test_docs_index_reachable.py
- L42 — ★op 集合随环境变化(Linux CI 没有 torch/kornia/mahotas/xfeatures2d,共 859 op;本地是 885)。把本地生成的文档与活的 registry 比对的检查,只有在满配环境下才有意义 —— 与 test_opdocs 相同的约定,未齐全就 skip(原因里会给出缺少的 backend 名)。在 2026-09-07 的 CI 上,有 22 项在这里落败。与环境无关的检查(文件的存在、内容的量、图的存在)照常运行。
- L80 — ★只看 Markdown 语法是不够的。
docs/GALLERY.md 在表格中有 14 处使用 <img src="...">,朴素地扫描 ]( 一个也看不到(在 Codex 的对抗性审查中发现,2026-09-06)。也要看原始 HTML。
- L189 — ★允许标记重复,就会让一个旧表格残留下来却依然变绿。生成器只改写第一个 start–end,所以第二个会永远保持旧的并持续被发布(Codex 的对抗性审查,2026-09-06)。
- L210 — ★以前用「有 20 行且能看到 4 个维度名」就通过,但那样即使掉了几百个 op 也会变绿(Codex 的对抗性审查,2026-09-06)。要与每个维度的实数一个不落地核对。
- L249 — ★输出差异在哪里。不输出的话,就无法追踪那种只在整套测试里才落败的顺序依赖问题(如 registry 污染)。
- L312 — ★只有件数和名字,类型契约(in_sort/out_sort)、类别、HALCON 对应、tier 都会保持陈旧却变绿(Codex 的对抗性审查,2026-09-06)。RAG 会读 in_sort/out_sort 来挑选类型能连接的 op,所以那里陈旧就会自信满满地提出连不上的链。要连内容一起核对。
- L457 — ★检查产物「是否有内容」—— 只看一致的门,即使两边都为空也会变绿 # ————————————————————————— # 2026-09-06 的实测。低于它就落败(提高是自由的)。
tests/test_dsp.py
- L338 — ★最大值是谐波:period / (1/f_max_bin) 落在整数附近
tests/test_example_scripts_run.py
- L48 — ★2026-09-09,在加入这个门后的第一次 CI 上,7 个在 py3.12 上落败(py3.11 是绿的)。CI 故意只在 py3.11 安装 torch / kornia / mahotas / opencv-contrib,其他版本不装。测试侧本已有名为
requires_backend 的声明机制,但跑示例的门却没有它 —— 机制存在,和所有路径都经过它,是两回事。gallery2d_* 是「把该族的 op 全部跑一遍」的画廊,所以它的契约本身依赖于装了哪些 backend(它直写 op 名并与 registry 核对,缺一个就以「OPS 里多余」落败)。所以按族声明。剩下 2 个直接用 torch(fit_zernike / match_logpolar_z)。在满配环境(CI 的 py3.11,FULLSEYE_REQUIRE_OPTIONAL=1)里 skip 会变成失败,所以声明过多和漏声明两个方向都会落败。
- L87 — ★不传 PYTHONPATH(这个门的要点)。使用者不会设置环境变量。
tests/test_flyvision.py
- L328 (ja) — ★ The MTF identity is a small-footprint approximation and is NOT claimed
- L329 (ja) — ★ far from the optical axis: at ~35 deg elevation the measured transfer
- L330 (ja) — ★ already departs from exp(-…) by more than the on-axis tolerance. This
- L331 (ja) — ★ assert pins that hole so a future “curvature-corrected” resample has a
- L332 (ja) — ★ failing test to turn green rather than a silent regression to argue about.
tests/test_fslib.py
- L330 (ja) — backend 横断の一致 —— ★2026-09-14 に実際に壊れていたところ ————————————————————————— #
tests/test_fullseye_3dgs.py
- L78 (ja) — ★道具の有無と資産の有無は別。ここは mujoco の有無だけを見ていたので、 Menagerie が無い環境では
scene_registry.resolve() が返す None を掴んで TypeError になった。同ファイルの test_scene_resolution_via_registry は 既に資産の skip を持っており、作法が兄弟に適用されていなかった。
tests/test_gaits.py
- L99 (ja) — ★2026-09-14: ここは
resolve() の戻りを検査せず spec["xml"] を引いていた。 scene_registry が実在しない場面に None を返す設計(資産が無い環境では 正しい振る舞い)なので、資産チェックアウトが無いと TypeError で落ちる。 同じファイル群の test_fullseye_3dgs.py は既にこの skip 作法を持っていた —— 作法が兄弟に適用されていなかった ([[feedback_same_bug_class_recurs_check_siblings]])。
tests/test_glassmirror.py
- L91 — ★与直觉相反:以为「铜比金红」,写了 cu[2] < au[2] 结果落败。就算按公开值,相对于 Au 的 R(450 nm) ≈ 0.40,Cu ≈ 0.56,蓝色是铜更多(= 金是更饱和的黄)。错的是这边的先入之见,而不是表。
- L175 — ★把波长作为第 1 参数的理由(台账的「首个是数据」约定)。以前把数组传给顶角会抛出裸的 TypeError。
tests/test_honest_summary_arithmetic.py
- L41 — 改成「没有就说明理由并 skip」—— ★2026-09-08 的 CI 在这里变红:把本地有的东西也当成 CI 里有,就只有本地变绿(与
feedback_gate_computed_a_verdict_then_discarded_it 同型)。
tests/test_mcp_images.py
- L312 (ja) — ★最初
ones + inf にしていて、有限部が定数なので免除 op でも「定数」判定になり 落ちた —— それは診断器が正しい。確かめたいのは「免除 op なら非有限を異常と 言わない」だけなので、有限部に変化のある入力にする。
tests/test_mcp_server.py
- L57 (ja) — ★引数名を
name にしていて _call(4, "fullseye_op_help", name="gaussian") が TypeError になり、subprocess の実 stdio 往復が 1 度も走らないまま 23 件が緑だった(2026-09-15)。走らなかった検査は無いのと同じ。
- L105 (ja) — ★最初
gaussian が先頭と決めつけて落ちた。gauss_filter と gaussian は同じ HALCON 別名を共有する別 op で、api.find_op は name == halcon の正典を優先する。 検索もその規約に揃えたので、正典が先頭・gaussian が上位に居ることを見る。
- L249 (ja) — ★以前の被験者は台帳経由で索引に入ったこと(= 索引が台帳を数えている)も見る
- L316 (ja) — ★同日実測: 4 層で 480 枚が「どこにも無いノート」に見えたが、5 層目(ledger)で 480 / 480 が解決した。ここが 0 でなくなったら、まず引き忘れた層を疑うこと ([[feedback_search_all_tiers_before_declaring_a_gap]])。ノートの残骸と決めつけない。
tests/test_no_local_paths_in_shipped_code.py
- L22 — ★
tomllib 是从 Python 3.11 才有的。在模块顶部做裸 import 会在 3.10 上中断收集,一个测试也不跑 —— 2026-09-05 用 hypothesis 踩了同样的坑之后,紧接着在这项检查里又复现了(CI py3.10 collection error)。import 失败一定降为 skip。
- L53 (ja) — ★2026-09-14 追加: MSVC の標準インストール先。
fullseye_3dgs._find_cl_dir() が cl.exe を探すための候補として持っている。これは「私のマシンの作業物を 指している」のではなく「Visual Studio インストーラが決める場所」なので、 環境変数に追い出しても他人の環境で当たりやすくはならない(むしろ探索が 効かなくなる)。glob で実在を確かめてから使い、無ければ None を返す作りに なっていることを確認済み。 ※ _WIN_ABS は空白入りの語を 2 つ目までしか拾わないので、切り出される断片は C:\Program Files\Microsoft までになる。許可文字列は実際に切り出される形に 合わせる —— 正規表現の結果を見ずに「あるべき文字列」を書いて外した(2026-09-14)。
tests/test_op_contract_property.py
- L32 — ★在没有 hypothesis 的环境里,这一个文件的 import 失败会让整体停下 —— pytest 会因 collection error 中断,不再跑剩下的(2026-09-05,CI 在 2 分钟内死掉,一个测试也没跑)。降为 skip,别把别的也拖下水。
tests/test_op_contracts.py
- L52 (ja) — ★2026-09-14 実測: 901 op 中 151 本(16.8 %) がこの状態で、空ループを 1 周 しただけで緑を返していた —— 「門が判定を計算した直後に捨てる」の親戚で、 こちらは 判定を一度も計算しない。まず skip で見えるようにし、
test_probeless_ops_do_not_grow で本数を台帳に固定する(減る分には通る)。
- L56 (ja) — ★2026-09-14: 本来の直しを入れて 151 → 0 にした。 上に「本来の直しは
conftest.BANKS を全 in_sort へ広げること」と自分で書いておきながら、 ラチェットで本数を凍結したまま 9 日が過ぎていた —— 台帳は免罪符になりやすい ([[feedback_never_weaken_the_probe_to_get_green]])。 足したのは 11 sort: points(56) / signal(27) / video(16) / qimage(11) / cimage(9) / counts(8) / lightfield(8) / rgbimage(6) / matrix(4) / beatcube(4) / keypoints(2) = 151 op。形は推測ではなく backends_bridge._EMPTY_OF (12 sort すべての正準の最小値)と problems.py の入力生成器から取った。 これで 901 op すべてが 3 つの契約ゲートを実際に通る。 0 になった以上、このラチェットの役目は「増えたら落とす」に変わった。 新しい in_sort を足した人は conftest.BANKS に探針も足すこと —— 足さないと その op たちは「登録されているのに一度も実行されない」状態に戻る。
- L98 (ja) — ★非有限がその op の意味を運んでいるものは、この門の対象外。判断は ここで持たず
ops.NONFINITE_IS_MEANINGFUL を単一の正本として引く (test_backends_typed_liveness.KNOWN_NONFINITE_BY_CONTRACT が同じ表の 写しで、一致は別の検査が見ている。3 つ目の写しを作らない)。 2026-09-14: 探針バンクを 6 sort 広げたとき、ここで tb_mat_cond(特異行列の 条件数 = inf)と tb_geodesic_distances(不達 = inf)が落ちた。一度 探針から特異行列と非連結点群を外して緑にしかけたが、それは誤り —— 台帳は「inf が正しい答え」と既に宣言しており、落ちていたのは門がその 台帳を見ていないことだった。探針を削って緑にするのは欠陥を隠す行為で、 しかも同じ台帳の註に「自分の probe では特異行列を作っていなかったので tb_mat_cond を取りこぼした」という 2026-09-05 の教訓が書いてある。
tests/test_op_discovery.py
-
| L229 — ★它甚至不是原样通过:回退会截断到图像契约 [0,1] 后返回。负半部变成 0 的信号看起来像「滤波后的信号」,所以这会悄悄地撒谎。max |
差 |
= 1.0,最小值 -1.0 -> 0.0。 |
tests/test_op_example_coverage.py
- L58 — ★从配布物一侧计数母集合的 ratchet(2026-09-06)# ————————————————————————— # 2026-09-06 的实测。这是「不让它比这个数更差」的止动,而非目标值。台账 1,002 个 op 中,进入示例索引的只有 349 个,上面那两个「100 %」之所以成立,是因为母集合三层里只有两层。经过与按族的分解 = docs/KNOWN_ISSUES.md §38。
- L32 — ★op 集合随环境变化(Linux CI 没有 torch/kornia/mahotas/xfeatures2d,共 859 op;本地是 885)。把本地生成的文档与活的 registry 比对的检查,只有在满配环境下才有意义 —— 与 test_opdocs 相同的约定,未齐全就 skip(原因里会给出缺少的 backend 名)。在 2026-09-07 的 CI 上,有 22 项在这里落败。与环境无关的检查(文件的存在、内容的量、图的存在)照常运行。
- L203 — ★2026-09-08:把依赖第三方后端版本的 op 从台账里剔除、单独计数。这个台账写于「做图的环境」,验证于「跑测试的环境」。cv2 的实现随版本变化,所以本地(opencv 5.0)不起作用的旋钮在 CI(opencv-contrib 4.x)里起作用 —— 实测
xcv_grabcut 的 b 就是如此。台账只能主张在任何环境都成立的东西。依赖版本的部分不主张(拥有狭窄但正确的台账,胜过拥有撒谎的台账)。
tests/test_op_probe_ledger.py
- L76 — ★2026-09-08 加入。在那之前这个门只为 image / region / color / volume 这 4 类构造输入,让
contour 65 / points 57 / signal 26 / video 16 … 217 个 op(registry 901 个的 24 %)作为 “uncallable” 素通。「门站在正确的位置」和「门把全部都通过」是两回事 —— 拓宽的第一次就暴露出 tb_angle_3points 在探针下一次也跑不起来(注册是 points->feature,实体却取 3 个向量)。
- L192 — ★2026-09-08 的 CI(py3.10 / py3.12,无 torch)在这里变红 —— 因为把探针拓宽到全 sort 的第一次,首次到达了需要 torch 的 op(
tb_points_to_voxel)。「坏了」和「这个环境里没有」是不同的判定,混在一起就会把环境差异当成实现的 bug。在满配环境(FULLSEYE_REQUIRE_OPTIONAL=1)里照旧按失败处理。
tests/test_opdocs.py
- L212 — ★2026-09-03:由于所有 backend 的 _safe 都汇聚到了 backend_safe.guard,所以按 guard 立起的结构化标记来判定,而不是按 qualname 的字符串匹配(guard 也会在 qualname 里留下 “_safe(…)”,但那是给显示用的)。
- L1178 — ★没找到的原因:
ops.REGISTRY(899)与 2-D 笔记(899)一致,所以只要从 registry 一侧计数就会看起来「零缺失」。曾经这样下结论并搞错了。所以这个门从跨 tier 的索引一侧计数(memory: feedback_search_all_tiers_before_declaring_a_gap)。 ————————————————————————— #
tests/test_packaging_foundation.py
- L170 — ★2026-09-07:本地 wheel 上带着 sample_sources_ai 的 42 MB(共 96 MB)。原因是旧的 build/lib/ 缓存(从 package-data 移除前的残骸被重新打包进去)。这是读配置的检查抓不到的事故,所以由 tools/ci_wheel_check.py(unshipped_present)与 ci.yml 的大小上限去看 wheel 实物。目录也被移到了 package 外(tools/fops_article/)。这里要求明示排除(作为保险)。
tests/test_pivops.py
- L621 — ★只看名字级别的
PARAM_HINTS,会让门比 fuzzer 更窄。chain_fuzz._bind_args 还会看按 op 名狙击的 OP_PARAM_HINTS,所以这里也要两边都看(2026-09-06:把 dic 的 window / method 放进 OP_PARAM_HINTS 后,其实已经能绑定,却只有这里落败)。
tests/test_poc_scripts_run.py
- L57 — ★2026-09-08:放弃固定的 6,改为匹配 CPU 数。在共享 runner(2–4 vCPU)上,6 路并行只会把每一条拖慢,总时间并不缩短,等 PoC 增到 84 个时,每个 job 都撞上了 pytest 的 900 秒 timeout(py3.10 / 3.12)。本地(12 核)照旧以 6 或以上运行。
- L73 — ★
PYTHONPATH 不传(2026-09-09)。长期以来一直传 PYTHONPATH=<repo>,但那是使用者不会做的设置,意味着门离事故发生的地方偏了一步 —— 由于同样的盲点,examples/piv_flow_from_particles.py 等一直停留在「从 checkout 直接运行就 ModuleNotFoundError」(那一侧连运行的门都没有,所以没被察觉。test_example_scripts_run.py)。PoC 一侧 116 个里有 108 个自己把 repo 根目录加进 sys.path,剩下 8 个只 import fullseye,所以去掉后全数通过(已实测)。
- L91 — ★失败时也返回 stdout 的末尾。PoC 会把所见和「哪项检查落败」印到 stdout 后再 SystemExit(1),所以只有 stderr 的话,你只能知道空的「exit 1」而别无所知(2026-09-07 的 CI,py3.10 poc_ct_fidelity)。
- L100 — ★2026-09-07:这里长期返回 0,从而素通了下面的
assert code == 0 —— 一个刚算完合否就丢弃的门(实测:有 3 个 PoC 从不打印 PASS —— poc_dic_strain / poc_photoelasticity / poc_thermography_ndt)。改为返回 -2 让它落败。
- L122 — ★这个门把 84 个 PoC 一次性集中运行(session fixture)。这段时间会计到第一个测试上,所以 pyproject 的默认 timeout(900 秒)在共享 runner 上会落败。只在这里放宽 —— 放宽默认会连带钝化其他测试的挂起检测。
tests/test_public_reachability.py
- L71 (ja) — ★2026-09-14: この 13 本は 2026-09-05 から wheel に入っていなかったもので、 py-modules へ足した結果ここに現れた。演算子としては
unified._3DGS_OPS が _lazy_call(モジュール名, 関数名) で文字列から登録しているので、利用者には fullseye.op.<名前> 経由で届く。ここに残る 1〜6 本は各モジュールのデモ入口 (render_*_gif など)で、op ではなく絵を作る側。だから内部専用に置く。 —— 「配布から消えていた」を直すと「公開経路から見えない」が現れる、という 二段構えだった([[feedback_registered_only_gates_miss_unregistered]])。
- L88 (ja) — ★2026-09-15: 33 行すべてが公開経路(fullseye.<名前> / .ledger / .op)に届くように なっており、2 番目の検査が「この表から行を消すこと」と 33 件を挙げた。 消した 33: transforms / mosaic / fit_transform / tools_geom / matrix / shapematch / objmodel3d / matching3d / matching / calib / caltab / calibration3d / contours_xld / contours_xld2 / image_channels / filters_freq / filters_flow / regions_setops / regions_gen / region_morph / morph_minkowski / segmentation / image_gen / image_paint / misc_vision / imgops_nary / scattered / inspection / pipeline3d / watershed3d / mesh_decimate / sample_data / scale。 表は空でも残す —— 「出すべきなのに出ていない」ものが次に現れたときの器。名前>
tests/test_raster.py
- L26 — ★裸的 import 在缺失该项的环境里会中断整个收集(实测 2026-09-05)。
tests/test_rust_abi_parity.py
- L402 (ja) — ★契約では FS_E_INVALID_ARG(引数が定義域の外)であって FS_E_TYPE ではない。
FsValueError を足すまでは両方 FsTypeError で、Rust が 1 を返すのに Python は 2 相当を投げる、という状態コードの食い違いが残っていた。
tests/test_shapestats.py
- L196 — ★让平面自由,一侧均匀的展开就会被整个吸收掉(实测 4.9e-35)。中点只移动一半,平面也跟着移过去,所以不会作为左右差残留下来。这是这个定义的极限,而非缺陷 —— 想看的话就从外部给定平面,或加一个在正中线上的地标(midline)。
tests/test_studio.py
- L920 — ★
setDefaultFormat 只对无参构造函数生效,而 Studio 的 QSettings("Fullseye", "Studio") 固定指向 registry —— 这个 fixture 什么都没隔离(2026-09-05,registry 里残留了 pytest 的路径)。用环境变量把本体一侧的入口 studio._settings() 指向 ini。
- L2029 — ★直接构造
QSettings("Fullseye", "Studio") 会绕过隔离,写入用户的注册表(2026-09-05 的审计确认了实际危害)。设置入口保持为一个。
tests/test_studio_logic.py
- L22 — ★旧的 setDefaultFormat 方式对 Studio 的 QSettings(org, app) 不起作用。将本体的入口 studio._settings() 指向 ini(整个 session)。
tests/test_studio_ops_browser.py
- L11 — ★裸 import 在缺少 matplotlib 的环境中会中断整个收集(pytest 因一次 import 失败就不再运行其余全部)。2026-09-05 实测。
tests/test_videostream.py
-
| L319 — ★Collins (VSAM 2000):两者都以当前帧为基准。到 2026-09-05 为止,这个测试期望连续对 |
f[t-1]-f[t-2] |
,把实现的错误当作规范固定了下来(对匀速运动的均匀物体始终全为零 – 见下面的回归测试)。 |
- L43 — ★目录、提示和适配器以出货模块
typed_catalog 为正本(2026-09-05)。以前它们住在这里,backends_typed 把 tools/ 加进 sys.path 来读取 – 结果在 wheel 中 tb_* 143 op 悄然消失。把方向反了过来。
- L256 — 事件位置(点过程)– point_spectrum 的入口。★不要只用均匀随机:没有周期成分就一次也不会触及「寻找周期的 op」的有意义行为,所以用把 12 个无关事件混入周期 17.0 序列的结构化数据作种子(随机-only 的测试会隐藏结构缺陷,是本 repo 的规律)。
- L864 — ★混有非有限值的点云会让 KD 树的构建本身以生的 ValueError 崩溃(scipy:”data must be finite”)。池的设计是记录 NONFINITE 后仍保留值,所以脏点云来到这里是预期之内 – 由构建方防范。2026-09-06 实际踩到:新的族增加后连锁的走法变了,在 seed 3_000_0xx 命中这条路径,fuzzer 自身停止了(不是 op 的缺陷而是工具的缺陷。无法绑定的输入约定为跳过而非抛异常)。
- L1557 — ★到 2026-09-02 为止一直是
lambda v: True = 因为谓词被计为「有」,反而比没有更糟(点检脚本也会把它计为「有谓词」)。实测下它连 None / 42 / 字符串 / dict 都放行。正典是通过全部运行消费侧 6 个 op(reprconv 的 pairs_to_signal / pairs_to_image2d / pairs_to_table / angles_to_normals / shape_index_to_curvature / polar_to_cscalar)来确定的:6 个 op 都只接受上面两种形状,其余的都以 “pairs: must be (N, 2) or a 2-tuple of equal-length 1-D arrays” 变成指名的 fail-closed(实测)。因为不接受 (2,N),把 2-tuple 用 np.stack 压成 (2,N) 的 3 个 adapter 改成了 axis=1。长度不同的两条(histogram 的 counts/edges)也不是「对」,予以拒绝。
- L1667 — ★「恰好 2 个元素」与 pose(用
len >= 2 允许 info)是有意不同的。实测 2026-09-02:把 mesh 作为单个参数接收的 4 个既有 consumer(face_normals / vertex_normals / mesh_area / vertex_curvature)对 3-tuple 会送出 “mesh must be a 2-element tuple (vertices, faces)”,cadmap 的 _mesh 和 render3d._mesh_arrays 也只接受 2 个元素。也就是说 本 repo 的 mesh sort 正典是 2-tuple,多余的元素不是「信息更多」,而是让下游全灭的类型层面的谎言。唯一的例外 voxel_to_mesh(返回 (v, f, n))现在在 ops3d.RESULT_ADAPTERS 中取出正典的排列(与 gicp / vol_label 同样处理)。
- L25 — ★把这个脚本自身的所在位置从 sys.path 中移除。 Python 会把脚本的目录放到 sys.path[0],所以从 checkout 的
tools/ 启动时,即使在 wheel 侧的 venv 中也能 import 到 tools/ 下(未随附的 chain_fuzz 等),于是就在「能看到 wheel 里没有的东西」的状态下计数。2026-09-05 的复查中,这个门漏掉了 tb_* 143 op 的缺失正是因为这个。同时也把 cwd 移到空的临时目录(cwd 是 checkout 的话会发生同样的事)。
- L34 — ★在移动 cwd 之前记住原来的 cwd,此后把所有参数路径都相对它来解析。2026-09-05 实测:preflight 传的是绝对路径所以本地能通过,ci.yml 传的是相对路径,于是 dump 被写弃到临时 dir,compare 以 FileNotFoundError 崩溃 – 门在生产的调用路径上一次也没有执行比较。这是「门要立在事故发生的地方」的第 3 次。不是去修调用方,而是让它即使用相对路径调用也能正确运作,把这一整类关掉。
- L139 — ★2026-09-08:也看 editable 侧。在此之前
a["failed_backends"] 只是收集,谁也没读 – 在同一轮里作为与 examplefig 的图失败同类型的漏洞被揪出。editable 的 venv 有很多 optional 依赖,所以 backend 可能因版本不一致而 import 失败。这时 wheel 侧只是「因为依赖不存在,一开始就不在」,不记录失败,这个比较仍然绿着通过。掉落的 backend 的 op 就从注册表里悄然消失。
- L92 — ★这里会犯两次错。fuzzer 的
run_chain(1)把输入型 any 当作「总是齐备」(从池中任意抽取),(2)在 OP_ARG_BUILDERS 中注册的 op 自行组建参数。不把这两点算进去,就会把实际上每次都在运行的 op 报告为「结构上不可达」(实际上对 fuse_to_voxel / register_cross 误报了)。可达性不是由「只看型」决定的 – 一部分可达路径在代码这一侧。
- L89 (ja) — ★2026-09-14 追加。45,000 ケースを 3 秒で「食い違いなし」と言われたとき、 信じるのではなく自分が printf で挙げた「踏んでいない座標」を足す。 一致したときこそ探針を疑う([[feedback_one_probe_input_is_not_coverage]])。
- L185 (ja) — ★2026-09-14: ここは長らく値域だけを振って画素は 0..1 のままだった。相対しきい値は 値域を通して解決されるので、値域 (100,300) では絶対値 100〜300 と比べられ、 100% が空になっていた(実測: (100,300) は 780/780 が 0 画素、全体でも 63% が 物体 0 個)。4000 ケースが 0.6 秒で「食い違いなし」だったのは頑健だからではなく、 connection も measure_all もほとんど踏んでいなかったから ([[feedback_zero_findings_may_mean_never_executed]])。値域を名乗らせるなら 画素もその値域で描く。
- L198 (ja) — ★しきい値は画像に実在する値から引く。独立に引いていたときは 41% が 「選択 0 画素」で、物体が 2 個以上あるのは 14% だけだった ——
connection の 分岐(斜め接触・入れ子・多数)をほとんど踏んでいない。乱数で撒くと空ばかりに なるのは、しきい値も探針の一部だから ([[feedback_one_probe_input_is_not_coverage]]: 探針は入力画像だけではない)。 2 割は「当てずっぽう」のまま残す —— 空・全面・範囲外という端も要る。
- L236 (ja) — ★R-3 の相対→絶対の写像と画像の形。契約の関数なのに観測していなかった。
- L265 (ja) — ★
fs_region_runs は契約が「領域表現の唯一の窓」と呼ぶもの。それを 観測していなかった —— 面積と本数が合っていても、run の切り方が違えば run-length と dense mask は別物として振る舞う(隣接 run を結合するか、 行内の並びは昇順か)。観測していない性質はケース数では出ない。
- L295 (ja) — ★並びそのものを観測する。
sorted して比べていたので、物体の順序を逆にする 変異が 3,000 ケースで 1 件も殺せなかった(2026-09-14 の変異解析)。契約は 「最初の run の (row, col) 昇順」と明記しているのに、門がどこにも無かった —— 観測していないものは、どれだけケースを撒いても出てこない。
- L337 (ja) — ★R-3 の相対→絶対の写像そのものを観測する(契約
fs_image_absolute)。
- L351 (ja) — ★種別を捨てない。ここは長らく固定値 1 だったので、
_status_of を 書いて compare にコード比較まで足したのに、Python 側が常に 1 を 名乗るせいで状態コードの食い違いが構造的に出なかった(変異 m8 が 3,000 ケースで殺せなかった正体)。観測を足したつもりで足しきれて いない、という [[feedback_gate_computed_a_verdict_then_discarded_it]] の型。
- L381 (ja) — ★コードの値まで見る。「どちらも拒否した」で止めていたので、 契約が FS_E_INVALID_ARG(1)と決めている所で Python が FS_E_TYPE(2) 相当を投げていても素通りしていた(2026-09-14 に実際そうだった)。
- L390 (ja) — ★許容差は値域に対する相対で取る。絶対値で 1e-5 と決めていたら、 値域 (100,300) の画像で 1.04e-05 の差が「食い違い」として報告された —— が、切り分けると Rust vs scipy は float64 のままなら 8.53e-14、 float32 を経由した途端 1.04e-05。つまり
fslib の astype(np.float32) の丸めで、欠陥ではなく私の測り方の欠陥だった(値域比で見ると どの値域でも一様に 1.4〜5.2e-08 = float32 の相対精度)。 [[feedback_second_instance_artifact_not_physics]] と同じ型 —— 驚く結果は物理(実装の違い)で説明する前に道具を疑う。
tools/gen_blas_article_figs.py
- L93 — ★用半透明铺出 1 线程最快的区间。为不遮住线条先放置它,并把 alpha 保持得低(带子本身主张太强的话,线条的比较会变得难读)。
- L37 — 分类的英文名。★即使在英文版中也只有标题还是日文(实测 7 行)– 正文用
title_en / _summary_en 翻译过了,却忘了翻译标题,成了「切换了却混着日文」的典型。此处没有的分类照原文输出(不擅自造译)。
- L45 — ★对照表放在与算子文档不同的文件里。若用
opdocs.T,取用的原文会进入 opdocs.SEEN_STRINGS,现有的「框架译文有缺口」门就会把这 604 条全部算作缺口而使 CI 变红——那道门是为了让框架文案在五种语言上齐全,而这里是「译到哪算哪」的性质。混在同一张表里,会让一边的规矩毁掉另一边。
- L79 — ★一块 = 从含有 ★ 的行开始、以相同缩进接续的
# 注释行的连续。也拾取 Sphinx 风的 #: 注释。只剥掉 # 和空白,开头会留下一个 :
- L81 — 残下来,产物里就会出现「: ★…」(实际出现过)。
: 也在这里剥掉。
- L105 — ★下一个 ★ 到来时切成另一块(保持一块一个主张)。
- L197 — ★不翻译标记,固定为
_(ja)_。按语言翻译它会让机器无法计数 – tools/i18n_status.py 是数「没有标记的日文」的工具,所以标记若随语言变化,593 行就会变成「隐藏的日文」(实际变了)。ja 是语言代码,也向读者传达「这是日文」。
- L280 — ★笔记的集合从台账取(不去枚举文件)。2026-09-06 的对抗式复查(Codex)中,glob 文件并数 stem 的版本混入了一个
docs/ops/SAMPLES.md(不是 op 笔记),于是索引是 1,842、RAG 指南是 1,843,同时公开了互相矛盾的数字。笔记从 records 以 1:1 生成,所以 records 里的名字就是「有笔记的名字」的定义本身。与文件的一致由 tests/test_docs_index_reachable.py 另行检查(检测消失/多余)。
- L290 — ★用
__all__ 而非 dir(fullseye)。dir 包含模块属性(os / sys / warnings / annotations),而且在别的测试 import 之后会增加一个(1094 → 1095),所以漂移门只在整套件里失败(2026-09-06)。公开面是门面在 __all__ 中声明的 1,091 个名字。
- L339 — ★索引不只是给人的,也是 AI 的检索面(2026-09-06 用户的指出「索引也是被当作 RAG 使用的部分吧?」)。op 笔记兼作 AI 编码辅助的检索语料,所以在索引里明示机器读取的入口。把只有一半的东西写成「全部 op」,RAG 就会对剩下的一半自信满满地弄错 – 所以
_honest() 的实测行不从本节移除。
- L490 (ja) — ★2026-09-14: 長らく かな だけを見ていたので、「Studio 北極星」「実測記録」 のように 漢字だけで書かれた題に印が付かなかった —— 非日本語版の読者は それを英語の題だと思ってクリックする(印を付けないのは「読めない」という 事実を隠すことで、無訳より悪い、というのがこの関数の趣旨そのもの)。 題は常に日本語版ファイルから取る(
_doc_title(rel))ので、漢字を足しても 中国語の題を誤って日本語と呼ぶことは起きない。
- L655 (ja) — ★Qiita 投稿用の frontmatter(— で挟んだ YAML)は題ではない。中の
title: 行は 下の走査では見出しにも読み飛ばし対象にも当たらず、そのまま索引の見出しになって しまう(「title: ‘…’」と並ぶ)。挟まれた範囲ごと読み飛ばす。
- L94 — ★status=fixed 却没有门的不放行 – 是为了让这个台账自身不制造出「只留下修好了的记录、却止不住复发」的状态。
- L194 — ★链接目标(
docs/hardening/*.md)是用日文写的。替换成英文标题就成了谎言,所以标题照原样输出并附上 (ja) – 非日文版读者需要的不是「翻译过的标题」,而是「这是读不了的」这个事实。标记固定为 tools/i18n_status.py 能数的形式。
- L41 — ★这里不是「只是个常数」:线积分 p = Σ μ·Δx 超过 10 时,exp(-p) 就低于光子数 1,对数饱和而 p 触顶(photon starvation)。最初的版本把 μ 放成 0.55–1.0「/像素」,于是 p 达到 30,复原 μ 偏低 50–84%。零点(简单反投影)反而在 Dice 上胜出,才因此察觉。
- L166 — ★每种材质的数字是 召回率(recall)。是「在该材质标签内拾取到的比例」,而不是 Dice(因为不数落在标签外的假阳性,若称作 Dice 必然趋近 1.0)。整体的漏取/多取由下面的 precision / recall 另行给出。
- L65 — ★缠绕顺序朝外。反过来法线就朝内,render_beauty 会不抛异常地返回全黑(最初的版本就是这样,只有薄膜的球是黑的)。
- L153 — ★这是下界。因为它只看 op 名是否在
tests/ 中以 literal 出现,所以扫台账跑遍全部 op 的扫掠型测试(for name in ledger: ...)不计入。要读作「没有指名的测试」而非「没有测试」。
- L105 — ★2026-09-08:在这张表里的
tb_angle_3points 和 tb_indices_to_labels,不是「在图的定义域之外」,而是 不该放到桥上的 op。前者取 3 条向量,所以单条点云无法调用;后者返回 1-D,却把声明的 out 定为 labels(→ volume = ndim 3)。两者都保持注册着却一次也没运行过,fail-soft 返回着貌似合理的值。移到 backends_typed._OP_BRIDGE_SKIP,并从这张表里移除 – 有「出不了图」的记录,却在任何地方都没有「无法运行」本身的记录(有两道门,只有一道察觉到了)。
- L115 (ja) — ★2026-09-13: op が evolute 検証を得て厳格化。ECEF は地球表面(中心から ~6.4M m)の 座標を要るが、画像由来の合成点は原点付近で必ず楕円体の evolute 内に落ちるため 正しく拒否される(実データでは動く。合成入力では図を作れない恒久的な定義域ミスマッチ)。
- L127 — ★2026-09-07(用户指示「不必汇总成一张。分阶段的、有多个条件的分开出」「有些东西用伪彩色更好懂」「复杂的甚至可以用动画 GIF」)。在主图
<op>.png 之外,再加:<op>.a.jpg / <op>.b.jpg — 把旋钮拨到 0.1 / 0.5 / 0.9 的 3 张(仅当输出变化时。不变化就在 manifest 写理由)<op>.chain.jpg — 有前置 op 的 op 的阶段图(图像 → 中间 → 输出)<op>.gif — 当输出是视频 / 光场 / 体积时,依次展示帧 / 视点 / 切片(静图 <op>.png 为完成形,GIF 是追加。Studio 的 QTextBrowser 显示第 1 帧)。伪彩色只施加于量的场(距离·相位·朝向·深度·曲率 …)的输出,并在标题写 (viridis)。滤波类保持灰色(不呈现为会变色的 op)。
- L730 — ★「跑了」和「出了有意义的输出」是两回事(2026-09-07,用户指出「out 全黑是怎么回事?」)。把空数组算作「有图」,黑板就成了图。空就记为空,并在笔记里写理由。
- L592 — ★2026-09-02:highpass / bandpass_image 现在遵循「把 0 映射到 0.5 的 [0,1]」的约定返回。以前它们把带符号数组称作 image 返回,在保存·段间 clip 时负的那一半(约 50% 的像素)被无声地压成 0。把修好这件事用实测而非推测记录下来:最小值和负像素的比例。
- L727 — ★2026-09-02:estimate_noise 现在以 σ 的单位返回(以前在 σ>=0.08 时贴到 1.0,对相差 3 倍的 σ 返回相同的值)。摆出直线 y=x,好用眼睛确认「返回值是否就是 σ 本身」。
- L840 — ★_panel_grid 的标签不换行,一旦超出宽度就会和相邻的相撞而读不了(tile 262px / font 19-17px,所以一行 ≈ 12 个全角字符为上限)。把倍率的含义放到标题和副标题里,面板上只放简短的名字和数字。
- L1184 — ★2026-09-02:
area_center 现在如其名返回 (面积比, 行, 列) 3 个分量(此前只有面积比 1 个标量,不返回中心)。3 个分量都做了 [0,1] 归一化以不依赖分辨率,所以要还原到像素:行 ×(H-1) / 列 ×(W-1)。这里把还原后的中心打到图上,做成能一眼看出返回值确实是中心的形式。
- L1712 — ★逐点调用 apply_cmap 的话,会在那一个点之内归一化,于是全都变成同一种颜色。只做一次张开 0..1 的 LUT,从中查取。
- L1950 — ★2026-09-02:gabor 现在采用除以核的 L1 范数的固定尺度,返回可跨 op 比较的绝对值。此前它除以「该图像中的最大绝对值」,于是每个朝向都除以不同的除数,把响应的大小本身 = 朝向的判别力压垮了。作为代价,返回值落在 [0,1] 低端的狭窄区间(这 3 种花样里平均 0.007–0.030),所以直接贴上去 3 张都是全黑。图用 1–99%tile 拉伸来显示,标签的数字给出拉伸前的实测值(与 freq_sweep 的 highpass 面板相同的约定)。
- L2065 — ★2026-09-02:3 个 op 变成了各自独立的实现。以前 3 个都搭在 geom “zoom” 上,相互的最大差为 0.0 / 4.9e-14(= 相同),而且 3 个的 b 都是死的。现在 zoom_image_factor = 纵横 2 个倍率 / zoom_image_size = 目标尺寸 / rescale_img = 等方倍率 + 插值阶数。画布 shape 都保持为输入原样。
- L411 — ★噪声用 :func:
astrostack.noise_sigma(背景的稳健 σ)来测。用「与真值的残差 RMS」的话,连 PSF 的偏移都会进到残差里 – 这个实验特意逐帧改变 FWHM,所以选法一变,合成后的 PSF 就变了,残差增大到底是因为噪声还是因为像变了就分不清了(实测该值从 25.2 -> 61.3,但其中大部分并不是噪声)。背景 σ 不依赖于星的形状。
- L471 — ★「最大差」在单帧下不动 – 因为只要召回率不足 1,漏掉的 1 个像素就会原样压住最大值。用有多少像素仍大幅偏离正解和偏离的总量,去除的效果就会如实显现。
- L713 — ★ 按原始尺寸排列时,”检测到 2 个” 无法用肉眼确认(在 44x44 之内,相距 1.6 像素的一对只会成为几个像素大的一团)。为了不做出只让读者相信检测器说法的图,围绕每对裁出相同的物理范围并放大。
- L844 — ★ 误差图涂的是大小而非符号。最初的版本用发散配色,但本实验的误差始终为正,于是变成”正 = right 的蓝色”,得到相反的含义——损坏的状态被涂上了”正确”的颜色。这里想向读者传达的不是方向而是”错了多少”,所以只用 wrong 的单一颜色改变浓淡(为了不让含义只由颜色承载,同时并列标注符号和数值)。
- L573 — 5. ★跨越各种表示走一圈(变换的连锁正是谎言出现之处) # ————————————————————————— #
- L599 — ★ “是壳而非实体” 不可用最大值投影来断言 —— MIP 取的是深度方向的最大值,所以即便是薄壳内部也看起来是填满的(实际上曾经那样画过,差点给出”体积 5768 -> 壳 5608”这种几乎无差别的数字)。内部是否残留,用中心断面和内部填充率来说明。
- L896 — ★ 条纹所张成的像面的实际尺寸。设为 1.0 mm 时,208 采样/mm = Nyquist 104 cyc/mm,于是 200 cyc/mm 的条纹变成了 8 cyc/mm 的粗条纹(图自己在混叠)。若为 0.25 mm 则是 832 采样/mm,即便是最高频率 200 cyc/mm,一个周期也有 4.16 像素,足够了。
- L1151 — ★ 把两个量叠在一张图上,取决于尺度的取法,两条曲线可能偶然完全重合(最初的版本正是如此,看起来与”两个独立轴”的主张完全相反)。调尺度把它们拉开是蒙混,所以把面板纵向分开——图的结构本身就说”这是不同的轴”。
- L1299 — ★ 峰值取自整行。以前写成
line[c - s : c + s + 1],当 s 超过 c 时,起点变成负索引,于是 Python 只切出末尾 56 像素,把 0.6167 当作”峰值”返回(实际最大值是 0.9834)。归一化崩坏,曲线在 1.0 处封顶,dip/peak 也在 1.9x Rayleigh 处错误地给出 0.0067。
- L1581 — ★ “模糊在 1 像素以内”的范围不从格点上采。扫掠步长为 3.9 mm,而景深只有 0.74 mm,所以格点上一点都落不进(最初的版本就因 min() 变空而崩溃)。用二分法直接求边界本身。
- L1600 — ★ 夸张倍率是 纵向 像素/mm ÷ 横向 像素/mm。最初的版本写成了倒数,在拉伸了 8 倍的图上显示”0.13 倍”(向读者传达了完全相反的信息)。
- L2090 — ★ 分成上下两栏。叠在一张图上时,单位不同的两条线(像素数与检测率)会被读成落在同一纵轴上(实际上看起来正是如此)。
- L42 — ★ 在缺少这一步的期间,:func:
_called 对 (op 名 × example) 的所有组合调用 :func:_strip_prose,每次都用 ast.parse + tokenize 重新解析整个源码。实测 2026-09-05:2-D 881 op × 73 本 + 3-D 347 op × 118 本 + ledger 494 op × 73 本 = 约 14 万次完整解析,一次 opdocs.py md 要花 10 分钟(toc 和 html 也重建同一索引,所以完整再生成是 30 分钟级)。散文剥离每个源码一次就够了 —— 因为它不依赖 op 名。
- L105 — ★2026-09-08: ops1d(dsp 16 + funct1d 23)虽已注册,却 在 docs/ops 下没有一张笔记 —— 它出现在 OP_CATALOG 中,但因为没有每个 op 的笔记(类型契约、陷阱、相关 op),从 RAG 语料库中整个缺失。是在
poc_web_roll_periodicity 给 dsp 添了 2 个时发现的。
- L790 — ★n 元(多输入)层。到 2026-09-09 为止有 17 个算子一份说明都没有(
add_image、sub_image、bit_and、reduce_domain、union2…)。它们以 tier=nary 出现在 OP_INDEX.json 中,但 docs/ops/ 下没有说明,于是永远无法从 RAG 语料中检索到。漏掉的原因很清楚:这里只遍历 ops.REGISTRY,而 ops.REGISTRY(899)与 2-D 说明数(899)相等,从注册表一侧数就显得毫无缺失。只有跨层去数才会暴露。
- L832 — ★2026-09-07:
OPS3D[...]["doc"] 是注册时只切出 docstring 的第 1 行的产物(ops3d._build)。在笔记的”用法”里用它,无论实现写了几段都会变成一行 —— “用法只有一行的 op 494 本”中的 3-D 部分正是这个截断造成的(docstring 本身很长的 op 很多)。和台账 dim 一样,把函数的 docstring 整个读进来。
- L855 — ★ 桥接 op(
tb_<name>)与台账的 <name> 实现相同,示例以台账名书写。到 2026-09-06 为止有 147 本是”零示例”,但那只是没有数到以别名存在、调用同一实现的示例而已。继承台账一侧的示例,并在笔记中明确写上”原 op 的示例”(以免说谎)。
- L1075 — ★n 元算子无法通过
fullseye.apply 调用——那是单图模型。在这里写单图的调用方式会让说明撒谎:说明唯一的职责就是告诉别人怎么调用,所以错误的调用方式比没有更糟。公开入口是 fullseye.FullseyeGraph。
- L1094 — ★2026-09-07: 先写公开路径。这里只写了实现模块的直接 import,没有出现使用者实际使用的
fullseye.ledger.<名>(除 2-D 以外的全部 1,244 op)。PoC 反复报告”fs.<名> 里没有",问题不在于名字缺失,而在于**入口没有写**。名>
- L1455 — ★ 入口用 6 种语言呈现(2026-09-09)。叶子(Studio 的 op 帮助)有 6 种语言 10,191 页,然而通向那里的索引却只有日语 —— 译文存在却到不了,这种形式的缺失。框架的文案放在
T() 上,所以对照翻译的空洞由既有的门(test_chrome_translation_table_has_no_holes)来看守。
- L1500 — ★ 这里长期只指向
2d/guides/,从未把读者引向光学、PIV、断层成像等 30 个族的指南(2026-09-09 修正)。
- L119 — ★ 如果
build/lib 里残留着上次的 staging 副本,setuptools 会原样把它塞进 wheel(2026-09-05 实测:从 py-modules 中移除的模块仍留在 wheel 里,门的变异测试竟然通过了)。这与 release.yml 从 clean checkout 构建的理由相同。这里也一样,构建前务必清除。
- L313 — ★ 不带
--full 调用 --only suite 会得到 0 个项目,以前会说”全部 PASS”并以 rc=0 返回(2026-09-05 评审中实测)。什么都没检查却放行的门,比没有门更糟。
- L54 — ★唯一位于
tools/ 之外的生成物。正因如此才被漏掉——只要按 tools/*.py 去找生成器,就永远找不到它。
- L77 — * ★而且危险:刚生成的文章用相对路径写图像。公开版是改成
raw.githubusercontent.com 绝对 URL 后的(Qiita 用相对路径不显示图像 —— memory feedback_qiita_svg_path_and_cache)。只跑生成器,那些绝对 URL 会回退 42 行。要跑就一直跑到文章的公开步骤为止。 排除项要按文件名写。用散文归纳(”wing*_gallery 的 10 本”)机器无法比对,下面的 unclassified() 就不工作了。
- L167 — ★位于
tools/ 之外的生成物。只遍历 tools/*.py 永远发现不了它,实际上 docs/OP_INDEX.json 就一直被漏掉。
typed_catalog.py
- L217 — ★ 默认值本身很重的情况另作处理 —— 在 docstring 里写了费用表,并在 docs/KNOWN_ISSUES.md 中作为”未解决”保留。这里减轻是为了通过检查,而不是为了掩盖慢。fourier_smooth(points, keep) 的 keep 是没有默认值的必需参数。若无法绑定,就会以”参数组不起来”被永久跳过,在覆盖率表中只作为未到达出现(2026-09-06 首次计测时 13 op 中只有这 1 本掉了)。表面粗糙度。约束为 2dx <= lambda_lo < lambda_hi <= ndx / 0<hurst<1 / sq>0 / n>=8。亚像素计测。测量线的生成 op 不取输入,所以全部参数都需要提示。
- L271 — ★ 不加这一步,surface_params 每次都会 fail-closed 被拒绝,单看覆盖率这一个数字像是”能调用”,实际却从未执行。
- L459 — ★ 法线不要平行于轴。若与轴平行,距离场只沿一个轴变化,图的生成器做的”堆叠切片的 GIF”会塌成一帧(2026-09-08 实测)。倾斜的法线则所有切片都会变化。长度不起作用(op 会归一化),所以传入未归一化的向量,把这个规格也展示出来。
visionlab.py
- L53 — ★
float("50") 会成功,所以仅仅让它通过 float(),字符串就会作为毫米蒙混过关。visiondesign 一侧会拦截,但若在这里先转成 float,在到达那个校验之前就已经变成数值了(敌对性验证实测:VisionSystem(focal_mm=”50”) 通过了)。容器一侧也要持同样的规律。
visualhull.py
- L123 — ★ 一个不剩地所有点都在相机后方 = 几乎肯定是姿态的规约不符(2026-09-08,poc_livestock_body_volume 踩到)。这个函数要求 OpenCV 规约(+Z 朝前),但公开层中带
look_at 名字的是 render3d 的 gluLookAt 版(−Z 朝前的 4x4)。传入它的 M[:3,:3], M[:3,3] 会让全部 voxel 被判为后方,无一例外地返回空的轮廓,得到空的 hull。默默返回空,就和”雕刻完毕”分不清了,所以唯独这里要出声(也有有效的场景 —— 物体在视角后方 —— 所以不 raise 而只停在警告)。
world_render.py
- L69 (ja) — ★
resolve() は実在しない場面に None を返す(資産が無い環境では正しい)。 検査せずに spec["xml"] を引くと TypeError: 'NoneType' object is not subscriptable という、原因を何も語らない例外になる —— 呼び手には 「何が無いのか」と「どう直すのか」を返す。
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.