-
route_org_loop(): fast_lane -> coding/coder, full_replan -> planning_brd_prd_sdd/planner, loop_round += 1, writes an execution_event(event_type=loop_routed) recording the decision. loop_round >= 3 forces blocked_pending_human (blocked_reason= 'loop_limit_reached') and raises LoopLimitReachedError instead of routing (03-C §3.11: "不接受常规路由请求,只接受 manual_resume"). manual_resume walks execution_event's task_status_changed history backwards to find what status preceded the most recent transition into blocked_pending_human, and restores it -- 04-P says "恢复到触发前状态" but task has no previous_status column, so this reconstructs it from the event log already being written everywhere in this codebase, rather than adding a new column for a value that's already reconstructable. Also built close_task_done() (validating->done, validator_pass): 04-P names this transition but not a controller for it, and nothing in this codebase had ever set task.status='done' before this commit -- REQ-05's happy case ends there, so it had to exist for that to be reachable. Documented as a deliberate scope extension, not silently assumed. Simplification, noted rather than silently collapsed: 04-P models fast_lane/full_replan as two hops (validating -> routed_fast_lane -> coding) but c_org_loop_route's own 03-C contract returns the final state directly and no controller owns the second hop -- implemented as one atomic transition, with the route decision preserved via the loop_routed event instead of a persisted intermediate status. Neither REQ-05 nor REQ-09 check for that literal intermediate state. 11 new stdlib unittest cases, all real (sqlite is fast/free/local, no mocking needed). 157 total across U-001-016, all passing. This closes PH2-S1 (U-015 + U-016): REQ-04, REQ-05, and REQ-09 are now all real code, not just planned. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Closes the c_artifact_write gap U-011 flagged (03-C §3.7, unowned by any Unit despite REQ-02 needing it directly): src/artifact_write.py writes content to the target project, commits it to the target's own git history, validates depends_on_artifact_ids against existing rows before writing anything (REQ-02's failure case), creates the immutable artifact row. validation_status is set to 'passed' unconditionally -- noted as a real simplification (semantic content review, e.g. REQ-02's "PRD 里出现矛盾" boundary case, needs its own LLM-judgment step this codebase doesn't build yet). src/e2e_pipeline.py orchestrates architecture doc §11's MVP criteria 1-3: plan_documents() makes 4 real sequential Planner calls (BRD, then PRD referencing BRD, then SDD referencing PRD, then Benchmark referencing SDD), writing each via c_artifact_write with correct lineage. implement_code() calls Coder once, captures the resulting `git diff` as code_diff and the Coder's own response as test_report. validate_implementation() calls Validator once and parses an explicit 'VERDICT: PASS|FAIL|INCONCLUSIVE' line. run_end_to_end() chains create_task -> plan -> implement -> validate, using U-010's trigger_org_node_full only for task.status bookkeeping (a lightweight "confirm ready" call per phase) and plain org_node_trigger calls for actual content generation, since trigger_org_node_full's contract returns a status dict, not text. Real-verified: plan_documents ran for real against "实现贪吃蛇游戏" -- all 4 documents produced, correctly lineaged, validation_status=passed, real content (>100 chars each), ~5m45s total for the 4 sequential calls. Deliberately NOT run for real: run_end_to_end's Coder/Validator half (real code generation + real test execution) is a different order of magnitude in cost/time/uncertainty than every other real call this session -- built and mock-tested, but not executed without checking first. 19 new mocked stdlib unittest cases (4 for artifact_write, 5 for the pipeline orchestration, all real/unmocked for artifact_write since git operations are fast/free/local same as U-013's worktree tests) + 1 gated real test. 127 total mocked/real-local tests across U-001-014, all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
run_work_node(): the per-node contract -- input schema check (rejects outright, never starts, vs. output schema failure which retries), status machine (pending->running->(reflecting/retrying up to caller-specified max_retries)->done|blocked), execution_log_file lifecycle (active on start, closed in a finally so it closes even when run_fn raises), and USAGE_LIMIT_REACHED handling using 03-C §3.6's *exact* detection regex (`hit your (session|weekly|opus) limit`, case-insensitive) -- more precise than the phrase-matching approximations U-010/U-012 used before this Unit existed to give quota_wait_started_at/quota_limit_type a real owner. git worktree isolation (create_worktree/merge_worktree/remove_worktree) tested for real, no LLM call needed: two independent nodes each get their own worktree + branch, each run_fn writes and commits a different file, both merge back into the main checkout with --no-ff, git log confirms both commits landed, git_worktree_ref differs per node. This is REQ-03's boundary case, verified end to end with real git. "actual work" is an explicit required run_fn(cwd) dependency, not a hidden default calling `claude` -- what a node does is inherently node-specific (the whole point of "give each node a contract"); production callers wire in a real subprocess call, tests inject fakes. Corrects the same Done-line overreach as U-009/010/011/012 (5th occurrence): REQ-03's happy case needs c_artifact_write (still unowned, per U-011's flagged gap) and a real Coder session, neither of which U-013 has access to via its own dependencies (U-012 only). Boundary is what's real here. 10 new stdlib unittest cases, all real (no mocking needed -- git and the DB are both fast/free/local). 117 total across U-001-013, all passing. This closes PH1-S2, the sub-phase development-plan.md's own text flagged as "本项目风险最高的 Sub-phase" (highest-risk in the project). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Extends U-006's execute_work_graph in place (same controller, being completed, not a parallel module): - ClassifierBlockedError: raised when a response's permission_denials array has >=3 entries (03-C §3.5 says "3 consecutive or 20 cumulative" -- true cross-call cumulative tracking needs persistence U-013 doesn't provide yet, so this is a documented, conservative per-call approximation). - UsageLimitReachedError (carries quota_limit_type) + a new execute_work_graph_with_usage_limit_retry() implementing p_usage_limit_wait (04-P §4.4.1): 5->10->20->30min backoff (repeating at 30) for session/weekly quota hits, timeout after 8h/9d -> UsageLimitWaitTimeoutError; opus quota hits skip backoff and fail immediately (model-downgrade retry is a caller decision, not this function's). sleep/now are injectable so tests don't block on real waits. Retry operates at the whole-work-graph-call level, not per individual work_node_execution row -- U-013 (c_work_node_run, which actually owns that table) doesn't exist yet, so node-level quota tracking isn't attempted here; noted explicitly in development-plan.md rather than silently simplified. Also corrects the same class of Done-line overreach as U-009/U-010/U-011 (4th occurrence): REQ-07's happy case literally asks for REQ-01~06 all passing end to end, which needs PH2 (Validator root-cause tracing, Org-level Loop, breakpoint recovery) -- U-012 only owns REQ-07's boundary/failure and REQ-14's happy case, which was already correctly scoped. 23 new/changed mocked stdlib unittest cases (existing U-006 tests untouched and still passing -- subclassing WorkGraphExecuteError keeps them backward-compatible). 107 total mocked tests across U-001-012, all passing; both existing real-agent tests (U-006's reused spike, U-011's planner call) re-verified against the refactored code. 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> -
trigger_org_node_full(): guards (TASK_NOT_READY -- wrong task.status or required artifacts not validation_status=passed; CONCURRENCY_LIMIT_REACHED -- only on the planner/queued transition, per 04-P's guard column; USAGE_LIMIT_REACHED -- detected from the underlying claude error text, best-effort against REQ-14's cited "hit your session limit" phrasing) then calls U-005's trigger_org_node for the real subprocess call, then advances task.status: queued->planning_brd_prd_sdd (planner), planning_brd_prd_sdd ->coding (coder, gated on brd/prd/sdd/benchmark all passed), coding->validating (validator, gated on code_diff/test_report both passed). Verified for real: all three Org Agents actually triggered in sequence (chained claude --agent calls, ~15s/~$0.15 total) with task.status advancing correctly at each step -- not just planner like U-004/U-005's tests, all three personas confirmed invokable. Also corrects two more development-plan.md issues found while scoping this Unit, same class as U-002/U-009/U-036: - U-010's Done line cited '架构文档 §11"手工调用验证"里程碑' -- that phrase doesn't exist in architecture doc §11 at all. The real source is 05 §5.5's rollout step 2 ("手工调用验证...三个 Org Agent 分别可被触发"), whose "分别" (separately/respectively) is the load-bearing word: verify each CAN be triggered, not that a full artifact-validated chain runs end to end. That distinction is why this Unit's scope is exactly what got built -- not chasing planning_failed/coding_failed retries or validator PASS/FAIL routing, which need real Work Graph output (U-011+) or Org-level Loop routing (U-015/016, PH2) that don't exist yet. - Added an explicit scope note spelling out exactly which 3 transitions this Unit owns vs. which parts of p_org_task_lifecycle it deliberately doesn't touch, so nobody has to re-derive this from the code later. 11 new mocked stdlib unittest cases + 1 gated real chained-trigger test. 87 total mocked tests across U-001-010, all passing; the real test independently re-run and confirmed passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
create_task(): validates goal_text/project_id/task_type (INVALID_PARAM per 03-C §3.1), inserts the task row (status=queued, assigned_org_node=planner, loop_round=0 -- 04-P p_org_task_lifecycle start_state) plus a task_status_changed execution_event, both in one transaction (explicit rollback on failure between the two inserts, tested by dropping execution_event mid-call). c_project_create isn't reimplemented -- it's already complete in U-002 (project_scaffold.create_project). Corrects another Done-line overreach found while scoping this Unit: development-plan.md claimed U-009 alone satisfies all three REQ-01 cases (happy/boundary/failure), but the happy case ("依次触发 planner/coder/ validator...task.status 按状态机正确流转") needs c_org_node_trigger's full implementation -- U-010's own Done criterion is almost that exact sentence, and U-009 doesn't depend on U-010 or even touch org-node triggering. Same class of issue as the U-002/U-036 corrections earlier this session (an SDD/plan line claiming more than the Unit's actual dependencies support), judged low-stakes enough (doesn't change what code to write, just when the REQ-01 happy case gets marked satisfied) to fix directly rather than stop and ask, per the graduated caution this session has been using. Boundary (concurrency limit doesn't block task *creation*, only later scheduling) and failure (INVALID_PARAM) are both fully real at U-009's scope and tested; happy completes cumulatively once U-010 lands. 12 new stdlib unittest cases. 75 total across U-001-009, all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
Implements c_project_create (03-C §3.0) as a plain function for U-007 to wire up later: idempotent by target_folder_path, creates .graphlemon/ + one init commit in an existing git repo, PATH_NOT_FOUND/PATH_NOT_WRITABLE/ GIT_INIT_DECLINED per contract, never silently `git init`s (02-V §2.1). Also corrects a real SDD-vs-plan conflict found while scoping this Unit: development-plan.md's U-002 line cited architecture doc §7.3's directory tree (.claude/agents/, skills/, top-level runs/) as what to create inside a target project. But §13.1 (a later, confirmed decision) states those are graphlemon's own platform-repo assets (U-003 scope), and 01-M's own graphlemon_subdir_initialized field already points at §13.2, whose target- project tree is only .git/ + .graphlemon/ + the target's pre-existing src/. §7.3 predates the "target project is an independent code space" pivot and was superseded by it. Corrected development-plan.md, unit_matrix.json, CLAUDE.md, and 05-实施约束与依赖.md accordingly (user confirmed, 2026-07-31). 23 stdlib unittest cases (src/test_schema.py + new src/test_project_scaffold.py), all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Establishes the first commit for graphlemon before U-001 work begins: architecture/SDD docs (including the PH5 self-hosting design already folded into 01-M/03-C/04-P/mvcp-contract v1.7.0), the A-1 spike results, the graphloop-adapted supervisor/isolation utilities, PH3 wireframe prototypes (now cross-referenced from 02-V), and this session's development-plan review (U-024 dependency split, U-035 regression requirement, new U-004.5 e2e-harness unit, src/ directory convention). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>