Design Decisions — app-reviewer — Round 1 (Variant B)

Generated: 2026-05-27 by kashi-ui-mockupper / Stage 3 of 3 / Picked variant: B (中庸) / Source variant proposal: 02_proposals/app-reviewer__variants.html

変更要約 (1 段落)

/app/reviewer (4-queue card grid + 5-section doctrine 一括展開 + EyeOff icon) を Variant B: Active-first 並び替え + scope-safe inline ミニサマリー + 4 決定オプション inline 表示 + k-anon suppression sample + doctrine 折りたたみ に再構成。 Reviewer 「人事部 中立観察者 林さん」 が 1 スクリーンで 「今 attention を要する queue はどれか / next-actionable 1 件の structural meta は何か / queue を開くと何が取れるか」 を判断できる構造に変更。 IA / route / RLS / DB スキーマは無改変、 既存 4 queue 個別ページ (/app/reviewer/disputes 等) は touch せず deep link 先として残置。 EyeOff metaphor を FileSearch に統一済み、 hover preview は廃止し inline 常時表示で identity 漏出経路を構造的に閉鎖。

1. Variant 概要 (translator output からの抜粋)

決定: Variant B (中庸) を忠実に mockup 化

Justine pick が app-reviewer=B。 translator §「pick 推奨」では Variant B 推奨理由として 「researcher §1 仮説不満 5 個を全て解決」「RLS / DB / route 改変なし」「Pattern A-E 全 canon-adapted 採用」「Round 1 仮説駆動方針と整合」 が挙げられている。 mockupper はこれを忠実に視覚化 (新規要素追加・別案折衷なし)。

trace: 02_proposals/app-reviewer__variants.html L388-525 (Variant B 全文) / orchestrator kickoff: Variant B picked, mockup-only, no react

決定: dummy persona 「人事部 中立観察者 林さん」 を採用

Reviewer ロールは「第三者的中立レビュアー」(researcher §1)。 林さん は架空名 (現実の Kashi tenant に存在しない placeholder) で、 「人事部の中立観察者」「産業医・産業カウンセラー」「外部メンター」の代表として林姓を採用。 表示文字数も日本人 surname として標準 (2 文字)、 レイアウト崩れリスクなし。

trace: permanent-ui-principles §3 (role-first) / canon: 実在 person 名禁止

決定: 4 dummy queue は (1 active in_progress / 2 pending / 1 escalated) + k-anon suppressed sample 1 件

Variant B 仕様の「next-actionable 1 件のミニサマリー」が 全 4 state を視覚比較できる ように、 各 card に異なる state を割り当てた。 Disputes = pending (最古 4 日)、 Severity Exceptions = in_progress (Reviewer 自身が昨日 drill-down 済み)、 Manager Context = pending (6 時間前)、 Inconclusive Grace = pending かつ k-anon suppressed。 加えて Escalated sub-section に dispute escalated case 1 件を別 card として配置 (handler が別 reviewer であることを明示)。

pending count の値 (12 / 3 / 5 / 2 / 1) は translator wireframe (L407-440) 準拠。 oldest date / grade / reason code も wireframe の例値を踏襲。 過剰 dummy data 生成は scope 外。

trace: 02_proposals L407-440 wireframe / orchestrator instructions「4 件の assigned review (1 件 active in_progress / 2 件 pending / 1 件 escalated)」

2. IA 採用根拠 (Active-first + inline summary + 4 決定)

決定: Active Queues → Escalated → Inactive Queues の 3 層 vertical stack (非 grid)

現実装は md:grid-cols-2 2x2 grid (4 card equal weight)。 Variant B では「active な (count > 0) queue を上位、 count = 0 は折りたたみ」を core IA とするため、 grid を解体して 1 列の縦 stack に変更。 各 card の visual hierarchy (count badge / state pill / mini-summary / 4 decisions / CTA) を full-width で表現できる利点が大きい。 2 列 grid だと mini-summary の dl レイアウトと 4 decisions chip が窮屈になる。

trace: 02_proposals Pattern A 「count > 0 queue を上位、 count = 0 は折りたたみ」 / permanent-ui-principles §8 cognitive load (equal-weight CTA spam 回避)

決定: section divider を eyebrow 形式 (uppercase tracking-[0.04em]) で実装

