Skip to content

feat: durable preferred-weekdays setting the coach honors by default#87

Merged
cipher813 merged 1 commit into
mainfrom
feat/preferred-training-days
Jul 8, 2026
Merged

feat: durable preferred-weekdays setting the coach honors by default#87
cipher813 merged 1 commit into
mainfrom
feat/preferred-training-days

Conversation

@cipher813

Copy link
Copy Markdown
Contributor

Summary

Ran the coach with "2x/week weightlifting" — it honored the frequency but picked its own days, ignoring the standing Mon/Thu preference, because there was nowhere durable to store it and it had to be re-stated every conversation.

  • New Settings field preferred_weekdays (structured, Weekday[]) — a Settings-level durable preference rather than a Constraint (constraints are framed as "bounds the coach trains AROUND"; this is a positive scheduling input, closer to weight_unit's existing shape: one global preference, set once, read every generation).
  • UserSettings.preferred_weekdays (JSON column, migration b3c4d5e6f7a8, single-head chain verified + a real alembic upgrade head run against a scratch SQLite DB).
  • Threaded through MaterializeContext_context_block's CONTEXT payload, included only when non-empty (mirrors the weight_unit precedent).
  • Prompt rule (public baseline — this is what prod actually runs; the tuned vires-ops prompt currently falls back to baseline too, see its README): explicit day(s) in the user's message still win; otherwise default to preferred_weekdays; otherwise pick sensible evenly-spaced days as before.
  • Settings UI: new "Training schedule" card, day-of-week multi-select chips (mirrors the weight-unit segmented-button style).

Test plan

  • uv run pytest — full backend suite green (added: settings defaults/update/validation, coach-context payload inclusion/omission)
  • uv run ruff check . — clean
  • alembic upgrade head run from scratch against a throwaway SQLite DB — single migration chain resolves cleanly, preferred_weekdays lands as JSON NOT NULL DEFAULT '[]'
  • npx vitest run (web) — 146/146 passing (added: set + save, toggle-off)
  • npx oxlint — no new warnings
  • npx tsc -b + npm run build — clean

Brian ran the AI coach with a "2x/week weightlifting" request; it honored
the frequency but picked days on its own, ignoring his standing Mon/Thu
preference — because there was nowhere durable to store it, so it had to
be re-stated in every conversation.

Adds a structured Settings field (Constraints was a semantic mismatch —
the codebase's own framing is "bounds the coach trains AROUND", not a
positive scheduling input) modeled the same way weight_unit already is:
one durable global preference, set once, read on every generation.

- UserSettings.preferred_weekdays (JSON list, migration b3c4d5e6f7a8)
- SettingsOut/SettingsUpdate + reuse the Weekday literal from coach schemas
- Threaded through MaterializeContext -> _context_block's CONTEXT payload
  (mirrors the existing weight_unit precedent), included only when non-empty
- Prompt rule: explicit day(s) in the request still win; otherwise default
  to preferred_weekdays; otherwise pick sensible evenly-spaced days as before
- Settings UI: a day-of-week multi-select ("Training schedule" card)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cipher813 cipher813 merged commit e8a66f9 into main Jul 8, 2026
3 checks passed
@cipher813 cipher813 deleted the feat/preferred-training-days branch July 8, 2026 19:08
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.

1 participant