revise(02-03): bump warm-pool fragment count + journal hotkey listener
- W6: warm-tagged pool depth raised to ≥9 (8th-harvest threshold + 1 buffer) so a worst-case all-rosemary playthrough never exhausts. Total per-pool targets: ≥9 warm, ≥3 contemplative, ≥3 heavy, plus the sentinel. - W2: JournalIcon now listens for the 'tlg:toggle-journal' window event so App.tsx can wire a 'j' hotkey without lifting open/close state into the store. Hotkey is gated on the same revealed selector as the icon itself.
This commit is contained in:
+18
-3
@@ -370,7 +370,9 @@ wait. The wait was the thing. The flower would bloom in its own time. Most
|
|||||||
good things were like that, until they weren't.
|
good things were like that, until they weren't.
|
||||||
```
|
```
|
||||||
|
|
||||||
(Total: 9 in yaml + 2 in md + 1 sentinel = 12 fragments. Exceeds RESEARCH Assumption A8's "≥10" target with margin. Tags distribute: 4 warm, 3 contemplative, 3 heavy, 1 _meta = 11 plant-tagged + 1 sentinel; comfortably feeds 8th-harvest Lura threshold + plant-type unlocks.)
|
(W6 fix — bump warm-pool depth so a worst-case all-rosemary playthrough still has fragments left at harvest 8.
|
||||||
|
|
||||||
|
Total: ≥14 in yaml + ≥2 in md + 1 sentinel = ≥17 fragments. Tags distribute: ≥9 warm, ≥3 contemplative, ≥3 heavy, 1 _meta. The yaml block above shows 3 warm samples; the executor authors ≥6 additional warm-tagged fragments matching the same tonal register before committing. Pool depth must satisfy the worst-case constraint: 8 harvests of rosemary alone must not exhaust the warm pool. The exhaustion sentinel still exists as a defensive fallback (Pitfall 8), but the authored pool should be deep enough that it is never reached during normal Phase-2 play.)
|
||||||
|
|
||||||
**Step 3 — `src/sim/memory/pool.ts`** (PATTERNS Group D filter pattern):
|
**Step 3 — `src/sim/memory/pool.ts`** (PATTERNS Group D filter pattern):
|
||||||
|
|
||||||
@@ -643,7 +645,8 @@ PIPE-02's lazy split is structurally verified by `scripts/check-bundle-split.mjs
|
|||||||
**Commit:** `feat(02-03): Season-1 fragments + sim/memory selector + harvest/compost commands`. Run `npm run lint && npx vitest run src/sim/ src/content/ && npm run build` before committing (npm run build proves the new fragments parse).
|
**Commit:** `feat(02-03): Season-1 fragments + sim/memory selector + harvest/compost commands`. Run `npm run lint && npx vitest run src/sim/ src/content/ && npm run build` before committing (npm run build proves the new fragments parse).
|
||||||
</action>
|
</action>
|
||||||
<acceptance_criteria>
|
<acceptance_criteria>
|
||||||
- `grep -c "^ - id: season1\\." content/seasons/01-soil/fragments.yaml` returns ≥9
|
- `grep -c "^ - id: season1\\." content/seasons/01-soil/fragments.yaml` returns ≥14
|
||||||
|
- `[ "$(grep -c "tags: \\[warm\\]" content/seasons/01-soil/fragments.yaml)" -ge 9 ]` (W6: warm pool ≥ 8th-harvest depth + 1 buffer)
|
||||||
- `ls content/seasons/01-soil/fragments/*.md | wc -l` returns ≥2
|
- `ls content/seasons/01-soil/fragments/*.md | wc -l` returns ≥2
|
||||||
- `grep -q "season1.soil._exhaustion" content/seasons/01-soil/fragments.yaml`
|
- `grep -q "season1.soil._exhaustion" content/seasons/01-soil/fragments.yaml`
|
||||||
- `grep -q "tags: \\[warm\\]\\|tags: \\[contemplative\\]\\|tags: \\[heavy\\]" content/seasons/01-soil/fragments.yaml` (multiple)
|
- `grep -q "tags: \\[warm\\]\\|tags: \\[contemplative\\]\\|tags: \\[heavy\\]" content/seasons/01-soil/fragments.yaml` (multiple)
|
||||||
@@ -858,7 +861,7 @@ export function FragmentRevealModal(): JSX.Element | null {
|
|||||||
**Step 3 — `src/ui/journal/journal-icon.tsx`** (D-23 + D-29):
|
**Step 3 — `src/ui/journal/journal-icon.tsx`** (D-23 + D-29):
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useAppStore, selectJournalRevealed } from '../../store';
|
import { useAppStore, selectJournalRevealed } from '../../store';
|
||||||
import { Journal } from './Journal';
|
import { Journal } from './Journal';
|
||||||
|
|
||||||
@@ -873,6 +876,18 @@ export function JournalIcon(): JSX.Element | null {
|
|||||||
const revealed = useAppStore(selectJournalRevealed);
|
const revealed = useAppStore(selectJournalRevealed);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
// W2 — D-29 'j' hotkey toggles the journal. App.tsx dispatches a window
|
||||||
|
// CustomEvent so the JournalIcon owns its open/close state without lifting
|
||||||
|
// it into the store. The listener is keyed off the same revealed gate as
|
||||||
|
// the icon itself — pre-first-harvest the hotkey is a no-op (matches the
|
||||||
|
// anti-FOMO doctrine: nothing exists for the player to "discover" early).
|
||||||
|
useEffect(() => {
|
||||||
|
if (!revealed) return;
|
||||||
|
const onToggle = () => setOpen((o) => !o);
|
||||||
|
window.addEventListener('tlg:toggle-journal', onToggle);
|
||||||
|
return () => window.removeEventListener('tlg:toggle-journal', onToggle);
|
||||||
|
}, [revealed]);
|
||||||
|
|
||||||
if (!revealed) return null;
|
if (!revealed) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user