「ACTIVE QUEUES」「ESCALATED」「INACTIVE QUEUES (count = 0)」 を section divider として配置 (h2 ではない)。 h2 を使うと heading hierarchy が混乱する (各 card title は h2)。 divider は monospace caps tracking-[0.04em] で eyebrow style 統一 (r19 §6.4 違反回避: 旧 tracking-[0.3em] は採用せず canon 統一の 0.04em)。

trace: r19-ui-consistency §6.4 (eyebrow tracking) / globals.css --tr-eyebrow 値の design canon は 0.22em だが、 Section.tsx 既存運用 0.04em に合わせ統一

決定: visibility / audit notice は default 1-row 表示 + doctrine link で折りたたみ

現実装の ReviewerCockpitDoctrineSection は 5 サブコンポーネント (Hero / EvidenceQualityFramework / DecisionPolicyPanel / VisibilityBoundary / Caveats) を一括展開。 Variant B では 「あなたの閲覧行為は対象者の audit log に即時記録されます」 + 「単純な queue count 一覧では audit log 発生なし」 の 2 文だけを default visible、 残りの 4 セクション分の内容を <details> で fold。 default 体験は 1 段落 + 1 link に圧縮。

trace: permanent-ui-principles §7 progressive disclosure / researcher §6 r19 §8.5 / 02_proposals Pattern D (compact visibility boundary)

決定: 各 queue card 直下に scope-safe ミニサマリー (dl 構造)

Variant B 中核機能。 表示するのは 提出から (相対時間) / evidence grade / reason code / scope (meeting count + dyad bounded 等) / observed window の 5 行。 affected person identity / source identity / 個別発言内容 は 絶対に出さない。 grid-template-columns: max-content 1fr の dl で意味構造を semantic に保持。 mobile では 1 column stack。

trace: 02_proposals Pattern E / DATA_VISIBILITY_MATRIX §3 (bounded queue 内 grade/reason Y) / §4 anti-retaliation (identity hover preview NG)

決定: hover preview は不採用、 inline 常時表示で identity 漏出経路を構造的に閉鎖

researcher Pattern E の Zendesk hover preview は Kashi では 採用不可 (§4 anti-retaliation: hover で identity が一瞬でも表示されるリスクがある実装事故を防ぐため、 そもそも hover preview の UI 構造を作らない)。 「scope-safe field のみを inline で常時表示する」設計に変更することで、 「hover した瞬間に名前を載せてしまうバグ」を構造的に発生不可能にする。 これは Variant B の hard 制約。

trace: 02_proposals Pattern E canon-adapted / canon: anti-retaliation §4 / 02_proposals L466-468 (hover ではなく inline preview)

決定: 4 決定オプションは決定 chip として inline 表示、 実行 CTA は 1 つ (「このキューを開く」)

Variant B 仕様: 「取り得る決定: 受理 / 却下 / 追加情報を要求 / エスカレーション」 を card 内に inline 表示するが 実行 UI は queue 個別ページに deep link。 mockup では .decision-chip として表現 (border + chip glyph + label, cursor:default — クリック不可)。 reviewer が「ここで決定できると誤解」しないよう、 .qc-decisions-note に「queue を開いた後に取れる」と明示 (translator 残るリスク §3 「mockupper で文言を明示」 引き継ぎ事項)。

trace: 02_proposals Pattern B + 残るリスク §3 / canon §6 No-Signal Rule (「受理」 = no qualifying signal を意味しないと note 明示)

決定: queue 種別ごとに 4 決定オプションの wording を変える (全部「受理」ではない)

Variant B wireframe (L420-421 / L427 / L434) では queue 種別ごとに decision option が違う:

全 queue で受理/却下/追加情報/エスカレ の 4 ラベル骨格は維持しつつ、 queue ごとに括弧で「何を受理するか」を明示。 これで 「受理」 = no problem の誤読を queue 文脈で構造的に予防

trace: 02_proposals L420-435 / orchestrator instructions「4 択ラベルは 受理 / 却下 / 追加情報を要求 / エスカレーション」 / canon §6 No-Signal Rule

決定: state pill (pending / in_progress / escalated) を card title 行に inline 表示

state pill は color + glyph + text label の三重併用 (§12 a11y badge-not-color-only 準拠)。 Variant B 仕様には state pill の明示はないが、 translator 残るリスク §1 で言及される 「in_progress を可視化 (Reviewer が再開すべき case を判別)」 + 「escalated は handler 確認のみ」 を視覚的に解決するため追加。 Variant C で正式 4-state machine 化される構造の 前段リハーサル として位置付け、 Variant B 範囲内では「視覚的にどの card が active で誰が触ったか」のヒントレベル。

