Delete the mascot's points-earned pose, which stated a payout - #220
Merged
Conversation
…212) #16 ruled the mascot's hardcoded `'+15 XP'` particle dropped — "it goes with the toast" — because it matched no rule in the app. #160's vocabulary sweep rewrote it to `'+10 PTS'` and kept it, fixing the word and leaving the defect. A lesson pays what it authors, so no constant here can be right. Deleted rather than parameterized. The pose was unreachable — `CompanionReaction.xpGained` was fired by nothing, so `RoastyState.xp` was too — and the lesson result screen already plays its own celebration, which makes wiring a second one a decision about what it displaces rather than a cleanup. A points moment, if ever wanted, gets authored against a screen chosen for it and reads the real payout. Gone whole: the reaction, the mascot state, the particle burst, the face, the animation timings, and the two imports that had no other user. Every switch stayed exhaustive on its own — no `default` arm was added to hide the removal. Tests were narrowed to the eight surviving states rather than deleted, since they assert over the whole enum. A guard fails if any companion source states a points amount again, in either vocabulary and with or without a sign. It reads string literals only, so a comment explaining the rule is not mistaken for breaking it. Both source-scanning guards now share one walker. The three genuinely unwired reactions — correct, wrong, cardEarned — are untouched and split out to #219; §5.1 asks for the first two by name.
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.
Closes #212.
Implements a disposition of #16 that #160 was built to carry out, and missed.
What was wrong
#16's disposition table:
'+15 XP'inroasty_particles.dart#160's vocabulary sweep rewrote it to
'+10 PTS'and kept it — fixing the word and leaving the defect. A lesson pays what it authors, so no constant there can be right. Ten was no more read from a rule than fifteen was.The linter could never have caught it: the particles file is excluded from
no-magic-number, and that exclusion is justified for coordinates.Why deleted, not parameterized
The design does parameterize this burst (
roasty.jsx:575renders+{pointsAmount} PTS), so "pass the real payout in" looked like the faithful option. Triage rejected it on two facts:CompanionReaction.xpGainedis fired by nothing, soRoastyState.xpis too. Nothing has ever rendered it, and no test would have caught a wrong number in it.lessonComplete, and §5.1 puts points on that same screen. Wiring a second celebration there is a decision about what it displaces — scope this ticket has no business carrying.A points moment, if ever wanted, gets authored against a screen chosen for it and reads the real payout.
What went
The reaction, the mascot state, the particle burst, the face painter, the animation timings, and the two imports left with no other user. −85/+23.
Every
switchstayed exhaustive on its own — nodefaultarm was added to hide the removal, which is the easy way to turn a compiler error into a silent one. The two pre-existingignore_for_file: no_default_casesheaders are untouched.Tests were narrowed, not deleted: they assert over all nine mascot states, so removing them would have dropped coverage of the eight that survive.
The guard
A test fails if any companion source states a points amount again — either vocabulary, signed or not. Proven to fail, not just asserted to:
It reads string literals only, so a comment explaining the rule isn't mistaken for breaking it, and it is scoped to the companion layer —
+10 PTSis correct on the result screen, which reads the real payout. The rule is that painted mascot art states no amount, not that the string is banned app-wide.Both source-scanning guards (this one and the points vocabulary sweep) now share one walker in
test/support/.Verification
dart analyzeclean acrosslib,test,integration_testdart run dart_code_linter:metrics analyze libcleanReviewed on both axes. Spec: full pass on every acceptance criterion. Standards: five findings, none hard, four fixed in-branch — the shared walker, changelog section order, the two guard weaknesses above, and a redundant doc comment.
Out of scope
The three genuinely unwired reactions.
correct,wrongandcardEarnedare also fired from nowhere — and §5.1 asks for the first two by name: "Mid-lesson correct answers show no points toast — feedback is purely qualitative (Roasty reacts)." #160 deleted the toast and never wired its replacement, which was correctly outside its scope. That gap is #219, and deleting all three is a legitimate answer there. Untouched here beyond a doc pointer.docs/plans/extract-roasty-companion.mdstill names the deleted value. Left alone: the doc map classesdocs/plans/as "snapshots, not authority", and it is banner-marked complete.