-
Requirements doc (BRD/PRD level) for a new org-level role that monitors blocked_pending_human tasks, does real diagnosis (not blind retry), and acts within an explicit authorization boundary instead of always waiting on a literal human -- generalizing the planner_reviewer precedent (an autonomous judgment agent already replacing a human review gate) to this surface. Motivated by today's real incident: 4 tasks blocked with the same generic execution_error reason but three genuinely different root causes (stale process, legacy narrative-output format, a real concurrency bug), all diagnosed by hand. Also documents watch_resume.py's real concurrency-race flaw as a requirement input (FR-6) so the eventual implementation doesn't repeat it. Deliberately does not pick the autonomy boundary per blocked_reason -- left as an open question for explicit user sign-off, not something Planner should infer silently. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Removed the "disabled" framing from docs/done/validator-test-script- narrative-output-issue.md (moved todo/ -> done/, root cause identified, structural fix landed, spot-check clean) -- the mechanism it described (_CANONICAL_DOC_CHAIN, e2e_pipeline._VALIDATOR_MANIFEST) no longer exists in production code, superseded by the 2026-08-08 self-planning rewrite and Org Graph unification Phase 2. Planner's and Validator's self-planning catalogs already carry test_script as a suggested (not required) option; _CODER_NODE_CATALOG was the one gap -- added a matching entry there (mechanical check_script_compiles judgment, same as Validator's). All three org agents now decide per-goal whether this node is worth planning, with no remaining "this node type is globally off" switch anywhere. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Spot-check (real API spend, user-authorized) of whether the historical "narrative text standing in for real output" failure mode (docs/todo/validator-test-script-narrative-output-issue.md) recurs now that Coder self-plans its implementation graph (Org Graph unification Phase 2). Built a non-self-target temp repo with a real rate-limiter module containing a planted bug, and a goal requiring Coder to read it and produce an audit report -- the same "explore then produce content" trigger condition the original incident's root-cause analysis identified. Ran the real production path (plan_work_graph + run_graph) with RUN_REAL_AGENT_E2E=1. Result: not reproduced. The self-planned node's content was a real, line-cited audit report (correctly found the planted bug plus four other genuine issues), not narration standing in for missing work -- despite the Coder catalog's "impl" entry having no suggested_judgment, the planning LLM voluntarily attached its own narrative-detection judgment, closely mirroring work-graph-node-review's methodology. Recorded as a new timeline entry with an explicit single-run-confidence caveat and a concrete next step (_NODE_REVIEW_JUDGE_PROMPT wired directly into the catalog) if a real recurrence shows up later. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
FR-5a: a new, standalone four-stage Org meta-graph (renderOrgMetaGraph and friends) rather than extending the existing 3-node renderOrgGraphTopology (left untouched, it's pinned by test_graph_console_smoke.js). Each stage expands in place: planner/coder/validator reuse renderGraphVisualizerPanel unmodified against that stage's latest run (identified via org_nodes_involved, Phase 2c's replacement for the removed single-value org_node column); planner_reviewer has no self-planned work_graph_run, so it shows its planner_review_verdict execution_event history instead (new task_query.py::_planner_review_events_for_task(), mirroring the existing _loop_back_events_for_run() pattern). FR-5b: an attempt_number-ordered, click-to-reveal feedback timeline built from loop_back_events, which was already being fetched but never rendered. New frontend/test_org_meta_graph_smoke.js (35 assertions, same vm.Context sandbox convention as the existing 4 smoke tests). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
New skills/work-graph-node-review/SKILL.md documents the methodology for judging a self-planned Work Graph node's output (real structured content vs. narrative prose standing in for it) -- distilled from the real narrative-output incident (docs/todo/validator-test-script-narrative- output-issue.md §6) and the conditional-not-assertive phrasing lesson already applied in _NARRATION_RETRY_HINT. Scoped explicitly against planner-output-review (Planner's fixed doc chain, task-level gate), qa-task-validation (overall task acceptance), and skill-defect-remediation (rewriting a Skill file itself) -- this one judges a single self-planned node's output, nothing broader. Wired into roles/planner_reviewer, roles/coder, roles/validator role.json skills lists. .claude/agents/*.md left untouched -- that's a deploy-time artifact compiled from role.json by agent_profile.deploy_agent_definitions(), not hand-synced (confirmed stale already: coder.md is missing an even earlier Phase 2a skill addition). This completes Phase 2c (§2.1/§2.2/§6/§7.1 all implemented; §7.2's analysis was completed earlier without needing a code change). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
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>
-
Validator's terminal verdict is now a real self-planned node (node_type= 'final_verdict', judgment.kind='mechanical', on_fail.action= 'dynamic_loop_back') appended into the SAME shared work_graph_run Planner and Coder already contribute to (plan_work_graph(..., append_to_run_id= run_id)), instead of a flat post-graph org_node_trigger call against a separate hardcoded Validator manifest. This is what lets a failing verdict genuinely trigger Reflection-review + Fix-Skill + a precise loop back to whichever real ancestor node is at fault, reusing the existing dynamic_loop_back machinery instead of a parallel retry loop. The 2026-08-06 hard gate (a real non-zero exit from Validator's own test script force-overrides the verdict to FAIL, Python-enforced not just prompted) is preserved via a build_prompt wrapper + mechanical check closure sharing mutable state. INCONCLUSIVE is now treated the same as FAIL (triggers a bounded retry via dynamic_loop_back) rather than accepted as a terminal result. _VALIDATOR_MANIFEST/_VALIDATOR_DOC_PROMPTS/_VALIDATOR_VERDICT_PROMPT/ _validator_prompt_builder are kept unused (same precedent as _CODER_PROMPT). org_node column removal (§2.1), index narrowing (§2.2), and the new work-graph-node-review skill (§7.1) remain for a later sub-phase. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Found during Phase 1 real end-to-end verification (2026-08-12): 3 independent real runs, 3 different goals, all hit the same known, unrelated-to-Phase-1 issue -- a self-planned benchmark/test_script node's own judgment rejecting narrative summaries, exhausting loop_back's max_attempts. One of the three ran against the real production backend_server after the FK migration fix (bd1404d), confirming the new Phase 1 status machine routes the failure correctly (blocked_pending_human with a real diagnostic trail) even when the underlying pre-existing bug fires before planner_reviewer is ever reached. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Updates the Phase 2 SDD and requirements doc to reflect that Phase 2a (86fc0bb) and Phase 2b (7c46a2f) are done, not just designed. Records the concrete deviations/fixes found during implementation that the original design didn't anticipate: the run_id=None bug in the artifact-reuse resume path, the missing needs_worktree=True on Coder's run_graph() call, why §2.2's index narrowing needed to move from "maybe safe after 2b" to "actually needs 2c", and the test-fixture check_same_thread=False gap concurrent merged-graph layers exposed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Design for org-graph-unification-and-universal-self-planning-requirements.md §3.1's step 3, previously flagged as the largest known gap in the Phase 2 SDD. Extends §5.4's Reflection-review to judge both a target node AND a defect_kind (content_error vs skill_defect), adds §5.5 Fix-Skill (a real Validator-identity call rewriting the target node's skill_ref content, via the existing but never-wired-up skill_update.py::update_skill() + bug_record.create_bug_record()), and confirms Re-loop needs no new mechanism -- the existing _LoopBackRequested path already re-runs the target node, which picks up the new skill content automatically since Claude Code loads Skill content by name at call time, not at agent frontmatter deploy time. Two findings during design that motivated/validated this work: - org_level_loop.py's _ROUTE_FOR_CATEGORY has no 'skill_defect' key -- skill_update.update_skill() has never been called by any production path despite root_cause_trace.py being able to classify skill_defect since U-015. Fix-Skill is the first time this dead capability gets wired up for real, via a new path, not by fixing the old one. - execution_event.event_type's CHECK enum has had an unused 'skill_iterated' value since the original U-001 schema -- no new migration needed to log Fix-Skill events. Also found and recorded a third work_graph_run.org_node call site (root_cause_trace.judge_root_cause_via_work_graph) that §2.1's column- removal missed. Confirmed via AskUserQuestion: the Skill-rewrite call always runs under the Validator identity, regardless of which org_node's skill is being fixed -- avoids the self-correcting-its-own-blind-spot problem, and matches skill_update.py's own "a Validator-triggered rewrite" docstring intent from 03-C. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Phase 1 (planner_reviewer review gate + P0 resume-bug fix) shipped as ea19c7d, matching org-graph-unification-phase1-review-gate-design.md exactly (new task.status value, org role, _REQUIRED_ARTIFACTS narrowing, both bugs fixed). Moving that design doc and the P0 bug doc it subsumed to docs/done/, updating their status headers, and fixing the doc-path references left pointing at their old docs/todo/ location across agents/planner_reviewer/{SOUL,AGENTS}.md, src/schema.py migration docstrings, and the other Phase 2/deblackbox docs. Full suite green (731 tests) both before and after. Also ran Phase 2 SDD's §9 interface-reconciliation checklist against the real Phase 1 implementation now that it exists for real: all three items check out (run_id is included in plan_and_review_documents()'s return shape, the new task.status value is exactly reviewing_planner_output as assumed, and planner_reviewer's role.json doesn't pre-reserve a skill slot for Phase 2's new skill, which is fine -- a one-line addition when Phase 2c lands, not an incompatibility). Updated §9 to reflect this. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
User's key insight, recorded as a goal in the requirements doc (new §3.1): a failed node shouldn't just get a corrective retry (fix-bug, forgotten after this run) -- when the root cause is a systemic Skill defect, the Skill itself must be fixed (fix-skill, persists across all future tasks). Four-step chain: judgment fails -> Reflection-review node does full-chain root-cause diagnosis (one-off content error vs systemic skill defect) -> if systemic, a Fix-skill node calls the already-existing skill iteration machinery (skill_update.py::update_skill() + bug_record.py, real Git- versioned commits, previously only reachable via org_level_loop.py's coarse Org-level path, never from inside a Work Graph's own judgment/ loop_back cycle) -> loop back and re-run using the updated skill. Cross-referenced into the Phase 2 design doc: its dynamic_loop_back (§5) implements steps 1/2/4 of this chain but not step 3 (Fix-skill) -- flagged as the largest known scope gap in §8, not a missed detail. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Design for FR-2/FR-3/FR-4: extending self-planning to Coder/Validator, per-node subagent/skill/tools binding, and node-level precise loop_back replacing org_level_loop.py's coarse fast_lane/full_replan routing. Three findings during design research that revise the requirements doc's original FR-2 assumption ("just swap the call site"): - _GENERIC_PROMPT_TEMPLATE never solicits judgment/on_fail today -- Coder/ Validator switching to plan_work_graph() as-is would produce graphs with no judgment/loop-back capability at all. - run_graph()'s subagent_type/skill_ref are run-level constants passed to every node identically, not node-level despite work_node_execution already having columns for it -- needs a real (bounded) engine extension. - Today's on_fail.action="loop_back" target is statically declared at planning time via a single on_failure edge; it cannot express "a terminal validator dynamically diagnoses which of several ancestor nodes is the true root cause." New on_fail.action="dynamic_loop_back" designed for this, reusing root_cause_trace.py's jury/majority-vote structure with the vote target changed from a category to a node_id. Also incorporates three requirements-doc §7 decisions that were made (apparently concurrently) while this was being designed and overrule two of this doc's initial drafts: work_graph_run.org_node is removed entirely (not kept/sunk to node level) with concrete work_graph_run_query.py/ work_graph_fork.py rework; Coder/Validator get a suggested node-type catalog (not fully free-form); the append interface is a parameter on the existing plan_work_graph() (not a new function). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
… work, compress bloated incident log - Delete org-graph-as-work-graph-unified-loop-requirements.md: fully superseded by org-graph-unification-and-universal-self-planning- requirements.md; folded its one non-duplicated detail (the 2084590a benchmark-narration trigger incident) into that doc's background instead. - Split scheduler-production-polling-loop-{requirements,design}.md by completion status: FR-2 (in-flight task reconciliation, shipped) moves to docs/done/scheduler-task-reconciliation-{requirements,design}.md; FR-1 (new-goal auto-dispatch, still undecided) becomes a small standalone docs/todo/scheduler-new-goal-dispatch-requirements.md instead of staying bundled with a doc that's mostly done. - Compress validator-test-script-narrative-output-issue.md's six ad-hoc "第N轮更新" paragraphs crammed into one status line into a scannable timeline table; moved the task 2084590a benchmark evidence into §1 where the other repro examples live instead of leaving it stranded in the header. - implementation-gap-analysis.md: logged two new gaps found today (no pre-Coder review of Planner's output; node execution still depends on native Dynamic Workflow) plus the architecture.md §10.1 staleness itself, per that doc's own "edit in place" maintenance convention. - Updated the doc-path references left in src/task_execution.py and src/task_reconciliation.py docstrings to point at the new locations. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
- org-graph-unification-phase1-review-gate-design.md: implementable SDD for inserting a planner_reviewer stage (new org role, since _PRE_STATE/ _POST_STATE map org_node -> status 1:1 and can't reuse "validator" twice) between Planner and Coder. Folds in the P0 resume-artifact-assumption fix and a newly-found sibling KeyError in the fresh-run path. - graphlemon_architecture.md §10.2: records that §10.1's "方案 A" (reuse Claude Code's native Dynamic Workflow for Work Graph execution) was superseded -- the graph-orchestration layer already diverged (REQ-06 checkpoint/resume), and per today's decision the single-node execution layer is being migrated off it too, for controllability. - work-graph-node-execution-deblackbox-requirements.md: requirements+design for that migration -- replace the 3 remaining write_workflow_script/ execute_work_graph call sites with plan_work_graph()'s already-proven flat `claude --agent` + JSON-fence-extraction pattern. - Cross-referenced the two new docs from each other and from the existing P0/P2 todo docs they fold into or relate to. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Merges the fixed-flow change (Planner -> Validator -> Coder -> Validator), universal per-org-agent self-planning, node-level validator skill, and frontend dynamic/historical graph asks into one requirements doc, folding in the P0 resume-artifact bug and the P2 test_script structural-fix placeholder that were blocking on the same design. Records the user's 2026-08-08 decision to merge all four org stages into one work_graph_run (scheme A) rather than cross-graph routing (scheme B), plus the concrete schema conflicts that decision surfaces (work_graph_run.org_node's single value + unique-active-run index) for Phase 2's SDD to resolve. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
work-graph-partial-artifact-persistence and work-graph-self-planning- and-loop-back (requirements + design) are all shipped and tested; move them out of docs/todo/ and fix up the docs/todo/*.md and src/*.py path references that pointed at their old location. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Real end-to-end verification of Work Graph self-planning + loop-back (task 2084590a) hit the narrative-output problem again -- this time on a self-planned benchmark node, not test_script, disproving the earlier "BRD/PRD/SDD/Benchmark won't recur" hypothesis in validator-test-script- narrative-output-issue.md. The judge caught it once (round 3) but couldn't force a fix; the loop_back retry limit correctly exhausted and blocked the task cleanly instead of hanging or crashing. Also drafts org-graph-as-work-graph-unified-loop-requirements.md: extending today's Work-Graph-internal judgment/on_fail/loop_back mechanism up to the Org Graph itself, so Coder doesn't start from an unreviewed Planner output and a Validator FAIL can route to a precise node instead of a whole phase. Flags the real hard part (Planner/Coder each plan their own graph_manifest, so node ids don't share an address space across the org boundary) as the first open question, not yet implemented. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
…4843-main-checkout-drift
-
Mitigates the recurring test_script/validator_test_script narration issue (100% repro across 3 tasks, 6 nodes): the existing compile-error feedback buries its "not a narrative description" note under raw tracebacks, which wasn't enough to stop the model repeating narrative output on retry. Adds _NARRATION_RETRY_HINT as a separate, directive feedback item alongside the compiler detail. See docs/todo/validator-test-script-narrative-output-issue.md §6-7 for the full root-cause analysis and rationale. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
…9789-main-checkout-drift
-
…d4ef-main-checkout-drift
-
…bbe3-main-checkout-drift
-
…437e-main-checkout-drift
-
_launch_candidate() starts backend_server against a COPY of the prod db for health-checking only; without --disable-reconciliation-loop it would find resumable tasks in that copy and dispatch real claude -p calls before Deploy Supervisor decides whether the candidate is even good. Adds the flag plus a mocked-Popen regression test (LaunchCandidateArgsTest) so a future regression here fails fast instead of surfacing as a hang or a real incident. Also folds this into docs/todo/scheduler-production-polling-loop-design.md (§6.1) as part of the FR-2 design record. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Recovers tasks abandoned mid-flight (status in queued/planning_brd_prd_sdd/ coding/validating with no recent execution_event) by re-driving them through task_execution.run_or_resume_task_lifecycle on a background poll, guarded by an in-process in-flight lock to avoid double dispatch. Responds to a real 2026-08-06 incident where a task sat stuck in 'validating' for 15+ hours with nothing polling it. Scoped to FR-2 only from docs/todo/scheduler-production-polling-loop- requirements.md; FR-1 (new-goal auto-dispatch) stays out per that doc's own non-goals -- it's a separate, larger autonomy-boundary decision. Design recorded in docs/todo/scheduler-production-polling-loop-design.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Per CLAUDE.md's docs/ role split (todo = pending, done = shipped into the SDD/code): all seven Graph Engineering series items with a real implementation (B, D, E, F, G, H -- A had no separate doc, resolved directly in graphlemon_architecture.md; C is explicitly won't-do) now have their requirements+design docs moved from docs/todo/ to docs/done/, git mv'd to preserve history. Every cross-reference to the 12 moved files -- across the other moved docs themselves, graph-engineering-open-items.md, 2 Skill files, and 9 src/*.py docstrings/comments -- updated from docs/todo/<file> to docs/done/<file>. Verified no stale docs/todo/ references to any of the 12 filenames remain anywhere in the repo. graph-engineering-open-items.md itself stays in docs/todo/ (not moved) -- it's a living index that keeps gaining new entries from later comparison-note/gap-analysis passes (H itself was added this way, and a new item already appeared while this cleanup was in progress), not a single finished conclusion. Its own header now reflects that all of A/B/D/E/F/G/H are done and explains why it wasn't moved. Also fixed two pre-existing stray path references (missing todo/done/ prefix entirely, predating this cleanup) in its G section. Full src suite (625 tests) passes -- this is a pure documentation/comment change, no behavior touched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Implements docs/todo/role-package-abstraction-design.md. Requirements review (docs/todo/graph-engineering-open-items.md's H section) had already corrected the requirements doc's own dependency analysis before this; scope confirmed with user 2026-08-06: relax all 4 org_node CHECK constraints in one pass, not staged. Format is JSON, not YAML: 05 §5.7's pure-stdlib constraint rules out PyYAML, and unlike Skill files (whose YAML frontmatter only Claude Code itself ever parses, never this codebase's own Python), role.json genuinely needs to be read by agent_profile.py -- json.load is the zero-risk choice over a hand-rolled parser. role.json is a REFERENCE manifest, not a content copy: identity.soul_md_path/ agents_md_path still point at the untouched agents/<role>/SOUL.md/AGENTS.md files. This is what makes "deployed output must stay identical" close to automatic -- render_agent_definition()'s body-assembly logic doesn't change at all, only the frontmatter's data source does (hardcoded FRONTMATTER dict -> parsed role.json). Verified byte-for-byte: diffed the old (git HEAD) render_agent_definition() output against the new one for all three roles, zero differences. agent_profile.py: ORG_NODES is now discovered by scanning roles/ for role.json files (_discover_role_ids()) instead of a hardcoded 3-tuple; FRONTMATTER/_DESCRIPTIONS/_MIGRATED_FROM_PROFILE dicts are gone. Every public function takes an optional roles_dir override specifically so a test can prove "a new role needs zero code changes" against a throwaway fixture directory (NewRoleWithoutCodeChangeTest) rather than asserting it by inspection. schema.py: skill.owner_org_node/task.assigned_org_node/work_graph_run.org_node/ agent_profile.org_node relaxed from CHECK(x IN ('planner','coder','validator')) to CHECK(x != ''). Real blast radius found during design (bigger than the requirements doc's own risk note): task/work_graph_run/skill are referenced by several other tables' foreign keys, but since only the parent tables' own CHECK text changes (child FK definitions are untouched), only these 4 parent tables need rebuilding -- followed SQLite's documented procedure for schema changes under active foreign keys (foreign_keys=OFF for the duration, rebuild, foreign_key_check to confirm nothing went dangling, foreign_keys=ON). migrate_relax_org_node_constraints() depends on D's migrate_add_work_graph_fork_columns() having run (called unconditionally, idempotent) so work_graph_run's rebuild has the right column set either way. ux_work_graph_run_active and task's 3 indexes verified to survive the rebuild. work_graph_run_query.py's own separately-hardcoded _VALID_ORG_NODES (a real dependency the requirements doc's risk section missed) now reuses agent_profile.ORG_NODES instead of maintaining a second copy. Explicitly NOT done (scoped out during requirements review, not an oversight): frontend/app.js's 4 hardcoded 3-role spots (route regex, sort order, dropdown, lookup object) -- a new role still won't be recognized by the PH3 console. A `role` table with real FK referential integrity was also not built; this uses the simpler "just relax the enum" approach. Full src suite (623 tests) + supervisor suite (125 tests) pass with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
Implements docs/todo/work-graph-time-travel-debugging-design.md, backend and console together (user confirmed 2026-08-06). Key finding that shrank the v1 scope: ux_work_graph_run_active is a PARTIAL unique index (only covers non-terminal statuses), not a blanket one -- forking from a parent run that's already reached a terminal status never collides with it at all. v1 restricts forking to exactly that case, so no index/constraint change is needed, only two new nullable columns (parent_run_id, fork_of_node_exec_id). Resolved the requirements doc's FR-1 ambiguity ("override input_payload, re-trigger execution") as OUTPUT SUBSTITUTION instead: the fork point's own output_payload is replaced with the human-supplied content directly, it is never re-executed via a new claude -p call -- only the strict downstream subgraph actually re-runs. This sidesteps reconciling the different build_prompt/input_payload conventions each caller uses (Planner's artifact_type lookup, E's generic task_prompt field, F's jury) -- work_graph_fork.py only needs the persisted graph_manifest and each node's output_payload. Implementation needs ZERO changes to the execution engine: pre-seeding every non-downstream node as a 'done' work_node_execution row before calling the unmodified run_graph() on the unmodified graph_manifest is enough -- run_work_node()'s existing REQ-06 breakpoint-recovery short-circuit (already-'done' nodes return their persisted output without calling run_fn) does all the "reuse without re-executing" work for free. _reconstruct_build_prompt supports two graph shapes generically from persisted state alone (Planner's canonical doc chain via e2e_pipeline._planner_prompt_builder, and E's generic task_prompt field); anything else raises ForkGraphShapeUnsupportedError rather than producing broken prompts. New: src/work_graph_fork.py (create_fork/execute_fork/fork_work_graph_run/ start_fork_in_background, the last splitting fast DB-only setup from slow real execution so an HTTP caller gets run_id back immediately, same pattern task_execution.start_task_execution_in_background already uses). work_graph_run gets parent_run_id/fork_of_node_exec_id (SCHEMA_SQL + migrate_add_work_graph_fork_columns for existing databases). work_graph_run_query.py/task_query.py surface both fields. New endpoint POST /api/work-nodes/:node_exec_id/fork. Console: a "从这里分叉" form on each 'done' node in v_run_detail, a fork badge linking back to the parent run, and a 🔀 marker on v_graph_console's run list -- no diff/merge UI (non-goal #3), read-only branch visibility only. Verified end-to-end for real: started the actual backend, sent a real HTTP fork request, confirmed the new run persisted with correct parent_run_id/fork_of_node_exec_id lineage. Tests cover requirements doc acceptance standards 1-3 (PRD swapped -> SDD/Benchmark genuinely re-execute, BRD untouched; original run completely unaffected; the same node forked twice produces independent branches) plus schema migration idempotency, query-layer field surfacing, the HTTP route, and 3 frontend smoke-test assertions. Full src suite (608 tests) + all 3 frontend smoke tests pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
Implements docs/todo/validator-loop-until-dry-skill-design.md. Pure Skill + Agent-definition wiring, no execution-engine changes -- the convergence loop runs inside a single Work Node's one claude -p session (multi-turn tool use), not a graph_manifest-level cycle, so topological_layers()/ run_graph() are untouched. New Skill skills/unknown-scope-defect-sweep/SKILL.md: K=2 consecutive no-new-finding rounds to stop, 20-round hard cap, dedup key must be a structural identifier (file path + line, route path, package name) not a natural-language description (the same finding gets reworded call to call, so text-keyed dedup never converges), dedup set is "everything ever seen" not "everything confirmed" (the common bug the 14-step reference names: a rejected candidate reappearing as a false "new finding" every round). Each candidate is verified via qa-task-validation's existing PASS/FAIL/INCONCLUSIVE framework -- deliberately NOT root_cause_trace's three-perspective jury (F), since that answers a different question (root cause AFTER a failure) from this one (is this candidate real at all) -- documented in the design doc's own tradeoff note. Wired into agent_profile.py's FRONTMATTER["validator"]["skills"] and agents/validator/AGENTS.md's "必须加载" section with a concrete trigger signal (task description can't state an exact expected count/boundary up front). Only FR-4 (Skill wired into the rendered .claude/agents/validator.md) has deterministic, mockable behavior -- new test test_validator_references_unknown_scope_defect_sweep_skill. Acceptance criteria 1-3 (actually finds everything, actually dedups correctly, actually stops at the hard cap) need real multi-turn claude -p behavior, out of scope for mocked tests (RUN_REAL_AGENT_E2E=1 territory), same category of limitation as F's own real-concurrency-timing note. Full src suite (587 tests) passes with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Reviewed docs/todo/role-package-abstraction-requirements.md against the actual codebase before confirming direction. Two corrections to the document's own risk analysis: 1. Its dependency list for agent_profile.ORG_NODES/FRONTMATTER was wrong in one place and missing the largest one: work_graph_orchestrate.py doesn't import agent_profile at all (only org_node_trigger.py and project_scaffold.py::deploy_agent_definitions() do -- smaller real footprint than claimed). But the document missed two real hardcoded 3-role dependencies entirely: src/work_graph_run_query.py's _VALID_ORG_NODES, and -- the actually large one -- four separate hardcoded spots in frontend/app.js (a route regex, a sort-order array, a task-creation <option> dropdown, and a lookup object literal). 2. Acceptance criterion 1 ("a new role needs no code/schema changes") only covers schema.py + agent_profile.py per its own non-goal #1 (a new role doesn't need real Org Graph wiring) -- the console genuinely won't recognize it either way. Flagged so the design doc states this explicitly instead of letting "no code changes" read as end-to-end. Confirmed for design phase with these two additions folded in; the document's own open questions (§8) are left for the design pass, not pre-decided here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
Implements docs/todo/verifier-fan-out-jury-design.md. root_cause_trace.py: _tally_perspectives() extracts the existing >=2/3 rule out of judge_root_cause so the closure-based version and the new judge_root_cause_via_work_graph() share one implementation, not two that could drift apart. The fan-in vote stays plain Python (zero_token aggregation per the design-dynamic-work-graph Skill's own edge_type distinction) rather than becoming a fourth Work Node -- no reason to pay for an Agent call just to count votes. judge_root_cause_via_work_graph(): each perspective becomes an independent Work Node with real schema-constrained structured output ({"category", "detail"} directly), not real_validator_perspective's manual "CATEGORY:"/"DETAIL:" text-line parsing. judge_root_cause / real_validator_perspective are kept, not removed -- documented as the lightweight fallback for scenarios that don't need worktree/Work Graph overhead. org_level_loop.run_fix_loop (the one real production caller) now calls the Work Graph version; the fixer/verify calls are unchanged flat trigger_org_node calls. Real bug found and fixed along the way: this is the first production code path that actually triggers a run_graph() multi-node CONCURRENT layer (every graph_manifest before F was single-node or a strict serial chain, so G's ThreadPoolExecutor path had never really run in production). scheduler.py::run_goal_to_completion and task_execution.py::start_task_execution_in_background both created their conn without check_same_thread=False -- fixed both, since their conn can now reach run_graph()'s worker threads via run_fix_loop. Test boundary migrated in test_org_level_loop.py/test_scheduler.py: the 3 perspective calls are now mocked at work_graph_execute.write_workflow_script/ execute_work_graph (matching test_work_graph_orchestrate.py's pattern) instead of org_node_trigger.trigger_org_node. New tests cover: three real independent Work Node executions, judgment-rule equivalence with the closure version, clean per-node input_payload, and concurrent wall-clock overlap across the three perspectives. Full src suite (586 tests) + supervisor suite (125 tests) pass with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
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> -
Implements docs/todo/work-graph-parallel-execution-design.md: run_graph() now schedules graph_manifest nodes layer-by-layer (topological_layers(), Kahn's algorithm grouped by round instead of flattened), running a multi-node layer's nodes concurrently via ThreadPoolExecutor (default 4 workers) with a barrier between layers; a single-node layer stays synchronous, matching every real graph_manifest observed so far. topological_order() is now a thin flattening wrapper, unchanged behavior (regression-tested). _LockedConn/_FetchedRows makes the existing scattered conn.execute() call sites in work_node_run.py/work_graph_orchestrate.py/execution_log.py safe to call from multiple threads without touching those call sites -- note the lock must cover the full execute()-through-fetchone()/fetchall() cycle, not just execute() itself, or two threads can still collide on the shared sqlite3 connection handle. That gap was caught for real (not theoretically) by RunGraphRealSqliteConcurrencyTest during development -- committing the fixed version, not the first draft. create_worktree() (work_node_run.py) gets a module-level lock around the `git worktree add` call for concurrent layers touching the same repo. New tests: layer grouping, same-layer concurrency + inter-layer barrier, one node's failure not cancelling a concurrent sibling (WorkGraphLayerError aggregates), breakpoint-recovery resume of a concurrent layer, a quota-wait timeout coexisting with a sibling's real persisted output, real (non-mocked) sqlite under concurrent writes across several rounds, and real concurrent `git worktree add` calls. Full src (575 tests) + supervisor (125 tests) suites pass with zero regressions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
…c231-main-checkout-drift
-
…1a79-main-checkout-drift
-
…ea4d-main-checkout-drift
-
…d9ae-main-checkout-drift