Session 7e: Grade adapter, normalize consolidation, ARCH-2 banners
This commit is contained in:
+48
-20
@@ -411,24 +411,50 @@ No circular imports detected.
|
||||
### ARCH — Architecture
|
||||
|
||||
- **[ARCH-1] Dual grading paths.** Severity: Medium. Status:
|
||||
**DEFERRED in Session 7d** — the legacy `propAnalyzer → grader →
|
||||
UnifiedOddsProvider` chain returns a 4-letter grade + 0-100
|
||||
confidence + kill-conditions + reasoning.steps shape; the new
|
||||
`engine1` returns an 11-step grade + 0-1 confidence + factors. Both
|
||||
shapes are consumed by different surfaces (GradeCard + DemoScan vs
|
||||
the orchestrator's grade_history writer). Unification requires
|
||||
frontend + backend coordination — out of scope for the audit-fix
|
||||
session. Migration plan: (1) decide which shape the UI keeps; (2)
|
||||
write an adapter from the other shape; (3) rewire one route at a
|
||||
time, starting with `/api/analyze/prop`. Session 7d added a
|
||||
DEPRECATED banner to `src/services/grader.js` to signal that new
|
||||
features should land in engine1.js.
|
||||
**PARTIAL in Session 7e** — Step 1 of the migration (the adapter)
|
||||
is complete and tested. Steps 2-6 deferred per ESCAPE HATCH.
|
||||
Step 1 ✓ — `src/utils/gradeAdapter.js` translates engine1 output
|
||||
into the legacy shape `DemoScan` reads. 26 unit
|
||||
tests covering grade collapse, confidence math,
|
||||
kill-condition mapping, reasoning fallback, partial
|
||||
input safety.
|
||||
Step 2-6 deferred — legacy `analyzeProp` and `engine1.gradeProp()`
|
||||
have incompatible INPUT contracts: the legacy
|
||||
analyzer takes a raw prop and self-fetches data
|
||||
(odds, stats, opponent, spread, kill conditions);
|
||||
engine1 takes a pre-computed feature vector and is
|
||||
a pure grading function. To rewire any route to
|
||||
engine1 we'd first need to extract an
|
||||
orchestrator-lite preprocessor — that's the kind
|
||||
of architectural change 7c/7d's no-restructure
|
||||
rule blocks. The reasoning.summary string-level
|
||||
parity is also currently lost (concrete numbers
|
||||
in legacy vs abstract factor labels in engine1).
|
||||
Migration roadmap (now actionable for the next session):
|
||||
(a) Extract `gradingOrchestrator.gradeProp()` into a standalone
|
||||
`computeFeaturesForProp({player, stat_type, line, direction})`
|
||||
that lifts the player-roster + feature-fetch + trap-detect +
|
||||
consistency-score logic into a reusable callable.
|
||||
(b) Wrap engine1 + gradeAdapter behind a thin
|
||||
`analyzeViaEngine1(prop)` helper.
|
||||
(c) Rewire one route at a time — `/api/analyze/prop` first
|
||||
(lowest risk: single prop, public, well-tested), then
|
||||
`/api/analyze/batch`, then `/api/scan/parlay`, then
|
||||
`/api/bets/*`.
|
||||
(d) Remove `grader.js` + `propAnalyzer.js` + the legacy book
|
||||
adapters only after every consumer has migrated and a soak
|
||||
period.
|
||||
Session 7d's DEPRECATED banner on `src/services/grader.js` stays
|
||||
put.
|
||||
|
||||
- **[ARCH-2] Two circuit-breaker / rate-limiter modules.** Severity:
|
||||
Low (documented in 6a). `src/services/{circuitBreaker.js,
|
||||
rateLimiter.js}` (keyed registry, legacy) coexist with
|
||||
`src/utils/rateLimiter.js` (factory, new). Consolidation is purely
|
||||
cosmetic — both work. Scope: half-session. Status: open.
|
||||
Low. Status: **DOCUMENTED in Session 7e.** Both legacy modules now
|
||||
carry banners listing their three callers:
|
||||
- `src/services/UnifiedOddsProvider.js`
|
||||
- `src/services/adapters/ESPNAdapter.js`
|
||||
- `src/services/adapters/PinnacleAdapter.js`
|
||||
Full removal blocks on ARCH-1 Step 6 — the legacy book adapters
|
||||
retire together with the legacy grading path.
|
||||
|
||||
### SEC — Security
|
||||
|
||||
@@ -466,10 +492,12 @@ No circular imports detected.
|
||||
### DUP — Duplicates
|
||||
|
||||
- **[DUP-1] `normalizeName()` exists twice.** Severity: Low. Status:
|
||||
**DOCUMENTED in Session 7d.** Both implementations now carry
|
||||
cross-reference comments explaining the divergence (script keeps
|
||||
digits for legacy roster fields; trap detector strips them). Full
|
||||
consolidation deferred until the script can drop its digit support.
|
||||
**FIXED in Session 7e.** Consolidated into `src/utils/normalize.js`
|
||||
with a `keepDigits` option (default false). `trapDetection.js`
|
||||
imports the default; `scripts/populate-player-ids.js` wraps with
|
||||
`keepDigits: true` via `normalizeRosterName`. 9 unit tests cover
|
||||
accent strip, suffix removal, digit options, idempotency, null
|
||||
input.
|
||||
|
||||
- **[DUP-2] `oddsToImplied` etc. only live in `src/utils/odds.js`.**
|
||||
Confirmed not duplicated despite the `oddsNormalizer.js` neighbor —
|
||||
|
||||
Reference in New Issue
Block a user