Files
yoi/docs/report/test-suite-timing-investigation.md

243 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# テストスイートの実行時間調査
対象: `7042ec7d` (`hare/develop`, develop取り込み後)。以下の初回調査では製品コード・テストコードの変更なし。T-761による最適化後の測定は末尾に追記した。
## 結論
実行できた通常Rustテスト95バイナリの壁時計合計は **644.15秒(10分44秒)**。 `yoi-workspace-server` と `session-store` だけで **72.7%** を占める。 Webの通常テスト群は計約27秒であり、主なボトルネックではない。
全テスト成功という意味ではない。既存の `yoi` CLIテストのコンパイルエラー2件により、そのバイナリは測定対象外になっている。
## 条件・測定方法
- Linux、Rust 1.95.0、Deno 2.7.14、debug/test profile。
- `std::thread::available_parallelism()` は24。`RUST_TEST_THREADS` 未指定。
- リポジトリと `/tmp` は同じNVMe上のext4。専用・無負荷の測定ホストではない。
- crate内はlibtest既定並列、テストバイナリ間は逐次実行。SubWorkerには読み取り専用のコード調査のみを委任。
- ビルドと実行を分離。`cargo build --workspace --exclude yoi-e2e --tests --keep-going --message-format=json` で取得したtest executableを、それぞれのcrateディレクトリから実行。
- `RUSTC_BOOTSTRAP=1 <test executable> -Z unstable-options --format json --report-time` で個別時間を採取。`RUSTC_BOOTSTRAP`はこの計測用テスト実行プロセスに設定し、外側のCargoビルドには設定していない。テストが起動する子プロセスには継承される。
- 95バイナリで5,067 passed / 3 ignored / 0 failed。これはコンパイルできた対象だけの結果。
- 600秒のコマンド実行上限に達したため2バッチで実行。最初の未完了Server試行は集計せず、再実行して完走したServer測定だけを使用。644.15秒は完走した各バイナリの壁時計の合算であり、調査作業全体の所要時間ではない。
- 各条件1回の測定。キャッシュ・他プロセスの負荷による変動を含む。中央値や専用CI性能ではない。
- 個別テストの時間には同じバイナリ内の並列競合・ロック待ちも含まれる。個別時間の合計はスイートの壁時計と一致しない。
## 時間配分
### 外側のビルドとスイート
| 対象 | 壁時計 | 備考 |
| -------------------------------------------------------------------------- | -------: | ----------------------------------------------------------------------- |
| Rust test対象ビルド・初回 | 164.86秒 | 既存キャッシュあり。不足する対象をコンパイル。CLIテスト2エラーで終了101 |
| 同じRust test対象ビルド・再実行 | 2.32秒 | 温まったキャッシュ。同じ2エラー。正常完走ビルドの時間ではない |
| Rust unit/integration、95バイナリ | 644.15秒 | 外側のビルドを除く。テスト内部のCargo起動は含む |
| Rust doc (`cargo test --workspace --exclude yoi-e2e --doc --no-fail-fast`) | 22.36秒 | コマンド全体。2 passed / 21 ignored、rustdoc起動等を含む |
| Web unit (`deno task test`) | 10.01秒 | 665 passed、コマンド全体 |
| Web component (`deno task test:component`) | 11.30秒 | 413 passed、変換・起動込み |
| Web UX tooling unit (`tools/web-ux: deno task test`) | 5.65秒 | 16 passed |
これらの実行可能なテスト群を逐次足すと、外側のRustビルドを除いて **693.47秒(11分33秒)**。追加の単独再測定・並列数比較はこの合計には含めない。
### Rust crate別(各crate内のバイナリ壁時計合算)
| crate | 秒 | 主な内容 |
| ---------------------- | ---------: | -------------------------------------------------------------- |
| `yoi-workspace-server` | **376.68** | DB移行、DBを伴うAPI/authority等。Rust全体の58.5% |
| `session-store` | **91.40** | 巨大な旧形式inline画像の1テストが90.07秒 |
| `agen` | 34.94 | compile-fail/trybuildが27.35秒 |
| `worker-runtime` | 32.44 | timeout解除確認の1テストが31.02秒 |
| `api-macros` | 24.51 | compile-failが19.32秒、renamed dependencyのCargo checkが4.96秒 |
| `yoi-plugin-pdk` | 18.39 | wasmテンプレートのCargo check。2テストが並列で各約18秒 |
| `ticket` | 16.76 | SQLite schema/assignment/tag等 |
| `standalone` | 13.97 | Subject/Job等のintegrationも含む |
| `worker` | 9.45 | unitとintegration 9バイナリ |
| `tools` | 8.29 | 大きいbinary readの1テストが5.74秒 |
| `subjektiv` | 7.89 | Journal Unicode/budgetケース等 |
| `merge-request` | 2.73 | 主にstore integration |
| `workspace-drive` | 2.60 | 2バイナリ |
| `workdir` | 1.71 | 6バイナリ |
| その他 | 約2.39 | server-api等 |
## 1. Workspace Server:DB fixtureの反復と同時実行時の増幅
### 遅いケースの単独比較
同じコンパイル済みバイナリ、同じ入力をフィルタして1テスト・1スレッドで実行した。
| テスト(名前の共通prefixを省略) | 全体実行中 | 単独 |
| -------------------------------------------------------------------------------------------------------------------------- | ---------: | ---------: |
| `store::tests::migration_resumes_from_a_valid_partially_applied_chain` | 95.94秒 | **4.71秒** |
| `store::tests::schema_v50_plans_and_applies_the_complete_retained_chain` | 80.77秒 | **4.88秒** |
| `store::tests::schema_v89_runs_auth_then_cases_preserving_legacy_states_evidence_and_responsibility` | 63.80秒 | **6.24秒** |
| `server::tests::assignment_start_tests::orchestrator_start_and_assign_reject_missing_stale_cleared_or_reissued_delegation` | 81.03秒 | **7.46秒** |
ほかに、`migration_dry_run_and_apply_share_the_original_repository_secret_authority` 87.11秒、`opening_schema_84_with_uncertain_removal_preserves_old_server_recovery` 83.41秒、Journal erased-archiveケース78.79秒、v82移行67.32秒、v90移行63.59秒。
**「95秒の単独処理が必要」ではない。** 並列実行条件で所要時間が大幅に増幅する。一方で、Server全体を `--test-threads 4` にすると **544.25秒** と既定並列の376.68秒より44.5%遅かった。同じ1,126件成功・2件ignored。個別の待ち時間を短縮しても全体の処理量が減るとは限らず、並列数を減らすだけの対策は採用できない。
単独比較と並列数比較はそれぞれ1回なので、CPU・ディスク・SQLite内部処理の寄与率までは確定していない。`fsync`回数やI/O待ち率のprofileは未取得。
### ソースで確認できた反復処理
- `crates/workspace-server/src/store.rs:17521–17600` の `prepare_schema_v52()` は実ファイルDBに凍結Ticket schema、MR schema、v85凍結schemaを構築後、旧schemaへ戻す。`prepare_schema_v50()` はさらにそれを加工する(同`:17603–17656`)。
- `create_frozen_schema_v85()`(同`:17407–17500`)が読む凍結SQLは1,654行。fixture全体を包むtransactionはなく、多数のDDL・seedを個別に実行する。
- `migration_plan()` は単なる版一覧ではなく、DBをメモリへbackupし実際にmigrationを適用する(同`:2501–2518`)。
- `migrate_database()` は再度planを行ってから実DBを移行する(同`:2521–2525`)。v50完全連鎖テストは51→98の連鎖を計3回適用する。
- 通常APIテストも `server.rs:56594–56608` 等で新しいDBを繰り返し構築する。Serverの遅さは旧schemaテストだけではない。
- SQLite設定はWAL・foreign keys・busy timeout 5秒(`store.rs:13515–13529`)。5秒timeoutは上限であって、毎回5秒待っている証拠ではない。
- `store.rs` に固定sleepや `serial_test` はなく、store mutexもインスタンス単位。
改善候補は、fixture構築のtransaction化、通常APIテスト用の構築済みDBテンプレートから独立DBを作る方法、fixtureの不要な重複構築の削減。移行そのものの正しさ・durabilityを試すテストと、APIの前準備を分ける。実装・改善後の実測はまだ行っていない。
## 2. Session Store:1テスト90秒、本番readerの二次量処理
対象: `public_snapshot::tests::large_legacy_inline_images_project_as_bounded_refs_and_fetch_from_retained_storage`
- 実測 **90.07秒**。crate全体91.40秒のほぼすべて。
- `crates/session-store/src/public_snapshot.rs:4395–4404` で4画像・計18,373,509 bytesを用意。base64部分だけで24,498,012 bytesの単一JSONL行になる。
- `crates/session-store/src/worker_session_store.rs:60,92–94,149–162` の逆方向readerは64 KiB読むたびに、蓄積済みbuffer全体を改行検索し、全bufferを新chunkへコピーする。
- 巨大な一行では、検索・コピーが概ね `O(N²/chunk_size)` になる。この計算量はソース上確認済み。
- テストはこの巨大行を逆方向に5回取得する。静的概算で検索約23 GB・コピー約23 GB相当の累積メモリ処理となる。これはディスク読取量ではない。
- さらにJSON/base64 decode・hash・cloneが重なる。90秒の内訳をCPU profileで割合分解したわけではない。
改善候補は、改行検索を新規chunkだけに限定し、蓄積bufferの毎回prependコピーを避ける局所的な線形化。画像fixtureを縮小してテストだけ軽くするより、本番の巨大inline画像取得も同時に直す方がよい。入力と回帰条件は維持する。
## 3. Runtime:31秒の固定待ち
`worker_source::tests::runtime_owned_workspace_client_has_no_fixed_request_timeout` は **31.02秒**。
`crates/worker-runtime/src/worker_source.rs:1818–1836` はreqwest既定30秒timeoutの解除を確認するため、明示的に31秒遅延を指定する。helperの`:1889` に `std::thread::sleep(delay)` がある。ネットワークや大入力ではなく、意図された固定待ち。
単にsleepを短くすると `.timeout(None)` を削除してもテストが通るため、回帰検知が弱まる。短い初期deadlineを持つbuilderに本番と共通のtimeout設定を適用し、その解除を小さい実時間で検証するなど、テスト境界の見直しが必要。現段階では提案のみ。
## 4. テスト内部のビルド
- `agen/tests/compile_fail.rs`: trybuildの2ケースで27.35秒。
- `api-macros/tests/compile_fail.rs`: UI compile-fail群で19.32秒。
- `api-macros/tests/renamed_dependency.rs`: 一時プロジェクトのoffline Cargo checkで4.96秒。
- `yoi-plugin-pdk/tests/template.rs`: wasmテンプレート2ケースが各18.36 / 18.13秒、並列のためスイート全体は約18.39秒。
これらは外側のビルドとは別にテスト実行中にRustコンパイラを起動する。外側がwarmでもゼロにはならない。キャッシュを安全に再利用できるかは、依存rename・compile-fail・テンプレート自立性の検証目的を維持した上で別途検討する必要がある。
## 範囲外・既知の失敗・再実行
- `yoi` CLIテストは `crates/yoi/src/ticket_cli.rs:1382` の `edit_post_with_snapshots` 未実装、同`:1306` の `TicketMeta.created_by` 欠落でコンパイル不可。今回修正していない。
- opt-inのprocess E2E(`yoi-e2e --features e2e`)、Playwright/browser suite、ignored real-APIテスト・性能benchmarkは実行していない。
- Nixの `checks.default` はパッケージビルドで、`doCheck = false`。通常Rust全テストがそこで走るわけではない。
- このcheckoutには実行中と確認できるCI workflow定義がなく、今回の数字をCIの所要時間とは扱わない。
- テストによる `ConfigTreeSnapshot.ts` の自動生成フォーマット変更は、実行前の内容へ戻した。
測定用スクリプト・生ログはGit管理外の `target/test-timings/` に保持:
- `profile.ts`: build/run/single/summary
- `artifacts.json`, `results.json`, `summary.json`: 対象と全Rustテスト時間
- `build.meta.json`, `build-errors.json`: 外側のビルド
- `single-*.stdout`, `server-threads4.*`: 単独比較と並列数比較
- `remaining.ts`, `remaining-results.json`, `web-components.json`: Web/doc/warm build
例:
```sh
deno run -A target/test-timings/profile.ts build
deno run -A target/test-timings/profile.ts run
# ツール側の実行時間上限で中断した場合(完了結果は各バイナリごとに保存)
deno run -A target/test-timings/profile.ts run --resume
deno run -A target/test-timings/profile.ts summary
deno run -A target/test-timings/profile.ts single yoi-workspace-server \
store::tests::schema_v50_plans_and_applies_the_complete_retained_chain 1 single-v50
```
## T-761:最適化後の測定
`7042ec7d`上の作業差分で、変更した3 crate・通常8バイナリを再測定した。**合計500.52秒から317.72秒へ、182.80秒(36.5%)短縮**。1,796 passed / 2 ignored / 0 failed。ignoredは既存のままで、新しいskipや並列数制限は追加していない。
### 変更と検証範囲
| 変更 | 小さい検証 | 残した重要な接続 |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Session逆方向readerの線形化 | `retained_reader_*` 4件でchunk前後・正確な境界、budget不足からの再開、内容・offset・追加読取り量、不正行を検証 | `large_legacy_inline_images_project_as_bounded_refs_and_fetch_from_retained_storage` の約24.5MB行と実storage再読取りは不変。legacy IDの既存検証も維持 |
| Runtimeの31秒待ち除去 | `blocking_workspace_client_clears_initial_request_timeout` は初期20ms deadlineを渡し、本番の要求準備・timeout適用・HTTP送信・応答読取りを通す。要求受信後40ms経過を障害刺激にし、実応答で完了を判断 | `RuntimeOwnedWorkspaceClient` のdefault timeout設定、実HTTP成功、明示timeout指定とエラー報告を既存loopback fixtureで確認 |
| 通常APIの空schema構築共有 | `api_fixture_databases_isolate_writes_and_reopen_persisted_rows` は同一PKへの並行書込みを独立DBで行い、再openの保存値、pristine DBへの非混入、WAL/FKとFK拒否を確認 | 本番schema初期化の結果だけをSQLite Backupで各ケースの実DBへ複製。認証router・API seed・store・executorは各ケースのまま。既存ファイルは通常openし、保存内容を初期化しない |
| 旧schema fixture構築のtransaction化 | `prepare_schema_v52` / `prepare_schema_v50` の準備用DDL・seedをまとめる | 本番migrationとFK設定切替はtransaction外。全移行連鎖、途中再開、rollback、保存値・制約の既存試験を非template経路で維持 |
局所入力規則には既にDB不要のテストがあり、入力表の削除や大量のテスト再配置は行っていない。通常API用の3 constructorだけをtemplateへ変更し、移行・fresh作成試験が共用する `open_for_test` 自体は変更していない。
### 時間比較
初回と同じWorkspace test buildのfeature構成、debug profile、libtest既定並列、バイナリ間逐次、JSON report-timeで測定。外側のビルドは除外し、変更crateの全通常バイナリを選択した。最終sourceの測定は1回であり、専用・無負荷ホストの中央値ではない。
| crate | 初回 | 最終差分 | 短縮率 |
| ---------------------- | -------: | -------: | -----: |
| `session-store` | 91.40秒 | 9.77秒 | 89.3% |
| `worker-runtime` | 32.44秒 | 20.25秒 | 37.6% |
| `yoi-workspace-server` | 376.68秒 | 287.70秒 | 23.6% |
| 合計 | 500.52秒 | 317.72秒 | 36.5% |
巨大画像テストは90.07秒から8.01秒へ短縮。Runtimeの新timeoutテストは0.078秒だが、crate全体では他の復旧・Worker構築試験が支配的になり、31秒分がそのまま短縮されるわけではない。
先行測定でもSession 9.83秒、Server 291.02秒だった。Runtimeは先行測定19.05秒だが、後述のレビュー修正前なので最終sourceとの統計平均には使わない。
**通常Rust全95バイナリは再実行していない。** 未変更87バイナリの以前の143.62秒を足すと約461.35秒(7分41秒)、以前の644.15秒より約28.4%短い見積りになるが、これは全体の再実測値ではない。Web、Workspace全doctest、opt-in E2E/browserも再測定していない。
### 検証とレビュー
- 親でreader局所テスト、巨大画像、Runtime timeout/実HTTP、DB隔離、v50完全連鎖・途中再開を先に実行して成功。その後、変更3 crateの全通常8バイナリを既定並列で測定し成功。
- root `cargo check`、3 crateのdoctest選択(対象0件)、`cargo doc -p yoi-workspace-server --no-deps`、全体fmt/diff、状態契約命名検査が成功。既存のServer dead-code警告3件は残る。
- 初回と同じ全Workspace test buildで測定用バイナリを生成した。既知のTicket CLIテスト2エラーは継続し、build全体はexit 101。変更対象8バイナリは生成・実行できており、このbuild失敗を全テスト成功へ読み替えていない。
- readerとServer/Runtimeを独立にレビュー。Runtime初版はtimeout helperだけを通っており、本番呼出し漏れを検知できないというP2指摘を修正した。最終版は本番 `execute_blocking_inner` を通る。
- 本番のtimeout適用を一時的に `Some` の場合だけへ変更する故障注入で、新テストが0.04秒で実timeoutを検出して失敗。復元後0.07秒で成功。再レビューでP2解消、追加P1/P2なしを確認。
- 通常テストのfeature/target選択は変更なし。checkoutに通常suiteを実行するCI workflowは確認できず、Nixの`doCheck = false`も不変。ローカル成功をCI成功とは扱わない。
残る大きなコストはServerの実移行・復旧試験であり、並列実行中には完全連鎖等の個別時間が依然として長い。今回の短縮はクリティカルな接続を削除せずに得たもので、全suiteのボトルネックを解消したという主張ではない。
追加の生ログ・測定用scriptはGit管理外の `target/test-timings/` に保持する。
- `optimized.ts` / `optimized-artifacts.json`:初回と同じbuild方式と変更8バイナリの選択。
- `optimized-results-1.json` / `optimized-results-2.json`:先行測定/最終差分の測定。各バイナリのstdout/stderr/metaも保存。
- `timeout-mutation.stdout` / `.stderr`:None適用漏れの故障注入結果。
- `optimized-root-check.*` / `optimized-doc.*` / `optimized-doc-build.*`:compile・doctest・rustdoc結果。
再測定は `deno run -A target/test-timings/optimized.ts build`、続いて `deno run -A target/test-timings/optimized.ts run <識別子>`。通常の回帰検証には `cargo test -p session-store -p worker-runtime -p yoi-workspace-server` を選択できる。
## T-761追加要求:全通常suiteを1分以下へ
前節は最初の部分最適化であり、追加要求に対する全体再実行の結果ではない。以下ではCLIの既存test compile errorも修正し、通常Rust全96バイナリ、Workspace doctest、Web unit/component、Web UX tooling、root検証toolのテストを対象にする。外側buildは分離し、test内部の実Cargo起動やWeb変換、Rustケース列挙は実行時間に含める。以前から明示選択のE2E/browserとignoredは別枠のまま。
### 粒度・準備コストの変更
- Serverのconfig候補検証・cleanup分類・Ticket checkerの応答検証/描画など、局所規則を実DBなしのunitへ移した。実store入口の拒否と保存値不変、認証付き保存→Job結果→advisory配送は代表結合として残す。fakeモデル応答による分類試験を、モデル自体の判断精度の証明とは扱わない。
- 通常fixtureの空schemaを独立した実DBへ複製し、準備済みDBへの追加connectionだけ重複schema検証を省く。既存DB・再open・本番startupは検証を通し、trigger欠落の拒否試験を残す。旧schema templateはseed前の構造だけ共有し、対象区間のmigration試験と最古→最新の完全連鎖を分離する。実transaction・FK・WAL・rollback・保存値のassertionは維持。
- Driveページ上限試験の201件は、読取り前の準備だけ実ownerのmutationで作成する。認証付きTools/WIP読取り、ページ件数・cursor・全ID一致は変更しない。
- Journal復旧の3つのloopを6+2+4個の独立ケースへ分割。各ケース内の障害注入→復旧→再読取りは逐次のまま、DB/Runtimeは毎回独立。旧assertionと実reopenの全組合せは前後diffで独立レビュー済み。
- Runtimeの保存Manifest入力行列をunitへ分離し、実保存/再読取りとfactory入口の拒否を残した。論理timeoutには仮想時間、取消完了には開始/Drop通知を使い、固定sleepを除去。
- ViewImageの16 MiB caller-limit規則は局所readerへ移し、LocalWorkdirとの実接続はchunk境界を跨ぐファイルで検証する。Session Storeの巨大legacy行試験は入力サイズを維持。
- macroのrenamed consumerとWASM templateは、毎回独立sourceから実Cargo checkを行い、依存artifactのみ再利用する。成功判定はキャッシュしない。warm cacheに`compile_error!`を注入したtemplateが失敗し、復元後成功することを確認(`template-cache-mutation.*` / `template-cache-restored.*`)。
- test profileのSQLite Cコードをopt-level 2、Workspace Serverをopt-level 1とした。Rustのtest/debug assertionsとoverflow checksは無効化しない。通常のdev/release profileは変更しない。
### 全体runner
root `deno task test`(Linux)を追加。Cargoが選択したtest artifactを毎回列挙し、大きいバイナリを全ケース一意の複数processへ分配する。既存ignoredを含む全選択名は`inventory.json`に保存し、結果と対応付ける。未知listing・重複名・列挙失敗も全体失敗とし、成功結果によるskipは行わない。
並列上限はtop-level suite/shard数であり、内部Cargo/Vitest等まで含む総プロセス数ではない。実行上限180秒・外側build上限1,800秒は、性能目標60秒とは別のハング検出用。途中ログを保存し、timeout・SIGINT/SIGTERM時は同一process groupへTERM→KILLして結果を保存する。別sessionへ自ら離脱した子孫の回収は保証しない。runnerの独立レビューで初版の無期限待機を指摘され、修正後の再レビューではP1/P2なし。
### 途中の全体測定
- 初回runner:全101 suites成功、実行238.35秒、外側build75.20秒。1分未達。
- 32 top-level並列・Server32 shards版:96 binaries / 5,225選択名、全210 suites中205成功・5失敗、実行71.49秒、warm build0.40秒。失敗4件は待機上限超過、1件はWorkerの完了前履歴参照。この結果は成功扱いしない。`target/normal-tests/2026-10-16T05-39-04.512Z/`、`target/test-timings/final-normal-1.log`に保存。
- 同runの外側`time -p`はreal71.98/user702.72/sys352.49秒。平均約14.7 CPU相当であり、利用可能24論理CPUを有効計算で使い切った性能限界ではない。共有資源競合・I/O・後半の重いsuite待ちを含む。個々のCPU使用率やI/O寄与率の厳密な内訳をこの値だけから断定しない。
### 最終差分の検証結果(1分目標は未達)
同期修正後の最終runは **実行71.06秒・全210 suites成功・0失敗**。外側の変更分buildは48.56秒、コマンド全体は119.70秒。実行にはdiscovery 0.28秒を含む。キャッシュのある同一Linuxホストで1回の成功実測であり、cold build込み1分、CI性能、反復安定性の達成は主張しない。
- Rust通常96 binaries / 205 suites・shards:**5,222 passed / 3既存ignored**。実行結果合計とinventoryの全5,225選択名が一致することを別途検算した。
- Workspace doctest、Web unit **665**、Web component **413**、Web UX **16**、root tool **22** が成功。E2E/browserは未実行。
- root `cargo check`、Rust fmt、Deno fmt/lint、diff検査、状態契約命名検査(未承認0・stale0)が成功。
- Controllerは初期Idleではなく同じSubmitの完了fenceまで待つ。Protocolは2秒の実session lock解放検証を追加し、実Stop全体のwatchdogだけ15秒へ分離。Attentionは不要Git準備を削除し、実Restore中のrelease待ちだけ15秒へ変更。いずれも独立レビューでP1/P2なし。
- Runtime cleanupのサイズ比較は、同じGit入力から独立checkoutを作るよう修正。毎回別commitを作るとobject-prefixディレクトリ数も変わり得るため、「サイズだけ変える」という比較条件を固定した。256 bytes/128 MiB・失敗注入・再起動retry・body非アクセス・walker件数のassertionを維持し、独立レビューでもP1/P2なし。
途中の48 top-level並列runは67.55秒だったが4件失敗したため採用していない。既定は32 top-level(24論理CPU時)、大きいRust binaryは約36ケース/process・最大32 shards・各2 test threads。`--jobs 1..64`で明示指定可能だが、増やせば速く安定するとは扱わない。最終成功前の32並列runも71.18秒・1件失敗であり、最終成功値とは分離する。
最終ログは `target/normal-tests/2026-10-16T05-54-44.954Z/` の `summary.json`、`inventory.json`、`count-audit.json`、各processのstdout/stderr。全体出力は `target/test-timings/final-normal-4.log`。比較試行は `final-normal-1.log`〜`final-normal-3.log` に保存。外側buildと内部Cargo依存artifactは温まった状態で、成功結果の再利用による省略はない。
**要求の60秒までは約11秒残っているため、T-761は未完了。** Serverの実Worker起動・永続化・復旧を含む重いケースと、後半に開始するshardが残る。全コアを有効に使い切った性能限界を測定したわけではなく、さらなる短縮には残るfixture反復と実行順・競合の分析が必要。ここまでの変更は未commit・未pushで、稼働反映なし。