✓ [setup] B の書類登録 — 201
✓ [setup] B の取引先登録 — 201
✓ [tenant-read] GET /api/me — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/years — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/accounts — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/counterparties — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/transactions — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/entries — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/documents — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/documents/538bf8d6-b885-4c46-9c75-57cd96040749 — 404
✓ [tenant-read] GET /api/documents/538bf8d6-b885-4c46-9c75-57cd96040749/file — 404
✓ [tenant-read] GET /api/storage — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/billing — 404
✓ [tenant-read] GET /api/lifecycle — 403
✓ [tenant-read] GET /api/lifecycle/deletion — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/audit — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/system — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/investigation/shares — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/invoices — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/policies — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/consistency/summary — 404
✓ [tenant-read] GET /api/tax/profile — 422
✓ [tenant-read] GET /api/assets — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/books/journal?yearId=6b918237-43f1-406c-80b8-b8704907eda8 — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/statements/blue-return?yearId=6b918237-43f1-406c-80b8-b8704907eda8 — 404
✓ [tenant-read] GET /api/export/complete/plan — 200 (200: 本文に B の語なし)
✓ [tenant-read] GET /api/export/year-books/6b918237-43f1-406c-80b8-b8704907eda8 — 404
✓ [tenant-read] GET /api/years/6b918237-43f1-406c-80b8-b8704907eda8/events — 200 (200: 本文に B の語なし)
✓ [tenant-write] POST /api/years — 403 not_a_member
✓ [tenant-write] POST /api/counterparties — 403 not_a_member
✓ [tenant-write] PATCH /api/business — 403 not_a_member
✓ [tenant-write] PUT /api/storage — 403 not_a_member
✓ [tenant-write] POST /api/lifecycle/plan — 403 not_a_member
✓ [tenant-write] POST /api/investigation/shares — 403 not_a_member
✓ [tenant-write] POST /api/audit/verify — 403 not_a_member
✓ [tenant-write] POST /api/documents/538bf8d6-b885-4c46-9c75-57cd96040749/void — 403 not_a_member
✓ [tenant-write] PATCH /api/documents/538bf8d6-b885-4c46-9c75-57cd96040749/meta — 403 not_a_member
✓ [tenant-write] POST /api/lifecycle/deletion — 403 not_a_member
✓ [tenant-write] POST /api/years/6b918237-43f1-406c-80b8-b8704907eda8/close — 403 not_a_member
✓ [tenant-write] POST /api/documents (B の事業者へ) — 403 not_a_member
✓ [tenant-write] B の年度が増えていない — {"years":[{"id":"6b918237-43f1-406c-80b8-b8704907eda8","year":2026,"status":"open","start_date":"2026-01-01","end_date":
✓ [tenant-write] B に攻撃者の取引先が無い — 200
✓ [tenant-write] B の契約状態が active/trial のまま — {"status":{"state":"active","state_changed_at":"2026-09-06T00:13:31.342Z","readonly_since":null,"gra
✓ [tenant-write] B の屋号が書き換えられていない — {"userId":"2081f8be-8b4e-4438-8ad9-dbee79633e10","email":"audit-b-b17868b8-b196-
✓ [csrf] Origin: https://evil.example — 403 (期待 403)
✓ [csrf] Origin: null — 403 (期待 403)
✓ [csrf] Origin: http://127.0.0.1:8990 — 201 (期待 201)
✓ [upload] HTML を PDF と名乗る → 422 — 422 file_content_mismatch
✓ [upload] SVG は受け付ける（inline では返さない前提） — 201
✓ [upload] SVG の inline 要求 → octet-stream / attachment — application/octet-stream | attachment; filename*=UTF-8''evil.svg
✓ [upload] HTML の inline 要求 → octet-stream / attachment — application/octet-stream | attachment; filename*=UTF-8''page.html
✓ [upload] PDF の inline → application/pdf + CSP sandbox — application/pdf | sandbox; default-src 'none'
✓ [upload] 400文字のファイル名 → 422 — 422 validation_error
✓ [upload] パス風のファイル名は保存できても鍵に混ざらない — 201
✓ [upload] Content-Length 200MB の宣言 → 413 — 413 {"error":{"code":"file_too_large","message":"ファイルは25MBまでです","requestId":"f9b7a9c
✓ [ratelimit] login を同一IPで連打 → 21回目までに 429 — 21回目で 429
✓ [otp] 再設定コードを外し続ける → 施錠または同一応答 — {"i":7,"code":"reset_failed","status":401}
✓ [token] 署名を壊したトークン → 401 — 401
✓ [token] トークン無し → 401 — 401
✓ [token] X-Business-Id が UUID でない → 4xx（500 でない） — 400 invalid_parameter
✓ [session] パスワード変更後に旧トークンが 401 session_revoked — change=200 old=401 session_revoked
✓ [session] 新しいトークンは通る — 200
✓ [share] 共有を作れる（作成直後は fresh） — 201
✓ [share] 共有 URL を匿名で開ける（A社の帳簿） — 200
✓ [share] 共有から B の書類は取れない — 200 cd=null
✓ [share] 取消後は開けない — 200/200
✓ [share] でたらめなトークン → 開けません(200) — 200
✓ [verify] 存在しない文書ID → 記録なし(200) — 200
✓ [verify] 照合は形だけ返す — 200 {"matched":false}
✓ [idempotency] 同じ鍵の再送は replayed か同一応答 — 201/201 replayed=null

70 checks, 0 failed
CTX （検査用のトークンと識別子の行。公開版では取り除いています）
