日本語 · English · 简体中文 · 繁體中文 · 한국어 · Deutsch
This repository records why things are the way they are in comments in the source. The ones marked ★ are the load-bearing ones — what was measured, what went wrong, why it is built this way. This page is collected from them mechanically; the source is the single copy of record, so the two cannot drift apart.
Translation status: 637 of 1571. Untranslated entries are shown in the original Japanese — falling back silently would look like a translation, so a missing translation is shown as missing.
accel.py
- L296 (ja) — ★CPU 側(ops._otsu)と同じくビンの上端で切る(2026-09-26)。 中点で切ると argmax ビンの背景画素が前景に混ざる。ここを直し忘れると 同じ絵で CPU と GPU の答えが割れる(test_fast_parity が門)。
- L688 (ja) — ★2026-10-02: HALCON 名は
local_max(画素精度のマスク)。以前は local_max_sub_pix と書いていた。
- L812 (ja) — interior 差の判定閾値。★2026-09-20(GenSpark 第 32・33 報 N116): 0.0002 の差に “exact” と出て、 語が実測と矛盾していた —— 判定は閾値で決まるので、語に閾値を添える。
accel_match.py
- L170 — ★The window must be larger than the template or the count of full-overlap positions goes to zero → r = T//2 + f(coarse error) + win.
acoustics.py
- L1173 — ★
med == 0 was unconditionally treated as inf —— it reported “an infinitely dominant peak” even when peak was also 0 (silence, nothing in the band). As the docstring says, these two numbers are an honesty indicator for “it returns a peak frequency even when there is nothing there”, yet it was swinging in the most dishonest direction. The answer for 0/0 is 0.0. (2026-09-05: surfaced on Linux / numpy 2.5.2. The old version merely had a slight filter residual left so med > 0; the bug was there all along.)
- L1181 — ★The global median reverses its order when you narrow the band (pure noise 11375 vs a real defect 9433; measured 2026-09-06, see the _local_prominence table). Use this one for a bandwidth-independent verdict. The existing two are kept with their meaning unchanged —— a same name whose content changes is more dangerous than adding one.
- L1789 — ★
med == 0 was unconditionally treated as inf —— it reported “an infinitely dominant peak” even when peak was also 0 (silence, nothing in the band). As the docstring says, these two numbers are an honesty indicator for “it returns a peak frequency even when there is nothing there”, yet it was swinging in the most dishonest direction. The answer for 0/0 is 0.0. (2026-09-05: surfaced on Linux / numpy 2.5.2. The old version merely had a slight filter residual left so med > 0; the bug was there all along.)
- L2597 (ja) — ★fail-closed(2026-10-06): 全帯域の PHAT は帯域の限られた信号で黙って外す。
acquire.py
- L70 (ja) — ★公開面は本体から数える(
tests/test_acquire_contract.py の門が AST で 読み、ここと突き合わせる)。dir() は環境で変わるので一次情報はこちら。 2026-09-25 まで 7 つ足りていなかった —— 追記のつもりが当たっていなかった。
- L96 — ★2026-09-24: the table used to carry rows this module could not open.
capabilities() announced nine backends while Camera._open branched on five, so realsense, oak, zed and kinect answered ValueError: unknown backend even with the SDK installed — a declaration/implementation split of exactly the kind a “registered only” gate is blind to. Each row now names the opener, _open dispatches THROUGH the table, and test_acquire_contract.py asserts every declared backend has one. unit is the physical meaning of what grab() returns: “normalised” -> float64 in [0, 1] (an image) “m” -> float64 metres (a depth map; NEVER rescaled to [0, 1], which would destroy the measurement — 35 ledger ops take depth) (name, module-to-probe, pip, kind, unit, opener, one-line desc)
- L144 — ★No count of those SDKs is written here. The corpus lives in another tree, so a number quoted here has no gate keeping it true – it said “13” while the corpus had grown to 28 (2026-09-25). A figure nothing can check is worse than no figure. Each value names things that must exist – a test resolves every one of them, so a rename or a deletion turns the claim red instead of leaving a stale boast.
- L196 — ★
unit carries only what the standard states in prose. Where UVC does not state a unit (PU_GAIN_CONTROL says merely “the setting for the attribute of the addressed Gain control”) the entry is None – inventing dB there would be a claim the standard does not make.
- L254 — ★UVC 1.5 defines
dwExposureTimeAbsolute as “1: 0.0001 sec … 100000: 10 sec”, i.e. 100 us per step, while SFNC gives ExposureTime in us. The same number 5000 therefore means 5 ms under SFNC and 0.5 s under UVC – a factor of 100 that raises no exception and only moves the picture.
- L362 — ★This is the fix for a silent defect: a 12-bit sensor hands back a uint16 buffer, and dividing by the CONTAINER maximum (65535) instead of 4095 makes the whole image 16x too dark (measured: 4095 -> 0.0625) with no exception — every threshold operator downstream is then wrong. The container cannot tell you the depth; the pixel format can, so backends pass it in and this table decides.
- L1048 (ja) — ★
as_numpy_ndarray() はフレームのバッファをそのまま指す (vmbpy 同梱の例が「同じメモリを使う」と書いている)。vmbpy の取得は フレームを再キューしてバッファを使い回すので、複製しないと 次の 1 枚が前の 1 枚を書き換える —— 例外は出ず、絵だけが入れ替わる。
- L1425 (ja) — ★以前はここが [] を返していた。GenTL を出す全ベンダを覆える唯一の経路 だけが列挙できない、という穴だった。プロデューサは GenTL 1.6 の GENICAM_GENTL{32,64}_PATH に自分を登録するので、こちらはそれを読む。
- L1450 (ja) — ★同一性は
id。serial_number は Windows では取得できず既定 0 のまま 返るので、鍵にすると全機が同じ鍵になる(Stereolabs API reference)。
- L1459 (ja) — ★
camera_state の既定は NOT_AVAILABLE ―― 一覧に出ても塞がっている ことがある。黙って落とさず状態を添える(在るが使えない、は発見である)。 CAMERA_STATE の全メンバーは公表文書から裏が取れなかったので、 文書が名指しする NOT_AVAILABLE とだけ突き合わせる。
- L1471 (ja) — ★pyk4a は台数しか教えてくれないので、シリアルを読むには開くしかない (pyk4a の example/devices.py)。だから列挙そのものが装置を触る ―― 必ず閉じ、開けなかった機は落とさずに「在るが開けない」として返す。
annotate.py
- L3105 — ★Punctuation (。、) should not be rotated but shifted to the upper right, but here we don’t shift it —— rather than silently approximating what we can’t do, we write it in the docstring and leave it. Characters (punctuation) that shift to the upper right in vertical writing. A dot that sits at the lower left of the glyph in horizontal setting comes to the upper right in vertical setting —— the typographic manner is to move the position, not to rotate. Windows’
@-prefixed fonts (the vertical-writing face GDI selects by face name) did this on the font side. Pillow opens a font by file path so it can’t reach the @ face, and HarfBuzz’s direction="ttb" also gives different results with and without Raqm installed (this machine’s Pillow 12.3.0 has features.check("raqm") False). Following the policy choose what is consistent across platforms, here we shift by composition.
aoi.py
- L441 (ja) — ★積の向きが符号を決める。
fb * conj(fa) の山は「moving が reference に対してどれだけずれているか」に立つ(逆にすると符号が反転し、残差を測る ときに逆向きへ戻してしまうので、完全に一致する対でも残差が 1 を超える)。
api.py
- L170 (ja) — ★2026-10-02: 合成パイプライン 6 本を fs.<名前> から出す。以前は ``fs.pipeline3d.`` でしか届かず、 公開経路の門では「1 本も届かない島」として _INTERNAL に置かれていた。import 自体は torch が無くても 通る(torch_lazy)。torch を要るのは呼んだときの FPFH / ICP の側だけ。名前>
- L882 (ja) — ★名前はすべて glyph_ で始める。1-D / 2-D / 3-D でレジストリが分かれている repo なので、接頭辞の無い名前は公開経路ごとに別物を指す事故を起こす。
- L898 (ja) — ★JSON 一枚で受ける入口。op ではなく API 層の関数(レジストリの op は (画像, a, b) 固定でノブ 2 つなので、文字列も JSON も渡せない)。
- L953 — ★
annotate.overlay_mask is deliberately not exposed at the top level. The same-named imgio.overlay_mask is already public as fs.overlay_mask, and its arguments and meaning differ (imgio = raw RGB, mask>0.5, fill/margin / annotate = role-name colour, weights [0,1] allowed too, rejects a shape mismatch). Putting a different promise on the same name means the caller receives not an exception but a plausibly different picture. We don’t make breaking changes to the public API on our own, so retrieve the role-carrying one via fs.annotate.overlay_mask.
- L1115 (ja) — ★2026-10-02: 「名前の無い非公開関数」の棚卸しで、op として振る舞うのに公開経路が 1 本も無かった 18 本。 どれも既存の型つき台帳の約束(台帳 = 実装モジュールの集合)に合わないので、facade(fs.<名前>)から出す。 門は tests/test_hidden_ops_exposed_2026_10_02.py(定理か第 2 実装)。名前>
- L1678 (ja) — ★空・空白だけの名前は「無い」(2026-09-20、GenSpark N27): 多くの op は halcon 別名が “” なので、
name == halcon の一致で “” が lowpass に解決し、保存したパイプラインに空名が混ざると 別の op が黙って走っていた。名前の照合はこの先で行うので、ここで先に切る。
- L1681 (ja) — ★2026-10-11: このコメントと判定が docstring より前にあったので、関数に docstring が 無かった(
find_op.__doc__ が None)。説明の門(台帳・facade 版)が拾った。
- L1697 (ja) — ★大小文字とハイフンだけ違う名前は同じ op(2026-09-20、GenSpark N50): HALCON のリファレンスは GAUSS_FILTER のように大文字で書かれることが多く、
GAUSS_FILTER / Gauss-Filter が unknown だった。 正規化して 1 度だけ引き直す(元の綴りに一致が無いときだけなので、既存の解決は変わらない)。
- L1766 (ja) — ★2026-09-20(GenSpark 第 35 報 N124): 台帳 op の名前を apply に渡すと「unknown operator」と言い、 op_names() を案内していた(そこにも無い)。索引は tier を知っているので、正しい入口を言う。
- L2066 (ja) — ★2026-09-20(GenSpark 第 55 報 N199):
with strict_mode(): apply(gray, "access_channel") が例外にならず、 入力型の fallback(source=”input”)が台帳に残っていた。strict は op 本体の例外と GPU / 高速路だけが見ていて、 _guard_input と非有限出力の門は on_error しか見ていなかった —— 「厳密」が経路ごとに別の意味だった。 strict(strict_mode / set_strict / FULLSEYE_STRICT)は on_error=None のとき “raise” と同じ。明示の on_error は文脈より強い(引数 > 文脈 > 環境変数 > 既定)。
- L2097 — ★ There is currently no correct way to call this for colour images: passing them all at once mixes the colours, and calling three times per channel makes a self-normalizing op divide each channel by its own max, breaking the ratios between channels (the grey-edge angular error goes from 1.03 deg with our own Sobel -> 4.17 deg per image -> 27.86 deg per channel, 29.14 deg at the zero point). Which way to lean is a contract decision, so here we change not a single default value, refuse only when
on_error="raise", and by default record it in the ledger so it stays visible. Details and options in docs/KNOWN_ISSUES.md.
- L2385 (ja) — ★2026-09-20(GenSpark 第 26 報 N97): 素の str / dict / スカラーは ndarray でないのでここを素通りし、 既定の fallback 方針では入力がそのまま返っていた(
apply("abc", "gaussian") == "abc")。 raster を取る op には、配列にしてから同じ検査を掛ける。list / tuple は数値の入れ子として下で配列化される。
- L2421 (ja) — ★float16 / float32 → float64 の昇格は無損失(値も範囲も変わらない)なので記録しない(2026-09-20、 GenSpark N29): float16 は scipy.ndimage が扱えず op が RuntimeError → fallback で入力のコピーが 返っていた。float32 は op が float32 で走り float32 を返していた(契約は float64)。
- L2692 (ja) — ★2026-10-18(外部レビュー 0.6.0 N224): 以前の文は「got name=ndarray」だけで、受け取った image 側 (op 名の文字列)を言わず、規約の説明と食い違って読めた。受け取った 2 つと、直した呼び方を言う。
- L2813 (ja) — ★形状不一致(2026-09-19 外部レビュー #13): ラスタ同士の n-ary で形が違うと numpy の 「could not be broadcast」がそのまま台帳に残り、既定の方針では第 1 入力が そのまま返る(sort として妥当な fallback)。返り値の形だけ見た利用者には 「(32,32)+(32,16) が (32,32) で成功した」と映った。何が要るかを文で言う。
- L2817 (ja) — ★ただし第 2 入力がマスク(畳み込みの核)の op は形が違って当然 —— 3×3 のマスクを 画像と同じ大きさに埋めないと呼べない、では入口として壊れている(2026-10-12、例の 付与で発見)。核を取る op だけ名指しで外す。
- L3126 (ja) — ★2026-09-20(GenSpark 第 15・16 報 N67): 4 op の入口の関門(ops.NATIVE_CRASHES_ON_DEGENERATE)は 効いているのに、その事実は ops.py の中にしか無く、registry を使う側からは見えなかった。 行に載せる(None = 関門なし。理由の文がそのまま値)。
- L3130 (ja) — ★2026-09-20(GenSpark 第 20 報 N84): 同じ HALCON 別名を複数の op が名乗る(cv_ / sk_ の移植と コアの実装)。どれが走るかは find_op の規則(完全一致 → name == halcon → _ALIAS_CANONICAL)で 決まっていて曖昧ではないが、その事実が行に無かった。halcon_peers = 同じ別名を名乗る他の op。
- L3251 (ja) — ★2026-09-20(GenSpark 第 24 報 N95): 綴り違いの sort が黙って 0 行だった(「該当なし」と区別できない)。
- L3261 (ja) — ★台帳には入力ゼロの op(カタログを返すだけ)が在り
in_sort が None になる。 生の None を並べ替えの鍵に混ぜると TypeError で落ちる —— レジストリと n-ary だけ だった頃は None が現れなかったので、この鍵は 2026-09-25 まで壊れずに済んでいた。
astrostack.py
- L157 — ★Hypothesis test: we predicted that “there is no value in moving as long as it fits in one cache line (64B)” but were wrong. For float32 the crossover is at K≈17-19, close to 64B (K=16), but for float64 the actual crossover is K≈23-25 (about 200B) against a predicted K=8. It is decided by the number of elements, not the byte count —— the per-element fetch cost dominates. Moving while there are only a few is actually slower (1.4x slower at float64 K=5), so the crossover point is essential.
-
| L380 — ★MAD collapsing to 0 while the image is not flat = quantization (2026-09-08, hit by poc_thermal_radiometry). With integer DN, |
x-med |
is also an integer, so the sigma we can return is only a multiple of 1.4826 —— 0.0 for a real-image equivalent of σ=0.5, and σ=1.0 and σ=1.983 both give the same 1.4826. Silently returning 0 makes the threshold equal to the background, and downstream (star_detect) finds nothing. This is an entry point that returns a value, so instead of raising it speaks up (the caller can pick method=”clip”). Refusing is the job of the side that produces the answer = star_detect. |
- L617 — ★ The sole entry point for shot noise. With photons_per_unit=1, “expected value = lambda”.
- L708 — ★ field_seed is fixed (the same sky), only seed is varied (a different observation).
- L781 — ★Until 2026-09-08 this gate’s comment said “perfectly flat = noise cannot be measured”. It was the premise that was wrong —— there is one more path by which σ becomes 0: when MAD collapses under integer DN (0.0 for a real image equivalent to σ=0.5). Returning empty for a non-flat image is not a conservative answer but a wrong answer; in fact, 2 point targets planted in a 200x200 integer frame were being returned as 0. We split the paths: if flat, return empty (no stars); if not flat, refuse.
- L1106 (ja) — ★ 画像の外の中心は「flux 0・area 0・snr inf」を黙って返していた —— 拒否する。 画像の縁で欠けた開口は計算はできるが flux が系統的に少ないので
truncated で印を付ける(area_px は欠けた後の面積)。
- L1344 (ja) — 残差の sigma で下支えする。★ 以前は +inf に置き換えていたので 何も落とさず、宇宙線がそのまま平均に入った。
- L1702 (ja) — 束ねた sigma で下支えする。★ 以前は中央値画像の空間 MAD を使っていたが、 平坦な整数データではそれも 0 になり床が 1e-12 —— 読み出し雑音の +1 DN が 全部「宇宙線」になった(32x32x9 枚で真の宇宙線 1 に対し 871 画素)。
- L1743 — ★On a tie, pick the bin with more raw votes. A 3x3 smoothing gives the same sum whether seen from the left or the right of the true peak, so taking argmax on the smoothed value alone can pick “an empty bin next to the peak” —— exactly that happened in measurement: the true shift (-0.087, +0.996) had its votes 7 + 4 split in two at the bin boundary, and its centre, off by one bin, ended up with 0 votes (frame_align wrongly fail-closed as “not overlapping”). A weight of 1e-6 is far smaller than the smoothed value’s step (1/9), so it does not change the ranking when there is a real difference.
- L1766 — ★2026-09-08: also return the height of the second-place peak. For a star field there is one peak, but for repetitive structures (halftone dots, gratings, textiles) peaks of the same height line up shifted by a lattice vector, and whichever you pick “everyone agrees” = inlier_ratio becomes 1.00. The agreement rate is not “the probability the answer is correct”, so we report whether there was a single peak as a separate number (0 = single peak, close to 1 = there are other equivalent candidates).
backend_safe.py
- L212 (ja) — ★2026-09-20(GenSpark 第 44 報 N158): 環状バッファは黙って古い方を捨てる。捨てた数を数えないと、
fallbacks() が 256 件しか返さない理由が利用者から見えない(counts と件数が合わない)。
- L490 (ja) — ★2026-09-19 の門(tests/test_op_probe_ledger)が最初に捕まえたのがこれ:
fly_tau_from_expansion は 「膨張していない標本の time-to-contact は NaN(数を発明すると plausible-wrong)」と docstring に書き、 レジストリの tb_fly_tau_from_expansion はそれを signal の既定値で埋めて有限契約を守る。 関数を直接呼べば NaN の意味が保たれる(flyvision の docstring 参照)。ここに足すときは、その op の docstring に「NaN を返す理由」が書いてあることを確かめること。
- L509 (ja) — ★2026-10-18(0.7.0 の preflight の退化スイープ): 複素の sort を名乗る op でも、入力が実数の NaN / Inf だと実数の配列を返すことがある(3 op とも float64 の NaN を返した)。複素の時だけ埋めていたので、 その実数の非有限がそのまま外へ出ていた。実数でも複素数でも、非有限は記録したうえで 0 で埋める。
- L580 — ★A feature op returns a numpy SCALAR, not an ndarray, so the branch above never saw it: a NaN/Inf measurement (e.g. a 0/0 inside sk_blur_effect on a degenerate frame) used to flow straight out of api.apply. Scrub non-finite scalars to the sort fallback so the declared “finite, sort-valid” guarantee actually holds for feature/contour scalars too.
backends.py
- L23 — ★The _safe fallback is a LAST RESORT and it can MASK A DEAD OP. For out_sort==”image”
backend_safe.fallback returns the clipped INPUT, so a wrapper whose library call raises on every input looks to evolution / difftest / coverage like a working identity op instead of a failure. Runtime robustness is kept, but the degradation is DETECTABLE: every swallowed exception is recorded in the shared fallback ledger and strict mode re-raises instead. 2026-09-02: the ledger / strict switch moved DOWN into backend_safe so that the 23 other backend files (each with a private _safe) report to the SAME place — before, this module was the only one of 24 wrapper families that recorded anything. The names below are kept as thin aliases for callers and tests that import them from here.
- L819 — LBP encoding. ★Until 2026-09-08
b really did nothing, and method was fixed at 'default' (not rotation-invariant). Measuring on real textures (brick / grass / gravel), for anisotropic materials the amount moved by rotation is 9.64x the distance between materials, and switching to 'uniform' brings it down to 1.72x (examples/poc_real_texture_invariance.py). Without a choice there is no way to lower it, so we assigned b. It is made into a threshold table as the convention for when branches increase along the same axis (not nested ifs). b=0.5 (default) is 'default' as before.
- L1035 — ★Passing a bool array to cv2 makes
cv2.Laplacian corrupt the heap, and the process dies at a later unrelated op (2026-09-05 Fable review; I reproduced the SIGSEGV myself within 100 runs on Windows, exit 127). The facade coerces dtype to the contract, but the direct op.fn path (tests, coverage, evolution loop) passed it through. We coerce to float64 at the family’s entry.
backends_auto.py
- L60 (ja) — ★scikit-image が無いときは、同じ答えを返す numpy の双子か、止まる例外か、どちらか(2026-10-25)。 それまでは
_HAS_SK / _HAS_CV が偽だと別の式(面積率、矩形の構造要素、画像平均のしきい値、 恒等写像 …)に黙って落ちていた —— min 構成(numpy + scipy)で image / region 入力の登録 op 488 本を走らせると 89 本が例外なく走って別の値を返した(tools/check_fallback_parity.py で再現できる)。 bit 一致で書けるものは numpy_twins に写し(門: tests/test_numpy_twins_2026_10_25.py)、書けないものは _require_dep で :class:backend_safe.MissingDependencyError を投げる(門: tests/test_fallback_parity_2026_10_25.py)。
- L152 (ja) — ★HALCON と同名の形状係数は、HALCON の式で計算する(2026-09-26)。 名前を借りたのにに別の量を返すと、HALCON のレシピを移してきた人が 同じしきい値で違う判定を得る —— しかも例外は出ない。一次情報: circularity C = min(1, F / (π·max²)) max = 重心から全輪郭画素までの最大距離 compactness C = max(1, L² / (4π·F)) L = 輪郭長 roundness C = 1 - σ/μ μ,σ = 重心→輪郭距離の平均と標準偏差 rectangularity 同じ 1 次・2 次モーメントを持つ矩形との差の面積を矩形面積で正規化 (https://www.mvtec.com/doc/halcon/2605/en/circularity.html ほか)
- L160 (ja) — ★HALCON の
eccentricity は3 値を返す演算子である(Anisometry / Bulkiness / StructureFactor)。2026-09-26 まで、この op は skimage の離心率 sqrt(1-(b/a)²) という 3 つのどれでもない量を返していた。 3 つとも無次元なので、そのまま返して HALCON と数が合う。円なら (1, 1, 0)。
- L174 (ja) — ★寸法を持つ特徴は HALCON と同じ画素値で返す(2026-09-26、ユーザー判断)。 それまでは画像サイズで割って [0,1] に収めていた(「解像度に依らない」規約)。 HALCON のレシピを移してきた人にとっては、正規化も式の違いと同じだけ「数が 合わない」原因になる。正規化が要るなら利用者が割れるが、割った値から画素数を 復元することはできない —— 情報を捨てない側に倒す。docs/KNOWN_ISSUES.md §51。
- L292 (ja) — ★2 次モーメントで向きが決まらない形では、向きは定義に含まれない。 正方形や円は共分散が等方なので固有ベクトルが任意に決まる —— そのまま採点すると モーメント矩形が 45 度回った状態で当たり、正方形が 0.651 になる(実測)。 HALCON は「矩形なら 1 を返す」と明記し、向きが決まらない形での過小評価は 最大 10% と書いている(https://www.mvtec.com/doc/halcon/1911/en/rectangularity_xld.html)。 等方なときは「同じモーメントを持つ矩形」が向きの数だけ在るので、どれを選んでも 定義は満たす。ここでは重なりが最大になる向きを選ぶ —— 任意性を最大側で潰す。
- L808 — ★Do not change the canvas (reshape=False) + reflect outside the frame (mode=”reflect”). Angle is -45°..+45° (0° at a=0.5). The original image is folded back into the four corners, so this is not directly suited to uses that want to “fill outside the frame with a background colour” such as deskewing forms (this is a known design decision, not a bug — for details and how to choose, see the docstring of
ops._rotate_img).
- L831 — ★However, keep the return shape on the same canvas as the input. The image in this registry has a contract that it “connects unconditionally between stages”, so changing the shape makes the evaluator fail because it cannot match the target image (measured: the moment the target-size version returned (70,50),
test_evolve_is_reproducible_given_seed failed with “operands could not be broadcast together with shapes (70,50) (64,64)”). So we place the image resampled to Ht x Wt at the top-left of the canvas, pad the margin with 0, and crop the overflow —— the fact that “the image is now Ht x Wt pixels” stays visible as is.
- L1103 (ja) — ★画素で返す(2026-09-26、ユーザー判断)。それまでは 3 成分とも 画像サイズで割って [0,1] に収めていた(「解像度に依らない」規約)が、 同名は同じ数を取る方に倒した —— 正規化は利用者が割れるが、割った値 から画素数は復元できない。docs/KNOWN_ISSUES.md §51。 [0] 面積(画素数)、[1] 重心の行、[2] 重心の列。 領域が空のときは面積ゼロ・中心は画像中心(fail-soft)。
- L1119 (ja) — ★3 成分を返す op は、空でも 3 成分を返す(スカラーに落ちると 受け取る側の形が入力で変わる)。円の値 (1, 1, 0) を既定にする。
- L1132 (ja) — ★頭打ちを外し、HALCON の式に揃えた(2026-09-26)。以前は
min(1.0, C'/10) で、C’ = L²/(4πF) が 10 を超える形(幅 2 px なら 長さ 80 以上の傷)を全部 1.0 に潰していた —— 傷や割れという、いちばん 見たい領域で「形が違うのに同じ数」が返っていた。HALCON は上ではなく 下を 1 で切る(画素近似で 1 を下回りうるため)。 docs/hardening/compactness-saturated-at-one.md
- L1144 (ja) — ★HALCON は同じ 1 次・2 次モーメントを持つ矩形との差で測る。 以前は軸平行の外接矩形との比(skimage の extent)だったので、 同じ長方形を 30 度回しただけで 1.000 が 0.359 に落ちていた (HALCON は 0.998 のまま)。docs/hardening/halcon-named-shape-factors.md
- L1155 (ja) — ★HALCON の roundness は
1 - σ/μ(重心→輪郭距離の平均と標準偏差)。 以前は 4A/(π·長軸²) という別の量で、16x64 の矩形で 0.239 対 0.577 と食い違っていた。
- L1161 (ja) — ★量もスケールも違っていた(2026-09-26)。等面積円の直径を画像サイズで 割っていたが、HALCON の Diameter は輪郭 2 点間の最大距離(画素)。 30x70 の矩形で 0.2585 対 74.85。おまけに輪郭版
diameter_xld は最大弦を 返していたので、双子どうしで 5.6 倍食い違っていた。
- L1169 (ja) — ★HALCON の
elliptic_axis は (Ra, Rb, Phi) を返す。 ここが返して いたのは Anisometry(= Ra/Rb、別の演算子 eccentricity の出力)を 10 で割ったものだった —— 名前が約束している量ではない。
- L1174 (ja) — ★画素で返す(2026-09-26)。頭打ちも外れる —— 厚みが画像の長辺の半分を 超える領域は、それまで全部 1.0 だった。
- L1178 (ja) — ★画素で返す(2026-09-26)。HALCON の
contlength は輪郭長(画素)。
- L1183 (ja) — ★頭打ちを外した(2026-09-26)。
min(1.0, H/W) だったので、 縦長の対象が全部 1.0 になっていた(60x20 で 1.0、真値 3.0 / 160x4 で 1.0、真値 40.0)。横長は正しく出るので、向きが変わった 瞬間に情報が消える。HALCON の height_width_ratio も軸平行の 外接矩形の高さ/幅で、上限は無い。 docs/hardening/features-saturated-at-one.md
- L1201 (ja) — ★頭打ちを外した(2026-09-26)。細長い形(幅 4・長さ 80 以上)で モーメント特徴が全部 1.0 になり、形が違うのに同じ数が返って いた。値域 [0,1] は feature の契約ではない。 docs/hardening/features-saturated-at-one.md
- L1249 (ja) — ★2026-10-07: 0 画素の平均・標準偏差は 0/0(NaN を guard が置き換えていた)
- L1345 (ja) — ★2026-10-25: skimage 無しの Moore 追跡は画素解像度の別の輪郭(点数も座標も違う)だった。 登録 op の答えとしては返さない(fail-closed)。追跡そのものは明示的に
backends_auto._moore_boundaries(mask) を呼べば使える(近似であることを名乗った別経路)。
- L1355 — ★2026-09-02: what it returned was the integer pixel coordinates of
np.where themselves, so despite calling itself sub_pix it had no sub-pixel precision. We added refinement along the normal via parabola fitting (the same shared helper as core ops._edges_sub_pix; a same-named op wins last in the registry, so this is what actually runs —— fixing only core has no effect). Measured (a synthetic step edge whose true position is column 20.37, a=0.2): the old implementation returned columns {20.0, 21.0} with mean absolute error 0.500 px, and after refinement {20.324, 20.370} with 0.0228 px (about 22x improvement). The number of points and how connected components are split are unchanged (coordinates just move less than 1 px).
- L1434 (ja) — ★画素で返す(2026-09-26)。HALCON の
area_center_xld は (Area, Row, Column, PointOrder)。面積と重心を画素で返す (PointOrder は向きの印なので返していない —— §51)。
- L1440 (ja) — ★region 版と同じ HALCON の式。重心は囲まれた面積の重心を使う (点の平均ではない —— 点が密な側に寄ってしまう)。
- L1446 (ja) — ★region 版と同じ欠陥がここにも在った(
/10 + 頭打ち)。 直した op の双子を見落とすと、穴が半分残る。
- L1465 (ja) — ★画素で返す + 最小外接円ではなく最大弦(2026-09-26)。 領域版
diameter_region と同じ量になる。
- L1470 (ja) — ★HALCON は最小外接矩形ではなく同じモーメントを持つ矩形で測る。 輪郭を一度ラスタ化して region 版と同じ式に載せる(差の面積を 直接測るため)。
- L1476 (ja) — ★領域版と同じ頭打ちが輪郭版にも在った(2026-09-26)。 直した op の双子を見落とすと、穴が半分残る。
- L1484 (ja) — ★region 版と同じ HALCON の 3 値。Ra, Rb は囲まれた面積の幾何 モーメントから導く ——
cv2.fitEllipse は輪郭「点」への 最小二乗当てはめで、細長い形では大きく外れる(実測: 4x80 の 棒で Anisometry 39.1 対 20.65)。HALCON の定義は前者。
- L1500 (ja) — ★elliptic_axis: HALCON は (Ra, Rb, Phi)。fitEllipse は直径を返すので 半径にし、角は列(x)軸から反時計回りのラジアンに直す。
- L1502 (ja) — ★
ang は最初に返る軸(d1 = 短軸のことが多い)の向きなので、 長軸でなければ 90 度回す —— これを忘れると領域版と 90 度ずれる (30x70 の矩形で region 0 度 / xld -89.9 度、2026-09-26 に実測)。
- L1555 — ★At b >= 0.75 it averages over 4 directions (0/45/90/135 degrees). The default b=0.5 is only 0 degrees as before, so existing results do not change by a single bit. Whether it helps depends on a (co-occurrence distance) (poc_real_texture_invariance section 6, 3 real materials): it helps isotropic materials at short-to-medium distances, and helps anisotropic brick only at distance 4 (swing/resolution 3.13 -> 1.54). At distance 1, brick
- L1560 — conversely worsens (0.30 -> 0.56). ★The root cause is that extending the distance collapses the resolution itself, 0.0328 -> 0.0122.
- L1760 — ★2026-09-02: these two shared
{"kind": "zoom"} and were therefore a completely identical implementation, and neither used b (measured: max difference 0.0 for the same input, difference 0.0 between b=0 and b=1). In HALCON the factor version takes two scale factors and the size version takes a target size, which are different things, so we split the kind to match the reality to the names.
- L1833 — ★2026-09-02: the old spec was out_sort=feature / metric=”area”, but the reality was
np.mean(mask) = the area ratio occupied in the image. Since HALCON’s area_center is an op that returns (Area, Row, Column), there was a double discrepancy: (1) it does not return the centre, (2) the area is a ratio rather than a pixel count (= resolution-dependent). A single scalar cannot satisfy the name, so we make it the 1-D vector of the match sort, the same as ncc_locate, and return (area ratio, row, column). Both match and feature are terminal sorts (candidates are identity only), so the genome->op mapping does not move.
- L1840 — ★Since 2026-09-26 all 3 components are in pixels (area [pixel count], row [px], column [px]). The description stayed “normalised” for three weeks, and an example written from it broke by multiplying the coordinates by (H-1) (2026-10-15). tests/test_feature_units_doc_2026_10_15.py checks that the description matches the behaviour.
backends_bridge.py
- L518 (ja) — ★定数列で軸が潰れると
axes_transform は ValueError を投げる(傾きが 無限大になるため、向こうの仕様)。潰れた軸だけここで開く —— 定数列は 「描けない」のではなく「真ん中に水平線 1 本」が正しい絵。
backends_decomp.py
- L142 — ★Apply the BLAS thread cap once outside the loop. This is where a square matrix capped at work_max=64 is SVD’d up to 60 times, using most of the decomposition time in this repo (30.7 s per suite run / 31.4 s total decomposition, svd 23,987 times = 98%). A 64x64 SVD is 3.9x slower with 24 threads than with 1 thread —— because the GEMM inside the decomposition is too small and the synchronization cost exceeds the computation (table in the docstring of fsthreads). Wrapping it each time pays the 2.4us of the mechanism 60 times, so we place it outside the loop.
- L210 — ★
ev[0] is the algebraically largest eigenvalue, not the one with the largest absolute value. On a bright ridge the principal curvature is negative, so ev[0] becomes the one with the smaller absolute value, giving the inverted response of 0 on the ridge and 1 on either side (2026-09-05 Fable review, measured [1, .64, 0, 0, 0, 0, .64, 1]). We take the largest absolute value as described.
backends_measure1d.py
- L83 — ★ A float image in 0..255 (cv2.imread(…).astype(float)) was clipped to a flat 1.0 above 1 — every edge brighter than 1 vanished silently.
backends_r3.py
- L49 — ★Until 2026-09-05 it was swallowing exceptions with
except Exception: out = None. At registration an outer backend_safe.guard is applied, but if the exception is erased inside, the outer sees nothing —— even in strict mode no exception is raised and nothing remains in the ledger. This was a miss of the 2026-09-02 audit of “only 1 of 24 families reached the ledger” (Fable’s adversarial review flagged it as the 5th family). Let the exception out as is: the outer guard records it, coerces it to a value matching the sort, and re-raises if strict.
- L441 (ja) — ★探針は 32 px(2026-09-19、GenSpark 第 7 報 N12): 24 px だと db4 / sym4 の level=2 に足りず (必要 (8-1)·2² = 28 px)、import のたびに pywt の「Level value of 2 is too high」が漏れていた。 さらに
python -W error::UserWarning では警告が例外になり、この try/except が xwt_visushrink / xwt_firm_denoise を黙って落としていた(931 → 929 op、FAILED_BACKENDS にも残らない)。 探針は機能の門であって警告の門ではないので、探針の中の警告は数えない。
backends_scipy.py
- L198 — ★At lambda >= ~12 scipy throws “boundary conditions did not converge”, and the guard’s fallback was the identity (the old 1+40a made 70% identity for a>=0.3, including the default 0.5. 2026-09-05 Fable review). We aligned the description to 1-11 as well.
backends_subpix.py
- L453 (ja) — ★2026-10-02: 以前は halcon “” で「local_max_sub_pix は core op が既にカバー」と書いていたが、 core の
local_max が名乗るのは画素精度の HALCON local_max(サブピクセルではない)で、 local_max_sub_pix を名乗る op は 1 本も無かった(accel の表だけが誤って書いていた)。 兄弟の sp_local_min_sub_pix は local_min_sub_pix を名乗っており、max 側だけが空いていた。
backends_typed.py
- L493 (ja) — ★2026-10-07: 空入力を op が正しく拒否した後、ここが空配列の平均 = NaN を返して いた(8 op。外側の guard が置き換えるので有限に見え、台帳にだけ source=output で 残っていた)。拒否の後始末が 0/0 を作らないよう、空なら 0.0。
- L570 (ja) — ★本当に効く r_lo / r_hi(半径の窓)だが、後者は既定が None で「データから決める」 意味なので、正の数値既定を要求する橋の選定には載らない。嘘のノブを 1 本足すより a だけを配線して b を『未使用』と書くほうが正しい。
- L588 (ja) — ★2026-10-07: 相対スケールの端が定義域の外へ出ていた 2 本(契約電池で、端の knob が 全入力で拒否されていた)。両端は a=0.5 の値が相対スケールと同じになるよう選んだ (window 10 / k 3)—— 既定の挙動と図の主図は動かない。整数の既定を持つ引数は
_make_runner が整数に丸めて渡す。
- L594 (ja) — ★2026-10-18: points_render の不透明度は (0, 1] —— 既定 1.0 の相対スケールは a > 0.5 で 1 を超えて拒否。 足跡の半径は 0.5〜4 画素(a=0.5 で 2.25)。
- L607 (ja) — ★2026-10-07 実測:
tb_cx_apply_transfer_function は H を 32x32 固定で束縛していたので 32x32 以外のスペクトルでは全入力・全 knob で拒否していた(契約電池 24x24、図 128x128)。 tb_temporal_band_power / tb_temporal_bandpass は帯域 [3, 5] Hz 固定で、12 フレーム / 32 fps の探針(ビン間隔 2.67 Hz)には帯域内のビンが無く、契約電池で一度も計算されていなかった。
- L801 (ja) — ★cleandoc で共通の字下げを外してから継ぐ(2026-10-11)。.strip() だけだと 1 行目以外が 4 字下げのまま残り、 字下げの無い橋渡し文を後ろに足すため後段の cleandoc も最小字下げ 0 と見て外さない → docs/ops の Markdown で空行の後の本文がコードブロックとして表示されていた(tb_ 146 本)。
- L886 — ★Until 2026-09-05 it read
tools/chain_fuzz (not shipped) via sys.path manipulation. It failed in the wheel, and since the build() below silently returned [], the tb_* 143 ops were disappearing.
ballistics.py
- L309 (ja) — ★減衰つき(Levenberg–Marquardt)。素の Gauss–Newton は軌跡が短い(曲がりが雑音に埋もれる)と ω の方向が ほぼ不定になり、1 歩で 1e7 rad/s へ飛んだ(2026-09-30、PoC ㉔ の 10〜45 コマ)。費用が下がる歩だけ受け入れる。
- L804 (ja) — ★ dt が標本間隔を超えると模型は標本の間で区分線形になり、C_d と推力が別の値に化けるのに例外も NaN も出ない (30 fps の同じ軌跡で dt = 0.5 s にすると C_d 0.33 → 3.1、2026-10-23 の敵対的レビュー)。歩数の上限は ms で渡した t を止める。
- L965 (ja) — ★ 残差が離散化の床にあるなら n·ln(RSS_b / RSS_t) は丸め屑の比を増幅するだけ(雑音ゼロの真値で +144、推力の推定値は 3e-14 m/s²)。
blob2d.py
- L289 — ★Mind the sign: vertices are ordered as (row, col), so the orientation returned by
_monotone_chain is counter-clockwise (viewing row as x) = clockwise on screen. The inside is the side where the cross product is non-negative (writing <= 0 produced solidity 0 for all objects).
- L621 — ★Erosion alone produces only one side. An object with a smaller label, even when a larger-labelled object is adjacent, keeps itself as the neighbourhood minimum and is judged “interior” (2026-09-06 measured: at the column where 1 and 2 touch, the contour on the 1 side disappeared). Looking at both erosion and dilation gives the symmetric judgment of “there is a different label in the neighbourhood”.
calib.py
- L274 — ★On 2026-09-06 we measured that this gate does not fire on a real camera. On distortion-free synthetic data it works as designed (ratio 3.8e-14 at 0 degrees tilt, 8.6e-10 at 0.05 degrees, both refused). But with realistic barrel distortion k1=-0.18, the planar-homography model no longer fits in the first place, and the ratio sticks around 1.9e-06 regardless of tilt (0 degrees 1.916e-06 / 0.05 degrees 1.935e-06 / 0.2 degrees 2.005e-06).
- L280 — ★Only when two conditions are met together: that there is distortion and that the board moves sideways between viewpoints. With either one alone the gate rings as designed (the separation is the 3 in tests/test_calib.py). And an actual calibration session always has both, since you shoot while moving the board by hand. Nor is it enough to just raise the threshold —— with distortion, the gap between full degeneracy 1.92e-06 and 2 degrees tilt 4.42e-06 is only 2.3x, and no dividing line can be drawn. Therefore: * leave the threshold as is (it works correctly for distortion-corrected points) * return the ratio itself as
orientation_rank_ratio * let the later gate that actually stops things say “tilt the board” (below). Instead of fixing it, we hand the user the material for judgment.
caltab.py
- L256 — ★What this gate does not catch: errors in the intrinsic parameters for a single planar target (especially the fx/fy ratio). A single-plane homography places only two constraints on the intrinsics (Zhang 2000), so a wrong fy is mostly absorbed into the 6 DoF pose being solved here, and the residual can stay below the threshold. Measured 2026-09-05: even setting fy wrong from 500 -> 300 gives RMS 0.90 px on Linux/scipy 1.18 (0.14 px with the correct K). The same input becomes 6.39 px on Windows/old scipy, so it “detects or not” purely by the difference in where the optimization converges. If you want to verify the intrinsics, take 3 or more viewpoints or use a non-planar target. Where this works is inconsistencies that “cannot be absorbed by the pose” (wrong correspondences, a non-planar board).
carpath.py
-
| L169 (ja) — ★OMPL の mod2pi は (−π, π] に折る(Python の [0, 2π) ではない)。ここを [0, 2π) にすると t >= 0 の判定が常に真に なり、CCSC 系 8 語が一度も候補に出ず(2026-09-28 に語の族を数えて発見)、負の区間長が 2π − |
t |
の遠回りに化ける。 |
champion_to_macro.py
- L225 — ★Enforce the headline honesty claim (“a DNA op is added only when it beats the hand baseline on a LOCKED holdout”) — previously this flag was printed but never gated, so a worse-than-hand macro could be registered and then selected by the next evolution. The gate refuses that unless it is explicitly overridden.
conngraph.py
- L357 (ja) — ★2026-10-07: 非零の向きつきグラフに閉路(自己ループ含む)が無ければ W は冪零 = 半径はちょうど 0。 ARPACK は冪零(Jordan 塊)で擬スペクトルの縁を返す(鎖 500 個で 0.366、層状 DAG で 3.6e-5 → reservoir_from_graph が 0 を拒否せず 2.5 万倍に拡大した)。残差では見分けられないので構造で判定する。
- L365 (ja) — ★2026-10-07: 強連結成分で並べ替えると W はブロック三角 → 固有値は対角ブロックの和集合。 既約な非負ブロックなら Perron 根に ARPACK が確実に届く(冪零な DAG 部分は 0 に寄与)。
- L727 (ja) — ★ 軸ごとに [0,1] へ伸ばすと(成分が横一列のとき)縦だけ 3 倍に伸びて 成分内の距離が成分間より大きくなる —— 全体は一様に縮める。
- L1077 (ja) — ★2026-10-07: 入力の和が 0 以下の受け手(負の重みが勝つ)は「和を 1 に正規化」できない。 以前は 1e-300 で割って 1e300 倍に吹き飛び、linear の正規化で他の列が 4e-301 に潰れた。
- L87 — ★Bit-exactness is not guaranteed (corrected 2026-09-05). The math is independent per row, but
U @ w is a BLAS GEMM, so the reduction splitting and vectorization path change with the row count M, and the rounding can change. Measured: the moment torch was added to CI’s py3.11 job (= the moment a different OpenMP runtime was loaded), the results diverged between chunked and non-chunked. What is guaranteed is numerical agreement (a few ULP), not bit-exactness.
demops.py
- L105 — ★We do not provide the option to fill with the median or the like. Filling creates a plain that does not exist and lets water through without raising an exception. But the size of the effect we record honestly. On the same real data (Tokyo bayfront 1024x1024, 3.83% missing), the max catchment cell count compared across 3 ways: outlet 312,108 (29.8%) / median fill 338,188 (32.3%) / wall 315,023 (30.0%). Filling inflates by about 8%, but the fact that “one cell gathers 30% of the whole” is itself the reality of this terrain (a flat reclaimed land really does converge to one spot). Writing at first, from looking only at the fill, “this figure is a product of filling” was an exaggeration; taking a control shrank the effect. We do not provide a fill option because it becomes impossible to distinguish where the terrain is real and where it is fill, not because the figure changes by orders of magnitude.
- L613 — ★We first noticed this slowness when the sky-view factor for 513^2 took 41.9 seconds in the PoC (examples/poc_dem_terrain.py). The tests used only small grids, so they confirmed it “works” but not that it is “usable”.
- L694 — ★Fixed 2026-09-08 (found by
poc_stockpile_volume). When a line-of-sight sample rounds via np.rint to the target cell itself, that cell’s height gets compared against itself as “intervening terrain”. Since t < 1 the denominator dist*t is small, and (z-eye)/(dist*t) > (z-eye)/dist is always true when z > eye —— so cells higher than eye level were self-occluding across the board. Measured (before fix): a 10 m column on flat ground was returned as “not visible” from 25 m away at eye 2 m, and only a 1 m column below eye level was “visible”. The highest point of a convex solid is always visible from outside, so this is geometrically wrong. We do not count the iterations where the sample landed on the target cell.
- L754 — ★The ledger declares
points = (N, 3). Passing a scalar yields (3,), which conflicts with the declaration, so we always fold to (N, 3) (surfaced by the fuzzer’s TYPEMISS on 2026-09-06; the fuzzer had not been run after adding the 6 geocentric-coordinate ops). When you want (H, W, 3) as a grid, use :func:dem_geocentric_grid.
-
| L807 — ★Inside the evolute the geodetic latitude is not unique -> instead of silently returning an out-of-range latitude, refuse. The evolute of the ellipse x²/a² + z²/b² = 1 is (a·x)^(2/3) + (b·z)^(2/3) = (a²-b²)^(2/3). Only outside the equality is the region where “the normal is uniquely determined” (since the 2/3 power is non-negative, the sign is |
z |
). |
- L988 (ja) — ★ 鎖の残り。ECEF ↔ 測地座標 は在ったが、その先(ジオイド高・標高・datum・ENU) # が無く、能力ノート docs/capabilities/geodetic-frames.md に「どれも未実装。 # GNSS が返すのは楕円体高で地図が使うのは標高、取り違えると日本付近で 30〜40 m # 静かにずれる」と自分で書いてあった。ここを閉じる。 # ————————————————————————— # :func:
dem_height_frame_convert が受ける高さの基準。
detect.py
- L60 (ja) — ★しきい値は argmax ビンの上端(2026-09-26、ops._otsu と同じ直し)。 中点だと argmax ビン(背景の山を含む)の画素が前景に入り、平らな板で 全画素が 1 つの対象として返っていた。
device.py
- L62 (ja) — ★
available は「SDK が入っている」であって「Fullseye から開ける」ではない。 2026-09-25 まで名簿はこの 2 つを 1 つの欄で答えていた —— dynamixel_sdk を入れた 機械で available は True になるのに、open_driver("dynamixel") は「その SDK を 直接使え」と断る。読んだ人は「対応済み」と受け取る。 implemented は環境に依らない(この版に一級のアダプタが在るか)ので、表にも 書けるし、どの機械でも同じ門で見られる。「いま開けるか」は implemented and available。
- L68 (ja) — ★欄の名前は自分で決めていない ——
acquire は既にこの区別を持っていた (implemented = opener が在る / available = SDK が在る、「the two are different questions」と註まで在る)。同じ問いに 3 層が別々の語で答えると、 読む側は毎回学び直す。先に正しかった層の語に合わせる。
- L105 (ja) — ★名簿の綴りと構築子の綴りが違っていた。 名簿(
capabilities())は io-modbus と名乗るのに、構築子は DigitalIO("modbus") を取る —— つまり表を読んでそのまま渡すと ValueError になっていた。名簿を 印刷しておきながら、その綴りで呼べないのは名簿の側の不備である。
- L161 (ja) — ★名簿に 12 載せて、扉が 3 つしか無かった(2026-09-25)。
capabilities() は I-O・サーボ・ロボット・ROS を名乗るのに、開ける口が在ったのは :class:DigitalIO の 3 backend だけで、残り 9 には入口が 1 つも無かった —— 名簿を読んだ人が、そこから何かを始める方法が無い。隣の層(comm)は 同じ問いに既に答えていたので、これは機能の不在ではなく片側の入口だけが 塞がれていた型である。開けないものにも「何を入れればよいか」を返す。
- L189 (ja) — ★PyPI に無い SDK(ベンダ配布の wheel)は「pip install None」と言わせない。
drivehumanoid.py
- L375 (ja) — ★ユーザー案(2026-10-03)「あらかじめ物体ごとの描画をマスク付きで作っておく」。精細なメッシュを向き × 位相ごとに 一度だけ描き(色・マスク・深度のずれ)、毎コマは縮めて貼り、世界の深度と比べて前後を決める。見た目は精細なまま、 1 体の費用は貼る画素の数だけ。近似は 2 つ(門で大きさを測る): (1) 方位を n_yaw 段に丸める、(2) 事前描画は水平に 遠くから見た像なので、カメラが高い・近いときの透視の違いを無視する。
driveinf.py
- L209 (ja) — ★道の帯は step ごとに切る: 描画器(render3d)は頂点が 1 つでもカメラの後ろにある三角形を捨てるので、100 m 級の 1 枚の帯は車載カメラから丸ごと消えた(2026-10-01)
driveworld.py
- L615 (ja) — ★2026-10-07: 置いた高さ z を物体に残す(残さないと world_move が元の z を外せず、z=2 で置いて z=2 へ動かすと底が 4 になった)
dualxray.py
- L218 (ja) — ★2026-10-15 探針で見つけた: Pb 50 mm でも e^{-130} は 0 にならず、正規化すると「ほぼ何も通らない」スペクトルが ふつうの顔で返っていた。透過が 1e-12 を切ったら値を返さず拒否する。
- L956 (ja) — ★2026-10-15 探針で見つけた: Fe(26)より上は R がほとんど同じになる(80 kV・窓 20/45 keV の薄い板で Fe 4.403 / Ni 4.417 / Cu 4.418 / Zn 4.416 —— Cu と Zn は逆転する)。区別できない範囲を照合に入れると、 単調性の検査で拒否するか、雑音で Z が 26〜30 を飛び回る。照合は Fe までにし、それより重い R は範囲の外(NaN)。
engine.py
- L190 (ja) — ★backend が入っていないだけの名前は「unknown」でなく不足 extra を言う(api._resolve と同じ門、2026-09-19)
- L243 (ja) — ★op 名は文字列でなければならない(2026-09-20): 以前は str() で何でも名前にしていたので、 {“op”: “gaussian”} が “{‘op’: ‘gaussian’}” という op 名になり、run で unknown operator になっていた。 名前の規則は stage_name の 1 本(diagnose_stages / unified.Pipeline と共有)。
- L274 (ja) — ★2026-09-20(GenSpark 第 30 報 N107): {“stages”: None} が 0 段のエンジンになり、run が入力をそのまま 返していた(壊れた設定が「成功」)。[] は文書どおり恒等、None / 数値は設定の壊れ。
- L280 (ja) — ★2026-09-20(GenSpark 第 30 報 N107 の ‘x’ の行): 文字列は 1 文字ずつ段になっていた。from_ops と同じ ops 文字列。
- L372 (ja) — ★範囲外は断る(2026-09-20、GenSpark N40): –upto 9 / -1 が黙って全段 / 0 段になっていた
evis_fullseye_bridge.py
- L152 — ★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 — ★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 — ★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
- L148 (ja) — 書いた図の sha256 -> 名前。★同じ中身の図が 2 枚出たら台帳に積む
- L220 — ★
colorize_depth returns float [0,1]. Receiving it with np.asarray(..., np.uint8) truncates every 0.x to 0 and turns it pitch black (hit on 2026-09-06).
- L378 — ★Do not drop the body of the example. It is a pity that the figure does not appear, but the numbers must be shown.
- L417 — ★Do not just hand off to :func:
_to_rgb8 here. That passes (H,W) to colorize_depth, but inside it each frame is normalized individually, so a frame that is all 0 and a frame that is all 1 come out the same colour (caught by a test on 2026-09-09). Only by passing the value range explicitly does the scale become a single one.
- L482 — ★Pillow folds a frame identical to the previous one into a single frame (that time is added to the previous frame’s display time, so the speed of motion does not change). We count after writing and, if it differs from the number passed, record both in the ledger —— so as not to silently pass off “a 72-frame GIF” whose content is 40 frames.
- L650 — ★2026-09-08: when the panel is small the title does not fit, and
annotate_figure_grid (correctly) refuses, so one figure was silently disappearing. A 29×19 core grid or a 24×24 reduced map appears routinely in PoCs, yet the error says “shorten the title” —— the actual fix is “enlarge the panel”. Two people fell into the same hole independently (there is a case where one scene figure on the signboard disappeared), so instead of making each caller write the enlargement, we do a nearest-neighbour enlargement once here. We use nearest neighbour so as not to create values by enlarging (interpolation would create intermediate values that do not exist on the figure, and the pseudo-colour would lie).
- L767 (ja) — ★2026-10-03: 下の余白を 16 px 広げた。軸名の帯(左下)が x 軸の目盛りの数字に重なって 「0.5」や「20」を隠していた(transforms_tour の図で踏んだ。全部の save_plot に効く)。
- L779 (ja) — ★2026-10-21: 棒を 1 本ずつ別の系列にした図(色を棒ごとに変えるため)は、系列の中に x が 1 つしか なく plot_series が間隔を知れないので、棒が描画域の 70 % の幅になり隣と重なった(製造公差 PoC の 歩留まりの対比図で目視)。棒の x を全系列から集め、その最小間隔(棒が 1 本しかなければ目盛りの 間隔)を画素に直して、1 点の系列にだけ bar_width として渡す。複数点の系列は従来どおり自分の間隔。
- L811 (ja) — ★2026-10-03: 凡例はデータを最も隠さない隅に置く(MATLAB の legend(‘best’))。右上固定だと 減衰の遅い応答の山が凡例の下に隠れた。点の数で象限を選ぶ最初の版も、Runge の端の山を 半分隠した —— 隠れるのは「点」でなく「線の画素」なので、各隅に凡例を試しに描き、 その矩形の下にあるデータの画素(背景でも格子でもない画素)を数えて最少の隅を選ぶ。
examples/acoustic_condition_monitoring.py
- L469 — ★Parabolic interpolation retains a bias that pulls toward integers (because the peak is sinc-like and cannot be fully approximated by a quadratic). We sweep from 0 to 1, measure the bias, and show that it forms an S-curve —— if we stop at “we could read down to the sub-sample”, this bias silently rides along in the result.
examples/annotate_paper_tour.py
- L51 — ★EXTEND: replace text and path with the text and polyline (x, y) of your own figure
examples/blas_thread_budget.py
- L117 — ★This is the key point. 96x96 is not “fast because it is small” — it is a size at which being small is exactly what makes multithreading a loss. Put it outside the loop once (wrapping it each iteration means paying the cost of the throttling mechanism itself 30 times).
examples/blob_split_tour.py
- L98 — ★Measured (honest): a seed also stands on a bar of height 2 < h. blob_seeds uses the residual
f - R > 0 as the seed, but when each component is reconstructed with background 0, a component whose peak height M < h gives R = M - h < 0, so the residual is positive across all pixels of the component and even a 1 px border of background (skimage’s h_maxima rejects with residual >= h). We report without fixing the implementation. Here we drop the bar’s seed and check the “seedless blob” path.
- L129 — ★Measured (honest): the split does not sit on the intersection line — the side of the higher-numbered seed bites in along the valley. blob_split, dilating stage by stage, assigns “a pixel touched by both regions” to the max of grey_dilation (= the larger number), so via 8-connected diagonal chaining the higher-numbered region intrudes several columns along the valley line. Swapping the seed numbers swaps the direction of intrusion too (a bias of numbering, not geometry). We report without fixing the implementation.
- L153 — ★Measured (honest): with textbook h-maxima, the seeds merge into one the moment h exceeds “the prominence of the lower peak (16 - saddle 10.07 = 5.93)”. blob_seeds uses residual > 0 as the seed, so residual = min(h, prominence) > 0 always holds and the lower peak’s seed never disappears at that h. The merge happens when h exceeds “the higher peak - saddle (22 - 10.07 = 11.93)” — the peak it references is the opposite one.
examples/coherence_scanning.py
- L166 — 6) ★ Cross-check against the phase-shifting method # —————————————————————— #
examples/dem_geodesy_tour.py
- L49 — ★Unless the repository root is on the path,
demops is not found (this example does not import fullseye, so the path hook does not kick in).
- L61 — ★EXTEND: replace with the north-west corner of your own tile (this is near Tokyo).
- L131 — ★Honest breakdown: a single Bowring iteration gives 1e-9 m on the ellipsoid surface, but the error grows with height (measured 8e-7 m at 8848 m, 4e-6 m at 20 km). The docstring’s “1e-12 deg / 1e-7 m” are near-surface values and do not hold at stratospheric heights. For terrain use (elevation < 9 km) it is 1e-6 m, and here we set the threshold at 1e-5 m.
- L160 — ★EXTEND: replace dem with real data (row 0 is north). This is a known slope.
examples/dem_terrain_analysis_tour.py
- L46 — ★Unless the repository root is on the path,
demops is not found (this example does not import fullseye, so the path hook does not kick in).
- L59 — ★EXTEND: cell size [m]. For real data, obtain it via dem_cell_size_webmercator(zoom, latitude).
- L158 — ★Honest observation: when there is a no-data cell partway down a slope, its northern neighbour, even as an outlet, does not drain into the no-data but goes south-west (the direction with a finite drop). The implementation is “drain into no-data only when there is nowhere else to descend”, narrower than the docstring’s “allows flow toward no-data”. Here we only print and do not assert.
examples/example_inner_diameter_mm.py
- L67 (ja) — 穴(暗い側)を前景に。★面積の大小では決めない —— 穴と地の面積がほぼ同じだと 取り違える(R=100 px の的で地の側を「穴」と取った、2026-10-15)。輝度で決める。
- L71 (ja) — area_center は (面積 [px²], 行 [px], 列 [px])。★2026-09-26 に正規化 [0,1] から HALCON と同じ画素値に変わった(ecdaf14637)。
examples/gallery2d_color_artistic.py
- L224 (ja) — ★向きも見る(2026-09-26)。ここまでの確認は「二値」「自明解でない」だけで、 どちらの向きでも通っていた —— 実際この op は兄弟の補集合を返していた (docs/hardening/itk-threshold-ops-returned-the-dark-side.md)。明るい画素の 方が region に入ることを、入力そのものと突き合わせて確かめる。
examples/gallery2d_edges.py
- L217 (ja) — ★null を破るのは「雑音の扱い」: 素の衝撃は雑音を構造に化かすので、 段差が真値を超える。超えたら鮮鋭化ではなく増幅である。
examples/gallery2d_features.py
- L270 (ja) — ★返り値は bits/16 なので 16 倍して読む。上限は画素数で決まる —— 連続値の 画像では最小の刻みが ~1/N になるので推定は log2(N) 付近で頭打ちになり、 16 には届かない(256x256 = 65536 画素で 16 前後、128x128 では 13.7 と実測)。 「測れない線」を画素数から先に引いておくための注意書きで、門もそう書く。
examples/gallery2d_morphology.py
- L228 (ja) — ★背景の 1 点だけでは足りない —— 前景の外に 1 画素も漏れていないことを 全数で見る。離散の円板で膨らませると境界の外まで塗ってしまい、最初の実装は 前景 197 画素の円に対して外へ 48 画素(24%)漏らしていた。中心の値は正しい ままなので、中心だけ見る検査では捕まらない。
- L240 (ja) — ★閾値を選ばない op なので、検証も「閾値を選ばずに 3 つの山を同時に当てる」 形にする。高さ 1.0 / 0.6 / 0.3 の山を置いて、そのまま返るかを見る。
examples/gallery2d_texture_freq.py
- L305 (ja) — ★窓は
_k(a) が決める —— a=0.5 は 7x7(5x5 ではない)。ここを取り違えると 閉形式の定数がずれて、正しい実装が落ちる(実際に一度落とした)。
examples/gallery_illusion_invariants.py
- L231 (ja) — ★docstring は (−2, −2) と書くが、この盤(行・列、上向きで出発・白で右)では (+2, −2)。 定理が言うのは「周期 104 で同じ斜めの 2 マス」で、符号は回転の規約で変わる(perpetual.py の自己検査と同じ読み)。
examples/gallery_nary_image_algebra.py
- L117 (ja) — ★公開の入口
fullseye.apply は n-ary の 2 入力に「同じ形」を要求する(3×3 のマスクは形の不一致で拒まれる)。 画像と同じ大きさのゼロ配列の中央(scipy の原点 = N // 2)に置けば、同じマスクとして働く。
examples/gallery_openvx_spec_values.py
- L39 (ja) — vx_nonlinear_filter の function(vx_non_linear_filter_e)。★引用符つきの “median” を書くと、例の索引 (tools/op_example_index.py)が「この例は 2-D の median op を呼んでいる」と数えてしまう (引用符つきの op 名は振り分けの一覧として拾う規則)。ここは fullseye の median op を使わないので 1 本の文字列から分ける。
examples/optics_four_f_processor.py
- L84 (ja) — ★数字は構成で変わる。どの構成で測ったかを必ず併記する —— 併記しないと 説明文が別の実行の数字を引いたまま残る(2026-09-26 にこの例で踏んだ)。
- L199 (ja) — ★(1, N) のまま渡すと four_f_filter が「2x2 未満」で断る。 場と同じ格子に広げる —— 断ってくれる op のおかげで気づけた。
- L217 (ja) — ★図・動画は opt-in。既定で出さないのは、CI が図の生成時間を払わないため。
examples/piv_flow_from_particles.py
- L27 — ★Since it imports a module (pivops) at the repo root, place the repo root at the front so it runs straight from a checkout. Same convention as the other examples. Without this,
py -3.11 examples/<name>.py fails with ModuleNotFoundError (measured 2026-09-09: of the 83 that had no gate to run them, only these 2 of this kind failed).
examples/poc_active_contours.py
- L258 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_allsky_cloud_cover.py
- L104 — ★The last 3 are thin clouds (differing optical thickness). Raising the threshold drops them thinnest-first — that is what produces the staircase in Section 4.
- L142 — ★Solid-angle weight. dΩ/dA = sinθ/(f²θ) — the Jacobian of the equidistant projection.
examples/poc_asbuilt_wall_deviation.py
- L497 — ★What was missing was not tilt but bulge. The quantity predict_bulge returns in closed form as the first-order coefficient becomes, as is, a spurious tilt and a spurious in-plane deflection.
- L555 — ★To the closed form we pass the effective tilt with the portion absorbed as bulge (§6) included. Without it, only the single point at f=0 is off by 1.2 mrad, making the prediction look wrong.
- L660 — ★A floor of noise only. Reading it the same way against a zero-bulge wall yields this.
examples/poc_astro_photometry.py
- L322 — ★ We got it wrong here once: thinking “scale=2 so brightness is also 1/4”, we wrote flux/4 and produced -74.89 %. The conservation law (6.1e-14 above) rejected it. The per-pixel brightness becomes 1/4, but the total sum of a star does not change.
- L423 — ★ We dropped an assert here once: the rms in the table above (one stack, 8 isolated stars) gave good-6-frames 0.306 % vs good-12-frames 0.324 % = 0.947x. This is not a refutation of the theoretical 1.414 — it meant that rms was the sum of “per-star systematic offset” and “noise”, and with 8 samples you cannot isolate the noise alone. As in stage 1, only after accumulating iterations and subtracting the per-star mean does noise alone remain.
examples/poc_attention_identities.py
- L232 (ja) — ★合否にするのは厳密に数えられる側だけ。(QK^T)V は 2T^2 d + 2T^2 d 回、 Q(K^T V) は 2Td^2 + 2Td^2 回の積和なので、比は 厳密に T/d である。 これは機械に依らない整数の主張で、交差点が T == d にあることの中身でもある。
- L563 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/poc_barcode_1d.py
- L806 — (d) ★The edge count of measure_pos depends non-monotonically on sigma.
examples/poc_battery_ct_degradation.py
- L316 — ★
sdf_offset is scalar only, so to offset it as a field we warp the grid and evaluate.
- L334 — ★To keep the stack from punching through the can, we locally compress it to the height the deflected end plate allows (in real cells too the electrodes are pressurized and shrink). Without this, at tall gas voids the end layer gets eaten by the can and the layer-count comparison breaks (that is what happened at first).
- L612 — ★Count layers by the “number of rising edges”. Counting by
vol_wall_thickness pairs (rising -> falling), a single extra falling edge just inside the can’s inner surface throws the pairing off and drops even a healthy cell from 17 -> 16.
examples/poc_battery_electrode_tortuosity.py
- L136 — ★Processing not on a public path: a 6-neighbour adjacency graph in voxel space. fullseye has 3-D # connected components (vol_label) and a distance transform (vol_distance_transform), but # no entry point (geodesic distance, transport) for handling “a path passing through the void”. # ————————————————————————— #
- L258 — ★Passing a 64-voxel slice as is gives a panel only 64 px wide, so the title text does not fit and the whole figure fails (examplefig does not give up silently).
- L279 — ★Leaving the solid phase at 0 makes log10(dissipation) negative, so the solid phase is painted brightest (we produced exactly that once on 2026-09-08). We map the solid phase to the bottom 2 % of the void.
examples/poc_beam_modal_video.py
- L629 — ★Collision: at fps 48.5 the aliasing of the illumination lands exactly on f_1 = 3.00 Hz
examples/poc_beats_fringes_and_screens.py
- L237 (ja) — ★デューティ 50 % の矩形格子は偶数次が消える —— 矩形波のフーリエ係数が 偶数調波でちょうど 0 になるからで、これは実装の都合ではない閉形式の事実。 最初「±1, ±2 が立つ」と期待して NG にした: 期待が誤っていた(op は正しい)。 偶数次が「消えていること」まで見るので、山の位置だけを見るより強い門になる。
- L535 (ja) — ★図の書き出しが失敗したら、ここで拾う。見ないと「検査は全部 OK・でも図は 1 枚も出ていない」が黙って通る(examplefig は fail-soft で貯める)。
examples/poc_bev_sensor_fusion.py
- L135 — It is placed. ★This is not decoration: * Putting a face on a cell boundary spills half of the face’s return into the neighbour as noise, dropping the fit rate to 0.5 by discretisation alone. * Putting a face at a cell centre makes the ground truth itself go in or out depending on floating-point rounding (actually hit: the returned column of the side wall fell off the ground truth, and most of the 133 falsely-occupied cells were that). Placing it in between makes neither happen.
h avoids multiples of 0.2 m — to show the height quantization. lx/ly are set to odd multiples of 0.1 m.
- L564 — ★The error is about the world z-axis (= same as place). Writing
R_wc @ rz turns it into a roll about the optical axis, and the reprojection error morphs to 1/5 (hit on 2026-09-07: it came out 0.98 px and did not match the geometric prediction f·tanθ, which is how it surfaced).
examples/poc_bilateral_asymmetry.py
- L585 — ★Keep it in a form that can pass the hole-D gate as is (the margin collapses first, the angle jumps afterward).
examples/poc_bone_trabecular_thickness.py
- L708 (ja) — ★穴が塞がったので、所見を「無い」から「規約が 1 画素ずれる」に書き換える。
examples/poc_bump_coplanarity.py
- L147 — ★A genuine low-order defect (a die-attach void = the centre sinks gently). Deliberately not made exactly quadratic — if it were quadratic, the fit would by definition absorb 100 %, making the question “how much gets absorbed” trivial.
-
| L306 — ★Clip at ±SPEC_UM before passing. examplefig’s diverging colour map normalizes per panel by max |
v |
, so without clipping the colour meaning across the 3 panels does not line up. |
- L445 — 6. ★The harm of over-subtraction —— it absorbs genuine low-order defects # ————————————————————————— #
- L540 — (e) ★surface_form_error via the ledger returns only a PV float
examples/poc_cad_scan_deviation.py
- L434 — ★The ledger’s out adapter truncates the dict to (R, t), so rmse does not get through
- L897 — Chapter 6: ★The defect pulls the alignment —— predicted by projection onto the rigid-body 6-D # ————————————————————————— #
- L1103 — ★Do not add a defect —— if you do, Chapter 6’s datum shift (0.107 mm) becomes a pedestal on the point movement and mixes with “the amount broken by the initial angle”.
- L1256 — ★Producing a “%” for the control group whose ground truth is 0 gives a meaningless huge number from division by zero. Present the area in mm^2 as is, and append % only when the ground truth is meaningful.
- L1267 — ★Do not read the difference of a single run as “it worked” —— vary the seed and compare against the spread
- L1357 — ★An assert that fires once the gap is closed. It actually fired on 2026-09-07, and this line was rewritten: after the note that “cylindrical holes, chamfers, and fillets cannot be built”, plane / cylinder / torus / capsule were added. The note changed the tool, so we record it and move on.
- L1379 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
examples/poc_calipers_under_illusion.py
- L141 (ja) — ★はじめ図説に「半幅を変えると採用点の数が変わる」と書いたが、生成された 本文を読むと 4 通りとも 41 点だった。書いたことがデータと違ったので 直し、「変わらない」ほうを門にした。証拠の数が動く例は第 5 章のツェルナー。
- L150 (ja) — (b) ★探針 1 枚では足りない —- ずらし量 × 探索半幅の格子で全数を見る 最初は shift=0.25 だけで試して「測定器は決して動かない」と書いた。 格子で見ると 0.125 と 0.375 でだけ 0.14 度傾く。既定に見える 0.25 は、たまたま外れない側だった。
- L266 (ja) — 外れた組み合わせを絵の上に描き戻す。★全体図では 8 px の飛びが潰れて 見えないので、目地の帯の周りだけを等倍で切り出す。
- L365 (ja) — ★測定線は軸そのものの上にある。そのまま塗ると被写体が消えるので、 指示線だけ 12 px 上へ逃がして描く(測っている行は軸の行のまま)。
- L476 (ja) — ★中心の座標は推測せず illusion.py から読む(最初 (h/2, w/4) と当てずっぽうに 置いて、周りの円のエッジを掴み rms が 3.4 になった)。真の中心は (170, 168) と (170, 452)、半径 30。
examples/poc_camera_calibration.py
- L152 — ── Calibration (a hand-rolled minimal bundle adjustment. ★ Gap (e)) ──────────────────────────────────── #
- L181 — ★ Gap (d): the image points of camera_calibration are (row, col). project_points are (x, y).
- L519 — ★ Gap (b): reprojection_error does not know about distortion. Even passing the ground-truth values does not yield 0.
- L740 — 2. ★ The main point: the reprojection RMS is nearly the same, yet the fx error differs by more than an order of magnitude
- L748 — 3. ★ The cancellation mechanism: the ratio of fx matches the ratio of Z
- L754 — 4b. ★ An honest record of a loss: with a narrow field of view + 0.30 px noise, the zero-point B that pins the principal point to the image center is more correct than estimating it (a condition where you cannot do better really exists)
- L770 — ★ Gap (c): since the points are distorted, what stopped it was not the degeneracy gate but the later non-finite K gate. We even confirm that its message contains “tilt the board” (added 2026-09-06).
- L778 — 5b. ★ Gap (c3): the closed form is systematically off by the amount of distortion (initial-value only)
- L782 — 6. ★ Gap (b): reprojection_error does not know about distortion -> even passing the ground-truth values, it stays large
- L788 — 7. ★ Hole (a) [Resolved 2026-09-19]: intrinsic estimation is now exposed on the facade. It used to be invisible from
fs, and this tripwire kept firing “once it is closed, update the docstring”. Now it is callable as fs.camera_calibration (capability note camera-intrinsics-calibration). It is a facade function, though, not an op in the registry (it is not the fixed (image, a, b) form).
examples/poc_cell_counting.py
- L68 (ja) — ★2026-10-02: 他の PoC と同じく、リポジトリ直下を自分で sys.path に足してから fullseye を import する。 パスフック頼みだと、examples/ から PYTHONPATH 無しで走らせたとき(tests/test_poc_scripts_run.py の走らせ方)に 本線の editable install の fullseye が先に入り、この worktree で足した台帳(watersheds_marker)が無くて落ちた。
- L860 — ★The smallest h you can specify is 0.05 x max(distance transform). A single large cell in the image is enough to raise the lower bound of h for the whole image (a coupling imposed by the op’s spec).
- L1048 — ★The headline of this PoC. At the place where the bias line crosses 0, the segmentation error is not a valley.
- L1337 — ★Over-merging and missing are different things —— things that stick together have not “disappeared”
- L1365 — ★The optimal h moves with density (it always moves by either the bias criterion or the one-to-one criterion)
- L1368 — (5) ★A point where the count is correct yet the segmentation is entirely wrong really exists: the bias is under 3 %, yet many segmentation errors remain and the one-to-one correspondence is far from the best.
- L1394 — ★The smallest h you can specify rises with the size ratio (a scale coupling imposed by the tool’s spec)
- L1434 — (10) ★Mechanically confirm that the tool’s gap “still exists” (it fails once fixed = a good kind of failure) (a) the distance transform of the evolution op is normalized by its maximum value
examples/poc_change_detection_misreg.py
- L947 — ★A single graph: residual offset vs false positives (the sweep line + the registration-result points)
examples/poc_cold_chain_excursion.py
- L570 — ★The window for finding the peak goes only up to just before the next door opening/closing. If you make it too wide, at large τ it picks up the rising edge of the next pulse and makes it look as though “the cliff never comes” (stepped on this on 2026-09-08 with a 200-minute window: the measured y=53 stretched to 153 minutes).
- L949 — ★Make the line-of-sight direction (the D axis) the width. If you project with (t, y, x) as is, D = time 720, and you only get a thin (H, W) = (60, 12) image.
- L1008 — ★Distinguish whether a “hit” is thanks to the convention or mere chance: perturb each point by ±1 m and count.
examples/poc_colocalization_crosstalk.py
- L355 — ★Prediction of tail loss: the tail of the Gaussian below the threshold T does not enter the region. Of a peak-p point, the in-region fluorescence is 1 − (T − pedestal)/p (the closed form for the volume of a 2-D Gaussian). Pedestal = cytoplasm + background (+ the bleed-in), and p is squashed by the PSF by a factor of σ_ves²/(σ_ves²+σ_psf²).
- L657 (ja) — ★2026-09-20:
graph_degree_preserving_shuffle(結合グラフの辺の繋ぎ替え = null model)が台帳に入った。ここで探している 「画像ブロックの並べ替え検定」とは別物なので、graph_ の族は穴の判定から除く(語が同じだけ)。
examples/poc_colormap_readability.py
- L343 — ★The difference readable from a row of steps is Δ + a one-pixel-wide ramp —— forget this and you overestimate the cliff by 2x (I first wrote it that way and got 0.57 vs the measured 0.30)
- L406 — ★Divide by the true gradient. Without dividing, you end up counting “places where the field is steep” as boundaries
- L657 — ★Exceeding the number of colors is rejected by default (this PoC pointed it out and it became fail-closed the same day). Here the goal is to measure “what happens if you cycle”, so we set cycle=True explicitly —— forcing that explicitness is itself the countermeasure.
- L732 — ★Fixed the same day thanks to this PoC’s note. The roster’s criterion was only “monotonicity of lightness”, so cividis—monotonic in lightness but coarse in color-difference steps—was calling itself “safe”. Now uniformity of color difference is also part of the criterion, and cividis has moved to CVD_SAFE.
examples/poc_complex_plane_fields.py
- L289 (ja) — ★「そのまま渡すと厳密に 2」が言えるのは 2 次以下の多項式のときだけ (中心差分がそこまで厳密だから)。一般の正則場では 2 から同じ床の分 だけ引かれる —— 実測 2 − 4.89e-05 に対し正則側の床は 2.06e-04 で同じ桁。 だから「2 に十分近い」ではなく「2 とのずれが床と同じ桁」を門にする。
examples/poc_compound_eye.py
- L271 (ja) — ★実測(2026-10-11): 雑音だけの利得は N=49 で 7.05(√49=7.00)、周縁 8px 除外で 全体利得 7.19、床は外周 4 画素にだけ載り k>=4 で 1e-15 の丸め屑。 → 第 2 章の飽和(5.33)は重ねの原理ではなく縁(像の外から画素を借りる帯)の誤差。
- L402 (ja) — ★PoC の門(tests/test_poc_scripts_run.py)は exit 0 に加えて “PASS” の印字を 要求する(合否を計算したのに捨てる門を防ぐ規約)。以前は “OK:” と書いていて、 台帳に登録した瞬間に「exit 0 だが PASS を印字していない」で落ちた。
examples/poc_connectome_across_decades.py
- L147 (ja) — ★2 匹の平均(半整数)を丸めると偶数丸めで奇数/偶数のギザギザが出る —— 合計(整数)で数える
examples/poc_connectome_motor_bottleneck.py
- L328 (ja) — ★2026-10-06: 人型ロボット / evis のデータが無い環境(CI・初見の人)では系列が合成歩容 1 本だけになり、 折れ線は点 1 個で描けず図が消えて PoC 自身の assert で exit 1 だった(手元は人型ロボットのデータがあって緑)。 系列が 2 本未満なら点で描き、図注は実際に使ったデータを言う。門 = tests/test_poc_connectome_motor_figures.py
examples/poc_crop_phenotyping.py
- L209 — ★Always draw the random numbers up front in the shape (n_plant, NESTED_MAX). If you change how many you draw per leaf count, the random sequence shifts, and increasing n_leaf by just 1 gives a different canopy (2026-09-07: the vegetation coverage stopped being monotonic in leaf count and the cliff could not be measured).
- L525 — ★
grid_coords places the voxel centers (center spacing = span/res, not span/(res-1)). At first I multiplied by span/(res-1) and produced errors of +12 % area and +18 % volume on a sphere —— a unit mix-up “is wrong in a plausible way”.
- L933 (ja) — ★2026-10-06: 題が「当たる」と外れた予想のほうを言っていた(本文は「予想が外れた」)。実測を言う。
- L972 — ★Take both the ground truth and the leaf-angle distribution from the very canopy this section is looking at. Reusing the k of the reference condition (7 leaves) shifts the ground truth by the gradient of upper leaves standing more upright.
- L981 — ★The largest plane is not necessarily the ground (once the canopy closes, part of the crown becomes the largest). The version that took the first plane as the ground answered an elevation of 1.69 m (stepped on this 2026-09-07). It only stabilized once we added the rule to take the lowest plane.
- L1008 — ★Control group: apply the same formula to the true normals (which the buffer holds).
- L1137 — ★The axes of
occupancy_grid are (x, y, z). render_volume_projection collapses axis 0 as the line-of-sight direction, so if you want a nadir view, swap to (z, y, x). Calling it without swapping produces a “nadir view that was meant to be a side view” (a silently-wrong pattern).
examples/poc_ct_fidelity.py
- L342 — ★The headline of this PoC. You can see with your eyes where the FBP crosses zero-point A (the horizontal line) and zero-point B. The x-axis is the number of projections (sparse on the left). The x-axis is log —— the crossing happens on the sparse side (12–45 of them), and on a linear axis it collapses to the left edge, making the crucial part unreadable.
- L407 — ★Closed on 2026-09-06. Previously it pinned down the broken behavior = “doubling the detectors improves the mass deficit by more than 2x”. Now it pins two things: (1) mass is conserved in the first place, (2) it does not change with the number of detectors (since n_detectors is the width of the detector, not the fineness of sampling, so as long as the target fits, the added amount only adds empty bins).
examples/poc_ct_void_morphology.py
- L233 — ★Substituting with die occupancy, at coarse voxels a 50 µm-thick die falls between the voxel centers and the reference itself disappears (at 60 µm, phase 2/3, it actually became 0).
- L558 — ★Passing all-nan (nothing could be measured at any phase) to np.nanmean raises a warning. “Could not be measured” is not something to average, so we make it nan explicitly here.
- L634 — ★Drop the nan (unmeasurable points) before plotting —— the line-plot op rejects non-finite values.
- L808 — ★Fires once the gap is closed. It fired on 2026-09-07 and this section was rewritten —— after the note that “esdf accepts a length-3 voxel_size, yet the side that plots its output was cubic-only”, query_distance (and occupancy_grid) came to accept per-axis res.
- L878 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
- L1097 — ★The volume fraction is preserved even with coarse voxels; what dies first is the shape metric (the side where the prediction was wrong)
examples/poc_datacenter_thermal_field.py
- L221 — ★2026-09-08: This PoC recorded that there was “no entry point to build a field from scattered points”, so
fs.interp_scattered was added. Points that fall outside the convex hull are returned by the op as a mask, so there is no need to guess with isfinite (it does not break even if fill_value is set to a finite value).
- L862 — ★Break the gate to check whether “false peaks 0” is really counting anything.
examples/poc_dem_terrain.py
- L42 — ★Unless the repository root is on the path,
demops is not found (this example does not import fullseye, so the path hook does not kick in).
- L76 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
examples/poc_dense_bubble_count.py
- L748 (ja) — ★最初は「相対 3 % 以内」と書いて、真値 30 個で 1 個ずれた 0.033 で落ちた —— 言いたかったのは 「誤っても 1 個ぶん」なので、個数の差で書き直した(2026-10-18)。真値は画面の外に出た細胞も 数えているので、1 個の差の一部は op でなく真値の規約の側にある(どれかは区別していない)。
- L751 (ja) — ★2 回目: 1 個ぶんでも足りなかった(最大 2 個、600 枚の全数で)。ずれの大きさは印字に残し、 門は「自信をもった誤りの件数」だけにする —— 合わせ直すたびに門を緩めるのは門ではないので、 ここで止める。
- L846 (ja) — ★記録(門ではない): o = 0.4 では「決まらない」と言った塊の区間が真値を外す。いびつな泡が 別の泡に食い込むと、くびれが山を残さず、上限 hi にも数えられない(op の docstring の限界)。
examples/poc_dfm_thickness_overhang.py
- L284 — ★Orientation (front/back) is determined by winding order, but the winding order of marching cubes flips with the sign convention of the input. For a closed mesh it is uniquely determined by the signed volume —— decide it by formula, not by eye.
- L379 — ★Do not align the grid origin to the wall face. Cutting at 3.0 makes the wall face land exactly on the voxel boundary, giving an error of 0.000 mm at all 8 sweep points and producing the false conclusion “no quantization happens” (I once wrote that on 2026-09-07). A real mesher will not align the grid to the part’s faces, so use a non-aligned origin.
- L455 — ★Do not sweep h only at points where “T/h is an integer”. At integer ratios the number of occupied voxels is exactly T/h, so errors of 0.000 mm line up and it looks like “no quantization happens” (I once wrote that on 2026-09-07). Sweep h continuously.
- L705 — ★Do not include the exactly-45-degree tilt direction —— the 2349.7 mm^2 back of the plate also sticks to the threshold, and the table of “which orientation is best” gets hijacked by the story of the step.
- L824 — ★An assert that fires when a hole gets filled. It fired on 2026-09-07 and this line was rewritten —— in response to the observation “there is no per-face area”, face_areas / mesh_volume / boundary_vertices were added. Record that it was filled and move on.
examples/poc_dic_strain.py
- L104 — ★Normalize with a single constant fixed from the reference image. Dividing by each image’s maximum makes the overall brightness change with even a slight shift of the maximum under deformation, adding an unrelated error to estimators (Lucas-Kanade / Horn-Schunck) that assume brightness constancy.
- L211 — ★Pin the finding: since deformation is not interpolation but re-rendering of the speckles, an integer shift should match exactly. If this breaks, the “ground truth” from section 2 onward is no longer ground truth, and it becomes unclear whether we are measuring the estimator or our own interpolator.
- L247 — ★Pin the finding: all three must beat by an order of magnitude the zero point that merely answers “nothing moved”. If even one falls below a factor of 10, that estimator is not usable in this scenario.
- L282 — ★Pin the finding. (1) piv’s bias is smaller than lk / hs across the entire sweep. Note: “one order of magnitude smaller” holds only at the single point u=0.37 in section 2 (0.0002 vs 0.0042 = 21x); comparing the sweep maxima it is about 6x (piv 0.0015 / lk 0.0088). Here we pin the max-to-max comparison conservatively at 2x.
- L365 — ★Pin the finding. (1) lk and piv recover 100 µε to within ±30 µε (measured +9.1 / +0.4).
- L369 — (2) ★hs returns only 22 µε for 100 µε —— the above “the sign and order of magnitude come out” does not apply to hs (the regularization flattens the uniform strain itself). Since the claim disagrees with the measurement, we pin the measurement.
- L413 — ★Pin the finding. (1) A 2-degree rotation, under small-strain theory, produces a lie of around -609 µε as expected (the material has not stretched). That is 30% of steel’s yield strain of 2000 µε.
- L438 — ★It does not dull under a uniform gradient (ε linear in x) —— because the least squares of a symmetric window returns the slope of a linear function exactly. To see the window’s effect, a strain field with curvature is needed. The strain concentration at a notch tip is exactly that, so we build in a Gaussian-shaped concentration.
- L484 — ★Pin the finding. (1) The peak of lk decreases monotonically with window width (the limit of spatial resolution itself).
- L522 — ★Cutting and counting one corner shifts by 2x depending on the window choice. Use the average over all windows.
- L577 — ★Pin the finding: the bias decreases monotonically as the speckles are made thicker. The lk bias seen in section 3 is not a property of the estimator alone; undersampling of the speckle makes up half of it. If this stops being monotonic, one pillar of the “0.01 px” claim collapses.
examples/poc_die_tilt_tsv_overlay.py
- L167 — Grid extent. ★Unless the tail of the erf (±4σ) is included, on a tilted die the outer-ring vias get cut differently at each z, producing a false tilt.
- L241 — ★vol_label via the ledger, unlike the docstring, returns only labels (the n of
(labels, n) is dropped. section 9 (f)).
- L297 — ★Do not subtract MU_SI here. Outside the via the probe passes through air (0), so the raw value is directly proportional to the material’s occupancy. If you subtract and clip, the gently sloping edge collapses to 0, and the length goes 100.0 -> 98.1 µm (-1.9 %).
- L484 — ★Subtract the control group to extract only “the part the tilt added” (canceling the estimator’s systematic error).
- L634 — (f) ★The same op returns different content in its return value depending on the calling path.
examples/poc_dimensional_inspection.py
- L521 — ★Can we trust the rms —— adversarially move just one point outward.
- L1553 — ★On 2026-09-06 the “buried” state was resolved. Previously it was
n_reach == 0 (pinning that it does not reach). Now we pin that it does reach.
examples/poc_document_scan.py
- L271 — ★Applying sobel_dir directly to a binary mask quantizes the gradient direction to 0/90 degrees, and the one-point-one-vote directional Hough collapses onto those two lines (measured: 2 of the 4 lines are exactly 0.00 / 90.00 degrees). Blur first, then measure the direction.
- L389 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_driving_decisions.py
- L247 (ja) — ★2026-10-03 まで縞が x に 10 m 長く y に並んでいた(90° 回っていた、ユーザー指摘)。下の門が向きを確かめる。
examples/poc_driving_endless_map.py
- L329 (ja) — 追従カメラ: 車の 7 m 後ろ・3 m 上から、車の 25 m 先を見る(★頂点がカメラの後ろにある三角形は描かれないので、 カメラを車の真上に置くと足元の地面に穴が開く)
- L337 (ja) — ★描画器は頂点が 1 つでもカメラの後ろにある三角形を捨てるので、足元に穴(空の色)が開く。地平線より下なのに何も 当たらなかった画素だけを地面の色で埋める(第 6 回の env_render と同じ扱い。見た目だけで、門には使わない)
examples/poc_em_second_opinion.py
- L115 (ja) — ★面積で揃える: 仕込んだ融合は「min_area 以上の 2 ラベルの和」なので必ず大きい。負例をそのまま 使うと「大きいラベル = 怪しい」だけで AUC が出てしまう(最初の実測: 弦 0.86 に対し面積だけで 0.87)。 負例は正例と同じ下限(2 × merge_area)以上の成分に限り、基準の「面積だけ」も同じ集合で測る。
examples/poc_emva1288_in_camera_processing.py
- L430 (ja) — ★壁時計でなく CPU 時間で掛ける: スイートが PoC を 6 本並べて走らせると、単独 31 秒が壁時計 115 秒になった(2026-10-13 の全量)。 この PoC が自分で使う計算量を見るのが目的なので、他のプロセスの混み具合で揺れない量にする。
examples/poc_endless_zoom_and_turning_solids.py
- L75 (ja) — 深さの巡回に使う色。★赤と緑は対にしない(意味が見る人で反転するため)
- L303 (ja) — ★主張は整数で置く。埋まった箱の数が 6 ズームとも同じ整数列である ことが「ズームしても同じ集合を見ている」そのもので、整数だから 環境に依らない。
- L310 (ja) — ★次元のほうは最小二乗を通るので機械精度でしか主張しない。
sd == 0.0 と書いていた時期があり、CI で落ちた —— 6 つとも 6 桁まで 同じ値なのに std != 0 で、degrade の記録も 0 件だった。同じ整数列を 渡しても BLAS の並列化で lstsq の最下位ビットが揺れる。 それは「ズームで次元が動く」ことではない。
- L412 (ja) — ★ここで最初の予言を外した。「2 パーセントの床は marching cubes の面取りの せい」と読んだが、距離を伸ばすと厳密な立方体も同じところまで落ちた —— 床の正体は透視投影だった。面取りのぶんは別の量(最大/最小の比)に出る。
- L630 (ja) — ★op が静かに degrade していないか。
fs.op.* は backend_safe.guard 越しで、 例外が出ても「sort 妥当な別の値」を返す —— 厳密な等式の検査だけが落ちて、 原因が症状から離れる。degrade していたらここで名指しする。
- L645 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/poc_eye_to_brain.py
- L60 (ja) — ★背側から見るだけだと、像の左右(方位角)は soma の y 軸 = 奥行きに写り、応答の移動が見えない (2026-09-20 に実測: 縞を動かしても同じ場所が光って見えた)。背側と側面の 2 方向を並べる。
- L139 (ja) — ★2 値の縞では 1 ビットでも相関 0.99 で量子化の効き目が測れない(実測)。背景 0.5 に +0.3 の 滑らかな縞(σ = 6 px)= 低コントラストの像で、ビット数が信号を潰す条件にする。
- L162 (ja) — ★実測(2026-09-20): 効いているのはビット数ではなく「背景を引く」適応。背景 0.5 の像を適応なしで入れると 全柱が刺激され重心が動かない(実データで 0.63)。適応した連続値と 8 ビットは同じ(0.99)。
examples/poc_fabric_defect.py
- L83 — ★The mask areas are deliberately kept comparable. The combined AUC is close to an average weighted by the number of positive pixels, so if one were an order of magnitude larger, “combining hides it” would not occur.
- L119 — ★The mask radius is set individually as a multiple of σ —— to equalize the areas. If the areas differ by an order of magnitude, “the combined AUC becomes the AUC of the larger area”, and what this PoC wants to measure, “combining hides it”, gets swapped for the different story “the larger area wins”.
examples/poc_fiber_orientation.py
- L376 — Section 2. ★★The naive average breaks with a 180-degree period # ————————————————————————— #
- L469 — Section 4. ★★Without choosing weights, the orientation degree always comes out small # ————————————————————————— #
- L499 — ★Because angle is a periodic quantity, coloring it with colorize_depth makes 0 degrees and 179 degrees opposite colors. fullseye has no name for a cyclic LUT, but passing (cos2θ, sin2θ) to colorize_flow gives a double-angle cyclic LUT (see “tool gaps” (f) at the end).
- L693 — ★The name “coherence” exists, but it is the two-signal coherence of signal processing (a different thing).
- L724 — (e) ★Two members of the same family disagree in their input checks.
examples/poc_fly_optomotor_steering.py
- L503 (ja) — ★2026-10-06: 6 系列に配色の役が 5 つしかなく、motor right が HS left と同じ色だった。 層ごとに 1 色、左 = 実線・右 = 破線にする。
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
- L176 (ja) — 絞り。★2026-10-14: defocus_blur のぼけが 2 倍広かった(σ = 錯乱円の直径/2、正しくは /4)のを直したら、F 5.6 では 被写界深度が 2 倍深くなり、0.42 mm 間隔の像で奥行きが区別できなくなった(テクスチャ有の RMS 0.47 → 0.91 mm)。 旧版の結果は「F 5.6 と書いて実質 F 2.8 のぼけ」の上に立っていた —— 書いた値と効いていた値を揃えて F 2.8 にする。
- L601 — 1. The picture works. ★The threshold is +3 dB — real semiconductor images are mostly smooth metal (die, leads), which is already in focus in a single frame, so the AIF gain is smaller than with a synthetic pattern that is high-frequency everywhere (the honest picture of the shop floor; the old full-texture field gave +14 dB).
examples/poc_forensics_roc.py
- L396 — ★Gap (a) is a “constant map”, so drawing it makes reading the numbers unnecessary.
- L523 — ★The headline of this PoC. The curve of the strongest detector drops to the diagonal (and below) with a single press of the save button.
- L677 — (4) ★Gap (a): the op’s argmin readout is essentially a constant map for a re-saved image. AUC is exactly 0.5 = indistinguishable from random.
- L704 — (9) ★Gap (b): 8-pixel grid. It only guesses right when the difference is a multiple of 8 (no re-saving).
- L52 (ja) — 色。★赤と緑は対にしない
- L355 (ja) — ★変数名は章ごとに分ける(あとの章の best に上書きされて、図の説明が 別の章の数字を出していた)
- L370 (ja) — ★図が主題を映しているか。x, y だけで描くと zw 面の回転が消える。 実際にそれで 2 つの GIF がバイト単位で同一になっていた。
- L403 (ja) — ★marching-cubes 系と同じく巻きが内向きなので絶対値を取る
- L425 (ja) — ★B との差が「断面の角数に依らない」= 2 つの誤差が独立に分かれている証拠
- L559 (ja) — ★x, y だけを描くと zw 面の回転が消える。一般の向きで見る。
- L651 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/poc_fourier_ptychography.py
- L239 (ja) — ★明視野と暗視野の境に LED が乗る構成(ピッチ 7 mm・距離 70 mm、照明 NA 0.0995)は外し、境の章で別に見せる
- L390 (ja) — ★高さだけの線(振幅は一様)では、full(384 画素)で 2 本の初期値が 0.098 違って拒否された(差は照明 NA 0.2〜0.3 の 帯に集まる。暗視野の露光を 4 倍にしても 0.092)。散乱の弱い物体の高い周波数は、k の丸めの模型の誤差に埋もれる。
- L581 (ja) — ★実データでは瞳を画素ごとに自由に推定する(pupil_degree=None)。2〜4 次の多項式に射影すると残差が 2.3 倍 (0.0143 対 0.0061)になり、G7 の大きな要素でも変調が 0.4 に落ちる —— 実機の瞳は振幅にも構造がある(推測)。
examples/poc_gear_tooth_metrology.py
- L199 — Imaging-system blur. ★The 2-D Gaussian blur has no entry point to pass σ directly, so we back-compute σ = 0.3 + 2.7 a from the evolution op’s knob a and pass that (see “tool gaps” (c) at the end).
examples/poc_geodetic_height_frames.py
- L411 — ★A round trip cannot rule out “both wrong in the same direction”. Cross-check against an independent implementation.
-
| L440 — ★Prediction (printed before measuring): the slope is atan |
∇H |
. Using h it becomes atan |
∇H+∇N |
. |
- L467 — ★Split the max difference between prediction and measurement into ‘model error’ vs ‘discretisation’. Refine the cells.
-
| L587 — ★Prediction (closed form): the downhill direction turns by more than 90 degrees ⇔ ∇H·(∇H+∇N) < 0 ⇔ |
∇H |
^2 + ∇H·∇N < 0. Compute the rate before measuring. |
-
| L647 — ★The second (and the real) closed form. Since the line of sight is drawn through h at both ends, the linear part of N rides equally on both the line of sight and the ground and cancels. What remains is the amount N departs from the chord = |
N’’ |
d^2 / 8. Here N’’ is 2C(cos^2θ - sin^2θ), so |
N’’ |
<= 2C. |
- L1120 (ja) — §10 穴。★2026-09-08 にこの節は「geoid / enu / datum は 0 件」を門にした。 2026-09-22 にその門が鳴った(埋まったから)—— 門を消さずに、まだ空いている 語幹へ付け替える。閉じた側は「何が閉じたか」を名前で固定する。
- L1124 (ja) — ★2026-10-15: material_xray_attenuation(X 線の減衰)の “att-enu-ation” が語幹 enu に当たる。 測地の ENU ではなく単語の一部 —— 同じ文字列の別の意味として名前で固定する。
- L1126 (ja) — ★2026-10-19: water_attenuation(水の減衰)も同じ。
- L1128 (ja) — ★2026-10-05: granular の datum_tilt_check(粉体の山の基準面の傾きの警報)が語幹 datum に当たる。 測地成果ではなく「高さ図の基準面」の意味 —— 同じ語の別の意味として名前で固定する。
- L1138 (ja) — ★
ortho は逆向きの教訓: op 名に ortho を含むものは 0 件のままだが、 能力は dem_height_frame_convert(frm/to に “orthometric”)で在る。 件数で「在る」と言ってはいけないのと同じくらい、名前で「無い」と言ってもいけない。
- L1141 (ja) — ★2026-10-15: 語幹 “ortho” は名前で実験計画の直交表の op(orthogonal、別の語)に 当たるようになった。門が問うているのは「標高(orthometric)の op」なので、検索語を正確にする。 あわせて検索側の穴も塞いだ: 欧文のクエリは 1 行目の doc までしか見ておらず、”orthometric” は dem_height_frame_convert の引数の説明にしか無いので 0 件だった(opassist.find に docstring 全文の段)。
- L1152 — ★For
vertical op_find returns a count, yet not one of the hits is relevant (stem matches like boundary_vertices) —— never claim it ‘exists’ from the count.
examples/poc_glyph_typo_detection.py
- L40 (ja) — 壊す位置(行, 列)。★真値はここで決まる。
- L158 (ja) — ★統計は画像の全マスをまとめて取る —— 閾値をその形で導いたから。 行ごとに取ると、4 字の行では四分位が粗すぎて 0.48〜0.59 に跳ね、 正しい版面を自分で断ってしまう(実測)。導出と適用で統計を変えない。
- L210 (ja) — ★マスを少し広げて切り出し、その中で「このマスに属する成分」 だけをマスクにする。隣の字がマスの縁からはみ出していると、 マスちょうどで切ったときにその分が消し残り、置換後に 旧字の切れ端が浮いて見える(実測)。
- L287 (ja) — ★床は「同じ字なのに絵が違う」量。書体が 2 本以上あるならその散らばりで測るのが 実態に近いが、素の Linux には CJK が 1 本しか入らないことがある (実測: CI は fonts-noto-cjk だけで、この PoC が丸ごと skip して落ちた)。 1 本しか無いときは、ぼけ・線幅・わずかな回転・再標本化という既知の妨害で 同じ字を揺らして床を作る。測っているものが違うので、名前も表示も分ける。
- L355 (ja) — ★合成に対する主張を固定する(真値は自分で植えたので厳密に測れる)。 ここが割れたら、穴が塞がったか本当に壊れたかのどちらかで、 assert を消して通すのはどちらでもない。
- L364 (ja) — ★環境に依存する量を assert しない。 床は「その環境に入っている書体の 散らばり」から作るので、どの書体が入っているかで動く —— 実測 2026-09-17: 手元(Meiryo / 游ゴシック / MS ゴシック)は 0.0581、CI(Noto 系 3 本)は 0.0462。本数は同じ 3 本で、違うのは中身(CI の 3 本は互いに似ていて 距離の中央が 0.0250 対 0.0437)。この差で
電 1 字(距離 0.053)が CI でだけ床を超え、fp == 0 が手元で緑・CI で赤になった。 固定すべきなのは順序である —— 壊れた字の最小距離が、無事な字の最大距離を 上回ること。これは閾値の置き方と無関係に手法の良し悪しを測る(CI の実測: 無事な字の最大 0.053 < 壊れた字の最小 0.069 で、両環境とも完全に分離)。 その上で「床がその隙間に落ちたか」は環境の性質として報告する。
- L375 (ja) — ★これは note 080 で退けた「順位で判定する」とは別物 —— 判定は今も床で行い、 ここで固定するのは分離しているという性質だけ。
- L403 (ja) — ★書体 1 本の環境では主張を弱める。妨害から作った床は書体の散らばりより 狭く(実測 0.0258 対 0.0581)、撮り方の違いだけで無事な字まで超えてしまう (実測 7 本中 5 本)。この環境では言えないことを言わないのが正しく、 閾値を緩めて通すのは測定を捨てるのと同じ。CI には CJK を 2 本入れてある。
examples/poc_good_sample_variation_model.py
- L286 (ja) — ★地の模様が弱いと、汚れた 3 枚の傷が位相相関の山を引っ張り、0.65 px の「ずれ」として拒否された (実測。拒否は正しい振る舞い —— 汚れた良品は位置合わせも汚す)。ここは帯の比較なので模様を強くする。
examples/poc_granular_heap_repose.py
- L357 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
- L408 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_graph_hierarchy_segmentation.py
- L369 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_grating_interferometry.py
- L323 (ja) — ★正直な限界: 段差の縁の 1 画素だけが π を超える板(平らな背景の隣)は、折り返しが見えずに通る
examples/poc_gravitational_lens_invariants.py
- L77 (ja) — 色。★赤と緑は対にしない
-
| L129 (ja) — ★縁の幅は像面の画素で測る。光源面の距離をそのまま使うと、倍率の 大きいところで縁が細く見え、面積が系統的にずれる(実測 2.1% → 0.2%)。 d は光源面の量なので、像面での変化率 |
∇d |
で割って像面の単位に直す。 |
- L242 (ja) — ★はじめ「暗い像が小さくなる u = 1.5 がいちばん苦しい」と読んで外した。 実測ではどの解像度でも u = 0.3(焦線に近い側)が最悪で、u = 1.5 の 暗い像は n=3201 でも 209 画素ある。苦しいのは「像が小さい」ほうではなく 「像が引き伸ばされて細い弧になる」ほうだった。
- L531 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/poc_hyperspectral_foreign_matter.py
- L105 (ja) — 見た目の色(線形 RGB の反射率)。★同じ色にしたのは設計(この PoC の問いそのもの: 色を合わせた異物)。 皮つきアーモンドの茶色に、殻・木片・茶色に着色した樹脂片を ±3 % で合わせた。黒い樹脂だけは黒い。
- L418 (ja) — ★実データの破片は暗い(反射率の中央値 0.07)ので、生の反射率の SAM は足し算のベースラインに負ける(下で数える)。 連続体除去(
spec_continuum_removal、上側の凸包で割る)の帯の深さ 1 − R/包絡 を特徴にする。
- L466 (ja) — ★外の真値の検査 1: 別の撮影の基準試料(Training/PP・PE・PET の 11x11)をライブラリにして、試験の場面の PP / PET / PE を分ける
- L482 (ja) — ★外の真値の検査 2: この PoC の材料表の物理(吸収帯 + Kubelka–Munk)をライブラリにする
- L944 (ja) — 幾何平均(間が空いていれば余裕の真ん中)。★初版は q_k だけで決め、試験のトレイで粒径・含水率の端の仁を 丸ごと排出した(画素の分位点は仁の「個体」のばらつきを数えていない、2026-10-15 に図で見つけた)。
- L1038 (ja) — ★クラスごとに同じ画素数で選ぶ: Fisher の Sb = Σ n_k (μ_k − μ)² は画素の多いクラス(ベルト・仁)に 引っ張られ、少ない樹脂片どうし(PE と PP)を分ける帯域を選ばなくなる(2026-10-15 の初回で実測)。
- L1050 (ja) — ★log 反射率で選ぶ: 画素ごとの明るさ(陰影)は全帯に共通の足し算になり、多変量の J はその方向を クラス内のばらつきとして割り引く(1 帯域だけでは明るさと材質を分けられない —— k = 1 が弱いのはそのため)
examples/poc_illusions_and_perpetual_drawing.py
- L60 (ja) — ★ここは以前「錯視の図で測る側を採点する」章だった。だが並んでいた検査は 自分で置いた定数を読み返すだけで、間に変換が 1 つも無かった —— 厳密に水平に引いた目地が水平だ、平坦に塗ったマスが平坦だ、同値に置いた 2 パッチが同値だ。錯視は人間の知覚の性質なので、測る側が騙される理由が そもそも無い。同義反復なので落とした(2026-09-24、指摘を受けて)。 残したのは 1 件だけ —— 素朴な長さ計測が実際に外すこと。これは 知覚ではなくアルゴリズムの偏りの話なので、中身がある。
- L95 (ja) — ★外した予言 —— 「矢羽根が長いほど偏りも大きい」と読んだが違った。
- L103 (ja) — ★錯視の絵(カフェウォール・チェッカー・カニッツァ・フレーザー・ エビングハウス)は直線と矩形を引いているだけで、この箱の力を 何も示していない。2026-09-24 の指摘を受けて主図から降ろした。 残すのは、測る側の偏りが見える 1 枚だけ。
- L144 (ja) — ★閉形式で厳密に出るものと、再帰で誤差が積もるものを同じ物差しで見ない。
- L167 (ja) — ★最初は「104 歩で 52 マス = 0.5 /歩」と書いたが、実測 0.114 と合わなかった。 測り直すと正味の増加は 104 歩あたりちょうど 12 マス(整数)。周期の 中で塗っては消すので、正味はずっと少ない。推測でなく実測が正しかった。
examples/poc_interferometry_step.py
- L401 — 3) ★Repeated measurement — separate bias from spread # —————————————————————— #
- L444 — 4) ★Comparison with the zero point (the max sample of the envelope) # —————————————————————— #
- L516 — 6) ★Noise sweep — where measurement breaks down # —————————————————————— #
- L556 — ★A small spread is no evidence of correctness
examples/poc_interreflection_fringe_error.py
- L289 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
- L292 (ja) — ★この PoC だけは CPU 時間が壁時計を大きく上回る(手元 24 スレッドで CPU 10〜13 秒・壁時計 0.6〜0.7 秒、 OMP/OPENBLAS/MKL_NUM_THREADS=1 では CPU・壁時計とも 0.1 秒未満)。計算そのものは小さく、差は BLAS の スレッドの空回り(待ちの spin)で、コア数に比例して増える。60 秒の上限は手元の 4.7 倍で、CI の走者(4 コア) では空回りがさらに小さいので据え置く。上限に近づいたら、計算が増えたのか空回りかをスレッド 1 で切り分ける。
examples/poc_itof_multifreq.py
- L341 (ja) — ★2026-10-18: residue_crt の錨を Wang–Xia 2010(IV-A 節)どおりに直した後は、最尤の復号と同等になる。 修正前(最も長い周期 = 16 MHz を常に錨にした)は 0.556 / 0.407 と大きく誤っていた。差の許容は 最尤の 10 % + 標本 5 個(誤りの少ない条件で数個の入れ替わりを許す)。
examples/poc_kendama.py
- L112 (ja) — ★CI(2 コア、PoC を並列に走らせる)では full の設定が 600 秒の枠を超えて -1(timeout)になった(2026-09-30、run 36657843727、 手元 160 s)。FULLSEYE_POC_BUDGET=reduced(CI では既定)で、大皿の 20 試行(予測誤差の曲線と主要な門)はそのままに、小皿・中皿・ 画素雑音・推奨品の試行を 10 に、画素雑音の段を 0 / 2 / 8 / 16 px に、3DGS の試行・コマ・間隔の段を減らす。門の閾値は変えない (測った段だけで判定)。展示の数字は full の実測で、reduced は「同じ経路が走る」ことの証拠に留める(先頭に BUDGET: を印字)。
examples/poc_knife_tactile_toughness.py
- L483 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_larval_connectome_reservoir.py
- L43 (ja) — ★CI(2 コア)では full の設定が 600 秒の枠を超えて -1(timeout)になった(2026-09-20、run 35501201432)。 FULLSEYE_POC_BUDGET=reduced(CI では既定)で標本・格子・seed を減らす。展示の数字は full の実測で、 reduced は「同じ経路が走る」ことの証拠に留める(先頭に BUDGET: を印字)。
- L207 (ja) — 5. 図(FULLSEYE_FIGURE_DIR があるときだけ)。★2,952² の隣接行列をそのまま描くと 1.3 % の点で一色になり、 Fiedler 配置は重い裾の次数分布で 1 点に潰れる(2026-09-20 に実際にそうなった)。升に集約し、対照と並べる。
examples/poc_laser_line_speckle_floor.py
- L349 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_leak_localization.py
- L591 — ★Test of prediction C —— vary the leak position finely to scatter the fractional part
- L726 — ★Control group —— swap only the reflections left/right. If the direction of the bias reverses, we can say the cause is ‘the farther joint determines the direction of the bias’.
examples/poc_lens_tolerancing.py
- L165 (ja) — ★2026-10-21: 棒の縦軸は 0 から(自動範囲は最小値の少し下から始まり、差を 10 倍に見せていた)。
examples/poc_lidar_terrain_change.py
- L425 — ★The area of cores that could not be measured contributes nothing to the earth volume. Also return the value divided back by the effective rate —— without dividing back, you take the ‘silently missing earth volume’ for the correct value.
- L713 — ★A number close to the true value is not necessarily ‘correct’ —— count the two opposing errors separately
- L842 — ★When there are too few valid cores, do not treat the LoD as ‘measured’ (the standard deviation of 2 points is a number but carries no meaning).
- L845 — ★If you decimate here, C2C ends up measuring the ‘post-decimation point spacing’ and the density dependence vanishes (when I first wrote it aligned to 6000 points, it came out a constant 0.42 m at every density).
- L965 — — ★ Change vanishes exactly by the amount you align away ————————————– #
- L1329 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
examples/poc_lightfield_depth.py
- L707 — 2b. ★ Gap (d): the docstring says 0-d but it is actually (1,)
- L723 — 6. ★ Gap (a): the default linear pulls 1.15 toward 1.0, cubic does not
- L747 — 10. ★ Gap (e) was closed on 2026-09-06. It has been rewritten toward pinning the closed state (previously it asserted that ‘a warning is raised’).
examples/poc_livestock_body_volume.py
- L1187 — ★3 cameras and 6 cameras give exactly the same set of tangents (in parallel projection two opposing cameras coincide)
- L1195 — ★An odd 13 cameras beat an even 16
- L1209 — ★A 3-D convex hull is no substitute for the ‘convex hull of the cross-section’ (it misses the chest girth by a wide margin)
- L1212 — ★Doubling law: the chest-girth error doubles with body weight (the residual is a 2nd-order term)
examples/poc_machine_condition_fusion.py
- L184 — Heat generation [W] of (coupling, bearing A, bearing B, whole machine). ★Normal, unbalance and looseness are made deliberately identical —— 3 modes that are fundamentally indistinguishable by heat.
- L202 — ★As hot as the bearings. The only difference is the spread (both bearings + whole machine).
- L1028 — ★2026-09-08: here we had hand-written numpy’s rfft —— because we read it as ‘no entry for a one-sided amplitude spectrum in the ledger’, but
fs.spectrum was there all along (it just did not show in the ledger). This is a case of deciding ‘it does not exist’ after looking at only one tier, so rewrite it to use the op.
- L1162 — ★2026-09-08: here we had written ‘no spectrum in the ledger’, but
fs.spectrum was there from the start (dsp’s 1-D tier). What was missing was only ‘showing in the ledger (fs.ledger)’ and ‘the per-op notes’; this PoC pulled from only one tier, decided ‘it does not exist’, and hand-wrote numpy’s rfft. Now that ops1d is wired into the ledger, both can be looked up.
examples/poc_malecns_activity_wave.py
- L241 (ja) — ★同じ瞬間を 3 方向から(2026-09-20、ユーザー「いくつかの方向から発火状態を見れると良い」): 上段コネクトーム、下段 shuffle
examples/poc_material_optical_library.py
- L111 (ja) — ★2026-10-15: 水の k を Hale & Querry 1973 から Segelstein 1981 に差し替えた(RII の Hale の表は NIR を 0.2 µm おきにしか持たず、1.45 / 1.94 µm の吸収帯を線形補間で 1/3 に潰していた。n は滑らかなので Hale のまま)。 1500 nm の k は optiland 0.6.3 の MaterialFile で Segelstein.yml を評価し直した値(2.2392e-4)。
- L195 (ja) — ★2026-10-15: 以前は k の相対差に 1e-6 を掛けて n の門に混ぜていたので、k が ±100 % ずれても通った。 写した k は有効数字 5 桁(1.4361e-07 など)なので、丸めの幅は相対 5e-5。optiland が k を持たない点(0)では こちらも 1e-8 未満(水の 500 nm は Segelstein の 9e-10、吸収の無い区間)。
examples/poc_measurement_system_analysis.py
- L155 (ja) — ★★看板は一目で読めるものにする。濃淡の地図は情報としては正しいが 読者には「色のついた雑音」で、何の図か分からない。ゲージ R&R の古典的な 見せ方 —— 部品ごとに測定値を縦に並べる —— なら、10 個の塊が縦に離れて いるのが部品差、各塊の太さが測る行為のばらつき、と目で読める。
- L211 (ja) — ★「全部内側のはず」と書いたら 1 升はみ出した。実データのほうが正しい —— 規格の例題はわざと 1 点だけ管理外にしてある(範囲図の読み方を示すため)。
- L466 (ja) — ★2 点を結んだ直線では「7.3 % 違う」としか言えない。交互作用の強さを 掃引すると、いつモデル選択が効いていつ効かないのかが曲線で見える。
- L661 (ja) — ★★規格の「t 表を引く直前に切り捨てる」は、滑らかな t(ν) に対する階段。 実装が踏んだ欠陥(切り捨てずに引いた)が、そのまま曲線と階段の差になる。
- L684 (ja) — ★3 点の散布では「向きが逆」が読み取れない。相関係数を掃引すると、 2 本の曲線が無相関の水平線を反対側で横切るのが見える。
- L756 (ja) — ★★その 150 は乱数ではなく閉形式で出る: X1²+X2² は u²χ²₂ = 平均 2u² の 指数分布なので、上側 95 % 点は 2u² ln 20。公表値と小数 1 桁まで合う。
- L771 (ja) — ★★閉形式が絵になる場所。x1 = x2 = 0 では X1^2 + X2^2 は u^2 chi^2_2、 すなわち平均 2u^2 の指数分布。95 % 点は 2 u^2 ln 20 で閉形式。
- L837 (ja) — ★★半幅を 3 本の水平線で並べても「なぜ違うのか」は見えない。密度を 重ねると、正規近似の裾が実際より厚いことが絵で分かる。
- L849 (ja) — ★区間は水平の線分で描く(plot_series は非有限を拒むので 「NaN で区切って 2 本の縦線」は使えない。読みやすくもある)
- L912 (ja) — ★窓は3 段階すべてが入るように取る。伝播則の下端が 0 を超えるのは x1 > 2 k u = 0.0196 なので、そこまで届かない窓だと「追いつく」が見えない。
- L922 (ja) — ★各コマで最大値に正規化する。絶対密度のままだと、指数(原点で 2e4)と 後半の正規(1.6e3)で 1 桁違い、後半が平らに潰れて形の変化が見えない。
examples/poc_mesh_quality_repair.py
- L602 — ★Show it saturated. The raw difference is at most %.2f mm, and painting it as-is makes 99 %% of the pixels 0, a pitch-black ‘it ran but nothing shows’ figure.
- L816 — ★Plot log-log. On linear axes the error collapses to a single point on the coarse side, giving a figure where the slope (= error law) cannot be read at all (I once plotted it that way on 2026-09-07).
- L832 — ★Overlaying the cumulative distributions as-is crushes all 4 above 0.9 and nothing is readable. What moves is the upper tail, so put quantiles 0.5–0.99 on the x-axis and plot ‘the curvature at that quantile’ on the y-axis (the upper half of the inverse cumulative).
- L568 — ★The measurement is slower than that. The fraction of grain-boundary pixels actually erased on the mask, f_eff, is smaller than f (the blur leaks the neighbouring black into the 1 px at both ends of the gap, and the local threshold picks it up), so compare against the prediction re-derived with f_eff, ΔG0 + 6.64 log10(1-f_eff).
examples/poc_moire_screen.py
- L586 (ja) — ★2026-09-23: 語の網を (“notch”, “destripe”, “mura”) に狭めた。npr 族が入って ‘moire’ と ‘periodic’ が引っかかるようになったが、
halftone_moire_period は うなりの周期を予言する op であって落とす op ではない —— 穴は残っている。 「語で引く穴の固定」は、別の意味で同じ語を使う族が来た瞬間に偽陽性になる (この PoC は (a) で fly_hex_lattice の例を既に書いている)。穴の主張は 語でなく「何ができないか」で書くこと: ここで無いのは「特定の (fx, fy) を 落とす」op であって、「モアレという語を含む op」ではない。
- L636 (ja) — ★2026-09-23: “moire” はここから外した —— この PoC が「族の名前か docstring に入れておけ」と書いた提案がそのまま実装され、
halftone_moire_period が 引けるようになったため。穴の記録は埋まったら埋まったと書く(消さない): 消すと「昔から在った」ことになり、何が効いたのかが記録から落ちる。
- L640 (ja) — ★元の判定は「名前にその語を持つ op が返らないこと」(docstring 一致は数えない)。
op_find は docstring も語幹も拾うので、素の == [] にすると edge_alias_energy のような無関係の族で必ず鳴る(一度そう書いて落ちた)。
- L646 (ja) — ★2026-10-13:
lattice_moire_peak(flyvision、標本化格子がナイキストを超えた模様から作る モアレの尖り = ピーク/背景中央値)も引けるようになった。網点の 2 版のうなりとは別の モアレ(格子×周期面)で、ディスプレイ・メッシュ・織物の検査カメラ側の語。
- L649 (ja) — ★2026-10-15: 位置合わせのモアレ 8 op(moirealign、
moire_*)が加わった —— ピッチの僅かに違う 2 枚の格子の 縞の位相から nm のずれを読む側で、網点のうなり(画質の欠陥)とは逆にモアレを測りに使う語。
- L651 (ja) — ★2026-10-15: op_find に docstring 全文の段(最低点 12)が加わり、本文で「モアレ」に触れるだけの op (fly_vogel_lattice・halftone_screen・sampling_alias_distance)も並ぶ。名乗る op だけを数える。
examples/poc_multibeam_bathymetry.py
- L359 (ja) — ★走時を使い切った光線は cosθ が層の途中の値のまま残り、後ろの層で dt_full が 負になりうる。負の dt は rem を「生き返らせ」光線を進めてしまう(実データの 152 節点のキャストで 57 度・0.13 s が 110 m → 493 m になった)ので 0 で止める。
- L544 — The number of partial angles that synthesise the echo. ★Setting this to 61 makes, at 70 degrees, the arrival times of adjacent partial angles 330 µs apart, wider than the 64 µs pulse width, so the envelope becomes a comb and amplitude detection picks up one tooth (the detection offset came out as -1131 µs). It is more correct to build a histogram of the arrival-time density and convolve it with the pulse.
- L572 — ★Do not clip the lower bound at 0 —— the nadir beam then becomes one-sided and the illuminated band halves (stepped on this once, with the footprint coming out at half).
- L729 — ★Divide the x-axis by the beam’s own echo length. Overlaying in raw µs lets 70 degrees (21 ms) monopolise the axis, collapsing nadir and 45 degrees into a single vertical line.
- L732 — ★
plot_series rejects points outside xlim (because they stick to the frame and look like real data). Clipping is the caller’s job, so clip first.
- L1151 — ★Do not look at the middle of the overlap —— there both survey lines have the same swing angle, so the same error rides on both and the difference goes to zero. Take the maximum over the whole band.
- L1222 — ★Make the y-axis height (= −depth). Plotting depth as-is flips top and bottom, making a ‘smiling’ shape look like a ‘frown’.
- L1293 — ★The y-axis is −depth. Plotting depth as-is gives an upside-down figure with the sea surface at the bottom and the seabed at the top.
- L1327 — ★
op_find matches on partial stems, so even when the count is non-zero the contents can be irrelevant (“footprint” → sk_median_disk). Look all the way to the top-level name before saying ‘it does not exist’.
- L1383 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
- L1974 (ja) — ★左右に分ける: 音速の取り違えは θ について偶(左右対称)。ロールの小さな 取付偏りや参照格子の左右の食い違いは奇(D tanθ δ)。中心対称な階級なので k と n−1−k が鏡像。偶部で崖を測り、奇部は両解で同じか(= 音速でない)を見る。
- L2231 — ★The cliff of the all-paths case is earlier than predicted. The difference is the bias of amplitude detection (a quantity absent from the closed form)
examples/poc_nuclei_ploidy.py
- L686 — ★There really exist rows where two opposing failures cancel and masquerade as ‘exactly the true value’
examples/poc_one_stroke_epicycles.py
- L209 (ja) — ★線画なので灰色のまま出す。(H,W) を渡すと save_gif が疑似カラーに 塗って黄緑の絵になる(実測)—— 強度そのものを見せる図では色は邪魔。
- L246 (ja) — ★env は examplefig が 呼ばれるたびに読むので、ここで入れれば効く (import 時に固定されていたら –out が黙って無視される、の回避)。
- L267 (ja) — ★2026-10-06: 図の見出しが「photograph (NASA AS11-45-6709)」のまま北斎を描いていた(前の題材の名残)。 出典は入力から決める(–image で自分の写真を渡したときに北斎と名乗らない)。
- L418 (ja) — ★この絵では既定のペン幅 1.0 px がたまたまほぼ当たっており(偏り -0.0031)、 解いた幅 0.900 px のほうが偏りは大きい(-0.0294)。閉形式が当てるのは 偏りではなくインク率なので、門はそちらに置く —— 偏りで門を作ると 「元から合っていた絵」で落ちる(実測でそうなった)。
- L422 (ja) — ★偏りで門を作ると「元から合っていた絵」で落ちる(この絵では既定 1.0 px の 偏りが -0.0031 と既にほぼ 0 で、解いた 0.903 px のほうが偏りは大きい)。 閉形式が当てるのはインク率で、線が重なるぶん実測は必ず下回る —— 門はその向きと大きさに置く。
- L457 (ja) — ★ナイキストを満たしているかを先に測る。等弧長の打ち直しは、標本間隔が 線分より粗いと角を切って線そのものが短くなる —— フーリエに載せる前の 段階で情報が落ちるので、ここを見ないと「予言が当たった」の土台が崩れる。
- L523 (ja) — ★図を出さない設定のときは組む前にやめる(examplefig.enabled はそのためにある)。 72 コマを描いてから捨てていたので、この PoC だけで 322 秒かかっていた —— スイートは FULLSEYE_FIGURES=off で全 PoC を並列に走らせ、1 本 600 秒・ 全体 5400 秒の上限があるので、共有ランナーで timeout に落ちる(CI py3.12)。 数値の門はフレームに依らないので、ここを飛ばしても採点は 1 つも減らない。
examples/poc_pallet_load_utilization.py
- L232 — ★Deck points float up to +3σ from noise, so cut them with a floor threshold. Without it, even a load with zero overhang gets a spurious 0.006 m3 of “overhang”.
- L479 — ★When g = w exactly, it comes down to “whether the grid happens to line up”.
examples/poc_panorama_drift.py
- L112 — ★Gap (a): none of the following 4 appear in the fs facade or in fs.op
examples/poc_particle_sizing.py
- L213 — ★With only a single seed, the ups and downs of this curve become just noise. Use 4 seeds to separate the mean from the spread before saying it “crossed over”.
- L428 — ★Control group —— match only blobs that are neither merged nor split, one-to-one against the very particle that blob images. If the ground-truth side is all particles, the selection bias that “bigger particles merge more easily” creeps in and becomes indistinguishable from sampling bias (I first wrote it that way and got it wrong).
examples/poc_particle_tracking.py
- L702 — ★The return is not a mask but (N, 3) (z, y, x) coordinates (the 2-D
local_max / sk_local_maxima return an image, so the family is inconsistent. Section 10 gap (g)). At first I counted with count_nonzero and got the order of magnitude wrong.
- L777 — ★To fit 3.4× up and 0.93× down on one plot, the vertical axis is the log10 ratio. 0 is “exactly the ground truth”. Kept linear, downward deviations get crushed and become invisible.
- L792 — ★Overlaying the raw MSD, the 4Dτ line dominates everything and the differences are invisible. Taking the ratio divided by the ground truth, the departure from 1.0 (= how it breaks) can be read from the shape.
examples/poc_periodic_video_boundary.py
- L137 (ja) — 第 2 章 ★空の出力は、等変性の門を素通りする # ————————————————————————— #
- L267 (ja) — 第 4 章 ★汚れるフレームは集合として閉形式で予言できる # ————————————————————————— #
- L296 (ja) — ★汚れが先頭側だけで末尾側に無いこと = 窓が後方(因果的)である証拠
- L457 (ja) — ★この 1 行が要る。門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見ており、落とすと exit -2(門が付ける合成コード、 意味は「exit 0 だが PASS を印字していない」)で赤になる。
examples/poc_phase_measuring_deflectometry.py
- L496 (ja) — ★2026-10-15: 手元 23 秒の計算が、CI の並列のシャード(py3.12 3/4)では壁時計 120.6 秒になり、この門だけが赤に なった。壁時計は同じ機械で走る他のテストの負荷を数えてしまう。この門が抑えたいのは「この PoC 自身の計算量」 なので、プロセスの CPU 時間で測る(壁時計は併記する。テスト側の 600 秒の打ち切りは別にある)。
examples/poc_photoelasticity.py
- L160 — ★Pin the finding: this is an exact cross-check against fullseye’s Mueller op, agreeing to machine precision even sweeping δ once around in 15-degree steps and θ over 5 values (measured 2.2e-16). If this loosens, what Section 3 onward measures is not the “readout procedure” but a bug in the op.
- L181 — ★Pin the cross-check of the stress field itself too. If the integrated force does not match the load it is not the “ground truth”, and the central value should be algebraically identical to the closed form 8P/(πDh).
- L207 — ★Pin the level of the zero point. Every subsequent “N×” uses this 1.09 MPa as the denominator, so if it moves the meaning of the comparison changes.
- L231 — ★Pin the finding: the naive procedure of reading only integer fringes from a single dark-field image cannot even beat the zero point by 2×. Because the resolution is rate-limited by the fσ/h = 1.78 MPa step. The contrast with Section 4’s phase shift (whose error drops to machine precision) is the backbone of this PoC.
- L286 — ★Since we invert from the same intensity equation with zero noise, θ should come back exactly (the algebra that produces 4θ from the 4 plane-polarization images is itself the inverse map).
- L308 — ★Pin the finding. (1) The agreement exceeds 95 % but never reaches 100 %. The rest are pixels sign-flipped by the (δ,θ) ↔ (-δ,θ+90°) ambiguity, which cannot in principle be removed by a single measurement at one wavelength. Pin the finding as-is: neither “nearly matches” nor “fully matches”.
- L371 — ★Pin the finding. (1) There is no depolarization (the Stokes magnitude is exactly 1). This is the basis for Section 5’s claim that what drops in the modulation is not the light level but the phase sensitivity.
- L377 — (2) ★★The measurement says the opposite of the naive expectation that “passing a mask fixes it”: no mask 97.0 % / excluding undersampling 97.1 % / excluding low modulation as well drops to 81.9 %. Because removing the low-modulation pixels fragments the region and skimage’s unwrap picks a different 2π offset per island. “Both can be excluded by a mask” is correct as a forecast but wrong as a prescription. Pin the measured value.
- L442 — ★Pin the finding. (1) With neither noise nor quantization, δ comes back exactly from the bright-field/dark-field ratio.
- L445 — (2) ★The error from 8 bit quantization “alone” is the same order as the error from noise σ=0.002 alone (measured 0.00277 vs 0.00305). The camera’s bit depth weighs as heavily as noise.
examples/poc_pigment_unmixing.py
- L860 — ★The very basis for “do not collapse into a single number”. Within the same row, 1.000 and 0.013 sit side by side.
- L1082 — ★Record the failure to win in the figure too. Not a single reconstruction comes below the zero-point line.
examples/poc_pipe_wall_loss.py
- L423 — ★For the sound region, choose a “z where not a single defect falls”. At first I wrote z=20..60 as the sound region, but that was right above the bottom-of-tube corrosion (wall thickness 4.5 mm).
- L471 — ★r_in/r_out are in pixel (voxel) units. Passing them in mm samples outside the field of view and makes the return all 0 (silently. At first this produced a pitch-black figure).
- L817 — ★It is normalized per panel, so clip to the same range before passing (without clipping, only E0 gets painted at ±4 mm and the others at ±1 mm, and they can’t be compared).
- L1040 — ★Rings when the gap is closed. It rang on 2026-09-07 and I rewrote this section —— following the note that “passing in mm returns all 0 with no exception”, it became fail-closed when the ring is outside the field of view. Record that it changed from returning empty and staying silent to rejecting and telling.
examples/poc_pixel_shift.py
- L418 (ja) — drizzle(既存 op、面積保存の別実装)で独立に合わせる。★drizzle の shifts は「フレームの中身が基準からずれた向き」 なので、センサのシフト(画素 (r, c) がシーンの c + dc を見る = 中身は −dc ずれる)とは符号が逆。
- L508 (ja) — ★Q = 2 は「折り返しが出るか」の境目。見える解像の得(系の MTF ≥ 0.1 の帯域)が尽きるのはもっと手前: sinc(0.5)·MTF(0.5Q) = 0.1 の Q*。F 11(Q = 1.75)は画素律速の判定でも得は 1.0 倍。
examples/poc_plateau_venue_lod2.py
- L124 (ja) — ★文献値との差は門にしない(正直に): 間引いた点群の主軸方向の外接幅は 562 × 298 × 244 m で、 文献の 535 × 294 × 209 m より 1〜17 % 大きい。主軸の取り方(点の主成分か慣性主軸か)と外接の取り方の 違いで、どちらが「正しい」かをこの例は決められない。比較の文には文献値(535 m)を使う。
examples/poc_pod_lighting.py
- L406 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_powder_grinding_ae.py
- L269 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_powder_scoop_pour.py
- L313 (ja) — ★2026-10-07: 共有ランナーでは同じ計算が手元の数倍かかる(poc_reproducible_icp で 6 s → 41〜57 s)。 CI(py3.10)で 5.33 s になり落ちた。主張は手元の 5 s、CI は 8 倍の枠で「桁が変わっていない」だけを見る。
- L316 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
- L503 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_print_registration.py
- L151 — Halftone screen ruling [lpi] (a conventional value in commercial printing). ★Deliberately avoiding an integer ratio: at 1200/150 = 8.00 px every halftone dot falls at the same fractional position, the sampling phase aligns and the compositor produces artifacts (measured, the centroid jumped by 1.4 px per fractional offset). In real scans, too, the resolution is almost never an integer multiple of the screen ruling.
- L405 — ★The ledger’s port discards info to match the declared out type, so use
.raw (a pitfall documented with measurements in the comment of fullseye/init.py).
- L855 — ★On the FM side, do not narrow the search range (narrowing doesn’t change the result, but it forecloses the excuse that “AM’s aliasing is due to the search range”).
- L1242 — ★A point where the two-stage broke is always a point where the coarse exceeded the cell radius (pin the inclusion relation)
- L1277 (ja) — ★2026-09-13: ‘lattice’ だけ例外を 1 つ許す。flyvision 族の
fly_hex_lattice(複眼の六角格子)が この語を含んで CI で鳴った(run 34751219513)。あれは網点の格子ではないので印刷の穴は 残ったまま —— 例外は名指しで 1 件に限り、それ以外が現れたら今までどおり鳴る。 「語で引く穴の固定」は、無関係の族が同じ語を使った瞬間に偽陽性になる、という実例。
- L1281 (ja) — ★2026-10-13: 縞に近づくハエの眼(poc_zebra_stripes_fly_eye)の
fly_vogel_lattice(フィボナッチ の複眼)と lattice_moire_peak(標本化格子のモアレの尖り)も同じ語を含む。どちらも複眼の 標本化格子で、網点の格子ではない —— 名指しで足し、印刷の穴は残ったまま。
- L1286 (ja) — ★2026-09-23: ‘halftone’ / ‘screen’ / ‘moire’ の 3 語は埋まった。npr 族の
halftone_screen(回転網点の合成)と halftone_moire_period(2 版のうなりの 周期と向きを閉形式で)が入り、この PoC が「入口が 1 つも無い」と書いていた うちの合成とモアレ予言はファサードから引ける。穴の記録は消さずに、埋まった 語を「在ることの検査」に裏返す —— 消すと「昔から在った」ことになる。 残っている穴は ‘rosette’ / ‘misregist’ / ‘lpi’ / ‘trapping’(版ずれの測定、 スクリーン角/線数の推定、トラッピング)で、そちらが印刷検査の本丸。
- L1330 — ★Add noise to the reference too —— with a zero-noise image, star_detect gives “0 stars” and a ValueError (which is itself a correct fail-closed).
- L1353 — ★2026-09-08: Following this PoC’s note, I fixed the op side. I wrote “cannot be used on repetitive structures” with measured numbers in the docstring, and made it return the runner-up peak / top peak of the vote as
vote_margin. This number can distinguish two cases that the approval rate cannot.
examples/poc_print_warpage_risk.py
- L364 — ★A newly born layer is placed “on the surface that is already warped at that time” (element birth is done in the deformed configuration). Forget to initialize this, and only the later-grown layers stay at zero displacement, and the warp measured by column average becomes 1/4 (stepped on it 2026-09-07). The mechanics (K and f) are on the nominal grid, so they are unchanged.
- L806 — ★The neck vanishes entirely. The part splits into two, so it must not be solved.
examples/poc_pv_thermal_survey.py
- L381 — ★MOD_SHELTER is a module that is sound but not exposed to wind. In Section 3 it turns into a “fault” under the whole-average criterion.
- L583 — ★Decide the module number by area fraction per number. Rounding the average of the numbers turns boundary pixels into a neighboring number (or 0) and breaks the per-module processing.
- L812 — ★The cost of the module median —— blind to a whole-module anomaly
- L1270 — ★
apply_cmap normalizes by that array’s min/max if vmin/vmax are not passed (making the color’s meaning change per condition), so always pass them.
examples/poc_pxrd_phase_peel.py
-
| L185 (ja) — ★a の門 5e-5 の余裕(組み込み時 2026-10-06 に雑音の種を 12 通りずつ振って実測): 誤差は雑音でなく較正の系統で決まり、 この像(傾き 3°・向き −40°)では +3.0〜+4.1e-5(種 21 は +3.8e-5)。種による散らばりは ±0.5e-5 程度で、24 通りの最大は |
4.2e-5 |
。 種は固定なので結果は決定的。門を締めると系統の偏りに当たり、緩める理由も無いので 5e-5 のまま。 |
- L260 (ja) — ★40 s は手元(19-22 s)の 2 倍で決めていたが、CI の py3.10 の走者で 41.6 s に なり落ちた(2026-10-11、ほかの 13 門は全部 ok)。走者は手元の約 2 倍遅いので 3 倍の 60 s に。
- L262 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_real_coin_metrology.py
- L136 — ★Even if the counts match, you are not necessarily counting the same thing. Verify that one circle fits exactly into one component (one-to-one) —— without this, “24 = 24” holds even by chance (one blob of two stuck together + one piece of garbage, still 24).
- L341 (ja) — ★2026-10-06: 題の「46 %」が固定文言で、実行の値(+0.40 で -50.41 %)から外れていた。実行の値を差し込む。
examples/poc_real_deblur_honesty.py
- L199 — ★What we protect is not “which one wins” but that the winner differs per metric. Fix the method name, and it becomes a gate that fails merely because the implementation improved.
examples/poc_real_defect_floor.py
- L156 — Amplitude step. ★This itself is a knob. If coarse, the limit rounds to the same grid point, and one misreads a difference created by the step, like “the larger σ, the wider the gap”, as real (2026-09-09; at 34 levels the median of σ=1.5 and σ=3.0 both rounded to 3.20).
examples/poc_recycling_sorting.py
- L520 — ★Before the sweep, form a prediction from the algebra and print it.
examples/poc_registration_basin.py
- L785 — ★When the user explicitly passes
estimate_normals, thinking “but the normals do exist”. This is the remainder of the gap, 14 orders of magnitude worse than the default.
- L965 — ★Gap 1 was closed on 2026-09-06. This assert has been rewritten to pin the closed state (previously it pinned the broken state:
d_fixed < 1e-6 < d_default = broken). If the breakage returns, this fails.
- L976 — ★Gap 2 was closed on 2026-09-06. Previously it was
< 0.9 * len(ka) (pinning the broken state). Now it pins that the default gives an exact match.
examples/poc_reproducible_icp.py
- L39 (ja) — ★既定(図なし)の経路は CI の PoC の門そのもの。手元 6 s が CI で 41〜57 s(約 9 倍)になり「所要 ≤ 30 s」で落ちた (0.4.0、a9f7e765c)。既定は手元 2.5 s 以下に絞り、主張の重い版(20 万点 × 11 順、ICP の家族 5 本)は –full に移した。 記事・展示の数字は –full の実行から写している。
- L465 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
- L468 (ja) — ★GPU の測定(–full で GPU があるときだけ)の待ちは CPU 時間に入らない —— 門は CPU 側の計算量だけを見る。
examples/poc_rotation_invariance_audit.py
- L115 — ★HALCON-style region moment invariants. Different from
moment_invariants for 3-D point clouds (choosing by name alone will demand (N,3) and fail).
- L208 — ★Relative variation loses meaning when the denominator is near 0. For near-circular shapes the true value of Hu[1] is near 0, so silently reporting it in % turns into “off by 30 %”.
- L220 — ★Where the prediction was wrong. When writing it I thought “interpolating the grey and re-thresholding is rougher”, but for the perimeter it was the opposite.
- L262 — ★Since the background is monochrome, the contour is drawn in a saturated color. Grey has no saturation, so a saturated color is distinguishable from any tone by hue – more reliable than an inverted color, and it is instantly clear that “this is an overlaid line”. Inverted colors come into their own when the background is colored and “any chosen color could collide”.
examples/poc_safety_clearance.py
- L114 — ★The torso is built by placing two capsules side by side. A single cylinder makes the cross-section circular, and the shoulders (±0.19 m from the trunk center) fall outside the torso’s shadow – the real torso has a flat cross-section 0.50 m wide / 0.30 m deep, and an outstretched arm is hidden by the torso when seen from behind.
- L126 — ★X0 and the speed are chosen so that “the true separation distance stays positive in every trial (no contact)” and “it stays in the danger band long enough” – walking fast passes through the danger band in a few frames, leaving too few samples to count missed detections.
- L673 — ★If you vary the density while occlusion is left in, the occlusion bias (+0.12 m) rides on every row and hides the effect of density. The control group’s job is to turn off one factor at a time.
- L683 — ★With a single draw of noise and decimation, the miss rate swings by a few %. Run it 3 times and average.
- L840 — ★Evaluate row by row in bulk (a per-cell Python loop would run 15000 times).
- L1079 — ★Volume ops are (depth,row,col). grid_coords is (nx,ny,nz), so transpose it.
examples/poc_sam_hybrid_bonding_voids.py
- L332 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_scan_to_bim_asbuilt.py
- L658 — ★Applying trim keeps selecting only “the well-fitting points” and falls into another solution with RMSE 0.13 mm (measured: the pulled-in angle is 0.17 mrad at trim=0.9, 0.62 mrad without trim). In as-built inspection the defect itself is the large residual, so trim throws the defect away.
- L950 — ★The headline claim in one image: an intact ceiling appears tilted purely from how it is aligned
examples/poc_sea_ice_concentration.py
- L232 — 2. ★Zero baseline vs linear mixture decomposition # ————————————————————————— #
- L252 — 3. ★★The blob size (perimeter) determines the bias # ————————————————————————— #
- L291 — 4. ★★The bias sign flips with closeness (cancellation point) # ————————————————————————— #
- L353 — 6. ★When the endmember is off by 5 % # ————————————————————————— #
- L380 — 7. ★★Third component (thin ice) # ————————————————————————— #
- L490 — (b) spec_unmix did exist (★checked 3 tiers before writing “not present”)
examples/poc_search_sweep_width.py
- L829 — ★The way shape matters differs by search type. Match the sweep width and compare only the curve shape.
- L869 — ★Plot the miss rate 1-P. P itself sticks to the top-right and hides behind the legend box, invisible (I actually hid it once and noticed). Decide the figure after checking whether it “can be read” – even if the numbers are right, a hidden plot conveys nothing.
- L1089 — ★Reproducibility check: since both the seed and the frame count differ from §3, how much it moves under the same conditions.
- L1266 — ★That it exceeds the zero baseline (with the false-positive rate matched). The gain is modest – “even the zero baseline reaches 174 m” is the finding of this section, so that is what gets pinned.
- L1272 — ★A missed prediction: subtracting the global background is an affine transform, so effectively the same as the zero baseline
- L1286 — ★A missed prediction: with the measured p, the parallel search does not reach 1.000 at C=1
- L1290 — ★Shape matters only for the parallel search: with the sweep width matched, random agrees while parallel splits
- L1293 — ★A missed prediction: the flat curve was supposed to be stronger, but was weaker instead (because of its long tail)
- L1296 — (6) ★Doubling W and doubling t are equivalent
- L1304 — (8) ★Watchdog: false positives concentrate directly below. W moves a lot with the threshold alone
- L1322 — ★The gate on the filled-in side (2026-09-08). Since a Japanese-text tier was added to op_find and domain-neutral descriptive terms were written into star_detect’s docstring, it pins that it ranks near the top for Japanese queries. If it regresses, this fires.
- L1327 — ★Only “point detection” still does not surface – the single character “point” inevitably appears in the descriptions of contour ops like cv_canny / frei_amp too, so ties line up and push it out. It does not hide the limitation that the Japanese-text tier only helps when “words of two or more characters take effect”.
examples/poc_segmentation_gauntlet.py
- L237 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
- L282 (ja) — ★表は世界ごとに 1 枚。examplefig.save_table は 1 セルごとに text_box を全画像に掛けるので、65 行 × 16 列の 1 枚は 100 秒を超えた (実測 104 s)。11 行 × 11 列 × 6 枚なら数秒で、読む側も世界ごとに手法を比べられる。
examples/poc_shape_from_polarization.py
- L296 (ja) — ★2026-10-15: 壁時計は CI の並列のシャードで同じ機械の他のテストの負荷まで数える (poc_phase_measuring_deflectometry がこれで赤になった)。この門が抑えたいのはこの PoC 自身の計算量なので、プロセスの CPU 時間 (time.process_time)で測り、壁時計は併記する。
examples/poc_solar_el_inspection.py
- L366 — ★The calibration line is also passed through the same imaging system (blur). A calibration line pasted without blurring responds 2.4x stronger than a real crack and pulled the cliff toward the thick side (stepped on this on 2026-09-07).
examples/poc_solar_limb_darkening.py
- L317 — 2. ★Zero baseline (50 % method) vs max gradient vs attenuation model # ————————————————————————— #
- L367 — 3. ★★Sweeping the attenuation coefficient u – it bends rather than scaling proportionally # ————————————————————————— #
- L391 — ★Control group – with the blur turned off, all that remains is the geometry (the position of the 50 % surface)
- L427 — 4. ★★The sign of the blur’s effect changes with the threshold (cancellation point) # ————————————————————————— #
- L488 — 5. ★Black spots – 3 % outlier points move the radius # ————————————————————————— #
examples/poc_spc.py
- L144 (ja) — ★MT 法。単位空間の MD² の平均はちょうど (n-1)/n(導出した恒等式)。 1.0 を固定する検査はどんな有限標本でも間違いになる。
examples/poc_star_astrometry.py
- L264 — Image synthesis (★ gap: fullseye has no public op that places a star at specified coordinates) # ————————————————————————- #
- L1243 — ★ “small per run” and “small in aggregate” are different claims.
- L1348 — ★ The bias of “uniform/isolated” being 0.0000 is a given – the plate solution was fit to those 24, so least squares drives the mean of the residuals to 0. To see the error on unused stars, leave one out at a time and re-solve.
examples/poc_stockpile_volume.py
- L658 (ja) — ★座標の約束: 格子の行 0 を北(画像の上)とし、世界座標は (x = 東, Y = 北 = -行方向, z = 上)。 行方向をそのまま +Y にすると左手系になり、絵が鏡像になる(上から見た静止図と左右が食い違う)。
- L863 — ★The winner flips depending on the yardstick: volume uses a horizontal base plane, the centroid uses a plane fit
- L879 — ★A prediction that missed: interpolation is not under- but overestimating
- L882 — ★Cancellation: with the interpolated perimeter the error looks small, and with only the visible points it comes back
- L891 — ★A gap in the tooling. This spot will fire once dem_viewshed is fixed (that’s the intent)
- L893 — ★2026-09-08: the op was fixed on the strength of this PoC’s finding, so being visible now is correct. We pin that it matches our own line-of-sight test and is close to the closed form (it will fire again if it breaks).
examples/poc_strain_history.py
- L507 — ★Closed-form prediction. Central = (w²-1)/24 x d²(velocity)/dt² (the blunting from smoothing), causal = returns the velocity delayed by (w-1)/2.
- L578 — ★Do not make a plot that overlays the histories themselves – truth, cumulative, and direct are indistinguishable to the eye (the error is 0.1-3 % of the truth), and it becomes a plot that merely looks “well matched”. Only produce plots where what was measured is visible.
examples/poc_structure_4d_deterioration.py
- L349 — ★Occlusion is judged by the design shape (
p_nom). If degradation of a few mm to a few tens of mm pushes the surface inside the self-occluding box, the deepest part of the defect goes entirely unmeasured, creating the false scene of “the deeper the defect, the less visible” (hit on 2026-09-07: the core of the defect trough at -21 mm all went NaN).
- L437 — ★The normal of
fit_plane_3d has an arbitrary sign. Align it to the true outward direction (on the scanner side).
- L507 — ★Going through the ledger returns only the declared out type (pose), so receive everything via
.raw.
- L696 — ★Actually try “if differing density is the problem, then just make it uniform” (voxel_grid_downsample)
- L1257 — ★Count the observable information content itself from the point cloud (the diagonal of the normal equations)
- L1299 — ★First take the floor of the measurement method itself – just measure twice with no degradation and no pose error.
examples/poc_surface_roughness.py
- L270 — ★The truth is defined only after declaring the band. Not the roughness component itself, but “the roughness component after cutting at λc” is the truth. If you make this the raw rough_true, even measuring by the correct procedure is off by -23%, and that 23% mixes with the sampling error. There is no “roughness truth” that does not include a band – this is also the claim of Section 2.
examples/poc_swc_tree_truth.py
- L200 (ja) — ★門 4: fullseye の op が自前の計算と整数まで一致する(op の実例 + 第 2 実装)
- L209 (ja) — ★門 2: 3 次元 Sholl は回転で整数が 1 つも動かない
examples/poc_table_tennis_bounce.py
- L53 (ja) — ITTF の台の跳ね(30 cm → 約 23 cm)を満たす e と、その落下の衝突の速さ [km/h]。★空気抵抗を無視した √(23/30) = 0.876 では 上り下りの抵抗で 1.2 cm 足りない(21.8 cm)ので、main の最初に抵抗込みで解き直す(_calibrate_ittf)。
examples/poc_table_tennis_rally_loop.py
- L342 (ja) — ★送り合いの刻みは dt = 0.2 ms。刻みごとにコマを作ると 10 本で 2 万コマ超・数百 GB になり、 図づくりがメモリ逼迫で止められた(2026-10-01)。コマはシミュレーションの時刻で刻む: 1/2 速・25 fps = 0.02 s ごとに 1 コマ、軌跡は直近 0.3 s。コマは uint8 で持つ。
examples/poc_table_tennis_spin.py
- L49 (ja) — ★追跡カメラは予算に関係なく 240 fps。120 fps に落とすと標本が半分になり、回転の誤差が √2 倍(バック 0.9 → 10.9 %)、 コマ間で球が 1.6 cm 動くので跳ねの谷も浅く見えた(2026-09-30)。予算は長さの掃引の刻みだけで削る。
- L245 (ja) — 画像から見つけた跳ね(真値は使わない)。★z の局所最小のうち最も低いもの —— 欠けた検出が残ると空中に偽の 「跳ね」ができ、最初の谷を採るとその手前で軌跡を切ってしまう(バックスピンで 36 コマしか使えなかった)。 高さの閾値(台 + r + 1.5 cm)で選ぶ手は、コマ間で球が 1.6 cm 動く 120 fps で本物の谷を落とした
examples/poc_telecentric_metrology.py
- L113 (ja) — 狙い = iterative)。★2026-10-15 から門に使う: 手元に optiland が無いとき(CI)は、この記録値と telecentric.chief_ray_angle・raytrace.chief_ray(入射瞳が無限遠なら絞りを狙う)の両方を 2e-6 mm で照合する (記録は 6 桁に丸めてあるので丸めの幅 5e-7 mm を含む)。
- L1231 (ja) — ★リングごとに自由な楕円(5 自由度)を当てると、影で弧が 90〜180° しか見えない外側のリングは長半径が外挿で 膨らむ・縮む(2026-10-15 に元の解像度で見て分かった: 外側のリングで楕円が白い線から外れ、間隔が 246〜257 px/mm と ばらついた)。テレセン(正射影)なら傾いた板の同心円は「中心と形を共有する楕円の族」に写るので、族ごと当てる。 族の仮定そのもの(中心の共有)は (c) でリングごとに中心を解き直して確かめる。
examples/poc_tem_ctf_thon_rings.py
- L345 (ja) — 許容幅(★初回の実行で 400 Å の例が 12.5 % / 5.2° で旧の幅 10 % / 5° を外れ、広げた —— 記録として残す): 大きさは max(60 Å, 10 %)(実写 part2_001 で著者の 2 つの推定どうしが非点で 9 Å、この推定とは 190 Å 違う桁)、 向きは 8°(大きさの誤差 / 大きさ ≈ 0.12 rad = 7° の桁が、向きの決まりにくさの目安)。
examples/poc_template_tracking.py
- L93 — ★ Gap (a): there is no public op that returns a correlation map, so we borrow a private one. Use it only after verifying in Chapter 0 that it matches the public op
fs.op.ncc_locate.
- L327 — ★ Gap (d): a public op would silently return [0,0,0] here. Return an explicit failure instead.
- L1241 — (2) The zero point has a floor – quantization of integer coordinates (★ gap b)
- L1271 — (9) ★ Theme: the confidence’s strengths and weaknesses reverse with conditions
- L1275 — ★ The cliffs each is good at are opposite = you cannot pick either one as the confidence
examples/poc_theorems_as_pictures.py
- L308 (ja) — ★手前側の辺を集めて、ひとつの座標系で一度に焼く。三角形を 1 枚ずつ 焼くと、呼び出しごとに自分の外接矩形へ正規化されて図が壊れる。
- L423 (ja) — ★判定は “is not a similarity” で行う。”similarit” だけで見ると op 名
ifs_similarity_dimension そのものに当たって必ず通る —— 最初それで書いており、しかも preset 名を間違えて(“fern”、正しくは “barnsley_fern”)未知 preset の拒否を見ていたのに OK が出ていた。
- L547 (ja) — ★図の書き出しが失敗したら、ここで拾う。見ないと「検査は全部 OK・でも図は 1 枚も出ていない」が黙って通る(examplefig は fail-soft で貯める)。
examples/poc_thermal_drift_metrology.py
- L560 (ja) — ★語で穴を固定すると、別の意味で同じ語を使う族が来た瞬間に鳴る。
gauge は 測定システム解析(msa_gauge_rr = ゲージ R&R)が入った時点で当たるように なった —— この repo で 4 度目の偽陽性なので、意味の合う語だけに絞る。
examples/poc_thermal_radiometry.py
- L522 — ★Forward is direct integration, inverse is a calibration table. Round-tripping through the same table trivially yields error 0 and does not count as measuring the floor.
- L543 — ★Case-0 being exactly 0 is because 350.0 K happens to land on a table node. Move off the node and the interpolation error shows – calling 0 the floor is a lie.
- L772 — ★The x-axis is the rise above the surroundings. Left as T_obj, the divergence collapses into a single vertical line at the left edge, and the crucial “where it jumps from” cannot be read.
- L782 — ★
plot_series rejects points outside the frame (because they stick to the frame and look like real data). The caller clips the diverging side first.
- L836 — ★The x-axis is the absolute Δε. Plotted as relative Δε/ε the three curves overlap exactly (because ε drops out of the equation, per §2) – the plot says nothing.
- L1169 — ★What the guard band uses is the upper overhang. Since what we want to assert as a pass is that “the truth is not above the threshold”, we clip at the upper end of the interval. Using the lower off[0] clips too shallow (by however much the distribution is right-skewed) – wrote it that way once and noticed because the false passes did not decrease.
- L1272 — ★For the same mix-up, on the ε=0.10 surface L_obj drops negative and raises an exception. In other words, “halt or fail silently” is decided not by the mix-up but by the scene.
- L1346 — ★Make the heat source a flat plateau. As a peak, “the bolt and its surroundings at the same temperature” does not hold, and you cannot separate whether the apparent trough is due to emissivity or to temperature.
- L1392 — ★The correction removes the bias but multiplies the noise by 1/ε. That is why only the bolt is grainy in figure (d).
- L1464 — ★
op_find matches on partial stems. blackbody returns 4 hits, but their contents are morphology such as cv_blackhat and have nothing to do with thermal radiation. Reading “it exists” from the count misses. Say it only after looking at the leading name.
- L1614 — 3. ★A prediction that missed: the absolute error is larger at higher temperature
- L1616 — ★Even changing the yardstick, the emissivity error does not diverge with the rise ratio (it plateaus in Δε/ε)
- L1619 — ★What diverges is the reflected apparent temperature (the smaller the rise, the more it jumps)
- L1632 — 6. ★★Coverage rate. At the floor (ρ=0) both RSS and MC are 95 %; adding correlation makes RSS drop
- L1636 — ★The MC side settles at 94.4-94.6 % (not exactly 95 %). The interval ends are set by percentiles over 40000 trials, so there is sampling error, and in reality quantization is mixed in too. Say “MC hits” including all of that.
- L1652 — 7. ★The misses lean to one side (symmetric ±k·u misses a skewed distribution)
- L1656 — 8. ★★guard band: false passes are ignore > RSS > MC, false fails the reverse
- L1676 — ★The correction removes the bias but in exchange multiplies the noise by 1/ε (close to the ε ratio of 9.5)
examples/poc_thermography_ndt.py
- L61 — ★Take the observation time long enough — beyond the healthy part’s t* (6.8 s). Too short and the healthy part’s knee goes outside the window, and TSR answers the healthy part as “the depth at the window edge” (in practice it stuck at 2.82 mm).
- L126 — ★This part alone is an approximation. Since the 1-D solution has no lateral diffusion, at each time we blur in-plane with a Gaussian of diffusion length σ(t)=√(2αt). The physical scaling law is correct, but it does not satisfy mass conservation at the boundary.
- L236 — The range over which TSR searches for t*. ★Excluding the ends is not decoration —— the 2nd derivative of a high-order polynomial always blows up at the ends (Runge). Without it the argmax sticks to the first or last frame, and depth sticks to the 2 values at the window ends (measured, 2026-09-06). We swept degrees 4–11 and settled on 8 (at 4–5, depths beyond 1.5 mm stuck to the ends; 8 and above give the same answer as 9/11).
- L271 — ★Rounding t* to the grid step quantizes depth into staircase steps (with 64 points, 5 % steps). We fit a parabola to 3 points to recover the sub-grid position of ln t.
- L329 — ★Pin down the observation. This is a near-zero sanity check, so if it breaks the implementation is broken.
- L343 — ★The bias of the estimator itself. Without passing through any image, we apply
tsr_depth to an exact 1-D curve. The error here is the “floor of the polynomial fit,” and only what remains after subtracting it from the deviations in Section 3 onward is the contribution of lateral diffusion and noise.
- L361 — ★Pin down the observation: the floor is not zero but small. We bound it on both sides —— if it became zero, the reinterpretation in Section 3 (“even a curve that doesn’t pass through an image deviates by a few %”; ±5 % is roughly the same as the floor) would no longer hold, and if it grew large we could no longer attribute the deviations from Section 3 onward to lateral diffusion.
- L396 — ★Pin down the observation. That these 2 lines hold simultaneously is the very claim of this section. (1) When the 16 items are collapsed into a single average, TSR loses to the null baseline that “always answers 1.50 mm.”
- L426 — ★Pin down the observation. (1) The lower-right triangle, where the diameter is 4 times or more the depth, is hit within a few % (roughly the same as the floor in Section 1).
- L457 — ★Control group: the same scene with lateral diffusion turned off. This separates “blame lateral diffusion” from “blame insufficient pixels / a mask that can’t be extracted.” Looking at only one side and blaming physics is the most common mistake in this kind of experiment.
- L504 — ★Pin down the control group’s observation: with lateral diffusion off, all 16 fall within ±8 %. This one line is the evidence that “the only cause of breakage is lateral diffusion, not pixel coarseness nor how the mask is taken.” Loosen it and the conclusion of Section 3 reverts to the misreading that ‘raising the resolution fixes it’.
- L514 — ★If the reasoning above (the diffusion length at the end of the window matters) is correct, then cutting the window fixes it. When you form a hypothesis, always place one experiment shaped to disprove it. —————————————————————— #
- L535 — ★Pin down the heaviest observation of this PoC —— the “aspect-ratio limit” was not physics but how the fitting time window is chosen. (1) With a 4-second window, all 8 small ones fall within ±20 % (measured worst case -14 %).
- L623 — ★Pin down the observation: if heating is uniform, the raw single frame detects the most, while the 2nd derivative of TSR detects none. “It works for depth estimation but is unsuited to detection” = the same tool does not necessarily work for both, which is exactly this section’s claim.
- L670 — ★Lamp reflection. This is the one with structure at the same scale as the defect.
- L697 — ★Pin down the observation. (1) The only thing that breaks it is (c)’s unevenness at the same scale as the defect. (b)’s gentle gradient barely breaks the raw single frame —— since this is where “the prediction was off,” we explicitly confirm that (b) does not undercut (a).
- L778 — ★Put NETD into the default cube as well. With zero noise, the in-plane variation of the sound region becomes exactly 0 and the SNR turns into a meaningless number like 1e9 (measured and fixed).
examples/poc_thin_film_reflectometry.py
- L92 (ja) — ★色名から色相への対応は私の選択(CSS の色は表の色より彩度が高い)—— 色相だけを比べる。
- L210 (ja) — ★ 実測で採点(公開データ、CC BY 4.0)—— この PoC の主役 # ————————————————————————— #
- L308 (ja) — ★フラット補正(2026-10-15、図を見たユーザーの指摘「Si 側が 2 段に分かれて見える」から): 写真は視野の中心が明るい 周辺減光を持つ(裸の Si は左端 0.238 → 中央寄り 0.263、SiO₂ は中央寄り 0.103 → 右端 0.095)。補正しないと、Si の 暗い側が「薄い膜」と読まれ(0 nm 付近は R が膜厚の 2 乗でしか下がらないので、数 % の明るさの差が 10〜17 nm に化ける)、 明るい側は 0 nm に張り付いて、2 段に見えた。減光を半径の 2 乗 V = c₀ + c₁ r² として裸の Si の側だけで当てはめ、 視野全体を割る。SiO₂ の側は当てはめに使っていないので、その明るさの傾きが消えるかが独立の検算になる。
- L437 (ja) — ★予言が外れた: 「裸の Si は無彩色(C* < 3)」と置いたら C* 6.6 だった。Si の反射率は 400 nm 0.49 → 800 nm 0.33 と 短波長ほど高いので、裸のウェハは青みの灰色に見える(実物のとおり)。門を所見の側に書き直した。
- L475 (ja) — ★境の直上でも FFT は最大 %.0f nm 外す(窓の DC の裾とフレネルの位相の分)—— 2 倍の厚さで 1 % 以内に入る。
examples/poc_timelapse_growth.py
- L472 — ★Vary the grid phase in 5 ways and count separating bias (mean) from spread (width).
- L610 — 2) ★Y-shape —— slice the volume along the row passing through the center of the merging pair
examples/poc_traffic_counting.py
- L256 — ★Rows cut off at the left or right of the frame have their centroid pulled. We also measure the version with them dropped.
examples/poc_tree_ring_dendro.py
- L229 — ★Reading the pixel map diagonally makes the numbers flicker as k, k+1, k, k+1 at the boundary (nearest-neighbor staircase). Short runs of fewer than 5 samples (1.25 px) are absorbed into the preceding value —— left alone, the ground-truth boundaries increase by 1–2 and it became “18 in the direction where the year count matches + 13 that don’t = 31 > 24.”
- L336 — ★Take everything with threshold=0 and measure the step height yourself. The amplitude of measure_pos (the difference between the two ends of the gradient lobe) stops midway up the step when the grain makes the gradient non-monotonic, returning a 0.14 step as 0.05 (counted in Section 8).
- L345 — ★The outer-edge radius used to convert back to px is that of the measured row. Using the median over the whole 15° sector makes the outer edge move by more than 10 px within the sector due to eccentric growth, so all the outer rings shift (I first wrote it that way and dropped rings 18–35 entirely).
- L543 — ★Is the width correlation high even in the direction where the year count is wrong —— the year count and the width correlation are separate quantities
examples/poc_vanishing_detail_and_morphing_area.py
- L73 (ja) — 色。★赤と緑は対にしない
- L623 (ja) — 3. 消える距離は整数(束ね幅を縦に積む。★各行を正規化しない)
- L638 (ja) — ★消える行(f·k が整数)に左端で印を付ける
- L775 (ja) — ★見せる図は決め打ちの制御点で(検査のほうは乱数 4 通りで通してある)
- L851 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/poc_vegetation_cover.py
- L320 — so here we reduce it to the 2 bands green and red to solve it. ★A gap in the tooling.
- L543 — ★Whether it lies on the diagonal is precisely “whether it can answer in fractions.” The line of a binary method becomes a staircase and departs far from the diagonal in the band of mixed pixels.
- L755 — ★Show “only the numbers match” as a picture. The 3rd and 2nd frames share almost no common pixels, yet only the count of white pixels is balanced.
- L953 — (7) ★PPI breaks under noise —— even with 60 % or more pure pixels it fails to pick up the leaf. Meanwhile with zero noise it hits on the same scene = the cause of the cliff is not a shortage of pure pixels.
- L993 — (11) ★A gap this PoC found and fixed in fullseye 0.1.10. Three Otsus were returning different answers for the same input —— merely multiplying the same image by 4095 shifted the verdict by otsu 13.34 pp / cv_otsu 13.92 pp, and only sk_otsu was affine-invariant. The cause was the
np.clip(v, 0, 1) in ops._otsu and backends._u8 (floats in 0..255 saturate every pixel, making it “all foreground”). Now all three are invariant to scaling. The remaining 0.5 pp in cv_otsu is because OpenCV internally quantizes to 8 bit, which is behavior as documented in the docstring. The gate is tests/test_value_range_saturation.py.
- L1007 — (12) ★A gap in the tooling: spec_unmix rejects B=3 (color images) = there is no path to solve RGB
- L1013 — (12b) ★There really exist scenes where only the coverage-ratio number matches while not a single pixel is hit. This one line is the strongest evidence for “do not round down to a single number.”
examples/poc_veiling_glare.py
- L229 — ★Cross-check on the fullseye side: Airy pattern → does psf_to_mtf agree with the closed form
examples/poc_vessel_network.py
- L263 — ★Add the fluctuation after blurring. Adding it first lets the PSF smooth it out, leaving the threshold boundary clean (I first wrote it that way, and even raising the amplitude to 0.35 produced not a single whisker).
- L452 — Section 2-3. ★★Where do the whiskers come from / the pruning threshold depends on resolution # ————————————————————————— #
- L560 — Section 4. ★★Diameter estimation —— always overestimated near branches # ————————————————————————— #
- L620 — Section 5. ★★Murray’s exponent —— a 10 % in diameter becomes a 1 in the exponent # ————————————————————————— #
- L751 — Section 6. ★Control group for crossings / branches lost to resolution # ————————————————————————— #
- L890 — (c) ★skeleton_prune3d does not “prune short branches” but “shortens all branches”
- L903 — (d) ★fs.skeleton_nodes returns only endpoints even though its docstring says “coordinates”
examples/poc_video_physics_consistency.py
- L175 (ja) — ★ 縁に触れた bbox の辺は車の縁でなく画像の縁。そのまま使うと位置が 0.36 m ずれて黙って軌跡に入る(2026-10-23 の敵対的レビュー、 発射条件の端 3000 本中 2 本)。label_extent は切り詰めを知らないので、ここで止める。
examples/poc_warehouse_flow.py
- L145 — ★”Waiting for people” 4 cases x (7.5 + slow-down 2.5) and “aisle interference” 8 cases x (2.5 + slow-down 2.5) both add 40.0 seconds to the null baseline —— deliberately matched. It won’t necessarily agree with reality, but that “the same number arises from different causes” can be shown with one example.
- L160 — The null baseline’s “stationary” threshold [m/s]. ★Unless it is placed well above the apparent speed created by noise (σ√2/Δt = 0.085 m/s @ Δt=0.25 s), stationary people are misjudged as moving and the null baseline shrinks (at 0.15 m/s the null baseline halves at Δt=0.25 s, yielding the false conclusion that “the finer you sample, the less dwell there is”).
- L239 — ★Since it is visible if even one of the cameras can see it, entering the blind spot means the height at which all cameras are blocked = the maximum of each camera’s limit. I had this as min and the prediction was off by 0.5 m.
- L329 — ★Derive the arrival time of the people queuing from the time work actually starts (deriving it from an estimate was off by 20 seconds, and the waiting bar did not overlap the working bar).
- L342 — ★The meeting place must be right alongside a row of shelves. A cross-aisle that is not between two shelves is open on both sides with a clearance of 1.9 m and is not classified as a “narrow aisle” (the first implementation had them meet at the level of the main aisle, and 4 of 10 fell into “other”).
- L435 — ★It is a merge, not a swap —— a swap does not break the temporal nesting that “within the same bar, the one that started later is the waiter” (only the roles swap, and both roles are filled correctly). What breaks it is when two people look like one.
- L594 — ★Keep only the stationary core. A bar spans 1.8 m from two people’s footprints, so the center of a passing person also falls inside the bar for 2-3 frames (in measurements this created “an interference with only one person” and dropped 8 of 10). Take the longest run that stayed within :data:
CORE_R of the median as the core.
- L846 — ★Counting by multi-person components makes “a column where 10 people passed through the aisle” thick and mixed, so compare “while waiting” and “while walking” within the same single person.
- L1257 — Marker size. ★Since “awaiting restock” and “out of stock” happen in front of the same shelf, draw from the largest marker and layer the smaller ones on top. Drawn at the same size, the later-drawn one completely hides the earlier one, and on the figure 5 looked like 2.
examples/poc_water_level.py
- L346 — 2. ★Zero point vs homography # ————————————————————————— #
- L389 — 3. ★The sign changes with the anchor position # ————————————————————————— #
- L422 — 4. ★Ripple —— robustness only helps when there are outliers # ————————————————————————— #
- L459 — 5. ★★Reflection —— comes out systematically low # ————————————————————————— #
- L622 — (d) The caliper existed (★I started to write “it does not exist” but pulled 3 tiers and found it)
examples/poc_web_roll_periodicity.py
- L123 — ★The circumference difference between the 1st nip and the 2nd nip is deliberately only 15.7 mm (for the cliff in section 6).
- L158 — Raise the number of trials only for section 6 (the cliff). ★With 24 trials the report rate was non-monotonic — 100 % at 12000 mm and 88 % at 14000 mm — and the position of the “detection cliff” moved with small-sample fluctuation (with 120 trials 12000 mm settled at 93 %, and 100 % holds only at 17000 mm and above). Only the section that claims the cliff position is measured at a trial count where the floor does not wobble.
- L253 — ★The op returns the vertex without rounding (exceeding ±0.5 is the information that “that is not a maximum there”). Since this PoC also evaluates the comb’s harmonic bins, we round explicitly here.
- L802 — ★The floor is not 0. With 24 trials the longest 2 points happened to be 0 % and the judgment “the shortest L that holds 0 %” passed, but with 120 trials even the longest 20000 mm leaves 2 %. Measure the floor first, then decide at what multiple of the floor to call it a cliff (do not use 0 % in the judgment).
- L1057 — ★With 120 trials it was no longer exactly 100 % (97 / 98 %). The “100 %” of 24 trials was just a small denominator. Look at the floor and set it at 95 %.
examples/poc_weld_bead_profile.py
- L696 (ja) — ★2026-10-13:
op_find("laser") は 0 件でなくなった —— coherent 族 (laser_line_coherent / speckle_field / triangulation_speckle_limit)が引っかかる。 だがあれは光条を描く側と、スペックルが決める誤差の床を返す閉形式で、 画像から列ごとの中心を取る op ではない。穴は残っている(語でなく族で固定する)。
- L700 (ja) — ★2026-10-15: op_find に docstring 全文の段(最低点 12)が加わり、引数の説明に “laser” と書いただけの 無関係な op も並ぶようになった。ここで固定したいのは「名前か 1 行目で laser を名乗る op」なので、その段は除く。
- L705 (ja) — ★2026-09-23:
op_find("stripe") は 0 件でなくなった —— wave 族の wave_fringe_period(「縞模様の画像から周期を測り返す」)が docstring で 引っかかる。だがあれは画像全体の 1 本の支配的な周期を返す op で、 ここで要るのは列ごとの輝線の中心をサブピクセルで取る op。穴は残っている。 語で穴を固定すると、別の意味で同じ語を使う族が来た瞬間に偽陽性になる (この repo で 3 度目: fly_hex_lattice / halftone_moire_period / これ)。
examples/poc_weld_bead_scan_angle.py
- L485 — ★Candidates are “points that returned to the height of the base-metal surface,” so all the flat base metal outside the groove also becomes a candidate. Only after confirming that weld metal (a drop of at least CHECK_DEV from the base-metal surface) exists within the inner CHECK_IN mm is it accepted as a toe —— without this gate, candidates slide down onto the base metal and the leg length flies out by 1.7 mm.
- L489 — ★Take the gate depth deeper than the deepest groove. Setting it first at -0.6 mm let a groove of depth 0.45 mm (0.74 mm vertically) pass the gate, and 1 of the 16 cross-sections was off by 2.2 mm.
- L572 — ★The mean of true values for only the surviving cross-sections. See what dropped out of the aggregation.
- L999 — ★Only the convexity deviated from the prediction. The cause is the creep of the toe (because τ is an absolute-value threshold).
- L1193 — ★How the groove disappears with angle (viewed by the drop from the base-metal surface)
examples/poc_what_a_picture_cannot_check.py
- L280 (ja) — ★偏りの正体を探し当ててから書く。平面の推定が 1.88 と 真値 2 より低いのは、最初に疑った「点数が足りない」ではなかった (400 → 3,000 点で 1.8825 → 1.8709 とむしろ下がる)。正体は べき乗則を見る半径の窓で、既定は対距離の 1〜25 パーセンタイル —— 単位正方形ではその上端が箱の端に当たり、相関和が飽和して傾きが審う。 窓を小さい r 側に寄せると 2.05 まで上がる。
- L402 (ja) — ★平行移動フレームの効き目: まっすぐな区間を含む曲線でも半径が崩れない
- L480 (ja) — ★K の一致は必要条件にすぎない
- L630 (ja) — ★図の書き出しが失敗したら、ここで拾う。見ないと「検査は全部 OK・でも図は 1 枚も出ていない」が黙って通る(examplefig は fail-soft で貯める)。
examples/poc_worm_neurites_grow.py
- L111 (ja) — ★dist_to_root には coords に無い節点も入っている(1 匹目で 196 本中 54 本)。 座標のある節点だけに絞らないと最大値が食い違う(最大 12 倍)。
examples/poc_zernike_aberrations.py
- L85 (ja) — n <= 6 の 28 モード。★(n+1)(n+2)/2 = 28 は閉形式で数えられる
- L402 (ja) — 絵を作る道具 —— ★色は飾りでなく量に結びつける # ————————————————————————— #
- L588 (ja) — ★本物の op と突き合わせる —— 同じ仕様の 2 度目の実装。
fit_zernike は torch(grid_sample)で補間するので、CI の py3.10 / py3.12 には入っていない(大きさと時間のため py3.11 だけ)。 だから発見そのものは numpy の写しで立て、op があるときだけ照合する。
- L707 (ja) — ★同じ絵を線形補間で読むとどうなるか(章ごとの接尾辞 lin_)
- L838 (ja) — ★1 次か 2 次かは「収差を半分にしたときの比」で分かる(章ごとの接尾辞)
- L865 (ja) — ★帯は必ず書く。球面収差のハローは明るいので、同じ帯でも段数が変わる (実測: 無収差の 3.5-8.0 λ/D は線形 1 段、球面収差 0.30 波なら 6 段)。
- L1041 (ja) — ★検査で使った点像は瞳 96・格子 1024(1 画素 0.19 λ/D)で、絵としては 粗い。同じ無収差をもう一度、細かい刻みで描き直す(数は検査のもの)。
- L1298 (ja) — ★門 tests/test_poc_scripts_run.py は exit 0 だけでなく PASS の印字も見る。
examples/polarization_camera_pipeline.py
- L110 (ja) — ★雑音つきで回復した行列は coherency の最小固有値が僅かに負に出る(雑音 1e-4 → -1e-4 程度)。tol は雑音の水準で置く。tol を勘で小さくすると「非物理」に化ける。
examples/profile_shape_inspection.py
- L25 — ★Since it imports a module directly under the repo (profileops), put the repo root at the front so it runs straight from a checkout. Same convention as the other examples. Without this,
py -3.11 examples/<name>.py fails with ModuleNotFoundError (measured 2026-09-09: of the 83 that had no gate to run them, only 2 of this type failed).
examples/representation_roundtrip.py
- L175 — (c) Gaussian -> voxel mass. ★A number I got wrong once
examples/shape2d_morph_descriptor_tour.py
- L64 — ★EXTEND: replace with your own contour-extraction result (
{"shape": (H,W), "cs": [ (N,2) (row,col), ... ]})
examples/shapestat_landmark_tour.py
- L71 — ★EXTEND: put your own landmarks (N,3) into s (the point ordering must correspond)
- L123 — ★EXTEND: put your own group (K,N,3) into scrambled (position, orientation, and size may be scattered)
- L221 — ★EXTEND: arrange your own landmarks as “all of the left, then the right in the same order” and put them into lm
- L276 — ★EXTEND: make surf your own surface points (mesh vertices, point cloud) and normals their oriented normals
- L299 — ★EXTEND: replace with your own group (K,N,3) (the point ordering must correspond across individuals)
examples/voxel_labels_color.py
- L81 — 1) ★Color stability —— the reason this family exists # —————————————————————— #
- L152 — 4) ★Anisotropic spacing # —————————————————————— #
examples_3d/alpha_shape_topology.py
- L149 — ★Discriminative assert: the alpha shape preserves holes = it barely contains the axis probe. The null method (convex hull) FAILs this condition with containment ≈1 (= discriminative).
examples_3d/ct_hand_radiograph.py
- L34 — Actually call it and verify. ★Until 2026-09-05, this example wrote “matches np.sum(axis=0) when azimuth=elevation=0” but had never once verified it. Moreover, because the op → example index mistook the hasattr string for a call, “ops with not a single example” were hidden inside 100% coverage.
examples_3d/geodesic_dome.py
- L6 (ja) — ★この例の要点は絵ではなくオイラーの公式: V − E + F = 2 から、次数 5 の 頂点はどれだけ細分してもちょうど 12 個になる。11 個でも 13 個でも球には ならない。ここでは次数を 別実装の op(conngraph.graph_degree_table)に 数えさせて確かめる —— 自分で数え直して自分と一致しても、何も確かめたことに ならないため。 repo をそのまま clone した状態でも動くように、リポジトリ直下を import パスへ入れる。
- L48 (ja) — ★オイラーの公式の帰結。細分しても 12 から動かない。
examples_3d/geometry_metrology.py
- L186 — ★Output the difference from the infinite-line version as a number (the same 2 segments)
examples_3d/hull_bounds.py
- L237 — — Panel C: ★new min_enclosing_sphere (tight) vs naive sphere (oversized) —
- L272 — ★(1) new op — min_enclosing_sphere: radius recovery on a known sphere + contains all points + nearly minimal ============================================================
- L296 — ★(2) beat-null of the new op — on an asymmetric point cloud, smaller than the naive sphere, nearly minimal, on the safe side ============================================================
examples_3d/mesh_props.py
- L404 — ★Flipping the winding order reverses the sign of the volume = the sign is itself an orientation check
examples_3d/metrics_eval.py
- L234 — ★Nearest-neighbor distance lies when it is “just re-measured with zero change.” Re-taking the same slope at a different density or position makes the nearest neighbor grab an adjacent point along the surface, producing a spurious change on the order of the point spacing. M3C2 projects onto the normal direction, so that component drops out. (The prediction before writing this PoC, “C2C also comes out too large under a normal shift,” was wrong —— moving parallel surfaces along the normal direction alone keeps the nearest-neighbor distance nearly at the true value. The lie appeared in the re-taking along the surface instead.)
examples_3d/minimal_surfaces.py
- L6 (ja) — ★この例の要点は絵ではなく定義そのもの: 極小曲面とは「平均曲率 H が至るところ 0」の曲面である。既存の
vertex_curvature がまさにその H を測るので、 「これは極小曲面だ」という主張を、作り方を知らない op が採点する。 対照群として単位球(H = 1)と半径 1 の円柱(H = 0.5)を同じ手続きにかけ、 門が素通しでないことを示す。
- L12 (ja) — ★カテノイドとヘリコイドは等長なのでガウス曲率 K が一致するが、それは 必要条件にすぎない —— K が一致しても極小とは限らないので、門は H に置く。 repo をそのまま clone した状態でも動くように、リポジトリ直下を import パスへ入れる。
- L130 (ja) — ★平行移動フレームの効き目: まっすぐな区間を含む曲線でも半径が崩れない
examples_3d/sdf_csg.py
- L167 — ★Trap: even as a scalar,
res is the number of voxels per axis, so if bounds are anisotropic the voxel is not a cube (here x,y is 0.125 and z is 0.0625). Computing the volume with h**3 is off by exactly a factor of 2 —— in this example it actually gave 295.00, a 99 % error against the closed form 148.03, and the assert below fired.
examples_3d/space_carving.py
- L117 — ★Use
carve_look_at (2026-09-08). Same implementation as look_at, but the name reachable from the public layer is this one —— fs.look_at is a different thing, render3d’s gluLookAt version (4x4, −Z forward), and passing its M[:3,:3], M[:3,3] drops all points behind the camera and returns an empty hull without raising an exception.
examples_3d/structured_light_scan.py
- L122 — ★ Coordinate-system pitfall:
look_at builds the pose in the gluLookAt convention (camera looks down -Z, +Y is up), but render_mesh first rewrites that Vc to (x, -y, -z) before multiplying by K (= the same CV convention as depth_to_points / K, depth is +Z forward). Triangulation is closed on the CV-convention side, so the pose must also have FLIP applied before it is composed. Skip this and the projector faces behind the camera, and the depth stays at a ‘plausible magnitude’ while being entirely wrong (the very first run did exactly this: RMSE 78 mm = indistinguishable from zero).
eyebrain.py
- L242 (ja) — ★fly_hex_resample と同じ向き: 画面の x = 方位角 az(右が正)、y = 仰角 el(上が正)。uv から組むと 像と眼の絵の左右が食い違う(2026-09-20 に実測: 縞を右へ動かすと柱の u が減った)。
fast.py
- L254 — ★Do not ship the uint8 gaussian. The 8U path of
cv2.GaussianBlur uses an 8-bit fixed-point kernel, so its difference from the float64 core is 1.174/255 (measured, the max over this module’s 6 gate images x 5 PARITY_AB points), which does not meet ‘agreement to 1/255’. box is 0.494/255, and median / morphology are 0.000/255, so only those are shipped. If a fast uint8 gaussian is needed, add it explicitly under a separate contract of ‘to 2/255’.
- L294 — ★Everything listed here has passed the :func:
parity gate. When adding, always follow the order ‘implement -> run the gate -> ship it if it passes’.
- L320 — ★Do not ship
edges_image (as a HALCON name, the same as canny). That name in the registry is backends_auto’s skimage canny (with real hysteresis), a different algorithm from the core canny. Mismatch rate 1.0 (measured). – HALCON-name twin (an op registered in the registry under an alias with an identical implementation) ———- same idea as accel._TWIN_ALIASES. The gate runs against the implementation under that name in the registry, so if the implementation diverges it fails and is not shipped.
- L372 — ★Do not decide by ‘was the observed output {0,1}’ – even a continuous op produces all-0 output on a constant image, which is misjudged as binary and silently tightens the criterion (hit during implementation). Decide by the declared out_sort in the registry.
- L403 (ja) — ★twin はどれも歴史的な規約(reflect / 正方形)しか実装していないので、
b が新しい選択肢を選んでいる間は core にそのまま落ちる。 速くはならないが、答えは 1 ビットも変わらない —— median の k>5 と同じ扱い。 ここを黙って無視すると「速いが違う」ができる(実測: parity が 11 件割れた)。
feat_fpfh.py
- L304 — ★2026-09-07: The pose computation is numpy (FPFH, RANSAC, and Kabsch are all numpy), and torch was used only to wrap the return value. Because of that, on CI without torch (py3.10 / 3.12) this op became a whole-op ImportError and the PoC failed. If torch is present it returns a Tensor as before; if not it returns numpy with the same values (values unchanged).
feat_shot.py
- L80 (ja) — ★2026-10-11: 平面上の点の λ3 は丸め屑(λ3/λ1 ~ 1e-17)。軸に沿った平面では 厳密に 0 で落ちるが、傾けた平面では屑が正になり「特徴の無い平面」から キーポイントが 203 個出ていた(回転不変の主張が崩れる)。床は λ1 に対する相対量で。
flyvision.py
- L217 — ★ 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.
fourierdesc.py
- L296 (ja) — ★この族の既存 op(elliptic_fourier)は Kuhl-Giardina の実係数(a,b,c,d) # で、楕円 1 つ 1 つを表す。こちらは同じ輪郭を複素係数 c_k で見る —— # z(t) = Σ c_k exp(2πikt) と書けるので、各項が「回る腕」そのものになり、 # パーセバルで打ち切り誤差を描く前に予言できる。用途が違うので両方置く。 # ————————————————————————— #
- L396 (ja) — ★偶数点では添字 n/2 が k = +n/2 と k = -n/2 の同じ 1 つの係数である。 両方を並べるとエネルギーを 1 本ぶん多く数えてパーセバルが破れる (実測: n=8 で 1.17e-01、n=512 で 7.5e-03 ずれた)。numpy の
fft.fftfreq に合わせて k = -n/2 の側だけを出す。 最初の検査(正方形の輪郭)はこの係数がたまたま 0 に近くて通っていた —— 探針 1 枚では足りない、の実例。
fscript.py
- L1220 (ja) — ★しきい値は argmax ビンの「上端」(2026-09-26)。(k + 0.5)/256 は そのビンの中点で、argmax が指すのは背景の山を含むビンなので、同じ ビンに居る背景画素が前景へ漏れていた(背景 0.30 / 明部 0.90 の板で 4,096 px 全部が前景、期待 400)。
ops._otsu / accel._otsu / detect._otsu_mask と同じ式を 4 か所に別々に書いてあり、4 つとも 同じ誤りを持っていた —— docs/hardening/otsu-threshold-at-the-bin-midpoint.md。
- L1284 (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 横断で見る。
- L632 (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 連結を注入したのに一切検出されず、掘ったら 注入のほうが効いていなかった、という経路で見つかった。)
- L725 (ja) — ★契約 R-1(fullseye_abi.h): 失敗した演算子は「何も見つからなかった」演算子と 区別できなければならない。逆さの区間は呼び手の間違いであって、「空を寄こせ」 という正当な指定ではない —— 黙って空の Region を返すと、しきい値の計算を 間違えたレシピが「不良ゼロ」として通る。2026-09-14、同じ契約の Rust 実装が FS_E_INVALID_ARG を返すのにこちらは空を返す、という差分で見つかった。
- L780 (ja) — ★契約 R-1:
threshold で直したのと同じ欠陥が兄弟に残っていた。逆さの区間は 呼び手の間違いであって「空を寄こせ」という指定ではない —— 黙って 0 個を返すと、 面積の下限と上限を取り違えたレシピが「該当なし = 良品」として通る。 2026-09-14、Rust 実装が FS_E_INVALID_ARG を返すのにこちらは 0 個を返す差分で発見。
fsruntime.py
- L284 — ★A judging recipe may use ONLY the curated fslib-backed builtins, under EVERY profile (not just industrial). Any other call is a 650-op evolution-registry op resolved through fscript._call_registry_op → api.RT, whose _safe wrapper is fail-OPEN (it swallows an op failure and returns a benign “no defects” value). That surface must never be a recipe’s operator — a studio/reference runtime judges parts too — so a recipe that uses it is rejected at load (docs/FSCRIPT_DECISION.md 1.6b).
fullseye/__init__.py
- L468 (ja) — ★2026-10-02: 「名前の無い非公開関数」の棚卸しで、op として振る舞うのに公開経路が 1 本も無かった 18 本。 どれも既存の型つき台帳の約束(台帳 = 実装モジュールの集合)に合わないので、facade(fs.<名前>)から出す。 門は tests/test_hidden_ops_exposed_2026_10_02.py(定理か第 2 実装)。名前>
- L511 (ja) — ★1-D 版は signal_ 接頭辞で出す。素の名前で出すと
fs.local_std(1-D)と fs.ledger.local_std(2-D)が別物を指す —— 既に lowpass がその状態になっており(facade=dsp / ledger=2-D)、 同じ罠を増やさない。次元をまたぐ同名は、呼ぶ側で見分けがつく形にする。
- L741 — ★The adapter that conforms to the declared out type discards everything from the 2nd element onward of an op that returns a tuple (
wht of drizzle_resample, info of piv_cross_correlate). When the discarded side is needed, it was unreachable through the ledger’s entrance. On 2026-09-06, a super-resolution PoC wrote flow, info = fs.ledger.piv_cross_correlate(...), unpacked the (2,R,C) along the 1st axis, used the 2nd row of dy as dx, and turned the shift estimate from 0.12 -> 0.74 px (no exception raised). Use .raw to reach the bare return: fs.ledger.piv_cross_correlate.raw(a, b).
- L1234 (ja) — ★字の検証・修正(glyph_*)。dir() でなく __all__ が一次情報なので ここに載せる —— dir は環境依存で、載せ忘れは全体スイートでしか出ない。
- L1321 (ja) — ★2026-09-20(GenSpark 第 50 報 N175 / N176):
import fullseye; fullseye.os が通っていた —— import に使った 道具(os / sys / warnings と future の annotations)は facade の名前ではない。tab 補完と dir() を汚さない。
fullseye/mcp/catalog.py
- L70 (ja) — ★
dim は docs/ops の族ディレクトリ名(2d / 3d / oned のほか optics / annotate … 31 種)で、厳密な次元ではない —— volume を取る registry op は 2d/3d/ の下にあり dim: 2d。 次元は in / out の sort から読む(2026-09-20、GenSpark 第 31 報 N109。族と次元の分離は 0.2.2)。
- L96 (ja) — ★2026-10-02: 区切り文字を “/” にそろえてから並べる。素の sorted() は Windows の “\“(0x5C)と Linux の “/”(0x2F)で順序が変わり、
segmentation/watershed/ と segmentation/watershed3d/ の 前後が入れ替わって OP_NOTES.json の鍵の順が OS ごとに違った(手元の regen は緑、CI の –check が赤)。
- L103 (ja) — ★frontmatter は閉じ線まで読む(2026-10-02): 先頭 1200 文字で切っていたら、examples: の行が 44 本に伸びた text_box の閉じ線が範囲の外に出て「op の無いノート」に見え、索引の op がノートから引けなくなった。
- L125 (ja) — ★5 層。最初は 4 層で組み、「索引にもレジストリにも facade にも無いノート」が 480 枚残った。残骸かと思ったら 480 / 480 が
fullseye.ledger で解決した (型付き台帳。レジストリでは tb_project、台帳では project のように接頭辞が 違う)。「無い」と言う前に全層を引く —— 4 層目まで引いて止めていたら、実在する 480 個の機能を残骸と呼んでいた。
- L311 (ja) — ★2026-09-20(GenSpark 第 41 報 N141): 「callable なら op」でクラス 41 個(Image / Pipeline / MissingBackendError / TcpChannel …)が facade 層に op として混ざり、
fullseye_search_ops の検索面を汚していた。クラスとモジュールは型・器であって op ではない。関数(生 / builtin / functools.partial)だけを op として数える。同じ報の「facade 表に無い 474 件」は halcon_facade_map.json(HALCON 対応表、鍵は camera.xxx の名前空間つき)との比較で、 残る 460 件は import fullseye で呼べる実関数 —— 表の目的が違うので設計のまま。
- L361 (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 なので「飽和」が先に当たった。 より根本的な異常を先に言う: 非有限 → 定数 → 範囲外 → 飽和 → 平坦。
- L109 (ja) — ★飽和・平坦は image / color だけ。region は 0/1 が契約なので「飽和」ではない —— リファクタで region を含めてしまい、
--demo で otsu の出力が「飽和」と判定されて 小図が昇格した(2026-09-15 実測)。region の定数(空 / 全面)は上で拾う。
fullseye/mcp/handles.py
- L51 (ja) — ★thumb_dir を渡されたときに作っていなかった(mkdtemp のときだけ存在する)。 小図の保存が FileNotFoundError で落ち、テスト 4 件で発覚(2026-09-15)。
- L156 (ja) — ★2026-10-11: 根の中の壊れた png・object 配列の npy は ValueError 等を HandleError に 写さず投げ、dispatch を抜けてサーバのループが死んでいた。読めない中身は理由つきで断る (-32602)。npy は pickle を決して許さない。
fullseye/mcp/server.py
- L508 (ja) — ★2026-10-11: Content-Length が無い / 0 のフレームで None(= EOF)を返し、サーバが 黙って終了していた。EOF は「ヘッダを 1 行も読めない」ときだけで、壊れたフレームは FramingError(→ -32700)にしてループを続ける。
- L1357 (ja) — ★bbox が無いときは glyphops.make_spec に任せる。版面が取れなければ items に bbox が 入らない = 黙って外れた箱で直すことは起きない。ここでは理由を付けて断る。
- L1630 (ja) — ★2026-10-11: find_ops は「既知の種別以外は拒否する」と書きながら typo を受け、 0 件を返していた。search_ops と同じ門を通す。
- L1777 (ja) — ★2026-10-11: params が配列 / 文字列、name が配列 / dict のとき、.get や辞書引きの AttributeError / TypeError が run_stdio_server のループまで抜け、サーバが死んでいた (後続の正しい要求にも返事が無い)。型は境界で検査して -32602、残りは最後の網で -32603。
- L1824 (ja) — ★2026-09-20(GenSpark 第 38 報 N135): 「2390 names」が op 数と読まれた —— 数えているのは op 名 + HALCON 別名。
fullseye/xlsxio.py
- L46 (ja) — ★ float64 に直してから [0,1] に clip すると uint8 の 0..255 が 0/1 の 2 値に潰れた
- L51 (ja) — ★ 切り捨ての int() だと 1000 px が step 3 で 334 px になり longest を守らない
- L68 (ja) — dict の表は key / value の 2 列(mdio と同じ)。★ list(dict) はキー文字列の 列になり、1 文字ずつのセルに綴られていた
fullseye_comm.py
- L393 (ja) — ★CRC は公表された検査値で裏を取る。CRC-16/MODBUS の諸元は
width=16 poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37(CRC catalogue)—— check は ASCII "123456789" の CRC である。 自分で作った入力の往復だけで試すと、反射入力と反射出力を同時に取り違えた実装が 緑になる(自分で包んで自分で開けるので、向きの誤りが打ち消し合う)。 外の値と突き合わせて初めて、線の向こうの装置と話が通じることが言える。
- L641 (ja) — ★表は 1 つに畳む —— 同じ PDU 処理を RTU の装置役 (:class:
ModbusRtuLoopback)でも使う。2 つ書くと、FC を足した ときに片方だけ増える。
- L751 (ja) — ★
modbus-rtu は 2026-09-25 まで「名簿に載るだけ」の行で、開こうとすると 「pymodbus を入れて直接使え」と断っていた。だが RTU は Modbus TCP と同じ PDU を別の框で包んだものにすぎず、その PDU の組み立てと解釈は既にここに在って 単体試験も付いていた。足りなかったのは框(アドレス + CRC)と線の口だけで、 断り続ける理由は無かった —— 名簿は「持っていないもの」だけでなく、 「持っているのに繋いでいないもの」も隠す。
- L764 (ja) — ★断り文句が「install ‘None’」と言っていた。
cclink は pure-python の master が存在しないので pip 名も import 名も持たない —— そこを場合分けせずに 書式へ流し込んだ結果、open_channel("cclink") は 「install ‘None’ and use the None client directly」と答えていた。 入っていないものを名指しする口は、名指しできない相手で必ず崩れる。 2026-09-25、device.open_driver を足すときに同じ分岐を書いて気づいた(隣の 層を直したら、元の層を読み返すこと)。
- L771 (ja) — ★もう 1 つ: 相手が入っているときに「install しろ」と言っていた。入って いるのに入れろと言う案内は、読んだ人をそこで止める。
- L817 (ja) — ★同梱の顔ぶれをここで凍らせる(名簿を全部登録し終えた後)。これより前に 呼ぶと空を覚えてしまい、
unregister が同梱の protocol を消せてしまう。
g1_policy_bridge.py
- L33 — ★Do not bake a local absolute path into the distribution (in the 2026-09-05 audit, a private sibling project name was riding in the PyPI wheel). Give the default via an environment variable. The scene XML of the Unitree G1. Points to MuJoCo Menagerie’s
unitree_g1/scene.xml.
- L61 — ★Security boundary.
pickle can call an arbitrary callable during load, so passing find_class through means just opening a checkpoint runs code. An RL checkpoint is an artifact meant to be received from others, so this is a realistic threat. (Measured 2026-09-05: the pass-through version returned os.system / subprocess.Popen / builtins.eval directly and could actually create a file during load().) Only the numeric classes actually referenced by a brax PPO checkpoint are listed here. When something is missing, add it to this list (the exception message prints the module name).
gicp.py
- L178 (ja) — ★2026-10-07 レビュー修正: 小角線形化 R ← (I+[ω]×)R は原点まわりの回転なので、原点から 遠い点群(オフセット 1e3 で回転誤差 20°)では回転と並進がほぼ縮退して誤った姿勢に落ちた。 target の外接箱の中心 c へ両点群を寄せて解き、t = t’ + c − R·c で世界へ戻す (外接箱の中心は点の順に依らない = reproducible=True のビット一致を保つ)。
glassmirror.py
- L44 (ja) — ★2026-10-15 から既定ではない(
source="table" で選んだときだけ使う)。実測の表との色差は 法線入射で Cu ΔE*ab 8.3 / Au 6.6 / Ag 2.7 / Cr 0.6 / Al 0.2 —— 銀は青が 0.91 に落ちて黄ばんで いた(実測では 0.98 でほぼ中性)。以前の図を同じ値で再現したいときのために残す。 それでも「銀はほぼ中性で最も明るい / 金と銅は 500 nm 付近で立ち上がる赤黄色 / アルミはやや暗いが平坦」という色の順序は正しく出る(テストで固定)。
- L324 (ja) — 多重反射の和は偏光ごとに取ってから平均する。★ 以前は Rs と Rp を先に平均して 1 本の R で和を取っていたので、斜め入射で透過率を過小評価した(air→1.5、 60° で 0.836 対 正しい 0.848)。垂直入射では Rs = Rp なので値は変わらない。
glyphops.py
- L44 (ja) — ★2026-09-18: ここまで all に無かった(api 側は名前で import していたので 気づけなかった)。一次情報は all なので、公開するものは全部書く。
- L308 (ja) — ★リングの内径は字のにじみの外に置く。にじみ(アンチエイリアスやぼけ)の 中を背景として数えると、地色と文字色の中間が混ざって多峰に見える —— 実測で、ぼけ σ=1.2 の合成看板が背景の集中度 0.52〜0.60 になり、 平坦な単色の地なのに「置換できない」と断った。内径は呼び出し側が
edge_transition_width から決められる。
- L324 (ja) — ★「同じ量子化ビンに入った割合」で集中度を測ってはいけない —— 実写では 最頻色がビンの境目にまたがって割合が半分になり、平坦な看板の地色まで 多峰と判定した(実測で前景の占有率 0.31〜0.64、閾値 0.5 では全滅)。 最頻色からの距離が許容幅に入る割合で測る。同じ実写で 0.87〜1.00、 合成した赤い縁取りでは 0.63 と、はっきり分かれる。
- L342 (ja) — ★縁取りは最頻色の占有率では捕まらない —— 縁が太ければ字のすぐ外は「縁の色一色」で 立派に単峰になる(実測で赤い縁取りを単峰と 判定した)。近いリングと遠いリングの色が 違うかで見る。違えば背景は 1 色では書けない。
- L456 (ja) — ★消す範囲もにじみの幅から決める。2 値マスクは字の芯しか覆わないので、 固定の 1 画素だけ広げて塗ると、旧字の灰色の縁が幽霊として残る (実測: 置換した字の周りに旧字の輪郭がうっすら見えた)。
- L462 (ja) — ★平均色で塗るだけでは継ぎ目が見える。地にはノイズと量子化のざらつきが あり、塗った面だけが滑らかだと矩形が浮く(実測: 置換した字の周りに はっきりした四角が出た)。地のばらつきも測って合わせる。
- L475 (ja) — ★触る必要のある画素だけに限る。塗った面の外は入力のまま残す —— でないと、消去した矩形の縁が地のざらつきと食い違って四角い継ぎ目が 見える(実測: 置換した字の周りにはっきりした枠が出た)。 境目は少しぼかして、切り替わりを見えなくする。
- L501 (ja) — ★極性は多数決で決めてはいけない。行に密着した帯では字が 57 % を占める ことがあり(実測 2026-09-17、合成の掲示の 1 行目)、「インクは少数派」と すると白黒が丸ごと反転して距離が 0.025 -> 0.121 に跳ねた。 外周は背景という事実で決める —— 字は縁まで届かない。
- L836 (ja) — ★大きさは行で 1 つに揃える。マスごとに元の字のインク幅へ合わせると、壊れた字の 広い/狭いをそのまま引き継いで字の大きさがばらつく(2026-09-18、縦書きの試作で ユーザー指摘)。CJK は正方なので、一辺 = min(行のインク高さ, マス幅の中央値)。
- L1031 (ja) — ★マスを少し広げて切り出し、その中で「このマスに属する成分」だけを マスクにする。マスちょうどで切ると、外周リングが隣の字のインクを 拾って「色が多峰」と誤判定し、直せるものまで断ってしまう (実測 2026-09-17: 壊れた 4 字のうち 3 字がこれで断られた)。 また隣の字のはみ出しが消し残り、置換後に旧字の切れ端が浮く。
- L1036 (ja) — ★上下左右に余白を付けて切り出し、その中で「このマスに属する成分」だけを マスクにする。bbox ちょうどで切ると、背景色を測る外周リングが 隣の字のインクと字の縁を拾い、「色が多峰」と誤判定して 直せるものまで断る(実測 2026-09-17: 壊れた 4 字のうち 3 字が これで断られ、背景色の占有率が 0.49〜0.57 に落ちていた)。 余白は画像そのものから取る —— 行の bbox は字に密着しているので、 bbox の中だけでは純粋な背景が手に入らない。
- L1101 (ja) — ★色が多峰(縁取り・影)で断ったマスがあると、インクのマスクに縁まで入って距離が 膨らむ(実測: 5 px の縁取りで無事な 4 字が全部「床の 2.5 倍」に出て unrelated に 化けた)。測れていない距離で誤字/別物を言わない。
- L1148 (ja) — ★2026-09-18: ここを「大津 + 外周で極性」に替えて退行した(既存 12 枚で 見逃し 0 -> 6、誤検出 4/14 -> 9/22)。出荷済み
_ink_mask と同じ規則でも、 1 マスに当てるのと画像全体に当てるのでは別物 —— 全体の大津は壁や板の 明暗で閾値が動き、字の縁を取り込む。固定の暗さ閾値に戻す。白字の看板は この経路では取れない(既知の穴として記録)。
- L1164 (ja) — ★枠 = 中身が薄く、大きく、他の成分(字)の外接箱よりずっと大きい成分。3 つ目の 条件は 2026-09-18 に足した: 無いと、小さな画像(280x432)で 96 px の「中」(外接箱 9216 px > 画像の 2 %、中身 0.3)が枠と見なされ、行が丸ごと消えた。PoC を育てた 1,000 px 級の画像では字が 2 % を超えないので見えなかった尺度依存。「画像の半分以上に 渡る」で切ると生成ポスター 10 枚で誤検出 5/8 → 7/8 に退行した(半分に届かない枠の 切れ端が残る)ので、字の大きさ(成分の外接箱の中央値)を物差しにする。
- L1180 (ja) — 行は水平投影の帯で取る。★成分をまとめる方法は使えない —— 漢字は部品に 分かれて出る(
電 は 3 つ)ので、重なりや中心距離で束ねると行間の狭い 看板で 2 行が 1 行に融け、逆に離れた部品が 3 行目になった(実測 6/12 枚)。
graphinv.py
- L793 (ja) — ★2026-10-07: kmax = 0 の個体(辺 0 本など)は「0-core = 全員」を最内殻にして全ノードを数えていた (三角形 2 個体 + 空 1 個体で appearances [3,3,3,1,1])。殻が無い個体は誰も含まない。
halcon_coverage.py
- L93 (ja) — ★2026-10-06: 正本は同梱の fullseye/data/(c5268029e で移した)。旧来の data/ だけを見ていたため、 facade の 600 本が黙って数えから落ち、HALCON 対応が 982 → 388 と出ていた(例外も警告も無し)。
honest_summary.py
- L34 (ja) — ★wheel には data/halcon_operators.json を同梱しない(MVTec のリファレンスの説明文を含むため。 名前だけは halcon_names_data として出荷している)。
fullseye coverage が FileNotFoundError で落ちていた (GenSpark 第 6 報 N5)ので、無いなら何が要るかと数字の在処を言って終える。
- L68 — ★Exclude auto ops that FAILED the functional gate from the headline — they were previously only [warn]-printed while still counted, inflating the “functionally gated” parity number with ops the gate rejects.
- L87 — ★2026-09-08: This line read – “= %d evolvable registry ops + %d n-ary capability ops (disjoint).” Measured, 979 + 17 = 979, i.e. the 17 n-ary ops are a subset of
reg_counted (nary_names - reg_counted is empty). The heading’s 979 is correct, but the breakdown line alone looks like ‘addition’, and a reader adding it gets 996. The numbers agree yet the explanation lies, so it was fixed. Whether the breakdown holds as a sum is checked every time by tests/test_honest_summary_arithmetic.py.
illusion.py
- L290 (ja) — ★周りの円は互いに重ならないように置く。n 個を半径 rs の環に並べるとき、 隣どうしの中心間距離は 2rssin(pi/n) なので rs > rr / sin(pi/n) が要る。 最初これを守らずに (rs=62, rr=46, n=6) と置いたら、周りの円が融合して 花のような 1 つの塊になった —— エビングハウス錯視になっていない。
imgevolve.py
- L48 (ja) — ★module / requires(2026-09-19): 「unknown operator」が backend 不足を隠していた (外部レビュー #1)。索引が出自と optional 依存を持てば、core 環境の
api._resolve が同梱の複製(fullseye/data/OP_INDEX.json)から不足 extra を 案内できる。requires は AST で静的に読むので、生成環境に依らず同じ値。
- L57 — ★Do not swallow it (adversarial review 2026-09-06).
imgops_nary is a primary module needing only numpy and scipy, so a failed import means a ‘broken checkout’, not ‘a feature absent in that environment’. Previously it was except Exception: pass, and because this function serves as both generator and checker, CI could publish an index with all 17 ops vanished while staying green.
- L81 — ★2026-10-24: IMREAD_COLOR / IMREAD_GRAYSCALE alone demote a 16-bit file to 8 bits (cv2 drops the low byte) and the result was then divided by 255. IMREAD_ANYDEPTH keeps the samples; scaling follows the decoded dtype.
- L158 (ja) — ★2026-09-20(GenSpark 第 37 報 N131): 台帳 op(
color_lut)と汎用アルゴリズム(quicksort)は索引に 載っているのに has が「unknown」と答えていた —— 発見面(索引)と判定面(registry + nary)が別だった。 索引(同梱複製)の台帳行と algo 層をここで引く。
- L356 (ja) — ★os.path.basename は実行 OS の区切りしか知らない —— Linux では
C:\\...\\fullseye.exe が丸ごと 1 要素になり 「fullseye で始まらない」と判定された(手元 Windows 緑・CI Linux 赤)。両方の区切りで最後の要素を取る。
- L363 (ja) — ★parity.main() は自分で sys.argv を読む —— サブコマンド名 “parity” が残っていると 「unrecognized arguments: parity」で落ちていた(GenSpark 第 6 報 N6)。accel / bench と同じく argv を差し替える。
- L401 (ja) — ★2026-10-18(外部レビュー 0.6.0 N228 の再現で見つけた): color 層は OpenCV が要る(extra
opencv)。 素の pip install fullseye では空が正しいのに、ここが無条件に assert していたので fullseye index が AssertionError で落ちていた。黙って空になるのを止めたいのは OpenCV が在るときだけ。
- L463 (ja) — ★2026-10-18(外部レビュー 0.6.0 N228): checkout の判定が「HERE に docs/ が在るか」だけだった。wheel の HERE は site-packages そのものなので、別のパッケージが site-packages/docs/ を置いていると、そこへ OP_INDEX.json を書きに行く(読み取り専用の環境では落ちる)。checkout にしか無い正本の組で判定する。
- L546 (ja) — ★2026-09-20(GenSpark 第 53 報 N187、再現): –seq 無しは空列を「ソートして」[] を印字し rc 0 だった。
- L655 (ja) — ★help の実行例(2026-09-19、GenSpark 第 6 報 N9 / K2): 配布物では console_script
fullseye が入口で、 py -3.11 imgevolve.py は checkout 専用の綴り。呼ばれ方に合わせて例文を書き換える。
- L665 (ja) — ★2026-10-18(外部レビュー 0.6.0 N217):
fullseye algo list に倣って fullseye ops list と打つと rc=2(unrecognized arguments)だった。list は既定の動作と同じなので、語として受けて同じものを出す。
imgforensics.py
- L192 (ja) — ★ complex は ComplexWarning だけで虚部を捨て、実部のハッシュを返していた。 文字列・object も同じく受け取らない
- L706 (ja) — ★2026-10-18: 受けるのは 2-D の uint8 だけ。float の [0,1] を渡しても古い Pillow は mode=”L” で生のバイト列を 読み替えて黙って通し(画素値は意味の無い数になる)、Pillow 13 で初めて “Invalid mode for data type” で落ちた。 試験 1 本がこの経路で無意味な入力を 1 か月使っていた。型を確かめてから渡す(mode は dtype から決まる)。
imgio.py
- L99 — ★Two criteria (2026-09-08, fixed within the same day). At first the choice used only ‘CIE L* has 0 reversals’, but
poc_colormap_readability measured that cividis raises a colour-difference ridge despite 0 reversals. Even with monotone lightness, if the colour-difference spacing is uneven a nonexistent boundary appears in a smooth field – it had claimed to be ‘safe’ on a one-sided criterion. Measured (512 steps, max / median of adjacent colour difference, and the count of local maxima exceeding 1.6x the median): ========== ========== ============== ========== Map / L* reversals / dE max/median / ridge count ========== ========== ============== ========== 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 was dropped because this repo’s approximate LUT is coarse, not a problem with the published cividis itself (its 6 control points are the fewest among the sequential maps). For those who want to choose with colour-vision deficiency in mind, :data:CVD_SAFE is provided. tests/test_pseudocolour_family.py measures both criteria every time.
- L124 — Maps said to keep their order readable even with colour-vision deficiency (P/D type). ★
cividis’s approximate LUT has 6 control points and a coarse colour-difference spacing, and does not meet the :data:PERCEPTUAL_SAFE criterion (measured dE max/median 2.23). Adding control points would let it enter both – since hand-copying primary-source values has a prior record of typos, this is held until the source can be confirmed.
- L712 (ja) — ★2026-10-18(外部レビュー 0.6.0 N209): 順は save(path, arr)。逆に呼ぶと「path must be … got ndarray」で 止まってはいたが、逆順だとは言わなかった。配列が path に、文字列が arr に来たら、それを言う。
-
| L721 (ja) — ★2026-09-20(GenSpark 第 34 報 N120): PFM は float 専用の形式なのに、既定の 8 bit 経路が 0..255 の 値を float32 として書き、読むと 0..1 に clip されて別画像になっていた(往復 max |
Δ |
0.98)。 PFM の既定は float(無損失)。 |
- L915 (ja) — ★2026-09-20(GenSpark 第 18 報 N78): 無い・ディレクトリ・読めない、が全部同じ文だった。
imgmetrics.py
- L151 (ja) — ★2026-09-20(GenSpark 第 23 報 N92): 配列なしで呼ぶと空集合の pop(KeyError)/ 0-d の float() (TypeError)という内部の文が出ていた。
- L163 (ja) — ★2026-10-11: 符号付きの幅を最大値(int16 = 32767)にしていて、skimage の peak_signal_noise_ratio(data_range = iinfo.max - iinfo.min = 65535)と 6.02 dB ずれた。 幅は dtype が取りうる全範囲。符号なしは max - 0 で従来と同じ。
matappear.py
- L167 — ★Passing a 0-dimensional (scalar) value made
r.shape[-1] throw a bare IndexError (caught in the adversarial audit of 2026-09-04). A spectral reflectance has at least a wavelength axis – a scalar is not ‘a value per wavelength’, so the guard explicitly refuses it.
- L273 (ja) — ★ 範囲外は黙って clip せず拒否する(cos=5 が垂直入射、cos=-0.5 が全反射に化けていた)。 丸めの屑(1 + 1e-15 など)だけは許す。
- L349 — ★A real grating diffracts on both sides (if the grooves are symmetric, the +/-m efficiencies are nearly equal). If you do not include both +/-, then depending on the geometry of light source and line of sight all solutions can be negative, and the ‘keep only positive lambda’ filter drops everything and goes pitch black. Measured: a CD illuminated perpendicular to the grooves (delta-sin = -0.55) had m=+1,+2 all vanish at lambda<0, and the 440 nm of m=-2 was the real answer.
match3d.py
- L344 — ★2026-09-07: Replaced with numpy’s FFT. The formula is the same (float32 fftn -> phase only -> real part of ifftn -> argmax), and there was nowhere it needed torch. On CI without torch (py3.10 / 3.12) this op became an ImportError and the PoC failed.
-
| L1048 (ja) — ★2026-10-07 レビュー修正: 境界 voxel は占有側の 1 層なので、iso 面より平均 |
n |
₁/2 voxel 内側(勾配 n の向き = 高い値の側)にある(軸平行で 0.5、斜めで最大 0.87)。d が系統的に その分ずれていた。各 voxel を − |
n |
₁/2·n だけ iso 面側へ戻してから投票する。 実測(40³、真の法線、半 voxel ずらし 10 通り×表裏): 軸平行の平均誤差 ±0.5 → 0.000、 斜め面は投影の離散化で ±0.3 以内が残る。 |
-
| L1110 (ja) — ★2026-10-07 レビュー修正: 境界 voxel は占有側の 1 層で、iso 面より平均 |
n |
₁/2 voxel 内側(勾配 n の向き)にある。半径が明球で −0.6、暗球で +0.6 voxel 系統的にずれていた。 各 voxel を − |
n |
₁/2·n だけ iso 面へ戻してから投票する(明球・暗球どちらでも同じ式)。 実測(48³、半径 7〜13、中心を半 voxel 内で乱した球): 平均誤差 明球 −0.64 → +0.17 / 暗球 +0.57 → −0.15 voxel (残りは丸め投票と放物線補間の偏り)。 |
- L1794 — ★2026-09-07: Rewrote the body in numpy. This ICP is nearest-neighbour search by cKDTree and pose update by a 3x3 SVD, with not a single task for torch, yet it made torch mandatory. On CI without torch (py3.10 / 3.12), 4 PoCs fell with
ImportError: this operator needs the optional 'torch' backend and it surfaced (with torch present locally it went unnoticed – a case of ‘put the gate where the accident happens’). The numbers are the same float64 formula, so the result does not change with the environment. The return type is kept for compatibility: torch.Tensor if torch is present, numpy.ndarray if not (values identical). If a device other than “cpu” is requested, fail-closed.
- L2029 — ★2026-09-07: Rewrote the body in numpy. Nearest-neighbour search, the 6x6 normal equations, and Rodrigues are all small CPU linear algebra with no need for torch, yet it had been made mandatory. On CI without torch (py3.10 / 3.12) the PoC fell with an ImportError and it surfaced. The formula is the same float64, so the result is unchanged (the difference from the torch version was measured as 0 in R/t and 0 in RMSE).
- L2044 (ja) — ★2026-10-07 レビュー修正: 小角線形化 R ≈ I+[ω]× は「原点まわり」の回転。原点から遠い 点群(UTM 座標など、オフセット 1e3 で回転誤差 23°)ではてこの腕 p が巨大になり、 回転と並進の自由度がほぼ縮退して Gauss-Newton が誤った姿勢へ収束していた。 dst の外接箱の中心 c へ両点群を寄せてから解き、最後に t = t’ + c − R·c で戻す。 外接箱の中心は点の順に依らない(reproducible=True のビット一致を保つ)。
-
| L2915 (ja) — ★2026-10-07 レビュー修正: 未中心化の |
p |
² は原点から遠い点群(オフセット 1e6)で桁落ちし 半径が 7.5e5 も狂った。重心へ寄せて解き、中心を戻す(数学的には同じ解)。 |
- L3069 — ★2026-09-07: fail-closed if the ring is outside the image.
r_in/r_out are in pixels, so passing them in mm reads outside the field of view and returns all 0 with no exception (surfaced when poc_pipe_wall_loss produced one pitch-black figure). If not a single radius is inside the maximum distance from the centre to the image’s four corners, the return can only be empty.
- L3080 — ★2026-09-07: Replaced grid_sample (bilinear, align_corners=True, zeros padding) with scipy’s map_coordinates(order=1, mode=”constant”, cval=0) – the same bilinear interpolation, and it runs even on CI without torch (py3.10 / 3.12). The measured difference is at most 6.0e-06 (random image over the range 0..1; the rounding difference between float32 and float64).
- L3129 — ★2026-09-07: Replaced with map_coordinates for the same reason as polar_unwrap (bilinear, out-of-range 0). Runs even without torch. The measured difference is at most 7.6e-06.
- L3260 (ja) — ★2026-10-07: 瞳の中心・半径を外から渡せるように(既定は従来どおり)。
- L3474 — ★2026-09-07: Replaced affine_grid + grid_sample (align_corners=False, zeros padding) with numpy coordinate computation + scipy’s map_coordinates(order=1). torch was used only for the bilinear resampling, and in an environment without torch (CI py3.10 / 3.12) this op became an ImportError. The convention was carried over verbatim: the normalized coordinate of an output voxel (d,h,w) is ((i+0.5)/N)2-1, and after rotation it is mapped back to input pixel coordinates by (g+1)/2N-0.5 (the align_corners=False definition). The last axis of grid is in the order (x, y, z) = (W, H, D). The measured difference from the torch version is at most 7.6e-06.
materials.py
- L977 (ja) — ★X 線の列の op 4 本の台帳は
opstomography の spectral_xray(dualxray と同じ族)。materials.__all__ は opsoptics の matprop 台帳と 1 対 1(tests/test_materials.py)なので、ここには足さない —— 足すと matprop の登録と食い違い、統合で他の作業(電子線の列)と同じ行を取り合う。
- L1146 (ja) — ★引き先は「NIST の化合物の表の名前」か「化学式」だけ。化学式を名前として引き直すと、化学式と 同じ名前のレコード(BI4GE3O12、CDWO4)が自分自身に戻って無限に再帰する(2026-10-23 に実際に踏んだ)。
mathestimation.py
- L90 (ja) — ★床(eps)は q がちょうど 0 の所だけに掛ける。最初は q 全体を np.maximum(q, eps) で床上げしていて、 1e-49 のような小さな q が 1e-12 に持ち上がり p より大きくなって、KL(p‖p) が −3e-10(負!)になった (KL ≥ 0 の門で 2026-10-03 に捕まえた)。
- L256 (ja) — ★2026-10-07: ±inf は欠測(NaN)と区別する。以前は黙って欠測扱いで更新を飛ばしていた。
- L365 (ja) — ★2026-10-07: acos は π の近くで桁落ち(π−1.5e-6 で ω の誤差 4e-4 rad)→ 角は atan2(sinθ, cosθ)、 π の近くの軸は対称部 (R+Rᵀ)/2 = cosθ I + (1−cosθ) a aᵀ の最大対角の列から、符号は歪対称部から取る。
mathgeometry.py
- L228 (ja) — ★最初は発散を np.gradient(中心差分)で取り、Poisson を 5 点 Laplacian で解いていた —— 2 つが互いの随伴でなく、 縁で発散の総和も釣り合わず、隅で距離が真値の 0.52 倍に縮んだ(2026-10-03)。同じ G から両方を作ると Poisson は「勾配が X に最も近い φ」の最小二乗そのものになり、縁(断熱)でも無矛盾になる。
- L251 (ja) — ★熱の段は直接法で解く: u は距離とともに e^{−r/h} で 1e-30 まで落ち、遠くの勾配の「向き」はその極小値の 相対精度に乗っている。CG は絶対誤差 ~1e-12 で止まり、極小値を塗りつぶして遠くの向きを壊した (3-D で誤差 0.045 → 0.279、2026-10-03)。定数のずれが無害な Poisson の段だけ CG にする。
- L307 (ja) — ★2026-10-07: 面に使われない頂点が 1 個あると M と L にその行が 0 で入り、熱の段が特異 → 全頂点 NaN (513 頂点で例外なし)。始点と繋がらない成分は φ が任意の定数(実測 0.755)で有限に見えた。 始点を含む連結成分だけで解き、残り(未使用・非連結)は inf にする(geodesic_heat_grid と同じ約束)。
- L356 (ja) — ★2026-10-07: 始点が別々の成分にあると φ の定数は成分ごとに任意 → 成分ごとに始点で 0 に合わせる
mathnumerics.py
- L258 (ja) — ★2026-10-07: 重みを差の直接の積で作ると、Chebyshev 1200 点や区間 [0, 1e-4] で 積が 0 / inf に飛び全点 NaN になっていた。重みは共通の定数倍を除いて決まるので、 対数で和を取り最大で正規化してから exp する(符号は別に数える)。
- L425 (ja) — ★2026-10-11(台帳契約の門): 係数表でない table({pre, post} など)を渡すと生の KeyError: ‘coeffs’ が漏れていた。何が足りないかを名指しして拒否する(fail-closed)。
- L441 (ja) — ★2026-10-07: list も格子扱いしていたので、d 点 x d 次元の点列 [[x, y], [x, y]] が ndarray なら点ごと、list なら外積格子と、同じ数値で答えが変わっていた。格子は tuple のみ (文書の呼び方
(gx, gy) は tuple)、list は ndarray と同じく点 (M, d) として読む。
mathops.py
- L114 (ja) — 定理が門になる図(2026-09-23)。★
MATHOPS(台帳が読む一覧)と __all__ (import * の公開面)は別物で、両方に書かないと片方だけ通る。
- L1734 (ja) — ★既存の cplx_* は閉曲線を点列で持つ層(積分・巻き数・ローラン・等角写像)。# ここで足すのは領域の層 —— 値の場・位相彩色・ニュートンの吸引域・ # 脱出時間・翼まわりのポテンシャル流。新しい語は 1 つも作らない # (cimage / rgbimage / labels2d / mask / roots / signal はすべて既存)。 # 真値は「使った式」ではなく、偏角の原理・Cayley の定理・主カージオイドの # 閉形式内部判定・c=0 のジュリア集合(単位円板)・そして既存 op である # cplx_winding_number / cplx_cr_residual / cplx_joukowski / poly_roots。 # ————————————————————————— #
- L2206 (ja) — ★もう一方の臨界点 -b は円の内側になければならない。外に出ると dz/dzeta = 0 が流れの領域に現れ、そこで速度が発散する(翼でなく尖りが 2 つある図形になる)。
-
| L2319 (ja) — ★どれも「きれいな図」だが、採ったのはきれいだからではなく、 正しさを定理が言えるからである。数学の図はきれいなので、合って いるかを誰も確かめない —— だから絵の外に真値を置く: circle_packing_apollonian デカルトの円定理(厳密な代数等式)+ 整数充填 ford_circles 接するのは |
ps - qr |
= 1 のときに限る(整数で厳密) phyllotaxis_pattern 隣の番号差がフィボナッチ数(黄金角のときだけ) ifs_fractal モランの式 sum r^d = 1 と、既存 fractal_dimension space_filling_curve 4^n 点をちょうど 1 回ずつ・隣は必ず距離 1 相棒(neighbour_index_gaps / ifs_similarity_dimension / curve_locality)は 主張を数にする側で、これが無いと「それらしい絵」しか残らない。 ————————————————————————- # |
- L2432 (ja) — ★四つ組の最後が「直前に生まれた円」。それを落とす反射は親をもう一度 作るので、種の四つ組だけ 4 方向、以降は 3 方向に進む。ここを間違えると depth 3 で 56 個のはずが 88 個になった(実測。一意な円は 56 のままなので、 絵は正しく見えるが同じ円を何度も描き、以降の段が指数的に太る)。
- L2773 (ja) — ★2026-10-07: 縮小しない写像(r >= 1)を黙って通すと二分法が上端 8.0 に張り付き (r=1.2 の 2 枚で 7.99999…)、恒等写像 1 枚では 0 を返していた。Moran の式は 全写像が縮小(r < 1)のときだけ意味を持つので、ここで明示的に拒否する。
- L2782 (ja) — ★2026-10-07: 写像の数が多いと解が 8 を超えうる —— 上端を広げてから二分する。
- L2850 (ja) — ★ムーア曲線 = ヒルベルト曲線 4 本を輪に閉じたもの。四分割の向きと進む方向は 総当たり(8 対称 x 反転、4096 通り)で「継ぎ目 3 か所と折り返しが全部距離 1」を 満たす 32 解を出し、その 1 つを固定した。手で置くと隣接条件が静かに壊れる (最初の実装は隣接 False・閉 False のまま、絵としては正しく見えていた)。
- L2956 (ja) — ★クラドニ図形は「板」ではなく膜の解である。よく見る coscos - coscos は ヘルムホルツ方程式 + ノイマン境界の膜のモードで、実際のクラドニ板は 重調和方程式に従う別物。砂が節線に集まる絵は同じでも周波数比は合わない。 ここでは膜と明記し、膜の真値(閉形式の固有値・ベッセル零点)だけで採点する。 干渉と回折の真値は既存 op(grating_wavelengths / fraunhofer_pattern)。 ————————————————————————- #
- L3046 (ja) — ★2026-10-07: 矩形は [0,1] x 0,aspect。以前は y を [0,1] で取りつつ n pi y/aspect を 使っていたので、aspect != 1 で y=1 の辺が境界条件(Dirichlet なら 0)を破っていた。
- L3054 (ja) — ★2026-10-07: Dirichlet(sin x sin)は m=0 か n=0 で恒等的に 0 —— 全ゼロの場を 「固有モード」として返していた。拒否する。
- L3059 (ja) — ★2026-10-07: 組合せ (m,n)-(n,m) の 2 項は aspect != 1 だと固有値が pi2 (m2 + n2/a2) と pi2 (n2 + m2/a2) で異なり、和は固有モードでない。
- L3128 (ja) — ★2026-10-07: 以前は「集めた数が c+8 を超えたら止める」で、低い次数(m=0..2)の 高い零点ばかり集めて m>=3 の低い固有値(j’{3,1}**2 = 17.65 …)を落としていた。 j’{m,1} は m について単調増加なので、次の次数の最初の零点が、集めた中の c 番目を 超えた時点で打ち切れば取りこぼしは無い。
- L3327 (ja) — ★真値は公表値か閉形式だけ: 線形系は expm(At)x0 が厳密解で刻み半分に すると誤差が 1/16(4 次)、Lorenz のリアプノフ指数の和はトレース恒等式 により厳密に -(sigma+1+beta)、ロジスティック写像の周期倍分岐は 3 と 1+sqrt6、 相関次元は円 1・カントール log2/log3。絵では何も確かめられない。
- L3331 (ja) — ★関数(callable)を引数に取らない —— 型付き台帳は入力を sort で登録し、 連鎖ファザーがデータから引数を組むので callable は載らない。系は族名か係数配列。 ————————————————————————- #
- L3515 (ja) — ★
table は列名 -> 1-D 配列。状態を (S, n) のまま 1 列に入れると型の嘘に なるので、成分ごとの列に開く(x0, x1, … と時刻 t)。
- L3860 (ja) — ★上限は 60 パーセンタイルにしていたが、有界な集合では大きい r で C(r) が 飽和して傾きが下がる(充填した正方形で 1.83、真値 2.0)。飽和の 手前に寄せる。下限は近傍の離散化(雑音の床)を避ける。
measuring1d.py
- L375 (ja) — ★空の表は名指しで拒否する(2026-10-12 の空入力の方針 A)。空 list を空 list で返すと、 測定が 1 件も取れなかったことが mm 換算の後ろで見えなくなる。
- L624 (ja) — ★ここを「もう片端が次数 3 以上」と書いていた最初の版は、実測で 一度も発火しなかった: ヒゲの根元が枝の端点クラスタと 26 近傍で 融合して次数 2 になる配置が普通にあり、その場合に素通りしていた (「刈った」と報告しながら 0 本という、いちばん静かな失敗)。
mesh.py
- L410 — ★ match the whole line: a comment that merely mentions end_header used to end the header there and shift the binary body (silent garbage).
- L655 — ★ A comma is a column separator only when it is the ONLY one on the line. “1,5 2,5 3,5” (decimal commas, European locale) used to be re-split into 6 columns and read as xyz + colour (silently wrong).
meshio_opt.py
- L452 — ONCE from all three. ★ Per-channel, a 16-bit orange scene whose blue stays <= 255 (in 16-bit units) had blue divided by 255 -> 0.78 instead of 0.003.
metrics3d.py
- L373 (ja) — ★2026-10-07 レビュー修正: md=None(軸方向は無制限)で球の半径を r にしていたため、 実際は「半径 r の球」で切り取っていた(面が法線方向に r 以上動くと両側が揃わず nan)。 無制限の円筒は球で絞れないので、全点を候補にして軸・半径で判定する。
motionio.py
- L137 (ja) — ★ 値域(ptp)最大の単調列を時刻にすると、左→右に掃く縁の x(0..239 px)が 秒単位の t(0..0.1)に勝って x と t が入れ替わった(2026-10-07)。 x・y は画素座標なので整数値。時刻は「整数でない単調列」を優先し、 決まらなければ推測せず拒否する(見出しを付ければ名前で読める)。
occupancy.py
- L230 — ★2026-09-07: Made
res accept per-axis values (length 3 allowed too). Restricted to cubic, a flat volume like a bird’s-eye grid (thin z x wide xy) is forced to use the same spacing even on the unneeded axis (poc_bev_sensor_fusion measured: of 4.096 million voxels only 8.1 % are used). The same-family grid_coords had accepted per-axis res from the start – the mismatch where the contract’s breadth differs at the entrance and the exit was aligned. Existing callers passing a scalar are unaffected.
- L340 — ★2026-09-07: Made
res accept per-axis values (length 3 allowed too). Previously int(res) allowed only a cubic grid, and while esdf accepts a length-3 anisotropic voxel_size, this side – which subtracts its output in world coordinates – was restricted to cubic, a contract narrow on only one side. It jams outright on a grid like CT’s thin junction layer (30,180,180) (measured in poc_ct_void_morphology). Existing callers passing a scalar are unaffected.
octscan.py
- L1238 (ja) — ★窓の端で振幅が下り坂のところは、0 で埋めた外側との段差が「極大」に見える → 元の振幅で極大のものだけ
op_probe.py
- L42 (ja) — ★2026-09-17:
feature を足した。戻りの橋 feature_to_img が入るまで、 2-D 台帳に feature を入力に取る op が 1 本も無かったので代表値も要らな かった。門(knob_liveness / probe_ledger / op_contracts)は 3 本とも 「測れない op が居る」と正しく落ちてこの穴を教えた。
opassist.py
- L56 (ja) — ★2026-10-23: カメラ校正(calib / caltab / fit_transform、21 op)。実装は 2026-08 から あり試験も 30 本超あったのに、台帳が無いので op ノートが 1 枚も無く、fs.ledger / OP_INDEX.json / op_find(“caltab”) のどこからも引けなかった(fs.<名前> は 21 中 1)。 新語なし(points / pose / matrix / table / contour / image2d)。名前>
- L77 — ★2026-09-08: ops1d (dsp 16 + funct1d 23) was registered yet appeared neither in docs nor in op_run / op_assist / op_find – ‘registered’ and ‘reachable’ are different. Adding them to opdocs made this gate ring on the unreachable side.
- L318 — ★Design (2026-09-04, user: ‘It’s better to handle various container types, but consistency matters too’): At first
kind mixed in “seq” and “matrix” – that is, the value type (numeric, integer, or choice) and the container shape (single, vector, or matrix) competed in one field. From the UI’s view an ‘int 3-vector’ could not be expressed, and only matrices had their structure under the seq key, so handling was scattered. This was made orthogonal: kind holds only the value type, and the container always goes into container. A scalar is not made an exception either ({"form": "scalar", "shape": ()}), so the UI can write its branching as a single path.
- L452 — ★Longest match. Scanning shortest-first,
sigma_per_mm matches _mm and becomes “mm” (it is actually 1/mm). Get the unit wrong and the UI’s number silently becomes something else.
- L535 (ja) — ★2026-09-20(GenSpark 第 15 報 N71):
write_wav(path, x, rate) は in=[“signal”] なので、 第 1 引数の path に signal が割り当てられ、op_run("write_wav") が配列をファイル名として 開こうとしていた。パス名の引数は、宣言 sort が “file” のときだけデータ(読む側)で、 それ以外は書き先のパラメータ —— データ型は次の引数へ送る。
- L568 — ★The key point: some arguments do not have their default given as a tuple.
center=None (an optional (row,col)), the required trans (3-vector), k_cam (3x3 matrix)… looking at the default alone they appear to be ‘a single number’, and the UI breaks by showing one spin box. Supplement the structure by name.
- L782 (ja) — ★一様乱数の行列にしない —— 成分・モジュラリティ・rich club は構造が無いと 「どのノブでも同じ数」になり、押して動いても意味のある絵にならない。
- L786 (ja) — llmcore(2026-09-24): ★一様乱数にしない —— どの行も似た向きになり、 注意の重みが全行ほぼ一様になって「押しても何も起きない」種になる。 滑らかな画像を 8x8 パッチに切ると、近い場所が近い向きを向く。
- L802 — ★Found by measurement: passing a generic 0..1 signal into the wavelength input of
prism_min_deviation_deg gets rejected by ‘wavelength must be positive’, making it an op whose sample does not run. If the unit is known, seeding it with a range plausible for that quantity is closer to ‘runs when you press it’.
- L995 — A run of Japanese (CJK) text. ★
_WORD_RE is [a-z0-9]+, so a Japanese query yields not a single word (_WORD_RE.findall(...) == [] on the Japanese input). The stemming stage dies, and because partial match searches for a string that includes the whitespace, a multi-word Japanese query was structurally always 0 hits – in a product whose docstrings are mostly Japanese and that ships in 6 languages. Surfaced on 2026-09-08 when poc_search_sweep_width hit it (the Japanese queries for ‘point detection’ / ‘spot detection’ / ‘small target’ via op_find were all 0 hits, and although sub-pixel-centroid point-target detection is only star_detect, it could not be reached from Japanese).
- L1048 — The common-prefix length treated as a stem match. ★At 4, “median”/”medial” and “contrast”/”contour” get linked; cutting at 5, “correlation”/”correlate” (8), “segmentation”/”segment” (7), “rotation”/”rotate” (5), and “gaussian”/”gauss” (5) are picked up while the two pairs above are not.
- L1058 — The suffix allowed after the common prefix. ★Deciding by prefix length alone links “median”/”medial” (they share a 5-character “media”). Judging whether the suffix looks like an inflectional ending, “correlation”/”correlate” (ion / e) passes, while “median”/”medial” (n / l) and “corner”/”cornea” (r / a) fall out.
- L1154 — ★Floor. Without it, “zzz-nothing-matches” returns
histogram_match (because “matches” stem-matches match_*). If the weight of the matched words is under 15 % of the whole query, it is treated as ‘no match’. Measured: “digital image correlation” is 0.19 (passes), “zzz-nothing-matches” is 0.10 (dropped).
- L1294 (ja) — ★欧文の段(2026-10-15): 欧文のクエリは 1 行目の doc までしか見ておらず、引数の説明にだけ 出る語が 0 件だった —— “orthometric”(標高)は dem_height_frame_convert の frm / to にしか 書かれておらず、op_find(“ortho”) は名前に ortho を含む doe_orthogonal_array(直交表)しか 返さなかった。docstring 全文の部分一致を、どの段より低い点(12)で最後に拾う。
- L1335 (ja) — ★2026-09-19(GenSpark N2):
fullseye.apply([x, y], "add_image") で動くのに、 op_names() にも op_find() にも載っていなかった(op_names は 1 入力のレジストリだけ、 op_find は台帳 + レジストリだけを見ていた)。呼べるものは探せなければならない。
- L1364 (ja) — ★2026-10-18(外部レビュー 0.6.0 の一次検証): op_find(“sgm”) が 0 件で、外部 AI は「SGM は無い」と結論した。 実際には
fullseye.disparity_sgm(Hirschmüller の SGM、census の費用 + 経路集約)が 0.1 系から在り、 fullseye.stereo の族ごとファサードにだけ在る —— 台帳・2-D レジストリ・n-ary のどれにも載らないので、 探す側からは見えなかった([[feedback_search_all_tiers_before_declaring_a_gap]] と同じ型)。 名前と docstring の 1 行目で、他の層より 1 点低く拾う(同名なら op 表の行が勝つ)。
- L1392 (ja) — ★2026-09-20: 何で当たったかを
match に(exact = 名前の完全一致 / name = 名前の部分一致 / stem = 語幹 /
- L1463 (ja) — ★2026-09-20(GenSpark 第 55 報 N200): op_run(img, “gaussian”) が
unhashable type: 'numpy.ndarray'、 op_run(“gaussian”, img) が「not in any ledger」で終わり、registry op は apply で走ることを言わなかった。
- L1483 (ja) — ★2026-09-20(GenSpark 第 20 報 N87): 種を作れない型(mesh / lab / matrix …)は None のまま 関数に渡り、IndexError / AttributeError / AxisError が利用者に届いていた(11 op)。 呼ばずに、どの入力を渡せばよいかを言う。
- L1496 (ja) — ★2026-09-20(N71): データ引数が署名の先頭に無い op(write_wav(path, x))は名前で渡す —— 位置で渡すと 配列が path に入る。データ引数の名前は param_spec が知っている。
- L1506 (ja) — ★2026-09-20(GenSpark 第 34 報 N122、再現): 入力を一部だけ渡すと(blend_mode(base) で top 無し)Python の生の 「missing 1 required positional argument」が届いていた。0 個のときは上で種を作って言うのに、1 個以上のときは 検査が無かった。必須のデータ引数が位置でも名前でも来ていなければ、期待する形を 1 文で言う。
- L1524 (ja) — ★2026-09-20(N87): 自動の数値サンプル(1.0)が座標や行列を要する引数に合わないと、op の中の IndexError がそのまま利用者に届いていた(scene_box の center_mm 等)。自動値が原因なら言う。
ops.py
- L339 (ja) — ★勾配は片側差分の大きい方で取る。
np.gradient の中心差分は 1 画素で 立ち上がる段差を 2 画素に広げてしまい(段差の頂点で 0.5 しか出ない)、 理想の段差が幅 2.00 と報告される —— 測る道具が理想ケースで 2 倍を返す。 片側差分なら段差で 1.0、傾斜 m の斜面でも m となり、どちらも正しい。
- L637 (ja) — ★相対床だけでは足りない: 一様面 + 丸め屑では値域そのものが屑なので、 相対床も屑まで下がってしまう。絶対床 1e-5(画像は [0,1] 契約)を併せる。
- L713 (ja) — ★一様な面では勾配が丸め屑しか残らず、
arctan2 はその屑の符号で任意の角度を 返す —— 明るさを 0.01 変えただけで向きが一斉に変わる。絶対値の床では画像の 明るさに依存してしまうので、必ず相対量で切る。
- L817 (ja) — ★膨張は前景をはみ出す。連続の世界では半径 r の円は収まっているが、離散の 円板で膨らませると境界の外の画素まで塗る —— 実測で前景 197 画素の円に 対し外へ 48 画素(24%)漏れ、そのせいで粒度分布の生存率が 1.0 を超えた。 太さは前景の量なので、必ず前景で切る。
- L1010 (ja) — ★各画素には「入った時点で属していた山」の persistence を入れる。 ここで find(i)(= 最終的な根)を引くと、全画素が最後に残った 1 つの山の値に なってしまう —— 実測で高さ 1.0 / 0.6 / 0.3 の 3 つの山が全部 1.000 になった。
- L1017 (ja) — ★画像の最小値そのものの台地(たいていは背景)は 0 にする。そこは最後に 処理されて全体最大の山に吸収されるので、放っておくと背景一面が最大値に なって地図が読めない(実測で背景が 1.000 になった)。閾値を新たに選ぶのでは なく「最小値ちょうど」だけを落とすので、閾値フリーの性質は保たれる。
- L1109 (ja) — ★
m / n**2 ではなく (m + 0.5) / n**2。前者は値が {0, 1/4, 1/2, 3/4} と なって平均が 0.375 にしかならず、ディザ全体が暗い側へ偏る(1 ビットの傾斜で 平均が 0.031 ずれるのを実測した)。閾値は刻みの真ん中に並べる。
- L1298 (ja) — ★歴史的な挙動を
b <= 0.5 の帯に置く。これらの op の b は 2026-09-17 まで 「未使用」で、保存済みの進化プログラムが持つ b の値は事実上ばらばらに散って いる。新しい選択肢を上半分だけに割り当てれば、およそ半数の既存プログラムは 1 ビットも結果が変わらない(全域に割り当てると全部変わる)。 b <= 0.5 が旧実装とビット一致することは tests/test_knob_b_options.py が固定する。 ————————————————————————— #
- L1312 (ja) — ★境目は 0.5 を含めて歴史側に置く。0.5 は「まん中」として既定値に使われて いて(api.apply の既定、studio の中央、保存済みプログラムの初期値)、ここを 新しい側に入れると既定のまま呼んだだけで答えが変わる。実測で gaussian と その HALCON 別名の一致検査まで割れた。
- L1420 (ja) — ★しきい値は argmax ビンの「上端」で取る(2026-09-26)。中点で取ると、 argmax が指すのは背景の山を含むビンなので、その中点より上に居る背景画素 自身が前景に入る。背景 0.30 / 明部 0.90 の板では 400 px の答えが 4,096 px (全画素)になり、例外も警告も出なかった —— skimage と OpenCV は同じ絵で 400 を返す。ビンの上端で切れば argmax ビンの画素は全部背景側に落ちる。 試験の入力に必ず雑音が載っていたため 30 年物の門が全部通していた (docs/hardening/otsu-threshold-at-the-bin-midpoint.md)。
- L1547 (ja) — ★2026-10-07: 0 画素の面積率は 0/0(np.mean が NaN を返し、guard が黙って置き換えていた)
- L1687 — ★Pad the edges with the edge value. Previously it was
np.convolve(x, k, "same"), which averages the w points at both ends with zero – the start and end of a contour got dragged toward the origin (0,0) by up to 50 px or more, producing a figure where the red streaks of 140 contours converged to the upper left (found 2026-09-06 when per-op figures were first made; in numerical tests the mean deviation was 0.3 px and it was invisible).
- L2283 (ja) — ★pickle は名前で(2026-09-19 外部レビュー N5):
fn は backend_safe._safe のクロージャで pickle できず、Op を丸ごと multiprocessing / joblib に渡すと PicklingError で止まっていた(Pipeline は名前を持つので通る、という非対称)。 復元先は復元する側の環境の登録: backend が入っていない環境で戻すと KeyError(不足 extra の案内つき)になり、黙って別の実装にはならない。
- L2456 (ja) — ★2026-09-19 の外部レビュー(#1): scikit-image 無しの環境で
sk_canny を呼ぶと 「unknown operator」になり、存在しないのか backend が入っていないのかを 区別できなかった。fn は backend_safe._safe に包まれて __module__ を失う ので、登録の側で出自を残す(後勝ち = REGISTRY の重複解消と同じ規則)。 imgevolve.py index がこれを module / requires として索引に書き、 api._resolve が未登録の名前を引かれたときに索引から不足 extra を案内する。
- L2465 (ja) — ★pyproject の optional-dependencies と食い違うと案内が嘘になるので
tests/test_usability_review_2026_09_19.py が突き合わせる。
- L2752 (ja) — ★2026-10-07: 複素の sort は sanitize(実 sort 向けの規約で実部だけを返す)を通さない。 以前は tb_angular_spectrum_propagate / tb_cx_apply_transfer_function / tb_fmcw_window_apply が cimage / beatcube を名乗りながら float64 を返していた(虚部を黙って捨てる = 位相が消える)。 backends_bridge の橋は同じ理由で既に素通しにしていた —— その規約をこちらにも揃える。
- L2767 — ★A ledger of ops that crash the whole process on the native side with a degenerate input (2026-09-05).
guard can only catch Python exceptions. Once something is written out of bounds inside C/C++, it is over there, and the user’s whole pipeline vanishes – the worst way for fail-soft to break. There is no recourse but to reject at the entrance, so list it here with a reason and set a barrier at registration time. Behaviour differs by platform – that is the reason this ledger exists. The 3 below crash on Linux (Ubuntu 24.04 / Python 3.12 / PyPI wheel), but on Windows not one reproduced with the same input. A different native build means the boundary breaks differently, so a fine line of ‘this kind of input is fine’ cannot be trusted – reject degenerate inputs wholesale. Not ‘remove it once fixed’ but remove it once the upstream can be confirmed fixed (this is not our own code, so the removal condition differs).
ops1d.py
- L117 (ja) — ★2026-10-11(台帳契約の門): read_wav / read_audio は (x, rate) を返すのに宣言は signal で、adapter が無かった(io 族は連鎖ファザーの目録から外れていて、誰も 型を確かめていなかった)。resample と同じく本体(x)を取り出す。rate が要るなら
fs.ledger.read_wav.raw(path) か dsp.read_wav(どちらも (x, rate) のまま)。
ops3d.py
- L437 — ★out is not image2d but rgbimage (measured 2026-09-02). Both the docstring and the implementation say ‘RGB (size, size, 3) float [0,1]’, and only this line claimed a 2-D luminance image. This op only ran once a mesh seed was supplied, and the type predicate surfaced it with a TYPEMISS: “declared ‘image2d’ but returned ndarray(512,512,3)” (until then, because of the shape that splits (V,F) into 2 positional arguments, it had never run once). The other 3 render_* ops (ambient_occlusion / cast_shadow / supersample_mesh) are 2-D as measured, so image2d is fine for them – the lie was only this one line.
- L460 (ja) — ★どれだけ細分しても次数 5 の頂点はちょうど 12 個。これは V - E + F = 2 の帰結であって実装の都合ではない(11 個でも 13 個でも 球にならない)。mesh_subdivide は任意メッシュの細分で、正多面体から の構成は持っていなかった。入力を取らない生成 op。
-
L466 (ja) — ★極小曲面と掃引(2026-09-23)。極小曲面は平均曲率 H が至るところ 0 の 曲面で、既存 vertex_curvature がまさにそれを測る —— 「これは極小曲面だ」 という主張を、作り方を知らない op が採点する。カテノイドとヘリコイドは 等長なのでガウス曲率 K が一致するが、それは必要条件にすぎない(門に するのは H)。実測 |
H |
中央値 0.0001 に対し、対照群の単位球 1.00004・ 半径 1 の円柱 0.50000。 |
- L476 (ja) — ★これは節面近似であって厳密な三重周期極小曲面ではない。残差は 隠さず docstring に書く(主曲率スケールの 1 % 程度)。
- L562 (ja) — ★新しい sort は作らない: ノード表と枝表は「単位も意味も違う 2 つの表」で、 タプルで返して adapter に
r[0] と書くと 枝表を黙って捨てる (pose_error / m3c2_distance で繰り返した失敗の型)。1 つの dict に 両方を入れれば宣言 ‘table’ が実返りと一致し、捨てるものが無い。
- L717 — ★Added 2026-09-08. Until then the pose helper for carving (visualhull.look_at) could not be reached from any public layer, and grabbing the same-named render3d.look_at (gluLookAt, -Z forward) resulted in an empty hull without exception (poc_livestock_body_volume).
- L738 (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 に渡ると意味を失う。
- L828 — ★The reason (a) for holding it back – ‘the points candidate list gets shorter and silently overwrites the existing champion’ – is gone now that backends_typed.TYPE_TO_SORT folds coordgrid -> points: the 2-D bridges tb_sphere_sdf / tb_box_sdf carry INPUT_ADAPTERS._points_to_grid and actually build a coordinate field from the point cloud, so their “points” declaration is not a lie (measured: passing (64,3) returns (16,16,16) = alive). The lie was only on the 3-D ledger side.
- L991 — ★axis=1. The canonical form of
pairs is (N,2) (measured: the 6 consuming ops explicitly reject (2,N)). While the predicate was lambda v: True, this produced (2,n) and declared as its type ‘a shape no consumer can accept’
- L1029 — ★The canonical form of position is 3 components [z, y, x]. Decided not by majority vote but by running the consumers: refine_translation_lk / refine_lm fail-closed with “init_pos must have exactly 3 components [z, y, x] (got 4)” when passed 4 components (measured). The generator is also 3 components (8.0, 8.0, 8.0). But the match_* family returns 4 components [score, d, h, w] as per docstring, so flowing it with a declared out of “position” wipes out the downstream refinement ops = a type lie. Since score itself is honest information, the function side is not trimmed (get() stays at 4 components), and the coordinates alone are extracted on the call() side that claims the ledger’s type (the same treatment as project_points).
opsacoustics.py
- L195 (ja) — ★新しい型の語は作らない。積層・A スキャン・C スキャンは kind の印つきの dict(table)で、 印の無い table は消費する 5 op がすべて ValueError で拒む —— 別の族の table を積層として 黙って読む経路が無い。
- L198 (ja) — ★A スキャンを素の signal にしない理由: 超音波で測る量は時刻(深さ = 往復時間)で、 素の 1-D 配列は時刻の原点(表面エコーの手前の窓の始まり)と rate を失う。上の rate の 注記と同じ「例外も NaN も無しに深さが狂う」経路になるので、t と rate を同じ dict に 入れて流通させる(dict の
rf を取り出して acoustics の op に渡すのは呼び手の明示的な行為)。
- L202 (ja) — ★C スキャンの RF の立方体(画素 × 時刻)は返さない: 返すのはゲートの中で読んだ像だけ (振幅・位相・同相・符号つき山・到達時刻)。立方体を image / volume として流せば 「時間の軸を空間の軸として」読む経路ができる(混ぜると黙って嘘をつく)。
- L205 (ja) — ★接合面の地図は既存の labels2d(整数ラベル = 積層の種類)。2 入力なので 2-D の橋は 架からず、1 入力の op の in はすべて table か無し(TYPE_TO_SORT に無い)。
opsastrostack.py
- L85 — ★ Instead, we explicitly reject a raw (N,H,W) ndarray. A 3-D array passes the same structural check whether it is video (T,H,W) / voxel (D,H,W) / histcube (H,W,T) / zscan, so a mix-up raises no exception and returns a “plausibly wrong composite” —— this is exactly the same danger as the photon family separating histcube from voxel. Here, however, we obtained the same defense not by adding a type but by requiring that it “be a list”. The moment you write list(volume), the caller has declared that “the leading axis is the frame axis”. * image2d —— composite, drizzle output, single frame. All are 2-D float64, so existing 2-D ops (filter, threshold, morphology, psf_to_mtf) can be used with their meaning intact. It is not even non-negative (residuals of κ-σ combining and negative fringes of spline interpolation appear), so calling it counts would instead be a lie. * keypoints —— the return of
star_detect is (N, 2) as (row, col). The keypoints in TYPE_CHECKS is “(N,3) or any 2-D array”, so it applies directly and is consumed by psf_fit / aperture_photometry.
-
L101 — ★ This is not pairs: the canon of pairs is the “(x, y) pair” fixed by the 6 ops on the reprconv side, whereas this is (row, col) in image coordinates, following the same convention as fit_transform / mosaic. Mixing them swaps rows and columns (the same shape as this repo’s known trap where features.match_keypoints returns (x,y) while fit_transform requires (row,col)). Calling it keypoints at least shares the promise of “a point on the image”. * indices —— the indices (1-D int) of the adopted frames returned by lucky_select. Exactly the existing vocabulary. [frames[i] for i in idx] returns to images. * measurement —— noise_sigma is a single real scalar. * matrix —— the (3,3) homogeneous transform from frame_align. It is the same thing that transforms / fit_transform / mosaic handle, so there is no reason to invent a dedicated term. * table —— dict / list of dict (quality, PSF fit, photometry). The table in TYPE_CHECKS is list |
dict, so both apply. The cost of not separating (honest): if a non-astronomical image sequence enters the images pool, frame_align finds no stars and halts with ValueError. Since this is fail-closed, it is not “zero findings” but “reached and correctly rejected”, yet from a chained fuzzer’s view the 2 align ops may end up being nothing but CONTRACT. Since the same symptom can appear as the reason the photon family separated counts (7/17 are never executed), if measurement shows this to be the case, then the decision to put “image sequences containing point images” in a separate pool is justified —— we do not preemptively add a type (in this repo the order is: add a type only after evidence emerges that “mixing makes it a lie”). |
opsconngraph.py
- L66 (ja) — 作る —— シナプス表から隣接行列へ、帰無モデル、二値化。★カテゴリ名は docs/ops/conngraph// に なる: "build" は .gitignore の build/ に当たり、ノート 3 枚が commit されず CI だけ赤になった(2026-09-20)
opsdem.py
- L35 — ★ Honest limitation: the
depth pool can also include depth from a camera’s perspective projection. In perspective depth, how many ground meters 1 px corresponds to changes with depth, so a slope computed with a constant cell_size is plausibly wrong. So why not separate the type —— this is not a type mix-up but the same kind of error as giving cell_size wrongly, and cell_size is already a required argument (no default is set). Adding a type cannot prevent non-orthographic depth (the predicate can only see up to “a 2-D real array”), and instead a dem pool with not a single op that has a seed would be created, making all 13 ops permanently unexecuted. Rather than pretending a type prevents what it cannot, we made it explicit with a required argument and docstring, and chose to actually run it in the fuzzer. * only the output of dem_fill_sinks is depth —— the result of filling sinks is still an elevation grid and goes straight into dem_flow_direction. Declaring it image2d here would sever the in-family chain (fill -> flow) by type. * dem_flow_direction is labels —— the return is int8 0-7 and -1 (no outflow target), a sign with no ordering meaning. Calling it mask would treat it as binary, and calling it image2d would make the average of 3 and 4 meaningful. It applies directly to the labels predicate (integer dtype, 1-3 dimensions). * dem_stream_network is binary but image2d —— its content is float64 with 0.0/1.0 plus nan for missing data, and does not satisfy the mask predicate (bool or integer dtype). Making it bool would make “not a channel” and “no value at all” indistinguishable, so we matched the type to the implementation. * everything else is image2d —— slope[deg], aspect[deg], curvature[1/m], hillshade[0,1], relief[m], horizon elevation angle[deg], sky view factor[0,1], visibility[0/1]. All are 2-D real fields, so existing 2-D ops (smoothing, threshold, morphology, pseudo-color, annotation) can be used with meaning intact. The value range is not necessarily [0,1], but that is the same standing as the composite of astrostack: in this repo image2d is used not as a promise of brightness but as a promise of “a 2-D real field”. category -> [(op name, module, [input types], output type)]
opsflyvision.py
- L64 (ja) — ★ 重みは公開しない:
fly_hex_resample の個眼×画素の重み行列は functools.lru_cache で内部にだけ保持し、op の入出力型には現さない —— 出すと「画素座標系に依存する巨大な派生物」が型プールを汚し、下流の 2-D op が それを画像と取り違えて黙って処理してしまう(zscan を video に渡すと通る、と 同じ事故の型)。出さないことでこの取り違えを構造的に不可能にする。
opsgraph.py
- L35 (ja) — ★比べられる数字はヌルで割った比だけ。素の個数は規模で決まる。
- L44 (ja) — ★matrix の束を images に載せない —— 画像を渡すと全画素 > 0 で「全結合が全員に在る」 というもっともらしい嘘を返す。table なら他 op の表を渡しても op が断る。
opsimgforensics.py
- L206 — ★ In the predicate of
phash, checking the dtype is the essence. With only ndim == 1 it completely overlaps the existing signal and the point of separating is lost.
- L208 — ★ The predicate of
fingerprint cannot be distinguished from image2d by shape. It can only be cut by zero-mean-ness, which is a statistical guess at runtime, so the predicate carries the same weakness (that is why we separate by type). Leave this weakness noted in the predicate’s comment.
- L224 — ★ The seed of
fingerprint must always be made through sensor_fingerprint. If you place rng.standard_normal((H, W)) directly, that is white noise, not a fingerprint, and matching will always return “uncorrelated” = you think you added a check surface but you did not.
- L227 — ★ The seeds of
images must be the same shape and 2 or more. With only 1, sensor_fingerprint keeps failing closed and never runs.
- L242 — ★
qualities=None of jpeg_ghost_quality assumes “12 entries of 40..95 step 5”, so unless the seed of images is 12 entries it will always raise ValueError. This is the intended fail-closed (it does not return a map where indices and qualities are misaligned), so match the count on the fuzzer side.
- L246 — ★ The
bits of watermark_* must be at most the capacity (number of 8x8 blocks of LL). A 64x64 image2d + level 1 LL is 32x32 = 16 blocks.
opsinterferometry.py
- L96 — ★ Not piggybacking on the existing
signal was the result of measurement. At first we judged “since csi_signal_simulate ([] -> signal) pours a genuine interference signal into the pool, it is reachable”, but running the chained fuzzer with that wiring, over 600 chains (300 x length 6 + 300 x length 8), csi_peak_position and chromatic_confocal_height were never executed once (only 7 CONTRACT records). The cause is that the signal seed is a sinusoid with negative values, and the probability that the entry op is drawn earlier in the same chain is low. It is exactly the same trap that opsphoton stepped on with counts, and as a result of fail-closed working perfectly, “zero findings” looks like robustness. In a re-measurement under the same conditions with sweep as a dedicated pool, all 9 ops were executed. That mixing the 2 types does not silently pass a mix-up is guaranteed by each having a dedicated discriminator (both thresholds measured in closed form): - passing a spectrum to csi_peak_position -> carrier_tolerance. An interference signal has its carrier at 2/λ (Nyquist’s 0.333), while a confocal peak is at 0.010. The same check catches even a 1000x unit error in measurement. - passing an interference signal to chromatic_confocal_height -> max_carrier_fraction. The AC component of the confocal response is low-frequency only (measured 0.010 / 0.010 / 0.015), while the interference signal is 0.333. Entry = csi_signal_simulate / chromatic_confocal_simulate (both produce with no arguments), exit = csi_envelope (-> signal) and the 2 measurement ops.
opsmath.py
- L97 (ja) — ★閉形式の内部判定。脱出時間の図に「ここは絶対に出ない」を重ねられる。
-
| L102 (ja) — ★定理が門になる図(2026-09-23)。数学の図はきれいなので、合っているかを 誰も確かめない —— ここに入れるのは絵の外に真値があるものだけ。 デカルトの円定理 / |
ps - qr |
= 1 / フィボナッチの斜列 / モランの式 / 4^n 点をちょうど 1 回ずつ。相棒の 3 本は「主張を数にする」側で、 これが無いと「それらしい絵」しか残らない。 |
- L108 (ja) — ★型は
pairs(N,2)。points は (N,3) の 3 次元点で、 最初そちらで登録して型契約の門に捕まった —— 名前が似ているので 取り違えやすい(門が無ければ「もっともらしく間違った」宣言が残った)。
- L123 (ja) — ★波動(2026-09-23)。クラドニ図形は「板」ではなく膜の解 —— 板は重調和 方程式に従う別物で、砂が節線に集まる絵は同じでも周波数比は合わない。膜と 明記して、膜の閉形式(矩形は pi^2(m^2/a^2 + n^2/b^2)、円はベッセルの零点) だけで採点する。干渉と回折の真値は既存 op(grating_wavelengths / fraunhofer_pattern)が独立に持っている。
- L140 (ja) — ★力学系(2026-09-23)。真値は公表値か閉形式だけ: 線形系は expm(At)x0 が 厳密解で刻み半分なら誤差 1/16(4 次)、Lorenz のリアプノフ指数の和は トレース恒等式で厳密に -(sigma+1+beta)、ロジスティックの周期倍分岐は 3 と 1+sqrt6、相関次元は円 1・カントール log2/log3。絵では何も確かめられない。
opsoptics.py
- L232 (ja) — ★真値が閉形式で外部参照が要らない: 恒等フィルタ → 180 度回転、 (i2πf)^n → n 階微分(ガウシアンの微分は閉じた式)、渦位相板の 巻き数が整数。fourier_plane_filter は入力を取らない生成器で、 four_f_filter が場と透過関数を受ける(cimage 2 つ)。
- L243 (ja) — ★ pupil_blur は「画像 × カーネル」の一般畳み込み(filters_freq.convol_fft) ではない —— PSF の標本間隔 λN/oversample を検出器ピッチへ面積積分して から畳む、その単位合わせが本体。だから PSF を作る側に置く。
- L304 — ★ Not normals (the (N,3) normals of a point cloud) but normalmap. The two are similar in shape, but passing (N,3) is rejected by _normal_map with ValueError. Declaring it normals here would be a lie that “you may pass point-cloud normals”, and the chained fuzzer would end in CONTRACT every time and never execute this family (= it turns into zero findings).
- L407 (ja) — ★trace_rays は登録しない: 台帳の trace_rays は optscene が持ち、正準名 lens_trace_rays は窓口(facade)の 別名として予約済み(opnames.FACADE_ALIASES)で、台帳に置くと test_op_names_phase1 の衝突の門が赤になる。 台帳からは ray_bundle / noncoaxial_trace で同じ追跡に届く。refractive_index は別の作業が中を直しているので この回は登録しない(既定の媒質が要る)。
- L538 (ja) — ★新しい型の語は作らない(位相も image2d、統計は table)。
- L539 (ja) — ★2-D の橋(tb_*)は架からない: 1 入力の op は speckle_statistics だけで、その in の image2d は sort
image(_NEW_SORTS の外)、out の table は sort に写らない (2026-10-13 に backends_typed.build の条件で確かめて決めた。_OP_BRIDGE_SKIP 不要)。
- L543 (ja) — ★材料は名前(別名可)かレコード dict で受ける。波長曲線はすべて pairs(λ [nm], 値)= 光源・QE・ ライトガイドの曲線と同じ形(像 = 光源 × 光学系 × 対象 × QE の波長積分へ渡す)。全部が引数だけで 描く側(画像を受けない)なので 2-D の橋は架けない(_OP_BRIDGE_SKIP)。
- L574 (ja) — ★曲線は materials と同じ pairs(λ [nm], 値)。像の明るさ = ∫ 光源 × 光学系・対象 × QE dλ を spectral_product で 1 本ずつ掛けて spectral_integral で積む。QE を掛ける前に energy_to_photons。 画像を受けないので 2-D の橋は架けない(_OP_BRIDGE_SKIP)。
- L597 (ja) — ★膜も基板も材料表(materials)の鍵で指定する。画像(分光の帯域画像)を受ける map も表を返すので 2-D の橋は架けない。
- L605 (ja) — ★レンズの処方(raytrace)と硝材の分散(materials)→ 波長ごとの焦点位置の較正表 → 戻りスペクトル → ピーク → 高さ・透明板の厚さ。観察対象(透明板・金属)の反射率も同じ材料表から。画像を受けないので 2-D の橋は架けない。
- L616 (ja) — ★画像を受ける op の in は image2d(橋の外)、引数だけの op は表 / 曲線を返す側なので 2-D の橋は架けない。
- L631 (ja) — ★fail-closed: 扱えない面の種類・座標変換面・r² の非球面項・別名でしか表に無い硝材は拒否、近似は allow_partial で明示したときだけ(結果に approximate=True)。画像を受けないので 2-D の橋は架けない(_OP_BRIDGE_SKIP)。
- L640 (ja) — ★fail-closed: 無い面・未知の欄・lens_system が拒否する値は ValueError。基の系は書き換えない。
- L648 (ja) — ★fail-closed: 矩形窓は参照の周期が整数のときだけ(そうでなければ拒否し、窓の宣言 hann を促す)、ナイキスト以上・1 周期未満は拒否。 法線の復元は影の無い画素だけ有効(他は NaN と valid = False)。雑音の模擬は種を明示。
- L661 (ja) — merit を再実装しない。★fail-closed: カタログに許容距離内の近傍が無いモデル硝材・無効な始点・未知の merit 欄は ValueError。
- L667 (ja) — lensopt の変数・LM をそのまま使い、硝材を変数にできる(離散の外側ループ)。★fail-closed: 未知のオペランド・足りない/余計な引数・ 範囲外の添字・有限でない値・重みが全部 0 の表は ValueError。
- L677 (ja) — 追跡の前に毎回解き直される(傍らの数値は解いた値)。★fail-closed: 未知の種類・循環したピックアップ・絞りを動かす厚みの解・ 軸上の主光線の解・根の無い F/# の解・collimate しない afocal は ValueError。
-
| L690 (ja) — ★fail-closed: 収束しない屈折は NaN と converged = False、表の外の波長・未知の水の種類・ |
g |
>= 1・n <= 1 は拒否。 波のスペクトルは Pierson-Moskowitz(1964)/ JONSWAP(1973)、水の吸収は Pope & Fry(1997)、散乱の位相関数は Petzold(1972)。 |
- L704 (ja) — Kolb, Mitchell & Hanrahan (1995)。幾何光学のみ(回折なし)。★fail-closed: 射出瞳が無限遠の系・非有限の入力・範囲外の波長/照明の表・ 軸対称でない系への点光源(前方追跡で回す)は ValueError。ケラレ/全反射の光線は NaN と vignetted = True で返す。
- L760 (ja) — ★fail-closed: 非有限の高さ・波頭より浅い底・下を向かない光・n <= 1・充填率の範囲外・定数画像・両クラスのない欠陥マスクは拒否。 濡れ面は Lekner & Dorf(1988)、水中画像は watermedia(Akkaynak & Treibitz 2018)、瓶は 2 次元の断面の光線追跡。
- L771 (ja) — ★格子の式 mλ = d(sin α + sin β) と Czerny–Turner の幾何から、角分散・分解能 mN・帯域の幅(スリットの像 ⊗ 画素 ⊗ 回折)・smile / keystone(3 次元の格子の式)・高次の重なりまで。chromconf の spectrometer_fwhm_nm と spectralrad の band_fwhm_nm を、スリット・格子・焦点距離・画素から実体化する。画像を受けないので 2-D の橋は 架からない(table は sort に写らず、spectrum は 2 入力)。
- L782 (ja) — ★LP モードは特性方程式の数値解(遮断 = Bessel の零点)。画像を受けないので 2-D の橋は架けない。
-
| L792 (ja) — ★縞はずれを M = p_m/ |
Δp |
倍(ウェハが動く)/ p_w/ |
Δp |
倍(マスクが動く)に拡大する。差動の 2 対で共通の誤差を消す。 |
- L803 (ja) — ★暗視野は縞の可視度の比(試料あり / なし)で、画素より小さい構造の小角散乱を測る。散乱角の広がりへは公表式で換算。
- L815 (ja) — 読み戻す。★新しい型の語は作らない: 図は印つきの dict(table)で、印の無い table は書き出しの op が ValueError で拒む。SVG / DXF は既存の text(文字列)、画像は rgbimage。
- L845 (ja) — 高さで変わる倍率・ケラレ・ぼけを実光線で。★光線は入射瞳でなく絞りを狙う(入射瞳が無限遠でも動く)。
- L864 (ja) — ★1 画素 4 枚 = 各画素で R・G・B(偽色が消える、解像はそのまま)/ 半画素 = 折り返しが消える(開口の MTF は上がらない)。
- L873 (ja) — ★新しい型の語は作らない。干渉スペクトル・A スキャン・B スキャンの束は kind の印つきの dict(table)で渡し、 印の違う table は消費する op がすべて ValueError で拒む(oct_interferogram / oct_bscan_spectra / oct_ascan / oct_bscan の 4 種)—— 別の族の table を黙って読む経路が無い。B スキャンの画像だけは image2d(dB)で出し、 界面を辿る op は装置の出力の図(実画像)も同じ image2d で受ける。
- L893 (ja) — ★距離は周期 c/(2f) の剰余。高い f ほど細かいが折り返す / 多重反射・縁の混合・高調波・背景光で壊れる。
- L904 (ja) — 高 NA の複素像。★新しい型の語は作らない。像の組は kind=”fp_stack” の印つきの table、復元は kind=”fp_result” で、 fp_reconstruct は印の違う table を ValueError で拒む。撮像の入口は振幅と位相の image2d、装置の像の組は volume と 照明の方向余弦 2 本の signal。
- L933 (ja) — ★新しい型の語は作らない。曖昧な法線の集合(候補 2 本 / 4 本)を normalmap と 区別するために新 sort を作るかを考えたが、集合は
kind == "sfp_candidates" の dict(= table)で返す: (K,H,W,3) を normalmap と申告すると法線を食う op(積分・ 陰影)に 4 本重ねの配列が渡るが、table なら normalmap の枠には入らず、逆に sfp_disambiguate は印の無い table を ValueError で拒む —— 混ぜても黙って嘘を 返す経路が無いので、語彙を増やす理由が無い(2026-10-13 に確かめて決めた)。
- L939 (ja) — ★2-D の橋(tb_*)は架からない: 1 入力の op の in は image2d(sort image、_NEW_SORTS の外) か normalmap / polsweep / table(TYPE_TO_SORT に無い)。_OP_BRIDGE_SKIP 不要。
- L969 (ja) — ★新しい型の語は作らない。断面と輸送行列は kind の印つきの dict(table)で渡し、印の無い table は消費する 5 op がすべて ValueError で拒む —— 別の族の table を幾何として黙って 読む経路が無い。パターンと画像は既存の images(2-D 画像の list、fringe の位相シフトと同じ)。
- L972 (ja) — ★縞と ToF は 1 つの族(このカテゴリ)にまとめ、sort は分けない。物理は同じ「経路ごとの フェーザの和の偏角」で、op の入出力はどちらも名前つきの値の dict(table)—— 縞は bias [rad] と height_error、ToF は depth / bias [m] と鍵の名前も単位も違い、位置で 並んだ配列を取り違えて渡す経路が無い(混ぜても黙って嘘を返さない)ので語彙を増やす理由が無い。
- L976 (ja) — ★2-D の橋(tb_*)は架からない: 1 入力の op の in は table / images(TYPE_TO_SORT に無い)。
- L993 (ja) — ★新しい型の語は作らない。パッチの組・解・描画の結果は kind の印つきの dict(table)で、印の無い table は消費する op が ValueError で拒む。多角形は points((V, 3))、放射は signal((N,))。
- L995 (ja) — ★2-D の橋(tb_*)は架からない: 1 入力の op の in は table(TYPE_TO_SORT に無い)。
opsphoton.py
- L85 — ★ Note that since counts is a 1-D float64 array itself, nothing prevents “calling” dsp / funct1d (the type vocabulary is for the chained fuzzer’s pool separation, not for Python’s callability). For the reverse bridge = the path that non-negates a signal into counts, see the “bridge” note below. * countrate — the count rate sequence (Hz) of a SPAD (1-D, non-negative). It is the same “non-negative 1-D” as counts, but a different quantity, so we put it in a separate pool. There are 2 reasons, both based on measurement: (a) the unit differs by 7 orders of magnitude. The value range of the counts pool is around 0-250 counts, and passing this to spad_deadtime_apply(dead_time_ns=50) gives 250 Hz x 50 ns = 1.25e-5 -> a value infinitesimally close to the identity map is returned without exception. The op “reaches” but the physics of dead time (saturation, 1/tau fail-closed, the non-injectivity of the paralyzable type) is never stepped on. This is the same “plausibly wrong pass” as when histcube piggybacked on voxel, with neither CONTRACT nor TYPEMISS emitted. (b) the physics differs. Dead time acts on the detector’s rate stream, not applied per bin to a TCSPC time-bin histogram (the correct distortion model for a histogram is Coates = tcspc_coates_correct). Making them the same vocabulary would make the evolutionary search learn the physically wrong chain “applying a dead-time correction to a histogram” as a legitimate type connection. countrate is a narrow sort knowingly separated with only 2 ops, apply <-> correct (on par with jones having 2 ops and stokes having 3 ops). However, these 2 ops are strictly inverse to each other, so a round-trip invariant circulates within the pool. * histcube — the arrival-time histogram cube per pixel (H, W, T), time axis last. The existing
voxel is a “3-D array” and TYPE_CHECKS is also only ndim == 3, so structurally it passes. But voxel is a (D, H, W) spatial grid with different axis meaning: passing a (D,H,W) volume as histcube makes dtof_cube_depth read W as the time axis and return not an exception but a “plausibly wrong depth map” (measured: 0.0075 m for all pixels with a uniform volume). Note that a flat histcube is also judged empty on the dtof_cube_depth side and silently not passed (double defense). Bridge (measure against narrow sorts, implementation pending = awaiting the parent’s judgment): what could become a signal -> counts bridge is an op that “regards an arbitrary real 1-D as a non-negative photon rate profile and Poisson-samples it” (a 1-D version of photon_sample). Making the handling of negative values an explicit argument avoids silent rectification and does not break discipline. Existing non-negative-output 1-D ops (funct1d.abs_funct_1d measured min 0.0023, dsp.envelope measured min 0.749, both guaranteed non-negative) would, if that bridge exists, be a natural front stage for signal -> counts. See the report for details.
opspiv.py
- L25 — * ★ We newly established
flow2d. The existing flow_dense has the predicate ndim == 4 and shape[0] == 3 (3-D scene flow), so 2-D (2, h, w) does not apply in the first place. Borrowing the name would mean the ledger declares “it returns 3 components” while returning 2 components, making the declaration a lie. It satisfies this repo’s condition for adding a type (“if there is no op that has a seed, it becomes permanently unexecuted”): 7 generating ops (cross_correlate / multipass / deform_pass / ensemble_correlate / replace_outliers / to_velocity / sample_at_windows) and 13 consuming ops (including overlap of 8 field quantities, 2 visualizations, 2 tests, 3 evaluations), so generation and consumption are closed within the family.
- L35 — ★ We always give it an exit (the 5 ops of
visualise) —— a type that can be made but not seen becomes a dead end mid-chain and produces a “narrow sort”. Fail-closed in both directions is also confirmed by measurement: passing a 2-D flow to reprconv.flow_magnitude raises ValueError (rejecting by name with “takes (3, D, H, W)”), and passing a 3-D scene flow to piv_vorticity raises ValueError. * the input image pair is image2d —— particle images are 2-D real fields themselves, so existing 2-D ops (smoothing, threshold, background subtraction, annotation) can be used with meaning intact. There is no guarantee brightness fits in [0,1], but that is the same standing as the composite of astrostack. * piv_outlier_mask is mask —— bool 2-D, as the predicate says. Unlike dem_stream_network, which could not call itself mask because it has nan, here missing data is folded to the True (outlier) side, so it is closed as bool. * statistics are table (dict). piv_error_stats / piv_peak_locking. * the output of the velocity conversion piv_to_velocity is also flow2d —— the unit changes from px/frame to m/s but the type is the same. Here we write honestly: the type cannot protect the unit. So we made both scales required arguments (the same judgment as cell_size of demops). We also considered separating the unit by type, but that would be a type where only 1 op makes m/s and no op consumes it —— contrary to the order “add after evidence emerges”, so we did not adopt it.
opsprintpath.py
- L54 (ja) — ★様式化(2026-09-23)。「きれいな絵」を返す op ではなく、保った量と捨てた 量を数で返す op にする —— 既存の NPR ライブラリは絵しか返さない。真値は モアレ周期の予言(描く前に分かる)、被覆率 w/d の閉形式、既知の縞の向き、 Lloyd の単調減少(既存 stipple_energy が測る)、セル平均の L2 最適性。 点描の 6 op と同じ族に入れたのは、どちらも「濃淡を離散的な墨に落とす」 同じ問題で、入口も出口も同じ語彙(image2d / pairs)だから。
opsrangedoppler.py
- L108 — ★ Record of correction: the first draft of this module wrote “in real, the sign of velocity is lost”, but that was wrong (it is correct for a 1-D real signal of the range axis alone, but once 2 axes are present the sign is preserved). A test broke first and revealed it. What is actually lost is “which of the pair is real”, half the amplitude, and half the unambiguous ranging range.
_as_beat_cube rejects at the dtype stage and names the fix (explicitly build an analytic signal). ————————————————————————– Entry and exit to avoid a narrow sort (dealing with a measured lesson) ————————————————————————– This repo has actually stepped on 2 traps: (1) a type with no op that produces it is permanently unreachable (the case where score was the only 1 blocked among 434 ops), (2) piggybacking on an existing pool gets rejected fail-closed every time and looks like “zero findings” (the case where 7/17 of the photon family were unexecuted). beatcube is treated for both: entry (ops that produce beatcube) : fmcw_beat_simulate (arguments only, no input type) fmcw_window_apply (beatcube -> beatcube) exit (ops that return to an existing sort) : range_doppler_map -> image2d (largest pool) fmcw_range_profile -> signal beamform_delay_sum -> signal beamform_doa -> table The point that the entry is an “argument-only source” is the same form as tcspc_simulate (no input type -> counts), so the chained fuzzer needs a dedicated generator just like counts (a hand-off item for the parent; the actual generator is included in the report with execution confirmed). The exit falls into image2d and signal, 2 of the largest pools in this repo, so it does not become a closed narrow sort like jones (2 ops) or countrate (2 ops).
opsreprconv.py
- L257 — ★
flow cannot be written with a single predicate. Because dense (3,D,H,W) and scattered (N,3) coexist under the same type name, a predicate that passes both protects nothing, and deciding on one necessarily makes one of the existing 4 ops a TYPEMISS. Separating is correct (the same judgment as separating video from voxel), but that is work to rewrite the declarations of existing ops and is outside this module’s scope, so here we only leave the proposal.
opsspc.py
- L91 (ja) — ★単位空間の MD² の平均は ちょうど (n-1)/n(導出、当てはめではない)。 教科書の「単位空間の距離は平均 1」を有限標本で正確に言い直したもので、 1.0 を固定する試験はどんな標本でも間違い、(n-1)/n は全部で正しい。
- L120 (ja) — ★新しい型の語は作らない。曲線(大きさの格子・POD・下限)も表の列として返す。
- L121 (ja) — ★2-D の橋(tb_*)は架からない: 出力の table は backends_typed.TYPE_TO_SORT に 写らないので _OP_BRIDGE_SKIP に入れる必要も無い(2026-10-12 に確認して決めた)。
opsspecular.py
- L160 (ja) — ★出力は既存の語彙(images / normalmap / image2d / table)だけ。法線マップは photometric と同じ規約なので integrate_normals(高さ)・render_shaded へ無改造で流れる。装置の幾何は table(rig)で、他の op は rig= で受ける(既定の装置なら省略可)。順方向は高さ場(image2d)→ 縞の鏡像(images)。
opstomography.py
-
| L141 (ja) — この台帳に置く。★出力は既存の語彙だけ: スペクトルと μ/ρ(E) は pairs、チャネル・線質・CRLB は table、 チャネルの像と基底の厚みは images (C |
B, H, W)、R 値と実効 Z は image2d。 |
opsvolcolor.py
- L63 — ★ However, the existing
labels predicate is ndim >= 1, and a 2-D label image and a 3-D label volume coexist. The 11 ops of this module all raise ValueError (fail-closed) when passed 2-D, so a mix-up never silently passes. The danger is the reverse: in a pool with only 2-D seeds it looks like “zero findings” while never being executed —— the same form as the trap opsphoton stepped on with counts. Be sure to pour 3-D label seeds on the wiring side (see “when the parent wires” below). * voxel — the source grey volume that vol_label_overlay overlays, and the binary volume that vol_label_color_flicker receives. Both are the existing voxel vocabulary of (D,H,W) itself, so there is no reason to make a new term. * rgbimage — the return of cross-sections and projections (H,W,3). Existing rgbimage-consuming ops (specular separation, color conversion, save) can be used with meaning intact. This is the exit of the rgbvolume vocabulary, so the new vocabulary is not a dead end. * matrix — the return of vol_label_palette (n+1, 3). A 2-D real matrix itself. * table — a set of shape statistics / legend / flicker measurement / colored mesh.
- L77 — ★ Not making a new vocabulary for “a set of colored meshes” was the result of measurement. At first we intended to add
colormeshes, but when we swept all existing table-consuming ops and passed the return of vol_labels_to_meshes (measured 2026-09-02, across ops3d / ops1d / opsmath / opsoptics / opslightfield / opsphoton / opsacoustics / opsinterferometry / opscadmap), the ops that consume table are only 3 (abcd_matrix / wavefront_stats / istft), and all 3 fail-closed with ValueError. That is, it does not meet the condition “mixing makes it silently wrong”. Adding a vocabulary to something that does not meet it just adds one new consumer-zero vocabulary = one dead end (the decision criterion of docs/OP_COMBINATION_MATRIX.md). Note that when you want to flow individual meshes downstream as the mesh sort, strip them with [(m["vertices"], m["faces"]) for m in result] —— since this discards color, do not do it implicitly in an adapter. ————————————————————————– One new vocabulary and its reason (measurement-based) ————————————————————————– * rgbvolume — a (D, H, W, 3) colored volume. The existing lightfield predicate is only ndim == 4, so a color volume fully satisfies lightfield. Measured (2026-09-02, passing a (8, 16, 16, 3) color volume to lightfield ops): - lf_refocus / lf_subaperture / lf_epi / lf_depth_from_focus, these 4 ops return a finite (16, 3) result with neither exception nor NaN (each claiming “refocused image”, “sub-aperture image”, “EPI”, “depth”). Meaningless finite values, read with the z-axis as angular axis V and the y-axis as angular axis U. - only lf_all_in_focus gives a TypeError from insufficient arguments (not a type matter). The reverse (a light field to vol_label_slice_rgb) fails closed with shape[3] != 3. Only one side is safe, so runtime checks cannot be relied on. The same judgment as separating zscan from video. Entry = vol_colorize_labels (labels -> rgbvolume) and vol_label_overlay (voxel + labels -> rgbvolume), exit = vol_label_slice_rgb / vol_label_mpr_rgb (-> rgbimage). Produced 2, consumed 2, so no dead end.
optdraw.py
- L677 (ja) — ★入射瞳が無限遠(物体側テレセン)では近軸の F 値 = EFL / 入射瞳径 が 0 になる —— 意味の無い「F/0.00」を書かない
- L911 (ja) — ★上面図は第三角法で側面図と横軸 y を共有するので、センサーの長辺(像の横 = 世界の x)は縦に描かれる。 向きを取り違えないよう、軸の矢印と名前を描く(+X が上)。
optics.py
-
L871 (ja) — ★奇数次の微分は奇関数。偶数長の fftfreq はナイキストの -1/2 だけを 持ち対の +1/2 が無いので、そこを残すと実の場の「微分」に虚部が出た (実測 max |
Im |
0.34)。hilbert_x と同じくそのビンを 0 にする。 |
- L887 (ja) — ★補集合はここで作る。
1 - lowpass を呼び出し側に作らせると、 境界の扱いが 2 通りに分かれて lowpass + highpass = 1 が崩れる。
- L892 (ja) — ★ナイキストのビンを 0 にする。
fftfreq は偶数長で -1/2 だけを 返し、対になる +1/2 が無いので、そこを残すと片側位相が奇対称を 厳密に満たさない(実測: 残差 1.6e-09 → 0 にすると 2.3e-16)。 離散ヒルベルト変換で標準的な扱いで、scipy.signal.hilbert も同じ。
- L2767 (ja) — ★縁はモザイクのまま鏡映で 2 画素広げてから抜く。広げ幅が偶数で
reflect (縁の画素を重ねない鏡映)なら 2x2 の位相が保たれる。マスク後の面を伸ばすと 未計測の 0 が縁に写り、一様な場でも縁が暗くなった(実測 16 画素)。
optscene.py
- L2349 (ja) — σ = 0.42·λN(Airy 強度の最良ガウス近似)。★ 以前は 0.42·(1.22λN) で 22 % 太かった
- L2749 (ja) — ★2026-10-11(台帳契約の門): lens_spec() は image_circle_mm を None で持つ(鍵は在る) ので
.get(.., 0.0) が None を返し、float(None) の生の TypeError が漏れていた —— 下の「image_circle_mm が無い」の ValueError に届いていなかった。
ozakimm.py
- L341 (ja) — ★2026-10-07: 行・列の最大値で 2 の冪に先に正規化してからノルムを取る(1e-200 × 1e200 で 二乗がアンダー/オーバーフローし 0 を返していた)。2 の冪の倍率は正確なので通常域の結果はビット同一。
pcseg.py
- L489 — ★
full_matrices=True (default) allocates the (N, N) U and throws it away. Measured 2026-09-06: for 20000 points, 3.73 s / 3.2 GB, whereas full_matrices=False is 0.876 ms (4263x) with Vt bit-identical. For 100k points it dies at 80 GB. The same pattern was in pcseg.fit_plane / measure / ops / camera / pnp3d (all throwing away U). The static gate is tests/test_svd_full_matrices.py.
perpetual.py
- L115 (ja) — 密度の配色(暗い紺 → 橙 → 生成り)。★赤と緑は対にしない
- L149 (ja) — ★
np.add.at は同じことをするが桁違いに遅い(散らばった加算)。 1 次元に畳んで bincount で積むと CI の予算に収まる。
- L315 (ja) — ★色を黒でいた時間に結びつける。途中で通っただけのマスと、早くから 黒いままのマスが同じ濃さになるのが「白黒の点」の正体だった。 高速道路は最後にできるので薄く、最初の混沌は濃く出る。
- L326 (ja) — ★構図 —— 蟻が触った範囲は盤の一部しかない(既定では 1/3 ほど)。 埋まった範囲の外接箱で切り出さないと、絵の大半が余白になる。
- L341 (ja) — ★切り出すと 100 画素角ほどになる。最近傍で伸ばす —— これはセル オートマトンなので、補間すると存在しない中間値を作ってしまう。
- L364 (ja) — ★外接箱で枠を使い切る(外接円だと三角形が上下に余白を残す)
- L376 (ja) — ★密度をそのまま色に —— 双一次で積み、asinh で暗部を伸ばす
- L470 (ja) — ★★平方根には枝が 2 つあり、片方は「親 3 円に接しない円」を返す。 最初は主値だけを使っていて、絵の左上に外円の外へ逃げる円の鎖が 出た —— 絵としては「フラクタルっぽい」ので、見ただけでは欠陥と 分からない。接することを数で確かめて枝を選ぶ。
- L491 (ja) — 持ち上げる。★「順位で正規化すれば配り直される」と読んだが外れで、 極小円が多数派なので大きい円が全部下端に潰れ、前より悪くなった。
- L560 (ja) — ★点群の外接箱で枠を使い切る(式の定数で決め打ちにしない)
- L582 (ja) — ★正規化する前の速さ。色と太さをこれに結びつける(飾りでなく量)。
- L636 (ja) — ★色は濃度 v に結びつける(単調な配色なので順位が保たれる)
- L877 (ja) — ★二項係数そのものを積むと C(62,31)*31 が int64 を黙って溢れる。 要るのは偶奇だけなので、リュカの定理の帰結 「C(n,k) が奇 ⟺ (n & k) == k」を使う(桁あふれの余地が無い)。
- L897 (ja) — ★向きの符号は回転の規約で変わる。定理が言うのは「周期 104 で同じ斜めの 変位を繰り返す」ことなので、そちらを門にする(大きさは縦横とも 2)。
- L904 (ja) — ★高速道路は正味で 104 歩あたりちょうど 12 マス黒を増やす(実測で整数)。 最初は「104 歩で 52 マス」と書いたが実測 0.114/歩 と合わず、測り直して 12/104 = 0.11538 だった。周期の中で塗っては消すので、正味はずっと少ない。
- L921 (ja) — ★★描いた円が本当に接しているか。平方根の枝を選び損ねると、 絵としては「フラクタルっぽい」まま外へ逃げる鎖が出る(実際に出した)。
photometric.py
-
L98 (ja) — ★2026-10-02: 以前は np.sign(nz) * 1e-6 + 1e-12 で、nz がちょうど 0(真横を向く法線)のとき np.sign(0) = 0 になり分母が 1e-12 → p = -1e12 を返していた(±1e-6 で抑えるつもりが効かない)。 0 は正の側に寄せる。真横の法線の勾配は本来無限大で、ここでは |
p |
, |
q |
≤ 1e6 に抑えた値になる。 |
pipeline3d.py
-
L45 (ja) — ★2026-10-02: 以前は符号なし距離 distance_point_plane( |
d |
)で PV = max |
d |
− min |
d |
を出しており、 平面の両側に散る点では PV を桁で過小に報告した(±h の 2 層で真の 2h·cosθ = 0.0188 に対し 0.0020)。 平面度の PV は符号つき残差の山と谷の差。RMS は 2 乗なので元から正しかった。 |
pivops.py
- L506 — ★ A window where the correlation peak does not stand (no texture, uniform everywhere) returns nan —— we do not return 0 so as not to mix “not moving” with “unknown”. But what fraction is nan can only be known from the return value, and the form was such that you only notice when
flow.mean() becomes nan (2026-09-06). We count it here. Measured: an image with only a 16x16 square on a uniform background has only 16 of 98 windows finite (0.163). Full texture gives 1.000.
pnp3d.py
- L241 (ja) — ★2026-10-07 レビュー修正: 旧式は回転ブロックに -[Xc]x(= t も回す更新の微分)を使い、 実際の更新(t は回さない)と食い違っていた。初期値が良いほど収束が線形に遅くなり、 30 反復で最小に届かないことがあった(重心中心化した DLT 初期値で 50 反復要した)。
- L309 (ja) — ★2026-10-07 レビュー修正: 世界原点から遠い点群(オフセット 1e4、画素ノイズ 0.5 px)で DLT の脱正規化 M = T2⁻¹·Pn·T3 の並進列が桁落ちし、t が壊れた初期値から LM が 回転誤差 175° の別解へ落ちていた。入口で重心 c を引いて解き、最後に t − R·c で戻す (Xc = R(X − c) + t’ = R X + (t’ − R c))。
polish.py
- L435 (ja) — ★2026-10-05 chain_fuzz の 2 回目の発見(ttc_from_scale → raster_wipe_area): 面積の 4 項が有限でも、N 本の和(N·single)と 一筆の y 座標((i − (N−1)/2)·pitch)はまだ溢れうる。区切りの NaN 以外に非有限が出たら黙って返さない
pose_quat.py
- L190 (ja) — ★2026-10-07 レビュー修正: ry = ±90°(ジンバルロック)では R[2,1], R[2,2], R[1,0], R[0,0] が どれも丸め屑になり、rx, rz を屑の atan2 で決めていた(ry=90° ちょうどで行列の往復誤差 0.16)。 cos(ry) = hypot(R[0,0], R[1,0]) が √ε 未満なら rx と rz は和/差しか決まらないので rx = 0 に 固定し、rz を残りの成分から取る(R[0,1] = −sin rz, R[1,1] = cos rz が ±90° の両方で成り立つ)。
- L291 (ja) — ★2026-10-07 レビュー修正: 符号を w の正負で揃えると、w≈0 をまたぐ組(yaw +179° と −179°)が 反対の半球に分かれ、平均が恒等(0°)に潰れた。最初の四元数を基準に、内積が負のものを反転する。
-
| L425 (ja) — ★2026-10-07 レビュー修正: 回転が無い(純並進)と sin(θ/2)=0 で割れず、旧実装は 軸 0・並進 0 を返して並進を丸ごと失った。qr = ±1 なら qd = ±(0, t/2) なので t = 2·sign(w)·qd[1:]、軸 = t/ |
t |
、d = |
t |
(並進も無ければ軸 0・d 0)。 |
ppf.py
- L126 — ★ Raw PCA normals have an arbitrary sign, and under rotation flip on 40% of points. Since PPF features are angles between normals, if they flip the key changes. Measured (400 points, about the z-axis): with raw normals the key match rate at 0/37/90/143 degrees is 100 / 73.6 / 69.4 / 67.2 %, with oriented normals all 100 %. The same hole that
pointcloud.fpfh had stepped on, fixed together the same day.
printpath.py
- L45 (ja) — 様式化(npr、2026-09-23)。★test_printpath の門が
set(OPSPRINTPATH) == set(__all__) - {定数} を要求するので、 台帳とここの両方に書く必要がある。
- L185 (ja) — ★2026-10-07: 行番号 N123 とチェックサム *71 を外す(外さないと N が命令に見え、その行の移動が黙って落ちた)
- L195 (ja) — ★2026-10-07: G の無い座標だけの行(modal な移動)などは黙って捨てず拒否する
- L209 (ja) — ★2026-10-07: 以前は黙って無視され、直後の G91 の相対量が絶対座標として読まれていた 軸は数値なしでも書ける(
G28 X Y)ので、数値つきの語でなく文字そのものを見る
- L231 (ja) — ★2026-10-07: 始点未定の軸への相対移動は未定のまま(以前は相対量を絶対座標として読んだ)
- L717 (ja) — ★ペンプロッタの経路と 3D プリンタの経路は同じ対象(順に回る線分の列)で、 # 出口も同じ(contours_to_gcode → gcode_write / gcode_time_estimate)。 # だから族を新しく立てず、ここに stroke カテゴリとして足す。 # 参考: Kaplan & Bosch, “TSP Art”, Computational Aesthetics 2005。 # ————————————————————————— # 点描の距離。”euclidean” 以外は将来。
- L818 (ja) — ★画素ごとの最近傍をKD 木で引く。以前は各反復で (画素 x 点) の距離行列を まるごと作っていたので、202x300 の絵に 9,000 点を置くだけで 60,600 x 9,000 = 5.5 億要素(4.4 GB 相当)を 18 回組み直していた —— 手元で 101 秒、共有ランナーでは PoC の実行門(1 本 600 秒)に迫る。KD 木は厳密に同じ最近傍を返すので答えは 変わらない(同距離の並びだけは実装依存になるため、種を固定した回帰検査を置く)。
- L1034 (ja) — ★被覆率で塗る。整数画素の円板で塗っていたときはペン幅が階段になり (0.5 / 1.0 / 1.5 px がインク率 0.1900 で一致し、2.0 で 0.4853 へ跳ねた)、 「目標の濃さに合うペン幅」を解くことができなかった。画素中心から標本までの 距離で被覆率を出すと、ペン幅が連続なノブになる。
- L1076 (ja) — ★2026-10-07: 反射の詰め物を手で切ると r ≥ 辺の長さで足りず出力が縮んだ((8, 12), σ=3 → (4, 12))。 np.pad の reflect は繰り返し反射するので形が保たれる(r < 辺の長さでは従来と同じ値)
- L1086 (ja) — ★「きれいな絵」を返す op ではなく、保った量と捨てた量を数で返す op にする。 既存の NPR ライブラリは絵しか返さない —— 差はそこ。真値はモアレ周期の予言、 被覆率 w/d の閉形式、既知の縞の向き、Lloyd の単調減少(既存 stipple_energy が 測る)、セル平均が L2 最適であること。 ————————————————————————- #
- L1297 (ja) — ★ストロークを構造に沿わせるなら、縞の周波数ベクトルはその 直交方向に向ける(線は周波数ベクトルに直交に走る)。 この 90 度を入れ忘れていて、docstring は「沿う」と書きながら 実装は「横切る」だった —— 既知の角度の縞を渡す門で掴んだ (2026-09-23)。絵を見るだけではどちらも「それらしい線」に見える。
problems.py
- L147 — ★A deterministic global shuffle (fixed base, so train/holdout/locked index the SAME permutation) split into three DISJOINT bands keyed by the seed’s role (evolve.run draws train=seed, holdout=seed+10000, locked=seed+20000, so seed//10000 mod 3 picks the band). The old
off = seed % pool collapsed all three windows to the SAME frames whenever pool divided 10000 — a silent train↔holdout↔locked leak that made a train-overfit champion look like it “beat hand on a pure holdout”. A pure 3-way split needs pool >= 3n; a smaller pool cannot yield a clean holdout, so we refuse rather than leak silently.
profileops.py
- L270 — ★ At first we wrote it as “the one with larger curvature” and judged the trailing edge as the leading edge on NACA 2412. The curvature of the 3-point circle comes out larger at the trailing edge, where the upper and lower surfaces nearly touch, than at the roundness of the leading edge —— the intuition “the leading edge is round” reverses when measured with 3 points on the contour.
- L277 — ★ When the trailing edge is open, the 2 farthest points pick one of the corners of the trailing edge and the chord tilts. We re-take it at the midpoint of the gap, then decide the leading edge as “the point farthest from that midpoint”. Without doing this, even a symmetric airfoil shows camber by the half-gap of the trailing edge (measured 0.001257).
- L643 — ★ Before comparing, re-take by the same method. The chord frame (especially the trailing-edge midpoint) depends slightly on the placement of points, so matching a raw contour against a re-taken contour injects a 0.02 degree rotation and 7.8e-4 translation even for an identical shape —— that itself became the floor of the deviation (measured rms 6.05e-4). Put what you compare on the same footing.
- L654 — ★ Measure not point-to-point but point-to-polyline. Even after re-taking at equal arc length, the phases of the two do not coincide, so taking correspondence by index makes the phase shift become the deviation directly (measured: comparing the same shape against itself gives rms 6.05e-4 —— the same order as the defect we want to detect).
pxrd.py
-
| L976 (ja) — ★2026-10-07: 補正で割った値 v = I / c の分散は I / c² = |
v |
/ c(補正を σ に通さないと 2θ=55° で σ を 2.3 倍小さく見積もった) |
raster.py
- L222 — ★ /iinfo.max put a signed image in [-1, 1] (int16 -32768 -> -1.00003)
- L280 — ★2026-10-24: imageio (Pillow) returns a 16-bit RGB/RGBA/gray+alpha PNG as uint8 without an error. Read the declared depth from the IHDR and, when it is > 8, try the depth-keeping reader (OpenCV IMREAD_UNCHANGED) first.
raytrace.py
-
| L925 (ja) — ★2026-10-18(lensfile の第 2 実装との照合で発覚): 以前は「 |
t |
の小さい方」を選んでいた。光線が前の面から 出て、球の z 範囲の中から始まる(R < 0 の面が長い空気間隔の後にある望遠型など)と、後ろ側の球面 (t < 0)を拾い、全光線が「けられ」に化けていた(R = −14.5 の面の 26 mm 手前から y = 3 の光線が NaN)。 物理的な交点は頂点を含む葉 —— sag の式の枝で (1+k)·c·z = 1 − √(1 − (1+k)c²r²) ≤ 1 —— の上にある。 その葉の上の根だけを候補にし、両方が乗るとき(双曲面など)に |
t |
の小さい方を取る。 |
- L1226 (ja) — ★2026-10-14: 以前は bfl(無限遠の物体の焦点)を使い、有限物体でも像面を無限遠の焦点に置いていた (700 mm の物体で像は 51.39 mm なのに 47.71 mm、W20 −18 波の偽のぼけ)。近軸の像距離は無限遠なら bfl と同じ。
- L1240 (ja) — ★2026-10-15: 像面とほぼ平行・逆向きに進む光線は像面に届かない —— 無効にする。以前は傾いた鏡(tilt 45°)の後で D_z ≈ 1e-17 の光線が巨大な有限の点になり、spot_stats が rms 3.4e18 mm・n_vignetted 0 を返した (傾きは「その面だけ」の摂動で、光軸は折れない。折り返しは raytrace3d の fold_mirror で組む)。
raytrace3d.py
- L652 (ja) — ★光線が像面とほぼ平行・逆向き(像面の +z へ進まない)なら像面に届かない —— 無効にする。 以前の raytrace は傾いた鏡の後で D_z ≈ 1e-17 の光線を巨大な有限の点(rms 3e18 mm)として有効に数えた。
- L657 (ja) — ★局所座標は傾いた像面そのものの基底で取る(以前は傾けない座標系へ射影し、傾けた向きが cos θ’ 倍に縮んでいた)
realdata.py
- L38 — ★ Only those whose
public column is true may be used in figures to be published. Those limited to cited use for research and education purposes carry cite.
- L97 — ★ skimage only holds a bundled subset; the rest it fetches at runtime via pooch. Whatever it cannot fetch we do not use in this repo (if a PoC depends on the connection, it becomes unclear whether a failure was the implementation or the network).
render3d.py
- L1946 (ja) — ★極小曲面は平均曲率 H が至るところ 0 の曲面。既存
vertex_curvature が まさにそれを測るので、「これは極小曲面だ」という主張を、作り方を知らない op
- L1948 (ja) — が採点する。★カテノイドとヘリコイドは等長なのでガウス曲率 K が一致するが、 それは必要条件にすぎない —— 門にするのは H のほう。 ————————————————————————- #
- L2153 (ja) — ★marching cubes は面積 0 の三角形を出す(格子点をちょうど通る等値面で、 2 頂点が同じ位置に来る)。曲率 op はそれを正しく拒否するので、ここで落とす —— 黙って渡すと「曲率が定義できない」と下流で落ち、原因がここだと分からない。
- L2215 (ja) — ★平行移動フレームで掃く(フレネ枠を使わない —— 直線部で法線が定義できず、 変曲点で従法線が反転して管がねじれる)。真値は、円を中心線にすると トーラスになり体積 2 pi^2 R r^2・表面積 4 pi^2 R r が解析解であること。 ————————————————————————- #
reprconv.py
- L149 — ★ For conversion to an integer dtype, inspect the raw value before the cast. A hole found by adversarial inspection (2026-09-02):
np.asarray(nan, dtype=int64) raises no exception and returns INT_MIN, and after the cast dtype.kind == 'i' so it slips past the non-finite check below. A non-integer like 3.7 is also silently truncated to 3 —— a result off by 1 in the index is returned with no exception. This is exactly the lie of a conversion op.
- L1076 — ★ Regression point of a real bug. At first this was
np.maximum(sigma, finfo.tiny). At a duplicate point sigma = 2.2e-308, and sigma ** 3 in gaussians_to_voxel underflows to 0, causing division by zero -> NaN. What was meant to “avoid 0” was replaced with a value that produces NaN downstream (part of the volume becomes NaN with no exception = the textbook silent error). Since a duplicate point means “the spacing cannot be measured”, fail-closed instead of padding with a sentinel.
residue.py
- L336 (ja) — ★2026-10-07: [lo, hi) に候補が 1 つも無い標本は範囲外の値・score -inf・margin 2.0(最大の確信)を 返していた → 値と score は NaN、margin 0(residue_fault_locate の「決められない = NaN」と同じ約束)。
- L614 (ja) — ★2026-10-07: 範囲内に候補が無い画素は margin 0(= valid にしない)。値は warp 用に有限のまま残す。
-
| L698 (ja) — ★2026-10-07: refine 後に |
d |
が探索範囲 max_disp を越えた画素は黙って切らず valid=False にする。 |
roughness.py
- L55 (ja) — ★規格の文面どおりの ±λc/2(= 2.67 σ)は裾の 0.8 % を落とし、カットオフでの透過率を 0.5 でなく 0.5095 にする(2026-10-18 に実測して直した。α の定数も標本化の正規化も正しく、 原因は打ち切りだけだった)。4 σ まで取ると λc で 0.5 に 1e-4 台まで合う。
- L978 (ja) — ★2 は入れない: 局所二次の中心値の等価核は
G(u)(3/2 - u²/(2σ²)) になり、透過率が (1+x)exp(-x), x = ln2 (λc f)² へ変わって λc で 85 % になる(= 規格のカットオフ定義と 食い違う)。次数 0/1 の内部は同じ核なので、カットオフの意味が保たれる。
rust/fullseye_core/examples/python_ctypes.py
- L42 (ja) — ★第 5 引数 fs_dtype_t。2026-09-14 までヘッダにだけ在って実装と FFI 宣言に 無かった引数。ctypes は引数の数を検査しないので、抜けても黙って動く。
sample_data.py
- L147 — ★ Reason for adding it: in exhibits 111-113 it re-emerged that “synthesis can only produce the breakage it already knows” (a precedent where 9 defects appeared in 6 real shots). The PoC stays closed offline, and we place only the entry that swaps in real data in the ledger. For commercial=”check” and above, read the source’s page before using.
scale.py
- L54 (ja) — ★2026-09-17: 検査のタイル幅を 64/16 だけから 60/12 も見るように広げたら、 tile_safe と宣言されていた 168 本のうち 16 本が割れた。64 も 16 も 8 の 倍数なので、周期 8 の処理と、たまたま境界が穴に掛からない領域処理が すり抜けていた。以下はそのとき測って落ちたもの(誤差は 60/12 での実測)。
- L86 (ja) — ★2026-09-17: 走査長平滑化は隙間を最大 65 画素まで埋めるので、 標準タイラーの halo より広い。60/12 のタイルで 0.2613 ずれた(実測)。
- L89 (ja) — ★2026-09-17: 局所の二峰性は窓が最大 41 画素、傾き補正は角度を画像全体から 1 つ決める。どちらもタイルごとに測ると別の答えになる(実測 1.0000)。
- L185 (ja) — ★名前つきの理由はカテゴリの分岐より先に引く。category が先に返してしまうと、 幾何カテゴリの op はすべて「cv2 の座標上限」と説明されてしまい、実際の理由 (deskew なら「角度は画像全体から 1 つ決まる」)に辿り着けない。この辞書に 載っているのは実測で非タイル可と分かった op だけなので、載せた op 以外の 分類は 1 件も変わらない(2026-09-17 に 925 op 全数で確認)。
scene_registry.py
- L19 (ja) — ★配布物にローカル絶対パスを焼き込まない。ここは自分のマシンの作業物を指していた ので、他人が pip install した環境では黙って落ちる(しかも「場面が無い」ではなく 「その場面だけ静かに欠ける」形で)。環境変数で受け、未設定ならその場面を登録しない = 在ると偽らない。
loco_mujoco は入っていれば自分で在り処を知っているので探す。
sdf_ops.py
- L346 — ★ Reason for adding it, based on measurement:
poc_dfm_thickness_overhang and poc_cad_scan_deviation reported that # “a machine part is made of cylindrical holes, chamfers, and fillets, but since the primitives are only sphere and # box, it cannot be assembled with CSG”, and both wrote per-face analytic formulas themselves. The 4 here are all closed-form and exact (outside is the # Euclidean distance to the nearest surface, inside is the negative to the nearest face), so a synthetic part with # ground truth can now be assembled with CSG alone. # ————————————————————————— #
segcompare.py
- L216 (ja) — ★2026-10-07: 43*0.1/0.1 = 42.99999999999999 → floor で 1 voxel 手前に落ちた(spacing 0.1 で 1000 個中 47 個)。 整数のごく近く(相対 1e-9)は整数に寄せてから floor
sensitivity.py
- L396 (ja) — ★2026-10-15: 生きた列(影響ゼロでない列)が 1 本以下なら、組み合わせが 1 つも無いので交絡は定義上ない (以前は max_subset の範囲 2..2 に 1 が入って ValueError で落ちた。simcal で σ = 0 のボケの列が 0 になって踏んだ)。
- L418 (ja) — ★大きさの等しい項の順と符号の基準は丸めの屑で決めない(simcal._fmt_combo と同じ、2026-10-15 に CI の Linux でだけ順が入れ替わった)。1e-6 で丸めて比べ、同点は宣言順。
shapestats.py
- L557 (ja) — ★2026-10-07 レビュー修正: 中点がほぼ一直線(2 番目の広がりが 1 番目の 1e-3 未満) または一点だと、面は直線まわりに決まらず vt[-1] は雑音で決まる(真の面から 90 度 ずれうる)。中点の面の法線が左→右の平均ベクトルと 60 度以上食い違う場合も、鏡映面と して左右の対と矛盾する。どちらも左→右の平均ベクトルの、中点の主方向に直交する成分を 法線にする(面の位置は従来どおり中点の重心)。それも決まらなければ ValueError。
simcal.py
-
| L938 (ja) — ★同じ大きさの項(利得 × 照明のように |
e |
が等しい組)の順と「主の項」は、丸めの屑で決めない。 argmax / argsort は 1e-16 の差で入れ替わり、Windows では “illum^1 * gain^1”、CI の Linux では “gain^1 * illum^1” になった(2026-10-15)。大きさを 1e-6 の相対で丸めて比べ、同点は宣言順。 |
-
| L967 (ja) — ★重みは自然な座標(e· |
列 |
)なので、単位の違う項が混ざると指数が大きくなりうる(8 次の多項式の係数と利得: 2026-10-18 に exp が溢れた)。対数のまま ln_product も返し、積は溢れたら inf / 0 にする(落とさない)。 |
spc.py
- L426 (ja) — ★管理図と工程能力は「工程のばらつき」を見るが、その数字は測定のばらつきを 含んだままである。ゲージ R&R は総変動を「部品差」と「測る行為の差」に分け、 後者が前者を食っていないかを見る —— 工程能力の前に来るべき検査で、ここが 抜けていると「工程が暴れている」と読んだものが実は測定器だったという取り違えが 起きる。GUM は同じ問いを 1 回の測定について立て、成分ごとの不確かさを 合成する。どちらも閉形式で、照合できる恒等式を持つ。 =========================================================================== #
- L733 (ja) — ★どのモデルで出した数字かを必ず載せる(黙って切り替えない)
- L1042 (ja) — ★★破綻は警告でなく構造で返す。感度係数がすべて 0 になると、入力に 不確かさがあるのに合成不確かさが 0 になる —— 規格の比較損失の例 (
dY = X1^2 + X2^2 を x_i = 0 で評価)がまさにこれで、 c_i = 2 x_i = 0 だから 1 次近似は「不確かさゼロ」と答える。数式としては 正しいが測定の主張としては嘘で、モンテカルロは同じ状況で u = 50e-6 を返す。0 を返すこと自体は止めない(それが伝播則の答えなので)が、 guf_valid=False と invalid_reasons=["stationary_point"] を結果に 同伴させる。警告にすると握りつぶされ、呼んだ側は「測定が完璧だった」と読む。
- L1051 (ja) — ★この検出条件そのものは本実装の判断であって、規格が列挙したものではない。 規格が定めるのは線形モデルの 3 条件(Welch-Satterthwaite の適用可否 / 有限自由度の入力が独立であること / 出力分布が正規または t で近似できること)と 非線形モデルの 5 条件(最良推定値の近傍で連続微分可能 / 適切な次数の全微分で 成立 / 高次項に関わる入力が独立 / その分布が正規 / 落とした高次項が無視できる) で、「感度が全部 0」「区間が定義域を出る」という判定手順は書かれていない。 ここで実装したのは、その条件が破れたときに観測される形のほうである —— 停留点は高次項が支配する特殊例、負側への張り出しは正規近似の破綻の現れ。
- L1062 (ja) — ★停留点 = 不確かさのある入力の 1 次感度がすべて0(高次項が支配する)。 感度が非 0 なのに分散が 0 なのは、相関による厳密な打ち消し (X1 = X2 で Y = X1 - X2)で、u = 0 が正しい答え —— 妥当として note を付ける。
- L1073 (ja) — ★破綻は警告でなく構造で返す(警告は握りつぶされる/ログに消える)
- L1104 (ja) — ★ NaN は
nu <= 0 をすり抜け、下の isfinite で「無限大」扱いになっていた (dof=[4, nan] で nu_eff 16 = 自由度を水増しし k を小さく)。欠測は拒否する。
- L1121 (ja) — ★規格は「nu_eff が整数でなければ次に小さい整数へ切り捨ててから t を引く」 ことを要求する(安全側に倒すため)。16.64 のまま引くと k = 2.1132、 切り捨てて 16 で引くと 2.1199 —— 公表例題の 2.12 は後者。0.3 % の差だが、 拡張不確かさは報告書に載る数字なので規格どおりに倒す。切り捨て前の値も
dof_effective に残す(どこで丸めたかが見えないと追えない)。
- L1151 (ja) — ★区間が定義域を出たら、それは測定の主張でなく近似の破綻。 比較損失(二乗の和)は構成上非負なのに、規格の例題では伝播則の 95 % 区間が [-96, +296]e-6 と負側へ張り出す。伝播則は出力を正規と見なすので 境界を知らない —— 知っているのは呼ぶ側だけなので、境界を渡されたときに 限って検査する(既定で勝手に 0 を下限と仮定はしない)。
- L1530 — ★”no spread” is not “std == 0.0”. A column holding one repeated value leaves rounding dust behind: 4.2 stored 200 times gives std = 1.3e-14, not zero (measured). Dividing by that dust amplifies it into a distance of nonsense, and the absolute test never fires. Put the floor at the relative scale of the column, below which a spread cannot be represented in the data itself.
- L1562 — ★ std = 1 alone does NOT make a flat feature “contribute nothing”: a new observation that leaves the flat value is scored in raw units, so the same physical data in mm vs um gave MD 1.73 vs 1732 (2026-10-07 review). Zero its row and column of the inverse correlation instead — then its z drops out of z’ R^-1 z whatever the new value is.
- L1673 — ★A unit space given in part is the dangerous case: the missing piece would be silently estimated from the very data under test, so a drifted batch would score itself as normal. Refuse instead.
specops.py
- L811 — ★ This is a value that depends on both the staining and the imaging system and is not a universal constant —— if you quantify on your own slides, shoot a single-stain slide and re-measure it with :func:
stain_vectors_from_patches.
- L843 — ★ The 3rd vector is “the remainder”. With only 2, a 2x3 has no inverse, and using the pseudo-inverse silently distributes the residual to the 2. Set up an orthogonal 3rd vector and gather the density with no place to go into it (= it can be read later as the residual).
spectralrad.py
- L576 (ja) — ★既定の溶融石英(SILICA、Malitson の分散式)は材料表に k が無く、厚さは効かない —— 内部の吸収を入れたいなら k を持つ硝材の名前と厚さを渡す(材料表の glass の類)。
studio.py
- L349 (ja) — ★2026-10-03: GIF を QPixmap で読むと 1 コマ目しか出なかった(例の図の 1/4 は掃引 GIF)。QMovie で回す。
- L358 — ★ Right-click on the figure itself (user 2026-09-06: “it would be nice to be able to right-click what is shown as a figure and copy it to the clipboard”). A Studio UI convention of this repo —— the display side must let you do everything from a right-click too. It can do the same as the button row below (do not make it one or the other).
- L1550 (ja) — ★2026-10-03: (2, h, w) を “color” と判定し、描けずに前の画像が残っていた。
-
| L1560 (ja) — ★2026-10-03: 複素数は虚部を黙って捨てた min/max を出していた。 |
z |
で数える |
- L1583 (ja) — ★2026-10-03: dict は中身に関係なく「輪郭 0 本」と表示していた。台帳の op(~1,700 本)の大半は {“distance”: …, “t”: …} のような表を返すので、全部「輪郭 0 本」に見えていた。 輪郭(
cs を持つ)以外は表として、欄ごとに何が入っているかを出す。
- L1594 (ja) — ★2026-10-03: 空の配列は「先頭の値」を取りに行って IndexError、4 次元以上は先頭の 1 値を スカラーとして見せていた(台帳の op を Studio から走らせて踏んだ)。
- L2187 (ja) — ★ヘルプの「開けるファイル」表の正本(2026-10-03、ユーザー指摘「ヘルプにも機能として書いておいたほうがいい」)。 各行 = (分類キー, 何で開くか, 拡張子, 補足)。文字列は英語 =
tr のキー。拡張子は上の定数から引くので 定数に足せば表にも出る。表から漏れた拡張子・分類と違う行は tests/test_studio_dragdrop_formats.py の門が落とす。
- L6430 (ja) — ★2026-10-21: 走っている/終わりかけの実行ワーカーを静止させてから閉じる。QThread が 走ったまま親ごと破棄されると Qt は abort し、CI では「全件合格のあと exit 134」になる。
- L6987 (ja) — ★順位(2026-09-19、GenSpark 第 10 報 N17): 「canny」で先頭に edges_color(説明文に canny を含む)が 来て、Enter で挿入する op を取り違えやすかった。名前の完全一致 → 前方一致 → 名前に含む → HALCON 名 → 説明文だけ、の順に並べる(同順位は登録順のまま)。
- L9254 (ja) — ★fallback は画面に出す(2026-09-19、GenSpark 第 10 報 N16): グレー画像に edges_color(color 入力)を Run once すると、ライブラリは台帳に記録して sort の既定値を返すが、GUI は「ran … once」としか 言わなかった。結果の窓には既定値が映っているので、それを結果だと思わせてはいけない。
- L10327 — ★ The receptacle for figures. The examples write a PNG here via
examplefig. In runs that pass no environment variable (CLI), not a single one is written, so a picture appears only when run from the gallery (the example’s numbers and speed do not change).
- L10483 — ★ The receptacle for figures. The examples write a PNG here via
examplefig. In runs that pass no environment variable (CLI), not a single one is written, so a picture appears only when run from the gallery (the example’s numbers and speed do not change).
- L11360 (ja) — ★実行キー(F5 / Ctrl+Return / Ctrl+R)は「いま書いてあるものを走らせる」(2026-09-19、GenSpark 第 8 報 N13): Program に未適用の編集があるのに実行キーを押すと古いパイプラインが走り、画面は 「● unapplied edits」のまま何も変わらなかった(Xvfb + xdotool の実測、s8 → s9 が同一画面)。 先に Apply し、Apply が通らなければ(構文エラー等は Program の状態表示に出る)走らせない。
- L12260 (ja) — ★パスで渡すと sim_source は拡張子 .xml の時だけファイルと読み、.urdf / .mjcf はXML の文字列と 取り違えて「XML parse error」になった(2026-10-03 のテストで発見)。モデルはここでパスから作る。
- L12333 (ja) — ★2026-10-03: 3DGS の学習結果(.ply に f_dc/opacity、または .splat)は、以前は普通の点群として 色無しで開いていた。ガウスの中心を 0 次の球面調和の色で出す(不透明度 5% 未満は落とす)。 楕円体の描画ではなく中心の点 —— 形を見る用(splat の見た目そのものは gs_render)。
- L12336 (ja) — ★2026-10-03(ユーザー「Physical AI で使われるデータ形式も読んで表示」): glTF / LAS・LAZ / MJCF・URDF。 読み手は既存(meshio_opt / sim_source)で、依存は任意(無ければ pip の名前つきで断る)。
- L13825 (ja) — ★2026-10-03(ユーザー「画像をドラッグ・アンド・ドロップして見れる」「Python スクリプトも D&D で開ける方が便利」): 以前は 1 本目しか見ず、.py は「未対応」だった。種類ごとに全部さばく: 画像 1 枚 = 入力として読む(従来どおり)、2 枚以上やフォルダ = 画像ビューアで並べる、 .py = Python エディタのタブ、.json = パイプライン。
- L13844 (ja) — ★モデル + qpos 軌跡 (T, nq) を一緒に落とすと再生(nq が 3 や 6 だと点群と見分けがつかないので、 モデルと一緒に落とされた .npy は形に関係なく軌跡として読む)
- L14886 (ja) — ★2026-09-20(GenSpark 第 43 報 N154):
fullseye-studio --help が表示の無い Linux で SIGABRT。QApplication を作る前に –help / –version を答え、表示が無ければ Qt を起こさず 1 文で止まる(abort は説明にならない)。
studio_result.py
- L48 (ja) — ★2026-10-04: bool の配列(占有格子など、台帳の op が返す)は np.round が bool へ書き戻せず落ちた —— bool はそのまま二値
superquadric.py
- L182 (ja) — ★2026-10-07: 0 点の平均残差は 0/0(NaN を guard が置き換えていた)
tacsim.py
- L385 (ja) — ★既定の探索半径は窓の縁まで(双線形 ±0.5 px の余白に 2 px)。2026-10-05 までは窓の半分の半分(0.5 × 縁までの距離)で 打ち切っていて、201 px の窓では 50 px で止まり、半径 61 px の実機の接触を 49 px と答えた(tacscalib の門 12: −12.9 px)。 tacsim の合成(256 px・Hertz)は接触が窓の 1/4 より内側なので、直しても結果は 1 桁も変わらない。
- L422 (ja) — ★2026-10-07: 窓の端までの距離は中心から測る(原点 = 窓の中心と仮定していて、X・Y・中心を +8 mm ずらすと δ が 11 % 縮んだ)
- L506 (ja) — ★2026-10-07: a0 が 20 % 超ずれると黄金分割が区間の端 0.8·a0 / 1.2·a0 をそのまま返していた。端に張り付いたら その端を新しい a0 にして画素の選び(縁の除外の輪)ごとやり直す。8 回で内側に収まらなければ ValueError
tests/conftest.py
- L28 — ★ Escape Studio’s settings to a disposable ini for the whole session. # ————————————————————————— #
QSettings("Fullseye", "Studio") writes to the native store (on Windows, the registry HKCU\Software\Fullseye\Studio). We had placed the isolation in individual test files, so a file where it was forgotten polluted the user’s real registry. An audit on 2026-09-05 confirmed actual harm: 8 of the 10 recent_files were pytest temp paths, and real values like system\operator_timeout_ms also remained. (Isolation was in only 2 of 3 files, and test_studio_params.py passed through.) Stop adding it individually and place just one, here, as a session autouse. The environment variable is the only entrance that studio._settings() looks at, so this covers all tests.
- L44 — ★ Declaration of tests that need an optional backend. # ————————————————————————— # The CI note long said “do not install torch/kornia (corresponding tests graceful skip)”, but a measurement on 2026-09-05 showed that was not true —— the target tests did not skip but failed with
ImportError: this operator needs the optional 'torch' backend (14 of them). There was only a note, and no mechanism to verify it mechanically. Here we consolidate the declaration into a single entrance. The aim is both directions: * an environment without the backend -> skip (make the note true) * an environment where the backend should be present -> do not allow skip, make it fail (FULLSEYE_REQUIRE_OPTIONAL=1. The CI py3.11 job sets this) With only one direction, a genuine regression quietly turns into a skip (the same form as 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 は非連結を撃つ探針。
- L282 (ja) — ★特異行列は必ず置く。 一度ここから外しかけたが、それは誤りだった ——
tb_mat_cond が特異行列で inf を返すのは契約どおりで、ops.py の NONFINITE_IS_MEANINGFUL に「厳密に特異な行列は s_min=0 なので inf が 正しい答え。有限に潰すと『十分に良条件』と読めてしまう」と既に宣言済み だった。落ちていたのは op ではなく、有限性ゲートがその台帳を見ていない こと。探針を削って緑にするのは、欠陥を隠す行為。 (同じ註に 2026-09-05 の教訓が書いてある ——「自分の probe では特異行列を 作っていなかったので tb_mat_cond を取りこぼした」。探針から外すのは その取りこぼしをわざと再現することになる。)
- L400 (ja) — ★新規(2026-09-14): ここまで探針が無く、契約ゲートを一度も通っていなかった 5 sort = 101 op。残る 6 sort(video / qimage / cimage / lightfield / beatcube = 50 op)は形が複素・4-D で退化形の設計に手間が要るため、 一度に全部入れて切り分け不能にしないよう次の段で足す。
- L408 (ja) — ★第 3 段(2026-09-17): 戻りの橋
feature_to_img が入るまで、feature を 入力に取る op は 1 本も無かった(作る op は 125 本ある)。門が「探針の 無い op が 1 本に増えた」と正しく落ちて教えた。
- L453 (ja) — ★2026-10-07: ここに
return があり、上の docstring(sort 既定の帯を捨てない) に反して override のある 10 op は sort 既定の帯を一度も通っていなかった。 sort 既定は「拒否が明示の fail-closed で記録される」ことの検査として通す (test_op_contracts.KNOWN_FALLS_BACK_ON_EDGE に by-design として載る)。
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_acquire_contract.py
- L45 (ja) — ★「開く実装が在る」と「入っていないときに何を入れればよいか言う」は別。 上の門は opener の存在を見るが、SDK が無い機械で呼ばれたときに何と言うかは 見ていなかった。2026-09-25 に接続の 3 層(protocol / image source / driver)を 揃えたとき、
comm は cclink に「install ‘None’」と言い、device は 9 driver に 入口すら持っていなかった。同じ問いに答える層は、同じ約束をすること。
- L166 (ja) — 16.003663…**。★「16 倍」と書いて落ちた —— 器の幅と有効ビットの比は 2^4 ではなく (2^16-1)/(2^12-1) で、1 桁目から違う。
- L300 (ja) — ★「次は ## デバイス制御」と決め打ちしていたため、あいだに節を 1 つ足した だけでその表の行まで backend 行として読んでしまった(2026-09-24)。 節の終わりは次の見出しであって、特定の見出しの名前ではない。
- L323 (ja) — ★「見つける」は「開く」とは別の問い。1 列にまとめていたせいで、 開けるのに一覧に出てこない zed / kinect が表では ✓ のままだった (2026-09-25)。列の中身は AST から数えた実際の分岐と突き合わせる。
- L437 (ja) — ★ここまでの門は「acquire が持っている綴り」からしか数えていない。規格の全数を 分母に置くと、そもそも知らない形式が見つかる —— 実際これで 10 bit 非詰めの Bayer 4 形式が丸ごと抜けていた(2026-09-24)。台帳は EMVA が無償公開している 「GenICam Pixel Format Names and Values」の単板 59 形式。
- L484 (ja) — ★最初ここに「詰め形式は容器 = 有効」と書いて、この門に捕まった。実際は 2 通りある: (a) 10/12/14 bit の非詰めが 16 bit 容器に入る場合と、 (b) grouped(GigE Vision 1.x の
Packed)の 10 bit が 12 bit に 入る場合 —— 2 画素 = 3 バイトなので 1 画素あたり 12 bit になる。 真の lsb packed(p)だけが容器 = 有効。
- L516 (ja) — ★機能名はベンダの名前ではなく規格の名前なので、1 本の語彙表で GenTL を出す 全ベンダを覆える。だからこの層は「どのベンダの SDK を入れたか」と無関係に 検査できる —— 模擬ノードマップで足りる。実機が無いことは言い訳にならない。
- L678 (ja) — ★SDK のバッファを指したまま返すと、次の 1 枚が前の 1 枚を書き換える。 例外は出ない —— 絵だけが入れ替わるので、連写を保存して初めて気づく。 実機が要る経路なので実行では確かめられない。ソースで確かめる。
- L716 (ja) — ★複製が要らない backend と、その理由。黙って外さない。
- L772 (ja) — ★SDK を採点したのと同じ物差しで自分も採点する。違う物差しで測った数を 並べると「SDK より厚い」が意味を失う。しかも自己申告にしない —— 各軸が どの入口で満たされているかを実在する名前で名指しし、門がそれを引く。
- L821 (ja) — ★列挙軸の一番大きな穴はここだった。
_enumerate("genicam") は [] を返していて、 GenTL を出す全ベンダを覆える唯一の経路だけが列挙できない状態だった。 GenTL 1.6 が「プロデューサのインストーラは GENICAM_GENTL{32/64}_PATH に自分を 足す」と決めているので、こちらはその変数を読めばよく、ベンダごとの表は要らない。 実機も SDK も無しで検査できる —— 変数と .cti という名前のファイルがあればよい。
- L875 (ja) — ★
__all__ は「何を公開したか」の一次情報(dir() は環境で変わる)。だから 本体が増えたのに __all__ が増えない、という遅れは静かに起きる —— 実際に 2026-09-25 まで 7 つ足りていなかった(追記のつもりが当たっていなかった)。 門は台帳側でなく本体側から数える。
- L947 (ja) — ★
opencv backend が開くのは UVC の装置。その規格が制御の名前と、いくつかは 単位まで決めている。単位が SFNC と違うので、換算を往復で確かめる —— 100 倍の係数を書き忘れても例外は出ず、露光だけが狂う。
- L1162 (ja) — ★門そのものを呼んで、本当に落ちることを確かめる(式の真似ではなく)。
tests/test_annotate_bold_italic.py
- L59 — ★ Overstriking only thickens sideways. An outline that thickens up and down fills in the counters of CJK text (measured 2026-09-09: 11pt “quantity value area” became a black blob).
tests/test_aoi.py
- L145 (ja) — ★平均は保たれない(被写体と感度に相関があるとずれる)。実測 8.9 %。
tests/test_api.py
- L226 (ja) — ★台帳をまるごと外すと「層が現れない」で落ちる —— この門が見張る事故そのもの。
tests/test_astrostack.py
- L1053 — ★ 2026-09-08: a 3rd return value, vote_margin (2nd-place peak / 1st-place), was added. For a starfield the peak should be single and thus small —— fix that here too.
tests/test_backends_typed.py
- L71 (ja) — ★2026-10-07:
or True で無効化されていた。実測 936 op / 重複 0 —— 主張は成り立つので門に戻す
tests/test_backends_typed_liveness.py
- L57 — ★ For this one, there were 3 records —— here,
gen_op_figures.DOMAIN_MISMATCH, and the op’s own measured 0/60. Even so, the state of “registered yet never runs” continued. Knowing something and using it in a decision are different (KNOWN_ISSUES §42).
- L129 (ja) — ★2026-10-07: 探針を作れず
_live_report が検査せずに飛ばす tb_* op の台帳 {op: 理由}。 以前は skipped を返すだけで誰も見ておらず、探針の無い op は生死の検査を黙って抜けた。
- L725 (ja) — ★2026-10-07: 例外で抜けた組は検査していない —— 何組を実際に見たかに下限を置く (実測 159 op × 5 入力 = 795 組、例外 0)。
tests/test_blob2d.py
- L443 — ★All three objects must have different shapes. A seed of the same shape lined up makes circularity and holes all return the same value, hiding an “op that returns the same number for any knob”.
tests/test_caltab.py
- L121 — ★Whether the gate fires is environment-dependent, so do not assert it. Only check that the value is returned without being hidden.
tests/test_capabilities.py
- L167 (ja) — ★2026-09-24 に見つけた穴: 既存の門は frontmatter の
ops: に書いた名前が実在 するかは見るが、本文のコードは一度も実行していなかった。だから measure_pos(img, row=32, col0=0, col1=127)(実際の引数は測定線ハンドル)、 fs.frame_align([a, b])(実際は (reference, frame) の 2 引数)、 fs.ledger.blob_count(mask)(blob_count は台帳ではなく 2-D の進化 op)が 3 本とも走らないまま出荷されていた。名前の実在と呼び方の正しさは別物で、 前者だけの門は後者に構造的に盲目([[feedback_registered_only_gates_miss_unregistered]])。 走らないことが正しい例もある —— 利用者自身の写真や校正板の角点が要るもの。 それは理由つきで名指しする。名指しの無いものが 1 本でも落ちたら赤。 「ファイルが無いから仕方ない」を既定にすると、呼び方の誤りがそこに紛れる。
- L183 (ja) — ★2026-09-25:
io は例のなかで fs.open_driver("io-memory") から開く ようにしたので、免除の理由はロット画像だけに縮んだ。
tests/test_chain_type_contracts.py
- L222 (ja) — だけなので、格子も積分時間も最小で足りる。★二重スリットは「縞が 3 本 入らない」と fail-closed するので、スクリーンの幅と分離を検証済みの 組み合わせ(550 nm / 200 um / 200 mm / 5 um 画素)で渡す。
tests/test_ci_wheel_check_paths.py
- L68 — ★Do not look at returncode. What this check targets is argument resolution, not the contents of the wheel. Judging the contents depends on the environment —— measured 2026-09-05: in an environment that exposes the source via PYTHONPATH, because the script drops the repo root from sys.path, some modules cannot be imported and it fails (this does not happen in a pip-installed environment). Because returncode was being looked at here, on Linux this check was failing in a way that made it look like a “path resolution problem”.
tests/test_collection_sizes.py
- L65 — ★OPS3D is a flat table of {op name: metadata dict}. Counting it as
sum(len(v) for v in values()) yields the total number of metadata keys across all ops (2,492), which would have carved a meaningless number into the ledger (2026-09-08; I noticed by looking at the structure before writing).
- L85 (ja) — ★2026-09-25 追加: 通信の名簿(
comm.protocols)は数えていたのに、 駆動の名簿は数えていなかった。接続の 3 層(protocol / image source / driver)のうち 1 つだけ見ていない状態で、 driver が 1 行消えても誰も気づかない。
- L91 — ★Added 2026-09-08: two ledgers that accumulate descriptions. Descriptions are what quietly shrink most, so count them here (the source of docs/CAPABILITIES.md and docs/HARDENING.md).
tests/test_comm.py
- L135 (ja) — ★1 本だけ見る門は、1 本だけしか守らない。 ここには長いあいだ
test_cataloged_protocol_gives_install_hint が在り、ethernet-ip の断り文句 1 本だけを見ていた。その陰で cclink は 「install ‘None’ and use the None client directly」と答えていた —— pip 名も import 名も持たない 1 行が、場合分けの外に落ちていたからである ([[feedback_one_probe_input_is_not_coverage]])。全数で見る。
- L141 (ja) — ★「相手が居ない」は「扉が無い」ではない(device 側で先に踏んだ): native な protocol は本当に繋ぎに行くので、
OSError は扉が在る証拠として通す。
- L209 (ja) — ★捕まえられない例外は、無いのと同じ。
fullseye.open_channel は facade に 在るのに、それが投げる CommError は 2026-09-25 まで facade に無く、利用者は 内部モジュール名 comm を import しないと except に書けなかった。 1 つずつ足すのではなくクラスごと閉じる —— __all__ が公開の一次情報で、 そこに在って facade に無い名前は、書いた本人しか使えない。
- L214 (ja) — ★免除は理由つきで名指しする。
comm.register(protocol の登録)を facade に 出したら、既に在った fullseye.register(点群のレジストレーション op)を 上書きした —— 出荷していれば利用者の点群処理が静かに別物になっていた (2026-09-25、既存の例の門が捕まえた)。同名は譲らず、内部名で使う。
tests/test_connectivity_doc.py
- L96 (ja) — ★ここは長いあいだ
あり(= その lib が import できるか)の欄で、 機械ごとに違うので門が見られなかった —— 誰も検査しない欄が表に 1 列在る状態だった(しかも中身は kind == native の写しで、pyserial を 入れた機械では嘘になる)。2026-09-25 に「実装」(Fullseye 自身が開けるか) へ替えた。版で決まるので、どの機械でも同じ答えになる。
- L168 (ja) — ★入口の名前は実装の台帳から引く。表に手で書いた名前が古くなると、 「証拠が消えた対応済み」になる。
- L213 (ja) — ★門を壊して確かめる —— 「通るだけの門」と「何も見ていない門」は区別できない。 (節, 壊し方, 期待する文言)。壊すのは表の側で、判定は本物の関数を呼ぶ。
- L222 (ja) — ★実際に踏んだ形 —— 名簿には載るが開けない driver を「開ける」と書く。
- L352 (ja) — ★名簿が「在る」と言うのと、開けるのは別の問いだった。2026-09-25 まで
capabilities() の available 1 欄が両方を兼ねており、dynamixel_sdk を入れた 機械では available: True なのに open_driver("dynamixel") は「その SDK を直接 使え」と断った —— 読んだ人は「対応済み」と受け取る。acquire は既に implemented / available を分けて持っていたので、先に正しかった層の語に 合わせた。ここではその欄が実際の口の振る舞いと一致することを見る。
- L73 (ja) — ★2026-10-07: 0 サイズ入力で本体が NaN/Inf を出し、guard が記録して置き換えている op。
test_no_op_returns_a_non_finite_value_for_an_empty_input は guard 越しの戻り値だけを 見ていたので、置き換え後の有限値しか見えず、この 16 op の 0/0 を一度も捕まえていなかった (docstring の「0 除算の検出器」は空振りしていた)。台帳(source=output)で数える。 いずれも空配列の縮約(平均・比・最大)を素直に書いた形 —— 明示の拒否にするのが筋(bug-suspect)。
- L78 (ja) — ★2026-10-07 同日に 16 → 0。内訳: 9 op(area_frac / gray_histo_abs / intensity / sk_blur_effect / hx_estimate_* 4 本 / tb_superquadric_residual)は本体の 0/0 を明示の ValueError に、 残る tb_* 7 本は本体は既に正しく拒否していて、橋の後始末
backends_typed._fallback が 空配列の平均 = NaN を返していた(空なら 0.0 に直した)。器は残す —— 次に見つけたらここへ。
- L89 (ja) — ★スカラに「0 要素」は無い(2026-09-17、戻りの橋
feature_to_img で feature が初めて入力になったときに気づいた)。この門が探している のは 0/0 なので、空配列の代わりに分母を 0 にする値 0.0 を渡す。
- L147 (ja) — ★2026-10-07: 例外で抜けた op は戻り値を検査していない —— 母数が黙って縮まないよう下限を置く
- L208 (ja) — ★2026-10-07: 例外で抜けた組は検査していない —— 下限(実測 1738 / 1738)
- L244 (ja) — ★2026-10-07: 母数の下限。注意 —— guard は FloatingPointError も握って fallback にする (実測 36 op)ので、ここの FloatingPointError 枝には guard 越しでは来ない。 0/0 が外へ出る op は test_no_op_returns_a_non_finite_value_for_an_empty_input の KNOWN_NONFINITE_ON_EMPTY_INPUT(台帳の source=output)が捕まえる。
- L306 (ja) — ★2026-10-07: 以前は呼ぶ前に数えていたので、全 op が例外で抜けても n > 700 で緑だった
- L315 — ★What makes this tricky is that the defect this test guards against does not reproduce on Windows. Measured 2026-09-05: on Linux (Ubuntu 24.04 / py3.12 / PyPI wheel) 3 ops SIGSEGV on degenerate input. Feeding the same input to Windows crashed none of them. So “local is green” is no evidence, and it must be kept in a form where you can verify that the ledger is actually taking effect on both environments. ————————————————————————— #
- L322 — ★The counterpart to
ops.NATIVE_CRASHES_ON_DEGENERATE. It must match the main table 1:1. Changing only one side fails —— removing from the main table, or adding to it, requires rewriting here at the same time (= a human confirms the intent). Why a counterpart is needed: in gate mutation testing (2026-09-05), even after removing cv_cc_count from the main table, the test checking “every op in the ledger has a guard” still passed. An op removed from the ledger also drops out of the loop’s targets, so the entire check path disappears with it. The SIGSEGV being guarded is Linux-only, and on Windows a decent value happens to come back, so the last line of defense also fails to work. Only equivalence with an independent source (this set) catches both directions even on Windows. Same shape as test_the_two_nonfinite_ledgers_agree.
tests/test_demops.py
- L440 — ★The return is always (N, 3). Even passing a scalar yields (1, 3), not (3,) —— because the ledger declares points = (N, 3) (2026-09-06; the fuzzer’s TYPEMISS exposed the mismatch and the implementation was aligned to the declaration).
- L755 (ja) — ★ 旧日本測地系に近い 3 パラメータでは、同じ緯度経度が地上で数百 m 動く
tests/test_derived_headlines_2026_10_07.py
- L58 (ja) — ★2026-10-07(CI で判明): registry の op 数は入っている backend で変わる(py3.10/3.12 の CI は 910)。 見出し(上)は同梱の名前表だけで決まるので常に照合し、registry 行は完全な registry の環境でだけ照合する。
tests/test_device_open_driver.py
- L36 (ja) — ★「相手が居ない」は「扉が無い」ではない。 この門を最初に書いたとき、
io-modbus が ConnectionRefusedError で落ちて 1 件挙がった —— が、それは 「PLC に届く口が在って、線の先に誰も居なかった」ということで、口が無いのとは 正反対である。だから「この install が実際に開ける driver」からの OSError は通す。一緒くたにすると、門は CI に PLC を繋げと要求し始める —— 繋がりようの ない要求をする門は、やがて外される。
- L83 (ja) — ★pip も import 名も持たない driver は名簿に無い(在れば、その行が 「何も分からない行」なので、ここで落ちてよい)。
tests/test_device_register_driver.py
- L135 (ja) — ★台帳の門は
len(device.drivers()) を数える —— 登録は runtime でそこに 入るので、後片付けを忘れた試験が 1 本あるだけで台帳の門が落ちる (しかも落ちるのは別のファイルなので、原因が遠くなる)。
- L142 (ja) — ★★数だけ見る門は差し替えに盲目。
dynamixel を自前のもので置き換えても 行は 12 のままなので、台帳の門は緑のまま通る。中身(何が implemented か) まで見て初めて、登録が残っていないと言える。
tests/test_docs_index_numbers.py
- L37 — ★The op set changes with the environment (Linux CI lacks torch/kornia/mahotas/xfeatures2d and has 859 ops; locally 885). A check comparing the locally generated docs against the live registry is only meaningful in a full environment —— same convention as test_opdocs: skip if not complete (the missing backend name appears in the reason). On the 2026-09-07 CI, 22 items failed on this. Environment-independent checks (file existence, content volume, figure existence) still run.
tests/test_docs_index_reachable.py
- L42 — ★The op set changes with the environment (Linux CI lacks torch/kornia/mahotas/xfeatures2d and has 859 ops; locally 885). A check comparing the locally generated docs against the live registry is only meaningful in a full environment —— same convention as test_opdocs: skip if not complete (the missing backend name appears in the reason). On the 2026-09-07 CI, 22 items failed on this. Environment-independent checks (file existence, content volume, figure existence) still run.
- L80 — ★Looking only at Markdown syntax falls short.
docs/GALLERY.md uses <img src="..."> in 14 places inside tables, and a naive scan for ]( sees none of them (found in Codex’s adversarial review, 2026-09-06). Also look at raw HTML.
- L189 — ★Allowing duplicate markers lets an old table stay behind while still going green. The generator only rewrites the first start–end, so the second stays forever old and keeps getting published (Codex’s adversarial review, 2026-09-06).
- L210 — ★It used to pass on “there are 20 lines and 4 dimension names are visible”, but that goes green even if hundreds of ops drop (Codex’s adversarial review, 2026-09-06). Reconcile against the actual count per dimension, down to the last one.
- L249 — ★Output where they differ. Without it, you cannot chase order-dependent failures (like registry pollution) that only fail in the full suite.
- L312 — ★With only counts and names, the type contract (in_sort/out_sort), category, HALCON correspondence, and tier all stay stale while going green (Codex’s adversarial review, 2026-09-06). RAG reads in_sort/out_sort to pick type-connectable ops, so if that is stale it confidently proposes a chain that does not connect. Reconcile including the contents.
- L400 (ja) — ★日本語版だけを見ていた門を 6 言語に広げた(2026-09-16)。
local_std を足した ときに ja/en/ko/tw/zh が 1,947 のまま落ちたが、de は落ちなかった —— ドイツ語の桁区切りはピリオドで 1.947 と書くため、"{:,}" では一致も 不一致も見えない。門が 1 言語にしか立っていないと、他の 5 言語は黙って腐る。
- L467 — ★Check that the output “has content” —— a gate that only checks agreement goes green even when both are empty # ————————————————————————— # Measured 2026-09-06. Falls below it and it fails (raising it is fine).
tests/test_docs_no_local_paths.py
- L36 (ja) — ★区切りは 1 つとも 2 つとも書かれる —— JSON の中では区切りが二重になる。 一重の形だけ見ていたので 2026-09-25 に二重の形を丸ごと見落とした (最大の漏れが公開 JSON の 164 か所だった)。
- L39 (ja) — ★ここに綴りの例を書かないこと。この門は自分のコメントも読むので、 例として書いたパスがそのまま違反になる(実際に一度そうなった)。
- L41 (ja) — ★
e:\n のようなエスケープ列と LaTeX の q:\, は道ではない —— 区切りの次が n/r/t で語が続かないもの、道に使えない文字で始まるものは外す。
tests/test_dsp.py
- L341 — ★The maximum is the harmonic: period / (1/f_max_bin) lands near an integer
- L371 (ja) — ★どれも閉形式の真値を持つので、「動いた」でなく「理論値と合う」で検査する。 ————————————————————————— #
tests/test_dualxray.py
- L178 (ja) — ★探針で見つけた: Pb 50 mm の e^{-130} を正規化して「ふつうのスペクトル」を返していた
tests/test_dynsys.py
- L112 (ja) — ★残差の正体は burn-in 。短い burn での誤差は 3 倍以上大きい。
- L123 (ja) — ★r の列を1 本だけ選ぶ。横に幅を持たせると、隣の r の不動点が 別の柝に見えて r = 2.9 でも「3 本」になる(一度それで誤判定した)。
- L66 (ja) — ★mesh_to_voxel は points_to_voxel が optional の torch を要る。CI には torch が無いので 拒否の確認(上)だけ走らせ、通常入力の実行は torch のある環境に限る。
tests/test_example_names_do_not_shadow.py
- L46 (ja) — ★2026-10-07(同日): 範囲を 2 つ広げる。 # ————————————————————————— #
tests/test_example_scripts_run.py
- L48 — ★2026-09-09, on the first CI after adding this gate, 7 failed on py3.12 (py3.11 was green). CI deliberately installs torch / kornia / mahotas / opencv-contrib only on py3.11 and not on other versions. The test side already had a declaration mechanism called
requires_backend, yet the gate that runs the examples did not have it —— that a mechanism exists and that every path goes through it are different things. gallery2d_* is a gallery that “runs all ops of that family”, so its very contract depends on which backends are installed (it hard-codes op names and reconciles against the registry, failing with “extra in OPS” if even one is missing). So declare per family. The remaining 2 use torch directly (fit_zernike / match_logpolar_z). In a full environment (CI’s py3.11, FULLSEYE_REQUIRE_OPTIONAL=1) a skip becomes a failure, so both over-declaring and forgetting to declare fail in both directions.
- L87 — ★Do not pass PYTHONPATH (the whole point of this gate). Users do not set environment variables.
- L126 (ja) — ★2026-10-07: 以前は全例を走らせていた。session fixture はセッションごと(CI のシャードごと・ xdist のワーカーごと)に作られるので、CI では 4 シャード × 3 版 = 12 回、全例を走らせていた (シャードあたり 21〜41 分、run 37474292595)。手元の -n 6 では 6 ワーカーがそれぞれ全例を WORKERS 並列で回し、最大 48 本が同時に走って単独 207 秒の quickstart が 600 秒を超えていた。 いまは (1) xdist のワーカーでは引かれた 1 本だけを走らせ、並列は xdist に任せる (2) それ以外(CI のシャード)では、このセッションに残ったテストの分だけをまとめて並列に走らせる。
tests/test_fallback_names_identify_the_op.py
- L60 (ja) — ★2026-10-07: 台帳は 256 件の環状バッファ。溢れると
fallbacks() は新しい 256 件しか返さず、 下の「名前が潰れていない」「実在の op 名」は一部だけを見て緑になる(実測 186 件・溢れ 0)。
tests/test_features_do_not_saturate_2026_09_26.py
- L82 (ja) — ★族は6 つ。対称な矩形だけだと、対称性で消える特徴(奇数次モーメント)や 穴を数える特徴(オイラー数)が原理的に動かず、「潰れている」と区別できない。
- L93 (ja) — ★どの族でも一定で、それが正しい op。理由つきで名指しし、下の試験が 「本当にまだ一定か」を確かめる —— 動くようになったら外させられる。
tests/test_fix_op_name_and_range_2026_09_02.py
- L75 (ja) — ★2026-10-07: [0,1] を外れるが、まだ
ops.UNIT_RANGE_IS_NOT_THE_CONTRACT にも載らず 正規化もされていない image op(所有者の判断待ち)。conftest.inputs_for が override の ある op にも sort 既定の帯を返すようにして見つかった。
- L78 (ja) — ★2026-10-07 同日に空になった:
tb_normals_to_egi(拡張ガウス像の計数、最大 48)は橋の出口で 総数で割って割合([0,1]、和 1)にした(backends_typed._egi_counts_to_fraction。公開関数 reprconv.normals_to_egi は計数のまま)。器は残す —— 次に見つけたらここへ。
tests/test_flyvision.py
- L328 — ★ The MTF identity is a small-footprint approximation and is NOT claimed
- L329 — ★ far from the optical axis: at ~35 deg elevation the measured transfer
- L330 — ★ already departs from exp(-…) by more than the on-axis tolerance. This
- L331 — ★ assert pins that hole so a future “curvature-corrected” resample has a
- L332 — ★ failing test to turn green rather than a silent regression to argue about.
tests/test_four_f_2026_09_26.py
- L202 (ja) — ★ナイキストのビンを 0 にしたので、この対称性は 1e-16 台で成り立つ
- L288 (ja) — この一覧に門がある種類。★
FOURIER_PLANE_KINDS に足したらここも足す。
- L383 (ja) — ★2026-10-07: 以前は finally で
sys.path.pop(0) していたが、読み込んだ PoC 自身が repo 直下を 先頭に足すので、pop で消えるのはrepo 直下の方で、examples/ がワーカーの終わりまで先頭に残った (event_camera の取り違えと同じ型の漏れ)。丸ごと保存して戻す。
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_gen_poc_viewer.py
- L366 (ja) — ★2026-10-30: 運動拡大の掃引は振幅を 40 倍にしても指標が 3.93 -> 3.97 で平らだった(64 px 用の読み出しを 160 px の動画に当てていた)。つまみを動かしても絵も指標も変わらないビューアは偽物なので止める。
tests/test_generative.py
- L66 (ja) — ★ head を変えると画布の幅も変わる(矢羽根の置き場が要る)ので、 2 枚を直接重ねることはできない。軸の長さで比べる。
- L84 (ja) — ★ std() は平均を引くので、定数でも 1 ulp 残る(実測 5.6e-17)。 「全部同じ値」を厳密に言うなら ptp(最大 − 最小)。
- L111 (ja) — ★ ptp なら厳密。本物の辺があれば 0.85 前後になる量なので、門は十分厳しい。
- L132 (ja) — ★許容を 1 つにまとめない。閉形式で厳密に出るものと、再帰で誤差が積もる ものを同じ物差しで見ると、どちらかの門が甘くなる。接触だけは深さ 5 の 再帰の末端なので相対 1e-5(実測 9.2e-07)。
tests/test_glassmirror.py
- L91 — ★It was counterintuitive: thinking “copper is redder than gold”, I wrote cu[2] < au[2] and it failed. Even by published values, against Au’s R(450 nm) ≈ 0.40, Cu ≈ 0.56, so copper has more blue (= gold is the more saturated yellow). It was this preconception, not the table, that was wrong.
- L175 — ★The reason wavelength was made the first argument (the ledger’s “data comes first” convention). Passing an array to the apex angle used to raise a bare TypeError.
tests/test_glyphops.py
- L256 (ja) — ★bbox は描いた後のインクから取る。PIL の text() は書体の ascent 分だけ 下げて描くので、指定した座標をそのまま bbox にすると字が縦にはみ出し、 無事な字まで「遠い」と出る(実測 0.058〜0.110、床 0.058)。
- L348 (ja) — ★ここで検査するのは 閉形式で言い切れること だけにしてある。 端から端まで(受理率・誤検出)の証拠は repo の外の実写 12 枚で取った (repo の外に置いた実写一式、正本 = glyph コーパスの curated/140)。 合成の場面を 1 枚こしらえて「動いた」と言うのはやめた —— 候補の生成は 局所標準偏差の分位点で切るので背景がざらついていることを要求し、四隅の 精密化は背景の勾配が小さいことを要求する。実写はその両方を満たすが、 素朴な合成(一様乱数の背景)はどちらか片方しか満たせず、合成で緑にすると 「合成に合わせた実装」になってしまう。
- L483 (ja) — ★比(中央値 ÷ 床)は環境で動く(Windows 3 書体 1.90 / CI noto-cjk 2.45)ので、 境にしないし、ここでも値を断言しない。載っていることだけ見る。
tests/test_graphinv.py
- L248 (ja) — 非正方の画像は形の検査で止まる。★正方の画像は重み行列と区別できない(全画素 > 0 なら 全結合として数える)—— 入力が配線であることは呼び手の責任で、op は形しか確かめられない
tests/test_halcon_named_shape_factors_2026_09_26.py
- L277 (ja) — ★同名なのに HALCON と別の量を返すもの。直す予定のものだけをここに書き、 「本当にまだ違う」ことを下の試験が確かめる(直ったら台帳から外させる)。
- L280 (ja) — ★2026-09-26:
elliptic_axis と diameter_region はここから外れた —— ユーザー 判断で「寸法を持つ特徴も HALCON と同じ画素値で返す」と決まり、量もスケールも 合わせたため(docs/KNOWN_ISSUES.md §51 は解決)。台帳を空にしても門は残す: 次に「まだ合わせていないもの」が出たとき、ここに名指しで載せる場所が要る。
tests/test_honest_summary_arithmetic.py
- L41 — Make it “skip with a reason if absent” —— ★the 2026-09-08 CI went red here: assuming what you have locally is also present in CI makes only local green (same pattern as
feedback_gate_computed_a_verdict_then_discarded_it).
tests/test_imgforensics.py
- L1064 (ja) — ★2026-10-18: 以前は float の [0,1] をそのまま渡し、古い Pillow がバイト列を読み替えて黙って通していた (Pillow 13 で発覚)。本物の 8 bit に直してから JPEG を通す。
tests/test_kendama_combo.py
- L21 (ja) — ★2026-10-02: 以前は examples/ を sys.path の先頭に入れっぱなしにしていた。同じ xdist ワーカーで後から
import event_camera した test_sensor_sims が、ルートの event_camera.py でなく同名の examples/event_camera.py(デモ)を拾い run_event_demo が無いと落ちた(ワーカーへの振り分け次第で出る)。 PoC はファイルから直接読み、sys.path を汚さない。
tests/test_knob_b_options.py
- L41 (ja) — 歴史側で試す点。★0.5 を含める —— 0.5 は「まん中」として既定値に使われて いる(
api.apply の既定、studio の中央、保存済みプログラムの初期値)ので、 ここが新しい側に落ちると既定のまま呼んだだけで答えが変わる。 最初 b < 0.5 で切ったら、gaussian と HALCON 別名の一致検査まで割れた。
tests/test_ledger_contracts.py
- L55 (ja) — ★同日の 2 回目: 探針側の builder(
ledger_contracts.probe_builders)で 2,055 / CI 相当 2,019 に上がったので床も上げた(床を据え置くと、builder が黙って外れても気づけない)。
- L61 (ja) — ★空入力(h)と効かないノブ(f)の探針は同じ 1 回の探針に相乗りさせる (引数と結果を使い回す)。別モジュールで回し直すとスイートが 50 s 余分にかかる。
- L419 (ja) — ★2026-10-12 方針 A: 黙って値を返す op(zz_gap_silent)と生の例外(zz_gap_raw)も門になった。 「空なら空」と書いて値を返す op・書かずに ValueError で断る op は通る
tests/test_llmcore.py
- L48 (ja) — ★許容差を入れない。-inf の exp は厳密に 0 になる。
tests/test_mathops.py
- L518 (ja) — tier1 16 + complex 18 + construct 8 + wave 6 + dynsys 6。★ここは op を 足すたびに動く行なので、足した理由を残しておく(35 = 複素平面の 面 8 op、43 = 定理が門になる図 8 op、55 = 波動 6 + 力学系 6、59 = LU/QR/Cholesky/一般の固有値)。
- L1109 (ja) — ★極は標本に乗れないので偶数格子で(零点と違って値が数にならない)
- L1485 (ja) — ★数学の図はきれいなので、合っているかを誰も確かめない。ここでは絵を一度も 見ずに、定理と既存 opだけで合否を決める。 ————————————————————————— #
- L1563 (ja) — ★円は (p/q, 1/(2q^2)) に載っているので、接触は 2 次元の距離で見る。 x の差だけで測ると 0/1 と 1/9 のような組を「接していない」と読む (距離 0.1111 対 半径和 0.5062)—— 最初これで落ちた。
- L1683 (ja) — ★ムーア曲線は閉じている(最後から最初に戻れる)。ヒルベルトは閉じない。
tests/test_mcp_images.py
- L331 (ja) — ★最初
ones + inf にしていて、有限部が定数なので免除 op でも「定数」判定になり 落ちた —— それは診断器が正しい。確かめたいのは「免除 op なら非有限を異常と 言わない」だけなので、有限部に変化のある入力にする。
tests/test_mcp_server.py
- L160 (ja) — ★引数名を
name にしていて _call(4, "fullseye_op_help", name="gaussian") が TypeError になり、subprocess の実 stdio 往復が 1 度も走らないまま 23 件が緑だった(2026-09-15)。走らなかった検査は無いのと同じ。
- L208 (ja) — ★最初
gaussian が先頭と決めつけて落ちた。gauss_filter と gaussian は同じ HALCON 別名を共有する別 op で、api.find_op は name == halcon の正典を優先する。 検索もその規約に揃えたので、正典が先頭・gaussian が上位に居ることを見る。
- L421 (ja) — ★以前の被験者は台帳経由で索引に入ったこと(= 索引が台帳を数えている)も見る
- L452 (ja) — ★2026-09-17 に
b は「未使用」から端の扱いを選ぶつまみになった。 ノートがその意味と歴史側の帯を両方書いていることを固定する —— どちらか片方だけだと、保存済みプログラムを読む人が挙動を誤解する。
- L494 (ja) — ★同日実測: 4 層で 480 枚が「どこにも無いノート」に見えたが、5 層目(ledger)で 480 / 480 が解決した。ここが 0 でなくなったら、まず引き忘れた層を疑うこと ([[feedback_search_all_tiers_before_declaring_a_gap]])。ノートの残骸と決めつけない。
tests/test_mcp_wheel.py
- L215 (ja) — ★数を直書きしない。9 本目(fullseye_fix_text)を足したとき、この門は CI の core ジョブでしか走らず、手元のスイートは緑のまま CI だけ赤になった(2026-09-18)。 正本は checkout の TOOLS —— wheel が同じ集合を名乗ることを見る。
- L225 (ja) — ★順位を 3 位までに固定していた門は、新しい op(gauss_quadrature、2026-10-03)が「gauss」に正しく当たっただけで CI の core ジョブ(ここでしか走らない)を赤にした。見たいのは「2-D レジストリの op が索引の層から出る」こと。
tests/test_meshres.py
- L107 (ja) — ★2026-10-07: ここにあった
abs(pc_density(P[inner])["nonuniformity"] - 1) < 1e-9 or True は or True で常に真だった。実測 1.9121 —— 内側だけを切り出すと、その部分集合自身の縁で 近傍殻が欠けるので一様にはならない(主張そのものが誤り)。上の spacing の検査が本題なので削除。
tests/test_msa.py
- L80 (ja) — ★この恒等式は交互作用を残すモデルの性質なので、モデルを明示して問う。 既定の “auto” は規格の手順に従って交互作用を誤差へ畳むことがあり、そのとき EV^2 は「升目ごとの分散の平均」ではなく「畳んだあとの平均平方」になる。 (この門は実際にその切替を捕まえた —— 既定を変えた瞬間に落ちた)
- L91 (ja) — ★★連鎖ファザーが
msa_anova_table の NONFINITE を実検出した(2026-09-23)。 正しい対処は「この op の非有限を許す」ではなく「どこに出るかを宣言する」 こと —— 丸ごと許すと二度と鳴らない門になり、将来 0 除算や自由度計算の誤りで 部品行や測定者行に NaN が漏れても捕まえられなくなる。 残差の F / p —— F = MS/MS_error の分母そのものなので検定できない 全体の F / p / ms —— 平方和の合計行で、検定対象の効果ではない 交互作用(測定者 1 人)—— df = (p-1)(o-1) が 0 で推定量が存在しない
- L525 (ja) — ★表の脚注が「α = 0.05 で判定」と書いているので、表の再現を名乗る門は その α を明示して通す(既定 0.25 の妥当性とは別の話)。この例題では F = 0.434 がどちらの α でも非有意なので、結果はどちらでも同じ。
- L794 (ja) — ★区間の端は標本の分位点なので 1/sqrt(n) で揺れる。実測(種 8 本): n=200,000 で標準偏差 10.0 / n=1,000,000 で 4.2。偏りではないので、n を 決めた上で揺れの 3 倍で採る(「小さい」ではなく「この n ならこの幅」)。
- L814 (ja) — ★境界を渡さなければ検査しない(勝手に 0 を下限と仮定しない)
- L863 (ja) — ★端点は位置の揺れを拾うので、幅でも別に見る(こちらは sd 0.0035)
- L887 (ja) — ★許容は測った揺れから取る。n=1,000,000 の半幅の標準偏差は種 12 本で 0.0035(位置は 0.0146)。1 本の種に 2 sigma を当てて落とすのは 3 度目の 同じ誤りなので、4 sigma = 0.014 で採る。
tests/test_no_local_paths_in_shipped_code.py
- L40 (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 — ★In an environment without hypothesis, an import failure in this one file stops the whole thing —— pytest aborts on the collection error without running the rest (2026-09-05; CI died in 2 minutes and not a single test ran). Drop to skip so it does not drag others down.
tests/test_op_contracts.py
- L53 (ja) — ★2026-09-14 実測: 901 op 中 151 本(16.8 %) がこの状態で、空ループを 1 周 しただけで緑を返していた —— 「門が判定を計算した直後に捨てる」の親戚で、 こちらは 判定を一度も計算しない。まず skip で見えるようにし、
test_probeless_ops_do_not_grow で本数を台帳に固定する(減る分には通る)。
- L57 (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 たちは「登録されているのに一度も実行されない」状態に戻る。
- L78 (ja) — ★2026-10-07: 契約電池で
backend_safe.guard の fallback に落ちる op の台帳 {op: (分類, 落ちる入力名の集合, 理由)}。 上の 3 契約(例外なし・有限・決定的)は op.fn をguard 越しに呼ぶ。guard は例外を 握って sort の既定値を返し、非有限の出力は置き換えてから返す —— だから op 本体が 例外を投げても NaN を出しても、assert の時点では「例外なし・有限・決定的」に見えていた (2026-10-07 実測: 936 op 中 46 op が電池のどこかで黙って fallback、うち 8 op は 疑わしい欠陥。inputs_for が sort 既定の帯を返すようにしてさらに 10 op)。 今は guard の台帳(backend_safe.mark / events_since)を見て、ここに無い (op, 入力)で劣化が記録されたら赤にする。台帳の op が電池のどこでも落ちなくなったら それも赤(直ったら行を消す)。入力名の集合は「これ以上増えない」上限として使う。
- L201 (ja) — ★2026-10-24: kornia 0.9 未満の環境でだけ 全入力で理由つきで断る op。
xkor_clahe: 0.8 以前の equalize_clahe は OpenCV の CLAHE と最大 0.46 ずれ、0.9 で直った (backends_kornia._clahe)。CI は最新の kornia を入れるので、そこでは上の台帳どおり tiny4 だけが 落ちる。古い kornia では「その拒否文で落ちた」入力だけを許す —— ほかの理由の劣化は従来どおり赤。 (2026-10-24 に xkor_dog / xkor_laplacian の tiny4 を台帳から消した: 鏡映を自前で足すようにして 4x4 でも走る。tests/test_kornia_version_drift_2026_10_24.py)
- L223 (ja) — ★2026-10-07: 宣言した out_sort の形を守っていない op(
test_op_honours_declared_sort の else 枝 = points/signal/matrix/video/qimage/cimage/… の 120 op を新たに検査して見つかった)。 (2026-10-07 同日に 3 op を直して空になった: 複素の sort を名乗る tb_angular_spectrum_propagate / tb_cx_apply_transfer_function / tb_fmcw_window_apply が、ops._wrap_unguarded の guard で実部だけにされ float64 を返していた。表は器として残す —— 次に見つかった違反の置き場。)
- L243 (ja) — ★2026-10-07(CI で判明): optional backend が無い環境の ImportError は「劣化」ではなく 「この環境では走らない」—— requires_backend と同じく skip(py3.11 の完全環境では失敗にする)。
- L279 (ja) — ★2026-10-07: 全体実行でだけ fallback する op(単独・同じファイル群では再現しない)。 KNOWN_FALLS_BACK_ON_EDGE は「必ず落ちる」の完全一致なので、ここに載せたものは「落ちてもよい・ 落ちなくてもよい」として扱う —— 門を黙らせるのでなく、原因不明であることを名指しで残す置き場。 sk_gabor: -n 6 の全体スイートで tiny4 @ (a=0, b=0) の出力 16 画素中 8 画素が NaN(1 回観測)。 単独・test_fix_gabor_dc / test_studio_params / test_fix_op_name_and_range / test_api_device と 同じプロセスでは毎回有限。前に走った何かが残す大域状態が疑わしい(未特定、見直し台帳に載せた)。
- L325 (ja) — ★guard 越しでは「例外なし」は自明に真 —— 劣化の台帳で本当に走ったかを見る
- L338 (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 の教訓が書いてある。
- L366 (ja) — ★guard は非有限の出力を置き換えてから返す(source=output で台帳に残る)。 上の assert は置き換え後を見ているので、台帳の側で「置き換えが起きていない」を確かめる。
- L388 (ja) — ★fallback の値は自明に決定的 —— 比べたのが op 本体の出力であることを台帳で確かめる
- L446 (ja) — ★2026-10-07: ここに else が無く、points/signal/matrix/video/qimage/cimage/counts/ keypoints/rgbimage/beatcube/lightfield/any の 120 op は何も検査されずに緑だった。 形の契約の正本は backends_typed._sort_ok(進化の橋の出口と同じ表)。複素の sort は dtype も見る(backends_bridge._COMPLEX_SORTS)。
tests/test_op_descriptions.py
- L258 (ja) — ★2026-10-11: 台帳・n-ary・facade(fullseye.all)にも同じ規則を広げる # ————————————————————————— # 変異探針で、上の検査は ops.REGISTRY しか見ておらず、台帳 op・n-ary op・facade の関数は 説明を消してもどの門も鳴らないと分かった。既存の欠けは docs/LEDGER_GAP_DEBT.json の “description” に固定し、増えたら落ち、直ったら台帳から消す(縮むしかない)。
tests/test_op_discovery.py
- L247 (ja) — ★2026-09-17 に 3 -> 5。1-D の局所標準偏差と mu 則圧伸を足したため。 新しい 2 件は 1-D 実装に 2-D を渡すと ValueError で鳴る(既存の
lowpass と同じ、正しい向き)。危ないのは逆で、下でその 1 つを固定する。
- L262 (ja) — ★フォールバックの警告は op ごとに 1 回だけ。同じワーカーで先に別の試験が fs.op.lowpass の フォールバックを起こしていると、ここで警告が来ず落ちた(2026-10-01、-n 6 の全体スイートだけで再現・単独では緑)。 試験の順序に依存しないよう、1 回目の警告をもう一度出せる状態に戻してから見る。
-
| L272 — ★It is not even a pass-through: the fallback returns after clamping to the image contract [0,1]. A signal whose negative half became 0 looks like a “filtered signal”, so this lies silently. max |
diff |
= 1.0, minimum -1.0 -> 0.0. |
tests/test_op_example_coverage.py
- L58 — ★A ratchet that counts the population from the shipped-artifact side (2026-09-06) # ————————————————————————— # Measured 2026-09-06. A stopper to not make it worse than this number, not a target. Of the ledger’s 1,002 ops, only 349 are in the example index, and the two “100 %” above held only because the population had 2 of 3 layers. History and per-family breakdown = docs/KNOWN_ISSUES.md §38.
- L32 — ★The op set changes with the environment (Linux CI lacks torch/kornia/mahotas/xfeatures2d and has 859 ops; locally 885). A check comparing the locally generated docs against the live registry is only meaningful in a full environment —— same convention as test_opdocs: skip if not complete (the missing backend name appears in the reason). On the 2026-09-07 CI, 22 items failed on this. Environment-independent checks (file existence, content volume, figure existence) still run.
- L203 — ★2026-09-08: exclude from the ledger and count separately any op that depends on the version of a third-party backend. This ledger is written in “the environment that made the figures” and verified in “the environment that runs the tests”. cv2 implementations change with the version, so a knob that does not work locally (opencv 5.0) works in CI (opencv-contrib 4.x) —— measured,
xcv_grabcut’s b was exactly that. The ledger may only assert things that hold in any environment. Do not assert version-dependent parts (a narrow but correct ledger is better than a lying one).
- L363 (ja) — ★optional backend(torch 等)が無い環境では、その op は「走らせられない」のであって「壊れている」のではない。 97 本おきの抜き取りは登録簿が増減するたびにずれるので、torch の要る op に当たる/当たらないが環境で変わる (2026-09-29: op が 2 本増えて tb_points_to_voxel に当たり、torch の無い py3.10 / 3.12 のシャードだけ赤)。 飛ばした本数は数えて、実際に走った本数で門を立てる。
tests/test_op_probe_ledger.py
- L76 — ★Added 2026-09-08. Until then this gate only built inputs for the 4 of image / region / color / volume, letting
contour 65 / points 57 / signal 26 / video 16 … 217 ops (24 % of the 901-op registry) pass through as “uncallable”. That “the gate stands in the right place” and that “the gate passes everything” are different —— on the first widening, it surfaced that tb_angle_3points can never run under the probe (registered as points->feature, but the actual entity takes 3 vectors).
- L85 (ja) — ★2026-09-17: 戻りの橋
feature_to_img で feature が初めて 入力になった(作る op は 125 本あったが受ける op がゼロ だった)。この門は「探針を作れず一度も走らせていない op」を 数えるので、sort を足したらここにも足す。
- L197 — ★The 2026-09-08 CI (py3.10 / py3.12, no torch) went red here —— because widening the probe to all sorts first reached an op that needs torch (
tb_points_to_voxel). “Broken” and “absent in this environment” are different verdicts, and mixing them turns an environmental difference into an implementation bug. In a full environment (FULLSEYE_REQUIRE_OPTIONAL=1), keep it as a failure as before.
tests/test_opdocs.py
- L212 — ★2026-09-03: since every backend’s _safe was consolidated into backend_safe.guard, judge by the structured marker the guard raises, not by string match on qualname (the guard also leaves “_safe(…)” in qualname, but that is for display).
- L769 (ja) — ★2026-10-12: 図が無い理由(
gen_op_figures.DOMAIN_MISMATCH の値)も T() を通すので、その表の原文もキーとして正しい
- L885 (ja) — ★2026-10-12: 本文の訳が 2,212 本そろい、実データに「本文だけ未訳」の op が無くなった (以前はここで実在の頁を 1 枚選んでいた → StopIteration)。将来 op を足した瞬間に通る道なので、 本文の訳を 1 本だけ外した状態で生成器を直接呼んで固定する(test_notice_when_nothing_is_translated と同じ作法)。
- L1238 — ★Why it was not found:
ops.REGISTRY (899) and the 2-D notes (899) agree, so as long as you count from the registry side it looks like “zero missing”. I once concluded that and was wrong. So this gate counts from the tier-spanning index side (memory: feedback_search_all_tiers_before_declaring_a_gap). ————————————————————————— #
tests/test_optdraw.py
- L285 (ja) — ★2026-10-15 から鏡は折り返した系の断面図(noncoaxial_drawing)に、接合レンズは組図になった(拒否しない)
tests/test_packaging_foundation.py
- L158 — ★2026-09-07: the local wheel had sample_sources_ai adding 42 MB (96 MB). The cause was a stale build/lib/ cache (leftovers from before it was removed from package-data get repacked). It is an accident a config-reading check cannot catch, so the actual wheel is checked by tools/ci_wheel_check.py (unshipped_present) and the size cap in ci.yml. The directory was also moved outside the package (tools/fops_article/). Here we require the exclusion to be explicit (as insurance).
tests/test_pivops.py
- L621 — ★Looking only at the name-level
PARAM_HINTS makes the gate narrower than the fuzzer. chain_fuzz._bind_args also consults OP_PARAM_HINTS, which targets by op name, so look at both here too (2026-09-06: after putting dic’s window / method into OP_PARAM_HINTS, it was actually bindable yet only here it failed).
tests/test_poc_scripts_run.py
- L57 — ★2026-09-08: drop the fixed 6 and match the CPU count. On shared runners (2–4 vCPU) 6-way parallelism only slows each one, without shrinking the total time, and once the PoCs grew to 84, each job hit pytest’s 900-second timeout (py3.10 / 3.12). Locally (12 cores) it runs as before at 6 or more.
- L73 — ★Do not pass
PYTHONPATH (2026-09-09). For a long time PYTHONPATH=<repo> was passed, but that is a setting users do not make, and it meant the gate stood one step away from where the accident happens —— by the same blind spot, examples/piv_flow_from_particles.py and others stayed as “ModuleNotFoundError when run straight from a checkout” (that side did not even have a gate that runs it, so it went unnoticed. test_example_scripts_run.py). On the PoC side, 108 of 116 add the repo root to sys.path themselves, and the remaining 8 only import fullseye, so all pass even after removing it (measured).
- L87 (ja) — ★stdin は /dev/null(2026-10-23)。渡さないと子は親(xdist の worker)の stdin = execnet の パイプを継ぐ。worker が死んだあとも子がそのパイプを握り、controller が「node down」の後に 固まる形になりうる(手元で torch+libiomp5md の子が消えないゾンビになった日に疑った経路。 再現はしなかったが、子に親の制御パイプを継がせる理由は無い)。
- L96 — ★On failure, also return the tail of stdout. A PoC prints its findings and “which check failed” to stdout before SystemExit(1), so with stderr alone you only learn “exit 1” with nothing else (2026-09-07 CI, py3.10 poc_ct_fidelity).
- L99 (ja) — ★stdout は 4000 文字残す。1200 だと章の後ろだけが見えて、前半で 落ちた検査の実測値が CI から読めない(2026-09-24、poc_endless_zoom の 10 番目が落ちたとき「NG が残っている(10 番目)」しか分からなかった)。
- L108 — ★2026-09-07: this long returned 0, passing straight through the
assert code == 0 below —— a gate that discards its verdict right after computing it (measured: 3 PoCs never print PASS —— poc_dic_strain / poc_photoelasticity / poc_thermography_ndt). Return -2 so it fails.
- L140 (ja) — ★2026-10-07: 以前は全本を走らせていた。session fixture はセッションごと(CI のシャードごと・ xdist のワーカーごと)に作られるので、CI では 4 シャード × 3 版 = 12 回、全本を走らせていた (シャードあたり 21〜41 分、run 37474292595)。手元の -n 6 では 6 ワーカーがそれぞれ全本を WORKERS 並列で回し、最大 48 本が同時に走って単独 286 秒の PoC が 600 秒を超えていた。 いまは (1) xdist のワーカーでは引かれた 1 本だけを走らせ、並列は xdist に任せる (2) それ以外(CI のシャード)では、このセッションに残ったテストの分だけをまとめて並列に走らせる。
- L156 — ★This gate runs the 84 PoCs in one batch (session fixture). That time is charged to the first test, so pyproject’s default timeout (900 seconds) fails on shared runners. Widen only here —— relaxing the default would also dull hang detection for other tests.
tests/test_printpath.py
- L332 (ja) — ★頂点より少ない標本は既定で拒否(長さが縮んで濃淡の再現が壊れる)
- L369 (ja) — ★完全な係数列で呼ぶ(打ち切ると尾のエネルギーが分からず予言が下界になる)。 parametrisation は “index” —— stroke_resample_closed がすでに弧長で 打ち直しているので、ここで “arclength” を選ぶと op が内部でもう 1 度 打ち直して別の輪郭の係数になる(弧長の打ち直しは冪等でない)。
- L454 (ja) — ★目標の濃さに合うペン幅を閉形式で解くと、偏りが桁で縮む
tests/test_profileops.py
- L206 (ja) — ★2026-10-07:
or True を外した。実測 none=-0.003086 < rigid=-0.001662 < 0.5*none=-0.001543
tests/test_public_reachability.py
- L76 (ja) — ★2026-09-14: この 13 本は 2026-09-05 から wheel に入っていなかったもので、 py-modules へ足した結果ここに現れた。演算子としては
unified._3DGS_OPS が _lazy_call(モジュール名, 関数名) で文字列から登録しているので、利用者には fullseye.vision.gsplat.<名前> 経由で届く(2026-10-02 訂正: fullseye.op.<名前> は存在しない。 unified registry を公開経路として数えたら 17 モジュールが島でなくなり行を消した)。 ここに残る 1〜6 本は各モジュールのデモ入口(render_*_gif など)で、op ではなく絵を作る側。だから内部専用に置く。 —— 「配布から消えていた」を直すと「公開経路から見えない」が現れる、という 二段構えだった([[feedback_registered_only_gates_miss_unregistered]])。
- L85 (ja) — ★2026-10-02: py-modules の数え漏れ(68 → 408 本)と facade 経路の数え忘れを直して初めて見えた 9 本。 内部の道具(CLI・ヘルプ書庫・n-ary の組立て・Studio の索引・標本データの取得・大画像の実行補助)、 api が別名で包むもの(mesh_decimate → mesh_decimate_preserving)、fs.. でだけ届くもの (pipeline3d の合成 op 6 本 —— 2026-10-02 に fs.<名前> から出して行を消した)。 (watershed3d の 3 本は 2026-10-02 に台帳 opssegmentation の watershed3d へ載せて行を消した。)名前>
- L98 (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。 表は空でも残す —— 「出すべきなのに出ていない」ものが次に現れたときの器。名前>
- L120 (ja) — ★2026-10-02: コメント行の
[[feedback_...]] で非貪欲の \] が止まり、py-modules 407 本のうち 68 本しか数えていなかった(339 本が門に映らない)。コメントを剥いでから囲みを取る。
- L130 (ja) — ★2026-10-07: optional 依存が無いと import できない出荷モジュール
{module: 許す欠落依存}。 以前は except Exception: continue でどんな import 失敗も母数から黙って外していた —— 壊れたモジュールは「不可視の関数」の数にも島の検査にも入らず、ラチェットはむしろ緑に寄る。 ここに無いモジュールの import 失敗、ここにあっても別の理由の失敗は赤。
- L164 (ja) — ★2026-10-02: 4 つ目の公開経路 = 知覚 facade(fullseye.vision.<群>.<関数>、halcon_facade_map.json の "module.func" が実体)。HALCON 章の実装(segmentation.py 等)はここからだけ届いていた。 py-modules の数え漏れ(68 → 408 本)を直した途端に 35 モジュールが「見えない」と出たが、 その多くは facade 経由で届く。利用者が呼べる経路は全部数える。関数>群>
- L172 (ja) — ★2026-10-02: 5 つ目の公開経路 = unified registry(
fs.vision.<名前空間>.<op>)。3DGS などの op は 文字列 “module.func” から _lazy_call で登録され、facade map にも台帳にも名前が出ない (sugar_mesh・tsdf_mesh・route_planning 等)。”module.func” 形の module 欄だけを数える (fs.apply('x') のような呼び出し式は関数名ではない)。
tests/test_pxrd.py
-
| L246 (ja) — ★a の門 5e-5 の余裕(組み込み時 2026-10-06 に雑音の種を 12 通りずつ振って実測): 誤差は雑音でなく較正の系統で決まり、 この像(傾き 5°・向き 30°)では −2.7〜−4.2e-5(種 6 は −3.2e-5)。種による散らばりは ±0.5e-5 程度で、24 通りの最大は |
4.2e-5 |
。 種は固定なので結果は決定的。門を締めると系統の偏りに当たり、緩める理由も無いので 5e-5 のまま。 |
tests/test_rag_by_ops.py
- L48 (ja) — ★問題集は文脈の表と同じ書き手が同じ日に書いた —— 独立な評価ではないので、床は「後戻りしない」ことだけを言う。
tests/test_raster.py
- L26 — ★A bare import aborts the whole collection in an environment where it is absent (measured 2026-09-05).
tests/test_raytrace3d.py
- L276 (ja) — ★2026-10-15: 傾いた鏡(摂動)の後で像面と平行に進む光線を、以前は rms 3.4e18 mm の有効な点として数えた
tests/test_roughness_robust.py
- L75 (ja) — ★α は op の定数を読まず、ここで ln2/π から作り直す(両辺に同じ入力を渡す門は無効)
tests/test_runner_scratch_families.py
- L38 (ja) — ★宣言された家族。key = “."、値 = 守り方の説明。 ここに無い関数が ``_bind_args`` を呼んでいたら、この門は落ちる。
tests/test_rust_abi_parity.py
- L402 (ja) — ★契約では FS_E_INVALID_ARG(引数が定義域の外)であって FS_E_TYPE ではない。
FsValueError を足すまでは両方 FsTypeError で、Rust が 1 を返すのに Python は 2 相当を投げる、という状態コードの食い違いが残っていた。
tests/test_sample_data.py
- L125 (ja) — ★台帳は前からあったのに、人が読む
docs/ops/SAMPLES.md には出ていなかった (2026-09-16)。表の列は id / 種別 / アクセス / URL だけで、ライセンスと商用可否は ソースを読まないと分からなかった —— 看板(「DL URL / ライセンス」)と中身がずれて いた。出す側を直したので、ここでは台帳が空欄を作らないことを固定する。 ————————————————————————— #
tests/test_scale.py
- L63 (ja) — ★d: 穴がタイル境界を跨ぐ画像。これが無いと領域 op(fill_holes / select_shape / fill_up …)がタイル分割で壊れることを検出できない —— b の穴(70:90)はどのタイルにも収まっているので、埋めた結果が一致して しまう。2026-09-17 にこの探針を足して、tile_safe と宣言されていた 6 本が誤差 1.0(全く別の結果)で割れることが分かった。 穴は 45..95 にとり、tile=64 の境界(64)と tile=60 の境界(60)の両方を跨ぐ。
- L71 (ja) — ★e: 細かい周期を持つ画像。変換ドメイン(ウェーブレット)・非局所平均・ LBP はここで初めて割れる。乱数でなく決まった模様にしてあるのは、 乱数だと対称性の破れが隠れるため。
- L77 (ja) — ★f: 小さな粒と穴が多数ある画像。面積で選ぶ op(remove_small_holes / select_shape / diameter_opening)は、粒がタイル境界で切られて面積が変わる ことでしか壊れない —— 大きな構造しか無い探針では 0.0 のまま通る。 種を固定してあるので実行ごとに同じ(乱数そのものを検査対象にはしない)。
- L81 (ja) — ★種は 2 つ持つ。1 つの種は「構造の 1 標本」でしかない ——
xsk2_isotropic_close は種 0 と 7 で誤差 1.0(全く別の結果)、種 1 と 20260917 では 0.0 だった。半分の種で割れる op を「タイル安全」と呼ばない ために、当たり外れのある探針は複数枚そろえる。
- L92 (ja) — (tile, halo) の組。★64/16 だけで測ってはいけない —— どちらも 8 の倍数なので、 8x8 の周期を持つ処理(順序ディザの Bayer 行列など)はタイルの位相がそろって たまたま一致する。実測で
dither_ordered は 64/16 で誤差 0.0000、60/12 でも 50/10 でも 37/7 でも 0.1429 だった。整列していない幅を必ず 1 つ混ぜる。 これを入れた 2026-09-17 に、tile_safe と宣言された 168 本のうち 16 本が 割れることが分かった(fill_holes など 6 本は誤差 1.0 = 全く別の結果)。 3 組目 (50, 8) はハローが狭い設定。「支持長がハローを超えるか」で決まる op(ウェーブレット再構成・大きな構造要素のモルフォロジー)は、広いハローでは たまたま一致するので、狭い側も試さないと分類が甘くなる。halo は利用者が選ぶ値 なので、「ある halo でだけ安全」は tile_safe と呼べない。
tests/test_scale_law_2026_09_26.py
- L46 (ja) — 宣言表 —— 成分ごとの尺度指数。★新しい op を足したらここにも書く(完全性を門で見る) ————————————————————————— # 周囲長を経由する量は、ラスタ化の偏りで p が厳密に出ない(docs/KNOWN_ISSUES.md §50)。 そこだけ許容差を広げ、理由を名前で残す。
- L86 (ja) — ★HALCON の同名演算子は正規化しない中心モーメントを返すので、本来は p=4 / 5 / 8 になる。この repo は 1 スカラーへ合成する際に Hu の正規化 不変量を使っており p=0 である(docs/KNOWN_ISSUES.md §52、巡 13 で直す)。 ここは あるべき値を書き、直るまで strict xfail で開いたままにする —— 免除台帳に「例外」として畳み込むと、直ったことに誰も気づけない。
- L101 (ja) — ★§52 が直るまで落ちる 3 本。
strict=True なので、直った瞬間に「予期せぬ成功」で 落ちてこの表を直せと言ってくる(黙って通り続ける免除にしない)。
tests/test_segcompare.py
- L120 (ja) — ★最初は逆に読んで赤になった —— 名前は閉形式の門(半分に割ると split が m/N)で固定してある
- L126 (ja) — ★scikit-image の precision は正解側の対で割っている(コードは truth x test の表の行和)= こちらの recall。docstring は「test の対で割る」と書くので、名前が入れ替わっている。 F 値は対称なので誤差そのものは一致する。
tests/test_segmentation_halcon.py
- L496 (ja) — ★2026-10-02: 同じ台帳に score(segeval)/world(segworld)のカテゴリが足された。HALCON の 9 本は 4 カテゴリの中にちょうど 9 本、他のカテゴリの op は segmentation.py の物ではない。
- L499 (ja) — ★2026-10-18(統合 8 第 2 波): 同じ「classify」カテゴリに cropweed の Fisher 判別 2 本が入った。HALCON 章の 9 本は 実体が segmentation.py の物なので、module で絞る(カテゴリ名だけで数えると汎用の判別が混ざる)。
tests/test_shapestats.py
- L196 — ★Free the plane, and a uniform spread on one side gets entirely absorbed (measured 4.9e-35). The midpoint moves only halfway and the plane moves there too, so it does not remain as a left-right difference. This is a limit of this definition, not a defect —— if you want to see it, give the plane from outside, or add a landmark on the midline.
tests/test_simcal.py
-
| L104 (ja) — n^1 * d^~1(位相 4 pi n d / lambda)。★d の指数が 1 から外れるのは Fresnel の項(n だけに効く)の分。 2026-10-18 に決まる組の重みを e/ |
列 |
→ e· |
列 |
に直した(下の test_g2determined_combination_weights…)ので 0.94 → 1.07 に動いた。どちらも 1 の近くなので、この門は直す前も後も通る幅にしてある(向きの検査は下の門)。 |
- L339 (ja) — ★種は乱数を引かない(探針の種は型名の順に同じ乱数列から作られる)
tests/test_spc.py
- L237 (ja) — ★台帳 opsspc は 2026-10-12 から 2 モジュール(spc と pod)を載せる。比べるのは 「spc モジュールの op」どうし —— pod 側の一致は tests/test_pod.py が見る。
- L247 (ja) — ★真値は導出した恒等式と既存 op。当てはめた数字を固定しない。 単位空間の MD² の平均はちょうど (n-1)/n で、教科書の「平均 1」を有限標本で 正確に言い直したもの。1.0 を固定する試験はどんな標本でも間違いになる。
- L320 (ja) — ★この列の std は 0 ではない。4.2 を 200 個並べただけで丸め屑が 1.3e-14 残る(実測)。
std == 0.0 で判定していた最初の版はここを取りこぼし、 その屑で割った距離が意味を失っていた。屑が在ることを門に書いておく —— 絶対判定に戻したらこの行が落ちる。
tests/test_specularity.py
-
L790 (ja) — ★2026-10-07: ここにあった max|a - 7b| < 7e-12 or True は or True で常に真だった。 実測 max |
a - 7b |
= 4.91(b は 1.4e-16)—— 画像だけを 7 倍してアルベドを据え置くのはモデル違反で、 残差は 7 倍の線形にはならない(主張そのものが誤り)。成り立つ向き = 「線形ではない」を測った値で固定する。 正しい線形性の形は下の c の検査。 |
tests/test_studio.py
- L948 — ★
setDefaultFormat only affects the no-argument constructor, and Studio’s QSettings("Fullseye", "Studio") was fixed to the registry —— this fixture isolated nothing (2026-09-05; pytest’s paths were left in the registry). Point the main-side entry studio._settings() at an ini via an environment variable.
- L2066 — ★Building
QSettings("Fullseye", "Studio") directly bypasses the isolation and writes into the user’s registry (real harm confirmed in the 2026-09-05 audit). Keep the settings entry point to one.
- L89 (ja) — ★UI 言語はプロセス全体の状態(studio._UI_LANG)。切り替えたまま返すと、同じ worker で後に走る test_studio_result_preview の note が hi / ko になって落ちる(CI shard 5、2026-10-25)。teardown で戻す。
tests/test_studio_ledger_runner.py
- L129 (ja) — ★2026-10-13: 抜き取りを「名前の SHA-1 の小さい順に 60 本」にした。等間隔の抜き取り (names[::len//60])は、前の方に op が 8 本足されただけで 60 本がまるごとずれ、 見本で走る数が 26 → 17 に落ちて門が鳴った(偏光の 8 op は 1 本も抜き取りに入っていない = 窓の欠陥ではなく抜き取りの揺れ)。名前の指紋で選べば、op を足しても既存の 60 本は 新しい名前が指紋の上位に割り込むときしか変わらない。この抜き取りの実測は 60 本中 22 本。
- L143 (ja) — ★返り値が None の op(tid2013_root はデータの置き場が無ければ None を返す)は、窓でも 「kind: none」で out = None になる。例外が出たかでなく値が返ったかで比べる (2026-10-05: 台帳が 63 本増えて抜き取りの 60 本がずれ、tid2013_root が入って鳴った)。
tests/test_studio_logic.py
- L22 — ★The old setDefaultFormat approach had no effect on Studio’s QSettings(org, app). Point the main entry point studio._settings() at the ini (for the whole session).
tests/test_studio_ops_browser.py
- L11 — ★A plain import aborts the whole collection in an environment without matplotlib (pytest won’t run the rest after a single import failure). Measured 2026-09-05.
tests/test_telecentric.py
- L38 (ja) — ★2026-10-15 まで raytrace.chief_ray は入射瞳を狙い、物体側テレセンでは ValueError で止まった。 いまは入射瞳が無限遠なら絞りを狙う —— この層の主光線と同じ像の高さになること。
tests/test_threshold_polarity_2026_09_26.py
- L35 (ja) — しきい値「方法」の名前。★op 名から拾うので、新しく足した方法も自動で門に入る (免除台帳に名前を書かない限り)。綴りで探す門は綴りが違うものを見逃すので、 説明文も一緒に見る。
- L43 (ja) — ★暗い側が答えで正しい op。理由つきで名指しする —— 台帳が黙って腐らないよう、 下の試験が「本当にまだ暗い側なのか」を確かめる。
tests/test_trust_block.py
- L151 (ja) — ★2026-10-12: ここは長らく
release=True(厳密一致)で呼んでいて、docstring の 「普段は 行 ≤ 索引」と食い違っていた。0.6.0 の後に op を 1 本でも足すと(pod 5 op) 凍結済みの 0.6.0 の行は直せないので、どの commit でも必ず赤になる門だった。 厳密一致はリリース直前に tools/gen_trust_block.py --release-check で見る (その意味は下の grown / shrunk の対で固定してある)。
- L159 (ja) — ★2026-10-18: 先に索引を版の行とぴったり揃えてから 1 本足す。揃えずに足すと「厳密一致で 何件落ちるか」が、リリース後にどの層が増えたかで変わる(ops3d の op は 2-D 橋 tb_* も 生むので registry も 1 増え、2 件のはずが 3 件になった —— 門ではなく数え方の偶然)。
tests/test_vacuous_assertions.py
- L62 (ja) — ★他の試験の docstring に
\* 等が在ると ast.parse が DeprecationWarning を出す。数えるだけの処理なので黙らせる (門の出力に無関係な警告を 84 ファイル分足さない)。
- L95 (ja) — ★書き下した列(
for img in (v, w))は、中身が何であれ空にならない。 中の名前が「呼び出しの戻り」でも、周る回数は 2 と決まっている。
tests/test_videostream.py
-
| L319 — ★Collins (VSAM 2000): both are relative to the current frame. Until 2026-09-05 this test expected the consecutive pair |
f[t-1]-f[t-2] |
, freezing an implementation bug as the spec (always all-zero for a uniform object moving at constant velocity – the regression test below). |
tests/test_volops.py
- L384 (ja) — ★2026-10-07:
or True を外した(実測: マスク外で vol と違う 7783 画素はすべて 0)
- L567 (ja) — ★これらは「HALCON がボクセル型を持たない」ことを理由に足した族なので、正しさの 根拠は幾何が保証する真値しかない。だから全部、真値の分かる形(球・立方体・ トーラス・既知 sigma の白色雑音)で検査する。 ————————————————————————— #
tests/test_wave.py
- L85 (ja) — ★J’_0 の零点と比べると合わない —— 取り違えを門で固定する
tests/test_wingpoc_gallery.py
- L172 (ja) — ★英語側は展示数を指す句に限定する。英語の数詞は散文に普通に出るので (two separate numbers / two opposite kinds)、広く拾うと誤検知だらけになり、 誤検知だらけの門は消される。日本語の「N 点」は展示を数える言い方なので広いまま。
- L252 (ja) — ★入れ替える 2 件は受入日が違うものを選ぶ。同じ日の 2 件を入れ替えても 何も壊れないので、それで「捕まえた」と言うと破壊試験が嘘になる。
textregion.py
- L92 (ja) — ★幅 1 のストローク(2026-09-27 実測: size 16 のフォントは縦の連が 1 px で、行の再現率が 雑音に依らず 0 % だった)。境界画素の 1 歩先が既に地なら、その画素だけの幅 1。 勾配は 1 px の棒では消えて向きが定まらないので、勾配を使わず 4 近傍で決める: 上下がともに地、または左右がともに地なら、その画素の幅は 1。
- L103 (ja) — ★2026-10-30: 「出来れば全 PoC を載せたい」。初版は 80 本で切っていた。台帳の PoC は手書きの見どころか この一括のどちらかに必ず載る —— 載らない PoC があれば理由(図が無い・数が無い・分類の無い翼)ごと止める。
- L45 — ★The catalog, hints and adapters have the shipped module
typed_catalog as the source of truth (2026-09-05). They used to live here, and backends_typed read them by adding tools/ to sys.path – as a result tb_* 143 op silently vanished in the wheel. The direction was reversed.
- L284 (ja) — llmcore(2026-09-24): tokens は画像パッチを種にする。★一様乱数だと どの行も似た向きになり、注意の重みが全行ほぼ一様になって「走ったが 意味のある出力でない」側に落ちる。滑らかな画像を 8x8 で切ると、 近い場所のパッチが近い向きを向く = 注意が構造を持つ。
- L305 — Event positions (point process) – the entry point of point_spectrum. ★Don’t use uniform random only: without a periodic component you never once exercise the meaningful behavior of an “op that finds periods”, so seed it with structured data mixing 12 unrelated events into a series with period 17.0 (this repo’s discipline that random-only tests hide structural defects).
- L503 (ja) — ★rng を 1 つも引かない —— 探針(ledger_contracts)は種を型名の順に同じ乱数列から作るので、 ここで乱数を引くと型名が後ろの種(image2d / matrix / signal …)が全部ずれ、他族の op の判定が 動く(2026-10-15 に実測: 無関係な 6 op が「拒否」に、11 個のノブの判定が入れ替わった)。
- L508 (ja) — ★design と同じく rng を 1 つも引かない(種は型名の順に同じ乱数列から作られる)。模型の観測は simcal の内側の固定の種(20261015)で作るので決定的。
- L813 (ja) — ★2026-10-13: TYPE_CHECKS[“pose”] は (R, t, info) の 3 つ組も pose として通す (register_spin / register_shot / register_cpd_rigid / icp …)。ここで 2 つに 展開すると、その組が引かれた連鎖で ValueError(seed 3_000_0xx、縞に近づく ハエの眼の 5 op を足して抽選がずれた回で露見)。先頭 2 つだけ取る。
- L946 — ★A point cloud with non-finite values crashes the KD-tree construction itself with a raw ValueError (scipy: “data must be finite”). The pool is designed to record NONFINITE and keep the values, so a dirty point cloud arriving here is expected – the side that builds it must guard. Hit for real on 2026-09-06: a new family was added, the way chains are walked changed, and at seed 3_000_0xx this path was struck and the fuzzer itself halted (not a defect of the op but a defect of the tool. The promise is that unbindable input is skipped, not raised).
- L1298 (ja) — ★単位空間は渡さない(渡すなら 3 つ全部)。渡さない形は「データ自身から 作る」訓練時の呼び方で、ファザーが最も広く回せる。
- L6930 (ja) — ★2026-10-18: 窓 3 つ + 厚さ 0 から始まる勾配。窓の番号(low / high)のノブは窓が 3 つないと どの値も同じ 2 窓を指し、min_log(素通しに近い画素を拒否する下限)は L が 0.01〜0.04 の画素が 無いと効かない —— 効く入力を渡す(効かないノブを台帳に載せない)。 窓は 120 kV で 20 / 40 / 60 keV(隣り合う狭い窓 20〜35 / 35〜55 では Cr と Mn の R が逆転し、 effective_z_map が単調でないとして拒否する —— それは op の正しい拒否で、ノブの検査にならない)。
- L7140 (ja) — ★obs2 の 2 点目は台車 0 の終点から (−0.15, 1.0) ずらした所: 射影の角 0.1 → 0.2 rad で終点と点の順が入れ替わり、 組紐語が変わる(角が「効かないノブ」に見えない入力。類が同じかは角に依らない —— それは門が別に見る)。
- L8120 (ja) — ★2026-10-11: file = 書き出したファイルのパス(write_wav の返り、read_wav の入力)。 述語が無いあいだ、write_wav が None を返しても誰も気づかなかった。
- L8242 — ★Until 2026-09-02 it was
lambda v: True = since the predicate is counted as “present”, it’s worse than absent (the inspection script also counts it as “has a predicate”). Measured, it let through even None / 42 / a string / a dict. The canon was decided by running all of the 6 consuming op (reprconv’s pairs_to_signal / pairs_to_image2d / pairs_to_table / angles_to_normals / shape_index_to_curvature / polar_to_cscalar): all 6 op accept only the two shapes above, and everything else becomes a named fail-closed with “pairs: must be (N, 2) or a 2-tuple of equal-length 1-D arrays” (measured). Since (2,N) is not accepted, the 3 adapters that were collapsing a 2-tuple into (2,N) with np.stack were fixed to axis=1. Two arrays of differing length (histogram’s counts/edges) are also not a “pair” and are rejected.
- L8374 — ★”Exactly 2 elements” is deliberately different from pose (which allows info via
len >= 2). Measured 2026-09-02: the 4 existing consumers that take a mesh as one argument (face_normals / vertex_normals / mesh_area / vertex_curvature) emit “mesh must be a 2-element tuple (vertices, faces)” for a 3-tuple, and cadmap’s _mesh and render3d._mesh_arrays also accept only 2 elements. In other words the canon for this repo’s mesh sort is a 2-tuple, and an extra element is not “more information” but a type-level lie that wipes out everything downstream. The sole exception voxel_to_mesh (which returns (v, f, n)) now has the canonical order extracted in ops3d.RESULT_ADAPTERS (treated the same as gicp / vol_label).
- L8583 (ja) — ★2026-10-11:
system キーに最適化後の処方(同じ object_mm = inf)
- L8585 (ja) — ★2026-10-15: 絞りと像面の前の面は平面(R = inf、lens_system の規約どおり)
- L8587 (ja) — ★2026-10-15: 図の values に処方の平面の R = inf と、無焦点の EFL / BFL = inf、 分散の無い媒質の ν_d = inf を写す(lens_system の規約どおり)
- L8590 (ja) — ★2026-10-15: 非共軸の系(raytrace3d)は面の R = inf・物体の inf を記録に持ち、 ゴーストの表・光線の束は「届かない光線 = NaN」(trace_rays と同じ規約)、 図の values にも平面の R = inf を写す。opd_samples は瞳の外 = NaN、 with_wavelength は処方(object_mm = inf)をそのまま返す。
- L8597 (ja) — ★2026-10-19: 照準 / ケラレ係数を設定した処方もそのまま返す(R = inf、object_mm = inf)
- L8599 (ja) — ★2026-10-18: .zmx から読んだ処方(lensfile)は lens_system そのもの(物体が無限遠 なら object_mm = inf、平面の R = inf、ファイル側の面の表の DISZ = INFINITY)
- L8602 (ja) — ★2026-10-19: 構成ごとに解決した処方も lens_system そのもの(R = inf、object_mm = inf)
- L8604 (ja) — ★2026-10-19: 硝材置換・大域探索は処方(R = inf)を入れ子で返す
- L8606 (ja) — ★2026-10-19: 最適化後の処方(R = inf)を返す
- L8608 (ja) — ★2026-10-20: 解を解いた・解を外した・afocal の・像面を曲げた処方(R = inf、object_mm = inf)と、 その解の一覧(R = inf の行)を返す
- L8631 (ja) — ★2026-10-11(tests/test_ledger_contracts.py が初めて全台帳 op を呼んで挙げた分のうち、 docstring が非有限を名指ししているもの)。どれも「無い・測れない・届かない」を 0 で埋めず nan / inf で言う設計で、実際に非有限だった欄と docstring の欄が一致する ことを 1 本ずつ確かめた。docstring に書かれていない非有限(world_camera の depth の inf など)は載せていない —— 台帳の負債(docs/LEDGER_CONTRACT_DEBT.json)に残る。
- L8755 (ja) — ★2026-10-07: プロセスごとに分ける。固定名だと xdist の別ワーカーが同じ捨て場を共有し、片方の テストが「中身を消してから、何か落ちたことを確かめる」間に相手が消す/書く(Windows では開いている ファイルの unlink が PermissionError)。
- L456 (ja) — ★探針が作る
text は "ラベル 73" のように相対パスとしても成立する。 台帳でパス引数を text と宣言している書き込み op にそれが渡ると、op は素直に cwd へ書く —— cwd は repo 直下である。ファザー側(chain_fuzz.run_chain) には 2026-09-23 から捨て場が在ったが、採掘側のここには無かったので 2026-09-25 に repo 直下へ xlsx が 2 本生まれた。仕組みが在ることと、 全部の経路がそこを通ることは別([[feedback_count_wrapper_families_not_mechanisms]])。
- L25 — ★Remove this script’s own location from sys.path. Python puts the script’s directory on sys.path[0], so launching from the checkout’s
tools/ lets things under tools/ (the non-bundled chain_fuzz etc.) be imported even in the wheel’s venv, and you end up counting in a state where “things not in the wheel are visible”. In the 2026-09-05 review, this is exactly why this gate missed the absence of tb_* 143 op. Together with that, move cwd to an empty temporary directory as well (the same thing happens if cwd is the checkout).
- L34 — ★Before moving cwd, remember the original cwd and resolve all argument paths against it from then on. Measured 2026-09-05: preflight passes absolute paths so it passed locally, while ci.yml passes relative paths so the dump was written away into a temp dir and compare failed with FileNotFoundError – the gate never once ran the comparison on the production call path. The 3rd time for “stand the gate where the accident happens”. Rather than fixing the caller, make it work correctly even when called with relative paths, closing off this whole type.
- L139 — ★2026-09-08: look at the editable side too. Until then
a["failed_backends"] was only collected and no one read it – caught in the same round as a hole of the same type as examplefig’s figure failures. The editable venv has many optional dependencies, so a backend can fail to import due to a version mismatch. In that case the wheel side merely “isn’t there from the start because the dependency is absent”, records no failure, and this comparison passes green. The op of the fallen backend silently vanish from the registry.
- L92 — ★This can be gotten wrong twice. The fuzzer’s
run_chain (1) treats the input type any as “always available” (drawing arbitrarily from the pool), and (2) op registered in OP_ARG_BUILDERS build their arguments themselves. Without counting these two, an op that actually runs every time gets reported as “structurally unreachable” (it did misreport fuse_to_voxel / register_cross). Reachability is not determined by “type alone” – part of the reachability path is on the code side.
- 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 — ★Lay down the range where 1 thread was fastest in semi-transparency. Place it first so it doesn’t hide the lines, and keep alpha low (if the band itself asserts too much, comparing the lines gets hard to read).
- L69 (ja) — ★「描く」= 機械に線を引かせる層(2026-09-22 追加)。「見せる」が人に見せる ための絵なのに対して、こちらはペンプロッタ・レーザー・刺繍のように 線でしか描けない機械への変換で、出口が G-code になる。
- L75 — English names of the categories. ★Even in the English version only the headings stayed in Japanese (measured 7 lines) – the body was translated with
title_en / _summary_en, but the headings were forgotten, making it a textbook “switched but Japanese is mixed in” case. Categories not present here are emitted as-is (don’t invent translations).
- L91 (ja) — ★レシピ欄がまだ無い能力(理由つきで名指し、免除は縮める側)。 レシピ欄は 2026-09-15 に当時の 16 件 + 新設 8 件 = 24 件へ付けた(ブランチ rag/recipes-and-help)。そのブランチが本線に入らないまま 1 か月が過ぎ、その間に 足された能力 32 件には欄が無い。2026-10-15 に移植したとき、その分の連鎖・限界・ 実寸校正を確かめずに書き足すことはしなかった(型の門は通っても、限界と校正の文が 実測でなくなる)。欄を埋めたらここから消す —— 消し忘れは :func:
load_all が落とす。
- L132 (ja) — ★型付きの連鎖で書けない能力(ファサードの API で、(画像, a, b) の op ではない)。上の「後で書く」 とは理由が違う: 推奨パイプラインの各段は OP_INDEX の in/out の sort で型検査されるが、ここは 仕様(辞書)を書き出す関数で、画像の連鎖の途中に置けない。限界は本文の「向かない」に書いた。
- L48 — ★The translation table lives in a separate file from the op docs. Using
opdocs.T would register every source string in opdocs.SEEN_STRINGS, and the existing “holes in the frame translations” gate would count all 604 of them as holes and turn CI red — that gate exists to keep frame strings complete in all five languages, while this one is a fill-as-you-go collection. Mixing them into one table lets one discipline break the other.
- L82 — ★One block = a run of
# comment lines that starts from a line containing ★ and continues at the same indentation. Sphinx-style #: comments are also picked up. Stripping only # and whitespace leaves a : at the front
- L84 — left behind, and “: ★…” appears in the output artifact (it actually did). Strip
: here as well.
- L128 — ★When the next ★ arrives, cut it as a separate block (keep one claim per block).
- L220 — ★Don’t translate the marker; fix it to
_(ja)_. Translating it per language makes it uncountable by machine – tools/i18n_status.py is a tool that counts “Japanese without a marker”, so if the marker changes per language, 593 lines turn into “hidden Japanese” (it actually did). ja is a language code and also conveys to the reader “this is Japanese”.
- L253 (ja) — ★2026-10-07: 言語版の目次 INDEX..md もノートではない(以前は 5 本を数えて 3089 本を 3094 本と書いていた)
- L281 — ★Take the set of notes from the ledger (don’t enumerate files). In the 2026-09-06 adversarial review (Codex), a version that globs files and counts stems mixed in one
docs/ops/SAMPLES.md (not an op note), and the index said 1,842 while the RAG guide said 1,843, publishing conflicting counts at the same time. Notes are generated 1:1 from records, so a name in records is itself the definition of “a name that has a note”. Agreement with the files is checked separately by tests/test_docs_index_reachable.py (detecting missing / surplus).
- L291 — ★
__all__, not dir(fullseye). dir includes module attributes (os / sys / warnings / annotations) and moreover increases by one after another test imports (1094 → 1095), so the drift gate fell only in the full suite (2026-09-06). The public surface is the 1,091 names the facade declares in __all__.
- L340 — ★The index is not only for humans but also AI’s search surface (the user’s 2026-09-06 remark “the index is also the part used as RAG, right?”). Since op notes double as the search corpus for AI coding assistance, make the machine-read entry point explicit in the index. Writing “all op” for something that has only half will make the RAG confidently wrong about the other half – that’s why the measured lines from
_honest() are not removed from this section.
- L498 (ja) — ★2026-09-14: 長らく かな だけを見ていたので、「Studio 北極星」「実測記録」 のように 漢字だけで書かれた題に印が付かなかった —— 非日本語版の読者は それを英語の題だと思ってクリックする(印を付けないのは「読めない」という 事実を隠すことで、無訳より悪い、というのがこの関数の趣旨そのもの)。 題は常に日本語版ファイルから取る(
_doc_title(rel))ので、漢字を足しても 中国語の題を誤って日本語と呼ぶことは起きない。
- L518 (ja) — ★2026-10-11: 訳文ファイル(
X.zh.md など)の題はその言語で書かれている。以前は 日本語版と同じく漢字で判定して (ja) を付けていたので、中国語版の索引で中国語の文書が 「読めない日本語」と表示されていた。印はファイルの言語で付け、自分の言語なら付けない。
- L529 (ja) — ★2026-10-11: 日本語の原文にこの言語の訳があるなら、訳の題と訳へのリンクを先に出す (以前は英訳があっても英語版の索引が日本語の題と日本語版へのリンクしか出さず、 読める版があることが索引から分からなかった)。原文が日本語であることの印は残す。
- L690 (ja) — ★Qiita 投稿用の frontmatter(— で挟んだ YAML)は題ではない。中の
title: 行は 下の走査では見出しにも読み飛ばし対象にも当たらず、そのまま索引の見出しになって しまう(「title: ‘…’」と並ぶ)。挟まれた範囲ごと読み飛ばす。
- L94 — ★Don’t let through status=fixed with no gate – so that this ledger itself doesn’t create a state where only the record of having fixed it remains while recurrence can’t be stopped.
- L196 — ★The link targets (
docs/hardening/*.md) are written in Japanese. Replacing them with an English title would be a lie, so emit the title as-is and attach (ja) – what a non-Japanese-version reader needs is not a “translated title” but the fact “this is unreadable”. Fix the marker to the form that tools/i18n_status.py counts.
- L41 — ★This is not “just a constant”: once the line integral p = Σ μ·Δx exceeds 10, exp(-p) drops below a photon count of 1, the logarithm saturates and p hits a ceiling (photon starvation). The first version placed μ at 0.55–1.0 “per pixel”, so p reached 30 and the reconstructed μ came out 50–84% low. The zero baseline (plain back-projection) won on Dice, and that’s when it was noticed.
- L166 — ★The per-material numbers are recall. They are “the fraction picked up within that material’s label”, not Dice (since false positives falling outside the label aren’t counted, calling it Dice would always drift toward 1.0). The overall misses / over-picking are given separately below as precision / recall.
- L65 — ★The winding order is outward. Reverse it and the normals point inward, and render_beauty returns pure black without raising an exception (the first version was like that, and only the thin-film sphere was black).
- L84 (ja) — ★2026-10-03: 運転の系列の集大成と「開かれた運転基盤」のために足した 2 分野。テーマ表は製造の表と分ける (共通の 1 枚に足すと、運転の「digital twin」が製造の予知保全の op に、製造の「reconstruction」が 3DGS に当たる)。
- L288 (ja) — ★2026-10-15: 実験計画・応答曲面・品質工学・感度解析(opsmultivar)。鍵は製造のクラスタ名に実際に出る語 (射出成形の「optimization」、加工の「optimization」「prediction」)—— 工程条件の最適化と予測は、文献では 直交表・応答曲面・感度解析で回す領域。
- L306 (ja) — ★2026-10-15: sim-to-real 較正(opssimcal)。鍵はクラスタ名に実際に出る語(慣性センサ・力覚の「calibration」、 鍛造・交通・レーダの「simulation」「modeling」)—— シミュレーションを実物に合わせる・センサを較正する領域。
- L320 (ja) — ★2026-10-15: 収束型の演算(opsconverge)。鍵はクラスタ名・葉の名前に実際に出る語(有限要素の「finite」= 格子の収束の検証、 霧・散乱・光線の輸送の「fog」「scattering」「transport」= 多重散乱のモンテカルロ、描画の「rendering」= 相互反射を収束まで)。
- L389 (ja) — ★2026-10-15: 10 月に足した op の系列(研磨・粉体・粉末 X 線)は、既存のテーマの語に当たらず文献層から 1 本も 指されていなかった。語はクラスタ名に実際に出るものだけを置く(当たらない語は当てない)。
- L535 (ja) — ★2026-10-03: corpus2skill は葉へ写すときに Authors / Date / URL の行を落とす(元の papers/*.md には在る)。 その結果、出荷した文献層の代表論文がすべて「— (n.d.)」になり、「新しい順」も日付なしで並んでいた。 葉の Source: が指す元ファイルから、欠けた欄だけを補う(元のパスは読むだけで、出力には書かない)。
- L651 (ja) — ★2026-10-15: ここはテーマごとに先頭 8 本で黙って切っていた。表の後ろに足した op(10 月の研磨・材料表・ ファイバ・触覚・peg-in-hole …)は対応表に在るのに文献層のどこにも出ず、表に書いたことが嘘になっていた (2026-10-15 時点の表 251 op のうち 21 本。うち 3 本は SPC のテーマの鍵がどのクラスタ名にも当たらなかった分)。 テーマは多くても 17 本なので全部出し、当たらないテーマは INDEX に名指しする(dead_themes)。
- L101 (ja) — ★2026-10-15: 上の TIO2 はルチル単結晶の常光線だけ(430 nm から・k なし)。成膜した TiO2 は非晶質か アナターゼが多く n が低い —— 膜の計算はこちらを名指しする(非公開の膜の PoC で、ルチルの n で膜を 解くと傾いた面の膜厚の偏りが小さく出ることを確認)。
- L145 (ja) — ★光収率の幅(
light_yield_range_photons_per_mev、2026-10-24): 文献の値のばらつきが「何の違い」から来るかを 読んだ材料だけに (下限, 上限) を入れる(CdWO4 と LYSO)。それ以外は None(幅が無いのではなく、確かめていない)。 CdWO4 の 7,800〜15,800 という低い値の多くは、減衰 13 µs に対して整形時間が短い(1 µs では光の 2〜3 割しか 拾わない)ことと、光電子数 phe/MeV(光検出器の QE と光の集め方を掛けた後)を光子数 ph/MeV と混ぜたことによる。 こうした値は幅に入れない —— 幅は「絶対値として測った値」どうしの違いだけにする。
- L151 (ja) — ★発光の形(
emission_components、2026-10-24): 室温・X 線/γ 線励起で FWHM を数値で書いた一次文献は 見つからなかった。幅は全部、一次文献の図から読み取った値で、成分ごとに digitized_from_figure の印を付ける。 1 成分 = 中心 [nm]・FWHM eV・積分の重み・測定配置(surface = 励起した面から出る光 / thick_crystal_transmission = 厚い結晶の中を通って出てくる光)・励起の種類(xray / gamma / uv)・ 出典。ガウスはエネルギー軸の形(Ce³⁺・自己束縛励起子の帯はエネルギーで対称)で、波長軸へは消費側 (dualxray.scintillator_sensor_qe)がヤコビアン hc/λ² を掛けて移す。同じ測定配置の成分の重みの和は 1。
- L157 (ja) — ★
center_nm はエネルギー軸の中心(hc/E_c)。波長軸の山はヤコビアンで数 nm 短波長に出る(BGO 480 → 468 nm)。 図の「極大」は波長軸で読んだ値なので、厳密には中心をやや長波長に置くべきかもしれない —— 差は Q̄ で 1.4 % 以内 (2026-10-24 に計算)で、調査で承認された値(中心 = 公表の極大)をそのまま使う。 幅の分からない材料(CsI:Tl / NaI:Tl)は None のまま —— 消費側は発光の極大の 1 本の線として扱い、そう 返り値に書く(幅を推測で入れない)。実測の発光スペクトルがあれば emission_spectrum= で渡す (CsI:Tl は 2.25 / 2.55 eV の 2 帯だと分かっているが、幅と強度比を確かめられなかった)。
- L539 (ja) — ★k だけを取る区間(n は次の出典のまま)。2026-10-15: RII の Hale & Querry の水は NIR を 0.2 µm おきにしか持たず、1.45 / 1.94 µm の吸収帯を線形補間で 1/3 に潰していた。n は滑らか なので Hale のまま、k だけ Segelstein 1981(同じ研究室の続き、細かい刻み)から取る。
- L105 (ja) — 任意キー。ここに無いキーは拒む(fail-closed)。★所属・勤務先・製品名の欄は 意図して持たない —— 報告者に求めない情報は、台帳に置く場所も作らない。
- L313 — ★This is a lower bound. Since it only looks at whether the op name appears as a literal in
tests/, sweep-type tests that scan the ledger and run all op (for name in ledger: ...) aren’t counted. Read it as “no named test”, not “no test”.
- L335 (ja) — ★報告が付いた行にだけ鍵を足す(空の台帳で出力を動かさない)。 repo 内の判定は別の鍵に残す —— 1 つの段に畳まない。
- L265 (ja) — ★fail-closed: op の一覧は台帳の本体。ここを「(section failed)」の 1 行で済ませると カタログが黙って空になる(pip だけの利用者の RAG はこのファイルしか持たない)。
- L90 (ja) — ★2026-09-17: 戻りの橋
feature_to_img で feature が初めて入力に なった。1 段で image -> feature を作れる op(intensity = 平均輝度)を 前置きにする。これが無いと図が「型が届かない」に落ちる。
- L99 (ja) — ★2026-09-17:
deskew は「傾いていないものは動かさない」op なので、合成の 標準入力(canonical_image)に掛けると in と out が同じ絵になり、図が 何も語らなくなっていた(実測: 標準入力 8 枚のうち 5 枚で恒等、図は恒等の 方)。走ったことと意味のある出力が出たことは別 —— 先に 7.0 度 傾けてから 渡す(rotate_img の角度は -45 + 90a なので a=0.5778 が +7.0 度)。
- L115 — ★2026-09-08:
tb_angle_3points and tb_indices_to_labels, which were in this table, were not “outside the figure’s domain” but op that must not be put on the bridge. The former takes 3 vectors so it can’t be called with a single point cloud, and the latter returns 1-D yet declares out as labels (→ volume = ndim 3). Both, while registered, had never once run, and fail-soft was returning plausible values. Moved to backends_typed._OP_BRIDGE_SKIP and removed from this table – there was a record that no figure came out, yet nowhere a record of the inability to run itself (there were two gates, and only one had noticed).
- L124 (ja) — ★2026-09-13: op が evolute 検証を得て厳格化。ECEF は地球表面(中心から ~6.4M m)の 座標を要るが、画像由来の合成点は原点付近で必ず楕円体の evolute 内に落ちるため 正しく拒否される(実データでは動く。合成入力では図を作れない恒久的な定義域ミスマッチ)。
- L127 (ja) — ★2026-10-04: 主点を 0.5 画素ずらすだけの橋(CARLA ↔ Fullseye の内部パラメータ)。3×3 で焦点距離が正の K しか受けず、 汎用の合成 matrix は fail-closed で拒否される(op_probe の探針 K では走る —— tests/test_backends_typed_liveness.py)。
- L140 — ★2026-09-07 (user instruction “there’s no need to consolidate into one image; things that are stepwise or have multiple conditions should be split out”, “for some things a pseudo-color is easier to understand”, “complex ones may even be an animated GIF”). In addition to the main figure
<op>.png: <op>.a.jpg / <op>.b.jpg — 3 images with the knob swept to 0.1 / 0.5 / 0.9 (only when the output changes; if it doesn’t change, the reason goes in the manifest) <op>.chain.jpg — a stepwise figure for an op that has a preceding op (image → intermediate → output) <op>.gif — when the output is video / light field / volume, showing frames / viewpoints / slices in sequence (the still <op>.png is the finished form and the GIF is additional; Studio’s QTextBrowser shows the first frame). Apply pseudo-color only to the output of a field of quantity (distance, phase, orientation, depth, curvature …), and write (viridis) in the caption. Filter types stay gray (don’t present them as a color-changing op).
- L756 — ★”It ran” and “a meaningful output came out” are different (2026-09-07, user’s remark “what’s with the pure-black out?”). If an empty array is counted as “has a figure”, a black slab becomes a figure. Record empty as empty and write the reason in the note.
tools/gen_view2026_pages.py
- L181 (ja) — ★2026-10-30: 2 つの展示の日本語が 10/27 から「???…」のまま載っていた(× と − も全言語で ? に)。 文字コードの往復で失われた文字は ? か U+FFFD になる。どちらも訳として通さない。
- L592 — ★2026-09-02: highpass / bandpass_image now follow the convention of returning “[0,1] with 0 mapped to 0.5”. Previously they returned a signed array called an image, and on save / inter-stage clip the negative half (about 50% of pixels) was silently crushed to 0. Record the fix by measurement, not conjecture: the minimum value and the fraction of negative pixels.
- L727 — ★2026-09-02: estimate_noise now returns in units of σ (previously it stuck at 1.0 for σ>=0.08, returning the same value for σ that differed by 3×). Lay down the line y=x so you can visually confirm “whether the return value is σ itself”.
- L840 — ★_panel_grid labels don’t wrap, and once they exceed the width they collide with the neighbor and become unreadable (with tile 262px / font 19-17px, one line ≈ 12 full-width characters at most). Push the meaning of the scale factor into the title and subtitle, and place only a short name and number on the panel.
- L1184 — ★2026-09-02:
area_center now returns, as its name says, the 3 components (area ratio, row, column) (until then it was just the single scalar area ratio and didn’t return the centre).
- L1186 — ★Since 2026-09-26 all 3 components are in pixels (area [pixel count], row [px], column [px]). Before that they were normalised to [0,1], and this code multiplied by (H-1) / (W-1) to get back to pixels (until the 2026-10-15 fix it went on multiplying the pixel values by (H-1)). The returned centre is drawn on the picture so you can see that it really is the centre.
- L1713 — ★Calling apply_cmap point by point normalizes within that single point so everything comes out the same color. Build a LUT spanning 0..1 once and look up from it.
- L1951 — ★2026-09-02: gabor now uses a fixed scale dividing by the kernel’s L1 norm, returning an absolute value comparable across op. Previously it divided by “the maximum absolute value in that image”, dividing by a different divisor per orientation, which crushed the magnitude of the response itself = the discriminative power across orientations. In exchange the return value falls in a narrow band at the low end of [0,1] (mean 0.007–0.030 for these 3 patterns), so pasting it as-is makes all 3 pure black. Show the picture stretched to the 1–99%tile, and put the pre-stretch measured values in the label numbers (the same convention as freq_sweep’s highpass panel).
- L2066 — ★2026-09-02: the 3 op became separate implementations. Previously all 3 rode on geom “zoom” with a mutual maximum difference of 0.0 / 4.9e-14 (= identical), and moreover b was dead in all 3. Now zoom_image_factor = 2 scale factors (height/width) / zoom_image_size = target size / rescale_img = isotropic scale factor + interpolation order. The canvas shape stays as the input for all.
- L3878 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L411 — ★Measure noise with :func:
astrostack.noise_sigma (a robust background σ). Using “RMS of the residual against the ground truth” lets even PSF shifts enter the residual – this experiment deliberately varies FWHM per frame, so changing the selection changes the post-stack PSF, and you can no longer tell whether the increased residual is due to noise or to the image changing (measured, the value moved 25.2 -> 61.3, but most of that was not noise). The background σ does not depend on the shape of the stars.
- L471 — ★The “maximum difference” doesn’t move for a single frame – because as long as recall is below 1, one missed pixel holds down the maximum as-is. How many pixels remain largely off from the ground truth and the total amount of deviation reflect the effect of the removal directly.
- L713 — ★ Laid out at native size, “2 detected” cannot be confirmed by eye (within 44x44, a pair 1.6 px apart is only a blob a few pixels wide). To avoid a figure that forces the reader to trust the detector’s claim alone, crop the same physical extent around each pair and zoom in.
- L844 — ★ The error map colors magnitude, not sign. The first version used a diverging colormap, but the error in this experiment is always positive, so “positive = the blue of right” resulted, giving the reverse meaning where a broken state is painted with the “correct” color. What we want to convey here is not direction but “how wrong it is,” so vary only the intensity of a single wrong color (and, so that meaning is not carried by color alone, also show symbols and numbers).
- L1417 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L573 — 5. ★A full loop across representations (the chain of conversions is exactly where lies appear) # ————————————————————————— #
- L599 — ★ “A shell, not a solid” must not be argued with a maximum-intensity projection —— MIP is the maximum along the depth direction, so even a thin shell looks filled inside (indeed we once drew it that way and nearly reported the barely-different numbers “volume 5768 -> shell 5608”). Whether the interior remains is stated by the central cross-section and the interior fill ratio.
- L862 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L2065 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L896 — ★ The physical size of the image plane the bars span. When set to 1.0 mm, 208 samples/mm = Nyquist 104 cyc/mm, so a 200 cyc/mm bar turned into a thick 8 cyc/mm stripe (the figure was aliasing itself). At 0.25 mm, 832 samples/mm, and even at the top frequency of 200 cyc/mm one period is 4.16 px, which is enough.
- L1151 — ★ Overlaying two quantities on one figure means that depending on how the scales are chosen, the two curves can coincide exactly by chance (the first version did exactly that, looking like the opposite of the claim of “two independent axes”). Tweaking the scales to separate them is a fudge, so split the panels vertically — the very structure of the figure says “these are different axes.”
- L1299 — ★ Take the peak from the entire row. It used to be written
line[c - s : c + s + 1], and when s exceeds c, the start becomes a negative index, so Python sliced out only the last 56 pixels and returned 0.6167 as the “peak” (the actual maximum is 0.9834). Normalization broke, the curve capped at 1.0, and dip/peak also came out wrongly as 0.0067 at 1.9x Rayleigh.
- L1581 — ★ The range of “blur within 1 pixel” is not picked from the grid. The sweep step is 3.9 mm while the depth of field is only 0.74 mm, so not a single point falls on the grid (the first version crashed there because min() went empty). Solve for the boundary itself by bisection.
- L1600 — ★ The exaggeration factor is vertical pixels/mm ÷ horizontal pixels/mm. The first version wrote the reciprocal and displayed “0.13x” on a figure stretched 8x (conveying the exact opposite to the reader).
- L2090 — ★ Split into two rows, top and bottom. Overlaid on one figure, the two lines with different units (pixel count and detection rate) read as if they sit on the same vertical axis (which is how it actually looked).
- L2776 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L52 (ja) — 総合案内。★既存の Qiita 枠がこのファイルを指しているので、名前を変えない ―― 外部リンク・LGTM・ストックはこの URL に付いている。館の入口に充てるのが筋。
- L150 (ja) — 1 展示に出す静止画の追加枚数。★2 枚固定をやめる(2026-09-24)
- L405 (ja) — ★見出しは収蔵番号。順路番号(何番目か)は出さない —— 展示を 1 つ挟むだけで 以降が全部ずれ、記事を分けるたびに番号が動くため(2026-09-25)。
- L433 (ja) — ★追加の静止画。説明は 1 文に切る(枚数を増やすのが目的で、詳しい 説明は主図と 2 枚目が持っている)。2026-09-24 に 2 枚固定をやめた。
- L459 (ja) — ★展示に載るのは 1 本あたり 2 枚ほど。PoC は中央値 6 枚・最大 25 枚 作っているので、残りへの道を必ず出す(2026-09-24、ユーザー指摘 「生成した数百枚はどこにあるのか記事からは分からない」)。
- L484 (ja) — ★解説板の「この部屋の {n} 点」は生成で埋める。手書きの数は腐る ―― 10 翼中 9 翼が展示 53 点の頃の数を名乗ったままだった(産業検査は 10 と 書いて実際 27、2026-09-25)。例外は出ず、門も赤くならない。
.format は使わない(解説板に別の波括弧が在ると壊れるため)。
- L533 (ja) — 棟の目次。★展示数は毎回数えて出す(手で書くと必ず古くなる)。
- L539 (ja) — 目次に出す短い翼名。★区切りは ` / ` —— 翼名そのものに「・」が入るので (寸法・形状計測 / 医用・生物 / 色・分離)、「・」で繋ぐと境目が読めなくなる。
- L645 (ja) — ★
external の部(手書きの数学記事)は描かない。index は案内なので上で出した。
- L2611 (ja) — ★台帳に残すパスは repo 相対へ落とす(公開される場所なので)。
- L219 (ja) — ★2026-10-18(外部レビュー 0.6.0 N220 の一次検証): 以前は
--all-region が大域の _REGION_MODE を 立てるだけだったので、--all-image --all-region を 1 回で回すと画像の op まで二値の探針で測り、 別々に回すと 2 回目の --json が 1 回目を上書きした。結果、op_knob.json は region -> region の 87 op を一度も載せておらず(461 / 567)、9-16 以降に足した image -> image の 19 op も未計測のまま だった。二値の探針は op ごとに、入力の型(索引の in_sort)が region のときだけ使う。
- L657 (ja) — ★効かないノブを台帳に足して黙らせない(2026-10-23): 既定の入力では効かない 3 本は、効く入力で探る。 fp_design の境の許容は NA_obj = 0.12 で軸の 2 番目の LED(NA 0.1135・0.1267、差 0.0065)が許容の 2 倍の内側に入る。
- L949 (ja) — ★探針の 32×32 だと目盛の文字幅が書体で変わり、手元(Windows の書体)は右に 3 px はみ出して 拒否・CI(代替書体)は収まって通る —— 環境で判定が割れた(2026-10-11)。余白を取って両方で通す。
- L430 (ja) — ★2026-10-14: 絶対許容差 1e-12 は、出力が 1e-21 の桁(重力波のひずみ
chirp_newtonian)だと どのノブも「変化なし」にする。出力の最大絶対値が 1 より小さいときは、その大きさで許容差を縮める (1 以上の出力では以前と同じ)。
- L42 — ★ While this was missing, :func:
_called called :func:_strip_prose for every combination of (op name × example), each time re-parsing the whole source with ast.parse + tokenize. Measured 2026-09-05: 2-D 881 op × 73 examples + 3-D 347 op × 118 examples + ledger 494 op × 73 examples = about 140,000 full parses, so a single opdocs.py md took 10 minutes (toc and html rebuild the same index too, so a full regeneration is on the order of 30 minutes). Prose stripping needs to happen only once per source —— since it does not depend on the op name.
- L142 — ★2026-09-08: ops1d (dsp 16 + funct1d 23) was registered yet had not a single note under docs/ops —— it appears in OP_CATALOG, but with no per-op note (type contract, pitfalls, related ops) it was entirely missing from the RAG corpus. We noticed when
poc_web_roll_periodicity added 2 to dsp.
- L919 (ja) — ★2026-09-23 の実測: 1 回 7〜11 秒かかるこの関数を、
gen_docs_index_ops が 6 言語 x 3 ブロックで 18 回呼んでおり、test_the_generated_blocks_are_current だけで 129 秒使っていた(スイート 2,301 秒の 5.6 %)。答えは ops.REGISTRY と docs/ から決まり、1 プロセスの中で動かない。 前提は「同じプロセスの中では台帳とノートが変わらない」。生成器は regen_all.py が別プロセスで呼ぶので跨がない。プロセス内でノートを 書き換えてから読み直す側は _records_cache_clear() を呼ぶこと (呼ばないと古い答えが返る —— 黙って古い値を返すのが一番たちが悪いので、 ここに明記しておく)。
- L981 — ★The n-ary (multi-input) tier. Until 2026-09-09 17 operators had no note at all (
add_image, sub_image, bit_and, reduce_domain, union2…). They appear in OP_INDEX.json as tier nary, but with no note under docs/ops/ they could never be retrieved from the RAG corpus. The reason it went unnoticed is plain: this code walked only ops.REGISTRY, and ops.REGISTRY (899) matches the 2-D note count (899) — so counting from the registry side it looked complete. It only shows when you count across tiers.
- L1023 — ★2026-09-07:
OPS3D[...]["doc"] is, at registration time, just the first line of the docstring cut out (ops3d._build). Using it for a note’s “usage” turns it into a single line no matter how many paragraphs the implementation writes —— the 3-D share of “494 ops with a one-line usage” was caused by this truncation (many ops have long docstrings themselves). Read the function’s docstring in full, as for the ledger dim.
- L1046 — ★ A bridging op (
tb_<name>) has the same implementation as the ledger’s <name>, and examples are written under the ledger name. Until 2026-09-06, 147 of them were “zero examples,” but that only meant we had not counted that examples calling the same implementation exist under a different name. Inherit the ledger-side examples and note explicitly in the note that they are “examples of the original op” (so as not to lie).
- L1104 (ja) — ★2026-10-12: 2-D の例索引(
op_example_index._op_names_2d)は ops.REGISTRY から identity と 橋渡し op(category typed)を外し、n-ary 層(imgops_nary)はそもそも数えない。そのため この 3 種のノートは、examples/ に fullseye.apply([x1, x2], "add_image") や fullseye.apply(F, "tb_cx_ifft") と名指しで呼ぶ例があっても「(まだありません)」のままだった (n-ary 17 本・identity・元 op の例を継承できない tb_cx_* 7 本)。カバレッジの門の母集団は変えず、 ノートの案内だけ同じ呼び出し検出(_index_for)で名前を直接引く。
- L1282 — ★An n-ary operator cannot be called through
fullseye.apply — that is the one-image model. Writing the one-image call form here makes the note lie, and telling the reader how to call the operator is the note’s only job, so a wrong call form is worse than none. The public route is fullseye.FullseyeGraph.
- L1301 — ★2026-09-07: Write the public path first. This only wrote a direct import of the implementation module and did not surface
fullseye.ledger.<name>, which users actually use (all 1,244 ops other than 2-D). The reason PoCs repeatedly reported “not in fs." was not that the name was missing but that **the entry point was not written**.
- L1752 — ★ Surface the entry points in 6 languages (2026-09-09). The leaves (Studio’s op help) have 10,191 pages across 6 languages, yet the index leading there was Japanese only —— a gap of the form where the translations exist but cannot be reached. The frame’s wording goes into
T(), so holes in the parallel translations are watched by the existing gate (test_chrome_translation_table_has_no_holes).
- L1792 (ja) — ★2026-10-15: 族の名前だけでは中身が分からない。
drive(694)は研磨(polish)・粉末 X 線回折 (pxrd)・触覚(tac*)・peg-in-hole を抱え、optics は材料表(matprop)・ファイバ(fiber)・ センサーの特性(sensorchar)を抱える —— 族名で選ぶ読み手は、それらを開かずに「無い」と言う。 入口でカテゴリ名を全部見せる(名前は識別子なので訳さない。各カテゴリはその族の INDEX の節)。
- L1803 (ja) — ★2026-09-15: 用途から引く索引(docs/CAPABILITIES.md)へここから送る。文書だけを 渡した AI が 1 回目に見つけられなかったのは、この目次にも AI_RAG_GUIDE にも 導線が無かったから。
- L1812 — ★ For a long time this pointed only at
2d/guides/ and never once sent readers to the guides of the 30 families such as optics, PIV, and tomography (fixed 2026-09-09).
- L1970 (ja) — コードスパン。★
…(RST / docstring の二重バッククォート)を … より先に試す。 2026-10-07 まで ([^]+) だけで、p measures … p が「 の 2 文字目と次の の 1 文字目」で組まれ、コードと散文が**反転して**表示されていた(英語版 3,153 枚中 約 2,800 枚)。前に付いた RST ロール(:func:x など)は飲み込み、対象名だけをコードで出す (733 枚で :func:` が生で見えていた)。
- L2139 (ja) — ★置き換えは描画時と同じ退避記号で(空白にすると
**raises `ValueError`** の閉じの 直前が空白になって太字の組が外れず、英字にすると **name**`(a)` の閉じの直後が 英字になって外れない —— どちらも「閉じていない」と誤判定して次の箇条書きを飲み込んだ)。
- L2841 (ja) — ★2026-09-20: 生成を終えたあと、インタプリタの終了処理(fullseye が引き込む mediapipe の shutdown dispatcher)で 30〜60 分固まり、regen_all の連鎖がその間止まった(2 度実測、CPU 0)。 出力は全部書き終えているので、flush してから os._exit で確定させる。
- L121 — ★ If a previous staging copy remains in
build/lib, setuptools packs it into the wheel as-is (measured 2026-09-05: a module removed from py-modules stayed in the wheel, and the gate’s mutation test passed). Same reason release.yml builds from a clean checkout. Here too, always discard it before building.
- L233 (ja) — ★2026-10-18: スクリプトは一時 dir に置くので、
import fullseye は editable install(本線の 作業ツリー)を読んでいた —— worktree で出すリリースを検査したつもりで、別の版を見ていた。 PYTHONPATH でこの ROOT を先頭に置き、点検する対象 = 出すツリーにする。
- L319 (ja) — ★全出力は repo の外に残す。repo 直下に置くと「余計なファイル」を見る門に 当たりうるし、木が汚れて「凍った木で 1 回」という証拠の条件が崩れる。
- L362 — ★ Calling
--only suite without --full yields 0 items, and it used to say “all PASS” and return with rc=0 (measured in the 2026-09-05 review). A gate that passes while checking nothing is worse than no gate.
- L20 (ja) — # 選び方(★ここが肝)
- L55 (ja) — ★
__all__ と list_ops は入れない。どの族のテストにも出てくる語なので 392 本中 107 本を選んでしまい、そのうえ肝心の探針の門(test_op_probe_ledger)は その語を持たないので取り逃す(2026-09-23 実測)。広く取れば安全、ではない —— 選ぶ語は「その帳簿を読んでいる」ことの証拠でなければならない。
tools/qiita_post_poc.py
- L100 (ja) — 既定で投稿する記事の種類。★手書きの
external は名指ししたときだけ扱う —— 引数無しの 一括投稿が、生成物でない記事(数学の回など)を巻き込まないようにする。
- L49 (ja) — ★最上流。
auto_specs_data.py は backends_auto が registry を組む入力(wheel 同梱の data/auto_specs/*.json の複製)なので、registry を読む下流すべてより先に回す。 2026-10-07 まで tools/ の外にあって鎖にも表にも無かった(差分は無かったが、 spec を足して回し忘れても誰も気づけなかった)。
- L54 — ★The only generated artifact outside
tools/. That is exactly why it was missed — as long as you look for generators under tools/*.py, this one is never found.
- L56 — ★2026-10-15: moved up from 16th to 2nd. Its only input is the registry (it reads no other stage’s output), yet gen_capabilities_index and gen_trust_block read this file before it was rebuilt — when a merge that adds ops takes the mainline side of the index, the stale index lacks the new ops and the chain stops (the integration work got around it by running
imgevolve.py index by hand first). The order is checked by order_violations() from OUTPUTS / READS below.
- L73 (ja) — ★展示館より先に回す —— 生成器は見出しに収蔵番号を出すので、 未発行の展示が 1 つでもあると BuildError で止まる。
- L88 (ja) — ★これも
tools/ の外。2026-09-20 まで鎖に無く、docs/OPERATORS.md が 885 op / 47 分類(2026-09-06 の値)のまま置き去りだった(GenSpark 第 53 報と ユーザー指摘)。生成器が鎖に無い生成物は、必ず古びる。
- L92 (ja) — ★2026-10-07: 以下 3 本も
tools/ の外にあり、列挙が tools/*.py しか見ていなかったので 鎖にも表にも無かった。どれも registry とコミット済みの入力だけから決まり、2 回 回してバイト一致・各 3 秒(実測)。置き去りの実例: EXAMPLES.md は「67-op」、REFERENCES.md は「153 operators」、 OP_DISPOSITION.json は implemented 324(実際 405)のままだった。
- L100 — ★2026-10-15: it had no
--md and wrote nothing (it only printed a summary to stdout). docs/CONVERSION_MATRIX.md went stale at the 2026-09-02 values (“59 types / 164 conversion pairs”), and since –check cannot see “a stage that writes nothing” as drift, it passed for six weeks. Now trace_problems() rejects a stage that does not even touch its declared outputs.
- L108 (ja) — ★2026-10-15: 13 番目から最後の方へ下げた。docmap が docs/.md の題を読むので、 題を持つ生成物(OPERATORS / REFERENCES / EXAMPLES / EXAMPLES_3D / SENSOR_PLAYBOOK / CONVERSION_MATRIX / DESIGN_NOTES)を書く 7 段すべてより後でなければならない —— 以前はその 7 段より前にあり、題が変わると 2 回回さないと揃わなかった。 文献層の本体はコーパスが要る(EXCLUDED)が、「op ノート N 本」の件数は docs/ops を数えれば直せる。 docs/ops を書く opdocs の後、題を読む docmap(gen_docs_index_ops)の前。
- L308 — * ★ And dangerous: an article right after generation writes images with relative paths. The published version has them changed to absolute URLs on
raw.githubusercontent.com (with a relative path Qiita does not show images —— memory feedback_qiita_svg_path_and_cache). Running only the generator rolls those absolute URLs back by 42 lines. If you run it, carry it all the way through the article’s publishing steps. Write exclusions by file name. Summarizing them in prose (“the 10 of wing*_gallery”) cannot be matched by machine, and the unclassified() below stops working.
- L675 (ja) — ★2026-10-07: 印も探す場所も狭すぎた。初版は
open(..,"w") / write_text / savefig / json.dump だけを tools/*.py(直下のみ)で探していたので、 * repo 直下の生成器が 1 本も見えなかった —— samples.py(docs/EXAMPLES.md が 「67-op」のまま)、references.py(「153 operators」)、dispositions.py、 lib_coverage.py(885 op のまま)、honest_summary.py …。imgevolve.py と catalog.py だけが手で足されていた —— 手で足す方式は、足し忘れを拾えない。 * 画像の書き手が 1 本も釣れなかった —— PIL の .save、imageio の mimwrite、write_bytes、Fullseye 自身の write_video / save_gif …。 gen_banner の PNG は「731 2-D + 265 3-D」と書いたまま古びている。 * tools/impl2/ など下の階層も見ていなかった(docs/op_*.json の台帳)。 印を広げれば門・デモ・ライブラリも釣れる。それは構わない —— 釣れたものは全部 上の表に理由つきで載せる(印は緩めない)。
- L690 (ja) — ★2026-10-25: まだ狭かった。
pv.write_viewer( / fs.write_viewer( で HTML を書く生成器 (tools/build_view2026_viewers.py、題材の枝の tools/build_*_anim3d.py)がどの表にも 載っていなかった。同じ洗い出しで open(.., "wb")("w" しか見ていなかった)と shutil.copy* / copytree / move も足した。印ごとに「その印でしか釣れない実在の 生成器」を tests/test_regen_all.py が要求する(印を消せば落ちる)。
- L738 — ★A generated artifact outside
tools/. Walking tools/*.py can never find it, and in fact docs/OP_INDEX.json was being missed.
torch_lazy.py
- L69 (ja) — ★2026-09-20(GenSpark 第 24・25 報 N94): torch が入っているのに「install with」だけが出て、 導入すれば直ると誤って案内していた。入っているのに import で落ちたなら、その理由を言う。
treemorph.py
- L217 (ja) — ★殻の中点に置く((k - 1/2) * top / n)。上端を top ちょうどにすると最も遠い節点が 殻の上に乗り、回転で 1 ulp 動いただけで「内側/外側」が反転して交点が 1 -> 0 になった (回転不変の門が捕まえた)。
typed_catalog.py
- L242 (ja) — ★打ち直しは入力の頂点数より少ない標本を拒否する(角を切って線が短くなり、 濃淡の再現が壊れるため)。探針より確実に多い数を渡す。
- L252 (ja) — ★2026-10-07: 一時ファイル名にはプロセス番号を入れる(固定名だと xdist の別ワーカーが同じファイルを 同時に書き直し、読む側が壊れた zip や途中の G-code を掴む)。 printpath(2026-09-21)。読む op のパスは、その場で書いた小さな本物のファイルにする(無いパスは CONTRACT で 永久に走らない)。書く op のパスは一時ディレクトリ。z は種の mesh(単位立方体あたり)に当たる高さ。
- L323 — ★ The case where the default itself is heavy is handled separately —— we wrote a cost table in the docstring and left it in docs/KNOWN_ISSUES.md as “unsolved.” Making it lighter here is to pass the check, not to hide the slowness. The keep of fourier_smooth(points, keep) is a required argument with no default. If it cannot be bound, it is skipped forever as “cannot assemble arguments” and appears in the coverage table only as unreached (in the first measurement on 2026-09-06, only this one of 13 ops fell out). Surface roughness. Constraints are 2dx <= lambda_lo < lambda_hi <= ndx / 0<hurst<1 / sq>0 / n>=8. Subpixel measurement. The measurement-line generation op takes no input, so every argument needs a hint.
- L388 — ★ Without this, surface_params is rejected fail-closed every time, and by the single coverage number it looks “callable” while in reality it is never executed.
- L561 (ja) — して探針の値が読みやすいようにする。★既定の weight=”phat” は band が必須(0.5.0、 全白色化は帯域の限られた信号で外れる)。rate=1.0 なので band は cycles/標本で全帯域を明示。
- L578 — ★ Do not make the normal parallel to an axis. If it is axis-parallel, the distance field varies along only one axis, and the “GIF of stacked slices” the figure generator makes collapses into a single frame (measured 2026-09-08). With a tilted normal, every slice changes. The length has no effect (the op normalizes), so pass an unnormalized vector to also show that spec.
- L650 (ja) — ★32x32 は chain_fuzz の cimage プール(32x32)に合わせた値。進化の橋 (backends_typed)はこれを使わず、呼び出しのたびにスペクトルと同じ形の H を作る (backends_typed.CALL_TIME_ARGS。固定形だと他の大きさの画像で必ず拒否された、2026-10-07)。
unified.py
- L559 (ja) — ★2026-09-20(GenSpark 第 53 報 N181): dict / list を registry の鍵にして unhashable で落ちていた
verify_auto.py
- L74 (ja) — ★
match は 1 次元ベクトル(ops._ncc_locate と同じ形)。1 スカラー では表せない組(面積+重心、楕円の 3 指標 …)を運ぶために在る。 この枝が無かったので、下の「image / region = 2 次元」に落ちて ndim=1 で弾かれていた —— 正しく作られた op が「実装されていない」 と数えられ、HALCON 対応数が静かに 1 本少なかった。
video.py
- L228 — ★2026-10-24: imageio (Pillow) decodes a 16-bit RGB/RGBA PNG to uint8 and the uint16 request then stretched those 8 bits (off by up to 237/65535). A still PNG declaring > 8 bits goes through raster.read_raster (OpenCV, or refused).
visionlab.py
- L53 — ★
float("50") succeeds, so merely passing through float() lets a string slip through as millimeters. The visiondesign side rejects it, but converting to float first here means it becomes a number before it reaches that validation (measured under adversarial testing: VisionSystem(focal_mm=”50”) passed). Hold the same discipline on the container side too.
visualhull.py
- L127 — ★ Every single point behind the camera = almost certainly a convention mismatch in the pose (2026-09-08, hit by poc_livestock_body_volume). This function requires the OpenCV convention (+Z forward), but what bears the name
look_at in the public layer is render3d’s gluLookAt version (−Z forward, a 4x4). Passing its M[:3,:3], M[:3,3] makes every voxel judged as behind, and an empty silhouette without exception is returned, giving an empty hull. Silently returning empty is indistinguishable from “fully carved,” so here alone we raise our voice (there are valid cases —— the object being behind the field of view —— so keep it to a warning rather than a raise).
volops.py
- L1201 (ja) — ★半径は刻みの整数倍に落とす。EDT は離散球の中心で半径より少し大きい値を返すので (半径 4 の球で ~4.12)、生の最大値から刻むと直径が系統的に +0.1 ほど大きく出る。
- L1214 (ja) — ★膨張は前景をはみ出す(離散の球で膨らませるため)。実測で 24% 漏れ、粒度分布の 生存率が 1.0 を超えた。太さは前景の量なので必ず前景で切る。
- L1313 (ja) — ★最大厚さの次の刻みまで伸ばす。ここで止めると一番太い特徴の質量が 一度も消えず、分布から丸ごと落ちる(実測: 体積の 71% が欠け、平均径が 18.0 のところ 15.1 になった)。
- L1333 (ja) — ★一様なブロックでは勾配が丸め屑しか残らず、固有値分解はその屑から任意の向きを 返す。絶対値の床は輝度スケールに依存するので、必ず相対量で切る。
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.