Repository navigation
Review measured request profiles and decisions across optimization rounds - #389
david6666666 wants to merge 9 commits into
Conversation
Agent-assisted-by: Codex (implementation and verification) Signed-off-by: david6666666 <530634352@qq.com>
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Review at head What I checked
Questions / requested changes
Minor, non-blocking: in Static review of the diff plus Reviewed commit range: |
…e package The run review showed a green "Quality passed" next to a red "FAIL" and left the reader to work out why, printed a six-decimal baseline, and labelled every trace link "events:12" - a file line, not a destination. This makes the round readable first and exact second. - Lead each round with its recorded outcome in words: the gain against the target, the accuracy result and the round decision, in one sentence. The verdict and quality fields stay visible. - Round measurements to a readable precision, localise durations, and label the trace action "Open event" with the line kept in the tooltip and label. - Give the stage strip what a reader asks for: event count, rounds touched, recorded span, the current stage and a failure marker. Where only the campaign log speaks - hypotheses, knowledge retrievals, search dimensions - say so as log evidence rather than claiming the stage was recorded. Move the dashboard, live server, timeline, workflow projection and the trace modules out of harness into a new observability package, with the view template beside them. This follows docs/module-layout.md, which already holds the template as a view artifact rather than harness code, and keeps the read-only surface in one place. Imports, packaging, tests and docs follow. Refs #345, #333.
3b25c10 to
65dcef7
Compare
Captured from the H3 image campaign: a round that passed accuracy but missed the target, the stage strip with event counts and log evidence, and the same round in Chinese. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head 3b25c1057a7c1cdca8e92239e4b8a00e745fd6e3 (full diff; no earlier review in seed).
Blockers
-
Generated campaign snapshot is in the tree.
_state.json(new, repo root) is a one-lineload_dashboardpayload for campaignh3-image-b300(synthetic: false), includingrun_workflow, optimization traces, and thechart/temporalSVG. Nothing in the diff loads it, and it is outsideevidence/<campaign-id>/. Drop it from the revision. A fixture belongs under tests and has to be a minimal synthetic file that a test actually reads. -
Run review never shows the recorded attempt result.
src/inferrsi/observability/template.htmlattemptResult(around line 648) returns null unlessoptimization_trace.steps.state === 'present'. The trace section state this loader emits iscomplete/partial. The snapshot in_state.jsonshows that shape:batch-eightanddit-fp8both havesteps.statecompleteand a non-empty attemptresult(the FP8 result includes SSIM 0.8764 and mean RGB error 12.18). Those sentences are skipped, and the Outcome line falls through tooutcomeSentence. Accept a recorded attemptresultwhen the section state iscomplete(and when a partial section still carries items).presentis the story-object token, not the trace-section token. -
The fallback Outcome sentence misstates the measurement. Same template,
outcomeSentence(around lines 661–663):- Every signed
improvement_pctis labeled "Latency fell" / "Latency rose". The row already hasmetric_key,metric_unit, anddirection(minimize/maximize). A non-latency metric, or a maximize metric, renders a false sentence. Phrase the change from those fields. - The short-of-target branch always inserts an ideographic comma (
,) before "short of the … target", including when the UI language is English. The later clauses join with,. Use the active language's separator in both places.
This is the sentence reviewers see for every current row, because of blocker 2, and it remains the legacy-row sentence after that check is fixed.
- Every signed
-
Validator progress can replace the quality verdict.
docs/dashboard.md(around line 77) says progress never sets the run verdict.examples/qwen21_turbo_quality.py(around lines 140–144) writesprogress.jsoninside the sametrythat buildsreports. Theexcept Exception(around line 146) then discardsreportsand storesverdict: FAIL. Trigger:args.inferrsi_runis set andINFERRSI_RESULT_PATHis missing (KeyError), orlifecycle.atomic_write_jsonraises. A passing manifest list, or a real quality failure, becomes an I/O error verdict. Compute the verdict fromreportsfirst. Write progress in a nested try that leavesresultunchanged when the write fails.
Checked
- Runner
node()emits a start event (state=running) and a matching_endevent withelapsed_secondsand the command status returned byexecute_checked(src/inferrsi/harness/runner.py). run_workflowpairs start/_endby(kind, side, trial), keeps one identical edge, and marks conflicting edgesunknown.tests/test_dashboard_workflow.pycovers in-flight replay, cancel/skip, invalid progress counts, and redaction of command/tool payloads.- In-repo imports,
pyproject.tomlpackage data, the dsh template path, anddocs/module-layout.mdfollow the move frominferrsi.harness.dashboard*/inferrsi.data/dashboard/template.htmltoinferrsi.observability.
Follow-up
validation_progress calls .get on the progress.json snapshot whenever _object_snapshot reports a state other than missing (src/inferrsi/observability/dashboard_data.py, around the new validation_progress call). If a non-missing corrupt snapshot is not a dict, load_dashboard raises and the live poll fails. Ignore a non-dict the same way other corrupt artifacts are skipped.
Not verified
Tests were not executed. CI was not inspected. The harness → observability import graph was reviewed from the diff only.
I will re-read after the author pushes.
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head 65dcef749816a996e48bfed5d1e510f2628470db (full diff). pr/prior-reviews.md had no earlier findings and no previous head was seeded.
This review does not approve the change. I will re-read after the author pushes.
Blockers
-
Live "Current" stage sticks on the first start event.
src/inferrsi/harness/runner.pynode()(about line 52) appendsstate=runningand never rewrites that line; the finish is a second_endevent (about line 64).src/inferrsi/observability/template.htmlrenderWorkflow(about line 825) then doesevents.find(e => e.details?.state === 'running'). On a running run whose log issource_snapshot(running),source_snapshot_end(completed), thenquality_validation(running),findreturns the source snapshot, so Current stays on that stage for the rest of the run.stageFacts(about line 799) setsopenfrom the same sticky flag and nothing reads it; usingopenwould mark every stage that has already started. Current should follow the still-open workflow node (a start with no later_end), whichrun_workflowalready computes. -
A crashed trial is shown as an incomplete record.
src/inferrsi/observability/dashboard_workflow.pyabout line 76 treats onlyfailed,error,timeout, andcancelledas terminal.crashedis an allowed event state and is already a run state on the skipped path just below, but a node whose end state iscrashedfalls through tounknown. Trigger:measurement_endwithstate=crashed(includingexecute_checkedreturning that status throughnode()). The progress card renders "Record incomplete" andcompleteddoes not advance, while the node row still says crashed. Includecrashedwith the other terminal states. The stage strip has the same hole:stageFactspaintsstage-failedonly forfailed,error, andtimeout. -
Stage span is drawn when some timestamps are missing.
template.htmlstageFacts(about lines 787–796) says the span is withheld when any timestamp is missing, but it only requires one parseable time. Untimed events are dropped, so the shown span can be shorter than the stage. Trigger: two events in one stage, one withtimenull or unparseable. Omit the span in that case, matchingrun_workflowwall time, which already requires every start and end. -
Non-object validation progress aborts the candidate load.
src/inferrsi/observability/dashboard_data.pyabout lines 730–732 callsvalidation_progressfor every snapshot state other thanmissing. That function callsrecord.getimmediately. Trigger:validation/progress.jsonis a non-dict (for example[]), or the snapshot value isNonefor a corrupt or unreadable file.AttributeErrorfailsload_dashboardfor that run unless_object_snapshotalready guarantees a dict for every non-missing state; this diff does not show that guarantee. Callvalidation_progressonly for a dict. Any other present-but-unusable file should take the existing unknown-count path (state=unknown, no exception), the same path illegal counters already use.
Checked in the diff (not executed)
- Observability move:
cli.py,campaign_records.py, package-data, the template path, and the tests included here importinferrsi.observability. tests/test_dashboard_workflow.pymatches the projection for an identical duplicate edge, a conflicting end →unknown, a legacy measurement without_end→ unknown performance, cancel → skipped accuracy, and validator counters (cases, null total,completed > total→ unknown, private fields not exported).node()writes a start plus_end, and measurement / quality validation copyrecord["status"]onto the end event.- The Qwen validator writes
{"unit":"manifests","completed","total"}next toINFERRSI_RESULT_PATHwhenargs.inferrsi_runis set.
Not verified here
- Tests were not run. CI was not inspected.
- The review workspace only had the seeded diff, so leftover
inferrsi.harness.dashboard*imports outside this diff were not searched. examples/qwen21_turbo_quality.pycallslifecycle.atomic_write_json, which this diff does not define.
Follow-ups (non-blocking)
outcomeSentenceintemplate.html(about line 663) always inserts the Chinese comma,in the shortfall clause, including when the UI language is English.- No test covers
node()pairing, or a non-completed command status becoming the_endstate instead of the defaultcompleted.
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head bd996535f83c4f6d2f990f07109ce5b8dc91d880.
pr/prior-reviews.md is empty and previousHead is unset, so this pass covers the full synchronize diff.
Blockers
-
Outcome sentence states latency and inserts an ideographic comma in every language.
src/inferrsi/observability/template.htmloutcomeSentence(about line 657). The gain is alwaysLatency fell/Latency rose, while the same block printsrow.metric_unitand the row hasdirection. The below-target branch uses\uFF0Cwith nolanguagecheck, so English becomesLatency fell 5.0%\uFF0Cshort of the 10.0% target.
Trigger:improvement_pctbelowminimum_improvement_pct(comma);direction === "maximize"or a non-latencymetric_unit(wording).
Expected: join withlanguage === 'zh' ? '\uFF0C' : ', ', and phrase the gain fromdirectionplusmetric_unit/metric_key. -
The stage strip labels the filtered stage as in-flight.
template.htmlrenderWorkflow(about line 825).hereisstageSelect.value || <first running event's stage>, and both thecurrentclass and the "Current" label followhere.
Trigger: selected candidatestate === "running"with a running event in one stage, and the stage filter set to another stage. The filtered stage shows "Current"; the stage that still hasdetails.state === "running"does not.
Expected: keepselectedfor the filter, and applycurrent/ "Current" only to the running stage.events.findalso takes the firstrunningevent in list order, so an older unclosed start outranks a later one. -
A non-object
validation/progress.jsonfails the snapshot.src/inferrsi/observability/dashboard_data.py(about line 731) callsvalidation_progress(progress)for everyprogress_state != "missing".validation_progressindashboard_workflow.py(about line 115) callsrecord.getimmediately.
Trigger: the file is present and the snapshot value is not a dict (null,[], or another non-object).load_dashboardraisesAttributeErrorand the run cannot be reviewed.
Expected: treat a non-dict like the existing invalid-count path (quality groupstateunknown, candidate still returned).
tests/test_dashboard_workflow.pycovers well-formed objects,completed > total, and private-key redaction. It does not cover a non-object file. -
Native-only fields are read on the external-protocol path.
template.htmlrenderCandidatereadsrow.optimizationandinfo.code_locations(about line 879) beforeif (row.external && row.external.protocol)(about line 886). That block previously ran only after the external return.renderRunReview(about line 724) readsrow.run_workflow.groupsfor every row withrun_id.run_workflowis added on the native candidate return;dashboard_external.pyis a pure rename in this diff.
Trigger: render a selected external protocol row withoutoptimization.code_locations, or arun_idrow withoutrun_workflow.render()throws, sorenderDetailandlocalizePagedo not run. Default selection still prefersexternal.metrics.
Expected: guard missingoptimizationandrun_workflow, and keep the external return ahead of native-only fields unless an external fixture shows those fields are always present. A node test that renders an external protocol row and a native run would lock this.
I will re-read after the author pushes.
Verified
runner.pynode()writes a start event and aphase_endevent withelapsed_seconds, mapsKeyboardInterrupttocancelled, and copies theexecute_checkedstatus onto the end event when the command returns.run_workflowpairs start/end inside one run, collapses identical duplicate edges, marks conflicting edges unknown, withholdswall_secondswhen a timestamp is missing or an end is before its start, and leaves the run verdict untouched (test_dashboard_workflow.pyexpectsnot_recorded).- Progress counts accept only int
completed/totaland unitscases,samples, ormanifests. Extra keys such asprivatestay off the candidate row. - Codex / Anthropic activity labels keep command text, tool output, and error messages out of the exported event.
- Package data, the
files("inferrsi")template path, CLI imports, and theCampaignTracedoc path move together toinferrsi.observability.
Follow-ups
logFactsalways sets a knowledge note, including "No capture recorded", andrenderWorkflowappends that log line whenever the stage has no events. A not-applicable knowledge stage picks up the line. Attach it when the stage is in use.- "Review the failed check" is created only when both medians are non-null. A quality failure without medians still has the table "Open event" control.
examples/qwen21_turbo_quality.pywritesprogress.jsoninside the validatortry. A missingINFERRSI_RESULT_PATHor aPath.with_namefailure becomes verdict FAIL through the existingexcept. Keep that I/O off the quality verdict.- This diff adds no node/browser test for the run-review section, the stage strip, or trace labels.
Not verified here
Pytest, node UI tests, and CI were not run. The three new PNGs were not inspected. INFERRSI_RESULT_PATH's directory was not traced to {run}/validation/. Modules outside this diff were not searched for remaining inferrsi.harness.dashboard* imports.
|
Incremental review: Blocking
Smaller issues in the new stage strip
Still open from my previous review at Method: static review of the incremental diff plus the head files, and I ran |
The first move carried the dashboard and the trace readers but left the modules that write and verify trace evidence in harness: the campaign log, the narrative resolver, the knowledge capture and the campaign records. A reader looking for the trace logic found half of it. Move those four into observability as well, so the package holds the whole read-only record path: capture, log, story, trace parsing and the dashboard that renders them. harness keeps the execution side - runner, scenarios, evaluation and reporting. Imports, tests and docs/architecture.md follow. Refs #345, #333.
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head ee11d3ba270686d805e65087dc6391d0ac2b2461 (incremental bd996535f83c4f6d2f990f07109ce5b8dc91d880..ee11d3ba270686d805e65087dc6391d0ac2b2461).
This review does not approve the change. I will re-read after the author pushes.
Still open (from the review of bd996535)
The incremental diff does not touch src/inferrsi/observability/template.html, so both blockers remain.
-
Outcome sentence states latency and inserts an ideographic comma in every language.
src/inferrsi/observability/template.htmloutcomeSentence(about line 657). The gain is alwaysLatency fell/Latency rose, while the same block printsrow.metric_unitand the row hasdirection. The below-target branch uses\uFF0Cwith nolanguagecheck, so English becomesLatency fell 5.0%\uFF0Cshort of the 10.0% target.
Trigger:improvement_pctbelowminimum_improvement_pct(comma);direction === "maximize"or a non-latencymetric_unit(wording).
Expected: join withlanguage === 'zh' ? '\uFF0C' : ', ', and phrase the gain fromdirectionplusmetric_unit/metric_key. -
The stage strip labels the filtered stage as in-flight.
template.htmlrenderWorkflow(about line 825).hereisstageSelect.value || <first running event's stage>, and both thecurrentclass and the "Current" label follow that value. A stage filter is treated as the live stage.
Trigger:stageSelect.valueset while another workflow node is still open (start event with no later_end).
Expected: keep the filter as a view constraint. Mark Current from the still-open workflow node, whichrun_workflowalready computes — not from the firststate === 'running'event and not from the selected stage.
This push
bd996535..ee11d3ba only relocates campaign_records.py, knowledge_capture.py, optimization_log.py, and optimization_story.py from src/inferrsi/harness/ to src/inferrsi/observability/. Checked the seeded hunks:
campaign_records.pyrelative imports now use.dashboard_dataand.optimization_trace(was..observability.*).dashboard_data.pylazy-imports.optimization_story(was..harness.optimization_story).cli.pyandtests/test_campaign_records.py,tests/test_optimization_story.py,tests/test_optimization_trace.pyimport the new modules.- The other three moves are content-identical (
similarity index 100%), so relative imports among those four modules stay valid. docs/architecture.mdlists the observability modules.
No new blocker in those hunks.
Not verified
Tests were not run. No full-tree scan beyond this incremental diff for leftover inferrsi.harness.{campaign_records,knowledge_capture,optimization_log,optimization_story} imports. CI was not checked.
|
Incremental review: This commit: it looks clean. The four moves ( Still not approving. Nothing from my review at
Method: static review of the incremental diff, plus a repo-wide grep for the old module paths at Reviewed: |
… knowledge Signed-off-by: David Chen <530634352@qq.com>
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head 6d0207f5380c006ab4a65f0aee64d13dfbeb32d2 (incremental ee11d3ba270686d805e65087dc6391d0ac2b2461..6d0207f5380c006ab4a65f0aee64d13dfbeb32d2).
This review does not approve the change. I will re-read after the author pushes.
Still open (from the review of ee11d3ba)
This range edits template.html (round inputs, event dialog, trace panel removed) but does not change outcomeSentence or how here is chosen.
-
Outcome sentence states latency and inserts an ideographic comma in every language.
src/inferrsi/observability/template.htmloutcomeSentence(about line 660; not in this diff). The gain is stillLatency fell/Latency rosewhile the same block printsrow.metric_unitand the row hasdirection. The below-target branch still uses\uFF0Cwith nolanguagecheck, so English becomesLatency fell 5.0%\uFF0Cshort of the 10.0% target.
Trigger:improvement_pctbelowminimum_improvement_pct(comma);direction === "maximize"or a non-latencymetric_unit(wording).
Expected: join withlanguage === 'zh' ? '\uFF0C' : ', ', and phrase the gain fromdirectionplusmetric_unit/metric_key. -
The stage strip labels the filtered stage as in-flight.
src/inferrsi/observability/template.htmlrenderWorkflowline 929 still doesif (here === stage.name)and appendsCurrent. This diff only dropsjumpNoticeon that button.hereis stillstageSelect.valueor the first event withdetails.state === 'running'.
Trigger: choose a stage in the strip, or a running log whose firststate=runningevent is an earlier stage that already has an_end.
Expected:Currentfollows the still-open workflow node (a start with no later_end), whichrun_workflowalready computes. A stage filter must not paint that stage as in-flight.
New blockers
-
selection_rulesis not required to be a list.src/inferrsi/observability/optimization_trace.pyline 164 calls_strings(space["selection_rules"])._stringsis[_string(item) for item in value], so a JSON string is walked one character at a time and accepted.applied_skillsin the same function already rejects a non-list.tests/test_optimization_trace.pytest_selection_rules_are_optional_and_remain_bound_to_the_tracesetsselection_rulesto"invalid"and expectsTraceError.
Trigger: a trace whosesearch_space.selection_rulesis a string.
Expected:isinstance(..., list)before_strings, same asapplied_skills, and raiseTraceError("invalid_format"). -
Default lexical ranking calls
early.getwhenearlyis None.src/inferrsi/knowledge_operations.pyline 646. The filter isauthority != "package" or (not task_ranking and early.get("index_type") != "packaged-skill"). The next line isif early is not None and not matches(...), soearly is Noneis a real state (task-lexical reaches it via short-circuit). Forweighted-lexical-v1withauthority == "package",early.getruns and raisesAttributeErrorbefore that guard. The previous check usedself.records()[identity]and did not touchearly. This aborts the wholecollect, not one id.collect --relevancestill defaults toweighted-lexical-v1.
Trigger:collect --relevance <cue>(or capture with--relevance-method weighted-lexical-v1) when the package peekearlyis None.
Expected: ifearlyis None, do not call.get. Keep the catalogindex_typecheck for non-task ranking; only task-lexical should admit non-skill package records. -
Profile-first live view never polls.
src/inferrsi/observability/review_template.htmlline 60 setsconst live = data.live === true, and line 268 only callspoll()when that is true. Mode text isREAD ONLY · OFFLINEotherwise. This diff never setsliveon the snapshot data. The JSON payload is escaped before the template is read (dashboard.pyaround line 313), and the main template still switches onliveMode, whichreview_template.htmldoes not read.
Trigger:render_dashboard(..., live=True)forreview_layout: profile_first.
Expected: the embedded data haslive: true(or this template reads the same flag astemplate.html) so/api/statepolling starts.
Follow-ups (not blocking)
- Profile gap copy is latency-only.
review_template.htmlaround line 201 always says "Best measured reduction", and_round_trendlabels the axis "Speedup index" wheneverreview_layout == "profile_first", includingdirection === "maximize". The minimize/maximize ratios themselves match the target math. A target>= 100on a minimize baseline still renders a negative "Target latency" (ref * (1 - target/100));_round_trendalready drops that reference. task_scorecallsjson.dumps(_skill_selection.py). The import hunk only showsposixpathandre. If lines 1–3 do not importjson, everytask-lexical-v1score raisesNameError.
Not verified
Tests were not executed, and CI was not checked. Binary screenshots docs/dashboard-profile-review.png and docs/dashboard-profile-trend.png were not inspected. render_dashboard references view (dashboard.py around line 318) while its parameter is snapshot; the binding, if any, sits in the lines above this hunk and was not in the diff. If view is unbound, every dashboard render raises NameError.
Signed-off-by: David Chen <530634352@qq.com>
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head b3f748616d704706e380c0c72fada92ffefed74e (incremental 6d0207f5380c006ab4a65f0aee64d13dfbeb32d2..b3f748616d704706e380c0c72fada92ffefed74e).
This review does not approve the change. I will re-read after the author pushes.
Still open (from the review of 6d0207f)
This range updates docs/dashboard-profile-*.png and tools/plugin_bundle.py. src/inferrsi/observability/template.html is unchanged, so both blockers remain.
-
Outcome sentence states latency and inserts an ideographic comma in every language.
src/inferrsi/observability/template.htmloutcomeSentence(about line 660 at6d0207f; unchanged in this range). The gain is stillLatency fell/Latency rosewhile the same block printsrow.metric_unitand the row hasdirection. The below-target branch still uses\uFF0Cwith nolanguagecheck, so English becomesLatency fell 5.0%\uFF0Cshort of the 10.0% target.
Trigger:improvement_pctbelowminimum_improvement_pct(comma);direction === "maximize"or a non-latencymetric_unit(wording).
Expected: join withlanguage === 'zh' ? '\uFF0C' : ', ', and phrase the gain fromdirectionplusmetric_unit/metric_key. -
The stage strip labels the filtered stage as in-flight.
template.htmlrenderWorkflow(about line 825 atbd996535;6d0207fand this range leave howhereis chosen unchanged).hereisstageSelect.value || <first running event's stage>, and both thecurrentclass and the "Current" label usehere. A selected filter stage is painted in-flight. With no selection,events.findofdetails.state === 'running'stays on the first start, becauserunner.pynode()records finish as a separate_endevent and does not clear the earlierstate=runningline.
Trigger: stage filter set to any stage, or a running log whose first stage has already ended (source_snapshotrunning,source_snapshot_endcompleted, later stage running).
Expected: Current follows the still-open workflow node (a start with no later_end).stageSelectonly chooses which stage detail is shown.
Checked in this range
tools/plugin_bundle.pybundle_runtime:data/dashboard*.htmlis no longerpackage_data. HTML whose parent parts are exactly("observability",)is now copied. Diff only; bundler not run. Ifdata/dashboard/*.htmlis still a runtime input, thatpackage_dataclause still needs to stay.docs/dashboard-profile-review.png,docs/dashboard-profile-rounds.png, anddocs/dashboard-profile-trend.pngare binary. Pixel content not inspected. Screenshots do not change the two template paths above.
Not verified here
Tests not executed. CI not checked. template.html behavior is carried from the review of 6d0207f, where outcomeSentence and here were already unchanged.
|
Incremental review of the two new commits ( Resolved
Still failing / open
New code — questions Reviewed: |
Signed-off-by: David Chen <530634352@qq.com>
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head 0cea874aa2b7720cd9cd228a86f8a281568e1429 (incremental b3f748616d704706e380c0c72fada92ffefed74e..0cea874aa2b7720cd9cd228a86f8a281568e1429).
This review does not approve the change. I will re-read after the author pushes.
Still open (from the review of b3f7486)
src/inferrsi/observability/template.html is not in this range, so both earlier blockers remain.
-
Outcome sentence states latency and inserts an ideographic comma in every language.
template.htmloutcomeSentence(about line 660 at6d0207f; unchanged since). The gain is stillLatency fell/Latency rosewhile the same block printsrow.metric_unitand the row hasdirection. The below-target branch still uses\uFF0Cwith nolanguagecheck, so English becomesLatency fell 5.0%\uFF0Cshort of the 10.0% target.
Trigger:improvement_pctbelowminimum_improvement_pct(comma);direction === "maximize"or a non-latencymetric_unit(wording).
Expected: join withlanguage === 'zh' ? '\uFF0C' : ', ', and phrase the gain fromdirectionplusmetric_unit/metric_key. -
The stage strip labels the filtered stage as in-flight.
template.htmlrenderWorkflow(about line 825 atbd996535; howhereis chosen was still unchanged at6d0207f).hereisstageSelect.valueor the first event withstate === 'running', and that value drives both thecurrentclass and the "Current" label.
Trigger: a stage filter is selected, or a later stage is the open one while an earlier event is stillstate === 'running'.
Expected: use the filter only to choose which stage's detail is shown. Mark Current from the still-open workflow node (a start with no later_end).
New in this range
-
Native runs no longer record phase completion or duration.
src/inferrsi/harness/runner.pyremovesnode()(thefinallythat emittedphase + "_end"withstateandelapsed_seconds) and now only callsevent("source_snapshot")(line 161),event("measurement", ...)(line 167), andevent("quality_validation")(line 183), with no terminal state.tests/test_dashboard_workflow.pylines 84–85 and 111 lock that in: a start-onlyquality_validationevent leaves the workflow nodeunknownwhileexecution.jsonstill says failed, sorow["quality"] == "failed"and the stage state isunknown. A cancelled or failedexecute_checkedno longer writes that status onto the phase event.
Trigger: any native run after this revision, including Ctrl+C and a non-zero validator.
Expected: keep the start/_endpair (completed, failed, or cancelled, plus elapsed seconds). Fix the strip intemplate.html(item 2) so Current follows the open node; dropping_endleaves every native stage unknown. -
A withheld capture disappears from the review.
dashboard.pyline 302 storesunavailable_profilesfromread_profiles, andtests/test_profile_timeline.pyexpects a tampered source to become([], ["baseline"]).review_template.htmlrenderCaptures(line 448) only keeps captures withduration_us > 0and hides#capture-sectionwhen that list is empty. Nothing readsunavailable_profiles.
Trigger: the rawprofiles/*.json[.gz]is missing or its SHA-256 no longer matches the summary.
Expected: show each unavailable id in the capture section with the failure, including when no timeline remains. -
New timeline copy uses an ideographic stop, and one clause is untranslated.
review_template.htmlline 288 always appends\u3002, so English readsMatched baseline capture span 1.2 s; this capture 0.9 s\u3002. Line 438 appends' \u00b7 Open trace file\u3002'outsidetr(), so Chinese keeps the English fragment and English keeps\u3002.
Trigger: a candidate whosecomparison_keymatches the baseline (line 288); the source-file fold in either language (line 438).
Expected:language === 'zh' ? '\u3002' : '.', and put "Open trace file" in bothtr()strings.
Follow-ups
renderCaptures(line 451) takes the firstphase === 'baseline'capture as the only comparison target. A later baseline with the candidate'scomparison_keygets no span sentence and no baseline GPU column.- Each dashboard snapshot and each
/api/profile-events/request re-reads and hashes every raw capture (up to 64 MiB, 16 captures). That will dominate a live refresh once a trace is large.
Verified in this range
- Profile attachment stays under
profiles/<name>.json[.gz], with the parent path resolved against the campaignprofiles/directory. The event table is content-addressed;/api/profile-events/<sha256>is served only when that digest is registered and the gzip bytes match. Overview rows keep lane, name, start, and duration; the new test expects argument strings such as/privateto be absent. - The 256-bin difference array matches the node fixture in
test_full_profile_reader_checks_original_bytes_and_tracks_overlapping_events(gpu bins 2 and 3).
Not verified here: tests were not executed, CI was not inspected, and template.html was not re-opened from the tree (it is absent from this diff). This range also deletes six docs/dashboard-*.png files; the docs/dashboard.md hunks do not drop image links, and the unchanged doc body was not in the seed.
|
Incremental review: Resolved
Questions about the runner change
New code:
Still open from earlier reviews This commit doesn't touch
Reviewed: |
Signed-off-by: David Chen <530634352@qq.com>
Signed-off-by: David Chen <530634352@qq.com>
|
@amy-why-3459 @cursor PTAL at
On Windows, 158 dashboard, profile, Qwen, and search tests passed, plus 8 subtests. Ruff passed. In Chrome I also verified both the three real timelines and the list of unavailable IDs when every capture is withheld. |
amy-why-3459
left a comment
There was a problem hiding this comment.
LGTM
PR review verdict — PASS
Reviewed base main and head b9fe71c23fca52f7625e99ba87161f6076989a33. This is an incremental review of 0cea874aa2b7720cd9cd228a86f8a281568e1429 … b9fe71c23fca52f7625e99ba87161f6076989a33 (2 commits, 14 files), checked against my comment at 0cea874 and the latest bot review.
Verified:
- Native runs.
runner.pyis unchanged frommain. The dashboard now gets terminal state and command duration from each trial's or validation'sexecution.json(command_state,dashboard_data.pyL611-631). The open step comes fromstatus.jsonphaseplus the latest start (dashboard_workflow.pyL242-246). A recorded_endthat disagrees with the command record makes the stepunknown.test_dashboard_tracks_real_native_abba_and_validationdrives the realrun_experimentAB/BA flow and checks, at every step, that exactly the right node is running. - Stage strip. Current now follows the open workflow nodes (
stageFacts/renderWorkflow), separately from the stage filter. Untimed events suppress the stage span, and crashed or failed states are marked. There is a Node regression test for all of this. - Outcome sentence. The wording comes from
metric_key+direction(rose/fell/unchanged), with a neutral "Measured change" fallback. Joiners and punctuation are localized.attemptResultacceptscompleteandpartialtraces and uses the last recorded attempt. - Profiles.
- Overview polls reuse a digest keyed on dev/inode/mode/size/mtime_ns/ctime_ns (
_overview_digest). Opening the event table rehashes only the selected source. - Tests cover a same-size edit with the mtime restored, and an atomic replacement.
- The 512-lane limit is now enforced at attach time.
- Unavailable capture IDs are listed, and the baseline is matched only by a unique
comparison_key. - The attach, decode and lane limits and the positive-duration rule are documented in
docs/dashboard.md. review_template.htmlL288/L438 punctuation and the Perfetto instruction are localized.
- Overview polls reuse a digest keyed on dev/inode/mode/size/mtime_ns/ctime_ns (
- Validation progress. Invalid or unparsable
progress.jsonkeeps the command-level verdict and count. The Qwen validator writes next toINFERRSI_RESULT_PATH, and a failed progress write doesn't change either verdict. - Search.
skill_scorerejectstask-lexical-v1. The only caller (knowledge_operations.pyL685-688) sends task ranking totask_score. The PR body now documents the breaking import migration and the different campaign/standalone relevance defaults. - CI. At this head, full-check (3.10/3.11), installed-package (3.10/3.11), lint-and-smoke, declarations and pr-references all pass.
Not verified: I didn't run the tests locally. This review is based on reading the diff and the files at this head.
There was a problem hiding this comment.
PR review verdict — DO NOT PASS
Reviewed base 4b3afa55f278ca314e07d5f8acbd0a18f3fa72bf and head b9fe71c23fca52f7625e99ba87161f6076989a33 (incremental 0cea874aa2b7720cd9cd228a86f8a281568e1429..b9fe71c23fca52f7625e99ba87161f6076989a33).
This review does not approve the change. I will re-read after the author pushes.
Resolved from the review of 0cea874
src/inferrsi/observability/template.html is in this range.
-
Outcome sentence.
outcomeSentencenow takes the verb fromdirection(rose/fell/was unchanged) and the noun frommetric_key(latency*→ Latency,throughput*→ Throughput, otherwise the key; "Measured change" when direction is missing). The below-target join islanguage === 'zh' ? ',' : ', '.test_round_outcome_and_stage_strip_follow_recorded_evidencelocks the English strings (throughput rose / fell / unchanged, and a non-latency key). -
Stage strip.
renderWorkflowno longer treatsstageSelect.valueor the firstdetails.state === 'running'event as in-flight.currentand the Current label followstageFacts().open, set only when a workflow node isrunningon a candidate whosestate === 'running'. The same test selects diagnosis and asserts validation is the current stage, and that a crashed row clearsopen.
Attempt results: attemptResult at this head's parent still required steps.state === 'present'. It now accepts complete / partial and uses the last non-empty attempt. That test covers it.
Blockers
-
A non-dict execution or validation snapshot aborts the dashboard load.
command_stateinsrc/inferrsi/observability/dashboard_workflow.py(new helper,record.getimmediately) does not checkisinstance(record, dict).load_dashboardnow feeds it_object_snapshotpayloads whenevermissing_reason != "file_absent":- measurement:
native["measurement", side, trial] = command_state(execution)insrc/inferrsi/observability/dashboard_data.py(trialexecution.jsonbranch) - quality:
native["quality_validation", None, None] = command_state(validation)in the same file
This diff changes
validation_progressto return None unlessrecordis a dict, andtest_validator_counts_for_native_and_paired_traceswrites[]and{intovalidation/progress.jsonand still callsload_dashboard. Those values reach the snapshot consumer. The same helper's execution payload is not guarded.execution.jsoncontaining a JSON array (or any non-dict) raisesAttributeErrorinsidecommand_state. One bad trial file drops the run view. The native runner records command state without_endevents (test_dashboard_tracks_real_native_abba_and_validationexpects every nodeend is None), so this path is the one that decides the work-unit state.Trigger: a present
execution.jsonor validation record whose JSON value is not an object.
Expected: do not call.geton a non-dict. Leave the native entry unset, same asfile_absent, so the event-derived state (including a still-open running start) stays intact. A malformedprogress.jsonalready must not replace command-level state; a malformed command record should not either. Returning("unknown", None)and taking thenot end and commandbranch would still wipe a live start, because that branch does not treat"unknown"as "no command record". - measurement:
Follow-ups (not blocking)
refreshElapsedintemplate.htmllabels every livedata-startedcell "Phase duration".workDurationuses that label only whenduration_source === 'phase'or both endpoints exist. An open step has neither a paired_endnor a command elapsed (docs: phase finish time stays unknown without_end).skill_scorenow rejectstask-lexical-v1(src/inferrsi/_skill_selection.py).test_raw_string_selection.pyexpects theValueError. Callers outside this diff were not traced.
Not verified
Tests were not executed. CI was not checked. Of the new limits in docs/dashboard.md, this diff shows 64 MiB (_MAX_FILE) and 512 duration lanes (_MAX_LANES, tested). The 16-capture, 2³⁰-character, 2,000,000-event, and 128 MiB compact-table figures are not in the incremental diff.
Refs #333 and #345.
Open a profiled campaign to see the performance trend first, then the acceptance test, the request profiles, the round measurements and the adoption decisions. The review works live and as an offline HTML export. There is no change to
src/inferrsi/harness/runner.pyrelative to main.What the profile shows. A fresh 4096×4096 single-card run started by capturing a complete warm worker request with torch.profiler/Kineto. Of 5.35 s in the worker, six denoising steps occupied 4.49 s. The captured launch correlations attributed about 2.32 s to the two largest projection GEMM families and 1.61 s to dense attention. HTTP latency was timed separately without the profiler. The dashboard initially shows representative stage, CPU and GPU tracks; zoom, search or load the complete event table to inspect individual events. The original trace stays local. A repeated capture with the same comparison key shows whether the bottleneck changed.
How the evidence influenced the trials. The first candidate combined paired Q/K kernel launches. The repeated capture verified that launches fell from 600 to 300, but GPU time only fell from 148.9 to 146.3 ms. Paired HTTP latency was 5.432 → 5.404 s (0.52%, within noise); all six RGB pairs matched. The bottleneck remained in the projections and attention. The second candidate split each projection's 16,416 rows into 16,384 aligned rows and a 32-row tail, retaining the full K dimension. It measured 5.411 → 5.408 s (0.06%) and changed pixels in all six output pairs. Neither candidate was adopted. The 50% target was not reached.
Evidence and discovery. Each round links its actual retrieval, used skills, choices and outcome. Profiles are explicitly registered and hash-checked; only a bounded projection of timing data is served, without stacks or raw event arguments. The trend compares paired measurements and distinguishes incompatible runs. Campaign search now considers portable discovery skills and engine records under the specified hardware and workload; captures distinguish the total matched, the number returned and the resources actually loaded.
Use
campaign init --profile-first --backend cuda,campaign attach-profileanddashboard --live; the recording guide includes the review file and command. Existing campaigns and historical event records remain readable. The screenshot is hosted on the PR's existing preview branch; the PR adds no image files todocs/.Python import migration (breaking). Change
inferrsi.harness.<module>toinferrsi.observability.<module>forcampaign_records,campaign_trace,dashboard,dashboard_data,dashboard_external,dashboard_live,dashboard_timeline,knowledge_capture,optimization_log,optimization_story, andoptimization_trace. For example, importCampaignTracefrominferrsi.observability.campaign_trace. The CLI entry points remain available.Native run evidence. The runner keeps main’s start-only phase log. The dashboard takes terminal states and command durations from the snapshot and execution artifacts, and identifies the open native step from the running status and latest start. A phase finish timestamp requires a recorded end event. Historical paired events still provide phase durations. Invalid validator progress leaves the command result visible.
Search defaults.
campaign capture-context --relevanceusestask-lexical-v1to discover both portable skills and applicable repository records. Standalonecollect --relevanceretains its existing skill-only default. Pass--relevance-method task-lexical-v1to use the campaign ranking with standalone collection.Verification. 233 dashboard, trace, campaign and packaging tests passed locally, and Ruff passed. Verified rendering in desktop and phone viewports, the live connection and loading all 530,926 complete duration events from the baseline capture. The two experimental trials ran with main's runner on one B300.