Design Decisions — mirror-me — Round 1

Surface: /app/mirror/[managerId]  |  Picked variant: B (中庸 — Primary-Task Focus + IA Reorganization)  |  Generated: 2026-05-27  |  Mockup: ./index.html
このドキュメントの目的: Variant B を index.html として実装する際に行った 非自明な判断 を全て記録します。 将来の Justine (および React 実装エンジニア) が「なぜこの構造?」 と聞いたとき、 ここを読めば全ての根拠 (canon § / research pattern / 既存実装差分) が辿れる状態を目指しました。 全 8 section 構成: 概要 → IA 採用根拠 → 採用パターン一覧 → canon compliance → 既存実装からの差分 → 採用 token → 採用 evidence-grade → 既知のトレードオフ → Justine 判断点。

1. Variant 概要 (どの提案を mockup 化したか)

Picked variant: B — 中庸 (Primary-Task Focus + IA Reorganization)。 Risk: Med   Impl: M (4-7日)

Variant A の token 統一を前提として吸収した上で、 mirror-me ページ内のセクション順序と階層を Manager の primary task = 「直近主催ミーティング reflection」 を最上位にする再構成。 Evidence Grade Banner を fold 上に昇格、 MetricCard を 6 → 3 に絞り (詳細は折り畳み)、 PositiveCount を GracePeriod 前に移動 (P5 採用 + boundary copy 必須化)。 URL / nav / role ゲートは変えない、 ページ内構成のみ変更。

Mockup は 5 階層 (Tier 1-5) を すべて 1 ページに可視化 しています。 実 production では Tier 5 (empty state) は Tier 1-4 を完全置換 (grade が BLOCKED / INSUFFICIENT 時のみ表示) ですが、 review のため mockup では参考表示として残しています。

2. Information Architecture 採用根拠

決定: 5-Tier (Interpretation → Numeric → Positive → Attention/Raw → Empty)

Manager の primary task = 「ログイン直後の 5 秒で『今期の自分の facilitation は信頼できる窓で観測されているか / 重大な変化があるか』 を判断」 と定義。 現状の縦長スクロール (H1 → PositiveCount → RevealNames → TimeWindow → MetricCard×6 → 2 charts → IgnoredTurn → Chilling → GracePeriod → Dispute) では fold 内 = 「Positive grid + ボタン」 だけが見え、 解釈用 grade banner は scrollY ≈ 700px 付近にしか出ない。

解決策: Tier 1 (interpretation = grade + window) を fold 上に昇格 → Tier 2 (絞った 3 numeric card) で「重要なことだけ」 を見せ → Tier 3 で観測されたポジティブを boundary 付きで提示 → Tier 4 で詳細を畳んで → Tier 5 で empty を別ルートに。

根拠: research pattern P1 (summary-first 4/6 ref) + P4 (3-layer disclosure 6/6 ref) + permanent-ui-principles §7 §8 + r19 mirror-me 指摘 §7.1

決定: H1 を「あなたの Manager Mirror」 に + back-link を /app/me に修正

現状 H1 は「Manager Mirror」 のみで「これは誰の?」 が一瞥できない。 Manager が自分の mirror を見ていることを 役割 context として H1 自体に埋め込む のが canon §3 (role boundary first) の素直な実装。 back-link を /app/me (自分のホーム) に向けることで、 「Manager は他 Manager の mirror へ遷移しない」 という DATA_VISIBILITY_MATRIX §3 を nav レイヤーでも自然化。

根拠: canon §3 q1 (who is viewing this?) + Justine 不満候補「back が CEO に行く」 (Round 1 brief)

決定: MetricCard を 6 → 3 (Interruption / Directionality / Sustained-drop-days) に厳選

現状 6 card 並列は「すべて等しく重要」 という視覚信号を発する (§8 violation)。 Variant B は Manager 自己振り返りで「最も読み取りやすい 3 指標」 を default visible に残す: Interruption (受信側の動向) / Directionality (Gini で分布全体) / Sustained-drop-days (時系列パターン)。 残り 3 件 (Concentration / Persistence / Speaking trend) は Accordion で開示。

