Wire the composed surface: the honest fields now reach a user
PHASE 0 re-check caught the same failure a THIRD time, mine again. Last
turn I created GradeScaleLegend.tsx and never mounted it, and I reported
that the separation flag "renders per band" -- it did not. grep: zero
frontend references to separates_from_base_rate, served_grade or
factor_adjustment. The honest grade was reaching the API payload and dying
at the adapter boundary.
That is three occurrences in three orders of the same shape: built,
correct, unread. gradeBands, then served_grade, then the legend.
PHASE 2 — the composed surface is wired end to end:
analyzeViaEngine1 -> served_grade + factor_adjustment on the payload
scan/page.tsx -> ScanResponse types them and forwards them
gradeAdapter -> gradeMeaning, separatesFromBaseRate,
bandRealizedRate, factorsApplied, refusalReason
GradeResultCard -> renders "WHAT THIS GRADE MEANS"
What a user now sees that they could not before: what the band has
actually realized, an amber note when the read CANNOT be separated from
the baseline, and -- only where a factor actually fired, with its proven
sign -- what moved the read, in plain language rather than feature names
("where he hits it vs who is standing there").
No narrative on props where nothing fired: factorsApplied is empty and the
block self-hides. Only the three PROVEN hits factors have labels, so an
unproven factor cannot acquire prose by being added to the map.
PHASE 1 — GradeScaleLegend is now MOUNTED on the grade card (compact). The
ceiling is a stated position where the grade is, not a page a user would
have to find.
PHASE 3 hand-verified through the real adapter across twelve states: B+
with 3/0 factors, B with 1, C+/C/C- all flagged not-separable, D, F, a
switch-hitter case where 2 of 3 factors fire, two refusals and a
no-forecast. never-blank PASS, no-manufactured-A PASS, no-narrative-when-
nothing-fired PASS, separation-flag-reaches-card PASS.
No A-threshold loosening. No calibrated number leaks. p_win never mutated.
engine_grade still read by zero serving code. No Bonferroni slot.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
This commit is contained in:
@@ -86,6 +86,27 @@ function mapScanToGradeResult(input = {}) {
|
||||
side,
|
||||
grade: input.grade || '—',
|
||||
confidence,
|
||||
// ── THE HONEST GRADE FIELDS ────────────────────────────────────────────
|
||||
// The served grade knows whether its band can actually be separated from
|
||||
// the baseline, and which proven factors (if any) moved the forecast. Both
|
||||
// were being computed and thrown away at this boundary. A grade that cannot
|
||||
// separate must SAY so on the card -- that flag is the honest core, and
|
||||
// carrying it in an object nobody reads is the same as not having it.
|
||||
gradeMeaning: (input.served_grade && input.served_grade.meaning) || null,
|
||||
separatesFromBaseRate: input.served_grade
|
||||
? input.served_grade.separates_from_base_rate === true : null,
|
||||
bandRealizedRate: (input.served_grade && input.served_grade.band_realized_rate) ?? null,
|
||||
// Only factors that ACTUALLY fired, with their proven sign. No narrative on
|
||||
// props where nothing fired.
|
||||
factorsApplied: (input.factor_adjustment && Array.isArray(input.factor_adjustment.applied))
|
||||
? input.factor_adjustment.applied.map((a) => ({
|
||||
factor: a.factor,
|
||||
direction: a.multiplier > 1 ? 'up' : 'down',
|
||||
multiplier: a.multiplier,
|
||||
}))
|
||||
: [],
|
||||
refusalReason: (input.served_grade && input.served_grade.state !== 'graded')
|
||||
? input.served_grade.meaning : null,
|
||||
// DATA SEMANTICS (Session 58): projection is MODEL output and must never
|
||||
// be fabricated. The old fallback displayed the LINE as the projection —
|
||||
// the audit's model==line / +0% edge degenerate. No projection → the
|
||||
|
||||
Reference in New Issue
Block a user