From 8646516eae0cde505e197a7e6470822dcafadf7d Mon Sep 17 00:00:00 2001 From: graphlemon Date: Thu, 6 Aug 2026 00:59:22 +0800 Subject: [PATCH] graphlemon: auto-commit uncommitted changes for 90c6ca9d-21eb-4678-ab12-2e2f5bd011fd-main-checkout-drift --- .claude/agent-memory/planner/MEMORY.md | 1 + .claude/agent-memory/planner/project_run_history_click_missing_detail_page.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .claude/agent-memory/validator/MEMORY.md | 1 + .claude/agent-memory/validator/project_thin_test_report_placeholder.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 0 deletions(-) create mode 100644 .claude/agent-memory/planner/project_run_history_click_missing_detail_page.md create mode 100644 .claude/agent-memory/validator/project_thin_test_report_placeholder.md diff --git a/.claude/agent-memory/planner/MEMORY.md b/.claude/agent-memory/planner/MEMORY.md index 315b793..5203846 100644 --- a/.claude/agent-memory/planner/MEMORY.md +++ b/.claude/agent-memory/planner/MEMORY.md @@ -4,3 +4,4 @@ - [deploy_health_check.py HTTP-timeout comment missing](project_deploy_health_check_http_timeout_comment_missing.md) — HEALTH_CHECK_HTTP_TIMEOUT (line 26) has no comment directly above it, unlike its sibling STARTUP_TIMEOUT; distinct open fact, don't conflate the two - [artifact overview click-through bug: RESOLVED](project_artifact_overview_click_through_bug.md) — re-verified 2026-08-06, all 3 gaps fixed (data-artifact-id, #/artifacts/:id route, mountArtifactBrowser seeding); re-check before trusting "resolved" long-term - [org-strip click-through bug: 3 render sites, not 1](project_org_strip_click_through_bug.md) — renderOrgStrip (dashboard), v_task_detail's inline org-strip, and #/graph's renderOrgGraphTopology all share the same no-click gap; DAG/log/artifact display mechanisms already exist and must be reused, not rebuilt; no new backend endpoint needed +- [run-history click → missing run detail page](project_run_history_click_missing_detail_page.md) — gc_runs_list click only switches task selector, no #/runs/:run_id route exists (documented trade-off, not a bug regression); DAG-panel+log-viewer funcs are run-object-generic and reusable verbatim; backend needs one new by-run_id query since _work_nodes_for_run already exists keyed by run_id diff --git a/.claude/agent-memory/planner/project_run_history_click_missing_detail_page.md b/.claude/agent-memory/planner/project_run_history_click_missing_detail_page.md new file mode 100644 index 0000000..ff21adb --- /dev/null +++ b/.claude/agent-memory/planner/project_run_history_click_missing_detail_page.md @@ -0,0 +1,59 @@ +--- +name: project-run-history-click-missing-detail-page +description: Investigation findings for "运行历史(gc_runs_list)点击跳转错误 + 缺运行详情页" — root cause confirmation and exact reusable pieces, needed for SDD/Benchmark content of this task. +metadata: + type: project +--- + +Investigated 2026-08-06 for "控制台运行历史点击后跳转错误的 bug,并补上缺失的运行详情页" +(graph_manifest planned same session). Confirmed by reading the code (not by trusting the task's +framing): + +**Root cause, confirmed exactly as stated**: `mountArtifactsOverviewPanel()` +(`frontend/app.js:1530-1580`) renders `#gc_runs_list` from the real, working +`GET /api/work-graph-runs?project_id=` (`work_graph_run_query.list_work_graph_runs`). Row click only +calls `onSwitchToTask(li.dataset.runTaskId)` → `mountGraphConsole`'s `loadTaskAndRender`, which just +re-selects that task in `#gc_task_select`. There is genuinely no run-detail route today — the +existing inline comment at app.js:1524-1529 documents this as a deliberate FR-5 trade-off ("Graph +run rows are the one exception... since there's no separate 'run detail' route"), not an oversight +to silently work around. + +**What already exists and must be reused, not rebuilt**: +- `renderGraphVisualizerPanel(run, {enableNodeClick:true})` (app.js:981-1025) + `mountWorkNodeClickExpand` + (app.js:1053-1062) + `renderLogViewerHtml`/`mountLogViewer` (app.js:1078-1140) is the *entire* + "node list + per-node live/static log" mechanism already, used today per-task inside + `mountGraphConsole`. It takes one `run` object shaped `{run_id, org_node, graph_manifest, nodes: [...]}` + — nothing here is task-scoped internally except how the caller obtains that `run` object. A new + `#/runs/:run_id` page can call these same functions directly. +- `mountLogViewer` already implements exactly requirement #2 (live WS tail via `connectLogTailSocket` + → `/api/ws/work-nodes/:id/log` for non-terminal nodes, falls back to static `GET + /api/work-nodes/:id/log` on close/terminal status). Do not touch backend log write/push code. +- Router pattern to copy: hash routes with a dynamic segment already exist for `#/tasks/:task_id`, + `#/artifacts/:artifact_id`, `#/skills/:skill_id/audit` (app.js:77-106, regex-matched in `render()`, + not a full path router). `#/runs/:run_id` should follow the exact same `ROUTE_RE` + `render()` + branch pattern, not a new routing mechanism. + +**Backend gap, confirmed real**: no endpoint queries a single `work_graph_run` by `run_id` today. +`task_query.get_task` (`src/task_query.py:115-171`) builds `work_graph_runs` (each including +`nodes` via the already-existing private helper `_work_nodes_for_run(conn, run_id)`, +task_query.py:174-198) but only filtered `WHERE task_id = ?`. The cheapest correct fix: add a +sibling query function (e.g. in `work_graph_run_query.py`, which already exists and already owns +the "query work_graph_run across/outside a single task_id" responsibility per its own docstring) +that does `SELECT run_id, task_id, org_node, graph_manifest, status, started_at, completed_at FROM +work_graph_run WHERE run_id = ?` and calls the same `_work_nodes_for_run` (may need exporting from +task_query or duplicating the one query — duplicating a single small query is cheaper than +cross-module coupling here; Code Agent should pick based on how `_work_nodes_for_run` is +imported/underscored elsewhere). New route: `GET /api/work-graph-runs/:run_id`, 404 if missing +(mirrors `_handle_execution_log_get`'s NotFound handling). + +**How to apply**: when writing the SDD, scope this as (a) one new backend query fn + one new GET +route returning `{run_id, task_id, org_node, status, started_at, completed_at, nodes: [...]}`, +(b) one new hash route `#/runs/:run_id` composing the existing DAG-panel + log-viewer functions +verbatim, (c) a one-line change to `gc_runs_list`'s click handler +(`window.location.hash = "#/runs/" + li.dataset.runId` — note: needs `data-run-id` added next to +the existing `data-run-task-id`, since the run_id itself isn't currently a `data-*` attribute on +that `
  • `) — do not touch `list_work_graph_runs`/the list rendering itself per the task's explicit +constraint #4. Also update or remove the now-stale app.js:1524-1529 comment ("since there's no +separate 'run detail' route") once the route exists, and decide whether `mountGraphConsole`'s +existing per-task run panels should also link to the same `#/runs/:run_id` page for consistency +(not required by the task, but worth a one-line decision note either way). diff --git a/.claude/agent-memory/validator/MEMORY.md b/.claude/agent-memory/validator/MEMORY.md index 63c93d7..7479f6a 100644 --- a/.claude/agent-memory/validator/MEMORY.md +++ b/.claude/agent-memory/validator/MEMORY.md @@ -3,3 +3,4 @@ - [deploy_health_check comment resolved + stale-benchmark pattern](project_deploy_health_check_comment_resolved_stale_benchmark.md) — line 24 comment now PASS-verified; a task's benchmark.md can be superseded by that task's own later code_diff/test_report - [Fake-DOM escapeHtml harness gotcha](feedback_fake_dom_escapehtml_harness.md) — ad hoc app.js DOM harnesses need real textContent->innerHTML escaping or escapeHtml() falsely looks blank - [Known pre-existing supervisor test failure](project_known_preexisting_supervisor_failure.md) — RollbackPathBFailureTest fails deterministically, unrelated to src/ diffs; confirmed via pre-image checkout +- [Thin test_report placeholder, solid diff](project_thin_test_report_placeholder.md) — task 837fc183 test_report.md was just a launch stub; code_diff was solid, verified independently anyway diff --git a/.claude/agent-memory/validator/project_thin_test_report_placeholder.md b/.claude/agent-memory/validator/project_thin_test_report_placeholder.md new file mode 100644 index 0000000..66c1915 --- /dev/null +++ b/.claude/agent-memory/validator/project_thin_test_report_placeholder.md @@ -0,0 +1,29 @@ +--- +name: project-thin-test-report-placeholder +description: A task's test_report.md artifact can be a near-empty "workflow launched in background" placeholder even when the code_diff is real and solid -- don't treat placeholder test_report content as a signal to distrust the diff. +metadata: + type: project +--- + +Task 837fc183-f87f-41d9-8bc9-6262d7172834 (Org Graph 三节点条点击可达详情 fix, +verified 2026-08-06) had a `test_report.md` artifact whose entire content was: +"Launched the ... workflow ... in the background ... I'll be notified when it +completes; no further action needed right now." -- i.e. a stub, not an actual +test report (no assertions listed, no pass/fail summary). + +**Why:** despite the thin test_report, the actual `code_diff.patch` was +complete, well-commented, correctly wired (routing regex, click handlers, +history.replaceState, deep-link auto-focus, `getLatestRunForOrgNode` +ascending-array-last-wins logic matching `task_query.py`'s `ORDER BY +started_at` ASC), and came with its own new smoke test +(`frontend/test_org_click_through_smoke.js`, 23 assertions, 0 exit code) that +actually ran clean. Independent verification (reading the full diff, running +`node frontend/test_*_smoke.js`, running `python3 -m unittest discover -s +src`, tracing backend `ORDER BY`/API-shape assumptions) found no defects. + +**How to apply:** a thin/placeholder test_report.md is not itself grounds for +FAIL or INCONCLUSIVE -- keep verifying independently via the real code_diff, +run whatever tests exist, and judge on that evidence. It's worth noting as a +pipeline/process observation (parallel to [[project_zero_diff_terminal_state_gap]]-style +gaps), not as a substantive defect, unless independent verification actually +turns up a problem. -- libgit2 0.21.4