-
A merged graph's one run genuinely spans several org_nodes now (Planner/ Coder/Validator all append their own nodes into the SAME run) -- a single run-level org_node column was never accurate once Phase 2b/2c landed, and real per-node ownership already lives in work_node_execution.subagent_type. Schema: work_graph_run.org_node column removed; ux_work_graph_run_active narrowed from UNIQUE(task_id, org_node) to UNIQUE(task_id) WHERE status NOT IN ('done', 'failed') -- 'blocked' now counts as active on purpose, since resuming a blocked run always appends into the same row rather than inserting a fresh one. New migrate_drop_work_graph_run_org_node() handles already-populated databases, wired into backend_server.py's startup path. Call sites updated: work_graph_plan.py/work_graph_fork.py/ root_cause_trace.py's INSERTs; work_graph_run_query.py/task_query.py now return "org_nodes_involved" (derived from work_node_execution.subagent_type) instead of the removed single-value "org_node"; frontend/app.js's org-strip and run-list rendering updated to the list-based shape. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Implements org-graph-unification-phase2-universal-self-planning-design.md §2.3, §3, §6 -- Coder's implement_code() no longer runs one hardcoded synthetic "implement" node; it self-plans via plan_work_graph(conn, "coder", ..., append_to_run_id=run_id), appending its own nodes onto Planner's existing work_graph_run instead of creating a separate one. - work_graph_plan.py: per-org_node suggested node-type catalogs (_CODER_NODE_CATALOG/_VALIDATOR_NODE_CATALOG, "starting points, not requirements" same as _PLANNER_NODE_CATALOG), new judgment/on_fail/ promotes_to_artifact fields in the generic planning prompt. New plan_work_graph(..., append_to_run_id=...) parameter: merges newly planned nodes into an existing run (node_id collision -> raise, never silent overwrite), returns new_node_ids so callers can avoid reprocessing nodes an earlier stage already promoted to artifacts. New shared dispatch_build_prompt() for graphs mixing Planner-shaped (artifact_type) and Coder-shaped (task_prompt) nodes side by side. - e2e_pipeline.py: _write_completed_node_artifacts() now also promotes nodes declaring promotes_to_artifact (not just Planner's artifact_type nodes), with an only_node_ids scope so a merged-graph caller doesn't re-touch artifacts an earlier stage already wrote. implement_code() reworked around self-planning; code_diff stays Python-computed (a real git diff, not any node's own content -- no node can know the diff ahead of running it), test_report is promoted from whatever the self-planned graph declares, falling back to a synthesized concatenation if it declares none. needs_worktree=True now passed to run_graph() for Coder (found missing entirely during this rework -- harmless with the old single-node manifest, a real 03-C §3.6 gap once concurrent code-writing nodes are possible). Also fixed a real bug found while wiring this up: _review_planner_output_with_retries()'s "reuse existing artifacts" branch hardcoded run_id=None, even though every real artifact row already has a valid produced_by_run_id -- Coder had nothing to append into on that resume path. - work_graph_fork.py: _reconstruct_build_prompt now dispatches per-node (via the new shared dispatch_build_prompt) instead of requiring the whole graph to be one uniform shape -- a real regression Phase 2b would otherwise have introduced silently, since a forked merged graph can now genuinely mix both node shapes. Sequencing note (unchanged from Phase 2a's own finding): work_graph_run's org_node column removal and the ux_work_graph_run_active index narrowing (design doc §2.1/§2.2) stay deferred to Phase 2c -- Validator still creates its own separate run until Validator also appends into the shared one, so narrowing the index to task_id-only now would collide with it. python3 -m unittest discover -s src (752 tests) + discover -s supervisor -p "test_*.py" (126 tests) both green, zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
…4843-main-checkout-drift
-
Implements docs/todo/dynamic-work-graph-design-skill-design.md. G already answered FR-2 (how to mark a parallel-eligible node group): no new field needed -- topological_layers() infers independence purely from depends_on/edges, so the new Skill's job is just "express real dependencies honestly, don't add fake ones." New Skill skills/design-dynamic-work-graph/SKILL.md: the node-boundary / zero_token-vs-needs_judgment / per-node self-contained task_prompt methodology, wired into agent_profile.py's FRONTMATTER for coder and validator (Planner's own doc-chain path is untouched -- FR-4 only names Coder/Validator). work_graph_plan.py: new _GENERIC_PROMPT_TEMPLATE + generic_node_prompt_builder(), used whenever org_node != 'planner'. Planner keeps its existing fixed brd/prd/sdd/benchmark/... chain (_PROMPT_TEMPLATE) completely unchanged -- zero regression risk to the one real production planning path. Scoped per the requirements doc's non-goal #1 ("prove the mechanism works, don't cover every real scenario yet"): does NOT wire into e2e_pipeline.py::implement_code()'s existing single-node production path. New tests prove the mechanism itself: a Coder scenario that naturally splits into 3 independent modules produces a correctly-shaped graph_manifest, topological_layers() puts all three in one concurrent layer (ties E directly to G), and generic_node_prompt_builder drives it through run_graph() to completion. Full src suite (580 tests) passes with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
Root cause traced (docs/implementation-gap-analysis.md): the Benchmark document Validator relies on for its verdict was frequently a narrative about the work session ("The planner workflow completed and produced a Benchmark defining 18 scenarios...") instead of the actual scenarios -- found via a real skill-detail-page task's benchmark.md, then confirmed present since the earliest real self-hosting runs. Validator's own judgment was, in practice, resting on thin, sometimes-vacuous prose. Planner's work graph (brd->prd->sdd->benchmark) extends to benchmark->test_dataset->test_script: test_dataset/test_script are always present as nodes, but the generating subagent judges per-goal whether a real dataset/script applies (many goals, e.g. UI wiring, legitimately don't have one -- replying 'N/A: <reason>' is a real, expected answer, not a failure). test_script gets a genuinely mechanical verify_fn (real py_compile/node --check, not LLM judgment) -- the one node type where an objective check is actually possible. All four document prompts also gained an explicit anti-narration instruction (only 'brd' had a weaker version of this before). Coder's implementation prompt now receives the real benchmark/dataset/ script and must make the Planner's real script pass for real, not just whatever tests it invents on its own. Validator gets its own 3-node Work Graph (validator_benchmark -> validator_test_dataset -> validator_test_script), generated independently from SDD/PRD -- deliberately NOT reusing Coder's or Planner's own copies, same reasoning as a held-out eval set vs. the dev set a model was tuned against. The resulting script, if real, is actually executed against the current repository state; a non-zero real exit code force-overrides the verdict to FAIL in code (user-confirmed hard gate: the script is not up for LLM debate on a failure, only on a pass can subjective judgment add INCONCLUSIVE/risk notes). schema.py: artifact.artifact_type's CHECK constraint gains the 5 new types, plus migrate_expand_artifact_types() -- SQLite has no ALTER-based constraint migration, so this is the standard rebuild-copy-swap dance, applied for real to the live ~/.graphlemon/graphlemon.db (42 rows, verified byte-identical count before/after, integrity_check clean). skills/qa-task-validation.md and skills/project-sdd-planning.md already gained a standing principle from this same incident: verify cross-task data dependencies against real system state, not seeded fixtures alone (see prior commit d7035fc) -- this commit is the mechanism-level half of the same fix, not just the prose-guidance half. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
The 6th real self-hosting attempt (first to reach the full 4-node doc-writing graph after the previous five bugs) hit a genuinely new failure: this real graph_manifest had no edges at all, not just wrong field names -- worse than the case _normalize_graph_manifest already handled. With zero dependency info to normalize from, topological_order() scheduled 'benchmark' before 'sdd' (alphabetically first among zero-in-degree nodes), and build_prompt() crashed with KeyError: 'sdd_content' trying to format a template needing sdd's not-yet-produced output. _PROMPT_TEMPLATE always asks for exactly the same fixed 4-node linear chain -- that's a constant architectural fact, not something that should be re-inferred from the LLM's output every call. _normalize_graph_manifest now deterministically enforces brd->prd->sdd->benchmark whenever all four canonical artifact_types are present, regardless of what depends_on/edges the LLM did or didn't provide. Same "机制用代码" principle as ensure_worktree_committed and the earlier normalize logic. Three new regression tests: zero dependency info still gets the chain enforced, node_id != artifact_type still resolves to the real node_id (not a guessed string), and a partial set (missing one of the four types) is correctly left alone rather than guessed at. 560 tests green (440 src + 120 supervisor). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
U-031: closes a structural integration gap found during the REQ-01~14 regression audit -- plan_work_graph/execute_work_graph/run_work_node were each individually tested but never actually called together in production code (e2e_pipeline.py's only validated closed loop bypassed all three via flat org_node_trigger calls). Adds work_graph_orchestrate.py (topological sort over graph_manifest + one one-node dynamic-workflow agent() call per Work Node, needed for REQ-06's per-node breakpoint recovery), rewires e2e_pipeline.py's plan_documents/ implement_code onto the real chain, and fixes two bugs a real API run surfaced: graph_manifest's id/node_id/depends_on normalization (work_graph_plan._normalize_graph_manifest) and a missing repo_path in run_work_node's cwd resolution. work_node_run.py also now marks a node 'blocked' instead of leaving it stuck 'running' on any unretryable run_fn exception. U-024.5: the regression audit also found REQ-12's reconnect boundary case (refetch a snapshot after a dropped WS reconnects) was never implemented -- only the dashboard reacted to onStatusChange, and even it never refetched. Fixes mountDashboard/mountTaskBoard/mountTaskDetail (which embeds v_graph_visualizer) to refetch their current snapshot on reconnect. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
plan_work_graph(): real `claude --agent <org_node> -p` call, produces a graph_manifest (4 nodes for brd/prd/sdd/benchmark, dependency-chained sdd->prd->brd, each edge tagged zero_token/needs_judgment per 03-C §3.4), recorded as a work_graph_run row (status='planning' -- 04-P p_work_graph_execution start_state). Does not execute the plan or produce real artifacts -- 03-C §3.4 says so explicitly ("不执行,只规划"). Real call surfaced a genuine, undocumented constraint: --json-schema is silently ignored when combined with --agent (structured_output never appears; the identity itself works fine -- the response referenced the migrated SOUL.md's own principle numbering). First attempt at this Unit failed against the real API for exactly this reason. Fixed by asking the model to fence its JSON and parsing it out of `result` instead (_extract_graph_manifest, tolerant of bare JSON / fenced blocks / an extra wrapper key). Documented centrally in 05-实施约束与依赖.md §5.4.1.1 since this will matter for any future Unit needing agent-identity + structured output together, not just this one. Also corrects the same class of Done-line overreach as U-009/U-010 (development-plan.md claimed U-011 alone satisfies REQ-02's happy case, but c_work_graph_plan's own contract explicitly excludes execution) and flags a real, previously-invisible gap found while tracing REQ-02's actual dependencies: no Unit in development-plan.md's 43-unit breakdown owns c_artifact_write (03-C §3.7), despite REQ-02's happy AND failure cases both requiring it directly. Not fixed here -- noted for whichever Unit (U-012/ U-013, most likely) needs it first. 15 new mocked stdlib unittest cases + 1 gated real test (re-run and passing after the --json-schema fix). 98 total mocked tests across U-001-011, all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>