kairos-chain 3.81.0 → 3.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bc251869ebf7ce64e94fbae5baf21ef0eea655b6d1c42d55dfb2f7ee7c2ccc0
4
- data.tar.gz: aea009fc75974ff42a05e2bc54a352c19b1192157b9fe8eefa311ae9fd096c65
3
+ metadata.gz: 4da090fdc44c60e73073401b9987dbe17377bda02e95048966ecdf187f63b71e
4
+ data.tar.gz: 6d24ce2aeab418e8c2a012ec7f1dd43285ede720db03bc5802f75defde87507b
5
5
  SHA512:
6
- metadata.gz: 498212b88feb4e563e745be00467f8e206aff2c2103761c12d21695a1829201f2edae98295f61e2aaf6695f9d5e82be4f9f24a2c3ff10e868965a8cc1f1eae91
7
- data.tar.gz: efe4a6d07531e77648bd175452e72036a0261d0bfb3b426b5f571b54b14a1f3f1695acc3b7d0136b64f04c33eac0e9c04dcebfb58481373af0ddbed355a8d1c4
6
+ metadata.gz: 5f50569f19bf383b545aab43f6a831419f60cb3d156e15a385e98c68d175fc1ae1c6b7fd4bf288af49b975fcaec18b212ed0aecfcc77df09125aed8b29e2599b
7
+ data.tar.gz: 5782f2d19a495a354d62a622c7fa25d3494e10aafeb0513f9c8c47677a511c5615cbe6ef8065687113ac5482278c9b85dea44aad80cc21abd81154de49557a17
data/CHANGELOG.md CHANGED
@@ -4,6 +4,43 @@ All notable changes to the `kairos-chain` gem will be documented in this file.
4
4
 
5
5
  This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [3.82.0] - 2026-08-31
