@aiquants/daily-report 0.28.0 → 0.30.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,95 @@
2
2
 
3
3
  All notable changes to `@aiquants/daily-report` are documented here.
4
4
 
5
+ ## 0.30.0 (2026-10-06)
6
+
7
+ 0.29.0 の続き: 本体をストリームで返す 2 つの経路のフレームワークのデータの要求をパッケージが断ること (ホストの経路は薄いマウントに戻る)、原本の本文の 1 切れずつの受け渡しと無通信の締め切りと閲覧者ごとのスロットの上限、間隔を単調な時計で測ること、読み取りの予算切れの 504、暦に無い営業日の 400、行とカードのフォーカスのアウトラインをキーボードのフォーカスの属性の下だけで描くこと、整数の装置の画素のホバーの浮き上がり、List のカードの位置の読み上げ、キーの移動の `tabindex` をフォーカスの受け渡しで書くこと、ハンドラーの設定と戻り値の型の公開。どれも README の該当の節が今の契約を記す。
8
+
9
+ ### Security
10
+
11
+ - **ストリームの経路へのフレームワークのデータの要求はパッケージが断る**: ハンドラー工場の要求の隔離の包みが、SSE の経路 (`sse.loader`) へのデータの要求はどれも、API の経路 (`api.loader`) へのものは ID 一覧の NDJSON の分 (`ids-stream.data`。カーソル付きと末尾の斜線の `ids-stream/_.data` も) だけを、GET も HEAD も、認証より前に 404 の JSON (`{"error":{"message":"Not Found"}}`、`Cache-Control: no-store`・`X-Content-Type-Options: nosniff`) で断る (経路の方針の `frameworkDataRefusal`: `SSE_ISOLATION_POLICY`・`API_LOADER_ISOLATION_POLICY`)。断った要求は認証・購読・タイマー・クエリのどれも始めず、拒否の記録にも書かない。JSON のエンドポイント (`report`・`business-date`) と action は今までどおりデータの要求を受ける。
12
+ 以前はホストの経路が断る契約だったので、断りを置き忘れたホストでは `<経路>.data` の要求 1 つが、終わらない SSE の本体か ID 一覧の NDJSON の全量をサーバーのメモリに溜めた。どのホストも版を上げれば守られ、2 つの経路は薄いマウント (`(args) => dailyReportServer.sse.loader(args)` と `(args) => dailyReportServer.api.loader(args)`) でよい。
13
+
14
+ ### Fixed
15
+
16
+ - **原本の本文は 1 切れずつ渡し、止まった読み手はスロットを握り続けない**: GET の原本の本文は、256 KiB の 1 切れの写しを、ホストの書き手が読むたびに 1 つずつ渡す (本文は書き手の先に何も積まない)。同時実行のスロットは原本を参照する間だけ保持し、最後の 1 切れを渡したとき・クライアントが本文を取り消したとき・書き手が 60 秒のあいだ次の 1 切れを求めなかったとき (無通信の締め切り。読みのたびに始め直す) に返す。締め切りでは本文を失敗で終え、原本の残りを捨てる。
17
+ 1 人の閲覧者が同時に保持できる原本のスロットは枠の半分の切り上げ (⌈`attachmentConcurrency` / 2⌉。既定の 4 なら 2) で、それを超える要求は空きがあっても過負荷の 503 (`reason=concurrency`、`Retry-After`) になる。プロセスが溜めうるのは、転送が進む間は「同時実行 × 原本の上限」に応答ごとの渡し済みの 1 切れを足した分、無通信の締め切りを過ぎて止まった応答には 1 切れだけ (README の Attachments の Heap estimate)。
18
+ 以前は原本全体を最初の読みで本文の待ち行列へ渡し、スロットは送り終えるか 120 秒のバックストップまで保持した。読み止めたクライアントはスロットを 120 秒握り、バックストップの後もバイト列は書き手の待ち行列に残ってヒープの見積りの外に溜まり、1 人の閲覧者が読み止めた転送を並べれば枠を全部握ってほかの閲覧者を 503 にできた。
19
+ - **間隔・締め切り・有効期限は単調な時計で測る**: サーバー層のレートのバケットの補充、SQL の結果のキャッシュの有効期限、縮小画像の段の締め切りを過ぎた決着と決着しない読み取りや描画の計時、ハンドラーとサービスの経過時間のログは、プロセスの単調な時計 (`performance.now()` の切り捨て) で測る。壁時計は意味が時刻のもの (記録の `since=`・一時的な ID) だけに使う。
20
+ 以前は壁時計で測ったので、運用の時刻合わせで時計が戻ると、戻った分だけレートのバケットが補充されず (429 が `Retry-After` より長く続く)、キャッシュが有効期限を過ぎても新しいまま残った。
21
+ - **暦に無い営業日は 400**: API の `business-date` は、形の合う日付でも暦に無い日 (`2026-13-40`・`2026-02-29`・`2026/04/31`・月 0) を、クエリより前に 400 (`Invalid business date`) で答える。以前は形だけを見てクエリへ渡し、データベースの変換の失敗が 500 (サーバーの失敗の行) になった。
22
+
23
+ ### Changed
24
+
25
+ - **読み取りの予算切れは 504**: 縮小画像の生成の読み取りの段の締め切り (`readMs`、30 秒) が先に来たときの答えは 504 (`reason=read_timeout`、文面は `Thumbnail storage timed out`) で、ポート自身の締め切り (`deadline`) と同じ状態になった。ストレージの読み取りの締め切りは、どちらが先に切れてもクライアントには同じ 504 で、ログの理由がどちらの締め切りかを残す (どちらも warn)。キャッシュにも実体消失にも書かないのは今までどおり。縮小の段の締め切りは 502 (`render_timeout`) のまま。以前は読み取りの予算切れも 502。
26
+ - **行とカードのフォーカスのアウトラインはキーボードのフォーカスの属性の下でだけ描く**: 行の枠の面と List のカードの面のアウトラインは、`:focus-visible` に加えて、ビューの根要素が `data-daily-report-keyboard-focus` を持つときだけ描く (`ROW_FRAME_STATE_CLASS_NAME`・`CARD_SURFACE_STATE_CLASS_NAME`。祖先は `:where()` で読むので、詳細度は (0,2,0) と (0,3,0) のまま)。アウトラインを描くなら属性があり、属性があればタップスクロールのサークルは隠れるので、2 つが一緒に出ることは作りから無い。操作部品 (ボタン・リンク・タブ・スイッチ・入力欄) の輪は今までどおり `:focus-visible` だけに依る。
27
+ 以前は Chromium がポインターの押下の後の `Shift` や `CapsLock` だけの押下でも `:focus-visible` とするので、ビューがポインターの操作と見なしてサークルを描いている間に、行のアウトラインも描かれた。
28
+ - **ホバーの浮き上がりは整数の装置の画素**: カードのホバーの浮き上がり L は、画素密度 dpr で 2 CSS px 以下の最大の整数の装置の画素 (⌊2·dpr⌋ / dpr): 1・1.5・2・3 では 2 px、1.25 では 1.6 px (2 装置画素)、1.75 では 12/7 px (3 装置画素)。値はカード自身のカスタムプロパティ `--aqdr-hover-lift` に置き、2 つの画素密度だけを `resolution` の媒体条件で上書きし、浮き上がりの `translate` がそれを読む。G = 8 ≥ 輪 2 + 隙間 2 + アウトライン 2 + L は保たれる。
29
+ 以前は常に 2 px で、1.25 と 1.75 ではホバーした面が装置の画素の半分に乗り (2.5 と 3.5 装置画素)、1 px の枠線・輪・アウトラインが隣の画素の行へにじんだ。
30
+ - **キーの移動の `tabindex` はフォーカスの受け渡しで書く**: 行カーソルは移動先の `tabindex="0"` を `focus()` の前ではなく、移動元のフォーカスが外れた所 (移動元の `focusout` の中。どの要素もフォーカスを持たない) で書く。Chromium の `focus()` は要素の間のフォーカスの移動のたびにスタイルを 2 回計算し直し (移動元が失った直後と移動先が得た直後)、書き込みはその 1 回目に相乗りする。
31
+ 以前は `focus()` の前に書いたので、ホストの CSS が `[tabindex]` を見ると `focus()` の入口でもう 1 回計算し直した (Chromium 148 で 8 回のキーの移動が 24 回。今は 16 回)。
32
+ - **DEV の操作箱のアイコンのボタンの的は 24 × 24**: 再読み込みとキャッシュの消去のボタン (`showDevControls`) は、見た目の 16 px のまま、上下左右に 4 px はみ出す擬似要素で 24 × 24 の的を持ち (WCAG 2.5.8)、8 px 離れて並ぶ。以前は 16 × 16 の的が 4 px 離れて並んだ。
33
+ - **開発者向け**: ハンドラーの工場のモジュールを分けた。`src/server/handlers.ts` は設定・ロガー・可視集合の解決・index・JSON のエンドポイントの表・action・要求の隔離の包みを持ち、SSE の配信は `src/server/sse-delivery.ts`、ID 一覧の NDJSON の配信は `src/server/ids-stream-delivery.ts`、本体をストリームで返す 2 つの答えが共有する HEAD の規則は `src/server/stream-body.ts`、時計は `src/server/monotonic-clock.ts` にある。添付のレートのバケット (`createRateLimitBucket`) は制限・閲覧者ごとの拒否の記録・429 を 1 つに持ち、原本と縮小画像の配信が使う (行の書式は変わらない)。
34
+ docstring の歯止め (`scripts/lib/ratchet-docstrings.mjs`) は、関数が返す関数と、オブジェクトのリテラルの関数の値のプロパティも数え (呼び出し・`new`・JSX の属性へ渡すリテラルは数えない)、基準 (`docstring-baseline.json`) はこの規則で 1 回記録し直した。React Router の実物の要求の処理を通す spec は、断った `.data` の要求ごとに loader が 1 回呼ばれて認証が 0 回であること (経路の照合が外れた 404 ではないこと) を確かめ、添付の行は同じ URL の `.data` の無い要求が同じ処理で答えることも確かめる。
35
+
36
+ ### Added
37
+
38
+ - client のラベルのキー `listRowPosition(position, total)`: List のカードの主ボタンの最初の説明になる、一覧の中の位置 (en "3 of 40"、ja 「全 40 件中 3 件目」。数は UI の言語の桁区切り)。フォーカスを受ける主ボタンは `aria-posinset` を持てないので、行の枠の位置を言葉で伝える。窓より前への挿入・削除で描き直すのは行の枠とこの文言だけで、カードの本体は描き直さない。固有のキーは 84 (全体は 95) で、上書きは関数でなければならない。
39
+ - server の型 `DailyReportHandlersConfig`・`DailyReportHandlers` (`createDailyReportHandlers` の設定と戻り値) と `DailyReportServer` (`createDailyReportServer` の戻り値)。ホストと例は `Parameters<>` や `ReturnType<>` で引き直さずに読み込む。型だけの公開なので、バンドルは増えない。
40
+
41
+ ### Breaking
42
+
43
+ - server の値 `DAILY_REPORT_IDS_STREAM_ENDPOINT` を公開しない: フレームワークのデータの要求の断りはパッケージの要求の隔離が決め (上の Security)、ホストの経路はエンドポイントの名前を比べない。
44
+ Migration: ホストの SSE の経路と API の経路から `.data` の断り (`<経路>.data` に 404 を投げる部品) と `DAILY_REPORT_IDS_STREAM_ENDPOINT` の読み込みを外し、`sse.loader` と `api.loader` をそのままマウントする。React Router の実物の要求の処理を通す経路の試験は、そのまま 404 を確かめられる。
45
+ - ピアの `@aiquants/virtualscroll` の下限を 3.11.1 へ上げた (`peer-floors.json`)。両ビューが 3.11.1 の変更に頼る所は無いが、この版の試験はすべて 3.11.1 の上で通したので、公開する範囲 (`^3.11.1`) と文書の下限をそれに合わせた。
46
+ Migration: `@aiquants/virtualscroll` を 3.11.1 以降へ上げる。
47
+
48
+ ## 0.29.0 (2026-10-06)
49
+
50
+ 0.28.0 の続き: 添付の経路のフレームワークのデータの要求 (`<token>.data`) の拒否、本体をストリームで返す 2 つの答え (SSE と ID 一覧) の HEAD、読み取りポートの失敗の理由 `busy` と `deadline`、窓の終わりに数を書く拒否と 429 の記録、行のサイズの裏付けの無い `too_large` をキャッシュしない縮小画像の生成、ポインターで押したフォーカスをキーボードのフォーカスと見なさない判定、枠を越えない折り返す文言と側面ペインのパネルの最小の幅、DetailList のカードの日付の `<time>`。どれも README の該当の節が今の契約を記す。
51
+
52
+ ### Security
53
+
54
+ - **添付の経路はフレームワークのデータの要求を断る**: React Router のシングルフェッチのデータの要求 (経路が `.data` で終わる `<token>.data`) には、どのオリジンからでも、GET も HEAD も、インライン・ダウンロード・サムネイルのどれも、添付の経路の 404 (`Attachment not found`) で答える。断るのはハンドラー工場の要求の隔離の包みで (経路の方針の `frameworkDataRefusal`、判定は `isFrameworkDataRequest`)、認証・レートの課金・認可・ストレージの読み取りのどれより前に投げ、拒否の記録にも書かない (別オリジンの拒否ではない)。
55
+ 以前は、別オリジンのページのリンクから開く最上位のナビゲーションとして `<token>.data?inline=1` が隔離を通り、原本をストレージから読んだ後、React Router が本体を最後まで読んで文字列へ符号化し、`Set-Cookie` のほかのヘッダー (`private, no-store`・CSP の sandbox・`nosniff`・`Cross-Origin-Resource-Policy`・`X-Frame-Options`・`Content-Disposition`) を捨てて答えた (8 MiB の原本で約 1,250 万文字、ヒープの見積り「同時実行 × 上限」の外で約 37 MiB)。API・action・SSE の経路はデータの要求を今までどおり受ける。本体をストリームで返す 2 つはホストの経路で断る (README の Server wiring の Streaming routes)。
56
+
57
+ ### Fixed
58
+
59
+ - **SSE と ID 一覧のストリームの HEAD は本体の仕事を始めない**: React Router はリソースの経路の loader を HEAD にも走らせ、本体を読みも取り消しもせずに捨てる (アダプターは送り終えた応答の要求のシグナルも中断しない)。`sse.loader` は HEAD に GET と同じ状態とヘッダーで答え、Fan-Out の購読・heartbeat・可視集合の再解決のタイマーを始めない。ID 一覧もカーソルの検証 (400) までを GET と同じに行ってから、GET の 200 と同じヘッダーで本体なしに答え、全量と先頭ページのクエリを走らせない。既に中断された GET も同じ。
60
+ 以前は認証済みの HEAD の要求 1 つが、購読・heartbeat・可視集合の再解決のタイマー (DB への問い合わせ) を、誰も読まないままプロセスが終わるまで残した。
61
+ - **API の経路のエンドポイントとメソッド**: 順は認証 (401)・エンドポイント (知らない名前は 404。`toString` のような継承した名前も)・メソッド (エンドポイントが答えないメソッドは 405 と `Allow`。JSON のエンドポイントは `GET`、ID 一覧は `GET, HEAD`)。以前は GET 以外を `Allow` の無い 405 で断り、エンドポイントの名前を素のオブジェクトから引いた。
62
+ - **行のサイズの裏付けの無い `too_large` をキャッシュしない**: サムネイルの生成は、読み取りポートの `too_large` を、行が上限を超えるサイズを記録しているときだけ内容で決まる結論として記録する。サイズを記録していない行の `too_large` (裏付けが無い。ホストが一時的な拒否を `too_large` と取り違えても同じに見える) には、その要求に 404 (`Cache-Control: no-store`、検証子なし) で答えて記録せず、行は `reason=too_large size=unrecorded` (info。食い違いではないので `size_mismatch` は書かない)。次の表示は読み取りポートへもう一度問う。
63
+ 以前は全利用者に共有され期限の無い 404 をキャッシュしたので、ストレージの接続あたりのストリームの上限で 1 度断られただけの画像が、プロセスの寿命のあいだ誰にもプレビューを出さなかった (1 回の読み取りで 404・404・404)。
64
+ - **ポインターで押したフォーカスはキーボードのフォーカスではない**: キーボードのフォーカスの判定 (`isKeyboardFocused`) は、`:focus-visible` に一致し、要素の文書の最後の入力がポインターの押下でないこと。最後の入力は、その文書のビューがマウントされている間、文書ごとに記録する (`observeInputModality`: 捕獲段の `pointerdown` でポインター、修飾キーだけでない `keydown` でキーボード)。行を見せるスクロールとビューの根要素の `data-daily-report-keyboard-focus` は、どちらもこの判定だけを読む。
65
+ 以前は `:focus-visible` だけで決めたので、ポインターの押下でもブラウザーが `:focus-visible` とする文字入力の要素 (行のコメント欄・編集フォーム) をクリックすると、ビューが行を見せるスクロールをし、根要素に属性を付けて、タップスクロールのサークルを次の押下まで隠した。
66
+ - **折り返す文言は枠を越えない**: `WRAPPING_LABEL_CLASS_NAME` は `text-balance wrap-anywhere [word-break:auto-phrase]`。足した `overflow-wrap: anywhere` は 1 行に収まらない文節や語だけをその中で折り、その折り目を最小の内容の幅にも数えるので、flex の項目の自動の最小の幅が文言を最長の文節の幅に留めない (継承する性質なので、タイルの文言の箱の匿名の flex の項目にも届く)。文節が収まるところの行は変わらない。
67
+ 以前は側面ペインの選択を促す文言 (ja) が flex の項目の自動の最小の幅で最長の文節 「選択してください。」 (126 px) に留まり、ペインの幅 160〜197 px で破線の仮の面を左右 7 px ずつ越えた。
68
+ - **側面ペインのパネルの最小の幅は 200 px**: 選択を促す文言を囲む枠 (パネルの余白 2G 16・カードの面の寄せ 2 × 16・仮の面の寄せ 2 × 12 = 72) と、既定の根での文言の最長の文節 (9 字 × 0.875 rem = 126 px) の和 198 を、4 px の格子へ切り上げた値 (`SIDE_PANE_PANEL_MIN_WIDTH_PX`)。既定の根では ja の文言が文節の境だけで折り返し、はぐれた字の行を残さない。一覧のパネルの最小は 160 px のまま (以前は両方とも 160 px)。
69
+
70
+ ### Changed
71
+
72
+ - **読み取りポートの失敗の理由に `busy` と `deadline`**: `DailyReportAttachmentFailure` は閉じた 1 つのユニオンで、どの理由にも答えるステータスが決まる (`not_found`・`denied`・`invalid_path` は 404、`too_large` は原本 413・縮小画像 404、`unavailable` は 502)。新しい `busy` (ストレージが今は受けない一時的な拒否。接続あたりのストリームの上限ですぐ断られたなど) は 503 と `Retry-After: 5`、`deadline` (ストレージの呼び出しがポート自身の締め切りを過ぎた) は 504 で、原本と縮小画像で同じ。縮小画像の生成はどちらも結論にせず、キャッシュにも実体消失にも書かない (生成の合流を待った要求は同じ失敗を受け、次の要求は読み直す)。ログは warn。
73
+ ユニオンの外の理由は、推測で 502 へ寄せずにポートの契約違反の 500 (`reason=port_contract code=failure_reason`、error) にする (以前は 502)。縮小画像の 503 の文面は原因によらず `Thumbnail temporarily unavailable` (以前は `Too many concurrent thumbnail requests`)、504 は `Thumbnail storage timed out`。原本の 503 は `Attachment storage busy`、504 は `Attachment storage timed out`。README の読み取りポートの例は、自前の締め切りだけが止めた呼び出しを `deadline` で返す。
74
+ - **拒否と 429 の数は窓の終わりに書く**: 要求の隔離の拒否の記録と、添付の 3 つのレートのバケットの 429 の記録は、1 つの窓の仕組み (`createSuppressionWindows`。状態はインスタンスが持つ) を使う。キーの最初の事象がその場で自分の行を書いて窓を開き、窓の中の後の事象は数えるだけで、窓自身のタイマー (unref) が窓の終わりに、数えたものがあれば数の行を書いて窓を閉じる。
75
+ 数の行は `cross_site_rejected_suppressed count=<N> since=<窓の始まりの ISO 8601> routes=api:<n>,action:<n>,sse:<n>,attachment:<n>` と `rate_limit_suppressed count=<N> since=<…> viewer=<id>` (縮小画像は `variant=thumbnail` を足し、再検証のバケットは `revalidation_rate_limit_suppressed`)。429 の窓は閲覧者とバケットごとで、長さは `RATE_LIMIT_LOG_WINDOW_MS` (60 秒、429 の `Retry-After`)。キーごとに窓 1 つにつき 2 行まで。窓を決めるのはタイマーだけで、壁時計は `since=` を刻むだけ (時計が戻ったときの規則は無くなった)。
76
+ 以前は数を次の事象まで持ち越したので、続きが止まった窓の数は書かれず、ずっと後の無関係な拒否がその時刻で窓の始まりも経路も無く書いた。429 は利用者の次の許可を待ったので、拒否が止まったかバケットが追い出された数は失われ、要求を送り続けるクライアントには補充のたびに 2 行 (上限 60/分で 1 分に約 120 行) を書かせた。
77
+ - **DetailList のカードの日付はどれも `<time datetime>`**: メタデータの列の作成日時・更新日時・営業日も、見出しの札 (営業日・更新日時) と同じ部品 (`DateText`) で描く。無い日付の `-` は文字のまま。以前は同じ行の同じ日付を、見出しでは `<time>`、メタデータの列では平らな文字で公開した。
78
+ - **配置の格子の単位の契約の文言**: `DAILY_REPORT_LAYOUT_LATTICE_PX` の docstring と README の View height は、ホストができることだけを書く。ホストはビューの周りのバー (ヘッダーとフッター) をこの単位の倍数にそろえ、ビューの上の縁を格子に乗せる。ウィンドウの高さは決められないので、単位で割った余りはビューの中に残る。
79
+ 端へ揃えた行は、ビューの端と行の箱が整数の装置の画素にあればちょうど G (整数の画素密度ではビューの端が整数の CSS px にあるとき、1.25・1.5・1.75 ではビューの端が格子にあるとき)、それ以外 (0.9・1.1・1.33 などのブラウザーの拡大率を含む) では端を守る寄せで G 以上 G + 1 装置画素未満。クラスを字面で書くホスト (Tailwind) は、字面をこの値へ単体テストで結び付ける。
80
+ - **開発者向け**: ID 一覧の行の分割 (`createNdjsonLineSplitter`) は、テストのためだけの数え (`scannedCharacters`) をクライアントのバンドルに持たない。線形時間の spec は `String.prototype.indexOf` と `split` が調べた文字を数え、1 MiB を 1 KiB ずつ送って長さの 2 倍以下を求める (持ち越して全体を分け直す旧い形では約 5 億 3,800 万文字)。
81
+ `src/docs-examples.spec.ts` は、README と `docs/specs` の文のうちピアの下限を名乗る文が、`peer-floors.json` の下限のほかの版を書くと落ちる (公開の検査は manifest しか読まない)。ID 一覧のエンドポイントの名前はクライアントとサーバーが `DAILY_REPORT_IDS_STREAM_ENDPOINT` を共有する。
82
+
83
+ ### Added
84
+
85
+ - server の値 `DAILY_REPORT_IDS_STREAM_ENDPOINT` (`"ids-stream"`): ID 一覧の NDJSON を流す API のエンドポイントの名前。クライアントの URL とサーバーのエンドポイントの表がこれを使い、ホストは字面を書き写さずにこのエンドポイントだけを見分ける (React Router のデータの要求をこのエンドポイントについて断るなど。README の Server wiring の Streaming routes)。
86
+ - server の型 `DailyReportAttachmentFailure` の `busy` と `deadline` (上の Changed)。
87
+
88
+ ### Breaking
89
+
90
+ - 読み取りポートが `DailyReportAttachmentFailure` の外の理由を返すと、どちらの配信もポートの契約違反の 500 で答える (以前は 502)。`DailyReportAttachmentFailure` を
91
+ 網羅して分岐するホストのコード (理由ごとの表など) は、型検査が `busy` と `deadline` の欠けを示す。
92
+ Migration: ポートは 7 つの理由だけを返す (ストレージの一時的な拒否は `busy`、自前の締め切りを過ぎた呼び出しは `deadline`)。理由で分岐するホストのコードに 2 つを足す。
93
+
5
94
  ## 0.28.0 (2026-10-05)
