---
name: project-step1545-mystery-playable-v02-dynamic-2026-08-29
description: STEP 1545 mystery-playable v0.2 in-place upgrade — STEP 1543 page に dynamic generator + Jaccard anti-repetition + 5 scenario × 7 attribute × 6 location pool 追加、 browser smoke test 全 PASS
metadata: 
  node_type: memory
  type: project
  originSessionId: c922ed16-8768-46a2-904a-a44edbee09b5
  modified: 2026-08-28T23:05:52.814Z
---

# STEP 1545: Mystery Playable v0.2 (Dynamic Generator + Anti-Repetition) — STEP 1543 in-place upgrade

**Date**: 2026-08-29
**Trigger**: 藤本さん recommendation 承認 「C. Dynamic mystery generator (v0.2 の目玉)」 (STEP 1543 v0.1 完成直後、 藤本さんが next step として選択、 2 度目の承認)
**Sibling**: [[project-step1543-mystery-playable-page-2026-08-29]] (v0.1 base) / [[project-step1538-mystery-reasoning-connector-2026-08-29]] (engine)
**URL**: https://rei-aios.pages.dev/tools/step-1543-mystery-playable/ (v0.1 と 同 URL、 in-place upgrade)
**Files**:
- `src/mcp/mystery-generator-dynamic.ts` (400+ line — engine 層の generator 本体)
- `test/step1545-mystery-generator-dynamic-test.ts` (80/80 PASS — 10 section)
- `public/tools/step-1543-mystery-playable/index.html` v0.1 → v0.2 (+400 line generator port + UI)
- `dist-renderer/tools/step-1543-mystery-playable/index.html` mirror (md5 `27ef5860...`)

## 藤本さん 2026-08-29 引用 (対応 protocol)

> 「推理探偵モノもパズルと同じく無限に作れる」 → dynamic generation の正面応答
> 「直前に出した推論チップの組み合わせを記録して、 次の生成でそれを避ける制約を入れる」 → Jaccard anti-repetition

## v0.2 architecture

### Pool 定義 (5 × 7 × 6 combinatorial space)

- **SCENARIO_POOL** (5): 高級マンション / 山荘 / 深夜オフィス / 美術館閉館後 / 夜行列車 — title + subtitleTemplate(time) + time (crime hour)
- **ATTRIBUTE_POOL** (7): leftHanded / wearsGlasses / medic / tall / smoker / hasBeard / hasKey — label + evidenceNarrative (per-attribute prose) + displayPositive/Negative
- **LOCATION_POOL** (6): カフェ / GS / ジム / 病院 / バー / ホテルロビー — id + label + medium (surveillance evidence 種類)
- **NAME_POOL** (12): 佐藤 / 田中 / 木村 / 高橋 / 山田 / 中村 / 伊藤 / 渡辺 / 斎藤 / 加藤 / 小林 / 林

### Difficulty config

| Difficulty | Suspects | Chip set | Person-elim | Alibi count |
|---|---|---|---|---|
| easy   | 3 | alibi + elimination                 | 1     | 1 |
| medium | 4 | alibi + elimination + common_feature | 2     | 1 |
| hard   | 5 | alibi + elimination + common_feature | 2-3   | 1-2 |

### Backward machine algorithm

1. Pick scenario / names / culprit index (random)
2. Assign elimination method per non-culprit: 'person' or 'alibi' (unique per suspect)
3. Shuffle ATTRIBUTE_POOL, take personCount 個 → 各 person-method non-culprit を uniquely eliminate
4. Shuffle LOCATION_POOL, take alibiCount 個 → 各 alibi-method non-culprit の alibi 場所
5. Build suspects (culprit satisfies all person attrs; person-method suspects have opposite of their distinguisher; alibi suspects match culprit + have mustHaveBeenAt/Time)
6. Build facts (per-attribute person fact with evidenceNarrative + per-alibi record fact)
7. `verifyMystery(spec)` gate、 well-posed でなければ retry (max 30)
8. Signature = { chip: prefix } ∪ { attr: prefix }、 直近履歴と Jaccard 計算、 threshold 0.7 超えは retry

### Anti-repetition (Jaccard)

- localStorage key `mystery_playable_recent_sigs_v02`
- Rolling 20 事件保持
- Signature 定義: `{ chip:alibi, chip:elimination, attr:leftHanded=true, ... }` の sorted uniqued set
- Location は signature に含めない (低頻度で noise になる)
- Threshold default 0.7、 「またこのパターンか」 の operational 定義

