kashi · review-comments-audit · 57–62 reflection

Review Comments 57–62 — 反映監査

結論:57〜62 の改良インストラクションは、すべて実質的に main に反映&デプロイ済み。 6 pack すべてに専用テストがあり(folder57/58/59/60 + homepage62)、1,710 件のテストが main (eb466f8) で green。未着手 (NOT_DONE) はゼロ、監視・主張安全性の後退もゼロ。残るのは磨き込み・意図的な後回し・テスト網羅の隙間のみ。

「HP(公開ホームページ)」に限れば: 公開ホームページ / の pack は 61 + 62 の2つだけで、両方とも完了・本番デプロイ済み(kashi.ai-labo.workers.dev、最新 = RC62 v3.1)。57〜60 は別サーフェス(アップロード/個人ビュー・ログイン後アプリUX・検出器+/demo・ポリシーConsole)で、これらも反映済み。

6/6
pack 反映(実質)
1,710
テスト green on main
0
未着手 (NOT_DONE)
0
主張安全性の後退
19
gap(磨き込み/後回し/テスト)

監査方法:各 pack の受け入れ基準を Drive から抽出 → 6 体の懐疑エージェントが main (eb466f8) のテスト断言・src・git log・ライブサイトと突き合わせ → 領域ごとに DONE/PARTIAL/SUPERSEDED を根拠付きで分類。生成 2026-06-13。

優先 gap リスト(カテゴリ別)

未着手はゼロ。下記は「磨き込み」「設計上の後回し」「テスト網羅の隙間」「要確認の衛生項目」。意思決定が要るものだけを次の remediation round に回せます。

非問題(確認のみ) (3)

[RC59] No genuine implementation gap found. All 27 prompts (P01-P27 + Seq-B redesign + Seq-C admin) have merged commits on main (HEAD eb466f8); I executed 31 folder59 test files = 480 tests, ALL PASS, including the 24-fixture oracle that drives the real route and the named invariants (D03/R01 Kenji->Mika finding; R02/M04 no false-fire).
[RC59] Minor doc-note (not blocking): manifest entries for D06/M07 carry 'general_discussion(low-conf)->canonical unknown' classifier outcomes (F55 split-brain), resolved in-manifest with RESOLVED-P08b notes; these were doctrine-evaluated, not papered over (P21 run report). No action needed.
[RC62] Minor/non-issue (documented for completeness): the live page's inlined Next.js RSC/i18n script payload (__next_f.push) contains 発話 because it serializes the FULL ja.json bundle (demoContinuation.savedTurnsLabel, governance.wnd11Body, demoAbstention.*, etc.) for client hydration. These are NOT homepage copy and NOT in visible text — after stripping <script> blocks, visible HTML has zero 発話 and zero Kashiが見るもの. The acceptance criterion (no 発話 in visible text) is met. Not a regression to fix.

意図的な後回し / 設計上の段階分け (9)

