Skip to content

fix(baseball): treat empty Lift Builder player selection as "none" (#491)#645

Merged
njrini99-code merged 1 commit into
mainfrom
fix/baseball-491-auto
Jul 3, 2026
Merged

fix(baseball): treat empty Lift Builder player selection as "none" (#491)#645
njrini99-code merged 1 commit into
mainfrom
fix/baseball-491-auto

Conversation

@njrini99-code

Copy link
Copy Markdown
Owner

What & why

Closes #491. In the Lift Builder, deselecting every athlete in GroupAvailabilityGrid sent playerIds: undefined to saveLiftSessionPlan, which skipped the subset filter and materialized the session for the entire team/group — the exact opposite of "nobody". The UI implies per-player targeting, so an empty selection must mean none.

Changes

  • LiftBuilderClient.tsx
    • Block save with a clear error (Select at least one athlete before saving.) when zero athletes are selected, matching the existing title/date/exercise guards.
    • Always send the explicit per-player selection (playerIds: [...selectedPlayerIds]) instead of collapsing empty to undefined.
    • Button copy now reflects behavior: Save — N selected athlete(s).
  • lift-builder.ts (saveLiftSessionPlan)
    • Honor an explicitly-provided (even empty) playerIds array by intersecting with the resolved group/team scope. An empty selection now yields count: 0 with no DB writes. Only an omitted (undefined) value falls back to the whole resolved scope (documented affordance for non-UI callers).

No schema/table changes, no migration. Auth wrapper (withBaseballAction) and baseball_* table prefixes untouched.

Acceptance criteria

  • Zero selected players → save blocked with a clear error (and defense-in-depth count: 0, no DB writes if an empty set reaches the server).
  • Selecting 2 of 10 players materializes exactly 2 sessions (intersection honored).
  • UI copy matches behavior ("Save — N selected athletes").

🤖 Generated with Claude Code

)

Deselecting every athlete in GroupAvailabilityGrid previously sent
playerIds: undefined, which saveLiftSessionPlan interpreted as "no subset
filter" and blasted the session to the entire team/group — the opposite of
"nobody".

- LiftBuilderClient: block save with a clear error when zero athletes are
  selected, always send the explicit selection set (no more undefined
  footgun), and change the button copy to "Save — N selected athlete(s)".
- saveLiftSessionPlan: honor an explicitly-provided (even empty) playerIds
  array by intersecting with the resolved scope, so an empty selection
  yields count: 0 with no DB writes. Only an omitted (undefined) value
  still falls back to the whole resolved scope.

Auth wrapper (withBaseballAction) and table prefixes unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017VUauUXsm9aXegShmpJi5n
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
helmv3 Ready Ready Preview, Comment Jul 1, 2026 4:59pm

Request Review

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix Lift Builder empty athlete selection to target nobody (not whole team)

🐞 Bug fix 🕐 20-40 Minutes

Grey Divider

AI Description

• Block saving when zero athletes are selected, with a clear validation error.
• Always send explicit playerIds from the Lift Builder UI (never undefined).
• Treat an explicitly empty playerIds array server-side as “nobody” (no DB writes).
Diagram

graph TD
  A["LiftBuilderClient"] --> B{"Client-side guards"} --> C["saveLiftSessionPlan"] --> D["Resolve team/group scope"] --> E{"playerIds provided?"}
  E -->|"empty array"| F["Return count: 0"]
  E -->|"non-empty"| G["Materialize sessions"] --> H[("baseball_* tables")]

  subgraph Legend
    direction LR
    _ui["UI"] ~~~ _dec{"Decision"} ~~~ _db[("Database")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make selection mode explicit (e.g., scope = 'all' | 'subset')
  • ➕ Avoids overloading undefined vs [] as meaningfully different states
  • ➕ Easier for non-UI callers to be intentional about “all players” vs “none”
  • ➖ Requires API shape change and updates to all callers
  • ➖ More boilerplate for a simple UX-driven bug fix
2. Server-side schema constraint (reject empty `playerIds`)
  • ➕ Forces a clear contract: subset must have at least one player
  • ➕ Prevents ambiguous no-op requests reaching business logic
  • ➖ Does not support legitimate “target nobody” scenarios if ever needed
  • ➖ Still requires UI changes for good UX
3. Treat `undefined` as error for Lift Builder only (separate action)
  • ➕ Eliminates the footgun for this UI while preserving legacy semantics elsewhere
  • ➖ Introduces duplication or conditional behavior by caller context
  • ➖ More routes/actions to maintain

Recommendation: The PR’s approach is the best fit: keep undefined meaning “entire resolved scope” for non-UI callers, while making the Lift Builder always send an explicit array and blocking empty selection in the UI. The server-side intersection change provides defense-in-depth so an empty set cannot accidentally fan out to the whole team/group.

Files changed (2) +17 / -4

Bug fix (2) +17 / -4
lift-builder.tsHonor empty 'playerIds' as “no targets” in 'saveLiftSessionPlan' +5/-2

Honor empty 'playerIds' as “no targets” in 'saveLiftSessionPlan'

• Clarifies the schema contract: an explicitly provided empty 'playerIds' array targets nobody, while 'undefined' continues to mean “use full resolved scope.” Updates the filtering logic to run whenever 'playerIds' is provided (including empty), ensuring an empty selection yields 'count: 0' with no downstream writes.

src/app/baseball/actions/lift-builder.ts

LiftBuilderClient.tsxPrevent saving with zero selected athletes and always send explicit 'playerIds' +12/-2

Prevent saving with zero selected athletes and always send explicit 'playerIds'

• Adds a client-side guard that blocks saving when no athletes are selected and shows a clear error message. Removes the 'undefined' fallback by always sending 'playerIds' as an explicit array, and updates the save button label to reflect the number of selected athletes.

src/components/baseball/performance/LiftBuilderClient.tsx

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 93 rules

Grey Divider


Informational

1. lift-builder.ts outside actions dir 📘 Rule violation ⌂ Architecture
Description
src/app/baseball/actions/lift-builder.ts is a server action module (starts with use server) but
it is not located under src/app/actions/, which violates the server action placement requirement.
This makes server actions harder to discover and breaks the enforced project convention for action
modules.
Code

src/app/baseball/actions/lift-builder.ts[R326-331]

+    // group/team membership already grants.  An explicitly-provided empty set
+    // means "nobody" (count: 0) — it must NOT fall back to the whole team/group.
+    if (input.playerIds) {
      const requested = new Set(input.playerIds);
      playerIds = playerIds.filter((id) => requested.has(id));
    }
Relevance

⭐ Low

Repo commonly keeps server actions in feature dirs (src/app/baseball/actions, src/app/golf/actions),
not only src/app/actions.

PR-#579
PR-#547
PR-#296

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The checklist requires server action modules to live under src/app/actions/. The modified file
src/app/baseball/actions/lift-builder.ts clearly declares itself as a server action module via the
top-level use server directive, yet it resides in src/app/baseball/actions/ rather than
src/app/actions/.

Rule 1519234: Place Next.js server actions in src/app/actions directory
src/app/baseball/actions/lift-builder.ts[1-3]
src/app/baseball/actions/lift-builder.ts[286-289]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/app/baseball/actions/lift-builder.ts` is a server action module (it begins with `use server`) but it lives outside `src/app/actions/`, violating the required server action placement convention.

## Issue Context
This module exports server actions (e.g., `saveLiftSessionPlan`) and is imported by client UI code. It should be relocated under `src/app/actions/` (or a subdirectory of it) and imports should be updated accordingly.

## Fix Focus Areas
- src/app/baseball/actions/lift-builder.ts[1-5]
- src/components/baseball/performance/LiftBuilderClient.tsx[55-60]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@njrini99-code

Copy link
Copy Markdown
Owner Author

🤖 Mission Control — PR summary

Changes: Deselecting every athlete in Lift Builder now means “assign to none”, not the whole team — blocks save on an empty selection and always sends the explicit set; server honors an empty array as count: 0 with no writes. Closes #491.
Areas / risk: Lift session assignment scope — guards against accidentally blasting the whole team.
Watch: Empty selection → zero writes; omitted selection still falls back to full scope.
CI: ❌ Playwright, Unit tests failing — review before merge. (lighthouse-preview = known noise.)
Note: Bundled into batch #650.

@qodo-code-review

Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Business contracts

Failed stage: Business contracts [❌]

Failed test name: program-type variant engine — live runtime behavior > coach nav ORDER differs between College and Showcase

Failure summary:

The action failed because multiple Vitest test files had failing assertions/errors (6 failed tests
total), causing the test run to exit with code 1.

Key failures shown in the log:
- src/lib/baseball/tests/program-type-nav-variants.test.ts:
-
program-type variant engine — live runtime behavior > coach nav ORDER differs between College and
Showcase failed at src/lib/baseball/tests/program-type-nav-variants.test.ts:58:30 because the
visible nav item sets differ (e.g., "events" appears to be missing from one set), breaking
expect(new Set(college)).toEqual(new Set(showcase)).
- ... > absent programType falls back to
declaration (college-neutral) order failed at
src/lib/baseball/tests/program-type-nav-variants.test.ts:95:21 due to a mismatch between the
produced neutral order and the expected registryOrder (again showing "events" missing).
- ... >
re-ordering never adds or drops entries (set is conserved) failed at
src/lib/baseball/tests/program-type-nav-variants.test.ts:109:32 because the set of entries
changes (log shows "teams" unexpectedly present), violating the “set is conserved” invariant.

- src/test/golf/actions/insight-celebration.test.ts:
- markCelebrationShown > stamps
metadata.celebration_shown_at on first call failed because Next.js revalidatePath was called in a
test environment without the required static generation/request context: Error: Invariant: static
generation store missing in revalidatePath /golf/dashboard/my-insights, originating from
src/app/golf/actions/insight-celebration.ts:133:3.

- src/app/golf/actions/tests/round-recap.test.ts:
- Both tests in generateRoundRecap — 9-hole
vs 18-hole average comparisons failed for the same reason: revalidatePath was invoked without a
static generation store/request scope (Error: Invariant: static generation store missing in
revalidatePath /golf/dashboard/rounds/round-1), originating from
src/app/golf/actions/round-recap.ts:108:3.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

194:  ##[endgroup]
195:  npm warn EBADENGINE Unsupported engine {
196:  npm warn EBADENGINE   package: '@capacitor/cli@8.4.0',
197:  npm warn EBADENGINE   required: { node: '>=22.0.0' },
198:  npm warn EBADENGINE   current: { node: 'v20.20.2', npm: '10.8.2' }
199:  npm warn EBADENGINE }
200:  npm warn EBADENGINE Unsupported engine {
201:  npm warn EBADENGINE   package: 'mute-stream@4.0.0',
202:  npm warn EBADENGINE   required: { node: '^22.22.2 || ^24.15.0 || >=26.0.0' },
203:  npm warn EBADENGINE   current: { node: 'v20.20.2', npm: '10.8.2' }
204:  npm warn EBADENGINE }
205:  npm warn deprecated @types/mapbox-gl@3.5.0: This is a stub types definition. mapbox-gl provides its own type definitions, so you do not need this installed.
206:  npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
207:  npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
208:  npm warn deprecated glob@7.2.3: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
209:  npm warn deprecated serialize-error-cjs@0.1.4: Rolling release, please update to 0.2.0
210:  npm warn deprecated prebuild-install@7.1.3: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
...

245:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/coachhelm/v3/goals/suggestion-writer.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m
246:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/recurring-events.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 49�[2mms�[22m�[39m
247:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/exercise-conflict.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m
248:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/lifting/__tests__/overuse-rules.test.ts �[2m(�[22m�[2m58 tests�[22m�[2m)�[22m�[32m 43�[2mms�[22m�[39m
249:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ApproachMissGenerator.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m
250:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/causality-attribute.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 54�[2mms�[22m�[39m
251:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/dashboard-data.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 117�[2mms�[22m�[39m
252:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/golf-events.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 63�[2mms�[22m�[39m
253:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/composite-w305.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
254:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coach-morning-digest.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 44�[2mms�[22m�[39m
255:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/calendar-sync.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m
256:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/StandingBar.test.tsx �[2m(�[22m�[2m52 tests�[22m�[2m)�[22m�[33m 414�[2mms�[22m�[39m
257:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/insight-delivery-coach-feed.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m
258:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/InsightCard.test.tsx �[2m(�[22m�[2m31 tests�[22m�[2m | �[22m�[33m2 skipped�[39m�[2m)�[22m�[33m 624�[2mms�[22m�[39m
259:  �[33m�[2m✓�[22m�[39m fires player actions with (action, insightId) when expanded �[33m 330�[2mms�[22m�[39m
260:  �[90mstderr�[2m | src/app/baseball/actions/__tests__/route-shell-contract.test.ts�[2m > �[22m�[2mBaseballHelm route/shell contract (#374)�[2m > �[22m�[2madvisory drift reporting�[2m > �[22m�[2mreports orphanRoutes drift (advisory — does not fail)
261:  �[22m�[39m[route-shell-contract] orphanRoutes: 1 new/uncategorized item(s) (see docs/operations/baseball-route-contract-runbook.md to allowlist or fix):
262:  - /baseball/admin/demo-sessions :: disk page at src/app/baseball/admin/demo-sessions has no nav/hub/alias reference
263:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/route-shell-contract.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
264:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/travel.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m�[32m 76�[2mms�[22m�[39m
265:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/utils/__tests__/shot-helpers.test.ts �[2m(�[22m�[2m75 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m
266:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/course-library.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m
267:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/ai-policy-enforcement.test.ts �[2m(�[22m�[2m31 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
268:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/themes/shot-drivers.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 79�[2mms�[22m�[39m
269:  �[31m❯�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/program-type-nav-variants.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m | �[22m�[31m3 failed�[39m�[2m)�[22m�[32m 40�[2mms�[22m�[39m
270:  �[31m     �[31m�[31m coach nav ORDER differs between College and Showcase�[39m�[32m 14�[2mms�[22m�[39m
...

283:  �[32m✓�[39m player nav order follows the spec sequence: Today → Schedule → Tasks�[32m 1�[2mms�[22m�[39m
284:  �[32m✓�[39m every spec player nav surface (Today, Schedule, Tasks, Performance, My Profile) is reachable�[32m 1�[2mms�[22m�[39m
285:  �[32m✓�[39m player landing is the single consolidated home for EVERY program_type�[32m 1�[2mms�[22m�[39m
286:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/utils/__tests__/approach-putting-avg.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m
287:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/publish-lift-day-helm-bridge.integration.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
288:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/player-fingerprint.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 31�[2mms�[22m�[39m
289:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/stat-event-adapters.test.ts �[2m(�[22m�[2m26 tests�[22m�[2m)�[22m�[32m 34�[2mms�[22m�[39m
290:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/stats-data.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 43�[2mms�[22m�[39m
291:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/composite.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m
292:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/utils/__tests__/golf-stats-calculator-shots.audit-fixes.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 24�[2mms�[22m�[39m
293:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/operational-rule-engine.test.ts �[2m(�[22m�[2m22 tests�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m
294:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/generator-base-retraction.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
295:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/generator-base-run-lifecycle.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
296:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/daily-contract/__tests__/missed-sweep.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m
297:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2mconfidence < 0.4 forces lifecycle_state = "tentative" on INSERT
298:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
299:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
300:  featureArea: �[32m'coachhelm'�[39m
301:  }
302:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2mno existing row → INSERT with lifecycle_state = "detected" at high confidence
303:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
304:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
305:  featureArea: �[32m'coachhelm'�[39m
306:  }
307:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2msame signature, value within 5% → UPDATE existing row (no new insert) and no movement metadata
308:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
309:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
310:  featureArea: �[32m'coachhelm'�[39m
311:  }
312:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2msame signature, value moves >5% → UPDATE + sets movement metadata
313:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
314:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
315:  featureArea: �[32m'coachhelm'�[39m
316:  }
317:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2mDI-1: dedup lookup does not filter by created_at
318:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
319:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
320:  featureArea: �[32m'coachhelm'�[39m
321:  }
322:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2mDI-1: an existing row older than the old 30d window still routes to UPDATE (no insert, evidence refreshed)
323:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
324:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
325:  featureArea: �[32m'coachhelm'�[39m
326:  }
327:  �[90mstderr�[2m | src/test/coachhelm/v2/insights/upsert.test.ts�[2m > �[22m�[2mupsertInsight�[2m > �[22m�[2m3rd movement promotes detected → matured
328:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: resolvePlayerOwnership failed: supabase.from(...).select(...).eq(...).eq(...).order(...).limit(...).maybeSingle is not a function {
329:  action: �[32m'coachhelm.upsert.resolvePlayerOwnership'�[39m,
...

335:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/event-reminders.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[33m 316�[2mms�[22m�[39m
336:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/read-models/__tests__/elite-stat-events.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
337:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/development.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
338:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/coachhelm/FairwayTeamStats.test.ts �[2m(�[22m�[2m28 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
339:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/program-onboarding.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m
340:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/golf/__tests__/distance-units.test.ts �[2m(�[22m�[2m47 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m
341:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/standing-refresh.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m
342:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/calendar/availability.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 42�[2mms�[22m�[39m
343:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/generator-base-receipt-diagnosis.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m
344:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/CoachInsightCard.test.tsx �[2m(�[22m�[2m7 tests�[22m�[2m | �[22m�[33m4 skipped�[39m�[2m)�[22m�[33m 1570�[2mms�[22m�[39m
345:  �[33m�[2m✓�[22m�[39m fetches via getInsightsForCoach and renders a default-density card per row �[33m 927�[2mms�[22m�[39m
346:  �[33m�[2m✓�[22m�[39m shows empty-state copy when the player has no evidence-backed insights �[33m 628�[2mms�[22m�[39m
347:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/course-management.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m
348:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/calendar/__tests__/AttendancePanel.test.tsx �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[33m 790�[2mms�[22m�[39m
349:  �[90mstderr�[2m | src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx�[2m > �[22m�[2mPlayerCoachHelmDashboard — Insight Delivery refactor�[2m > �[22m�[2mrenders the HeroInsightCard when a topInsight is provided
350:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: generateHeroNarrative failed: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context { action: �[32m'v3.llm.generateHeroNarrative'�[39m }
351:  �[90mstderr�[2m | src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx�[2m > �[22m�[2mPlayerCoachHelmDashboard — Insight Delivery refactor�[2m > �[22m�[2mrenders the HeroInsightCard when a topInsight is provided
352:  �[22m�[39mAn update to HeroNarrativeCard inside a test was not wrapped in act(...).
353:  When testing, code that causes React state updates should be wrapped into act(...):
354:  act(() => {
355:  /* fire events that update state */
356:  });
357:  /* assert on the output */
358:  This ensures that you're testing the behavior the user would see in the browser. Learn more at https://react.dev/link/wrap-tests-with-act
359:  �[90mstderr�[2m | src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx�[2m > �[22m�[2mPlayerCoachHelmDashboard — Insight Delivery refactor�[2m > �[22m�[2mwires handleInsightAction → rateInsightAsPlayer for player ratings
360:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: generateHeroNarrative failed: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context { action: �[32m'v3.llm.generateHeroNarrative'�[39m }
361:  �[90mstderr�[2m | src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx�[2m > �[22m�[2mPlayerCoachHelmDashboard — Insight Delivery refactor�[2m > �[22m�[2mmaps dismissed action onto rating="dismissed"
362:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: generateHeroNarrative failed: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context { action: �[32m'v3.llm.generateHeroNarrative'�[39m }
363:  �[90mstderr�[2m | src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx�[2m > �[22m�[2mPlayerCoachHelmDashboard — Insight Delivery refactor�[2m > �[22m�[2mmaps acknowledged action onto rating="acknowledged"
364:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: generateHeroNarrative failed: `cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context { action: �[32m'v3.llm.generateHeroNarrative'�[39m }
365:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/app/golf/dashboard/coachhelm/PlayerCoachHelmDashboard.test.tsx �[2m(�[22m�[2m7 tests�[22m�[2m | �[22m�[33m3 skipped�[39m�[2m)�[22m�[32m 277�[2mms�[22m�[39m
...

387:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_severity_150_175 n=8 min=15
388:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mdoes not emit dominant-lie insight when misses are balanced across lies
389:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_direction_150_175 n=6 min=12
390:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mdoes not emit severity insight when avg distance_from_green is near baseline
391:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_severity_175_200 n=9 min=15
392:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mupserts with the same signature on repeat runs (dedup relies on upsertInsight)
393:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_severity_150_175 n=10 min=15
394:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mupserts with the same signature on repeat runs (dedup relies on upsertInsight)
395:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_direction_150_175 n=10 min=12
396:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mupserts with the same signature on repeat runs (dedup relies on upsertInsight)
397:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_severity_150_175 n=10 min=15
398:  �[90mstdout�[2m | src/test/coachhelm/v2/mining/approach-analytics.test.ts�[2m > �[22m�[2mgenerateApproachMissInsights�[2m > �[22m�[2mupserts with the same signature on repeat runs (dedup relies on upsertInsight)
399:  �[22m�[39m[insight-skip] reason=insufficient_sample type=approach_direction_150_175 n=10 min=12
400:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/approach-analytics.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m | �[22m�[33m2 skipped�[39m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
401:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ingest/arccos.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
402:  �[90mstderr�[2m | src/test/lib/error-logging.test.ts�[2m > �[22m�[2mlogError → monitoring sink�[2m > �[22m�[2mdoes not forward stale-server-action errors to the sink
403:  �[22m�[39m[error-logging] stale server action detected — client will reload to pick up the new bundle
404:  �[90mstderr�[2m | src/test/lib/error-logging.test.ts�[2m > �[22m�[2mlogError → monitoring sink�[2m > �[22m�[2mdoes not forward "was not found on the server" partial-match errors
405:  �[22m�[39m[error-logging] stale server action detected — client will reload to pick up the new bundle
406:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/error-logging.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[33m 3108�[2mms�[22m�[39m
407:  �[33m�[2m✓�[22m�[39m writes to sessionStorage and reloads on first call �[33m 407�[2mms�[22m�[39m
...

409:  �[33m�[2m✓�[22m�[39m falls back to a module-level flag when sessionStorage.setItem throws �[33m 803�[2mms�[22m�[39m
410:  �[33m�[2m✓�[22m�[39m falls back to the module flag when sessionStorage.getItem throws �[33m 803�[2mms�[22m�[39m
411:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/tasks/__tests__/reminder-sweep.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
412:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/__tests__/calculate-hole-stats.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
413:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/round-review-system.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 24�[2mms�[22m�[39m
414:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/lpga-standards-selection.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
415:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ranking.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
416:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/engine-run-coach-triage.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
417:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/coachhelm/v3/HoleShotPath/HoleShotPath.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
418:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/dashboard/__tests__/stat-card-sparkline.test.tsx �[2m(�[22m�[2m20 tests�[22m�[2m | �[22m�[33m4 skipped�[39m�[2m)�[22m�[33m 387�[2mms�[22m�[39m
419:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/ranking/score.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
420:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/settings-aliases-and-legacy-redirects.test.ts �[2m(�[22m�[2m29 tests�[22m�[2m)�[22m�[32m 29�[2mms�[22m�[39m
421:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/fairway/settings-team-panels.test.tsx �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 1352�[2mms�[22m�[39m
422:  �[33m�[2m✓�[22m�[39m TeamSettingsPanel reads the ACTIVE (women’s) team row from context — no client re-resolution �[33m 993�[2mms�[22m�[39m
423:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/recruiting/FairwayRecruitingPage.test.tsx �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[33m 1507�[2mms�[22m�[39m
424:  �[33m�[2m✓�[22m�[39m renders a distinct error notice with a working Retry and NO "add your first prospect" CTA �[33m 410�[2mms�[22m�[39m
425:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/import-registry-policy.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
...

438:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/baseball/engine-v10.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
439:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/pattern-miner.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m | �[22m�[33m5 skipped�[39m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
440:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/composite-confidence-calibration.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
441:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/whats-new/__tests__/FairwayWhatsNew.test.tsx �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[33m 586�[2mms�[22m�[39m
442:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/genome-dimensions.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
443:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/demo-access.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
444:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ScramblingGenerator.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
445:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/sand-source.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 106�[2mms�[22m�[39m
446:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/nav-manifest.test.ts �[2m(�[22m�[2m84 tests�[22m�[2m)�[22m�[32m 68�[2mms�[22m�[39m
447:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/coach-onboarding-staff-row.integration.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
448:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/chat-grounding-idempotency.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
449:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coachhelm-insight-lifecycle-archive-anchor.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 25�[2mms�[22m�[39m
450:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/tee-strategy.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
451:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/(dashboard)/dashboard/rounds/[id]/review/__tests__/page.test.tsx �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 76�[2mms�[22m�[39m
452:  �[90mstderr�[2m | src/hooks/__tests__/use-messages.test.tsx�[2m > �[22m�[2museMessages�[2m > �[22m�[2msendMessage (#450)�[2m > �[22m�[2mreturns false when the server action resolves { success: false } (no throw)
453:  �[22m�[39mError sending message: Not a participant in this conversation
454:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/team-join-code.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
455:  �[90mstderr�[2m | src/hooks/__tests__/use-messages.test.tsx�[2m > �[22m�[2museMessages�[2m > �[22m�[2msendMessage (#450)�[2m > �[22m�[2mstill returns false if the action throws directly (network failure)
456:  �[22m�[39mError sending message: Error: network down
457:  at �[90m/home/runner/work/helmv3/helmv3/�[39msrc/hooks/__tests__/use-messages.test.tsx:141:41
...

494:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/counterfactual-clamp.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
495:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coachhelm-calibration.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
496:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/contracts/baseball/access/scope-enforcement.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m
497:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/stats-leak-maps.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
498:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/shot-analysis/__tests__/shot-level-sg.property.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 216�[2mms�[22m�[39m
499:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/announcements/FairwayAnnouncements.logic.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
500:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/email/coach-digest-template.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
501:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/components/golf/coachhelm/v3/round-review-llm-card.test.tsx �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 107�[2mms�[22m�[39m
502:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/mining/__tests__/causal-engine.supersede.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
503:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/outcome-sweep-insight-resolve.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
504:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/alert-counts-visibility.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
505:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/notifications/dispatch.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
506:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/notifications/insight-notifier.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
507:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/Counterfactual.test.tsx �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 55�[2mms�[22m�[39m
508:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/complete-player-onboarding.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
509:  �[90mstderr�[2m | src/app/baseball/actions/__tests__/save-full-box-score.test.ts�[2m > �[22m�[2msaveFullBoxScore�[2m > �[22m�[2msurfaces transport errors from the RPC call
510:  �[22m�[39m[DB Error:games] { message: �[32m'connection reset'�[39m }
511:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/save-full-box-score.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
512:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/qualifying.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
513:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/insight-management.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
514:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/generate-alerts-honest-count.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
515:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/calendar/feed-token-security.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 52�[2mms�[22m�[39m
516:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/PuttBiasGenerator.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
517:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/contracts/baseball/source-trust/import-stamping.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
518:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coachhelm-validation.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
519:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/confirm-selection-chat.integration.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
520:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/calendar-page.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
521:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/__tests__/TeamSwitcher.test.tsx �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[33m 493�[2mms�[22m�[39m
522:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/player-access-enforcement.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
523:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ingest/arccos-transactional.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 18�[2mms�[22m�[39m
524:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/baseball/metrics/registry.role-visibility.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
525:  �[90mstderr�[2m | src/test/coachhelm/v2/learning/behavior-learner.test.ts�[2m > �[22m�[2mBehaviorLearner.loadBehavior aggregation�[2m > �[22m�[2mreturns zeroed profile when DB returns an error
526:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: behavior-learner.loadBehavior failed {
527:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/learning/behavior-learner.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
528:  action: �[32m'behavior-learner.loadBehavior'�[39m,
529:  featureArea: �[32m'coachhelm.learning'�[39m,
530:  source: �[32m'background_job'�[39m,
531:  metadata: {
532:  entityId: �[32m'00000000-0000-0000-0000-000000000001'�[39m,
533:  entityType: �[32m'coach'�[39m,
534:  dbError: { message: �[32m'boom'�[39m }
535:  }
536:  }
537:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/daily-contract/__tests__/contract-day.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 39�[2mms�[22m�[39m
538:  �[31m❯�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/insight-celebration.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m | �[22m�[31m1 failed�[39m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
539:  �[32m✓�[39m returns an error when the user is not authenticated�[32m 3�[2mms�[22m�[39m
540:  �[32m✓�[39m returns an error when the insight id is missing�[32m 1�[2mms�[22m�[39m
541:  �[32m✓�[39m returns Forbidden when the caller is not the player owner�[32m 1�[2mms�[22m�[39m
542:  �[31m     �[31m�[31m stamps metadata.celebration_shown_at on first call�[39m�[32m 8�[2mms�[22m�[39m
543:  �[32m✓�[39m is idempotent when celebration_shown_at is already set�[32m 2�[2mms�[22m�[39m
544:  �[32m✓�[39m reports failure when the load query errors�[32m 1�[2mms�[22m�[39m
545:  �[32m✓�[39m reports failure when the update query errors�[32m 1�[2mms�[22m�[39m
546:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/TeeStrategyGenerator.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
...

555:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/insights/upsert-priority-repersist.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
556:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coachhelm-safety-net.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
557:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/interests.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
558:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/effectiveness/event-ledger.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
559:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/chat-create-goal.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
560:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/learning/__tests__/outcome-validator.horizon.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
561:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/player-feedback.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
562:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/composite/synthesis-context-only.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
563:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/mining/__tests__/pattern-miner.supersede.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
564:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/notifications/email.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
565:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/coachhelm/v3/goals/evaluator.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
566:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/stats-center-derivations.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 14�[2mms�[22m�[39m
567:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/intent/loader.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
568:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/insight-lifecycle.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
569:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/read-models/__tests__/stat-visuals.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
570:  �[31m❯�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/round-recap.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m | �[22m�[31m2 failed�[39m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
571:  �[31m     �[31m�[31m skips the season-average and best-round comparisons for a 9-hole round�[39m�[32m 7�[2mms�[22m�[39m
...

616:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/goals/__tests__/window-metric.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
617:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/import-duplicate-verdict.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
618:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/dev-plan-progress.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
619:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/baseball/loaders-events.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
620:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/access-code.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
621:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/pattern-management.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
622:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/read-models/__tests__/player-daily-contract.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
623:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/coachhelm-insight-lifecycle-bounds.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
624:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/stat-layer-contract.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 164�[2mms�[22m�[39m
625:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/read-models/__tests__/player-snapshot-cards.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
626:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/DrillAttachment.test.tsx �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 146�[2mms�[22m�[39m
627:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/golf/actions/__tests__/team-category-insights-helpers.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
628:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/fairway/practice-rx-batch.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 95�[2mms�[22m�[39m
629:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/coaching-philosophy.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
630:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/fairway/settings-notifications.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 759�[2mms�[22m�[39m
631:  �[33m�[2m✓�[22m�[39m rolls back a failed optimistic cell save and shows a toast �[33m 420�[2mms�[22m�[39m
632:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/ui/button.test.tsx �[2m(�[22m�[2m15 tests�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m�[33m 540�[2mms�[22m�[39m
633:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/read-models/__tests__/command-center.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
634:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/coachhelm/areaTypes.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
635:  �[90mstderr�[2m | src/test/coachhelm/v2/post-round-trigger.test.ts�[2m > �[22m�[2mpostRoundTrigger�[2m > �[22m�[2msets coachhelm_failed_at + reason when trigger returns success: false
636:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: postRoundTrigger engine failed: team disabled coachhelm {
637:  action: �[32m'postRoundTrigger.engineFailure'�[39m,
638:  featureArea: �[32m'coachhelm'�[39m,
639:  playerId: �[32m'p1'�[39m,
640:  extra: { roundId: �[32m'r2'�[39m, triggerReason: �[32m'round_submitted'�[39m }
641:  }
642:  �[90mstderr�[2m | src/test/coachhelm/v2/post-round-trigger.test.ts�[2m > �[22m�[2mpostRoundTrigger�[2m > �[22m�[2msets coachhelm_failed_at + reason when trigger throws
643:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: postRoundTrigger threw: engine_boom {
644:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/post-round-trigger.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m
645:  action: �[32m'postRoundTrigger.throw'�[39m,
646:  featureArea: �[32m'coachhelm'�[39m,
647:  playerId: �[32m'p1'�[39m,
648:  extra: {
649:  roundId: �[32m'r3'�[39m,
650:  triggerReason: �[32m'round_submitted'�[39m,
651:  stack: �[32m'Error: engine_boom\n'�[39m +
652:  �[32m'    at /home/runner/work/helmv3/helmv3/src/test/coachhelm/v2/post-round-trigger.test.ts:60:35\n'�[39m +
653:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n'�[39m +
654:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n'�[39m +
655:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n'�[39m +
656:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
657:  �[32m'    at runWithCancel (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n'�[39m +
658:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n'�[39m +
659:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
660:  �[32m'    at runWithTimeout (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n'�[39m +
661:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64'�[39m
662:  }
663:  }
664:  �[90mstderr�[2m | src/test/coachhelm/v2/post-round-trigger.test.ts�[2m > �[22m�[2mpostRoundTrigger�[2m > �[22m�[2mtruncates failure reason to 500 chars
665:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: postRoundTrigger threw: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {
666:  action: �[32m'postRoundTrigger.throw'�[39m,
667:  featureArea: �[32m'coachhelm'�[39m,
668:  playerId: �[32m'p1'�[39m,
669:  extra: {
670:  roundId: �[32m'r4'�[39m,
671:  triggerReason: �[32m'round_submitted'�[39m,
672:  stack: �[32m'Error: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n'�[39m +
673:  �[32m'    at /home/runner/work/helmv3/helmv3/src/test/coachhelm/v2/post-round-trigger.test.ts:78:35\n'�[39m +
674:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n'�[39m +
675:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n'�[39m +
676:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n'�[39m +
677:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
678:  �[32m'    at runWithCancel (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n'�[39m +
679:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n'�[39m +
680:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
681:  �[32m'    at runWithTimeout (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n'�[39m +
682:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64'�[39m
683:  }
684:  }
685:  �[90mstderr�[2m | src/test/coachhelm/v2/post-round-trigger.test.ts�[2m > �[22m�[2mpostRoundTrigger�[2m > �[22m�[2mnever throws — fire-and-forget safe from after()
686:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: postRoundTrigger threw: boom {
687:  action: �[32m'postRoundTrigger.throw'�[39m,
688:  featureArea: �[32m'coachhelm'�[39m,
689:  playerId: �[32m'p1'�[39m,
690:  extra: {
691:  roundId: �[32m'r5'�[39m,
692:  triggerReason: �[32m'round_submitted'�[39m,
693:  stack: �[32m'Error: boom\n'�[39m +
694:  �[32m'    at /home/runner/work/helmv3/helmv3/src/test/coachhelm/v2/post-round-trigger.test.ts:88:35\n'�[39m +
695:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11\n'�[39m +
696:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26\n'�[39m +
697:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20\n'�[39m +
698:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
699:  �[32m'    at runWithCancel (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10)\n'�[39m +
700:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20\n'�[39m +
701:  �[32m'    at new Promise (<anonymous>)\n'�[39m +
702:  �[32m'    at runWithTimeout (file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10)\n'�[39m +
703:  �[32m'    at file:///home/runner/work/helmv3/helmv3/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64'�[39m
704:  }
705:  }
706:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/composite-strokes-backfill.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
707:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/HeroInsightCard.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 162�[2mms�[22m�[39m
708:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/utils/transient-error.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 63�[2mms�[22m�[39m
709:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/insights/baseline-registry.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
710:  �[90mstderr�[2m | src/app/baseball/actions/__tests__/change-password.test.ts�[2m > �[22m�[2mchangePasswordAction�[2m > �[22m�[2mrejects wrong current password with a sanitized message
711:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: [Auth] Password change reauth failed: Invalid login credentials { action: �[32m'auth.changePasswordAction'�[39m, metadata: { userId: �[32m'user-1'�[39m } }
712:  �[90mstderr�[2m | src/app/baseball/actions/__tests__/change-password.test.ts�[2m > �[22m�[2mchangePasswordAction�[2m > �[22m�[2mrejects wrong current password with a sanitized message
713:  �[22m�[39m[Auth Error:changePassword] { message: �[32m'Invalid login credentials'�[39m }
714:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/app/baseball/actions/__tests__/change-password.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 30�[2mms�[22m�[39m
...

730:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/coachhelm/CoachHelmSubNav.test.tsx �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 485�[2mms�[22m�[39m
731:  �[33m�[2m✓�[22m�[39m renders the four consolidated player tabs with their canonical routes �[33m 350�[2mms�[22m�[39m
732:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/counterfactual-cohort.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m
733:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/chat-push.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
734:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/diagnosis.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
735:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/golf/__tests__/sg-baseline-options.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
736:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/insights/calc-confidence.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
737:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/recap.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m
738:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/notifications.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
739:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/command-palette-nav.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
740:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/practice-rx.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
741:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/outcome-sweep-verdict.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
742:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/themes/sanitize-prose.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
743:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/learning/cross-learner.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
744:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/counterfactual-attempt-rate.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
745:  �[90mstderr�[2m | src/test/coachhelm/v2/feedback/coach-behavior.test.ts�[2m > �[22m�[2mrecordAction�[2m > �[22m�[2minserts only valid columns (no bogus `timestamp`) and propagates DB errors
746:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: coach-behavior.recordAction failed {
747:  action: �[32m'coach-behavior.recordAction'�[39m,
748:  featureArea: �[32m'coachhelm.feedback'�[39m,
749:  source: �[32m'background_job'�[39m,
750:  metadata: {
751:  coachId: �[32m'c-1'�[39m,
752:  actionType: �[32m'view_insight'�[39m,
753:  dbError: { message: �[32m'simulated'�[39m }
754:  }
755:  }
756:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/feedback/coach-behavior.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
757:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/prediction/__tests__/performance-predictor.quality.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
758:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/composite-sample-counts.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
759:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/ingest.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
760:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/fairway/pages/coachhelm/plan-markdown.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
761:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/log-error.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
762:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/components/IntentPill.test.tsx �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 69�[2mms�[22m�[39m
763:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/insight-visibility.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
764:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/server-error-logger.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
765:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/orchestrator-thresholds.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
...

790:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/golf/actions/patterns-dashboard-client.test.tsx �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 90�[2mms�[22m�[39m
791:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v3/stats/__tests__/proportion-test.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
792:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/window-honesty.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
793:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/server-route-guards.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
794:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/components/golf/layout/GolfSidebar.test.tsx �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 529�[2mms�[22m�[39m
795:  �[33m�[2m✓�[22m�[39m keeps core coach operations directly reachable from the sidebar �[33m 522�[2mms�[22m�[39m
796:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/import-source-registration.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
797:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/api/cron/shared-auth.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 16�[2mms�[22m�[39m
798:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/counterfactual-confidence-band.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
799:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/daily-contract/__tests__/ack-visibility.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
800:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/resolve-active-hub.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
801:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/import-source-enabled.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
802:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/golf/__tests__/team-theme.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
803:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/generator-prose.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
804:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/coachhelm/v2/mining/__tests__/shot-pattern-miner.distance-control.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
805:  �[90mstderr�[2m | src/test/coachhelm/v2/gate.test.ts�[2m > �[22m�[2mgate fail-closed behavior (LIVE-17)�[2m > �[22m�[2mcoach gate returns effectivelyEnabled=false when coach lookup errors
806:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: gate.isCoachHelmEnabledForCoach lookup failed {
807:  action: �[32m'gate.isCoachHelmEnabledForCoach'�[39m,
808:  featureArea: �[32m'coachhelm.gate'�[39m,
809:  metadata: { coachId: �[32m'coach-1'�[39m, dbError: { message: �[32m'transient db error'�[39m } }
810:  }
811:  �[90mstderr�[2m | src/test/coachhelm/v2/gate.test.ts�[2m > �[22m�[2mgate fail-closed behavior (LIVE-17)�[2m > �[22m�[2mplayer gate returns effectivelyEnabled=false when player lookup errors
812:  �[22m�[39m[ServerErrorLogger] Failed to persist trace: gate.isCoachHelmEnabledForPlayer lookup failed {
813:  action: �[32m'gate.isCoachHelmEnabledForPlayer'�[39m,
814:  featureArea: �[32m'coachhelm.gate'�[39m,
815:  metadata: { playerId: �[32m'player-1'�[39m, dbError: { message: �[32m'transient db error'�[39m } }
816:  }
...

821:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/lookup-attempt-config.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
822:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/cohort-bounds-unbounded.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m
823:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/shot-state-intelligence.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
824:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/nav-performance-capability.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
825:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/contracts/baseball/demo-stats-smoke.contract.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
826:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/showcase-org-nav.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
827:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/golf/__tests__/gender-sg-baseline.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
828:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/lie-specific-analysis.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
829:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v3/lookup-tables.shortputt.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m
830:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/lib/cron/auth.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 15�[2mms�[22m�[39m
831:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/active-context-staff-status.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
832:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/roster-read-model.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
833:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/test/coachhelm/v2/mining/shot-pattern-miner.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
834:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/stats-route-aliases.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 5�[2mms�[22m�[39m
835:  �[32m✓�[39m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/documents-capability.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m
836:  �[31m⎯⎯⎯⎯⎯⎯⎯�[39m�[1m�[41m Failed Tests 6 �[49m�[22m�[31m⎯⎯⎯⎯⎯⎯⎯�[39m
837:  �[41m�[1m FAIL �[22m�[49m �[30m�[43m business �[49m�[39m src/lib/baseball/__tests__/program-type-nav-variants.test.ts�[2m > �[22mprogram-type variant engine — live runtime behavior�[2m > �[22mcoach nav ORDER differs between College and Showcase
838:  �[31m�[1mAssertionError�[22m: expected Set{ 'command-center', …(23) } to deeply equal Set{ 'command-center', …(24) }�[39m
839:  �[32m- Expected�[39m
...

846:  �[2m    "documents",�[22m
847:  �[32m-   "events",�[39m
848:  �[2m    "import-center",�[22m
849:  �[2m    "performance",�[22m
850:  �[2m    "pipeline",�[22m
851:  �[2m    "postgame-review",�[22m
852:  �[2m    "practice-effectiveness",�[22m
853:  �[36m �[2m❯�[22m src/lib/baseball/__tests__/program-type-nav-variants.test.ts:�[2m58:30�[22m�[39m
854:  �[90m 56|�[39m     �[35mconst�[39m showcase �[33m=�[39m �[34mprimaryIds�[39m(�[34mcoachCtx�[39m(�[32m'showcase'�[39m))�[33m;�[39m
855:  �[90m 57|�[39m     // Same visible set (head coach holds every capability) but differ…
856:  �[90m 58|�[39m     �[34mexpect�[39m(�[35mnew�[39m �[33mSet�[39m(college))�[33m.�[39m�[34mtoEqual�[39m(�[35mnew�[39m �[33mSet�[39m(showcase))�[33m;�[39m
857:  �[90m   |�[39m                              �[31m^�[39m
858:  �[9...

@njrini99-code njrini99-code merged commit 5258b24 into main Jul 3, 2026
29 of 35 checks passed
@njrini99-code njrini99-code deleted the fix/baseball-491-auto branch July 3, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BaseballHelm: Treat empty Lift Builder player selection as "assign to none," not whole team

1 participant