chore: add scoreboard correlation tasks
This commit is contained in:
164
ai/tasks/pending/TASK-147-persist-scoreboard-list-candidates.md
Normal file
164
ai/tasks/pending/TASK-147-persist-scoreboard-list-candidates.md
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
---
|
||||||
|
id: TASK-147
|
||||||
|
title: Persist public scoreboard list matches as RCON candidates
|
||||||
|
status: pending
|
||||||
|
type: backend
|
||||||
|
team: Backend Senior
|
||||||
|
supporting_teams:
|
||||||
|
- Arquitecto Python
|
||||||
|
roadmap_item: rcon-full-data
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-147 - Persist public scoreboard list matches as RCON candidates
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make `scoreboard_candidate_backfill` persist safe rows into
|
||||||
|
`rcon_scoreboard_match_candidates` directly from `/api/get_scoreboard_maps`
|
||||||
|
list payloads, so public scoreboard URLs are available for RCON correlation
|
||||||
|
even if `/api/get_map_scoreboard` detail fetching fails, returns a different
|
||||||
|
shape, or lacks fields.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
A real Foy match existed in the scoreboard public list:
|
||||||
|
|
||||||
|
- scoreboard id: `1562115`
|
||||||
|
- server_number: `2`
|
||||||
|
- server slug: `comunidad-hispana-02`
|
||||||
|
- map: Foy Warfare
|
||||||
|
- start: `2026-05-20T20:54:11+00:00`
|
||||||
|
- end: `2026-05-20T22:24:11+00:00`
|
||||||
|
- score: allied `4` / axis `1`
|
||||||
|
- expected URL: `https://scoreboard.comunidadhll.es:5443/games/1562115`
|
||||||
|
|
||||||
|
But it was not available as an RCON scoreboard candidate until manually
|
||||||
|
inserted. After manual insert and materialization, the match detail page
|
||||||
|
correctly showed `Ver en Scoreboard`.
|
||||||
|
|
||||||
|
The backfill currently reads `/api/get_scoreboard_maps`, collects IDs, fetches
|
||||||
|
detail payloads, and calls `upsert_historical_match` from detail payloads. The
|
||||||
|
list payload already contains enough trusted data for a safe candidate:
|
||||||
|
`id`, `start`, `end`, `map.id`, `map.pretty_name`, `result.allied`,
|
||||||
|
`result.axis`, and `server_number`.
|
||||||
|
|
||||||
|
## Constraints / DO NOT BREAK
|
||||||
|
|
||||||
|
- Do not remove PostgreSQL migration logic.
|
||||||
|
- Do not switch back to SQLite.
|
||||||
|
- Do not break recent match cards.
|
||||||
|
- Do not show `Ver partida` in recent cards.
|
||||||
|
- Do not change detail-page scoreboard button behavior except enabling it when
|
||||||
|
`match_url` exists.
|
||||||
|
- Do not expose unsafe URLs.
|
||||||
|
- Do not generate scoreboard URLs from player names.
|
||||||
|
- Do not commit runtime DB files.
|
||||||
|
|
||||||
|
## Allowed Changes
|
||||||
|
|
||||||
|
- `backend/app/scoreboard_candidate_backfill.py`
|
||||||
|
- Existing backend storage/read-model helpers needed for the safe candidate
|
||||||
|
upsert path.
|
||||||
|
- Existing trusted scoreboard origin helpers needed to preserve URL safety.
|
||||||
|
- Focused backend scoreboard tests and fixtures/mocks.
|
||||||
|
- This task file when it moves through the task workflow.
|
||||||
|
|
||||||
|
## Implementation Requirements
|
||||||
|
|
||||||
|
1. Inspect:
|
||||||
|
- `backend/app/scoreboard_candidate_backfill.py`
|
||||||
|
- `backend/app/postgres_rcon_storage.py`
|
||||||
|
- `backend/app/postgres_display_storage.py`
|
||||||
|
- `backend/app/historical_storage.py`
|
||||||
|
- `backend/app/rcon_admin_log_materialization.py`
|
||||||
|
- `backend/app/rcon_historical_read_model.py`
|
||||||
|
- `backend/app/scoreboard_origins.py`
|
||||||
|
2. Add or reuse a safe upsert function for
|
||||||
|
`rcon_scoreboard_match_candidates`.
|
||||||
|
3. During `scoreboard_candidate_backfill`, for every list match inside the
|
||||||
|
requested window:
|
||||||
|
- build a candidate from the list payload
|
||||||
|
- validate `server_number` / `server_slug` mapping
|
||||||
|
- build `match_url` only from trusted scoreboard base URL and numeric
|
||||||
|
external match id
|
||||||
|
- persist candidate idempotently into
|
||||||
|
`rcon_scoreboard_match_candidates`
|
||||||
|
4. This candidate upsert must happen before `fetch_match_details`.
|
||||||
|
5. `fetch_match_details` must remain only for historical match/player stat
|
||||||
|
enrichment.
|
||||||
|
6. If `fetch_match_details` fails, the candidate row must still exist.
|
||||||
|
7. Add counters to the JSON report:
|
||||||
|
- `list_candidates_inserted`
|
||||||
|
- `list_candidates_updated`
|
||||||
|
- `list_candidates_skipped`
|
||||||
|
- detail candidate/detail match counters if useful
|
||||||
|
8. Keep existing historical upsert behavior.
|
||||||
|
9. Preserve trusted URL allowlist behavior.
|
||||||
|
10. Do not create candidates for untrusted origins.
|
||||||
|
11. Do not reintroduce Comunidad Hispana #03 as an active visible target.
|
||||||
|
12. Add tests covering a list payload equivalent to Foy `1562115`.
|
||||||
|
13. The test must prove:
|
||||||
|
- list payload alone persists candidate
|
||||||
|
- `match_url` is
|
||||||
|
`https://scoreboard.comunidadhll.es:5443/games/1562115`
|
||||||
|
- failure of detail fetch does not prevent candidate persistence
|
||||||
|
- operation is idempotent
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/orchestrator/backend-senior.md`
|
||||||
|
- `backend/app/scoreboard_candidate_backfill.py`
|
||||||
|
- `backend/app/postgres_rcon_storage.py`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- Backfill/storage helper files needed for the safe list-candidate upsert.
|
||||||
|
- Focused scoreboard tests covering list-only persistence and detail failure.
|
||||||
|
- This task file after moving it through the workflow.
|
||||||
|
|
||||||
|
Keep the task within the allowed changes. If a storage boundary requires an
|
||||||
|
additional backend file from the inspected list, document why in the task
|
||||||
|
outcome.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `python -m compileall backend/app`
|
||||||
|
- `python -m unittest discover -s tests -p "*scoreboard*"`
|
||||||
|
- `python -m app.storage_diagnostics`
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
|
||||||
|
- `docker compose --profile advanced up -d --build backend frontend postgres`
|
||||||
|
- `docker compose exec backend python -m app.scoreboard_candidate_backfill --server comunidad-hispana-02 --from 2026-05-20T00:00:00Z --to 2026-05-21T23:59:59Z --max-pages 5 --page-size 100`
|
||||||
|
- Query `rcon_scoreboard_match_candidates` and verify external match id
|
||||||
|
`1562115` exists for `comunidad-hispana-02`.
|
||||||
|
- Invoke the detail endpoint for
|
||||||
|
`comunidad-hispana-02:1779310451:1779315851:foywarfare` and verify
|
||||||
|
`match_url` is present.
|
||||||
|
- Review `git diff --name-only` and confirm the changed files match this task.
|
||||||
|
|
||||||
|
## Manual Verification
|
||||||
|
|
||||||
|
1. Open:
|
||||||
|
`http://localhost:8080/historico-partida.html?server=comunidad-hispana-02&match=comunidad-hispana-02%3A1779310451%3A1779315851%3Afoywarfare`
|
||||||
|
2. Verify `Ver en Scoreboard` appears.
|
||||||
|
3. Verify it opens:
|
||||||
|
`https://scoreboard.comunidadhll.es:5443/games/1562115`
|
||||||
|
4. Verify recent cards still do not show the public scoreboard button.
|
||||||
|
|
||||||
|
## Commit Message
|
||||||
|
|
||||||
|
`fix: persist scoreboard list matches as rcon candidates`
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document validation, candidate upsert decisions, counters added to the JSON
|
||||||
|
report, and any follow-up task instead of widening this task.
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split follow-up work into a new task if the scope grows.
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
---
|
||||||
|
id: TASK-148
|
||||||
|
title: Relink existing RCON matches to scoreboard candidates
|
||||||
|
status: pending
|
||||||
|
type: backend
|
||||||
|
team: Backend Senior
|
||||||
|
supporting_teams:
|
||||||
|
- Arquitecto Python
|
||||||
|
roadmap_item: rcon-full-data
|
||||||
|
priority: high
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-148 - Relink existing RCON matches to scoreboard candidates
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Add a deterministic relink flow that can update or resolve scoreboard URLs for
|
||||||
|
already-materialized RCON matches after new scoreboard candidates are inserted.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
After manually inserting the Foy `1562115` candidate, the match detail page
|
||||||
|
showed the expected scoreboard button. Future backfills may insert candidates
|
||||||
|
after RCON matches already exist, so the system must relink existing RCON
|
||||||
|
matches with null or missing `match_url` dynamically or via materialization.
|
||||||
|
|
||||||
|
Known Foy regression target:
|
||||||
|
|
||||||
|
- RCON match key:
|
||||||
|
`comunidad-hispana-02:1779310451:1779315851:foywarfare`
|
||||||
|
- candidate external match id: `1562115`
|
||||||
|
- expected URL: `https://scoreboard.comunidadhll.es:5443/games/1562115`
|
||||||
|
|
||||||
|
## Constraints / DO NOT BREAK
|
||||||
|
|
||||||
|
- Do not relax trusted scoreboard URL allowlist.
|
||||||
|
- Do not link to unsafe origins.
|
||||||
|
- Do not choose ambiguous candidates silently.
|
||||||
|
- Do not break old Carentan match:
|
||||||
|
`comunidad-hispana-02:1779178461:1779183861:carentanwarfare`
|
||||||
|
- Do not break Kharkov:
|
||||||
|
`comunidad-hispana-02:1779315955:1779319098:kharkovwarfare`
|
||||||
|
- Do not re-add public scoreboard buttons to recent match cards.
|
||||||
|
- Do not expose correlation debug text in normal UI.
|
||||||
|
|
||||||
|
## Allowed Changes
|
||||||
|
|
||||||
|
- Existing RCON materialization, historical read-model, and RCON storage
|
||||||
|
modules needed for deterministic candidate relinking.
|
||||||
|
- `backend/app/scoreboard_candidate_backfill.py` only when needed to trigger
|
||||||
|
or document the relink sequence.
|
||||||
|
- A focused backend relink command module or a narrowly scoped command option
|
||||||
|
on existing materialization CLI.
|
||||||
|
- Focused backend scoreboard correlation tests and fixtures/mocks.
|
||||||
|
- This task file when it moves through the task workflow.
|
||||||
|
|
||||||
|
## Implementation Requirements
|
||||||
|
|
||||||
|
1. Inspect current correlation logic:
|
||||||
|
- `backend/app/rcon_admin_log_materialization.py`
|
||||||
|
- `backend/app/rcon_historical_read_model.py`
|
||||||
|
- `backend/app/postgres_rcon_storage.py`
|
||||||
|
- `backend/app/scoreboard_candidate_backfill.py`
|
||||||
|
2. Add or improve a function that matches RCON materialized matches to
|
||||||
|
`rcon_scoreboard_match_candidates` using:
|
||||||
|
- same server slug / external server id
|
||||||
|
- normalized map identity
|
||||||
|
- overlapping or close time window
|
||||||
|
- score allied/axis where present
|
||||||
|
- winner where present
|
||||||
|
3. Tolerances:
|
||||||
|
- allow reasonable time drift between RCON and scoreboard, at least
|
||||||
|
+/- 15 minutes, preferably configurable or centralized
|
||||||
|
- for matches with null `started_at` / `ended_at` but `closed_at` plus
|
||||||
|
`duration_seconds`, derive a correlation window
|
||||||
|
4. When a best safe candidate is found, make `match_url` available in detail
|
||||||
|
payload.
|
||||||
|
5. Prefer deterministic scoring:
|
||||||
|
- exact map match
|
||||||
|
- close end time
|
||||||
|
- score match
|
||||||
|
- same server
|
||||||
|
- reject ambiguous ties unless one candidate is clearly better
|
||||||
|
6. Add a command or option to relink existing matches without needing new
|
||||||
|
ingestion:
|
||||||
|
- acceptable command module:
|
||||||
|
`python -m app.rcon_scoreboard_relink`
|
||||||
|
- acceptable alternative: an option inside
|
||||||
|
`app.rcon_admin_log_materialization`
|
||||||
|
7. The relink command must print JSON summary:
|
||||||
|
- `matches_scanned`
|
||||||
|
- `candidates_scanned`
|
||||||
|
- `matches_linked`
|
||||||
|
- `matches_skipped_no_candidate`
|
||||||
|
- `matches_skipped_ambiguous`
|
||||||
|
- `errors`
|
||||||
|
8. Ensure `scoreboard_candidate_backfill` can optionally trigger relink at the
|
||||||
|
end, or document the command sequence.
|
||||||
|
9. Add regression coverage for the Foy case:
|
||||||
|
- RCON match key
|
||||||
|
`comunidad-hispana-02:1779310451:1779315851:foywarfare`
|
||||||
|
- candidate external match id `1562115`
|
||||||
|
- expected `match_url`
|
||||||
|
`https://scoreboard.comunidadhll.es:5443/games/1562115`
|
||||||
|
10. Ensure the detail endpoint returns `match_url` after relink.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/orchestrator/backend-senior.md`
|
||||||
|
- `backend/app/rcon_admin_log_materialization.py`
|
||||||
|
- `backend/app/rcon_historical_read_model.py`
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- Existing RCON correlation/materialization/storage code needed for relinking.
|
||||||
|
- One relink CLI entry point or one existing CLI option.
|
||||||
|
- Focused scoreboard correlation regression tests.
|
||||||
|
- This task file after moving it through the workflow.
|
||||||
|
|
||||||
|
Keep correlation diagnostics out of this task except the JSON relink summary
|
||||||
|
required here. Use TASK-149 for detailed diagnostic output and docs.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `python -m compileall backend/app`
|
||||||
|
- `python -m unittest discover -s tests -p "*scoreboard*"`
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
|
||||||
|
- `docker compose --profile advanced up -d --build backend frontend postgres`
|
||||||
|
- `docker compose exec backend python -m app.scoreboard_candidate_backfill --server comunidad-hispana-02 --from 2026-05-20T00:00:00Z --to 2026-05-21T23:59:59Z --max-pages 5 --page-size 100`
|
||||||
|
- Run the new relink command.
|
||||||
|
- Use `Invoke-WebRequest` for the Foy detail payload and verify `found` is
|
||||||
|
true and `match_url` is present.
|
||||||
|
- Use `Invoke-WebRequest` for the Carentan detail payload and verify the
|
||||||
|
existing `match_url` is still present.
|
||||||
|
- Review `git diff --name-only` and confirm the changed files match this task.
|
||||||
|
|
||||||
|
## Manual Verification
|
||||||
|
|
||||||
|
1. Foy detail page shows `Ver en Scoreboard`.
|
||||||
|
2. Scoreboard button opens the `1562115` public URL.
|
||||||
|
3. Recent match cards still do not show public scoreboard links.
|
||||||
|
4. No `Detalle no disponible` state appears for the validated detail page.
|
||||||
|
5. Player filters and external profile links still work.
|
||||||
|
|
||||||
|
## Commit Message
|
||||||
|
|
||||||
|
`fix: relink rcon matches to scoreboard candidates`
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document correlation scoring choices, time-window derivation, ambiguity
|
||||||
|
handling, relink command output, validation, and any follow-up task instead of
|
||||||
|
expanding scope.
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split follow-up work into a new task if the scope grows.
|
||||||
146
ai/tasks/pending/TASK-149-scoreboard-correlation-diagnostics.md
Normal file
146
ai/tasks/pending/TASK-149-scoreboard-correlation-diagnostics.md
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
---
|
||||||
|
id: TASK-149
|
||||||
|
title: Add scoreboard correlation diagnostics
|
||||||
|
status: pending
|
||||||
|
type: backend
|
||||||
|
team: Backend Senior
|
||||||
|
supporting_teams:
|
||||||
|
- PM
|
||||||
|
roadmap_item: rcon-full-data
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
# TASK-149 - Add scoreboard correlation diagnostics
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Make missing scoreboard links diagnosable without exposing debug clutter in the
|
||||||
|
normal UI.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
When the Foy match had `match_url` null, investigation required manual
|
||||||
|
inspection of public pages, candidate tables, and historical tables. Backend
|
||||||
|
diagnostics should explain whether:
|
||||||
|
|
||||||
|
- no candidates exist
|
||||||
|
- candidates exist but map/time/score mismatch
|
||||||
|
- candidates were ambiguous
|
||||||
|
- candidate URL was unsafe
|
||||||
|
- relink was not run
|
||||||
|
|
||||||
|
The known Foy diagnostic target is:
|
||||||
|
|
||||||
|
- server: `comunidad-hispana-02`
|
||||||
|
- RCON match key:
|
||||||
|
`comunidad-hispana-02:1779310451:1779315851:foywarfare`
|
||||||
|
- expected candidate when available: external match id `1562115`
|
||||||
|
|
||||||
|
## Constraints / DO NOT BREAK
|
||||||
|
|
||||||
|
- Do not add visible debug text to `historico-partida.html`.
|
||||||
|
- Do not add timeline/source/debug metadata back to normal UI.
|
||||||
|
- Do not change recent card layout.
|
||||||
|
- Do not require internet for unit tests.
|
||||||
|
- Use fixtures/mocks for tests.
|
||||||
|
|
||||||
|
## Allowed Changes
|
||||||
|
|
||||||
|
- A focused backend scoreboard correlation diagnostic command.
|
||||||
|
- Existing backend correlation/read helpers only when needed to reuse safe
|
||||||
|
candidate selection output.
|
||||||
|
- Focused backend tests using fixtures or mocks.
|
||||||
|
- Documentation explaining the missing-scoreboard-button debug sequence.
|
||||||
|
- This task file when it moves through the task workflow.
|
||||||
|
|
||||||
|
## Implementation Requirements
|
||||||
|
|
||||||
|
1. Add backend diagnostic capability for a given RCON match:
|
||||||
|
- preferred command:
|
||||||
|
`python -m app.scoreboard_correlation_diagnostics --server comunidad-hispana-02 --match comunidad-hispana-02:1779310451:1779315851:foywarfare`
|
||||||
|
- optional alternative: also expose it inside `storage_diagnostics`, but
|
||||||
|
never in normal frontend payloads
|
||||||
|
2. Diagnostic output must be JSON.
|
||||||
|
3. Include:
|
||||||
|
- `rcon_match_key`
|
||||||
|
- `server`
|
||||||
|
- `map`
|
||||||
|
- `started_at` / `ended_at` / `closed_at` / `duration_seconds`
|
||||||
|
- score
|
||||||
|
- candidate search window
|
||||||
|
- `candidate_count`
|
||||||
|
- top candidate summaries:
|
||||||
|
- `external_match_id`
|
||||||
|
- `started_at`
|
||||||
|
- `ended_at`
|
||||||
|
- map
|
||||||
|
- score
|
||||||
|
- `match_url`
|
||||||
|
- `correlation_score`
|
||||||
|
- `rejection_reason` if rejected
|
||||||
|
- `selected_candidate` if any
|
||||||
|
- `final_reason`
|
||||||
|
4. Add a specific diagnostic for the known Foy case.
|
||||||
|
5. Add docs explaining how to debug a missing scoreboard button:
|
||||||
|
- run `scoreboard_candidate_backfill`
|
||||||
|
- run relink
|
||||||
|
- run `scoreboard_correlation_diagnostics`
|
||||||
|
- inspect detail endpoint
|
||||||
|
6. Keep diagnostics out of normal UI.
|
||||||
|
7. Do not emit raw sensitive data.
|
||||||
|
8. Do not emit unsafe URLs.
|
||||||
|
|
||||||
|
## Files to Read First
|
||||||
|
|
||||||
|
- `AGENTS.md`
|
||||||
|
- `ai/architecture-index.md`
|
||||||
|
- `ai/repo-context.md`
|
||||||
|
- `ai/orchestrator/backend-senior.md`
|
||||||
|
- `backend/app/rcon_historical_read_model.py`
|
||||||
|
- Backend correlation/relink code delivered by TASK-148.
|
||||||
|
|
||||||
|
## Expected Files to Modify
|
||||||
|
|
||||||
|
- One backend diagnostic command module or the existing diagnostics module.
|
||||||
|
- Existing safe correlation/read helper files only if necessary.
|
||||||
|
- Focused backend diagnostic tests using fixtures/mocks.
|
||||||
|
- One focused documentation file for the debug workflow.
|
||||||
|
- This task file after moving it through the workflow.
|
||||||
|
|
||||||
|
Do not add frontend debug surfaces or widen the normal detail payload for this
|
||||||
|
task.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- `python -m compileall backend/app`
|
||||||
|
- `python -m app.scoreboard_correlation_diagnostics --server comunidad-hispana-02 --match comunidad-hispana-02:1779310451:1779315851:foywarfare`
|
||||||
|
- `python -m app.storage_diagnostics`
|
||||||
|
- `powershell -ExecutionPolicy Bypass -File scripts/run-integration-tests.ps1`
|
||||||
|
- `node --check frontend/assets/js/historico-partida.js`
|
||||||
|
- `node --check frontend/assets/js/historico.js`
|
||||||
|
- `node --check frontend/assets/js/historico-recent-live.js`
|
||||||
|
- Review `git diff --name-only` and confirm the changed files match this task.
|
||||||
|
|
||||||
|
## Manual Verification
|
||||||
|
|
||||||
|
1. Run diagnostics for Foy and verify it explains why `1562115` is selected or
|
||||||
|
why no candidate is selected.
|
||||||
|
2. Run diagnostics for a match without public candidate and verify it explains
|
||||||
|
no candidates found.
|
||||||
|
3. Normal frontend pages do not show diagnostics.
|
||||||
|
|
||||||
|
## Commit Message
|
||||||
|
|
||||||
|
`chore: add scoreboard correlation diagnostics`
|
||||||
|
|
||||||
|
## Outcome
|
||||||
|
|
||||||
|
Document diagnostic fields, known Foy output behavior, documentation added,
|
||||||
|
validation performed, and any follow-up task instead of expanding normal UI
|
||||||
|
payloads.
|
||||||
|
|
||||||
|
## Change Budget
|
||||||
|
|
||||||
|
- Prefer fewer than 5 modified files.
|
||||||
|
- Prefer changes under 200 lines when feasible.
|
||||||
|
- Split follow-up work into a new task if the scope grows.
|
||||||
Reference in New Issue
Block a user