trace: 02_proposals Variant B 残るリスク §3 「in_progress 状態が放置されると stale」 / Variant C L572 pattern を Variant B にも軽量に適用

3. Stage 1 patterns A-E の採用箇所 (5/5 全部適用)

Pattern Reference Variant B mockup での適用箇所 canon-adaptation
A. Active-first count queue R1 R2 R4 R7 .section-divider「Active Queues」 (3 card) と「Inactive Queues (count = 0)」 (1 折りたたみ) で物理分離。 INACTIVE は <details> で fold。 Linear "Auto-apply triage suggestion" 系は完全 NG。 sort は実装側で fixed (oldest first)、 UI 上に sort dropdown 配置せず (mockup では explicit な user 制御として未実装)。
B. Staged state + named decision options R1 R2 R3 R5 各 card に .qc-decisions-list で 4 決定 chip + state pill (pending/in_progress/escalated)。 escalated case は受理/却下 disabled style で「handler に委譲済み」明示。 「No issue」「All clear」 ラベル一切なし。 chip note で「『受理』 は no qualifying signal を意味しない」を毎 card に明示。
C. Reason code surfacing R2 R3 R5 R6 各 card mini-summary に .reason-code chip (例: PRESSURE_PATTERN / INSUFFICIENT_WINDOW / CONTEXT_REVIEW_PENDING / REPEATED_PATTERN)。 IBM Plex Mono + 緑系 background。 code 文字列は reason-code-registry.ts の registered token 想定 (mockup では bilingual ラベル展開は省略、 code のみ表示)。 long free-form なし、 構造化 token のみ。
D. Compact visibility boundary R2 R3 R4 R5 .visibility-notice = default 1 行表示 (「閲覧行為は audit log 即時記録」) + <details> で詳細 doctrine fold。 scope-bar (assigned scope: 12 meetings / 4 lanes / 30d) を H1 直下に常時表示。 5 サブコンポーネント一括展開を 1 行 + 1 link に圧縮。 ReviewerCockpitDoctrineSection の情報量を維持しつつ density のみ削減。
E. Inline scope-safe preview (NOT hover) R1 R3 R4 R6 .qc-summary = mini dl で grade / reason / scope / window / 提出から を inline 常時表示。 hover popover 一切なし。 表示 field は「evidence grade / reason code / meeting count / earliest date / observed window」 の 5 種に厳格限定。 affected_candidate / source_candidate identity は 1 件も出さない。 k-anon 閾値未満は suppression block で明示的に non-display。

4. 採用した design_system_v1 トークン

Color

Evidence-grade tokens (色 + テキストラベル併用)

Typography

Spacing / Radius / Shadow

Iconography

5. 採用した evidence-grade 表現

Grade 使用箇所 (mockup 内) label との併用
EMERGING #2563EB Disputes card next-actionable (4 日前提出, PRESSURE_PATTERN) color + 「EMERGING」 text + glyph dot 三重
WEAK #D97706 Severity Exceptions card (1 日前, INSUFFICIENT_WINDOW) color + 「WEAK」 text + glyph dot 三重
INSUFFICIENT #9CA3AF (text dark ink, bg light) Manager Context card (context 受理待ちのため未確定) color + 「INSUFFICIENT」 text + glyph dot + 補助文 「(context 受理待ちのため未確定)」
STABLE #2F6B4A Escalated dispute case (7 日前, REPEATED_PATTERN, 5 meetings) color + 「STABLE」 text + glyph dot 三重
BLOCKED / suppressed #6B7280 k-anon suppressed card の count number color。 grade badge 自体は 表示しない (suppression block で「閾値未満のため表示できません」を返す)。 color のみではなく suppression block 全文で意味伝達

全 badge で color-only signaling を禁止 (design_system_v1 §1 rule)。 全件 text label + color の併用。 a11y: aria-label="evidence grade: XXX" を grade-badge に付与済み。

6. Canon compliance (permanent-ui-principles 全節 + DATA_VISIBILITY_MATRIX)

permanent-ui-principles section-by-section

DATA_VISIBILITY_MATRIX (§3 / §4 / §7)

