Repository navigation
dashboard: verify Pareto/ownership views against real archive schema, add utopia-nadir normalization, fix optimizer-cost telemetry gap - #691
Merged
Conversation
… add utopia-nadir normalization, fix optimizer-cost telemetry gap Issue #684 items 9 and 10 (dashboard verification + optimizer-cost telemetry fix). Telemetry (item 10): optimizer_seconds/optimizer_usd were always 0 in agent-mode runs because meter.py's automatic metering only works under host.py's headless driver (it reads a claude-code session log that only exists there) -- a SKILL.md compliance gap, not a framework instrumentation gap. commit.py now logs an optimizer_cost_warning when real wall-clock time clearly passed since the run's previous decision but the new commit still carries zero optimizer cost, surfaced in commit.py's own warnings list and on the dashboard's node detail. SKILL.md's guidance was strengthened and trimmed to stay within the repo's 5000-token skill-body budget; the long rationale moved to algorithm.md's new "Optimizer cost telemetry" section. Dashboard verification (item 9): built a synthetic multi-candidate reward+cost fixture with genuine dominance relationships (two non-dominated frontier candidates, one strictly dominated candidate) and confirmed dashboard.reduce_run's existing node shape (val/cost_usd/per_task/per_task_metrics) correctly feeds the frontend's already-tested Pareto frontier logic and per-objective Tasks-tab deltas. Also wired through round.py's real pareto-gate output schema (confirmed against the now-merged-adjacent PR #690): objective_values/objective_stderrs/pareto_archive per candidate, read off the same gate-table lookup dashboard.py already used for verdict_stable -- no round.py or commit.py changes needed. Utopia/nadir normalization: added an optional normalized-axes toggle to the Pareto scatter (lib/pareto.ts's normalizePoints, per the MOO survey's eq. 7), approximating the utopia/nadir points from best/worst OBSERVED values across the run rather than solving for them exactly. Raw units stay the default view. Per-task ownership view: added a Tasks-tab panel showing which candidate currently best-scores each task (GEPA's per-instance ownership idea), computed client-side from each GraphNode's existing per_task data. Verified against PR #687's actual compute_ownership() schema (owners/best_score/ownership_count) -- the client-side computation matches it exactly, so no new backend field or dependency on that PR landing first was needed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Osher Elhadad <Osher.Elhadad@ibm.com>
Contributor
|
🏷️ Automatic Labeling I've analyzed this pull request and added the following labels:
These labels were selected based on the PR title, description, and changed files. If you believe any labels are incorrect or missing, feel free to adjust them manually. |
This was referenced Oct 10, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue #684 items 9 and 10 only (dashboard Pareto/ownership verification + utopia-nadir
normalization, and the optimizer_seconds/optimizer_usd telemetry gap). Does not touch
round.py's gate logic (item 1/2), screening (5/6), merge_search.py (4), plan_round.py (3),
cost-reduction guidance (7), or hill-climb (8) — those are owned by sibling PRs #685-#690.
optimizer_seconds/optimizer_usdwere always 0 in agent-moderuns. Root cause:
meter.py's automatic metering only works underhost.py's headless driver(it reads a claude-code session log that only exists there) — a SKILL.md compliance gap, not a
framework instrumentation gap.
commit.pynow logs anoptimizer_cost_warningwhen realwall-clock time clearly passed since the run's previous decision but the new commit still
carries zero optimizer cost (surfaced in
commit.py's ownwarningslist and on the dashboardnode detail, same pattern as the existing
context_warning). SKILL.md's guidance wasstrengthened; the detailed rationale lives in
algorithm.md's new "Optimizer cost telemetry"section to stay inside the repo's 5000-token skill-body budget (confirmed by
test_agent_optimize_host.py/test_skill_authoring_lint.py, which my first draft tripped).reward+cost fixture with genuine dominance (two frontier candidates, one strictly dominated) and
confirmed
dashboard.reduce_run's existing node shape (val/cost_usd/per_task/per_task_metrics) correctly feeds the frontend's already-tested Pareto frontier logic andper-objective Tasks-tab deltas. Also wired through round.py's real pareto-gate output schema,
confirmed directly against PR optimizer: native Pareto archive gate + epsilon-constraint mode in round.py #690's merged diff:
objective_values/objective_stderrs/pareto_archive(inserted/reason/values) per candidate, read off the same gate-table lookupdashboard.pyalready used forverdict_stable— no round.py or commit.py change needed.(
lib/pareto.ts'snormalizePoints, MOO survey eq. 7), approximating utopia/nadir frombest/worst observed values across the run (not solved exactly, per the paper's own cost
caveat). Raw units stay the default view; normalized is additive.
each task (GEPA's per-instance ownership idea), computed client-side from each
GraphNode'sexisting
per_taskdata (lib/ownership.ts). Verified directly against PR optimizer: per-task ownership tracking for diverse parent/branch selection (GEPA-inspired) #687's mergedcompute_ownership()schema (owners/best_score/ownership_count) — the client-sidecomputation matches it exactly, so this needed no new backend field and no dependency on optimizer: per-task ownership tracking for diverse parent/branch selection (GEPA-inspired) #687
landing first.
What I found when testing against real pareto-shaped data
ParetoScatter/lib/pareto.tsfrontier logic was already correct (its own unittests cover dominance/ties) — the untested part was the integration: does
dashboard.reduce_run's real node output actually feed it correctly. A new backend test(
test_dashboard_pareto_frontier_fixture.py) proves it does, replicating the frontend'sdominance rule in Python against
reduce_run's ownval/cost_usdfields.dashboard.py'sgate_tablelookup (added forverdict_stable) was the right place to add thenew pareto-mode fields — same file already open for
verdict_stable, same per-candidate lookup,zero round.py/commit.py changes.
test_agent_optimize_host.pyandtest_skill_authoring_lint.py— trimmed to a one-line pointerwith the detail moved to
algorithm.md.Schema provenance
objective_values/objective_stderrs/pareto_archive: {inserted, reason, values, capacity, size_after}per candidate row, plus a top-levelpareto_archive: {version, objectives, capacity, points}persisted atpareto_archive.json.compute_ownership()—{owners, best_score, ownership_count}. My frontendlib/ownership.tsreimplements the samelogic client-side over data already exported today (
GraphNode.per_task), rather than dependingon
core/cap_evolve/task_ownership.py(which is computed on-demand forplan_round.py's branchplanning and persists nothing to graph.jsonl/events.jsonl for the dashboard to read).
Test plan
python -m pytest core/tests -q— 1917 passed, 1 skipped, 2 failed (bothtest_tau2_airline_eval_cost.py— pre-existing, unrelated model-pricing env failures, nottouched by this PR).
npx vitest run(frontend) — 28 files, 220 tests, all passing.npm run build— typechecks and builds cleanly;dist/rebuilt and committed (trackedintentionally per
dashboard/frontend/.gitignore).test_commit_optimizer_cost_compliance.py(compliance-warning logic),test_dashboard_pareto_frontier_fixture.py(frontier/dominated correctness against syntheticarchive-shaped data),
test_dashboard_pareto_archive_fields.py(real pareto-archive schemacarry-through).
pareto.test.ts(normalizePoints),ownership.test.ts+TaskOwnership.test.tsx(ownership computation + rendering).🤖 Generated with Claude Code