[RC58] PD-3 persistence gap (affects areas 09 exception review, 10 repair queue, 11 batch speaker mapping): the universal importer ingests through the real /api/meetings/upload pipeline, but it does NOT yet emit/persist a server-side TranscriptImportBatch. Consequently the exception-review panel, repair queue, and batch speaker-mapping panel render their EMPTY states in production — src/app/app/admin/speaker-mapping/page.tsx literally hardcodes `groups: []` with the comment citing this. The MODELS + UI panels + unit tests are complete and merged (so these are not stubs of intent), but the live end-to-end exception/repair/batch-mapping data flow is a documented staged follow-up. A skeptic should treat 09/10/11 as PARTIAL until a persisted batch feeds the panels live.
[RC58] Content host-move is intentionally staged (not a defect, but incomplete consolidation): /app/organization, /app/team-mirror, /app/review-queue currently GUARD then redirect to the legacy hosts (/app/ceo, /app/mirror/me, /app/reviewer) rather than hosting the content at the canonical URL. Spec C03 §8 explicitly defers the content move. Canonical URLs are reachable and protected, but the legacy routes remain the real content hosts.
[RC58] Admin retains direct/legacy access to /app/ceo and /app/reviewer via host-level requireRole even though those tabs were removed from admin's primary nav (deliberate: nav-visibility tightened, host gates unchanged, support-access preserved). Fully removing admin's cross-workspace reach (or adding an explicit `internal`/support role) is deferred to a larger auth decision (the C13 requiresInternalAccess split is also still a documented future tightening, not yet a real permission).
[RC59] CLARIFICATION on the 'Kimura leak' check (not a defect): The live /demo, /demo/why, /demo/trust, /demo/roles pages DO render 'Kimura'/'木村'/'Nao' 14-29 times — but this is the INTENTIONAL editorial product narrative (manager Kimura interrupting Nao, the canonical demo story) and the seed-persona 'Kimura (Manager)' on the STATIC /demo/roles guided page, NOT analyzer output. The RC59 area-14 'leak removal' is specifically about the LIVE uploaded-transcript result BODY, which folder59-p25 §3 firebreak-locks (Kimura is absent from all 6 live-ingest-result components, which do not import seeds; a live result from non-Kimura speakers renders only Participant A/B/C). The firebreak and de-identified executive aggregate (commit eb8686a #481) are both functionally and statically proven. So the area-14 objective (Kimura/sample names cannot leak into a real analyzed result) is DONE; the persona's presence in hand-authored marketing copy is by design and explicitly tested-for as the single permitted location.
[RC60] Per-output analysis-time policy binding (P16 follow-up): PR-1 binds the active policy VERSION at ingest only. No analysis pipeline file writes the per-meeting meeting_metrics analysis-time fields (evidence_grade, routing_destination, detector/abstention reason_codes, policy_binding_status='bound') — those migration-0051 columns are populated by nothing in non-test src. Existing rows stay 'legacy_unbound'. Confirmed deferred.
[RC60] Audit read-UI screen: P05 shipped the audit writer + audit API (/api/admin/communication-policy/audit) but there is NO audit-trail read screen under communication-policy/** (no audit/ page dir). A separate generic admin /app/admin/audit nav entry exists but is not the policy-specific audit viewer. Confirmed deferred.
[RC60] Automated a11y tooling: P18 a11y is manual/structural only; repo has zero jest-axe/axe-core/toHaveNoViolations usage. No automated accessibility gate. Confirmed deferred.
[RC60] Audit writing is best-effort, not transactional (documented in c19ac8b): a mutation can succeed with no persisted audit row if the insert fails (logged, not thrown). Fail-closed auditing needs an atomic RPC — open follow-up.
[RC61] No genuine functional gap. RC61's own gate file (test/homepage61-gates.test.ts) no longer exists on main — it was intentionally deleted by RC62 (#507) and replaced by the superset homepage62-gates.test.ts. So RC61's acceptance criteria are now pinned by RC62's tests, not by an RC61-named test. This is correct SUPERSEDED-IN-PLACE behavior, not a regression, but anyone grepping for 'homepage61' will find only the source-scope class name .home-v61 (retained as the CSS scope token) and the i18n localization-matrix fragments — the RC61 test artifact itself is gone.

ナビ/UX の磨き込み (1)

[RC57] Area 6 'in nav': the dedicated /app/history page is fully built, role-scoped, filterable, and tested, but it is NOT registered as a navigation entry. src/lib/navigation/workspaces.ts hard-caps top-level nav at 6 canonical workspaces (none is History) and its own comment (line 14) states 'history/trace/coverage have no nav home'. The admin console nav (admin-console.ts) exposes 'Transcript Imports' (/app/admin/imports, described as 'review import history') but not /app/history itself. Reachability is only via in-page links/CTAs (/me diagnostic, UploadMoreCTA for member/manager, ImportResultSummary, AdminReadinessCockpit). So a member/manager has no persistent top-nav route to their History; an admin reaches import history via the Imports section, not the PR05 History page. Whether this satisfies 'a History/logs page in nav' depends on interpretation — strictly, no nav surface points at /app/history. Recommend either adding History as a 7th workspace/admin-console section or confirming the intent was CTA-only reachability. (Note: no test asserts a nav link to /app/history, so this gap is not guarded against regression either.)

プロセス/衛生(要確認) (2)

[RC58] Several foundational modules merged with [DRAFT — NEEDS SIGN-OFF] banners (C03 role-gated shell #461, C06 readiness state machine #468). They are on main and consumed by downstream prompts, and the Prompt-16 final audit recorded a PASS, but the original DRAFT sign-off banners remain in the merged commit titles — worth confirming Justine formally closed the C03 admin-access-tightening sign-off and the C06 readiness-meaning sign-off (C06's was effectively anchored by the C12 #470 calibration approval Justine gave 2026-06-09).
[RC60] P16/P17/P18 commits land directly on main with no PR numbers in the subjects (P01-P05 carried #484/#485 etc.); ancestry confirms they ARE on HEAD eb466f8, but the merge trail is commit-only for the later prompts.

テスト網羅の隙間(機能は動作) (4)

[RC60] P03 DB-floor invariants (RLS, immutability/append-only triggers, partial unique indexes) are mock/read-confirmed in tests; no live-Postgres/RLS integration test exists. Migrations 0050/0051 are flagged for manual Supabase-dashboard apply ('[SIGN-OFF: schema]') — verify they are actually applied in prod before relying on DB-floor enforcement.
[RC61] Mobile 0-overflow has no committed automated regression test (it is a /browse runtime QA step recorded in both PR bodies). If the homepage regresses on overflow in future, CI would not catch it; only the manual /browse sweep would. Minor — flagged per the project's own scrollWidth-sweep lesson.
[RC62] 0-overflow 320–1440 is NOT pinned by any committed automated test — verified only via the /browse responsive QA pass recorded in PR #507 (test headers say so explicitly). A future layout regression would not be caught by `npm test`; it relies on manual re-QA. This is the one acceptance area without a self-defending test on main.
[RC62] Keyboard Enter/Space TOGGLE behavior and the reduced-motion RUNTIME animation are /browse-verified, not unit-pinned. Strong proxies exist (native <button> ⇒ Enter/Space for free, pinned as a real button by the DOM test; reduced-motion CSS rule pinned by the gate), so risk is low — but no test exercises an actual key event or computed animation duration.

pack 別 詳細

RC57 — ほぼ反映 Upload-history / personal-view workflow (logged-in)

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映(1) Upload-first workflow: upload → infer → review-only-uncertain → analyze → result → upload-more/historysrc/app/app/admin/upload/upload-form.tsx wires the full chain: inferMetadata (after parse, line 143), needs=new Set(inferred?.needsReview) gating (line 421), computePreviewRow → analyze → <ImportResultSummary> (line 341) with historyHref continuation. Hub at src/app/app/admin/imports/page.tsx. PR #405/#404 merged (commits 870c5d4, 8bf5e55). Locked by folder57-workflow-matrix-lock §M1 (computePreviewRow severity ladder failed→blocked→observational→warning→ready, 6 tests green).
✓ main 反映(2) Metadata inference (title/date/platform/lang/speakers/meeting-type+confidence/quality-flags, conservative)src/lib/ingest/{infer-metadata,language,source-platform,series-recurrence,speaker-member-match,internal-external}.ts all present and real. Orchestrator header states 'Conservative throughout — unknown/low-confidence over hallucination (AC-INFER-017)'. test/folder57-infer-metadata.test.ts (all detectors + needsReview surfacing) and bulk-upload-infer-date.test.ts pass. quality_flags column locked additive in migration 0042 (folder57-schema-foundation.test.ts). PR #404 (commit 8bf5e55).
✓ main 反映(3) Metadata review UX (exception-only)upload-form.tsx surfaces needsReviewBadge ONLY on uncertain fields (line 421-446), high-confidence fields show inferredBadge not a review prompt. folder57-infer-metadata.test.ts 'does not flag high-confidence fields' + workflow-matrix-lock §M2 'high-confidence fields are NOT flagged' / 'fully-evidenced file flags NOTHING' (needsReview===[]). PR #405/#406.
✓ main 反映(4) Bulk upload 20+ with batch speaker/team applysrc/app/app/admin/upload-bulk/bulk-upload-form.tsx: single batch-wide teamId selector (line 100), batch meeting-type with bulkTypeConfirmed gate (line 98/384), one speakerMap applied across allUniqueSpeakers for the whole batch (buildSpeakerStates line 304), spreadDatesAcrossWeeks for many files, per-file computePreviewRow. spreadDatesAcrossWeeks tested at count=20 (bulk-upload-infer-date.test.ts 'produces ascending dates' n=20). PR #406 (commit 690129f).
✓ main 反映(5) 'Upload another transcript' CTA on every result/trace/record screen in ALL statessrc/components/cta/UploadMoreCTA.tsx role-aware (admin/ceo→/app/admin/imports carrying team; member/manager→/app/history, never a 403; demo→/demo/ingest). Injected on /me (line 773), /mirror/[managerId], /ceo (line 277), trace page; ImportResultSummary provides it on upload forms. folder57-state-cta.test.tsx (23 tests) asserts injection on chosen surfaces, absence on reviewer/notices/demo, no double-injection. PR #409/#435.
△ 部分(6) History/logs page in nav showing completed/pending/failed/partial/observation-onlyPAGE is fully built: src/app/app/history/page.tsx renders a real filterable list, role-scoped via loadUploadAnalysisHistory, displayStatus() ladder (failure→partial→observation/insufficient→analyzed), 6 filter buckets (HISTORY_FILTERS incl observation_only). folder57-history-queries.test.ts + workflow-matrix-lock §M3 green. GAP: /app/history is NOT a top-level nav entry — src/lib/navigation/workspaces.ts defines exactly 6 canonical workspaces (home, my-view, team-mirror, organization-summary, review-queue, admin-console) and line 14 explicitly says 'history/trace/coverage have no nav home'. admin-console.ts nav exposes 'Transcript Imports' (/app/admin/imports) but not /app/history. The History page is reachable only via in-page links/CTAs (UploadMoreCTA, ImportResultSummary, /me diagnostic, AdminReadinessCockpit). So the page exists and is complete, but the literal 'in nav' acceptance is not met.
✓ main 反映(7) My Personal View auth→member→team→speaker identity-mapping DIAGNOSTIC (never bare 'contact administrator')src/lib/member-private/member-private-projection.ts resolveIdentityDiagnostic returns first-broken-link reason (NO_TEAM/NO_SPEAKER_ALIAS/NO_MATCHED_MEETINGS/OK). /me page.tsx lines 344-401 render a step panel (signed-in ✓ / team / aliases count / meetings count + suggested fix + history/audit links), comment explicitly 'Never a bare contact administrator'. test/folder57-me-identity-diagnostic.test.ts + workflow-matrix-lock §M5 (monotonic ladder, clamps negatives). PR #411 (commit f831eb5).
✓ main 反映(8) Manager Mirror clearly separated from Personal Viewworkspaces.ts team-mirror is a distinct workspace (id 'team-mirror', href /app/team-mirror, currentRoute /app/mirror) with productBoundaryNote 'Team Mirror reflects the manager back to themselves. NOT a window into reports private states'; my-view ('/app/me') is a separate workspace. PortalHeaderNav renders them as distinct tabs. ExcludedMeetingsDrawer (PR08 #412) bounded metadata-only exclusion reasons locked by workflow-matrix-lock §M4.
✓ main 反映(9) Executive view raw-existence vs eligible-count coherencesrc/app/app/ceo/page.tsx: projectCeoRoster yields insufficientCount + suppressedCount (k-anon), data-testid='coherence-explainer' (line 312) explains why exec roster shows fewer teams than Admin (k-anonymity suppression), kAnonSuppressedCount surfaced (line 239), reference-window resolution. PR09 #413 (commit ce62be5, marked [BLOCKER]). workflow-matrix-lock §M6/§M7 lock aggregate-only + suppression coherence.
✓ main 反映(10) Cross-surface data coherencetest/folder57-workflow-matrix-lock.test.ts is the dedicated cross-cutting lock: §M3 History status ladder pin, §M4 'no meeting type both excluded-by-Mirror and review-worthy' (one-directional gate, client+server union), §M7 scopeForStatus never grants full to non-success states / observational never escalates. 24 matrix tests + 113 total F57 tests green on main.
✓ main 反映(11) Demo-date/window coherencesrc/lib/config/reference-date.ts: production=live clock + ?asOf IGNORED; demo env=fixed date + ?asOf honored; invalid env degrades to production; invalid ?asOf falls back to env date. test/folder57-reference-date.test.ts + workflow-matrix-lock §M6 'demo coherence cannot move a production window'. Demo-session opaque-token continuity (PR #437) with closed-allowlist sanitizer locked by folder57-demo-session-continuity.test.ts (token scheme, sanitizer no-leak, stateless analyze route).
✓ main 反映(12) Governance non-regression (no broad transcript browsing, no manager named-subordinate risk labels, no HR decisions, k-anon/RLS intact)Migration 0042 locked additive/non-destructive + stores NO raw transcript columns (folder57-schema-foundation.test.ts: vtt_text/cue_text/transcript_text/body_text forbidden; demo_sessions deny-by-default). RLS tests present: test/rls/{folder57-demo-session-scoped-read,folder57-speaker-alias-cross-org,folder57-workflow-tables}.test.ts. history/me pages render no raw-text columns (grep clean). workflow-matrix-lock §M4 (Mirror metadata-only, banned content fields on entry type) + §M8 forbidden-phrase sweep (no harassment/intent/illegality/perf-score, no 'no signal=no problem', EN+JA). Sanitizer drops detail/plain/affectedSpeaker/evidence (demo-session-continuity test).
この pack の gap:
Area 6 'in nav': the dedicated /app/history page is fully built, role-scoped, filterable, and tested, but it is NOT registered as a navigation entry. src/lib/navigation/workspaces.ts hard-caps top-level nav at 6 canonical workspaces (none is History) and its own comment (line 14) states 'history/trace/coverage have no nav home'. The admin console nav (admin-console.ts) exposes 'Transcript Imports' (/app/admin/imports, described as 'review import history') but not /app/history itself. Reachability is only via in-page links/CTAs (/me diagnostic, UploadMoreCTA for member/manager, ImportResultSummary, AdminReadinessCockpit). So a member/manager has no persistent top-nav route to their History; an admin reaches import history via the Imports section, not the PR05 History page. Whether this satisfies 'a History/logs page in nav' depends on interpretation — strictly, no nav surface points at /app/history. Recommend either adding History as a 7th workspace/admin-console section or confirming the intent was CTA-only reachability. (Note: no test asserts a nav link to /app/history, so this gap is not guarded against regression either.)

RC58 — ほぼ反映 Logged-in app UX repair — 15-prompt sequence

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映01 — UX code audit docTwo read-only audit reports merged: docs/reports/ux_repair_prompt_00_codebase_audit.md (F58, 5-agent fan-out over 6e95ed7, route/component/state map + P0 wound list) and docs/kashi-ux-repair-audit.md = Folder-59 C01 (11-reader fan-out, commit 91ebbad #459, extends F58 audit, flags stale findings). Both cite file:line and rank UX risks. Doc-as-deliverable, which is the prompt's intent.
✓ main 反映02 — canonical role/workspace nav model (Home/My View/Team Mirror/Organization Summary/Review Queue/Admin Console)src/lib/navigation/workspaces.ts (WorkspaceId = exactly the 6 named workspaces; allowedRoles in real OrgRole enum; mustNotExpose encoded as data). Doc docs/kashi-ux-navigation-model.md. Commit ace5a79/d6ed6c9 (C02 #460). Pure deterministic helpers (getVisibleWorkspacesForRoles, userCanAccessWorkspace) pinned by tests. Names match the spec one-to-one.
✓ main 反映03 — role-gated app shell with ROUTE protection (not just hiding)Real route guards, not hide-only: src/app/app/{home,organization,team-mirror,review-queue}/page.tsx each call resolveWorkspaceAccess() (src/lib/navigation/workspace-access.ts) → unauthenticated redirects /login, forbidden renders <WorkspaceForbidden/> (calm 403), allowed redirects to host. Hosts ALSO keep their own requireRole — double-gated, can only deny what the existing model denies (never widens). PortalHeader nav now built from getVisibleWorkspacesForRoles; hardcoded NAV_LINKS deleted. Admin tightened to Home/My View/Admin Console in primary nav (deliberate sign-off). Tests: folder59-c03-shell.test.ts + folder58-prompt09-navigation.test.tsx (108 passing on re-run). Commit 1813383 (C03 #461).
✓ main 反映04 — admin console structure (Action Center/Teams&Members/Imports/Speaker Mapping/Data Readiness/Notices/Audit/Diagnostics)src/lib/navigation/admin-console.ts = typed 8-section single source of truth in spec order; Diagnostics last + requiresInternalAccess:true. src/app/app/admin/layout.tsx + AdminConsoleNav wrap every /app/admin/* page. Section shells exist: action-center, teams, imports, speaker-mapping, readiness, notices, audit, diagnostics (all dirs present under src/app/app/admin/). Each guards requireRole(['admin','ceo'],{requireMfa:true}). Commit dc54bd8 (C04 #462). Chrome-only; route protection at page level.
✓ main 反映05 — admin action center (one blocker/one CTA)src/lib/admin/action-center.ts — pure getAdminPrimaryBlocker(status) applies the 10-step priority order (no team→…→ready), returns ONE AdminPrimaryBlocker (severity + i18n title + impact + one CTA), unit-tested (priority, highest-wins, sparse-no-crash). /app/admin/action-center renders one primary blocker above a compact status row; /app/admin redirects to it. Severity styling = controlled amber/neutral/emerald, no healthy/safe language. Commit 3ce9ac5 (C05 #463).
✓ main 反映06 — canonical readiness state machine (Ready/Limited/Blocked/Observation-only/N-A)src/lib/readiness/readiness-state.ts — ReadinessStatus = ready|limited|blocked|observation_only|not_applicable across 5 areas, 17 dependencies, 5 pure calculators, conservative getReadinessSummary + buildReadinessInputFromAdminState adapter. Doctrine header explicitly forbids health-score, no-signal=safety, and that readiness≠access. Doc docs/kashi-readiness-state-machine.md. Merged DRAFT-needing-signoff but C07 consumes it and final audit recorded PASS. Commit 32f58c5 (C06 #468).
✓ main 反映07 — readiness UI plain language (no 'no signal=no problem')src/app/app/admin/readiness/page.tsx imports getReadinessSummary + renders ReadinessCard (src/components/admin/readiness/). Outcome-language not system-language. folder58-prompt08-empty-states.test.tsx pins forbidden reassurance denylist ('no problem','safe team','all clear', JA 問題なし/安心してください/健全なチーム) and that abstention blocks carry caveat + next action + semantic-lane disclosure. Forbidden-phrase scan clean across src/** + messages (Prompt-16 audit §4). Commit cff6439 (C07 #469).
✓ main 反映08 — universal transcript importer (one flow, file=batch-of-one)src/lib/imports/import-batch.ts typed spine ('one file = a batch of one', single status enum). src/app/app/admin/imports/page.tsx renders the real TranscriptImporter that ingests through the live /api/meetings/upload pipeline (not a stub — loads teams/profiles, real UploadDropzone). Legacy /app/admin/upload + upload-bulk redirect here (guards preserved). Doc docs/kashi-transcript-importer.md. Commit 7c26b46 (C08 #464).
△ 部分09 — exception-only import reviewModel DONE: src/lib/imports/import-review.ts — pure classifier surfacing ONLY uncertain/blocking/limiting exceptions (clean file → 0 items → 'ready'), 13 review categories, i18n copy, no absence=safety. UI DONE: src/components/admin/imports/ImportReviewPanel.tsx (exception-first, calm clean state). BUT the panel's own header states wiring to the importer's live parsed batch is a documented follow-up: 'the reused engine does not yet emit a TranscriptImportBatch.' So model+UI+tests are complete and merged, but the live exception-review data flow is staged (PD-3 persistence gap). Commit 1113ca0 (C09 #465).
△ 部分10 — partial-import/repair queue (ready files import, bad files queued not lost)Model DONE: import-batch.ts adds partially_imported/needs_repair/discarded states + per-file ignored/removed/replaced. UI route exists: src/app/app/admin/imports/repair/page.tsx (entry below the upload panel per spec §10). Tests pin counts (folder58-fix-bulk-mapped-count.test.ts, folder59-seqC C10). Same PD-3 caveat: repair queue is fed by persisted batches the importer does not yet emit server-side, so it renders its empty state live. Models/UI/tests merged, live wiring staged. Commit bbdc1a7 (C10 #466).
△ 部分11 — batch speaker mapping (durable, confidence, confirm-all/guest/ignore/undo/apply-future)Model DONE: src/lib/speakers/speaker-mapping.ts — SpeakerMappingActionType includes confirm_all_high_confidence, mark_guest, ignore_for_person_level, undo (+apply-future status), SpeakerMappingConfidence high/medium/low/none, member-match suggestions with evidence, durable SpeakerAliasStatus. canConfirmAllHighConfidence gate. UI: SpeakerMappingPanel.tsx. Tests: folder58-prompt04-speaker-resolver. BUT src/app/app/admin/speaker-mapping/page.tsx hardcodes groups:[] with explicit comment 'PERSISTENCE (documented gap, PD-3): aliases/groups come from imported batches, which are not yet persisted server-side… panel shows its empty state.' Model+panel complete+tested; live durable persistence is the staged follow-up. Commit 083a424 (C11 #467).
✓ main 反映12 — meeting-type validity (observation-only fallback)src/lib/meeting-types/meeting-type-model.ts — getMeetingTypeValidity returns supported|low_confidence|observation_only|unsupported; grievance/interview→unsupported(never review-worthy), training/incident_bridge/exec_review/unknown→observation_only, scoreable+high/med-conf→supported. Anchored to the live calibration gate (scoringModeFor). Admin selector + import-surface consistency. Tests folder58-prompt05-meeting-type.test.ts + regression §4.4. Commit dc457b9 (C12 #470) — this is also the calibration sign-off that closed the 15B-1 server Rule-3 hole.
✓ main 反映13 — diagnostics separation (debug gated to Admin/Diagnostics)src/app/app/admin/diagnostics/page.tsx = the ONE home for raw technical detail (parser/transcript/result-state traces, raw payloads, fixtures), guarded requireRole(['admin','ceo'],{requireMfa:true}); raw-internal sections marked internal:true and visually de-emphasized + positionally last. Header: 'raw detail must never be reachable by a non-admin role or the public demo.' Test folder59-c13-diagnostics-separation.test.tsx (passing). Commit 7ba7e7d (C13 #471).
✓ main 反映14 — governance/audit/anti-retaliation UX (private concern not leaked; forbidden-use sentence)src/app/app/admin/notices/page.tsx renders forbiddenUse.label + forbiddenUse.sentence + body in-product (lines 87-92). src/app/app/admin/audit/page.tsx = typed governance audit log. Employee trust layer: EmployeeTrustLayerSummary with data-employer-visible-on-view='false', non-leak guarantee (page-open/notes/drafts/vault private to employee). Tests: folder58-prompt13-employee-trust-layer.test.tsx (private-non-leak guarantee, managers-NOT-notified, member-private-projection unchanged) + folder59-c14-{no-leak-locks,notices-governance,private-state-policy,audit-event}.test.ts + c14b-panel-wiring (30+ passing on re-run). Codex adversarial round closed 3 fail-open anti-retaliation defects (commit 7a96da6). C14b wired panels to owner-only tables (#473). Commits ed4cd0d..576a43a (C14/C14b #472/#473).
✓ main 反映15 — full regression QAtest/folder58-prompt15-regression-cross-role.test.ts = 59 it/describe cross-role harness (state-model integrity, readiness ladder distinctness, configured-vs-aggregate no-naked-0, no-review-items≠exoneration, unknown/unsupported-type never review-worthy, speaker cross-form parity, server scoringMode↔classifier agreement guard). test/folder58-prompt15b-rule3-exploitability.test.ts is the durable boundary guard (now asserts the remediated clamped end-state). Folder-59 C15 = final regression QA verdict GO + 4 small safe fixes (commit 1368623 #474). Prompt-16 final acceptance audit = PASS (condition satisfied 2026-06-10, #433/#470).
✓ main 反映BOUNDARIES — no surveillance/HR-decision/health-score/no-signal=no-problem/debug-leak/private-state-leakEncoded as data + tests, not folklore: workspaces.ts mustNotExpose per workspace; readiness-state.ts doctrine bars health-score + absence=safety + readiness-grants-no-access; folder58-prompt08 denylist test (EN+JA reassurance forbidden); folder58-prompt13 + folder59-c14-no-leak-locks pin private-state non-leak (employer_visible_on_view:false, managers NOT notified); C13 gates all raw debug to admin+MFA Diagnostics; meeting-type model + 15b guard block unsupported types from review-worthy output; executive-summary verified to carry no transcript/named-individual/private-state field. Prompt-16 forbidden-phrase scan (harassment/intent/legal/discipline/performance-score/exonerated) clean across src + messages.
この pack の gap:
PD-3 persistence gap (affects areas 09 exception review, 10 repair queue, 11 batch speaker mapping): the universal importer ingests through the real /api/meetings/upload pipeline, but it does NOT yet emit/persist a server-side TranscriptImportBatch. Consequently the exception-review panel, repair queue, and batch speaker-mapping panel render their EMPTY states in production — src/app/app/admin/speaker-mapping/page.tsx literally hardcodes `groups: []` with the comment citing this. The MODELS + UI panels + unit tests are complete and merged (so these are not stubs of intent), but the live end-to-end exception/repair/batch-mapping data flow is a documented staged follow-up. A skeptic should treat 09/10/11 as PARTIAL until a persisted batch feeds the panels live.
Several foundational modules merged with [DRAFT — NEEDS SIGN-OFF] banners (C03 role-gated shell #461, C06 readiness state machine #468). They are on main and consumed by downstream prompts, and the Prompt-16 final audit recorded a PASS, but the original DRAFT sign-off banners remain in the merged commit titles — worth confirming Justine formally closed the C03 admin-access-tightening sign-off and the C06 readiness-meaning sign-off (C06's was effectively anchored by the C12 #470 calibration approval Justine gave 2026-06-09).
Content host-move is intentionally staged (not a defect, but incomplete consolidation): /app/organization, /app/team-mirror, /app/review-queue currently GUARD then redirect to the legacy hosts (/app/ceo, /app/mirror/me, /app/reviewer) rather than hosting the content at the canonical URL. Spec C03 §8 explicitly defers the content move. Canonical URLs are reachable and protected, but the legacy routes remain the real content hosts.
Admin retains direct/legacy access to /app/ceo and /app/reviewer via host-level requireRole even though those tabs were removed from admin's primary nav (deliberate: nav-visibility tightened, host gates unchanged, support-access preserved). Fully removing admin's cross-workspace reach (or adding an explicit `internal`/support role) is deferred to a larger auth decision (the C13 requiresInternalAccess split is also still a documented future tightening, not yet a real permission).

RC59 — 完全反映 Detector logic + /demo redesign + result page + privacy — 27 prompts

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映(1) End-to-end audit + 24-fixture manifesttest/fixtures/folder59/ has exactly 24 VTTs (C01-03/D01-06/M01-07/R01-08). test/fixtures/folder59-manifest.ts FOLDER59_MANIFEST has 24 entries with per-fixture expected parse/quality/exposure/detector states. folder59-fixture-runner.test.ts asserts 'manifest covers exactly the 24 fixtures on disk' + runs the REAL POST /api/demo/analyze per fixture. C01 audit = commit 02158e6 (#459). I ran the runner: 24-fixture suite PASSES.
✓ main 反映(2) Canonical result-state type (concern separation)src/lib/pipeline/demo-result-state.ts frozen 5-state DemoResultState; demo-display-model.ts adds 3 display states + PRIMARY_STATE_ELIGIBLE_LANES={STRUCTURAL_TIMING,STRUCTURAL_TURN_PATTERN}. folder59-p03-canonical-state-conformance.test.ts mutation-locks the EXACT state set and asserts ResolvedDemoResultContract splits parse/quality/metric-availability/evidence/abstention/interpretation/displayPrivacyMode into distinct typed fields. 12 tests pass. Commit 8ac72ec (#445).
✓ main 反映(3) Parser diagnosticsfolder59-p04-parser-diagnostics-conformance.test.ts locks parse-turns.ts/transcript-parser.ts/substrate-quality.ts surface structured speakerCount/per-speaker counts/timestampCoverage/typed reason codes (not prose). Debug payload exposes parser.parsedTurnCount/speakerCount/timestampCoverage (p23 test asserts numeric). Passes.
✓ main 反映(4) Quality-vs-exposure splitfolder59-p05-quality-vs-exposure-conformance.test.ts: INPUT_QUALITY_FAILURE_CODES (LOW_TRANSCRIPT_QUALITY/BLOCKED_SUBSTRATE) kept DISJOINT from EXPOSURE_LIMITATION_CODES (INSUFFICIENT_TURNS/SPEAKERS/DURATION); a valid short VTT must NOT carry an input-quality code AND substrate quality must NOT be 'low'/blocked (mutation-proven both directions). Semantic-off => unavailable_semantic_off NOT no_signal (p15 + fixture-runner). Passes.
✓ main 反映(5) Abstention reason codessrc/lib/ux/kashi-ux-states.ts ABSTENTION_REASONS; folder59-p06-reason-code-taxonomy.test.ts asserts each code carries severity/scope/blockedCapabilities/title/explanation+i18n keys and the full 22-code spec union is present; semantic-off + cold-start are CAVEAT/LIMITATION never input-quality BLOCKER; canRenderCanAnalyzeNo requires capability detail. src/lib/analysis/abstention.ts decideAbstention. Passes. Commit 22cf81c (#444).
✓ main 反映(6) Raw-metrics vs interpretation labelingfolder59-p07-raw-vs-interpretation-conformance.test.ts (commit 8ac72ec) passes. ResolvedDemoResultContract.metrics (participantCount/turnCount/floorTimeAvailable/interruptionDetectorRan/candidateCount/topInterruptionDyad) is a distinct object from abstention/interpretation, asserted in p03. demo-result-state.ts ZERO_COUNT_NEUTRAL_FALLBACK + allowsCategoryDistributionInterpretation guard against reading 0-count as imbalance.
✓ main 反映(7) Floor-time/evidence taxonomy (floor-time-only != directional)folder59-p08-floor-time-demotion + p08b-floortime-universal-demotion (commit 057b2ed #452) UNIVERSALLY demote floor-time-only concentration to descriptive (drops the facilitatorLed gate); D06/M07 display.state moved STRUCTURAL_SIGNAL_OBSERVED->NO_CONCERN. fixture-runner asserts floor-time status is evaluated_*/suppressed_*, never producing a directional dyad. p09-evidence-taxonomy passes. src/lib/analysis/evidence-grade.ts + comparable-exposure.ts.
✓ main 反映(8) Meeting-type+role policy (standup/incident/1on1/training/exec protected)folder59-p10-meeting-type-guardrail-conformance.test.ts: scoringModeFor maps incident_bridge/training/exec_review/brainstorm->observation_only (protective, never escalatory), grievance/interview->suppressed, weekly_sync/design_critique->scoreable (disjoint control = mutation-proven). applyMeetingTypeNormalization in demo-result-state.ts NEVER downgrades REVIEW_WORTHY/discourse signals. p11-role-facilitator (exec_review greylist + project_review facilitator-protected, #448). 24-fixture M01-M07 all assert no_signal. Passes.
✓ main 反映(9) Interruption vs overlap (D03/R01 Kenji->Mika; R02/M04 no false-fire)fixture-runner NAMED_INVARIANT_FIXTURES set {D03,R01,R02,M04}; D03/R01 assert top dyad = 'Kenji Morita->Mika Sato' (TOP_DYAD_KENJI_MIKA); R02 (fast handoff) + M04 (brainstorm overlap) assert intrusive-interruption status != evaluated_candidate with '*** NAMED-INVARIANT REGRESSION ***' shout. folder59-p12-interruption-overlap-conformance.test.ts. src/lib/analysis/structural-metrics/interruption-directionality.ts. All pass.
✓ main 反映(10) Detector availability + semantic-off (unavailable != no-signal)src/lib/pipeline/detector-availability-matrix.ts + detector-capability-registry.ts; folder59-p14-detector-availability-matrix + p14-matrix-render + p14-matrix-route-leaksafe + p15-semantic-off-output-rules. Matrix emits unavailable_semantic_off / unavailable_longitudinal_public_demo distinct from evaluated_no_signal; render shows 'Not evaluated' (JA 未評価) never 'no signal'. fixture-runner enforces semantic detectors == unavailable_semantic_off per fixture. Commit b383a99 (#447). Passes.
✓ main 反映(11) Discourse detector cards (5 cards, no intent/emotion)folder59-p16 (unanswered-question), p17 (chilling-delta), p18 (topic-credit), p19 (agreement-shift), p20 (agenda-preclosure) — each VERIFY-locks the card maps to a real detector, sits on CONVERSATIONAL_SEMANTIC lane (cannot drive primary state solo), and FORBIDDEN_TERMS (deliberately/intentional/misconduct/harassment/felt/intended-to/neglect/exclusion) absent from label+affirmative summary. Commit a80f8a0 (#449). All pass.
✓ main 反映(12) Fixture QA harness (24 fixtures, no external semantic API)folder59-fixture-runner.test.ts header + code: runs POST /api/demo/analyze with analyzeContent:false and KASHI_ENABLE_SEMANTIC_LANE='false' stubbed — 'NO external semantic / Anthropic API is ever called'; compares STRUCTURED state only, never screenshots. folder59-p22-batch-report.test.ts emits JSON+MD grouped report (scripts/folder59-batch-report.ts, commit ebee741). Ran 24-fixture oracle: passes.
✓ main 反映(13) Result-page UX (summary above fold, collapsible evidence, save-CTA below)folder59-p24-result-hierarchy.test.tsx mounts DemoVisualAnalysisResult (SSR) and asserts DemoResultHero + DemoMetricStrip render ABOVE DemoDetectorMatrix in document order; unavailable rows distinct from no-signal; caveats deduped to exactly 1; render-safe on minimal/absent-fields payloads (2026-06-06 lesson vectors). DemoVisualAnalysisResult.tsx:21 comment 'save below comprehension' (save CTA rendered below). Commit a608fe4 (#455). Passes.
✓ main 反映(14) Privacy/display-identity (DisplayPrivacyMode, public_anonymized default, Kimura leak removed)src/lib/pipeline/display-privacy-mode.ts: DISPLAY_PRIVACY_MODES=[public_anonymized,fixture_debug_named,tenant_role_based], DEFAULT=public_anonymized; buildSpeakerDisplayMap is single label source (no mixed Kenji/Participant-A). folder59-p25-display-privacy.test.ts §3 firebreak: 'Kimura (Manager)' lives ONLY in src/data/seeds/people.json and is asserted ABSENT from all 6 LIVE_INGEST_RESULT_PATH components + those components do NOT import seeds; a live result from non-Kimura speakers renders only Participant A/B/C. Exec aggregate de-identified (commit eb8686a #481). Passes. SEE GAP NOTE re live editorial pages.
✓ main 反映(15) Copy/localizationfolder59-p26-copy-cleanup.test.tsx (commit ffcef61 #458) mounts the real SSR stack from a real route payload and locks: typo 'storedin' absent; storage wording distinguishes processing (transcript not stored) from optional metadata snapshot; no-emotion/intent/misconduct boundary visible in always-rendered hero; JA matrix shows 未評価 never シグナルなし; JA-mode localizes (no half-English core page). Passes.
✓ main 反映(16) Privacy/security/governance (no transcript body stored, sanitizer, secret-phrase no-leak)folder59-p27-public-payload-no-content-leak.test.ts: SECRET-phrase + hostile + cross-speaker-repetition + D03 shared_tokens transcript -> ZERO leak in semantic-off payload (case-insensitive + token-split deep scan); POSITIVE CONTROL with lane ON re-admits fields (gate is the only switch, not a permanent strip = mutation-proven). p23-debug-export-leaksafe.test.ts: debug payload privacy.includesTranscriptBody=false, redactionApplied=true; redactTranscriptDebugFields strip is load-bearing (builder fed injected secret-bearing fields, proven to bite). p27b-governance forbids automated decisions/formal findings. __FORBIDDEN_KEYS_FOR_TEST sweep. Passes.
✓ main 反映(17) Final checks (no formal finding/HR/emotion/intent in public demo)fixture-runner asserts display.state NEVER REVIEW_WORTHY_EVENT (strongest public = STRUCTURAL_SIGNAL_OBSERVED candidate) + FORBIDDEN_PHRASES (emotion/intent/misconduct/harassment/harm/employment lexicon incl パワハラ/terminate) absent from EVERY fixture's serialized payload. p27b forbids formal-finding/automated-decision output. Live /demo 'harassment'/'パワハラ' occurrences are all legal-context (MHLW/EU AI Act positioning) + the explicit cannotSay disclaimer block ('Kashi が言えないこと: ハラスメントがあったかどうか') — boundary copy area 17 requires, not analyzer assertions. Passes.
この pack の gap:
No genuine implementation gap found. All 27 prompts (P01-P27 + Seq-B redesign + Seq-C admin) have merged commits on main (HEAD eb466f8); I executed 31 folder59 test files = 480 tests, ALL PASS, including the 24-fixture oracle that drives the real route and the named invariants (D03/R01 Kenji->Mika finding; R02/M04 no false-fire).
CLARIFICATION on the 'Kimura leak' check (not a defect): The live /demo, /demo/why, /demo/trust, /demo/roles pages DO render 'Kimura'/'木村'/'Nao' 14-29 times — but this is the INTENTIONAL editorial product narrative (manager Kimura interrupting Nao, the canonical demo story) and the seed-persona 'Kimura (Manager)' on the STATIC /demo/roles guided page, NOT analyzer output. The RC59 area-14 'leak removal' is specifically about the LIVE uploaded-transcript result BODY, which folder59-p25 §3 firebreak-locks (Kimura is absent from all 6 live-ingest-result components, which do not import seeds; a live result from non-Kimura speakers renders only Participant A/B/C). The firebreak and de-identified executive aggregate (commit eb8686a #481) are both functionally and statically proven. So the area-14 objective (Kimura/sample names cannot leak into a real analyzed result) is DONE; the persona's presence in hand-authored marketing copy is by design and explicitly tested-for as the single permitted location.
Minor doc-note (not blocking): manifest entries for D06/M07 carry 'general_discussion(low-conf)->canonical unknown' classifier outcomes (F55 split-brain), resolved in-manifest with RESOLVED-P08b notes; these were doctrine-evaluated, not papered over (P21 run report). No action needed.

RC60 — ほぼ反映 F60 Communication Policy Console (admin) — 18 prompts

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映P01 governance constants + safety floorscommit 3910894 (#484). src/lib/governance/communication-policy-constants.ts. test/folder60-p01-governance-constants.test.ts (15KB, ~30 its): safety_floor_version stable, prohibited inferences/uses complete, k>=5 non-lowerable, 4 profile presets exact keys/labels, 6 evidence grades, 5 routing destinations, 14 meeting types, 10 prohibited detectors locked_off, floor_time/interruption/chilling sole-escalation locks.
✓ main 反映P02 validation engine + snapshot hash + runtime assertioncommit a8f2747 (#485). communication-policy-{validation,snapshot,defaults,runtime-assertions}.ts. test/folder60-p02-validation-engine.test.ts (18KB) covers spec PART-10 tests 1-28: stable-stringify hash determinism, volatile-field exclusion, default factory pins floor/engine/retention versions, 14 validator rejection cases incl. value-leak vectors (16b/16c reject non-canonical keys without echoing), safe-policy acceptance.
✓ main 反映P03 durable model + repository (schema sign-off)commit 5a59554 shipped as '[DRAFT — NEEDS SCHEMA SIGN-OFF]' but sign-off was RESOLVED: migration 0050 (5 tables, RLS admin/ceo/hr_compliance default-deny, partial unique indexes one-active/one-draft-per-org, published-snapshot immutability trigger, append-only audit triggers) dated 2026-06-10; downstream P16/P17 commits carry '[SIGN-OFF · stacked]' tags and 0051 header reads '[SIGN-OFF: schema] apply via Supabase dashboard'. test/folder60-p03-repository.test.ts (12 spec tests): draft clone, second-draft/second-active rejection, hash recompute, published immutability, optimistic-concurrency hash mismatch, cross-org no-leak. Caveat (c19ac8b doc): DB-floor invariants are mock/read-confirmed, no live-Postgres/RLS test yet.
✓ main 反映P04 draft/publish API spinecommit 822c45b. src/app/api/admin/communication-policy/draft/{route,validate,publish,simulate,notices}. test/folder60-p04-routes.test.ts (16KB): full RBAC (admin/ceo create, hr_compliance/manager/member 403, unauth 401), draft lifecycle (reason required, 409 second-draft, stale-hash 409, 404 missing), publish (typed-confirmation, POLICY_PUBLISH_BLOCKED, retire+activate), rollback.
✓ main 反映P05 audit writer + audit APIcommit 649e4c4. communication-policy-audit.ts + /api/admin/communication-policy/audit/route.ts. test/folder60-p05-audit.test.ts: sanitizer redacts transcript/quote/snippet/evidence_vault/speaker_id at depth+in-arrays, keeps config keys; writer sanitizes before/after; reader org-scoped+publish_events_only+limit-cap 200+cursor; API hides request_context_json; per-action recording (draft_created/updated/deleted, publish_blocked, policy_published, rollback). Known gap (c19ac8b): audit is best-effort not transactional — a mutation can succeed with no audit row if insert fails (logged, not thrown); fail-closed needs atomic RPC follow-up.
✓ main 反映P06 overview screencommit 350da9f. overview/page.tsx + SafetyFloorPanel.tsx + presentation.ts. test/folder60-p06-overview.test.tsx: renders active+draft+safety floors+readiness+nav, honest empty states, floors sourced from constants.
✓ main 反映P07 profile & scope editorcommit cde0cd5. profile-scope/{page,MaterialChangeWarning,copy}. test/folder60-p07-profile-scope.test.tsx: 4 profile cards as radiogroup with constant admin_labels, earlier_awareness/custom floor-invariant statements.
✓ main 反映P08 meeting-type calibrationcommit 92946f3. meeting-types/{page,copy}. test/folder60-p08-meeting-types.test.tsx: 14 types render, locked types show badge+reason+no mode select, never offers locked mode as selectable.
✓ main 反映P09 detector configurationcommit 174693c. detectors/{page,SemanticLaneGatePanel,copy}. test/folder60-p09-detectors.test.tsx: 3 lanes, prohibited detectors visible+locked_off+badged+no toggle, 'Kashi does not' doctrine language, semantic-lane gate.
✓ main 反映P10 evidence & routingcommit ca24456. evidence-routing/{page,copy}. test/folder60-p10-evidence-routing.test.tsx: 6 evidence grades with 'not a finding' language, 5 routing destinations no forbidden labels, locked routing floors + human-review locks + automatic-action off.
✓ main 反映P11 visibility & rightscommit 1ed505e. visibility-rights/{page,VisibilityRightsEditor,copy}. test/folder60-p11-visibility-rights.test.tsx: 6-role matrix, locked rules (manager telemetry off / universal browsing off / perf-use off / auto-HR off / audit on), k>=5 floor enforced via min attribute.
✓ main 反映P12 notice & versionscommit 49e6e7f. notice-versions/page + communication-policy-notice{,-locks}.ts. test/folder60-p12-notice-versions.test.tsx: 9 required locked statements, deterministic floor-version-sensitive hash, notice renderer.
✓ main 反映P13 simulator engine + APIcommit ee19f4b. communication-policy-simulator{,-privacy,-confidence}.ts + /draft/simulate route. test/folder60-p13-simulator.test.ts (9KB): estimated-mode binds draft hash + low confidence, aggregate-only fields, review routes labeled 'candidates not findings', non-canonical meeting-key genericized, k=5 cell suppression+count, sanitizer strips identifiers at depth, RBAC (member 403), stores run bound to draft hash.
✓ main 反映P14 simulator screencommit bc49c5b. simulator/PolicyImpactSimulator.tsx. test/folder60-p14-simulator-screen.test.tsx: required disclaimer+privacy boundary, 30/90/180 windows, admin sees Run / HR does not, estimated-mode caution + low-confidence no-overclaim.
✓ main 反映P15 publish screencommit 4dafe47. publish/PublishClient.tsx + readiness publishBlockers. test/folder60-p15-publish.test.tsx: safety-floor reminder + typed confirmation + effective time + attestation, server blockers with fix links disable publish, empty form cannot publish.
△ 部分P16 runtime policy integration + analysis-output bindingcommit 99498e0 '[SIGN-OFF]' + runtime-policy-{routing,context}.ts + resolve-communication-policy.ts + migration 0051 (meeting_metrics policy-binding columns, closed enum bound/legacy_unbound/failed_policy_resolution, FK). test/folder60-p16-runtime-binding.test.ts: most-restrictive routing, evidence-grade conservatism, context resolver throws on no-active-policy (no silent unsafe fallback), legacy rows never rebound. PR-1 fbaea0f binds active-policy VERSION at INGEST (wired into all 5 ingest routes: upload/teams/meet/zoom/notta). GAP: per-output ANALYSIS-TIME binding (writing evidence_grade/routing_destination/reason-codes to meeting_metrics during analysis) is NOT wired — no analysis-pipeline file (run-conversational-case-analysis.ts etc.) writes those columns; this is the documented deferred follow-up.
✓ main 反映P17 emergency pause kill-switchcommits cc68242 (lib+API+UI) + dd5ece7 (live suppression PR-2) + eed1558 (4 refinements). communication-policy-emergency-pause.ts + emergency-pause-surface-guard.ts + emergency-pause/page.tsx + /api/admin/communication-policy/emergency-pause. test/folder60-p17-emergency-pause.test.tsx: input validators (>=1 surface, meaningful reason, future expiry, 7-day max), active-non-expired-only listing, overlay union, create-never-publishes/disable-never-deletes, RBAC (hr_compliance read-only), forbidden-claim+no-leak copy EN/JA. The c19ac8b-documented 'overlay computed but wired only into tests' gap is RESOLVED: guard now imported live into me/ceo/mirror/reviewer/* pages + mutation routes + send-drilldown-notice; test/folder60-pause-suppression.test.tsx (SPLIT fail-open/fail-closed) + folder60-pause-notification-suppress.test.ts (SUPPRESSED_BY_PAUSE, records nothing) prove live suppression.
△ 部分P18 full tests + accessibility + hardeningcommits 46956b6 (scanners+docs) + c19ac8b (honest caveats) + d50ffff (4 adversarial findings closed). test/folder60-p18-{copy-safety,privacy-leakage,console-consistency}.test.ts: copy-safety scans >=10 screens with mutation-proof adjacent-sentence laundering check; privacy-leakage redacts content keys at depth + k=5 suppression + runtime-context no-identifier; console-consistency nav<->filesystem honesty + canonical enum stability. docs/communication-policy-console{,-test-plan}.md exist. GAP: accessibility is asserted manually/structurally (radiogroup, min-attr, text queries) — NO automated a11y tooling (no jest-axe/axe-core/toHaveNoViolations anywhere in repo); the 'automated a11y tooling' item remains a deferred follow-up per the original note.
この pack の gap:
Per-output analysis-time policy binding (P16 follow-up): PR-1 binds the active policy VERSION at ingest only. No analysis pipeline file writes the per-meeting meeting_metrics analysis-time fields (evidence_grade, routing_destination, detector/abstention reason_codes, policy_binding_status='bound') — those migration-0051 columns are populated by nothing in non-test src. Existing rows stay 'legacy_unbound'. Confirmed deferred.
Audit read-UI screen: P05 shipped the audit writer + audit API (/api/admin/communication-policy/audit) but there is NO audit-trail read screen under communication-policy/** (no audit/ page dir). A separate generic admin /app/admin/audit nav entry exists but is not the policy-specific audit viewer. Confirmed deferred.
Automated a11y tooling: P18 a11y is manual/structural only; repo has zero jest-axe/axe-core/toHaveNoViolations usage. No automated accessibility gate. Confirmed deferred.
Audit writing is best-effort, not transactional (documented in c19ac8b): a mutation can succeed with no persisted audit row if the insert fails (logged, not thrown). Fail-closed auditing needs an atomic RPC — open follow-up.
P03 DB-floor invariants (RLS, immutability/append-only triggers, partial unique indexes) are mock/read-confirmed in tests; no live-Postgres/RLS integration test exists. Migrations 0050/0051 are flagged for manual Supabase-dashboard apply ('[SIGN-OFF: schema]') — verify they are actually applied in prod before relying on DB-floor enforcement.
P16/P17/P18 commits land directly on main with no PR numbers in the subjects (P01-P05 carried #484/#485 etc.); ancestry confirms they ARE on HEAD eb466f8, but the merge trail is commit-only for the later prompts.

RC61 — 完全反映 Public homepage / — rebuild (v2)

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映RC61 merged + deployed (provenance)Both PRs on main, HEAD=eb466f8. e691b81 'feat(homepage): destructive rebuild of public homepage / (Review Comment 61) (#506)'; eb466f8 'feat(homepage): v3.1 progressive-disclosure upgrade (Review Comment 62) (#507)'. git branch --contains both -> main. RC61 is SUPERSEDED-IN-PLACE by RC62 in the same surface (same page.tsx/HomeSections.tsx).
✓ main 反映Locked 8-section IA (Hero->Sample->Measures->How->WhoSeesWhat->Does/Does-not->Governance->FinalCTA)SUPERSEDED-but-satisfied: RC62 expands the spine to 11 sections that strictly contain RC61's 8. page.tsx:45-55 composes HomeHero->HomeLocalNav->HomeSampleOutput->HomeTrustStrip->HomeMetrics->HomeHowItWorks->HomeWhoSeesWhat->HomeDoesDoesNot->HomeGovernance->HomeFaq->HomeFinalCta. Pinned by homepage62-gates.test.ts:261-273 'page composes the v3.1 sections in order' (ordered indexOf). Live HTML has all 6 anchored section ids (sample/metrics/how-it-works/visibility/governance/faq each =1). RC61's 'Measures' == RC62 §4 Metrics 「Kashiが整理するもの」; additions (Trust strip §3, FAQ §9) are net-new, not removals.
✓ main 反映Sans-serif (no Fraunces on /)Gate 5 homepage62-gates.test.ts:206-218: SECTIONS_SRC/PAGE_SRC/DISCLOSURE_SRC never match /font-serif/; .home-v61 block contains var(--font-jp) + /font-variation-settings:\s*normal/. globals.css .home-v61 :where(h1,h2,h3){font-family:var(--font-jp);font-variation-settings:normal}. Live: the only 'fraunces' string is the layout-level CSS-module class on root <html> (fraunces_36c709ed-module__...) from global font wiring — NOT applied to homepage headings, which are scoped+reset by .home-v61.
✓ main 反映Locked JA copyCopy-lock suite homepage62-gates.test.ts:240-278 pins exact sentences: heroHeadline='会議をまたいで、発言機会の偏りを確認する。', heroTrust='Kashiの出力は確認用です。最終判断は人が行います。', metricsTitle='Kashiが整理するもの', sampleCardLabel='確認候補', role2Summary contains '自分が関与する会議'. Live HTML contains each locked string (grep count=1 each): 会議をまたいで…/最終判断は人が行います/Kashiが整理するもの/確認候補. RC62 evolved a few tokens (発話->発言の遮り, 「見るもの」->「整理するもの」, manager scope narrowed) — these are deliberate v3.1 supersessions, still within RC61's enterprise-JA register and re-locked by tests.
✓ main 反映Banned-copy + claim-safety gatesRC61's homepage61-gates.test.ts was DELETED by RC62 and REPLACED with stronger homepage62-gates.test.ts (Gate 1 banned-copy, Gate 3 claim-safety) + 3 forbidden-phrase gates extended (i18n-banned-words.test.ts +9, i18n-r17-forbidden-marketing.test.ts +9). 58/58 RC62 gate+disclosure tests PASS on main (just ran). Gate 1 BANNED scans rendered keys for ハラスメントを検知/感情を検知/監視-style positive phrasings; Gate 3 REDFLAGS_JA/EN blocks 監視/退職予測/生産性スコア/health score etc on non-negation keys. Live banned hits (ハラスメントを検知 / 監視 / 生産性スコア) are ALL in legitimate negation/forbidden copy — verified context: 'ハラスメントを検知しません', '部下を個別に監視する設計ではありません', '個人の生産性スコアとして扱う' (inside forbidden-use list). doesNot1-4 pinned = 発言内容の評価/感情推定/ハラスメント判定/人事判断の自動化 (test:96-98).
✓ main 反映Mobile-first 0-overflowBoth commit messages record '/browse 0-overflow 320-1440' verification (RC61 320-1440; RC62 320-1440 + accordion toggle + inert collapsed). Mobile-first construction in source: clamp() hero (home-h1 clamp(26px,5.4vw,40px) + 23px <=narrow override), responsive grids (sm:grid-cols-2, md:grid-cols-3), DisclosureCard 44px tap rows pinned by homepage62-disclosure.test.tsx:42-46 (w-full, min-h-[44px], focus-visible:ring). Note: scrollWidth sweep is a /browse runtime check, not a committed automated regression test — but recorded as run, and no overflow-prone fixed widths in source.
✓ main 反映Functionality / navigability preservedGate 4 homepage62-gates.test.ts:176-203: no placeholder href='#'; all 6 section ids exist; local nav chips link to real anchors; CTAs target real routes /demo+/pilot+/governance; hero has exactly one primary CTA. Live confirms href=/governance, href=/pilot x4, href=/demo x5, 20 collapsed accordion buttons (aria-expanded=false) rendered server-side. RC61's additive mobile consultation CTA preserved in SiteHeader.tsx:102-105 (md:hidden, min-h-[44px], ->/pilot). Disclosure a11y by construction: real <button aria-expanded aria-controls> + inert panel + role=region (homepage62-disclosure.test.tsx 58 passing assertions).
この pack の gap:
No genuine functional gap. RC61's own gate file (test/homepage61-gates.test.ts) no longer exists on main — it was intentionally deleted by RC62 (#507) and replaced by the superset homepage62-gates.test.ts. So RC61's acceptance criteria are now pinned by RC62's tests, not by an RC61-named test. This is correct SUPERSEDED-IN-PLACE behavior, not a regression, but anyone grepping for 'homepage61' will find only the source-scope class name .home-v61 (retained as the CSS scope token) and the i18n localization-matrix fragments — the RC61 test artifact itself is gone.
Mobile 0-overflow has no committed automated regression test (it is a /browse runtime QA step recorded in both PR bodies). If the homepage regresses on overflow in future, CI would not catch it; only the manual /browse sweep would. Minor — flagged per the project's own scrollWidth-sweep lesson.

RC62 — ほぼ反映 Public homepage / — v3.1 progressive disclosure

状態受け入れ領域根拠(テスト / ファイル / commit)
✓ main 反映Visible-first/foldable-second doctrine (trust line, trust strip, does-not summary, role summaries NEVER inside a collapsed accordion)HomeSections.tsx: HomeTrustStrip (L114-131) renders trust1-4 as a plain <ul>, no DisclosureCard; heroTrust rendered as a plain <p> in HomeHero L47; HomeDoesDoesNot L268-280 renders doesNot1-4 in a visible <ul> BEFORE the only DisclosureCard (forbiddenFoldLabel L282); HomeWhoSeesWhat L219 renders {r.summary} in a visible <p>, only see/hide/note go inside the per-role fold. Pinned by homepage62-gates.test.ts 'Core visibility' describe block (L113-143): asserts trust block contains trust1-4 AND not DisclosureCard; does-not idx < fold idx; role summary outside fold. All 58 tests pass at HEAD eb466f8. Live HTML confirms trust strip line '確認用の表示です' renders outside any aria-expanded button.
✓ main 反映Accessible DisclosureCard (real button + aria-expanded + aria-controls + inert + Enter/Space + 44px + reduced-motion)DisclosureCard.tsx L48-63: real <button type=button> with aria-expanded={open} (L51), aria-controls={panelId} (L52); panel L67-71 has id=panelId, role=region, aria-labelledby, inert={!open}; trigger className has w-full + min-h-[44px] + focus-visible:ring (L54). homepage62-disclosure.test.tsx pins all of this via renderToStaticMarkup: real-button, aria-expanded=false default, aria-controls→matching region id, inert on collapsed region, min-h-[44px], focus-visible ring, defaultExpanded→aria-expanded=true+non-inert. Live HTML: 20 buttons w/ aria-expanded, 20 unique aria-controls, 19 inert region panels. Enter/Space = native button (PARTIAL caveat: keyboard TOGGLE itself is /browse-verified per test header, not unit-pinned, but native <button> gives Enter/Space for free and is pinned). reduced-motion pinned: gates 'motion respects prefers-reduced-motion' asserts globals.css has prefers-reduced-motion + home-disclosure-motion; CSS L400-406 sets transition-duration:0.01ms.
✓ main 反映Trust strip (always-visible boundary strip)HomeSections.tsx HomeTrustStrip L114-131 renders trust1-4. ja.json: trust1=確認用の表示です。 / trust2=感情推定は行いません。 / trust3=ハラスメント判定は行いません。 / trust4=人事判断は自動化しません。 Pinned by gates 'the always-visible trust strip has its 4 lines' (L89-94) + core-visibility 'NO DisclosureCard' (L115-123). Live HTML contains '確認用の表示' in visible (non-script) markup.
✓ main 反映FAQ (6 Q&A)HomeSections.tsx HomeFaq L330-348 maps faqQ1-6/faqA1-6 into AccordionGroup. ja.json has exactly 6 Q + 6 A (verified: faqQ count 6, faqA count 6). Pinned by gates 'the FAQ has 6 questions and 6 answers' (L105-110). Live HTML renders heading 'よくあるご質問' in visible text.
✓ main 反映Local section navHomeSections.tsx HomeLocalNav L55-69 builds 5 chips (#sample,#metrics,#visibility,#governance,#faq) via reused StickyAnchorNav (src/components/sales-hub/StickyAnchorNav.tsx exists, real <nav> w/ aria-current). Pinned by gates Gate-4 'local nav links every chip to an existing anchor' (L187-191) + 'hero secondary anchor + section anchors exist' (L181-186). Live HTML contains navAria 'ページ内ナビゲーション' + chip labels サンプル/FAQ in visible text.
✓ main 反映Copy v3.1 (発話→発言, 「Kashiが整理するもの」, manager narrowed)ja.json: heroBody uses 発言の遮り (NOT 発話); metricsTitle='Kashiが整理するもの'; role2Summary='自分が関与する会議の運営傾向を確認できます。' (manager narrowed). Pinned by gates Copy-lock (L240-277): heroBody contains 発言の遮り AND not 発話 (L246-249); metricsTitle === 'Kashiが整理するもの' (L250-252); role2Summary contains '自分が関与する会議' (L258-260); also pins locked heroHeadline + heroTrust + sample 確認候補/根拠を見る. Live visible HTML (script-payload stripped): 発話=absent, Kashiが見るもの=absent, 発言の遮り + Kashiが整理するもの present.
△ 部分0-overflow 320–1440No committed automated overflow/responsive test exists (grep of test/ for scrollWidth/overflow/viewport = none). Both RC62 test headers explicitly state the responsive + keyboard + reduced-motion runtime gates 'run via /browse (no Playwright in this repo)' and are 'recorded in the PR'. So the 0-overflow 320-1440 criterion is manual-QA-verified-in-PR only, not pinned by a test that would re-bite on regression. Structural mitigations exist (mobile-first layout, .home-v61 scope, max-w wrappers) but no acceptance test asserts it on main.
✓ main 反映Gates (CI test gates: banned-copy, required-copy, core-visibility, claim-safety, CTA/link, typography, disclosure-ARIA, copy-lock, section3Card guard)homepage62-gates.test.ts (Gates 1-5 + disclosure-source + copy-lock + section3Card guard) and homepage62-disclosure.test.tsx (ARIA DOM) — 2 files, 58 tests, all PASS at HEAD eb466f8 (run confirmed). Merged as part of #507 (eb466f8 'feat(homepage): v3.1 progressive-disclosure upgrade (Review Comment 62)'). HEAD eb466f8 is the deployed commit.
この pack の gap:
0-overflow 320–1440 is NOT pinned by any committed automated test — verified only via the /browse responsive QA pass recorded in PR #507 (test headers say so explicitly). A future layout regression would not be caught by `npm test`; it relies on manual re-QA. This is the one acceptance area without a self-defending test on main.
Keyboard Enter/Space TOGGLE behavior and the reduced-motion RUNTIME animation are /browse-verified, not unit-pinned. Strong proxies exist (native <button> ⇒ Enter/Space for free, pinned as a real button by the DOM test; reduced-motion CSS rule pinned by the gate), so risk is low — but no test exercises an actual key event or computed animation duration.
Minor/non-issue (documented for completeness): the live page's inlined Next.js RSC/i18n script payload (__next_f.push) contains 発話 because it serializes the FULL ja.json bundle (demoContinuation.savedTurnsLabel, governance.wnd11Body, demoAbstention.*, etc.) for client hydration. These are NOT homepage copy and NOT in visible text — after stripping <script> blocks, visible HTML has zero 発話 and zero Kashiが見るもの. The acceptance criterion (no 発話 in visible text) is met. Not a regression to fix.