feat: durable preferred-weekdays setting the coach honors by default#87
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
Settingsfieldpreferred_weekdays(structured,Weekday[]) — aSettings-level durable preference rather than aConstraint(constraints are framed as "bounds the coach trains AROUND"; this is a positive scheduling input, closer toweight_unit's existing shape: one global preference, set once, read every generation).UserSettings.preferred_weekdays(JSON column, migrationb3c4d5e6f7a8, single-head chain verified + a realalembic upgrade headrun against a scratch SQLite DB).MaterializeContext→_context_block's CONTEXT payload, included only when non-empty (mirrors theweight_unitprecedent).vires-opsprompt currently falls back to baseline too, see its README): explicit day(s) in the user's message still win; otherwise default topreferred_weekdays; otherwise pick sensible evenly-spaced days as before.Test plan
uv run pytest— full backend suite green (added: settings defaults/update/validation, coach-context payload inclusion/omission)uv run ruff check .— cleanalembic upgrade headrun from scratch against a throwaway SQLite DB — single migration chain resolves cleanly,preferred_weekdayslands asJSON NOT NULL DEFAULT '[]'npx vitest run(web) — 146/146 passing (added: set + save, toggle-off)npx oxlint— no new warningsnpx tsc -b+npm run build— clean