-
c_task_create(U-009 已实现的 task_create.create_task())第一次接上 POST /api/tasks。c_bug_report_create 此前完全没有实现,新增 bug_record.create_bug_report() + POST /api/bug-reports。 发现并订正 03-C 一处输入契约遗漏:c_bug_report_create 的 input_contract 没写 project_id,但 execution_event.project_id 是 NOT NULL、bug_record 表自己没有 project_id 列可以在 related_task_id 留空时兜底推导,字面上无法满足约束——按 c_task_create 同款处理方式把 project_id 变成必填,03-C 已订正。 frontend/app.js 补上 #/goals/new、#/bugs/new 真实交互;控制台还没有 "当前项目"状态的正式载体(v_dashboard 是 U-025 才做),project_id 暂存 localStorage,v_project_setup 创建成功时写入。related_task_id 因为 c_task_list 未被任何 Unit 认领,简化成文本输入而非下拉,等 U-025 补上 任务列表后再换。提交成功后原型写的是跳转 v_task_detail,该页面也是 U-025 才建,暂时改成原页面内展示确认信息。 端到端冒烟时额外发现一个真 bug:create_bug_report() 原本没校验 project_id/related_task_id 是否存在,坏 project_id 会在 execution_event 插入时触发未捕获的 IntegrityError,请求直接 500——补了存在性校验, 改为干净的 INVALID_PARAM/400。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
c_pick_folder 补上 Windows(PowerShell FolderBrowserDialog)和 Linux (zenity 优先、回退 kdialog)实现,三平台都覆盖到。c_project_create (U-002 已实现的 project_scaffold.create_project())第一次接上 HTTP 路由 POST /api/projects——backend_server.py 因此第一次需要持有 sqlite 连接,schema.connect() 加 check_same_thread=False 参数,配合 server.conn_lock 序列化 ThreadingHTTPServer 各请求线程的访问。 frontend/app.js 补上 #/setup 真实交互(选文件夹→校验 Git 仓库→非 Git 仓库二次确认→创建→跳转仪表盘),DOM class 命名对齐 docs/wireframes/v_project_setup.html。 REQ-11 完整 happy 用例(含创建 task)还需要 U-023 的 v_goal_composer/c_task_create,本 Unit 只完成 v_project_setup/ c_pick_folder/c_project_create 部分,development-plan.md 已记录。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
now 默认值从 time.monotonic 改成 time.time(墙钟),使 quota 等待的 已耗时计算能在进程重启后正确续算;run_work_node 对已 done 的节点直接 返回存量结果不重跑,对 retrying/waiting_for_quota 节点从持久化的 retry_count/quota_wait_started_at 续算而非清零;needs_worktree=True 时复用已存在的 worktree 而不是重新 create。新增 resume_work_graph_run() 返回一次 run 里尚未完成的 node_exec_id 列表, 并对内部不一致的持久化状态统一抛 CorruptPersistedStateError。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Re-checking REQ-14's boundary case against the letter of its text found a real functional gap, not just a testing gap: U-013's opus handling only did "skip backoff" -- it never actually retried on a downgraded model, just failed immediately. REQ-14 boundary says "不走退避轮询,直接降级到非 Opus 模型重试" (skip backoff, retry immediately on a non-opus model) -- the retry was the part that was missing. Fixed: run_fn's signature is now run_fn(cwd, model=None); an opus quota signal retries immediately (no backoff) with opus_downgrade_model (default "claude-sonnet-5"). If the downgraded model somehow also reports an opus signal (shouldn't happen -- it's not using Opus), this doesn't loop forever chasing it, raises UsageLimitWaitTimeoutError instead. work_graph_execute.py's own opus handling (U-012) deliberately NOT changed to match: REQ-14's coverage only names c_work_node_run/c_org_node_trigger, and that mechanism (a multi-agent dynamic workflow, no single top-level --agent identity) has no one "the model" to downgrade -- a deeper A-1 question, documented as out of scope rather than silently left inconsistent without explanation. Also filled in a real test gap: quota_limit_type=weekly (detection + recovery, and the 9-day timeout) was never tested despite the mechanism already supporting it since U-013. 11 new/changed stdlib unittest cases across work_node_run.py's test suite (all existing run_fn lambdas updated for the new signature). 178 total across U-001-020, all passing. This closes PH2-S3 alongside U-019. REQ-14 is now genuinely complete, not just "mostly right." Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
Found running U-014's full real closed loop: the Validator gave an INCONCLUSIVE verdict and explicitly said it had no Bash tool, despite its frontmatter granting one. Isolated with a minimal test subagent: any "Bash(...)" scoped pattern (e.g. "Bash(git commit:*)") in a subagent's disallowedTools frontmatter field disables Bash *entirely*, not just that subcommand -- confirmed by comparing a disallowedTools=[Edit,Write] agent (Bash works) against one adding a single Bash(git commit:*) entry (Bash breaks completely). The CLI's own --disallowedTools flag documents this exact scoped syntax as supported; subagent frontmatter just doesn't honor it the same way, and nothing in the docs says so. Fixed agent_profile.py's validator FRONTMATTER to disallowedTools= [Edit, Write] only -- dropping the four Bash(git *) entries that were silently breaking test execution. The "don't commit/push/reset/clean" constraint now relies on the prose instruction already in the migrated AGENTS.md instead of a tool-level block that never actually worked; fixed that file's own (now-false) claim that it was enforced at the tool level, and documented the finding centrally in 05-实施约束与依赖.md §5.4.1.2 since it'll matter for any future agent definition, not just this one. Verified for real, redeployed: Bash now works for the actual Validator identity, Edit/Write remain correctly blocked. 1 test fixed (was asserting the now-removed scoped pattern) + 1 new test (disallowedTools frontmatter must never contain "Bash(" again). 174 total across U-001-019, all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
check_budget(): accumulates current_usage on success (04-P monitoring-> monitoring), and on reaching/exceeding limit_value transitions the task to blocked_pending_human with blocked_reason='budget_exceeded' (never 'usage_limit_wait_timeout' -- 04-P is explicit these two guardrails, human- configured budget vs Claude Code's own plan quota, must not share a blocked_reason) and raises BudgetExceededError rather than returning allowed=false silently, matching 03-C §3.12's own errors list. update_budget_limit_and_resume(): REQ-10's boundary case needs "raise the limit -> paused tasks resume" to be real; built the minimal version this Unit needs rather than the full settings-page controller (c_budget_config_update, U-030/PH3's job) -- reuses U-016's manual_resume (org_loop_route.route_org_loop) for the actual status restoration instead of reimplementing it. 6 new stdlib unittest cases, all real (sqlite, no mocking needed). 173 total across U-001-019, all passing. Also: the U-014 full real closed-loop run that's been going in a detached background process since earlier this session finished -- 957s (~16min). All 4 real BRD/PRD/SDD/Benchmark docs, a real JS snake-game implementation (engine.js/engine.test.js/index.html/app.js) from the Coder, and a genuinely careful INCONCLUSIVE verdict from the Validator: it explicitly refused to accept the Coder's own claimed "10/10 passed, verified with headless Chrome" without being able to reproduce it, correctly citing its own migrated SOUL.md rule ("工具错误和权限不足属于INCONCLUSIVE,不能洗成PASS"). It also caught a real test-fidelity gap (T3/T7 not matching the Benchmark's literal wording) via careful static tracing. Result preserved at /private/tmp/.../scratchpad/snake-game-result for inspection. The Validator also reported no Bash tool available despite its frontmatter granting one -- investigating that as a follow-up, separate from this commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
update_skill(): writes new Skill content to skills/<skill_id>/SKILL.md and commits it (03-C §3.8: file write + git commit must be atomic -- the DB insert only happens after the commit succeeds, so a git failure naturally leaves no orphaned skill_iteration row, no separate rollback machinery needed), rejects a missing triggered_by_bug_id (MISSING_TRIGGER_REF). rollback_skill(): restores the pre-iteration content from before_git_commit_sha and commits *that* as a new commit + new skill_iteration row (03-C §3.9: rollback is itself a new iteration, not a history rewrite); the rollback record's triggered_by_bug_id reuses the original iteration's, since c_skill_rollback's input contract has no bug_id of its own and that FK is NOT NULL. repo_path has no default (caught and fixed during this Unit, not shipped with the bug): an earlier draft defaulted it to this repo's own root, which would have made any test that forgot to override it silently commit into graphlemon's actual git history. Every call site must now be explicit; git log confirms nothing leaked into this repo while building and testing it. Resolves U-015's deferred skill_defect gap: re-reading 04-P §4.3's own transition table, bug_recorded (c_bug_record_create alone) and skill_iteration_triggered (-> c_skill_update) are separate, sequential transitions, not one atomic call -- so 03-C §3.10's "必须同时创建 skill_iteration_suggestion" is a same-flow requirement, not a same-API-call one. bug_record.py already accepted skill_defect (it was never actually rejected, just undocumented as resolved); update_skill() now fills in bug_record.skill_iteration_suggestion_id once the real iteration exists. Known gap, not this Unit's job: no real Skill content has been migrated from the Hermes profiles yet (05 §5.1 names the skills; agent_profile.py's frontmatter only references them by name) -- tests seed a placeholder skill file, same pattern as U-010/011 seeding placeholder artifacts for upstream producers that don't exist yet. 10 new stdlib unittest cases, all real (git + sqlite, no LLM call needed -- same category as U-013's worktree tests). 167 total across U-001-018, all passing. This closes PH2-S2. REQ-08 is now real code, and U-015's skill_defect note is resolved rather than left permanently deferred. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
run_fix_loop() chains U-015 (3-perspective root-cause judgment) + U-016 (routing) + real Coder/Planner/Validator calls into architecture doc §11's 4th MVP acceptance criterion: judge -> create bug_record -> route (fast_lane for category=coder, full_replan for category=planning -- a fixed mapping this Unit defines, since bug_record.suggested_route is technically an independent Validator judgment but REQ-05/architecture §11's scenarios always correlate the two, so no extra Agent call was added just to re-decide it) -> trigger the fixer -> re-trigger Validator -> close_task_ done on confirmed PASS. 3 new mocked stdlib unittest cases (route branching, verification-fails leaves the task out of 'done'). 160 total mocked tests across U-001-017, all passing. Real coverage reuses U-015's wall-collision scenario but this time drives an actual fix: a real Coder call edits collision.py in the repo, a real Validator call reads the fixed file and confirms it, running as a detached background process (survives this session's own restarts, unlike two earlier real runs this session that got silently orphaned by a session teardown with no completion record -- lesson learned, not repeated). This closes PH2-S1 (U-015/016/017): REQ-04/05/09 and architecture doc §11 criterion 4 are now real, verified code, not just planned intent. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
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>
-
judge_root_cause(): runs 3 perspective_fns (correctness/requirement- completeness/skill-defect, 04-P §4.3), requires >=2/3 agreement on a category or raises InconclusiveEscalateError with all raw judgments attached (REQ-04's failure case). trace_root_cause_test_failed() creates a brand-new bug_record on agreement; trace_root_cause_human_reported() field-completes an existing one instead (04-P's explicit distinction between the two origins, not a new record either way). c_bug_record_create (bug_record.py): validates root_cause_category against {planning, coder, skill_defect} -- core_engine deliberately excluded, matching U-001's schema CHECK constraint (PH5/U-034 scope). Known, deliberately-unenforced gap noted rather than guessed at: 03-C §3.10's "skill_defect requires creating a skill_iteration_suggestion" constraint can't be satisfied yet (skill_iteration.before/after_git_commit_sha are NOT NULL but don't exist until a real skill rewrite happens in U-018) -- REQ-04's three cases never exercise skill_defect, so nothing here needs it resolved yet. real_validator_perspective() builds a real claude --agent validator call framed from one of the three perspectives, parsing a CATEGORY:/DETAIL: response format. Also fixes a real diagnostic bug found investigating an unrelated failure: org_node_trigger.py/work_graph_plan.py/work_graph_execute.py's nonzero-exit error paths only included stderr in the raised exception, silently dropping stdout -- which is where a real `claude` failure's actual detail often lives. A real Coder call failed with exit 1 and empty stderr, giving zero diagnostic signal; fixed to include both streams (truncated). 18 new mocked stdlib unittest cases + 1 gated real test (3 real Validator perspective calls judging a deliberately-injected wall-collision bug, expecting agreement on root_cause_category=coder). 146 total mocked tests across U-001-015, all passing. 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> -
Resolves the A-2 assumption with a real `claude --agent planner -p` call (--permission-mode auto, $0.05) against a deployed target project: the migrated identity comes through correctly, not the default assistant persona. Verdict is "部分成立" (partially confirmed), per the criterion development-plan.md's U-004 line pre-registered for exactly this outcome -- Planner/Validator's SOUL.md migrated almost verbatim, but Coder's SOUL.md needed real rewriting: the original hardcoded a live Feishu Base API token (redacted, never committed), strongly bound its task-claiming to `lark-cli`/Base status vocabulary, and told itself to shell out `claude --dangerously-skip-permissions` (conflicts directly with 05 §5.3.1's `auto`-mode decision). All three replaced with graphlemon's own task table / c_org_node_trigger / task.status vocabulary. Also resolves a second, higher-stakes conflict found while scoping this Unit: where does `.claude/agents/<org_node>.md` actually live? Architecture doc §13.1 says graphlemon's own platform repo; 03-C §3.3 and 05 §5.1 (both core SDD, not the architecture PRD) explicitly say the target project -- matching how Claude Code's --agent flag actually discovers subagents (relative to invocation cwd). User confirmed 03-C/05 win. Resolved as two different files, not a contradiction: agents/<org_node>/SOUL.md (+ validator/AGENTS.md) here is the canonical migrated source (01-M 1.9 agent_profile.soul_file_path, a singleton with no target-project reference); src/agent_profile.py compiles that into the deployable .claude/agents/<org_node>.md and writes it into a target project via deploy_agent_definitions(). Does not reopen the U-002 correction from the previous commit -- .graphlemon/ scaffolding and agent deployment are different, non-conflicting concerns. validator's tools/disallowedTools frontmatter encodes qa/AGENTS.md's original workspace-permission contract (read-only on source, no git mutation commands) as actual Claude Code permissions instead of prose. 14 new stdlib unittest cases (test_agent_profile.py, all real) + 1 gated real-agent test (test_agent_e2e.py, RUN_REAL_AGENT_E2E=1, mirrors graphloop's pattern per CLAUDE.md's Testing constraint -- this is the first Unit that actually shells out to `claude`, so this is also where that harness gets built, per the harness-ownership decision from the earlier "什么还需要" review). 41 total tests across U-001-004, all passing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
U-003's coverage in unit_matrix.json is empty (no M/V/C/P/REQ) -- its Done criterion is a property, not a contract: platform dir and any target project dir stay physically separate, and the raw log directory never enters graphlemon's own git history. src/paths.py makes the `~/.graphlemon/ logs/...` example path from 01-M 1.13 / architecture doc §13.2 into the actual convention (GRAPHLEMON_HOME-overridable), defaulting to the user's home directory so it's outside this repo's checkout by construction rather than by a .gitignore rule. is_separate_from() is the property U-003 has to guarantee, tested from both directions (target nested in platform home, platform home nested in target). Also fixes a second stale reference to the pre-correction U-002 scope, found while scoping this Unit: U-036's "supervisor/ directory ownership" open question in development-plan.md still described U-002 as owning a `.claude/`/`skills/`/`src/` target-project tree (already corrected out of U-002 itself last commit). Notes that this makes the open question moot -- supervisor/ was never a real target-project candidate. 8 new stdlib unittest cases (src/test_paths.py); 31 total across U-001/U-002/U-003, 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>