Skip to content

fix(console): correct desk completeness, presentation and next run - #1170

Merged
Pigbibi merged 6 commits into
mainfrom
s2/desk-corrections-20261114
Nov 14, 2026
Merged

Pigbibi merged 6 commits into
mainfrom
s2/desk-corrections-20261114

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

AI assistance

Claude Code, model Claude Opus 5.5 (claude-opus-5-5), working as the single implementing writer for the SAME-S2 batch against an independent audit (sections 2, 3, 4 and 6).

What changed

Block 1: shared completeness (#2/#3/#4). todaySummary (application/console_api/operations.js) now keeps the runtime-daily reader's own read_summary.status decision. An accepted projection whose outer read is incomplete stays partial/incomplete, so it can no longer become a known-null last_run or a covered zero. Legacy bodies without read_summary keep the existing reconstruction, which now also checks the record's own incomplete kind/status. A missing or malformed read_summary on a body that does carry the field counts as incomplete.

Block 2: coverage, failure reasons, observation time (#3/#23/F1).

  • runsToday keeps read_failed as its own outcome: a summary of only failed rows is unknown/read_failed. It is never source_unavailable and never verified-empty. Mixed coverage records read_failed among the coverage reasons.
  • runRowCovered no longer treats a missing weekend record (non_trading_weekend) as covered, so the tape is never verified-empty on that basis.
  • The tape and ribbon freshness keep the stored as_of of every record that was read, stale incomplete ones included. The tape observed_at no longer falls back to request time; without a stored instant it is unknown/time_basis_unavailable.
  • Overview freshness keeps the stored age when every displayed account fact is stale, instead of reporting unavailable. Totals are unchanged: no partial or stale facts become a total.

Block 3: presentation (#4/F2/F3). Recent Signals shows the newest five runs, newest first. A loading ribbon shows a loading note instead of "no signals". A populated partial or stale list keeps its coverage or age note. A stale NAV is marked stale on the figure and shows its stale label and age.

Block 4: Performance (F4/F5). The minimum-set metadata is now always rendered: requested window, first stored date, portfolio and per-target return basis, and the truncation note. This applies whether or not a curve exists. The live N1 path never calls api.benchmarks() (/api/market-benchmark/performance), even when a curve becomes available. The gate is benchmarkReadAllowed(source), true only for fixture (mock) pages. Live pages show a note that the comparison is not read.

Block 5: #6 option 1/1a, next scheduled observation.

  • todaySummary(..., { schedule: true }) is an explicit opt-in that adds schedule (state, business_date, timezone, next_due_at) to each row. The default output is unchanged. worker.js only passes the option through deskN1Deps().runtimeDay: no interception, no wrapping, no second read.
  • The ribbon opts in only for the current New York business day's existing read. nextScheduledRun returns:
    • known (or stale with age) only when every configured account has a complete, schedule-verified record whose next_due_at is still after request time;
    • partial for the earliest observed candidate when coverage is incomplete;
    • unknown for missing, null, past, conflicting, duplicate, disabled, unevaluable, schedule-unverified or wrong-day records.
  • runs_today.expected/pending stay null.
  • The TopBar shows the read in its known/stale/partial/unknown states. A time already past is shown as unknown, and the chip is hidden behind the access lock.
  • The contract is documented in docs/desk-n1-read-projection-contract.md.

Bound files changed (16):

  • web/strategy-switch-console/application/console_api/operations.js
  • web/strategy-switch-console/application/desk/overview.js
  • web/strategy-switch-console/application/desk/ribbon.js
  • web/strategy-switch-console/worker.js
  • web/strategy-switch-console/frontend/src/desk/DeskApp.tsx
  • web/strategy-switch-console/frontend/src/desk/shell/DeskShell.tsx
  • web/strategy-switch-console/frontend/src/desk/shell/TopBar.tsx
  • web/strategy-switch-console/frontend/src/desk/pages/OverviewPage.tsx
  • web/strategy-switch-console/frontend/src/desk/pages/PerformancePage.tsx
  • web/strategy-switch-console/frontend/src/desk/i18n/en.ts
  • web/strategy-switch-console/frontend/src/desk/i18n/zh-CN.ts
  • web/strategy-switch-console/v2_asset_map.js (regenerated by npm run build + npm run sync:v2-assets, not hand-edited)
  • docs/desk-n1-read-projection-contract.md
  • tests/runtime_today_incomplete_validation.mjs
  • tests/desk_n1_projection_validation.mjs
  • tests/console_desk_n1_validation.mjs

How verified

Dependencies installed with npm ci in web/strategy-switch-console/ and web/strategy-switch-console/frontend/. package.json and the lockfiles are unchanged.

Command Result
node --experimental-strip-types tests/console_desk_overview_validation.mjs PASS
node tests/runtime_today_incomplete_validation.mjs PASS (new: outer-incomplete reader decision, malformed summaries, legacy bodies, stale/fresh partial, schedule opt-in with one read)
node tests/desk_n1_projection_validation.mjs PASS (new: weekend without record, failed-only and mixed failure, stale-incomplete observation time, no request-time substitution, all-stale and mixed-age Overview, next-run future/expired/offset/NY day/conflict/duplicate/unevaluable/unverified/partial/stale cases, opt-in only for today's read, unchanged read count, worker pass-through). All golden fixtures unchanged.
node --experimental-strip-types tests/console_desk_n1_validation.mjs PASS (new: six runs newest-five, loading vs empty, partial/stale populated lists, stale NAV, Performance metadata truncated/non-truncated/open window, benchmark request spy on a synthetic qualified curve, next-run chip in all states, light and dark, lock concealment, zh and en)
npx tsc --noEmit -p web/strategy-switch-console/frontend PASS
npm run build --prefix web/strategy-switch-console/frontend PASS (size budget OK)
npm run sync:v2-assets --prefix web/strategy-switch-console/frontend 45 assets generated
node tests/console_v2_assets_validation.mjs PASS
npm run test:operations --prefix web/strategy-switch-console PASS (includes the frontend operations suite)
npm run check:style-guards --prefix web/strategy-switch-console/frontend exit 0 (advisory)
Other CI asset-step scripts: display_names, candidate_readiness, acceptance_budget, kv_directory, source_quota, current_strategies_kv_dedup, inbox_requests, v2_i18n, account_state, catalog_release, presentation, strategy_display_identity PASS
node tests/strategy_switch_worker_validation.mjs PASS (run without --experimental-default-type, which local Node 24 rejects)
Runtime-daily legacy consumers: fe8a_runtime_today, runtime_today_request_reuse, runtime_daily_worker, runtime_daily_multi_target, runtime_daily_health_integration, console_api_worker, console_grouping_runs, console_gap_contract, console_design_api PASS
python3 scripts/check_style.py; build_display_names.py --check; build_config.py --check; runtime_settings.py validate PASS (one pre-existing advisory README note)

Could not pass locally: node tests/console_deploy_safety_validation.mjs fails at git merge-base --is-ancestor 9722414a… because this checkout is shallow and lacks that release-source commit. That is environmental and unrelated to these files. CI with full history is authoritative.

Why

The independent audit found that todaySummary discarded the reader's completeness decision, that a missing weekend record and failed-only summaries were misreported, and that tape freshness substituted request time. It also found that Overview dropped newest-signal order, loading, partial/stale and stale-NAV qualifications, that Performance hid its minimum-set metadata and held a latent non-approved benchmark read, and that available schedule evidence was lost before the Ribbon. The owner approved this file binding and #6 option 1/1a on 2026-11-14.

Risk

🤖 Generated with Claude Code

Pigbibi and others added 2 commits November 14, 2026 18:28
todaySummary now keeps the runtime-daily reader's read_summary decision
instead of rebuilding a weaker one, so an accepted projection with an
incomplete outer read is never a known-null last run or a covered zero.
Legacy bodies without read_summary keep their reconstruction.

Desk runs-today keeps read_failed as its own outcome. A missing weekend
record is no longer verified-empty tape coverage. Tape and ribbon
freshness keep the stored observation of every record that was read and
never substitute the request time. When every displayed account fact is
stale, Overview freshness keeps their age.

The ribbon's next_run is now an opt-in schedule projection through the
existing reader: known only when every account has a future next_due_at,
partial for the earliest observed candidate, unknown otherwise.
Expected and pending counts stay null. No additional storage reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recent Signals shows the newest five runs, distinguishes a loading
ribbon from an empty one and keeps partial or stale qualification on a
populated list. A stale NAV is shown with its stale label and age.

Performance renders the requested window, first stored date, return
basis per target and truncation note even without a curve. The live N1
path no longer calls the benchmark route, which is outside the approved
sources; fixture pages keep their synthetic comparison.

The shared top bar shows the ribbon next_run in its known, stale,
partial and unknown states, treats a past time as unknown and hides it
behind the access lock. The Logs next-run copy now reads "earliest
observed scheduled run". v2_asset_map.js is regenerated by the build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Pigbibi Pigbibi added the risk:low Documentation, tests or ordinary checks; automated path classification remains authoritative. label Nov 14, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-14T11:21:37.887570Z 67246b3 Manual request
🔒 Security Review ✅ Completed 2026-11-14T11:23:57.992110Z 67246b3 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Pigbibi Pigbibi changed the title fix(console): correct S2 desk completeness, presentation and next run fix(console): correct desk completeness, presentation and next run Nov 14, 2026
@Pigbibi

Pigbibi commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

Independent end-of-batch verdict: FAIL

Head: d27c484a9ab254f02c430696be26ea3d1c09231b
Base: b1b37e5b526250043ec76353827a2a432a4b2a5a
Reviewer: Codex (GPT-6), independent of the implementing writer.

This is an owner-requested independent session review, posted through the connected account. It is not an official Codex GitHub App receipt or owner approval. The supported receipt fields above record this review's exact head, complete coverage and one unresolved finding. The native governance action authenticates reviewer identity separately.

Blocking finding B1 (P2): nextScheduledRun can choose a later instant and the wrong target.

At application/desk/ribbon.js:182–184, candidates are sorted lexically. The shared instant normalizer removes .000 but retains nonzero fractional seconds. With two complete, fresh, bound records for NY business date 2030-01-08, observed at 14:30Z and requested at 15:00Z:

Synthetic target next_due_at
firstrade/target0 2030-01-08T19:30:00Z
firstrade/target1 2030-01-08T19:30:00.500Z

Expected earliest: target0 at 19:30:00Z. Actual: known target1 at 19:30:00.500Z, coverage 2/2. Adding an uncovered third account also returns the wrong partial candidate.

I reproduced this through the source schedule-instant validator → todaySummary schedule opt-in → nextScheduledRun. The validator explicitly accepts fractional instants; this is not malformed input. No production data was read. Fix with numerical instant comparison and a target-id tie breaker for equal instants; use chronological ordering for oldest observations too. Add known/partial mixed-precision regressions, then obtain review on the new exact head.

Other required areas

  • All 16 changed files are within the approved audit binding. Root tests/ resolution follows the audit's explicit root-relative convention.
  • Shared reader completeness, weekend/failure handling, stale-incomplete observation time, newest-five/loading/partial/stale presentation, stale NAV age and Performance metadata pass the reviewed cases.
  • The qualified-live-curve benchmark method/fetch spies prove no benchmark request.
  • Schedule opt-in forwards through the existing worker dependency; no worker interception or extra storage read. Missing/conflicting/unevaluable/unverified/disabled/past-time cases and lock concealment pass.
  • No schedule-derived expected/pending count was added. Configured-account results remain unknown; the unchanged zero-configured-account case still returns 0 / empty.
  • Legacy schedule-free shape and valid complete default outputs match base; approved completeness corrections intentionally change previously misclassified outputs.
  • externalFlow remains unwired.

Implementation deviations 0–6

  1. ACCEPTED: root test paths are bound by the audit.
  2. ACCEPTED with residual: Logs wording now says earliest observed scheduled run, avoiding a global-next claim. Logs still omits status/coverage/age and holds a separate one-time ribbon snapshot. The polling TopBar is not a substitute for qualifying that snapshot; add LogsPage and its tests to a later binding.
  3. ACCEPTED with residual: all-stale and tested mixed-age F3 cases are fixed. Pre-existing mixed-currency aggregate freshness remains unavailable; expand the golden-fixture binding before correcting it.
  4. ACCEPTED: unchanged golden fixtures and null coverage total on unknown next_run are conservative; known/partial coverage is reported.
  5. ACCEPTED with residual: benchmark reads are blocked, but the unchanged panel still shows generic failure wording alongside containment copy. Add BenchmarkPanel to the later binding.
  6. ACCEPTED: legacy weekend wording remains; Desk no longer treats it as verified coverage.
  7. ACCEPTED: production schedule/flow/history/count/age claims remain unverified.

These accepted deviations do not waive B1.

Verification actually rerun

PASS: runtime_today_incomplete, desk_n1_projection, console_desk_overview, console_desk_n1; full npm run test:operations; frontend TypeScript/build/budget; all 45 regenerated assets byte-for-byte equal to tracked output; console_v2_assets; fe8a_runtime_today (21 tests), runtime_today_request_reuse, runtime_daily_worker, runtime_daily_multi_target, runtime_daily_health_integration, console_api_worker, console_grouping_runs, console_gap_contract, console_design_api; documentation style (one advisory), display/config generation checks, runtime-settings validation and diff whitespace check.

Local console_deploy_safety fails at the missing release-source ancestry check. Confirmed shallow checkout and absent source object. Hosted JS job explicitly logs that suite PASS, corroborating the environmental explanation. The independent mixed-precision probe reproduces B1 despite the green suites. Browser visual/production acceptance was not performed.

Governance observation

Inspected merged #1168's receipt and #1169's receipt: official App codex-review-state:v1 markers bind completed reviews to exact heads.

This PR now also has an official exact-head receipt, and ai-review is green. The current failure is risk-gate: R2: needs owner-approved or agent-approved, not missing review evidence. The native classifier also considers protected path tokens, not only explicit r2_paths. My reproduced finding remains unresolved despite the automated clean receipt. No label, merge, issue edit or deployment was performed.

The full local report contains the per-area evidence, complete deviation judgments, tests and next-batch proposal. That proposal requires owner approval: #7 cash-flow semantics; #8/#19 runtime-state reads; #9/#10 Q1 saved/platform comparison; #12 decisions; all class-C data prerequisites; LogsPage/BenchmarkPanel and fixture binding additions; mixed-currency freshness, unknown coverage and cross-date timestamp presentation. It authorizes no new source, collection, production read, backfill, execution or deployment. B1 must be fixed before accepting this batch.

Pigbibi and others added 4 commits November 14, 2026 18:48
Normalized instants keep nonzero milliseconds, so lexical order is not
chronological within a second (19:30:00.500Z sorted before 19:30:00Z).
Order next-run candidates and the oldest stored observation by epoch
time, keeping the target id only as an exact-tie breaker. Add known,
partial, tie, offset, sub-second past-time and one-read regressions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tape entries and the tape's oldest observation were ordered as strings.
Normalized instants keep nonzero milliseconds, so "…:00.500Z" sorted
before "…:00Z", which put entries out of order within a second, made
truncation drop the wrong entry, could pick the wrong Overview "newest five"
and gave the wrong oldest observed_at. Both now sort by epoch time; the entry
id still breaks an exact tie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Normalized instants keep nonzero milliseconds, so the Overview last run,
runs-today observation time and snapshot time now order by epoch time
instead of string order. Exact ties keep their existing behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The daily reader validates observed_at but returns it raw, so whole and
fractional seconds and UTC offsets mix. The runtime today summary as_of
now picks the earliest epoch instead of the first string. Exact instant
ties and values outside the reader's instant grammar keep the previous
string pick; no time is invented.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Pigbibi

Pigbibi commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

Independent re-review verdict: PASS WITH RESIDUALS

Repository: QuantStrategyLab/QuantRuntimeSettings — PR #1170
Head: 67246b3979cdc00858ed12e26d00fedf1755167b
Base: b1b37e5b526250043ec76353827a2a432a4b2a5a
Reviewer: Codex (GPT-6), independent session review, not the implementing writer. Date: 2026-11-14.

This is an owner-requested independent session review, prepared for verbatim posting by the coordinator. It is not an official Codex GitHub App receipt or owner approval. Reviewer identity is authenticated separately by native governance. unresolved_findings:0 means zero unresolved blocking findings for this batch; accepted residuals below remain open follow-up work.

B1 and all four fix rounds: PASS.

  • Schedule candidates now compare epochs with target-id tie-break, and candidate observations select the chronological oldest instant. Known and partial coverage both choose the whole-second target ahead of its later fractional sibling.
  • Tape entries and oldest observations compare chronologically. Truncation retains the newest 100; Overview renders the newest five correctly across whole/fractional boundaries.
  • Overview's latest finished run, runs-today observation and snapshot timestamp compare chronologically, preserving exact-tie record behavior.
  • Operations' summary as_of chooses the oldest raw instant, handles offsets and fractional precision, preserves legacy exact-millisecond tie ordering, and retains the documented unparseable-value fallback.

The original round-1 probe exits 1 because its obsolete “known defect must reproduce” assertion now sees actual equal expected. A separate post-fix expectation version passes the original validator → summary → schedule chain, including partial coverage, default-output control, one-read semantics and midnight controls. B1 no longer reproduces.

I independently restored each former comparison in a throwaway exact-head copy. Nine experiments failed at their corresponding regression assertions: both schedule selectors, both tape selectors, tape rendering, all three Overview selectors and operations as_of. The final-head suites pass. The original checkout stayed clean.

Performance ordering: ACCEPTED RESIDUAL, not blocking this batch.

performance.js:202 still selects a newest observation lexically. Synthetic qualified inputs reproduce the wrong equity/four-risk observation and a one-second stale-age discrepancy. However, the current stored-history reader sets externalFlow:null, so the qualified branch remains unreachable through current live N1 sources. The current minimum-set window/history/basis metadata is independent of that selector. Correcting only observation/age produces identical Performance rendering in both languages, even for a synthetic qualified curve. Add this out-of-binding file and regressions to the next approved batch and repair it before any qualified-live-curve activation.

Other report-only sites remain separately scoped: runtime-instance last_change_at feeds legacy account metadata; alert sightings order fixture-sourced alert items; research-promotion update ordering belongs to the separate queue. None was changed or silently declared correct. The legacy Overview queue comparator is also retained as an investigation candidate.

Full-diff scope: PASS. Exactly the same approved 16 files. Fix rounds touch only six of those files. Full source/test/documentation diff reviewed; all 45 generated frontend assets, HTML and build identifier independently rebuilt and byte-equal to tracked output. No schema/fixture/lockfile, new source, flow wiring, collection, authority or execution change. Diff whitespace and inspected secret/resource patterns pass.

Actual validation: PASS for runtime_today_incomplete, desk_n1_projection, console_desk_overview, console_desk_n1, full npm run test:operations, frontend TypeScript/build/budget and asset validation, runtime-today reuse and 21-test compatibility suite, daily worker/multi-target/health integration, documentation style (one advisory), display/config generation and settings validation. Python unittest: 1,204 tests, 10 skipped, exit 0. Independent fallback and residual probes also completed. No browser or production acceptance is claimed.

Carried residuals: LogsPage still omits candidate status/coverage/age and uses a separate snapshot; BenchmarkPanel still conflates intentionally unrequested comparison with failure/loading; mixed-currency aggregate freshness remains limited; cross-date timestamp presentation and UTC/NY overlap documentation need clarification. Unknown schedule coverage denominator remains an optional decision. Production schedule/history/flow/count/age evidence remains unverified. Round-1 deviations 0–6 remain accepted with these limits.

The refreshed next-batch draft carries all prior contract decisions and evidence prerequisites, adds Performance and other timestamp investigations, and remains a proposal requiring owner approval. It grants no production read, collection, backfill, notification, execution or deployment authority.

No current-head hosted CI or official App review state was re-read here; prior-head statuses are not reused as proof. Native R2 governance and required checks remain separate. No remote write, label, issue edit, merge or deployment was attempted. Full report: /tmp/same-s2-rereview-REPORT.md; receipt: /tmp/same-s2-rereview-receipt.md.

@Pigbibi

Pigbibi commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

Owner merge approval (recorded by coordinator)

The repository owner approved merging this PR in the coordinator chat on 2026-11-14 19:14 SGT, after the independent re-review returned PASS WITH RESIDUALS with zero blocking findings for this exact head.

Recorded by Muse (coordinator agent) on the owner's instruction. The agent-approved label added alongside records this agent-side step.

@Pigbibi Pigbibi added the agent-approved An agent cleared this high-risk change on the current head; not an owner confirmation label Nov 14, 2026
@Pigbibi

Pigbibi commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

The head has advanced through four bounded fix rounds since the last review (current 67246b3979cdc00858ed12e26d00fedf1755167b). Please review the current head.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 67246b3979

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 67246b3979

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@Pigbibi
Pigbibi merged commit aadb8f1 into main Nov 14, 2026
20 of 22 checks passed
@Pigbibi
Pigbibi deleted the s2/desk-corrections-20261114 branch November 14, 2026 11:29
Pigbibi added a commit that referenced this pull request Nov 14, 2026
…#1171)

* fix(desk): complete S2 desk observation, freshness and next-run fixes

Completion round for the SAME-S2 Desk corrections (review of #1170).

- Performance: the last qualified day's observation is the
  chronologically newest normalized instant, not the lexically last
  string; a missing or unusable instant still leaves no time basis.
- Overview: displayed-observation freshness no longer depends on
  aggregatability. Mixed-currency cohorts keep unavailable totals (no
  FX) but report the displayed facts' age. The degraded golden changes
  accordingly.
- Logs: the next-run line keeps status, coverage, the stored
  observation instant and stale age; a passed candidate expires on a
  local clock; times carry their UTC date across UTC midnight. The page
  keeps one ribbon read per open and makes no added read.
- TopBar: a next run on another UTC day shows its UTC date.
- Contract: correct the UTC-day/NY-day overlap statement and make the
  todaySummary compatibility claim precise (shape unchanged, values
  intentionally corrected). Comment-only change in operations.js.

The BenchmarkPanel state item is not included: it needs a
PerformancePage.tsx change outside the approved binding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(desk): report unrequested benchmark reads as not requested

A live Performance page never reads the benchmark source, yet it reported
that intentional non-read as "failed" (fetch-failed copy beside the
contained copy) and briefly as "loading".

- Add a `not_requested` BenchmarkState; loadBenchmarks returns it when the
  source allows no read, without calling the API.
- The page starts in `not_requested` and sets `loading` only when a read
  will be made; PerformanceView shows a disallowed source as
  `not_requested` whatever state it holds.
- BenchmarkPanel renders `not_requested` with the contained copy only.
- Tests cover live/mock phases, both languages, and the unchanged
  zero-call and single api.benchmarks( pins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-approved An agent cleared this high-risk change on the current head; not an owner confirmation risk:low Documentation, tests or ordinary checks; automated path classification remains authoritative.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant