- EmojiGenerator: remove unused clickToCopyLabel, CopyFeedback import, forEach i - FontPairGenerator: prefer-const loadedFonts, remove unused headingFamily, bodyFamily, copyIconSvg - HashGenerator: remove unused copyIcon, checkIcon, copyLabel - Magic8BallGenerator: remove unused getTypeLabel - TeamsGenerator: remove unused teamPrefix, errAddTwo, errTeamsMin, errTeamsMax, errMorePlayers
943 lines
33 KiB
Markdown
943 lines
33 KiB
Markdown
# Critical Fixes + Quality Refactoring
|
||
|
||
## TL;DR
|
||
|
||
> **Quick Summary**: Replace all `Math.random()` calls with a shared cryptographically secure `crypto.getRandomValues()` wrapper, deduplicate the dice engine by importing `src/lib/dice-engine.ts`, extract reusable Astro components for result/copy UI, and refactor all 28 generators to consume the new shared patterns. Fix CI to gate deployment on passing tests and lint.
|
||
>
|
||
> **Deliverables**:
|
||
> - `src/lib/client/random.ts` + test (crypto wrapper)
|
||
> - `src/lib/client/i18n.ts` + test (client locale helper)
|
||
> - `src/components/ResultBox.astro` (reusable result container)
|
||
> - `src/components/CopyButton.astro` (reusable copy button using existing `CopyFeedback`)
|
||
> - 28 refactored generators using new utilities
|
||
> - `DiceGenerator.astro` importing from `dice-engine.ts`
|
||
> - Updated `dice-engine.ts` using crypto wrapper
|
||
> - Updated Privacy Policy translations
|
||
> - Fixed `.github/workflows/deploy.yml`
|
||
>
|
||
> **Estimated Effort**: Large
|
||
> **Parallel Execution**: YES - 5-7 tasks per wave
|
||
> **Critical Path**: Wave 1 (utilities) → Wave 2 (components) → Waves 3-6 (generator batches) → Wave 7 (dice + policy) → Wave 8 (CI) → F1-F4
|
||
|
||
---
|
||
|
||
## Context
|
||
|
||
### Original Request
|
||
User wants to fix critical issues and quality-refactor all generators into an easily extensible structure. No push to main without permission.
|
||
|
||
### Interview Summary
|
||
**Key Decisions**:
|
||
- Critical scope: Dice engine + honesty (Web Crypto API migration)
|
||
- Tests: YES - TDD for new utilities, tests-after + agent QA for generators
|
||
- Refactor scope: ALL 28 generators
|
||
- CI/CD: Fix deploy.yml to run tests and lint
|
||
- Quality over speed
|
||
|
||
### Research Findings
|
||
- **28 generators** exist (not 10 as stated in outdated CLAUDE.md)
|
||
- **29 files use `Math.random()`** despite aboutHowItWorks claiming Web Crypto API
|
||
- **Dice engine duplicated**: `DiceGenerator.astro:274-958` inlines `src/lib/dice-engine.ts`
|
||
- **Copy-paste UI**: Every generator recreates result + copy button DOM
|
||
- **Hardcoded i18n**: Strings in generator frontmatter/scripts instead of `translations.ts`
|
||
- **Missing `zod`**: Not in `package.json` despite direct import
|
||
- **CI gap**: Tests and lint exist but deploy.yml skips them
|
||
|
||
### Metis Review
|
||
**Identified Gaps** (addressed):
|
||
- Core objective tightened to single sentence
|
||
- Scope IN/OUT explicitly defined
|
||
- Test strategy recorded (TDD for utilities)
|
||
- Existing utilities inventoried (`clipboard.ts`, `validation.ts`, `animations.ts`)
|
||
|
||
---
|
||
|
||
## Work Objectives
|
||
|
||
### Core Objective
|
||
Replace every `Math.random()` call across all 28 generators with a shared cryptographically secure wrapper, deduplicate the dice engine by importing `src/lib/dice-engine.ts`, and refactor all generators to consume the new shared utilities.
|
||
|
||
### Concrete Deliverables
|
||
- `src/lib/client/random.ts` + `random.test.ts`
|
||
- `src/lib/client/i18n.ts` + `i18n.test.ts`
|
||
- `src/components/ResultBox.astro`
|
||
- `src/components/CopyButton.astro`
|
||
- All 28 `*Generator.astro` files refactored
|
||
- `DiceGenerator.astro` importing from `dice-engine.ts`
|
||
- `src/lib/dice-engine.ts` updated to use `random.ts`
|
||
- Updated Privacy Policy in `src/i18n/translations.ts`
|
||
- Fixed `.github/workflows/deploy.yml`
|
||
|
||
### Definition of Done
|
||
- [ ] `npm run test` passes (new + existing tests)
|
||
- [ ] `npm run lint` passes
|
||
- [ ] `npm run build` succeeds
|
||
- [ ] No `Math.random()` calls remain in generator scripts
|
||
- [ ] Dice engine is imported, not inlined
|
||
- [ ] CI runs tests and lint before deploy
|
||
|
||
### Must Have
|
||
- Cryptographically secure random for all generators
|
||
- Deduplicated dice engine
|
||
- Shared utilities for random + i18n
|
||
- Shared Astro components for result/copy UI
|
||
- All 28 generators refactored
|
||
- CI quality gates
|
||
|
||
### Must NOT Have (Guardrails)
|
||
- **NO shared dynamic `[slug].astro`** for Russian pages (breaks script bundling)
|
||
- **NO changes to generator JSON schema** (strict Zod — unknown fields fail build)
|
||
- **NO client-side router introduced**
|
||
- **NO push to main** without explicit user approval
|
||
- **NO removal of existing EN/RU page files** — keep separate files
|
||
- **NO over-abstraction** — keep utilities simple and focused
|
||
|
||
---
|
||
|
||
## Verification Strategy
|
||
|
||
> **ZERO HUMAN INTERVENTION** — ALL verification is agent-executed.
|
||
|
||
### Test Decision
|
||
- **Infrastructure exists**: YES (vitest v4.1.5 configured)
|
||
- **Automated tests**: TDD for utilities, tests-after for generators
|
||
- **Framework**: vitest (node environment)
|
||
- **TDD workflow**: RED (failing test) → GREEN (minimal impl) → REFACTOR
|
||
|
||
### QA Policy
|
||
Every task MUST include agent-executed QA scenarios.
|
||
Evidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`.
|
||
|
||
- **Frontend/UI**: Use Playwright — Navigate, interact, assert DOM, screenshot
|
||
- **Library/Module**: Use Bash (bun/node REPL) — Import, call functions, compare output
|
||
- **API/Config**: Use Bash (grep) — Search patterns, verify absence
|
||
|
||
---
|
||
|
||
## Execution Strategy
|
||
|
||
### Parallel Execution Waves
|
||
|
||
```
|
||
Wave 1 (Foundation - utilities + deps + CI draft, 5 tasks):
|
||
├── Task 1: Add zod + typescript to package.json
|
||
├── Task 2: Create crypto random utility (TDD)
|
||
├── Task 3: Create client i18n helper (TDD)
|
||
├── Task 35: Update Privacy Policy translations
|
||
└── Task 36: Fix deploy.yml quality gates
|
||
|
||
Wave 2 (Shared components + dice crypto + CI verify, 4 tasks):
|
||
├── Task 4: Create ResultBox.astro
|
||
├── Task 5: Create CopyButton.astro
|
||
├── Task 34: Update dice-engine.ts to use crypto random
|
||
└── Task 37: Verify CI blocks deploy on failure
|
||
|
||
Wave 3 (Generators batch 1 + dice refactor, 8 tasks):
|
||
├── Task 6: Refactor CardGenerator
|
||
├── Task 7: Refactor CoinGenerator
|
||
├── Task 8: Refactor ColorGenerator
|
||
├── Task 9: Refactor CountryGenerator
|
||
├── Task 10: Refactor DateGenerator
|
||
├── Task 11: Refactor EmojiGenerator
|
||
├── Task 12: Refactor FontPairGenerator
|
||
└── Task 33: Refactor DiceGenerator to import dice-engine
|
||
|
||
Wave 4 (Generators batch 2, 7 tasks):
|
||
├── Task 13: Refactor GradientGenerator
|
||
├── Task 14: Refactor HashGenerator
|
||
├── Task 15: Refactor LetterGenerator
|
||
├── Task 16: Refactor ListGenerator
|
||
├── Task 17: Refactor LoremGenerator
|
||
├── Task 18: Refactor LotteryGenerator
|
||
└── Task 19: Refactor Magic8BallGenerator
|
||
|
||
Wave 5 (Generators batch 3, 7 tasks):
|
||
├── Task 20: Refactor MealGenerator
|
||
├── Task 21: Refactor NamesGenerator
|
||
├── Task 22: Refactor NumberGenerator
|
||
├── Task 23: Refactor PaletteGenerator
|
||
├── Task 24: Refactor PasswordGenerator
|
||
├── Task 25: Refactor RpsGenerator
|
||
└── Task 26: Refactor ShufflerGenerator
|
||
|
||
Wave 6 (Generators batch 4, 6 tasks):
|
||
├── Task 27: Refactor TeamsGenerator
|
||
├── Task 28: Refactor TimeGenerator
|
||
├── Task 29: Refactor UuidGenerator
|
||
├── Task 30: Refactor WeightedGenerator
|
||
├── Task 31: Refactor WheelSpinner
|
||
└── Task 32: Refactor YesNoGenerator
|
||
|
||
Wave FINAL (After ALL tasks - 4 parallel reviews):
|
||
├── Task F1: Plan compliance audit (oracle)
|
||
├── Task F2: Code quality review (unspecified-high)
|
||
├── Task F3: Real manual QA (unspecified-high)
|
||
└── Task F4: Scope fidelity check (deep)
|
||
-> Present results -> Get explicit user okay
|
||
|
||
Critical Path: Wave 1 → Wave 2 → Waves 3-6 → F1-F4
|
||
Parallel Speedup: ~70% faster than sequential
|
||
Max Concurrent: 8 (Wave 3)
|
||
```
|
||
|
||
### Dependency Matrix
|
||
|
||
- **1**: - - 2, 3
|
||
- **2**: - - 4, 5, 34
|
||
- **3**: - - 4, 5, 6-32
|
||
- **4**: 2, 3 - 6-33
|
||
- **5**: 2, 3 - 6-33
|
||
- **6-32**: 4, 5 - F1-F4
|
||
- **33**: 4, 5, 34 - F1-F4
|
||
- **34**: 2 - 33, F1-F4
|
||
- **35**: - - F1-F4
|
||
- **36**: - - 37, F1-F4
|
||
- **37**: 36 - F1-F4
|
||
|
||
### Agent Dispatch Summary
|
||
|
||
- **Wave 1**: Tasks 1-3, 35, 36 → `quick` (deps + TDD utilities + CI draft + policy)
|
||
- **Wave 2**: Tasks 4-5, 34, 37 → `visual-engineering` + `deep` + `quick`
|
||
- **Waves 3-6**: Tasks 6-33 → `unspecified-high` × 28 (generator refactoring + dice)
|
||
- **FINAL**: F1-F4 → `oracle`, `unspecified-high`, `deep`
|
||
|
||
---
|
||
|
||
## TODOs
|
||
|
||
- [x] 1. Add missing dependencies to package.json
|
||
|
||
**What to do**:
|
||
- Add `zod` to `dependencies` (imported but missing)
|
||
- Add `typescript` to `devDependencies` (Astro projects need it)
|
||
- Run `npm install` to update lockfile
|
||
|
||
**Must NOT do**:
|
||
- Change existing dependency versions
|
||
- Remove existing packages
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `quick`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 2, 3)
|
||
- **Blocked By**: None
|
||
- **Blocks**: Tasks 2, 3 (npm install should complete)
|
||
|
||
**References**:
|
||
- `package.json` — current dependency manifest
|
||
- `src/lib/generator-schema.ts:1` — `import { z } from "zod"`
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `zod` listed in `dependencies`
|
||
- [ ] `typescript` listed in `devDependencies`
|
||
- [ ] `npm install` succeeds
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: Verify deps installed
|
||
Tool: Bash
|
||
Steps:
|
||
1. grep '"zod"' package.json
|
||
2. grep '"typescript"' package.json
|
||
3. npm install
|
||
Expected Result: Both found, npm install exits 0
|
||
Evidence: .sisyphus/evidence/task-1-deps.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `fix(deps): add zod and typescript to package.json`
|
||
- Files: `package.json`, `package-lock.json`
|
||
|
||
- [x] 2. Create crypto random utility with TDD
|
||
|
||
**What to do**:
|
||
- Create `src/lib/client/random.ts` with:
|
||
- `randomInt(min: number, max: number): number`
|
||
- `randomFloat(): number`
|
||
- `randomBytes(length: number): Uint8Array`
|
||
- `shuffleArray<T>(array: T[]): T[]`
|
||
- Create `src/lib/client/random.test.ts` with TDD tests
|
||
|
||
**Must NOT do**:
|
||
- Use `Math.random()` anywhere
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `quick`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 1, 3)
|
||
- **Blocked By**: None
|
||
- **Blocks**: Tasks 4, 5, 6+ (all generators)
|
||
|
||
**References**:
|
||
- `src/components/generators/NumberGenerator.astro` — uses Math.random
|
||
- `src/components/generators/PasswordGenerator.astro` — uses Math.random
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `src/lib/client/random.ts` exists with all 4 functions
|
||
- [ ] `src/lib/client/random.test.ts` passes
|
||
- [ ] No `Math.random()` in module
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: TDD cycle passes
|
||
Tool: Bash
|
||
Steps:
|
||
1. npm run test -- src/lib/client/random.test.ts
|
||
2. grep "Math.random" src/lib/client/random.ts || true
|
||
Expected Result: Tests pass, no Math.random
|
||
Evidence: .sisyphus/evidence/task-2-random.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `feat(lib): add cryptographically secure random utility with tests`
|
||
- Files: `src/lib/client/random.ts`, `src/lib/client/random.test.ts`
|
||
- Pre-commit: `npm run test -- src/lib/client/random.test.ts`
|
||
|
||
- [x] 3. Create client i18n helper with TDD
|
||
|
||
**What to do**:
|
||
- Create `src/lib/client/i18n.ts` with:
|
||
- `getClientLang(): 'en' | 'ru'`
|
||
- `getClientT(): T`
|
||
- Create `src/lib/client/i18n.test.ts`
|
||
|
||
**Must NOT do**:
|
||
- Change `translations.ts` structure
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `quick`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 1, 2)
|
||
- **Blocked By**: None
|
||
- **Blocks**: Tasks 4, 5, 6+
|
||
|
||
**References**:
|
||
- `src/i18n/translations.ts` — translation objects
|
||
- `src/components/generators/NumberGenerator.astro` — shows current `document.documentElement.lang` pattern
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `src/lib/client/i18n.ts` exists
|
||
- [ ] `src/lib/client/i18n.test.ts` passes
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: i18n helper tests pass
|
||
Tool: Bash
|
||
Steps:
|
||
1. npm run test -- src/lib/client/i18n.test.ts
|
||
Expected Result: Tests pass
|
||
Evidence: .sisyphus/evidence/task-3-i18n.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `feat(lib): add client i18n helper with tests`
|
||
- Files: `src/lib/client/i18n.ts`, `src/lib/client/i18n.test.ts`
|
||
|
||
- [x] 4. Create ResultBox.astro shared component
|
||
|
||
**What to do**:
|
||
- Create `src/components/ResultBox.astro` with:
|
||
- `result: string` prop
|
||
- Optional `label?: string` prop
|
||
- Copy button using existing `CopyFeedback`
|
||
- i18n via `useT(Astro.currentLocale)` in frontmatter
|
||
|
||
**Must NOT do**:
|
||
- Reimplement clipboard logic
|
||
- Hardcode English strings
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `visual-engineering`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 2, 3, 5)
|
||
- **Blocked By**: Tasks 2, 3
|
||
- **Blocks**: Tasks 6+
|
||
|
||
**References**:
|
||
- `src/lib/client/clipboard.ts` — `CopyFeedback` class
|
||
- `src/components/generators/NumberGenerator.astro` — result + copy DOM pattern
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `src/components/ResultBox.astro` exists
|
||
- [ ] Uses `CopyFeedback`
|
||
- [ ] `npm run build` succeeds
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: ResultBox renders and copies
|
||
Tool: Playwright
|
||
Preconditions: Dev server running
|
||
Steps:
|
||
1. Create test page with ResultBox result="test123"
|
||
2. Navigate to page
|
||
3. Click copy button
|
||
4. Assert "Copied" appears
|
||
Expected Result: Copy works, i18n labels correct
|
||
Evidence: .sisyphus/evidence/task-4-resultbox.png
|
||
```
|
||
|
||
**Commit**: YES (groups with Task 5)
|
||
|
||
- [x] 5. Create CopyButton.astro shared component
|
||
|
||
**What to do**:
|
||
- Create `src/components/CopyButton.astro` with:
|
||
- `text: string` prop
|
||
- `label?: string` prop
|
||
- Uses `CopyFeedback`
|
||
- i18n via `useT(Astro.currentLocale)`
|
||
|
||
**Must NOT do**:
|
||
- Include result display logic (that's ResultBox)
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `visual-engineering`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 2, 3, 4)
|
||
- **Blocked By**: Tasks 2, 3
|
||
- **Blocks**: Tasks 6+
|
||
|
||
**References**:
|
||
- `src/lib/client/clipboard.ts`
|
||
- `src/components/generators/PasswordGenerator.astro`
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `src/components/CopyButton.astro` exists
|
||
- [ ] Uses `CopyFeedback`
|
||
- [ ] `npm run build` succeeds
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: CopyButton works standalone
|
||
Tool: Playwright
|
||
Steps:
|
||
1. Create test page with CopyButton text="hello"
|
||
2. Click button
|
||
3. Assert "Copied" appears
|
||
Expected Result: Button copies, shows feedback
|
||
Evidence: .sisyphus/evidence/task-5-copybutton.png
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `feat(components): add ResultBox and CopyButton shared components`
|
||
- Files: `src/components/ResultBox.astro`, `src/components/CopyButton.astro`
|
||
|
||
- [x] 6. Refactor CardGenerator.astro
|
||
|
||
**What to do**:
|
||
- Replace `Math.random()` with `random.ts` functions
|
||
- Replace `document.documentElement.lang === "ru"` with `getClientLang()` / `getClientT()`
|
||
- Use `<CopyButton />` or `<ResultBox />` where applicable
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `unspecified-high`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 7-12, 13-19, 20-26, 27-32)
|
||
- **Blocked By**: Tasks 4, 5
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] No `Math.random()` in file
|
||
- [ ] Uses `random.ts` and `i18n.ts`
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: No Math.random in CardGenerator
|
||
Tool: Bash
|
||
Steps:
|
||
1. grep "Math.random" src/components/generators/CardGenerator.astro || true
|
||
Expected Result: Empty output
|
||
Evidence: .sisyphus/evidence/task-6-card.txt
|
||
```
|
||
|
||
**Commit**: NO (groups with batch)
|
||
|
||
- [x] 7. Refactor CoinGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6, 8-12)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: NO
|
||
|
||
- [x] 8. Refactor ColorGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6-7, 9-12)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: NO
|
||
|
||
- [x] 9. Refactor CountryGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6-8, 10-12)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: NO
|
||
|
||
- [x] 10. Refactor DateGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6-9, 11-12)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: NO
|
||
|
||
- [x] 11. Refactor EmojiGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6-10, 12)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: NO
|
||
|
||
- [x] 12. Refactor FontPairGenerator.astro
|
||
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 6-11)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**QA Scenarios**: grep Math.random → empty
|
||
**Commit**: YES
|
||
- Message: `refactor(generators): migrate batch 1 to crypto random (Card, Coin, Color, Country, Date, Emoji, FontPair)`
|
||
- Files: `src/components/generators/{Card,Coin,Color,Country,Date,Emoji,FontPair}Generator.astro`
|
||
|
||
- [x] 13. Refactor GradientGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 14-19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 14. Refactor HashGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13, 15-19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 15. Refactor LetterGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-14, 16-19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 16. Refactor ListGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-15, 17-19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 17. Refactor LoremGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-16, 18-19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 18. Refactor LotteryGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-17, 19, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 19. Refactor Magic8BallGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-18, 20-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: YES
|
||
- Message: `refactor(generators): migrate batch 2 to crypto random (Gradient, Hash, Letter, List, Lorem, Lottery, Magic8Ball)`
|
||
- Files: `src/components/generators/{Gradient,Hash,Letter,List,Lorem,Lottery,Magic8Ball}Generator.astro`
|
||
|
||
- [x] 20. Refactor MealGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 21-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 21. Refactor NamesGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20, 22-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 22. Refactor NumberGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-21, 23-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 23. Refactor PaletteGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-22, 24-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 24. Refactor PasswordGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-23, 25-26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 25. Refactor RpsGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-24, 26, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 26. Refactor ShufflerGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-25, 27-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: YES
|
||
- Message: `refactor(generators): migrate batch 3 to crypto random (Meal, Names, Number, Palette, Password, Rps, Shuffler)`
|
||
- Files: `src/components/generators/{Meal,Names,Number,Palette,Password,Rps,Shuffler}Generator.astro`
|
||
|
||
- [x] 27. Refactor TeamsGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 28-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 28. Refactor TimeGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 27, 29-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 29. Refactor UuidGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 27-28, 30-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 30. Refactor WeightedGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 27-29, 31-32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 31. Refactor WheelSpinner.astro
|
||
**What to do**: Same pattern as Task 6. Note: file is `WheelSpinner.astro`, not `WheelGenerator.astro`.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 27-30, 32)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: NO
|
||
|
||
- [x] 32. Refactor YesNoGenerator.astro
|
||
**What to do**: Same pattern as Task 6.
|
||
**Recommended Agent Profile**: `unspecified-high`
|
||
**Parallelization**: YES (with Tasks 13-19, 20-26, 27-31)
|
||
**Blocked By**: Tasks 4, 5
|
||
**Acceptance Criteria**: No Math.random, uses random.ts and i18n.ts
|
||
**Commit**: YES
|
||
- Message: `refactor(generators): migrate batch 4 to crypto random (Teams, Time, Uuid, Weighted, WheelSpinner, YesNo)`
|
||
- Files: `src/components/generators/{Teams,Time,Uuid,Weighted,YesNo}Generator.astro`, `src/components/generators/WheelSpinner.astro`
|
||
|
||
- [x] 33. Refactor DiceGenerator to import dice-engine.ts
|
||
|
||
**What to do**:
|
||
- Replace inline dice engine code in `DiceGenerator.astro:274-958` with imports from `src/lib/dice-engine.ts`
|
||
- Keep same UI and user-facing behavior
|
||
- Use `getClientLang()` / `getClientT()` for i18n
|
||
- Use `<ResultBox />` / `<CopyButton />` for result display
|
||
|
||
**Must NOT do**:
|
||
- Modify `src/lib/dice-engine.ts` in this task (Task 34 does that)
|
||
- Change dice notation syntax or features
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `deep`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 6-32)
|
||
- **Blocked By**: Tasks 4, 5, 34 (needs dice-engine.ts with crypto)
|
||
|
||
**References**:
|
||
- `src/components/generators/DiceGenerator.astro` — inline dice engine (lines 274-958)
|
||
- `src/lib/dice-engine.ts` — canonical dice engine
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `DiceGenerator.astro` imports from `dice-engine.ts`
|
||
- [ ] File significantly shorter (<300 lines)
|
||
- [ ] `npm run build` succeeds
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: Dice engine imported
|
||
Tool: Bash
|
||
Steps:
|
||
1. grep "import.*dice-engine" src/components/generators/DiceGenerator.astro
|
||
2. wc -l src/components/generators/DiceGenerator.astro
|
||
Expected Result: Import found, file <300 lines
|
||
Evidence: .sisyphus/evidence/task-33-dice-import.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `refactor(dice): deduplicate dice engine by importing from lib`
|
||
- Files: `src/components/generators/DiceGenerator.astro`
|
||
|
||
- [x] 34. Update dice-engine.ts to use crypto random
|
||
|
||
**What to do**:
|
||
- Replace all `Math.random()` in `src/lib/dice-engine.ts` with `random.ts` functions
|
||
- Update `dice-engine.test.ts` to mock `random.ts` instead of `Math.random`
|
||
- Ensure all tests pass
|
||
|
||
**Must NOT do**:
|
||
- Change dice notation syntax or parsing
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `deep`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 4, 5, 37)
|
||
- **Blocked By**: Task 2
|
||
- **Blocks**: Task 33
|
||
|
||
**References**:
|
||
- `src/lib/dice-engine.ts`
|
||
- `src/lib/dice-engine.test.ts`
|
||
- `src/lib/client/random.ts`
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] No `Math.random()` in `dice-engine.ts`
|
||
- [ ] Tests pass
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: Dice engine uses crypto
|
||
Tool: Bash
|
||
Steps:
|
||
1. grep "Math.random" src/lib/dice-engine.ts || true
|
||
2. npm run test -- src/lib/dice-engine.test.ts
|
||
Expected Result: No Math.random, tests pass
|
||
Evidence: .sisyphus/evidence/task-34-dice-crypto.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `refactor(dice): migrate dice engine to cryptographically secure random`
|
||
- Files: `src/lib/dice-engine.ts`, `src/lib/dice-engine.test.ts`
|
||
- Pre-commit: `npm run test -- src/lib/dice-engine.test.ts`
|
||
|
||
- [x] 35. Update Privacy Policy translations
|
||
|
||
**What to do**:
|
||
- Update EN and RU `aboutHowItWorks` text in `src/i18n/translations.ts` to accurately describe random generation
|
||
- Current RU text (line ~172) claims "Web Crypto API" but must reflect actual usage
|
||
- Also update EN equivalent (line ~78)
|
||
|
||
**Must NOT do**:
|
||
- Change other Privacy Policy sections
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `writing`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 1, 2, 3, 36)
|
||
- **Blocked By**: None
|
||
|
||
**References**:
|
||
- `src/i18n/translations.ts` — EN aboutHowItWorks (~line 78), RU aboutHowItWorks (~line 172)
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] EN aboutHowItWorks accurate
|
||
- [ ] RU aboutHowItWorks accurate and consistent
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: Privacy text updated
|
||
Tool: Read
|
||
Steps:
|
||
1. Read src/i18n/translations.ts lines 72-82 and 166-176
|
||
Expected Result: Text describes crypto.getRandomValues usage
|
||
Evidence: .sisyphus/evidence/task-35-privacy.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `fix(i18n): update about page for crypto accuracy`
|
||
- Files: `src/i18n/translations.ts`
|
||
|
||
- [x] 36. Fix deploy.yml quality gates
|
||
|
||
**What to do**:
|
||
- Add `npm run lint` before `npm run build`
|
||
- Add `npm run test` before `npm run build`
|
||
- Remove `-o StrictHostKeyChecking=no` from rsync SSH options
|
||
|
||
**Must NOT do**:
|
||
- Change deploy target or SSH keys
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `quick`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 1, 2, 3, 35)
|
||
- **Blocked By**: None
|
||
- **Blocks**: Task 37
|
||
|
||
**References**:
|
||
- `.github/workflows/deploy.yml`
|
||
- `package.json` — test and lint scripts
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] `npm run lint` runs before build
|
||
- [ ] `npm run test` runs before build
|
||
- [ ] No `StrictHostKeyChecking=no`
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: CI updated
|
||
Tool: Read
|
||
Steps:
|
||
1. grep "npm run lint" .github/workflows/deploy.yml
|
||
2. grep "npm run test" .github/workflows/deploy.yml
|
||
3. grep "StrictHostKeyChecking" .github/workflows/deploy.yml || true
|
||
Expected Result: lint and test found, StrictHostKeyChecking absent
|
||
Evidence: .sisyphus/evidence/task-36-ci.txt
|
||
```
|
||
|
||
**Commit**: YES
|
||
- Message: `ci(deploy): add test and lint gates, fix SSH security`
|
||
- Files: `.github/workflows/deploy.yml`
|
||
|
||
- [x] 37. Verify CI blocks deploy on failure
|
||
|
||
**What to do**:
|
||
- Verify updated `deploy.yml` workflow syntax
|
||
- Confirm deploy does not run if test/lint fails
|
||
|
||
**Must NOT do**:
|
||
- Trigger actual deploy
|
||
|
||
**Recommended Agent Profile**:
|
||
- **Category**: `quick`
|
||
|
||
**Parallelization**:
|
||
- **Can Run In Parallel**: YES (with Tasks 4, 5, 34)
|
||
- **Blocked By**: Task 36
|
||
|
||
**References**:
|
||
- `.github/workflows/deploy.yml`
|
||
|
||
**Acceptance Criteria**:
|
||
- [ ] Workflow syntax valid
|
||
- [ ] Build step after test/lint
|
||
|
||
**QA Scenarios**:
|
||
```
|
||
Scenario: CI dependencies verified
|
||
Tool: Bash
|
||
Steps:
|
||
1. grep -A5 "npm run test" .github/workflows/deploy.yml
|
||
Expected Result: Build comes after test
|
||
Evidence: .sisyphus/evidence/task-37-ci-verify.txt
|
||
```
|
||
|
||
**Commit**: NO (groups with Task 36)
|
||
|
||
---
|
||
|
||
## Final Verification Wave
|
||
|
||
> 4 review agents run in PARALLEL. ALL must APPROVE. Present consolidated results to user and get explicit "okay" before completing.
|
||
|
||
- [x] F1. **Plan Compliance Audit** — `oracle`
|
||
Read the plan end-to-end. For each "Must Have": verify implementation exists. For each "Must NOT Have": search codebase for forbidden patterns — reject with file:line if found. Check evidence files exist. Compare deliverables against plan.
|
||
Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`
|
||
|
||
- [x] F2. **Code Quality Review** — `unspecified-high`
|
||
Run `tsc --noEmit` + `eslint .` + `vitest run`. Review all changed files for: `as any`/`@ts-ignore`, empty catches, console.log in prod, commented-out code, unused imports. Check AI slop: excessive comments, over-abstraction, generic names.
|
||
Output: `Build [PASS/FAIL] | Lint [PASS/FAIL] | Tests [N pass/N fail] | Files [N clean/N issues] | VERDICT`
|
||
|
||
- [x] F3. **Real Manual QA** — `unspecified-high`
|
||
Start from clean state. Execute EVERY QA scenario from EVERY task. Test cross-task integration. Test edge cases: empty state, invalid input. Verify no Math.random() remains (`grep -r "Math.random" src/components/generators/`). Save to `.sisyphus/evidence/final-qa/`.
|
||
Output: `Scenarios [N/N pass] | Integration [N/N] | Math.random [CLEAN/N found] | VERDICT`
|
||
|
||
- [x] F4. **Scope Fidelity Check** — `deep`
|
||
For each task: read "What to do", read actual diff (git log/diff). Verify 1:1 — everything in spec was built, nothing beyond spec was built. Check "Must NOT do" compliance. Detect cross-task contamination. Flag unaccounted changes.
|
||
Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | Unaccounted [CLEAN/N files] | VERDICT`
|
||
|
||
---
|
||
|
||
## Commit Strategy
|
||
|
||
- **Wave 1**: `fix(deps): add zod and typescript to package.json` + `feat(lib): add crypto random utility with tests` + `feat(lib): add client i18n helper with tests` + `fix(i18n): update privacy policy for crypto accuracy` + `ci(deploy): add test and lint gates to deploy workflow`
|
||
- **Wave 2**: `feat(components): add ResultBox and CopyButton shared components` + `refactor(dice): migrate dice engine to cryptographically secure random`
|
||
- **Waves 3-6**: `refactor(generators): migrate batch N to crypto random and shared components`
|
||
|
||
---
|
||
|
||
## Success Criteria
|
||
|
||
### Verification Commands
|
||
```bash
|
||
npm run test # Expected: all pass (utilities + existing dice tests)
|
||
npm run lint # Expected: no errors
|
||
npm run build # Expected: static build succeeds
|
||
grep -r "Math.random" src/components/generators/ # Expected: no matches
|
||
grep -r "dice-engine" src/components/generators/DiceGenerator.astro # Expected: import statement
|
||
grep "zod" package.json # Expected: found in dependencies
|
||
grep "test" .github/workflows/deploy.yml # Expected: found
|
||
```
|
||
|
||
### Final Checklist
|
||
- [ ] All "Must Have" present
|
||
- [ ] All "Must NOT Have" absent
|
||
- [ ] All tests pass
|
||
- [ ] No `Math.random()` in generators
|
||
- [ ] Dice engine imported, not inlined
|
||
- [ ] CI runs tests and lint before deploy
|
||
- [ ] User explicitly approved (no auto-push to main)
|