Skip to content

feat(practice): add an explicit month-anchor step to Guided Solve (#10) - #30

Merged
tsenoner merged 3 commits into
mainfrom
fix/10-guided-month-anchor
Jun 23, 2026
Merged

feat(practice): add an explicit month-anchor step to Guided Solve (#10)#30
tsenoner merged 3 commits into
mainfrom
fix/10-guided-month-anchor

Conversation

@tsenoner

Copy link
Copy Markdown
Owner

Closes #10. Roadmap item 6/7 (the heaviest).

Guided Solve teaches a four-part method but only asked three picks — the month anchor (the linchpin from Learn Stage 3) was never checked; it surfaced only as a read-only StepTrace row. This adds a fourth step asking for the anchor's day-of-month (a number), between the year's doomsday and the final weekday.

Changes

  • useGuided — 5-state machine: 0 century → 1 yearDoom → 2 monthAnchor(number) → 3 final → 4 graded. New pickAnchor(n) for the number step; pick(w) handles the weekday steps.
  • drill.ts / db.tsGuidedAnswers.monthAnchorDay; Attempt.monthAnchorCorrect: 0 | 1 | null. gradeGuided grades it against trace.monthAnchorDay independently — no cascade: a wrong anchor never changes the final weekday grade (still absolute g.final === t.result). The three non-guided grade helpers backfill null; ~10 fixtures updated.
  • GuidedSolve — renders a NumberPad (reusing ANCHOR_DAYS) at step 2; adds a 4th summary row; per-step chime/haptic fires for the anchor too; graded === step 4.
  • stats.ts — surfaces the new dimension in the Progress step breakdown ("Month anchor"), so a step the user can now get wrong actually appears in their weakness rows (caught by the diff review as the one loose end).

Design notes (for review)

  • Ask for the date, not the weekday — the anchor's weekday is the year's doomsday already picked (monthAnchorWeekday === yearDoomsday), so a weekday re-pick would just re-ask the prior answer.
  • No leap-year hint — for leap years the answer shifts (Jan/Feb), and withholding the hint keeps it a genuine test of Stage 2 + Stage 3 mastery. Easy to add a hint if you'd prefer a gentler step.
  • The issue's "keep end-only vs per-step feedback" question is moot — PR Guided Solve: flag each intermediate step the moment it's answered #16 already made Guided per-step, so the new step gets immediate ✓/✕ like the others.

Verification

typecheck ✓ · lint --max-warnings 0 ✓ · 295 tests ✓ · build ✓. Tests: independent/no-cascade grading (drill.test.ts), the 4-step flow incl. the NumberPad (GuidedSolve.test.tsx), and a direct 5-step useGuided machine test. Adversarial review of the diff surfaced 0 Critical/Important (3 Minor, all fixed in this PR).

🤖 Generated with Claude Code

Guided Solve taught a four-part method but only asked three picks — the month
anchor (the linchpin from Learn Stage 3) was never checked, surfacing only as a
read-only StepTrace row. Add a fourth step that asks for the anchor's
day-of-month (a number), between the year's doomsday and the final weekday.

- useGuided: 5-state machine (century → yearDoom → monthAnchor(number) → final →
  graded); new pickAnchor() for the number step (pick() handles the weekday steps).
- drill.ts/db.ts: GuidedAnswers.monthAnchorDay; Attempt.monthAnchorCorrect (0|1|null);
  gradeGuided grades it against trace.monthAnchorDay INDEPENDENTLY — a wrong anchor
  never cascades into the final weekday grade (still absolute g.final === t.result).
  The three non-guided grade helpers backfill null; ~10 fixtures updated.
- GuidedSolve: NumberPad (ANCHOR_DAYS) for the anchor step; a 4th summary row;
  per-step chime/haptic fires for the anchor too; graded === step 4.
- stats.ts: surface the new dimension in the Progress step breakdown ("Month anchor").

We ask for the anchor DATE, not its weekday — the anchor's weekday IS the year's
doomsday already picked (monthAnchorWeekday === yearDoomsday), so a weekday re-pick
would be redundant. No leap-year hint, so it stays a genuine Stage 2+3 check.

Tests: drill.test.ts (independent grading, no cascade); GuidedSolve.test.tsx (4-step
flow incl. the NumberPad); a direct useGuided step-machine test. 295 tests, typecheck,
lint, build all green. Adversarial review of the diff: 0 Critical/Important.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daycipher Ready Ready Preview, Comment Jun 23, 2026 4:27pm

tsenoner and others added 2 commits June 23, 2026 18:05
Cleanup from /simplify + /code-review on the Guided month-anchor step:
- Add a shared ordinal() helper (format.ts) and use it for the
  month-anchor row — fixes "the 3th" (a January common-year anchor is
  day 3, so the row literally rendered "the 3th ✓").
- Make PickRow generic so the three weekday rows pass weekdayName
  directly, dropping the wd wrapper and its `as Weekday` cast and
  restoring compile-time Weekday typing the diff had widened away.

typecheck ✓ · lint --max-warnings 0 ✓ · tests ✓

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to the new ordinal() helper: the inline `${n}th` template in
StepTrace and the three workedExample step lines had the same grammar bug
the Guided row did. Worst case was workedExample's `The ${day}th`, where
day is any 1–31, so it rendered "The 1th / 21th / 31th"; StepTrace showed
"the 3th" for January common years. All now use ordinal(), so the helper
has zero remaining inline copies.

typecheck ✓ · lint --max-warnings 0 ✓ · 296 tests ✓

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tsenoner
tsenoner merged commit 1e8d4d4 into main Jun 23, 2026
3 checks passed
@tsenoner
tsenoner deleted the fix/10-guided-month-anchor branch June 23, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Guided Solve: add an explicit month-anchor step before the final weekday

1 participant