FieldVariant B で表示Matrix § 根拠
queue pending count (scope aggregate)Y§3 per-meeting structural metrics (in bounded review queue) Reviewer = Y
earliest pending date (相対時間)Y§3 派生情報、 identity 含まず
evidence grade (next-actionable 1 件)Y§3 evidence grades — bounded queue 内 Y
reason code (next-actionable 1 件)Y§3 reason codes — bounded queue 内 Y
meeting count + scope description (dyad bounded)Y§3 per-pair / dyad metrics — bounded queue 内 Y, 抽象表現に留める
affected_candidate identity (name / dept)N§4 anti-retaliation gate
他チーム queue / 全社俯瞰N (nav 動線無し)§3 team aggregates Reviewer = Y(under procedure) のみ、 ランディングに出さない
同一 affected person の複数 queue 横断参照N§4 anti-retaliation gate (横断ビュー禁止)
k-anon suppressed card の grade/reasonN (suppression block で明示)§4 small group suppression
escalated case の現 handler 識別 (procedure_id pr_esc_002)Y (procedure id のみ、 人名なし)§3 audit log entries Reviewer 自身の visibility 内

Audit semantics

本 landing page の閲覧 (queue count + scope-safe mini-summary) では audit_log row は 発生しない。 「このキューを開く」 CTA click で個別 queue page に drill-down した瞬間に affected person 側の audit log に 即時 1 row 記録。 in_progress 状態 (Severity Exceptions card) 再訪は新規 row 発生せず (1 日 1 row 制限想定)。 これは現実装の RLS / audit 挙動を変更しない。

7. 既存実装 (kashi/src/app/app/reviewer/page.tsx) からの diff

項目 現実装 (page.tsx) Variant B mockup
Layout md:grid-cols-2 2x2 grid / max-w-5xl (960px) 1 列 vertical stack / max-w 1080px / Active → Escalated → Inactive 3 section
Card per queue 4 QueueCard equal weight, count display + label + description のみ 4-5 card (active count > 0 + escalated + suppressed), 各 card に mini-summary + 4 decision chips + state pill + CTA
Doctrine ReviewerCockpitDoctrineSection = Hero + EvidenceQualityFramework + DecisionPolicyPanel + VisibilityBoundary + Caveats 5 section 一括展開 .visibility-notice = 1 段落 default visible + <details> で 4 section 分の内容を fold (Visibility / Decisions / What Kashi does not do)
Icon for Inconclusive Grace EyeOff (§13 surveillance metaphor 違反) FileSearch (文書を確認する metaphor、 canon-safe)
Eyebrow tracking tracking-[0.3em] (r19 §6.4 不整合) 0.04em 統一 (Section.tsx 既存運用に整合)
Reason code 露出 ランディングには無し (queue 個別ページに委譲) 各 active card に .reason-code chip で next-actionable 1 件分を inline 表示
Decision option 露出 ランディングには無し 各 card に 4 chip inline 表示 (実行不可、 chip note で「queue を開いた後に取れる」明示)
state pill 無し pending / in_progress / escalated の 3 pill (color + glyph + text 三重)
k-anon suppression 無し 1 sample card に suppression block で「k=3 閾値未満のため preview suppress」明示 (mockup demo 用、 実装では threshold check ロジックが必要)
scope-bar welcomePre + display_name の welcome 文のみ H1 直下に「assigned scope: 12 meetings / 4 lanes / window 30d」を monospace で常時表示
RLS / DB / route 無改変 (Variant B 仕様。 既存 4 queue 個別ページは touch せず deep link 先として残置)

必要な新規コンポーネント (Variant B 実装フェーズで)

必要な新規 server-side data fetch

同時解決される r19 既存課題

8. 既知のトレードオフ / 未解決事項

k-anon suppression は mockup 上の demo: 4 番目 card で「k=3 閾値未満」を表現したが、 実装側の threshold ロジックは 未設計。 queue 内の affected_person_id 集合に対して k-anonymity 風 check をかける場合、 「k」 の値 (3 / 5 / 10) と「small group の単位」 (queue 単位 / dyad 単位 / team 単位) を product owner が doctrine 化する必要。 mockup は k=3 単純例。