この 3 件選定は Manager の facilitation 意識直結 + 解釈閾値が一意 という基準。 Round 2 で Manager hearing 結果次第で並べ替えあり (例: Speaking trend を表に出すのが Manager の自然関心、 という反応が出れば差し替え可)。

根拠: canon §7 (default visible: 3-5 cards) + canon §8 (everything equal = fail) + r19 §7.1

決定: PositiveCount を Tier 3 に「下げる」 (P5 positive-first ordering 採用 + boundary copy 必須)

現状 PositiveCount は H1 直後の高位置にあり、 「Kashi は問題ないと言っている」 のように 誤読されるリスクがある (= canon §6 no-signal rule violation)。 Variant B では Grade Banner (Tier 1) の に置き、 かつ section 直上に翻訳者が要求した verbatim boundary copy を必ず表示:

これは観測されたポジティブな構造パターンです。 別の問題の不在を意味しません。 観測ウィンドウ内の no qualifying signal は「問題なし」 ではなく、 観測できなかった (insufficient meetings / low quality / out of scope) 可能性を含みます。

根拠: research pattern P5 (positive-first 5/6 ref) + 翻訳者 hard 要件 + canon §6 + EMPTY_STATE_AND_NO_SIGNAL_COPY_LIBRARY.md

決定: Tier 4 (GracePeriod / chart / 個別イベント) は ACTIVE 表示 1 つだけ展開、 残りは Accordion

GracePeriod が ACTIVE 状態のときは「Manager が今いる状態」 として常時可視。 chart 2 種 (Speaking trend / Interruption Bars) と個別イベントテーブル (IgnoredTurn / Chilling) は 解釈が分かれる材料 なので default 折り畳み (§7 progressive disclosure)。 個別イベントは「集計件数のみ表示、 氏名は出さない」 を section 内 note で明示 (DATA_VISIBILITY_MATRIX §4 anti-retaliation)。

3. 採用した Stage 1 research patterns

Variant B は研究 5 pattern を 全採用 (P5 は boundary copy 必須化で安全化)。 Stage 1 で除外された 3 canon-conflict pattern (AI risk バナー / 名前付き感情スコア / リーダーボード) は 1 つも採用していません

Pattern採用方法 (mockup 内の場所)References
P1 Summary-first Tier 1 Grade Banner を fold 上に。 H1 直下に観測窓 + 対象件数 + 信頼度 + 1 段落解釈 を一気に表示。 Stripe / Vercel / 15Five / Orbix B2B (4/6 ref)
P2 Window locked context TimeWindowToggle を Tier 1 内に置き、 全 MetricCard footer に last 90d + n=12 / quality: high を毎回表示。 何の窓で見ているかが card 単位で迷子にならない。 GitHub / Vercel / 15Five / Stripe / Lattice (5/6 ref)
P3 Honest empty state Tier 5 で「理由 list (reason code 付き) + canonical safe copy + 2 つの次アクション」 を構造化。 「all caught up」 や「no issue」 は使わず、 reason code 表示によって なぜ 出せないかを露出。 Linear / 15Five / Vercel / Stripe (4/6 ref)
P4 3-layer disclosure Tier 1 (interpretation) → Tier 2 main 3 card → Tier 4 accordion (chart + 個別イベント)。 明示的 3 階層。 6/6 ref で観察
P5 Positive-first ordering (boundary 必須化) Tier 3 に PositiveCount ×5 を配置、 section 直上に verbatim boundary copy を強制表示。 単独 P5 は §6 violation だが boundary 併置で safe 化。 15Five / Lattice / HiManager / Notion / B2B coaching (5/6 ref)

4. Canon compliance check