## Test 80/80 PASS + browser smoke test

- 3 難度全生成成功 (easy/medium/hard)
- 15 iteration well-posed 検証 (uniqueness=UNIQUE_CORRECT + necessity=ALL_NECESSARY)
- Anti-repetition: 10 生成で pairwise Jaccard max ≤ 0.7 (実測 0.67 = 2-attr set が 1 attr 共有時の理論最大)
- scenario pool coverage: 50 gen で 3+ distinct scenarios
- signature composition (chip + attr、 loc 除外)
- narrative fragments 全 fact に populated
- pool sanity (5/7/6 サイズ)
- signature deterministic for same seed
- max_attempts exhaustion honest error report

**Browser smoke test (claude-in-chrome MCP)** (local http server 経由):
- Engine ✓ (5 chip / 4 case / 7 attr / 6 loc / 5 scenario)
- 3 difficulty × 1 attempt = well-posed 通過
- 10 連続生成 max pairwise Jaccard 0.67 (< 0.7 threshold)
- 答え submit → 正解 render + trace + verifier + stats update 全動作
- Screenshot 保存: `screenshot-1787958234068-0.jpg` (1464x812) = 「美術館の閉館後 (自動生成)」 → 犯人 高橋 → 正解 flow

## bug 発見 → 修正 (実装中)

初回 test で section 4 (scenario pool coverage) fail: `seededRng(2000+i)` で LCG 第一出力が全て小さい値 (0.015...) → 全 50 iteration で scenario 0 のみ選択。 Knuth multiplicative hash (`* 2654435761 >>> 0`) で seed 分散して修正、 80/80 PASS。

## Signature 空間サイズ (honest scope)

- easy (2 attr set): C(7,2) = 21 unique signatures possible
- medium/hard (2-3 attr set): C(7,2) + C(7,3) = 21 + 35 = 56
- 実測: 10 生成で 0.67 が最大 Jaccard = size-2 set が 1 共通 attr = 期待通り
- 20 事件 rolling で signature 空間の 40-70% 消化、 pool 拡張 (v0.3) が飽和対策

## in-place upgrade (URL 継続)

STEP 1543 page (`/tools/step-1543-mystery-playable/`) を v0.1 → v0.2 に **同 URL** で upgrade。 v0.1 の 4 事件は fixed tabs として保持、 5 番目に 「🎲 動的生成」 tab 追加。 URL 変更なし = v0.1 の user に自動反映、 external link 破損なし。 chat-Claude verdict puzzle STEP 1537 v0.1.1 hotfix と同じ pattern。

## Honest scope

- v0.2 = 5×7×6 pool 固定、 pool 拡張 (v0.3) が「飽和対策」の次 step
- narrative は simple template (LLM なし)、 「事件の余韻」 は v0.3 defer
- contradiction / timeline chip は v0.2 でも narrative のみで elimination なし
  (証言矛盾 → decision layer は v0.3 defer)
- Backward machine greedy retry、 最適解ではなく最初に well-posed 通過を採用
- Signature に location を含めない意図的設計、 追加すると Jaccard が noise で低下しすぎる
- 「dynamic generator で世界初」 主張ゼロ、 constraint satisfaction random search + Jaccard filter の pedagogical 実装
- Stats: v0.1 の solved map は generated case (unique id per generation) にも適用、 「一度解いた事件は再カウントしない」 protection 保持

## site 反映

- URL: https://rei-aios.pages.dev/tools/step-1543-mystery-playable/ (in-place)
- md5: `27ef5860c8e362b49df9549f64845248` (public + dist-renderer mirror 一致)

## 次 STEP candidate (v0.3)

- contradiction / timeline chip elimination 昇格 (「証言 vs 記録」 decision layer + 距離 matrix 物理制約)
- Pool 拡張 (10 scenario × 12 attribute × 10 location = 3.6x combinatorial)
- LLM narrative layer (「事件の余韻」 追加装飾)
- Lean 4 formalization (uniqueness + necessity の formal 定理化)
- tool-schema-registry (STEP 1536) 統合 (puzzle + mystery + game 語彙共通化)
- 生成した事件の export (SNS 共有 or persist favorite)
- 難度アルゴリズム調整 (retry 回数 histogram で 難度の実質メトリクス)