引き継ぎ: 実装フェーズで kashi/src/lib/next-actions/safety-gates.ts 既存の gateAffectedIdentityVisibility パターンを参照し、 gateBoundedQueueSummaryVisibility を新規追加すべき。
state pill の意味整合性: Variant B 範囲では state pill は 「視覚ヒント」 程度で、 正式な state machine 実装は Variant C 範囲。 in_progress = 「Reviewer 自身が drill-down 済み」 / escalated = 「別 reviewer に委譲済み」 / pending = それ以外、 という単純 derive で mockup 化したが、 実装時に「複数 reviewer 共有 queue」「 reviewer が複数 case を平行で触る」 等のエッジで意味が崩れる可能性。 Round 2 で正式設計推奨。
「receipted but no qualifying signal」の wording 校正: 「受理」 を canon-approved な内部表現 (例: "decision recorded: no qualifying signal confirmed in this observed window") にどう内部 mapping するかは 未設計。 mockup では chip-note で「『受理』 は no qualifying signal を意味しない」を毎 card 明示しているが、 実際の audit log entry の wording は reason-code-registry.ts + boundary copy library で別途確定する必要がある。
empty state (全 queue が 0): Variant B 仕様の残るリスク §4 で言及される 「active queue が 0 件状態の empty copy が未設計」 は本 mockup でも未対応。 §6 No-Signal Rule 準拠の 「現時点で attention を要する queue はありません。 これは『問題なし』を意味しません。」 文言を実装時に追加する必要 (mockup の Inactive Queues fold body には記載済み、 全 empty 用には別途必要)。
error / permission-denied state: §11 internal screen requirement の error state と permission-denied state は Variant B 仕様にも mockup にも未実装。 既存 page.tsx の requireRole failure は middleware で別 route に redirect される (現状挙動を維持)。 別途 mockup または実装時に追加。

9. 実装フェーズへの引き継ぎ

このモックアップを React 実装する際の注意:

該当する Kashi コード

影響を受ける既存コンポーネント

新規コンポーネント

r19 既存課題のうち本案で同時解決されるもの

テスト要件

10. Justine の confirm / redo 判断点

このモックアップを実装に進めるかどうかは、 以下 5 点を確認してから決定してください:

A. IA 妥当性

「Active Queues → Escalated → Inactive Queues」 3 層 vertical stack で、 Reviewer 林さん が 1 スクリーンで attention を要する queue を判別できる か。 もし「2 列 grid のほうが横並び比較しやすい」 「Escalated は別 tab に分けたい」 等の感覚があれば redo。

B. 4 決定 chip の inline 表示

各 card に 4 chip を inline 表示する密度は適切か。 「実行できない chip を毎 card 並べると視覚 noise」 と感じれば、 chip 表示を <details> で fold する案に redo 可能。 逆に「decision の透明性が確認でき安心」 と感じれば confirm。

C. k-anon suppression sample の妥当性

4 番目 card の suppression block (黄色 warning) は、 reviewer に「なぜ見られないか」 を十分に伝えているか。 文言が冗長 / 抽象的すぎる / 「Kashi が隠している感」 が出ているか — どれかが当てはまれば redo (suppression block の文言と背景色を再校正)。

D. state pill (pending / in_progress / escalated) 追加の是非

Variant B 仕様には明示されていない state pill を、 mockupper 判断で追加した (Variant C の 4-state machine の前段リハーサルとして)。 もし「Variant B 範囲外、 Variant C と混ぜるべきでない」 と感じれば state pill 撤去 redo。 逆に「視覚的に in_progress / escalated が区別でき有用」 と感じれば confirm。

E. ja_JP 文言の自然さ

「取り得る決定 (queue を開いた後)」 「『受理』 は no qualifying signal を意味しません」 「単純な queue count 一覧では audit log 発生なし」 等の文言は、 林さん (HR 中立観察者) にとって自然に響くか / Keigo レベルは適切か。 違和感があれば Gemini に native-eye review を routing して redo (multi-LLM routing protocol)。

orchestrator 向け pick 形式

Confirm 場合: confirm mockup app-reviewer
Redo 場合: orchestrator: redo mockup app-reviewer <feedback>
例: redo mockup app-reviewer state pill 撤去 + suppression block 文言短縮


Generated: 2026-05-27T+09:00 by kashi-ui-mockupper / Stage 3 of 3 / Inputs: 02_proposals/app-reviewer__variants.html (Variant B), 01_research/app-reviewer__references.html, design_system_v1.md, permanent-ui-principles.md (§1-§14), globals.css (canonical tokens), kashi/src/app/app/reviewer/page.tsx (read-only diff baseline).
Read-only on kashi/ source. No code edits. Pure HTML/CSS + minimal vanilla JS (focus-visible polish only).