6
95
 
7
96
  0.27.0 の続き: 要求の隔離の許可の一覧化 (別オリジンから受けるのは添付の原本を開く最上位の文書のナビゲーションだけ)、Fetch Metadata の無い要求の `Origin` による判定、拒否の上限付きの記録、添付のどの応答にも枠の方針、配置の格子の単位と E2E のテスト用ハンドルの型の公開、ID 一覧のストリームの行の線形な分割、折り返す文言の改行の規則。どれも README の該当の節が今の契約を記す。
@@ -16,7 +105,7 @@ All notable changes to `@aiquants/daily-report` are documented here.
16
105
 
17
106
  ### Added
18
107
 
19
- - client の値 `DAILY_REPORT_LAYOUT_LATTICE_PX`: 配置の格子の単位 (4 CSS px)。パッケージ自身の格子の単位そのもので、ホストがビューの周りのバー (ヘッダー・フッターとそれらが分け合うウィンドウ) の大きさをこの倍数にそろえる契約 (README の View height の G-symmetric frame)。公開する配置の値はこれだけで、行の大きさは公開しない。
108
+ - client の値 `DAILY_REPORT_LAYOUT_LATTICE_PX`: 配置の格子の単位 (4 CSS px)。パッケージ自身の格子の単位そのもので、ホストがビューの周りのバー (ヘッダーとフッター) の大きさをこの倍数にそろえ、ビューの上の縁を格子に乗せる契約 (ウィンドウの高さはホストが決められないので、単位で割った余りはビューの中に残る。README の View height の G-symmetric frame)。公開する配置の値はこれだけで、行の大きさは公開しない。
20
109
  - client の型 `DailyReportViewTestHandle`・`DailyReportViewTestReadHandle`・`DailyReportRevealOptions`: E2E のテスト用ハンドル (`__virtualScroll`) の契約とその読み取りの部分、`revealIndex` の揃えの型 (VirtualScroll の `scrollToIndex` の第 2 引数。virtualscroll 3.11.0 の見せる操作 `{ align: "nearest" }` も含む)。型だけの公開なので、バンドルは増えない。ホストのテストは形を書き写さずに読み込む。
21
110
 
22
111
  ### Changed