§判定mockup 内の根拠
§1 core doctrine (no surveillance) PASS eye / camera / police アイコン 0 件 (確認: index.html grep 結果)。 red alert 0 件 (semantic 色は warning B45309 までで、 error B91C1C は未使用)。 「あなたは監視されている」 系コピー 0 件。 全 framing が「あなた自身の facilitation を自分が振り返る鏡」。
§2 forbidden wording PASS 「検知」「予測」「健康スコア」「生産性スコア」「at-risk」「all clear」「no issue」 一切無し。 Grade 用語のみで「STABLE = 観測の信頼度」 と必ず注釈。 P5 採用時の verbatim boundary copy が forbidden wording 化を防止。
§3 role boundary first PASS H1 「あなたの Manager Mirror」 で role context 明示。 page-subtitle で「視聴者: 田中部長 (自分) / 他の Manager の mirror は表示できません」 を fold 内に。 PortalHeader の role chip = Manager も常時表示。
§4 visibility per role PASS RevealNames ボタン unset (Manager 視点では出さない)。 IgnoredTurn / Chilling は集計件数のみ表示、 名前 0 件。 Tier 5 next action「カバレッジ確認」 は admin 向けではなく Manager 自身が呼べる経路 (これは React 実装時 route check 必要 — confirm 5 参照)。
§5 evidence semantics PASS Tier 1 で grade (STABLE) + reason-code (E2_CLEAR_OBSERVABLE_PATTERN) + window (90日) + quality (high) + 「これは判定ではない」 注釈を一括表示。 §5 必須 7 要素 (grade / reason / window / quality / scope / what-not-prove / safe-action) すべて 1 view 内。
§6 no-signal rule PASS Tier 5 で「No qualifying signal in this observed window」 canonical wording 採用。 「safe team / clean manager / no issue / all clear」 0 件 (確認済み)。 reason code 3 件 (n < 5 / quality low diarization / unsupported type) を明示。 boundary 注釈で「問題なしを意味しない」 を必ず併置。
§7 progressive disclosure PASS Default visible layer = 1 headline (H1) + 1 short explanation (subtitle) + Tier 1 banner + 3 cards (Tier 2) + 1 primary CTA (Dispute footer)。 Accordion 2 つ (詳細指標 / chart) + 1 つ (個別イベント) = 計 3 accordion で過剰でない。
§8 cognitive load PASS H1 1 個 / H2 0 個 (各 Tier の h3 = positive section 内のみ) / Tier label が monospace eyebrow で section 階層を視覚的に圧縮。 「Everything equally important」 を解消。
§9 dashboard rules PASS 各 MetricCard が 8 要素 (what / who / window / quality / grade / reason code / action / not-prove) を担保。 ランキング 0 件 / health score 0 件 / 個別 subordinate データ 0 件。
§11 internal screen 13 要素 PASS role label (PortalHeader chip) / visibility boundary (subtitle) / grade (Tier 1) / reason (各 card) / window (Tier 1 + 各 card) / quality (各 card footer) / safe actions (Dispute / Coverage) / forbidden actions (氏名表示禁止注釈) / audit (Dispute 経路で reviewer 連携) / empty (Tier 5) / error (未実装 — mockup で対象外) / permission (subtitle で「他の Manager は見られません」) / dispute (footer) — 11/13 mockup 内表示、 2 件 (audit log / permission denied) は対象外 surface のため。
§12 a11y baseline PASS H1 1 個。 heading 順序 (H1 → h3, H2 を使わず Tier label で段化)。 keyboard 操作可能 (button / a / details/summary)。 focus visible (outline 2px evergreen)。 全 grade pill / chip に aria-label。 Tablet 900px / phone 600px で grid 折り返し。 color + text label 併用 (grade pill 全部)。
§13 visual system PASS off-white base (#fafaf7) / evergreen + emerald accent / Lucide outline icon (SVG 簡略) / 大量 whitespace (space-4..space-12)。 eye / camera / police / red alert / AI glow / neon gradient 0 件。

5. 既存実装からの差分 (kashi/src/app/app/mirror/[managerId]/page.tsx)

本 mockup は static HTML/CSS のみで、 既存 React 実装には一切 write していません。 Round 1 翻訳者の B 提案 → mockup → 後続実装 phase で参照する差分は以下:

セクション現状 (line 番号は kashi/src/app/app/mirror/[managerId]/page.tsx)Variant B mockup での変更
H1 line 444: <h1 className="text-3xl font-semibold">{t("h1")}</h1> — text-3xl のみ、 「あなたの」 が無い場合あり (i18n 依存) 「あなたの Manager Mirror」 で role context を H1 に埋め込み。 subtitle で「視聴者 = 自分」 + 「他の Manager は見られない」 を明示。 back-link を /app/me に。
PositiveCount の位置 line 535-539: H1 直後の高位置。 boundary copy 無し Tier 3 に降格 (Grade Banner → 3 metric card の後)。 section 直上に verbatim boundary copy を 100% 表示 (削除不可)。
TimeWindowToggle の位置 line 622: PositiveCount の後、 RevealNamesButton の後、 MetricCard 群の前 Tier 1 (Grade Banner) の中に移動。 window-strip 内で 観測窓 + 対象件数 + 切替 toggle を 1 行に集約。
Evidence Grade Banner line 413: ManagerMirrorVisualSection 内で render される (中位置)。 viewport の fold より下に出ることが多い Tier 1 として H1 直下に昇格 (fold 上で必ず見える)。 grade pill (color + text) + 1 段落解釈 + verbatim「これは判定ではない」 を bundle。
MetricCard 数 line 764-827: 6 個並列 (Interruption / Concentration / Directionality / Gini / Persistence / Sustained-drop-days) 3 個に厳選 (Interruption / Directionality (Gini 含む) / Sustained-drop-days)。 残り 3 個 (Concentration / Persistence / Speaking trend) は Accordion で開示。
InterruptionBars / SpeakingTrendChart line 847, 866: 別 H2 section として常時表示 Accordion 1 つに統合 (default 折り畳み)。 chart は「詳細を見たい時だけ」 に降格。
IgnoredTurn / Chilling リスト line 894, 950: 別 H2 section として常時表示 Accordion 1 つに統合。 「集計件数のみ表示、 氏名は出さない」 注釈を section 内に追加 (anti-retaliation 強調)。
GracePeriod line 920: 別 H2 section として常時表示 (位置は IgnoredTurn の後) Tier 4 の冒頭、 default 可視 (ACTIVE 状態のときは Manager 文脈として常時可視。 INACTIVE のときは未表示)。
RevealNamesButton line 554: TimeWindowToggle と並ぶ Manager 視点では mockup 内非表示 (canon §4 — Manager は subordinate 名表示を持たない)。 Admin/CEO 視点で見るときのみ render する条件を React 実装に残す。
Empty state (INSUFFICIENT) page.tsx line 60-62 で GRADES_BLOCKING_RENDER 配列定義はあるが、 実 empty UI は限定的 (caveat 帯のみ) Tier 5 で完全分離: grade pill + 理由 list (reason code 3 件) + canonical safe copy + 「カバレッジ確認」 / 「upload」 2 ボタンの honest empty state を構造化。
Dispute line 989: footer に <DisputeButton> 位置は維持。 footer に説明文「(あなたに対する dispute は表示されません — anti-retaliation)」 を追記 (canon §4 強調)。
r19 token 統一 (Variant A 継承) color hex 直書き 18 件、 card padding 不揃い (16/18/24 mix)、 radius 不揃い、 chart 色に red 混入箇所 全 color が token 経由 (CSS variable)、 card padding 統一 (--space-5 = 24px)、 radius 統一 (--radius-md = 8px)、 chart は --color-emerald-600 + --ink-soft のみ。

実装フェーズへの引き継ぎ: 影響を受ける主要 component = ManagerMirrorVisualSection (Tier 1 化)、 MetricCard grid (6→3 厳選 + accordion 化)、 SpeakingTrendChart / InterruptionBars (accordion 内へ)、 PositiveCount (Tier 3 + boundary copy wrapper 追加)。 必要な新規 component = BoundaryNote (verbatim copy 強制表示 + tampering 防止)、 TierLabel (eyebrow ラベル)、 EmptyStateExplanation (reason code list + 次アクション 2 つ)。 RLS / API 変更 0 件 (UI 層のみで完結)。

6. 採用した design tokens (どこに使ったか)

Token用途
--color-kashi-evergreen #1F3D33PortalHeader background / primary button bg / focus outline / window toggle active
--color-kashi-evergreen-deep #244A3DPortalHeader border / role chip bg / primary button border + hover
--color-emerald-700 #047857secondary link color / breadcrumb hover / strong count emphasis
--color-emerald-600 #2F6B4A(= --grade-stable) Tier label num / chart actual line / GracePeriod accent
--color-emerald-50 + --color-emerald-100positive tile bg + border / grade pill bg
--cream #F5F0E6window toggle background / reason code chip bg / boundary copy bg
--ink #2A3A1Ebody text default
--ink-soft #5E6F50subtitle / metric sub / chart trend line
--ink-faint #8A9579eyebrow labels / monospace meta / footer note
--ink-on-dark #F5F0E6PortalHeader text / primary button text
--state-warning #B45309boundary copy left border / 「境界注釈」 chip / dispute button
--state-info #2563EBGracePeriod chip (ACTIVE)
typography --fs-h1 / --fs-h3 / --fs-body / --fs-body-sm / --fs-caption / --fs-eyebrowtype scale 6 段、 全 element で token 経由
spacing --space-2--space-128pt grid 厳守、 任意 px 一切無し
radius --radius-sm / --radius-md / --radius-lg4 / 8 / 12 px 3 値のみ使用
shadow --shadow-sm / --shadow-md / --shadow-focuscard resting / card hover / keyboard focus

7. 採用した evidence-grade 表現

GradeColor tokenText labelmockup 内出現箇所
STABLE (default 表示用例)--grade-stable #2F6B4A「STABLE」 文字必須Tier 1 grade pill, 各 MetricCard footer grade-dot
INSUFFICIENT (Tier 5 例)--grade-insufficient #9CA3AF「INSUFFICIENT」 文字必須Tier 5 empty-state__grade chip
WEAK / BLOCKED / EMERGING / HIGH_CONFIDENCE_STABLE各 token 定義済み同上本 mockup の dummy data では未出現、 token 定義のみ。 React 実装時に grade 値に応じて pill 色 + text を切替。

全 grade pill / chip は 色 + 文字 両方を保持 (色のみ signaling 0 件)。 design_system_v1 §1 a11y rule + canon §12 準拠。

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

トレードオフ 1: MetricCard 6 → 3 で「私の重要指標が消えた」 と Manager に感じさせるリスク

Accordion を開けば全 6 件見えるが、 default 折り畳みで「私が大事にしている指標 (例: Speaking trend) が下に降格された」 と認識される個別 Manager がいる可能性。 Round 2 で Manager hearing で「default で 3 個に絞られて困るものはあるか」 を確認推奨。 軽減策: accordion summary に CONCENTRATION · PERSISTENCE · SPEAKING TREND という monospace meta を出して 「ここに残り 3 件ある」 を視覚的に明示済み。

トレードオフ 2: STABLE が「良い結果」 と誤読されるリスク (canon §5 violation 寸前)

grade pill が緑色 + STABLE 文字で、 視覚的にどうしても「合格証」 のように見える。 軽減策: Tier 1 内の .grade-explanation .boundary で 「STABLE は『観測の信頼度』 を示すラベルであり、 ハラスメントの有無、 退職予測、 健康状態、 生産性、 いずれの判断材料にもなりません」 と明示。 Round 2 で「色が緑すぎて『良い』 に見える」 という Manager 反応が出たら、 grade pill の色を neutral (cream + dark text) にする案あり。

トレードオフ 3: PortalHeader の nav から「ロール往来」 を解決していない

Variant C の「Inbox model」 が解決するレイヤー (nav 5 個の認知負荷)。 Variant B は scope を「mirror-me ページ内」 に限定したため、 ロール間遷移の散らばりは未解決のまま。 Justine の Round 1 不満が「mirror ページの中で混乱する」 なら B で十分、 「ロール nav 自体が直感的でない」 なら Round 2 で C の議論に戻る。

トレードオフ 4: Tier 5 empty state を本 mockup では Tier 1-4 と並列に表示している

実 production では grade が BLOCKED / INSUFFICIENT のとき Tier 1-4 を完全置換 して Tier 5 のみ表示するのが正しい挙動。 mockup では review しやすいよう .empty-example wrapper で「↓ 参考」 ラベル付きで残置。 React 実装時には GRADES_BLOCKING_RENDER 既存ロジックに沿って分岐。

未解決 1: Adaptation watch のテキスト密度

GracePeriod panel に「Adaptation watch: 0 件」 を 1 行で書いたが、 実 data に「3 件観測」 が出た場合の表示形式 (リスト? カウンタ?) は未設計。 Round 2 で実 data を流したときに再検討。

未解決 2: PortalHeader の brand-mark を CSS で代替している

本 mockup は self-contained で kashi/ に依存しない方針のため、 /brand-mark-light.svg を CSS clip-path で簡略再現。 React 実装時には実 SVG をそのまま使用 (差分なし)。 これは mockup-only の制約。

9. Justine が confirm / redo すべき判断点

Justine への質問 5 点 (Round 2 brief 作成前に判断を)

以下の判断は Round 1 段階では mockupper が 妥当な default を選んだだけ です。 Justine が「これは違う」 と感じたら orchestrator に redo mirror-me <feedback> で再構築指示してください。

Q1. MetricCard の default 3 件選定 Interruption (受信側動向) / Directionality (Gini) / Sustained-drop-days の 3 件を default 可視にしました。 Manager hearing で「Speaking trend が自分の自然関心」 と出る可能性があり、 Round 2 で並べ替えるなら今のうちに方向性確認したい。 → 判断: この 3 件で OK / 別組合せ希望 / 6 件全部見せたい
Q2. 観測ウィンドウ default = 90 日 Variant B mockup は 90 日を active にしています (30 / 90 / 180 から)。 現状実装の DEFAULT_TIME_WINDOW_DAYS がどの値かは未確認 (kashi/components/dashboard/time-window-options で確認可)。 Round 1 提案として 90 日 default は妥当か、 30 日 default にすべきかを判断願います。 → 判断: 90 日 OK / 30 日に変更 / 180 日を default に
Q3. Grade pill の色 (STABLE = 緑) を維持するか 緑 (= 良い結果と誤読リスク) vs neutral (= cream + dark text、 「ただの観測信頼度ラベル」 に見える)。 canon §5 「Evidence grade is not a verdict」 の精神を最も強く守るなら neutral だが、 視覚的差別化が弱まる。 mockup は緑を採用 + boundary copy で打ち消す方針。 → 判断: 緑のまま (現案) / neutral に変更 / 緑だが彩度を落とす
Q4. 個別イベントテーブル (IgnoredTurn / Chilling) を Accordion 内に置いたが、 完全非表示にすべきか 現案: Accordion 内で「集計件数のみ表示、 氏名は出さない」 注釈付きで表示。 懸念: 「Manager が自分主催 meeting の Chilling 件数を見る」 こと自体が、 「Manager → 誰か特定して詰問」 に繋がるリスクがゼロではない (集計でも n が小さいと特定可能性)。 canon §4 anti-retaliation の精神では「数字も見せない方が安全」 という解釈もありえる。 → 判断: 件数表示 OK (現案) / 件数も非表示 / 件数表示だが k-anon ≥ 5 を強制
Q5. Tier 5 empty state の next action 「カバレッジ確認」 リンク先 現案: /app/admin/coverage 想定で「カバレッジを確認する」 ボタンを置きました。 が、 Manager 役は admin route にアクセス権が無い可能性 (RLS で deny される)。 Manager 自身がカバレッジを見る別 route が必要なら、 React 実装時にどこへ向けるかの判断が必要。 → 判断: Manager 専用 coverage route を新設 / 既存 admin route に統合 (権限拡張) / 「カバレッジ確認」 ボタンを外す