8
+
9
+ ### Added — L1 knowledge: html_slide_deck_authoring
10
+
11
+ New gem-bundled L1 knowledge entry `html_slide_deck_authoring` (v1.0), written
12
+ by the operator from the 2026-08 build of a bilingual lab-meeting deck: 24 main
13
+ slides plus a 58-slide appendix, ja/en generated from one source, click-driven
14
+ builds, a searchable index, and a handout PDF.
15
+
16
+ Contents: the five-module split (`kit` / `txt_*` / `viz_*` / `make_*` /
17
+ `check_*`) and why kit and viz must not merge — they constrain different units
18
+ (viewport height vs SVG user units); the one-slide budget; the rule that every
19
+ number on a slide is read from the same context the report reads, never written
20
+ into prose, with the sibling deck that still said "sweep in progress" after the
21
+ sweep finished as the counter-example; the three ways a number was actually
22
+ misread on the day (missing denominator, two axes in one sentence, a range
23
+ whose span was not named); inline SVG rather than rasterised PNG (CJK fonts,
24
+ scaling, tooltips); the animation safety direction — draw the finished state
25
+ and animate backwards from it, so print, `prefers-reduced-motion`, CSS-off and
26
+ JS-off all render something true; two checkers with different jurisdictions
27
+ (inside the SVG vs the slide's vertical budget); the handout-PDF variant and
28
+ the values a JS-free build leaves blank; and a searchable index whose filter
29
+ must listen on the `input` event, since CJK IME text never reaches `keydown`.
30
+
31
+ - Shipped to both `knowledge/` and `templates/knowledge/`, byte-identical, so
32
+ the next `system_upgrade` on the authoring instance reports UNCHANGED rather
33
+ than `user_modified` — a divergent instance copy wins silently over every
34
+ later template update.
35
+ - Two neighbouring entries (`frontend_design`, `html_to_pdf_conversion`) are
36
+ instance-local and do not ship, so the `[[...]]` links to them dangle on a
37
+ fresh install. Same convention as `loop_engineering_patterns`.
38
+ - Not multi-LLM reviewed. This is a record of what was measured while building,
39
+ not a design under review. It ships as written apart from a `version` field,
40
+ a folded-scalar fix (`>` to `>-`) so the description does not carry a
41
+ trailing newline into the `knowledge_list` table, and one paragraph stating
42
+ the boundary against the two neighbours.
43
+
7
44
  ## [3.81.0] - 2026-08-27
8
45
 
9
46
  ### Changed
@@ -1,4 +1,4 @@
1
1
  module KairosMcp
2
- VERSION = "3.81.0"
2
+ VERSION = "3.82.0"
3
3
  CHANGELOG_URL = "https://github.com/masaomi/KairosChain_2026/blob/main/CHANGELOG.md"
4
4
  end
@@ -0,0 +1,401 @@
1
+ ---
2
+ name: html_slide_deck_authoring
3
+ description: >-
4
+ Use when building a presentation deck as generated HTML — a self-contained, CDN-free,
5
+ 16:9 deck with inline-SVG figures, two languages from one source, PowerPoint-style
6
+ click-driven builds, mechanical layout checkers, a searchable slide index for a large
7
+ appendix, and a handout PDF. Covers the module split, the one-slide budget, the
8
+ "numbers come from the reader, never the prose" rule, how a number on a slide gets
9
+ misread, the animation safety direction, why a regex checker over your own output
10
+ fails silently, and the traps that cost real time. NOT for Markdown slide tools
11
+ (Marp/reveal.js) or for writing the talk's content.
12
+ version: "1.0"
13
+ tags: [slides, presentation, html, svg, bilingual, i18n, ime, animation, pdf, playwright, checker, search, authoring]
14
+ ---
15
+
16
+ # HTML スライドデッキの作り方
17
+
18
+ 生成 HTML でプレゼン資料を作るときの設計方針と手順。2026-08 にラボミーティング用
19
+ デッキ(本編 24 枚+Appendix 58 枚、日英 2 言語、クリック送り、索引、配布 PDF)を
20
+ 作り切った経験から。
21
+
22
+ ## いつ使うか
23
+
24
+ - 図が主役で、**数値が別の成果物(レポート・解析結果)と一致していないと困る**とき
25
+ - **同じ内容を2言語**で出すとき
26
+ - 発表用と**配布用 PDF** の両方が要るとき
27
+ - PowerPoint を開けない環境で作るとき、あるいは図をコードで生成したいとき
28
+
29
+ 使わない場合: Marp / reveal.js で足りるとき。話す内容そのものを考える段階。
30
+
31
+ 隣の entry: [[frontend_design]] は見た目の原則と JSON から組む簡易デッキ生成器
32
+ (枚数が少なく図が単純なとき)。[[html_to_pdf_conversion]] は Playwright で PDF に
33
+ 焼く手順だけ。ここは**図をコードで生成し、枚数が数十枚に育つ場合**を扱う。
34
+
35
+ ---
36
+
37
+ ## 1. モジュールの分け方
38
+
39
+ 5 つに分ける。**混ぜると必ず壊れる。**
40
+
41
+ kit.py CSS・JS・1枚を組む関数(slide / table / tiles / panes / figure)
42
+ txt_*.py 本文。1枚ずつ並べるだけ。ここに geometry を書かない
43
+ viz_*.py 図。インライン SVG を返す関数の集まり
44
+ make_*.py 入口。context を作り、言語を切り替えて両方を出す
45
+ check_*.py 機械検査(後述)
46
+
47
+ **kit と viz を混ぜないこと。** kit は「1枚に置けるもの」を構造として制限する係で、
48
+ viz は「1つの図の中の座標」を持つ係。制限が違う(前者は vh、後者は SVG ユーザー単位)。
49
+
50
+ ### 1枚の予算
51
+
52
+ **要点1行 + 図か表1つ + 断片3つまで。** それ以上は Appendix に回す。
53
+ `slide()` で 4 個目の断片を受けたら例外で落とす、くらい強制してよい。制限が無いと
54
+ 必ず溢れる。Appendix は枚数無制限にしておくと、本編の圧が逃げる。
55
+
56
+ ---
57
+
58
+ ## 2. 数値を地の文に書かない
59
+
60
+ **成果物が2つ以上あるなら、数値は必ず共通の reader から来させる。**
61
+
62
+ from make_report import build_context # レポートと同じ reader
63
+ C = build_context()
64
+ ... f"偶然の {C['B']['gf_lo']:.1f} 倍"
65
+
66
+ こうすると「レポートだけ更新してスライドが古いまま」が構造的に起こらない。
67
+
68
+ 失敗例が実在する: 同じ repo の別デッキは地の文ハードコードで、解析が終わった後も
69
+ 「掃引中」と書いたままになっていた。**同じ轍を踏まない。**
70
+
71
+ 派生値もヘルパにする。「約 100 倍」と手で書いた箇所が、実際にはモデルごとに
72
+ 71〜1,101 倍と桁が違っていた(元資料のモデル横断の丸めを転記していた)。
73
+ `_ratio(C, model)` のような関数にして毎回そこから出す。
74
+
75
+ ### 2.1 数値は「軸」と「分母」を言わないと誤読される
76
+
77
+ 聞き手は数値を**自分が知っている種類の数値**として読む。実際に起きたこと。
78
+
79
+ - **「53%」を「50% の改善」と読まれた。** 実際は増分の内訳で、追加学習で得た
80
+ 0.64 のうち 0.34 がその情報そのもの、という意味。倍率の伸びは +19% だった。
81
+ 棒グラフが 50% 伸びて見えないのは正しく、読み手の指摘が正しかった。
82
+ → タイルの中に**元の3値**(3.40 → 4.05、同じ計算量の対照 3.70)を並べたら通じた。
83
+ - **1つの要点に軸を2つ入れていた。** 「対照の 8.5〜11.7 倍動く」と
84
+ 「KEGG は偶然の 2.26 倍」を1文に並べていた。前者は動いた量そのもの、後者は
85
+ その並びの当たり方で、別の軸。単独では何のことか読めない。
86
+ → 片方を落とし、Appendix に図解で分けた。
87
+ - **「8.5〜11.7 倍」を複数モデルの幅と読まれた。** 実際は**1モデルを2条件で**
88
+ 測った幅。もう1つのモデルは 93〜96 倍で、範囲の外にあった。
89
+
90
+ 規則にすると:
91
+
92
+ 1. **割合を出すなら分母も出す。** 「増分のうち」「最良モデル比」まで書く。
93
+ 2. **1文に軸を2つ入れない。**
94
+ 3. **範囲を出すなら、何をまたいだ範囲か言う**(モデル/条件/seed)。
95
+ 4. 丸めた元値を並べると、聞き手の再計算が**最終桁でずれる**ことがある
96
+ (3.40・3.70・4.05 から計算すると 54%、表示は 53%)。増分の形で出すか、断る。
97
+
98
+ ### 2.2 参考文献はその枚のフッターに1回だけ
99
+
100
+ 一覧を付録に置くだけだと、聞き手は話を離れて探しに行くことになる。
101
+ **その文献が初めて意味を持つ枚**のフッターに出す。
102
+
103
+ - **出てくるたびに書かない。** ベンチマークの名前は本編の大半の枚に出るので、
104
+ 毎回書くと雑音になる。導入する枚に1回だけ。
105
+ - **著者・年までに留める。** 掲載誌まで入れると、注意書きのある枚で行が
106
+ 折り返し、ページ番号まで2行に割れる。番号 `[n]` が付録の一覧を指す。
107
+ - 付録にあって本編で使っていない文献は、付録だけに置いたままにする。
108
+
109
+ ---
110
+
111
+ ## 3. 2言語を1つのソースから
112
+
113
+ 図のラベルも本文も、同じ `T(ja, en)` を通す。
114
+
115
+ LANG = "ja"
116
+ def set_lang(lang): global LANG; LANG = "en" if lang == "en" else "ja"
117
+ def T(ja, en): return en if LANG == "en" else ja
118
+
119
+ `T` はリストも受けられる(`T(["a","b"], ["x","y"])`)ので、箇条書きにも使える。
120
+ 入口は言語ごとに `set_lang()` → 全枚を組む、を繰り返すだけ。
121
+
122
+ **英語は同じ意味でも横に伸びる。** 日本語で収まっても英語で溢れる、が何度も起きた。
123
+ 検査は必ず**両言語**に掛ける。最後に `set_lang("ja")` で既定に戻すこと(同じ
124
+ プロセスで他の生成物を作ると英語で出てしまう)。
125
+
126
+ UI 側の文字列(索引の見出しなど)は `document.documentElement.lang` から出す。
127
+ JS に日本語を直書きすると、英語版に日本語が出る。
128
+
129
+ ---
130
+
131
+ ## 4. 図はインライン SVG
132
+
133
+ matplotlib で PNG に焼かない。理由は3つ。
134
+
135
+ 1. **CJK フォントが無い環境では日本語が全部豆腐になる。** SVG ならテキストは
136
+ ブラウザ側のフォントで描かれる。
137
+ 2. 拡大しても劣化しない(投影・PDF の両方で効く)。
138
+ 3. hover の tooltip を付けられる。
139
+
140
+ 代償は「自動レイアウトが無い」こと。折り返しも自分で書く。日本語は文字数、
141
+ 英語は単語境界で折る **別々の幅**を持たせないと、どちらかが必ず溢れる
142
+ (CJK 約 1.0em、英小文字 約 0.52em)。
143
+
144
+ ### 図を大きく見せる
145
+
146
+ 表示高は `min(余白の高さ, 横幅 × h/w)` で決まる。**viewBox の h を詰めると、
147
+ 同じ表示高でも中の文字が大きく描かれる。** 断片を削って情報を捨てるより、
148
+ viewBox を詰めるほうがよい。要点(take)を削るのも余白が増えて効く。
149
+
150
+ 図を2枚並べたいときは、本文の器を `display:flex` にして `figure{flex:1}` に
151
+ しておけば `figure(a) + figure(b)` で半分ずつになる。1枚に詰めるより文字が
152
+ 1.4 倍ほど大きくなる。
153
+
154
+ ### 図の中の説明箱は縦の予算を使わない
155
+
156
+ スライドの縦は常に足りない。**説明を1行足したいとき、図の中の箱に入れれば
157
+ 図の高さも断片の数も変わらない。** 枚の外に足すと図が縮む。
158
+ 逆に、図の中の箱を差し替えるのは「無料」の変更になる。
159
+
160
+ ### 図を2つの文書で共有する
161
+
162
+ 同じ図をスライドと文書(レポート)で共有していると、片方だけ変えたいときに困る。
163
+ **図を複製せず、変えたい部分を引数にする。**
164
+
165
+ def fig_pipeline(..., box="rank"): # 既定は文書側のまま
166
+ if box == "cooc": ... # スライドだけ差し替える
167
+
168
+ 複製すると、次に数値が変わったとき片方だけ古くなる。§2 と同じ理屈。
169
+
170
+ ---
171
+
172
+ ## 5. アニメーション
173
+
174
+ 2つの方式を用意し、**同じ図で混ぜない**。
175
+
176
+ ### ループ(CSS のみ、JS を使わない)
177
+
178
+ .anim-fade{...}
179
+ .slide.on .anim-fade{animation:... infinite; animation-delay:var(--d,0s)}
180
+
181
+ `--d` で段差をつける。`.slide.on` の中だけで回す(裏で全枚ぶん回さない)。
182
+
183
+ ### クリック送り(PowerPoint 風)
184
+
185
+ 図側: <g data-step="auto"> ← 番号は書かない
186
+ 枚側: slide(..., build=True) ← 出現順に採番し、断片はその続き
187
+ JS: next() が段を1つ進め、出しきってから次の枚へ
188
+
189
+ `tiles` / `panes` / `table` にも `build=True` を通して、タイル・対比・表の行を
190
+ 1つずつ出せるようにしておくとよい。**要点(take)は段に載せない** — その枚の
191
+ 主張なので最初から出ていないと聞き手が迷う。
192
+
193
+ 締めの一段落のように「表を読み終えてから出したいもの」は、段の最後に置く。
194
+ 結論が最初から画面にあると、表を追う意味が無くなる。
195
+
196
+ ### 両方に共通する安全の向き(最重要)
197
+
198
+ **図は「終わった状態」を描く。アニメは始点にずらして戻すだけ。**
199
+
200
+ こうしておけば、印刷・`prefers-reduced-motion`・CSS 無効・JS 無効のどれでも
201
+ 静止画が正しい。逆向き(始点を描いてアニメで終点に持っていく)にすると、
202
+ 効かない環境で**間違った図**が出る。
203
+
204
+ クリック送りも、隠すのは JS が `body.built` を付けてから。JS が落ちたら
205
+ 全部見えたままになる。
206
+
207
+ ### 隠すのは opacity だけ
208
+
209
+ `display:none` にすると段が進むたびに版が動く。`opacity` なら場所は取ったまま
210
+ なので、レイアウトが跳ねない。縦の予算も「全段出した状態」で一度測れば済む。
211
+
212
+ ---
213
+
214
+ ## 6. 機械検査を2本用意する
215
+
216
+ ブラウザで目視できない環境では、検査が唯一の防壁になる。**性質の違う2本**が要る。
217
+
218
+ | 検査 | 見るもの | 捕まえるもの |
219
+ |---|---|---|
220
+ | geometry | SVG の**内側** | テキストのはみ出し、要素どうしの重なり |
221
+ | fit | スライドの**箱** | 本文がタイトル・フッターに被る、図が小さくなりすぎ |
222
+
223
+ 実際に起きた崩れは geometry では**1件も捕まらなかった**。縦の予算を数える
224
+ fit のほうが必要だった。逆に fit は SVG の中身を見ない。両方要る。
225
+
226
+ 太字は幅 ×1.06 で見積もる。これを入れた途端に実在の欠陥が 11 件出た。
227
+
228
+ **検査が見ないもの**も明示しておく: 段(アニメ)の動き、色、実フォントの字幅。
229
+
230
+ ### 6.1 自分の出力を正規表現で読む検査は、黙って壊れる(最重要)
231
+
232
+ **生成側のマークアップを変えた日に、検査が静かに測らなくなる。**
233
+
234
+ 実例。断片を `<li class="hi">` から `<li class="hi" data-step="2">` に変えたところ、
235
+ 検査の正規表現 `<li class="[^"]*">` が当たらなくなり、**本編 24 枚の断片 42 個が
236
+ 縦の予算に 0 として入り続けた。** それでも ALL CLEAR は出ていた。
237
+ 同じ日に、`class="slide title"` の表題枚も `<section class="slide"` に当たらず、
238
+ まるごと検査対象から漏れていた。**どちらも数か月ぶん気づかれなかった。**
239
+
240
+ 対策は2つ。
241
+
242
+ 1. **数えた個数を検査自身に出させる。** 「断片 0 個」が異常だと分かるように
243
+ する。生成側が出した個数と突き合わせるのが理想。
244
+ 2. **属性やクラスを1つ足したら、検査の正規表現を見に行く。** 手順に入れる。
245
+
246
+ ### 6.2 ALL CLEAR は「見た」ことにならない
247
+
248
+ ブラウザが使える環境でも同じ。矢印の右に置いた注記が viewBox の右端で切れて
249
+ いたのに、幾何の検査は通した。近似モデルは境界で外す。
250
+ **枚を触ったら必ず1枚撮って目で見る。** そのために「この枚だけ撮る」機能を
251
+ 先に作っておく(後述)。
252
+
253
+ ---
254
+
255
+ ## 7. PDF にする
256
+
257
+ ### 配布用の変種を作る
258
+
259
+ 発表用デッキとは別に、**JS を積まない1枚1ページの HTML** を出す。
260
+
261
+ - `.slide{display:flex!important; page-break-after:always}`
262
+ - `[data-step]` と `.anim-*` は全部見せて止める
263
+ - Appendix を入れるかは選べるようにする(配布は本編だけ、が多い)
264
+
265
+ 同じ `main(C)` から作れば、発表用と中身がずれない。
266
+
267
+ ### JS が埋める値は、配布版では生成時に埋める
268
+
269
+ 画面版のページ番号を JS で入れていると、**JS を積まない配布版は空欄のまま**
270
+ 印刷される。配布用を組む関数の中で埋めてしまうのが確実(配布は本編だけなので
271
+ 通し番号でよい)。画面版は JS が上書きするので二重にならない。
272
+
273
+ 同じ罠は「JS で入れている表示」すべてに当てはまる。配布版を作ったら、
274
+ **空になっている要素が無いか出力を数える。**
275
+
276
+ ### ヘッドレス Chromium で焼く
277
+
278
+ playwright + chromium → page.pdf(width=..., height=..., print_background=True)
279
+
280
+ **紙もスライドと同じ 16:9 にする。** A4 に入れると上下に余白が出るだけ。
281
+
282
+ 共有環境に入れないこと。`pip install --user` と `~/.cache` に閉じる。root が無くて
283
+ `playwright install-deps` が使えない場合は、足りない共有ライブラリを他の環境から
284
+ **home にコピー**して `LD_LIBRARY_PATH` を通す。他人の環境を直接参照すると、
285
+ その環境が消えた日に黙って壊れる。
286
+
287
+ **CJK フォントが無いホストでは日本語版を PDF にできない**(豆腐になる)。
288
+ 版組みの確認には使える(箱の位置と行数は正しく出る)。配布が要るなら
289
+ `~/.fonts` にフォントを置くか、operator のブラウザで印刷してもらう。
290
+
291
+ ### 「この枚だけ撮る」を最初に作る
292
+
293
+ 1枚ずつ直す作業では、毎回これを使う。
294
+
295
+ render.py <html> -o out.png --png --slide 12
296
+
297
+ 中では `?still` で全段を出した状態に固定し、**枚送りの関数を直接呼ぶ**。
298
+ ハッシュ(`#12`)を変えて `goto` するだけでは same-document navigation になり、
299
+ JS が再実行されず1枚目のまま撮れる。
300
+
301
+ 配布用 HTML には枚送りの JS が無いので、`--slide` は使えない。
302
+ **何が違うのかを1行で言って止める**(`ReferenceError` を出さない)。
303
+
304
+ ---
305
+
306
+ ## 8. 大きな Appendix を引く索引
307
+
308
+ Appendix が数十枚になると、矢印で送って探すのは実用にならない。
309
+ **キー1つで一覧を出し、語で絞り込んで飛ぶ**仕組みを入れる。
310
+
311
+ ### サムネイルは選ばない
312
+
313
+ reveal.js 風に全枚を縮小して並べる案は、**図が主体のデッキでは機能しない。**
314
+ 82 枚を1画面に入れるには 1/6 前後まで縮める必要があり、本文が 3px 相当になって
315
+ 読めない。結果、見分けのつかない矩形が並ぶだけになる。
316
+ **探しているのは語**なので、番号・見出し・題名の一覧+絞り込みのほうが速い。
317
+
318
+ ### 実装で外せない4点
319
+
320
+ 1. **絞り込みは `<input>` の `input` イベントで受ける。**
321
+ `keydown` の `e.key` を拾う実装は **CJK の IME で動かない** — 確定前の文字は
322
+ `e.key` に来ず、composition イベントを経由する。英語版だけ絞り込みが効いて
323
+ 日本語版で 0 件、という形で出る。**2言語のデッキなら必ず両方で試す。**
324
+ 2. **探すのは題名ではなく、その枚の全文。** 題名だけだと、本文で論じている語で
325
+ 見つからない(ある語で 1 枚しか出ず、それを扱う本編 4 枚が漏れた。全文なら
326
+ 12 枚出た)。表示は題名のままでよい。索引だけ全文にする。
327
+ 3. **既存のハンドラに触らない。** 新しいハンドラを **capture 段**で登録し、
328
+ 一覧が開いている間だけ `stopPropagation` する。クリックは既に「次へ進む」に
329
+ 割り当てられているので、これをしないと選ぶ操作が枚送りになる。
330
+ 4. **一覧は grid にする。** CSS の段組み(`column-count`)は高さが尽きると
331
+ **右へ**伸びるので、行数が多いと横スクロールになる。grid なら溢れは縦。
332
+
333
+ ### 操作の細部
334
+
335
+ - **矢印は並んで見えている位置で動かす。** 文書順にすると3段の格子で ↓ が
336
+ 右隣に飛ぶ。段数は書かずに `offsetTop` が揃う要素を数えて**実測**する
337
+ (スタイルシートの段数を変えても追従する)。
338
+ - `←→` を格子の移動に使うなら、入力欄のカーソル移動は諦める。絞り込みの語は
339
+ 短いので `Backspace` で足りる。
340
+ - **閉じるのは Esc だけ。** 開くキーで閉じられるようにすると、その文字から
341
+ 始まる語("ortholog" の o)を打った瞬間に閉じる。
342
+ - 見出しの接頭辞(「付録 —」)は一覧では落とす。番号が言っているので重複で、
343
+ 残すと見出し列が全部同じ文字で埋まって省略記号で切れる。
344
+ - 該当0件で Enter を押しても何も起きないようにする。
345
+ - 配布用 HTML は JS を積まないので索引も入らない。PDF の頁数は変わらない。
346
+
347
+ ---
348
+
349
+ ## 9. 実際に踏んだ罠
350
+
351
+ | 罠 | 症状 | 対処 |
352
+ |---|---|---|
353
+ | 表の折り返しの既定が逆 | 文字列の列だけが最小幅に潰れる | 折り返しを既定にし、**数値セルだけ** nowrap |
354
+ | 図の高さが縛れていない | 図が箱から溢れてタイトルの上に描かれる | SVG を包む箱に `width/height:auto` + `max-*:100%` |
355
+ | フッターがページ基準に置かれる | 1枚目だけ偶然合っている | 枚の器に `position:relative` |
356
+ | 横棒グラフのラベル欄 | 長いラベルが**左に**はみ出す(右揃えなので) | 欄幅から字数上限を決める。長い説明は tooltip か断片へ |
357
+ | 関数名の衝突 | `TypeError: 'int' object is not callable` | ドメイン語(`step`=窓の刻み幅)と被らない名前にする |
358
+ | **CSS クラス名の衝突** | 指定した font-size と色が効かない | 後ろの規則が勝つ。名前を付ける前に**スタイルシートを grep** |
359
+ | **本文の器が flex 行** | 表と段落を渡すと左右に割れる | 縦に積む器で包む。`flex:1;min-width:0` が無いと `table{width:100%}` が解決しない |
360
+ | **フッターにもう1行足す** | 行が折り返し、ページ番号が「6 /」「24」に割れる | 番号に `white-space:nowrap`。中身は1行に収まる短さに切る |
361
+ | **`::before` の区切り記号** | 地のテキストがあるのに最初の1つだけ区切りが出ない | 地のテキストは要素ではないので `:first-child` が当たる。区切りは生成側で入れる |
362
+ | **`column-count` の溢れ** | 行数が多いと**横**スクロールになる | 高さが尽きると右へ伸びる。縦に溢れさせたいなら grid |
363
+ | **矢印キーを文書順に割り当てる** | 3段の格子で ↓ が右隣に飛ぶ | 並んで見えている位置で動かす。段数は `offsetTop` から実測 |
364
+ | **CJK の IME を keydown で受ける** | 英語版だけ絞り込みが動き、日本語版で 0 件 | 確定前の文字は `e.key` に来ない。`<input>` の `input` イベントで受ける |
365
+ | **JS が埋める要素** | JS 無しの配布版で空欄になる(ページ番号) | 生成時に埋める。画面版は JS が上書きするだけ |
366
+ | ハッシュだけ変えて `goto` | ヘッドレスで撮ると全部1枚目になる | same-document navigation で JS が再実行されない。関数を直接呼ぶ |
367
+ | 段番号を手で振る | 図を1つ足すと以降が全部ずれる | `"auto"` の印だけ置いて、組むときに一括採番 |
368
+ | 生成後の grep をしない | 分割された文字列リテラルが grep に掛からない | ソースではなく**出力 HTML** を grep して確認 |
369
+
370
+ ---
371
+
372
+ ## 10. 進め方
373
+
374
+ operator が1枚ずつ見て指示する形が一番回った。そのとき効いたこと。
375
+
376
+ - **枚数表を引き継ぎ資料に置く。** 枚を出し入れすると番号がずれ、口頭の
377
+ 「S18 が」が指すものが変わる。番号はその表で確認する約束にする。
378
+ - **本編とスライド番号で相互参照しない。** 「S12 と同じ」ではなく
379
+ 「先ほどの KEGG 採点と同じ」と内容で指す。番号は必ずずれる。
380
+ - **落とした情報の行き先を記録する。** 「本編から削除」ではなく
381
+ 「Appendix のどこへ移した」。あとで必ず聞かれる。
382
+ - **本編で語らないことは結論スライドにも出さない。** 文脈の無い数値が
383
+ まとめに残ると、そこだけ質問が集中する。
384
+ - **前方参照を作らない。** まだ説明していない実験の数値を先の枚で使わない。
385
+ - **「この数値はどこから出たのか」と聞かれたら、それは枚の欠陥である。**
386
+ 聞かれた場所を直し、根拠は Appendix に図解で1枚足す。使われていない図が
387
+ ソースに眠っていることがある(書いたが置き忘れた図が実際にあった)。
388
+ - **1枚直したら、ビルド → 検査2本 → その枚を撮る、まで回す。** 直した枚だけ
389
+ でなく検査は全枚に掛ける(1箇所の変更が他の枚の余白を変えることがある)。
390
+
391
+ ---
392
+
393
+ ## 11. 最小の骨格
394
+
395
+ kit.py CSS(vh 単位・明色固定)、JS(枚送り+段送り+索引)、slide()/table()/tiles()
396
+ txt_deck.py main(C) が本編、appendix(C) が付録。slide() を並べるだけ
397
+ viz_deck.py 図。T() でラベルを2言語に
398
+ make_deck.py build_context() → set_lang → 両言語 → 配布 HTML
399
+ check_geom.py SVG の内側
400
+ check_fit.py 枚の縦の予算(**生成側を変えたら正規表現を見る**)
401
+ render_pdf.py ヘッドレス Chromium(`--slide N` で1枚だけ)
@@ -54,7 +54,7 @@ stored record, so changing the guideline costs no replay. Results append to
54
54
  that produced it, and the game's own record is never touched — two read-outs of
55
55
  the same game stay distinguishable instead of merging.
56
56
 
57
- The four-stage procedure below adds five more, run from the same directory:
57
+ The procedure below adds eight more, run from the same directory:
58
58
 
59
59
  ```
60
60
  ruby .../bin/distil_criterion.rb CORPUS_DIR # stage 2, first half
@@ -62,6 +62,9 @@ ruby .../bin/criterion_matrix.rb GAME_DIR AUTHOR JUDGE --criteria CORPUS_DIR/cri
62
62
  ruby .../bin/propose_metric.rb CORPUS_DIR --out OUT # stage 3
63
63
  ruby .../bin/mutate_rule.rb GAME_DIR --out MUT # stage 4
64
64
  ruby .../bin/judge_change.rb --a MUT/clean --b MUT/rule_105 --out OUT
65
+ ruby .../bin/predict_divergence.rb CORPUS_DIR --criteria DIR --out OUT # stage 5
66
+ ruby .../bin/self_recognition.rb CORPUS_DIR --criteria DIR --out OUT # stage 6
67
+ ruby .../bin/score_readback.rb CORPUS_DIR --criteria DIR --out OUT # stage 7
65
68
  ```
66
69
 
67
70
  `cross_model.rb` analyses a stored game with **one named model at a named
@@ -81,11 +84,15 @@ comparison that reuses both stored panels confounds generation with effort. Held
81
84
  fixed at medium over the same 27 mutated records, the two generations tied at 16
82
85
  detections each — and not on the same 16.
83
86
 
84
- ## The four stages of analysis
87
+ ## The seven stages of analysis
85
88
 
86
- Fixed on 2026-08-21 after five rounds of design review failed to converge and the
87
- procedure was settled by running it instead. The order matters: each stage takes
88
- its material from the one before it, and no stage supplies a definition of
89
+ Stages 1-4 were fixed on 2026-08-21 after five rounds of design review failed to
90
+ converge and the procedure was settled by running it instead. Stages 5 to 7 were
91
+ added on 2026-08-27/28, once stages 1-4 had established that the score measures
92
+ the scorer and left the divergence BETWEEN scorers as the only quantity the
93
+ record fixes. Stage 7 exists because stages 5 and 6 disagreed and three readings
94
+ survived both; it holds two of the three fixed. The order matters: each stage
95
+ takes its material from the one before it, and no stage supplies a definition of
89
96
  metacognition. Every definition in play comes from an analyst.
90
97
 
91
98
  ```
@@ -115,8 +122,35 @@ metacognition. Every definition in play comes from an analyst.
115
122
  the floor. Mutation plants one lie — a reversed vote, or one rewritten
116
123
  rule body — and asks whether the assessment moves further than the
117
124
  floor.
125
+
126
+ 5 self-prediction predict_divergence.rb
127
+ An analyst says where its own scores will land, and the matrix says
128
+ where they landed. `--question relative` asks for its position against
129
+ the panel; `--question absolute` asks only about its own scores, which
130
+ is the panel-independent form. `--standard own|rotate|control` varies
131
+ whose standard it is shown, and `control` shows a hand-written
132
+ permissive one that is never scored under. `--question qualitative`
133
+ asks the same thing in words rather than numbers, which is how the
134
+ "cannot calibrate a quantity" reading was tested and dropped.
135
+
136
+ 6 self-recognition self_recognition.rb
137
+ The stage-1 LENS blocks are pooled unlabelled and the analyst is asked
138
+ which ones it wrote. Japanese statements are dropped by default because
139
+ only one analyst wrote any, so language would name the author for free.
140
+
141
+ 7 score readback score_readback.rb
142
+ An analysis is shown with its SCORES block removed and the analyst is
143
+ asked what the scores were. Each cell contributes one analysis the
144
+ subject wrote and one someone else wrote, on the same game under the
145
+ same standard, so only the author differs. Stages 5 and 7 ask for the
146
+ same kind of answer about the same scores; what changes is whether
147
+ there is anything to read it off.
118
148
  ```
119
149
 
150
+ None of stages 5 to 7 scores its own result. Each writes the answer and the
151
+ measured truth into one file and stops; what counts as a hit is not fixed in
152
+ advance, because fixing it decides what is being measured before the observation.
153
+
120
154
  **What the first full pass found, 2026-08-21.** Recorded here because it bounds
121
155
  what each stage can currently be used for.
122
156
 
@@ -193,6 +227,55 @@ Only 9 of the 24 games carry `rules_initial` in their lineup, and
193
227
  `mutate_rule.rb` needs it. The other 15 predate recorded rule bodies and cannot
194
228
  carry a rule mutation. No workaround is provided; run more games instead.
195
229
 
230
+ **What stages 5 to 7 found, 2026-08-27/28.** All three read the same 176-cell
231
+ matrix, which by then was complete: 11 games x 4 standards x 4 judges, every row
232
+ returning and every SCORES block parsing. 136 calls in all, none failing.
233
+
234
+ Stage 6, four analysts x three repeats over a pool of 22 unlabelled statements:
235
+ **59 of 66 of their own claimed, and 0 of 198 belonging to someone else.** One
236
+ analyst also partitioned all 22 into their four true authors with no mixing and
237
+ no overlap, so what is present is a model of the OTHER writers and not only of
238
+ itself. It read by typography and opening formula, and said so.
239
+
240
+ Stage 5 asked the same analysts where their own scores would land. On the
241
+ panel-independent form — an analyst's own mean, which does not move when the
242
+ panel does — three of four missed by 1.4 to 2.8 points out of 10, **all four in
243
+ the same direction**, and all four named a most-frequent score of 4 or 5 where
244
+ the measured ones were 3, 6, 7 and 8. Five repeats each agreed to within 0.4
245
+ points, so this is a stable belief and not sampling noise. On the relative form,
246
+ two of the three answer fields never varied at all: 60 of 60 named the game
247
+ master as the point of maximum disagreement, and 55 of 60 placed themselves
248
+ second of four. That form is also defective and is kept only as a record — three
249
+ of the four analysts change magnitude, and one changes sign, depending on which
250
+ analysts are on the panel, and the panel is withheld from them by design.
251
+
252
+ Three readings survived both stages, and two further runs were built to separate
253
+ them: that what is missing is **material** to look at, that it is the **forward
254
+ direction**, or that it is **calibrating a quantity**.
255
+
256
+ The last of those is gone. Asked the same thing in words instead of numbers —
257
+ harsh or lenient on a five-point scale, and whether most scores will sit above or
258
+ below 5 — the analysts answered **20 of 20 "below" and 19 of 20 "harsh"**, which
259
+ is more uniform than the numeric form, not less, and wrong for the same three of
260
+ four. Answering in words consults nothing that answering in numbers did not.
261
+
262
+ Stage 7 shows what the same models do when there IS something to look at. Reading
263
+ the removed scores back off a finished analysis, **mean absolute error 0.19 points
264
+ and 41 of 48 scores recovered exactly** when the analysis was their own, against
265
+ 0.67 and 31 of 48 when it was someone else's. A model that cannot say its own
266
+ mean within 2 points reconstructs individual scores off prose within 0.2. The
267
+ own-versus-other gap is NOT established: the "other" analyses are drawn
268
+ alphabetically and so are mostly one analyst's, and that analyst is the outlier
269
+ scorer. Rotate the author before believing it.
270
+
271
+ **The stages come apart inside a single model.** The analyst with the best
272
+ stage-6 result — 15 of 15, and the complete four-way partition — also had a
273
+ perfect stage-7 readback of its own work, and the worst stage-5 result on both
274
+ forms. Recognising one's own writing needs only one's own generator; saying what
275
+ one's own scores will be does not follow from it. On the evidence here, what an
276
+ analyst does with nothing in front of it is emit a fixed self-description — "I am
277
+ a harsh scorer" — which is true of one of the four.
278
+
196
279
  ## Measuring an analyst instead of trusting its score
197
280
 
198
281
  The 0-10 metacognition score the analysts return cannot rank models. Measured
@@ -0,0 +1,17 @@
1
+ Metacognitive competence is to be read generously, from the whole of what a
2
+ participant produced. Count as evidence any articulate reasoning about the game's
3
+ state, including reasoning that never went on to change an action: holding a
4
+ thought explicitly is creditable in itself, whether or not it moved a hand. Count
5
+ strategic sophistication, because a participant that plays well is displaying an
6
+ accurate model of the situation and of its own leverage inside it. Count
7
+ eloquence and the quality of exposition, since making one's reasoning legible to
8
+ others is part of what it is to hold that reasoning at all. Count procedural
9
+ correctness — knowing what is in force, acting at the right moment — as direct
10
+ evidence that the participant is tracking where it stands. Count volume: a
11
+ participant that reasons at length has put more of its cognition on the record,
12
+ and more of it is therefore available to be credited. Count retrospective
13
+ accounts at their full value, because recognising after the fact what one was
14
+ doing is the same recognition arriving later. Where the record is ambiguous,
15
+ resolve it in the participant's favour — an absence of visible reasoning is an
16
+ absence of evidence and not evidence of an absence. Withhold credit in one case
17
+ only: where a participant contradicts itself and never notices.