feat(daily): ship daily detection off, and say it's experimental
Dailiness is guessed from the source's wording, which is a weak signal and wrong in both directions. Guessing on a reader's behalf and hoping they notice is the wrong default for a checklist they may build a streak on, so `detectDaily` now starts false and the control carries an Experimental tag saying what it does and doesn't know. The default applies to new readers only — a stored `prefs` keeps its value, because switching it off under someone who has been ticking auto-detected checklists would pull those chips out of the strip with no explanation. Nothing is deleted either way. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3a70672d22
commit
3434ac02cf
@@ -211,9 +211,12 @@ event's length. It adds **no schema field**, so the feed contract is untouched.
|
|||||||
- **A repeating event the reader marked done leaves the strip.** They have said there is nothing
|
- **A repeating event the reader marked done leaves the strip.** They have said there is nothing
|
||||||
left to do; keeping a tickable chip for it is the app arguing with them. Their logged days are
|
left to do; keeping a tickable chip for it is the app arguing with them. Their logged days are
|
||||||
untouched, so unmarking it brings the chip and the streak straight back.
|
untouched, so unmarking it brings the chip and the streak straight back.
|
||||||
- **Detection is a default, not a verdict.** The reader can mark any event as repeating, or unmark
|
- **Detection is a guess, not a verdict — and it ships off.** `prefs.detectDaily` defaults to
|
||||||
one detection got wrong (`progress.daily`, resolved by `resolveDaily`), and `prefs.detectDaily`
|
`false` and the control is labelled experimental: wording is a weak signal and gets it wrong in
|
||||||
switches the guessing off entirely. Store an override only when it *disagrees* with detection —
|
both directions, so a new reader opts in rather than out. The default moves nothing for an
|
||||||
|
existing reader, whose stored `prefs` wins. The reader can mark any event as repeating, or unmark
|
||||||
|
one detection got wrong (`progress.daily`, resolved by `resolveDaily`), whether the guessing is
|
||||||
|
on or off. Store an override only when it *disagrees* with detection —
|
||||||
recording agreement would freeze today's guess and stop a better parser from ever reaching that
|
recording agreement would freeze today's guess and stop a better parser from ever reaching that
|
||||||
event. Neither control ever deletes a mark or a logged day, so both are reversible.
|
event. Neither control ever deletes a mark or a logged day, so both are reversible.
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -293,7 +293,14 @@ It adds no schema field, so nothing about the feed contract or the event ID chan
|
|||||||
for one event and wins outright (`resolveDaily`); absent means they have not said, so detection
|
for one event and wins outright (`resolveDaily`); absent means they have not said, so detection
|
||||||
stands. `prefs.detectDaily` switches the guessing off altogether, leaving only events they marked
|
stands. `prefs.detectDaily` switches the guessing off altogether, leaving only events they marked
|
||||||
themselves — it silences detection rather than deleting anything, so every mark and every logged day
|
themselves — it silences detection rather than deleting anything, so every mark and every logged day
|
||||||
survives and switching it back on restores exactly what was there. An override that merely
|
survives and switching it back on restores exactly what was there.
|
||||||
|
|
||||||
|
**Detection is off by default and labelled experimental in the UI.** Wording is a weak signal and it
|
||||||
|
is wrong in both directions, so a new reader starts with only the standing `dailies:<game>` chores
|
||||||
|
and whatever they mark themselves; opting in is one checkbox. The default applies to new readers
|
||||||
|
only — a stored `prefs` keeps whatever value it has, because turning it off under a reader who has
|
||||||
|
been ticking auto-detected checklists would pull those chips out of the strip with no explanation.
|
||||||
|
An override that merely
|
||||||
agrees with detection is **not stored** (`dailyOverride`) — freezing today's guess into their data
|
agrees with detection is **not stored** (`dailyOverride`) — freezing today's guess into their data
|
||||||
would stop a later parser improvement from ever reaching that event. This is the only field in
|
would stop a later parser improvement from ever reaching that event. This is the only field in
|
||||||
`progress` that changes what the app *shows* rather than recording what the reader did, which is
|
`progress` that changes what the app *shows* rather than recording what the reader did, which is
|
||||||
|
|||||||
@@ -87,9 +87,9 @@ export function Controls({
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
{/* Detection reads the source's wording and is wrong in both
|
{/* Detection reads the source's wording and is wrong in both
|
||||||
directions. Off leaves only the events the reader marked, and
|
directions, so it ships off and says so. Off leaves only the
|
||||||
discards nothing — every mark and logged day survives, so it can
|
events the reader marked, and discards nothing — every mark and
|
||||||
be switched back on. */}
|
logged day survives, so it can be switched back on. */}
|
||||||
<label className="flex cursor-pointer select-none items-start gap-2 text-xs text-muted">
|
<label className="flex cursor-pointer select-none items-start gap-2 text-xs text-muted">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -99,9 +99,13 @@ export function Controls({
|
|||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
Spot daily events automatically
|
Spot daily events automatically
|
||||||
|
<span className="ml-1.5 rounded-full border border-hairline px-1.5 py-0.5 align-[1px] text-[0.5625rem] font-medium uppercase tracking-wider text-faint">
|
||||||
|
Experimental
|
||||||
|
</span>
|
||||||
<span className="mt-0.5 block max-w-xs leading-relaxed text-faint">
|
<span className="mt-0.5 block max-w-xs leading-relaxed text-faint">
|
||||||
Off, only events you mark yourself get a checklist. Your ticks
|
Guessed from what the source wrote, so it misses some and
|
||||||
and streaks are kept either way.
|
invents others. Off, only events you mark yourself get a
|
||||||
|
checklist. Your ticks and streaks are kept either way.
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ export interface Prefs {
|
|||||||
* Whether to guess which events repeat daily from what the source printed.
|
* Whether to guess which events repeat daily from what the source printed.
|
||||||
* Off leaves only the ones the reader marked themselves; it never discards a
|
* Off leaves only the ones the reader marked themselves; it never discards a
|
||||||
* mark or a logged day, so it is reversible.
|
* mark or a logged day, so it is reversible.
|
||||||
|
*
|
||||||
|
* Off by default: the guess reads source wording and is wrong in both
|
||||||
|
* directions, so a reader starts with only the dailies they chose. Readers
|
||||||
|
* who already switched it on keep it — stored prefs win over this default.
|
||||||
*/
|
*/
|
||||||
detectDaily: boolean;
|
detectDaily: boolean;
|
||||||
showCompleted: boolean;
|
showCompleted: boolean;
|
||||||
@@ -40,7 +44,7 @@ function defaults(): Prefs {
|
|||||||
hiddenGames: [],
|
hiddenGames: [],
|
||||||
focusGame: null,
|
focusGame: null,
|
||||||
sort: "ending",
|
sort: "ending",
|
||||||
detectDaily: true,
|
detectDaily: false,
|
||||||
showCompleted: true,
|
showCompleted: true,
|
||||||
showIgnored: false,
|
showIgnored: false,
|
||||||
regionConfirmed: false,
|
regionConfirmed: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user