• Adds paths.repo_root()/is_self_target() and forces needs_worktree=True in
    work_graph_orchestrate.run_graph() whenever target_folder_path is graphlemon's
    own checkout, regardless of caller intent -- 05 §5.8's unconditional rule,
    since a self-target in-place edit risks corrupting the currently-running
    process's own source out from under it.
    
    Adds src/core_engine_classify.py (path-based rule: .claude/agents/*.md,
    src/*, supervisor/* = core_engine; frontend/, docs/ = not) and
    bug_record.record_core_engine_change() (a PASS-path audit record, distinct
    from create_bug_record's FAIL-path root-cause attribution -- no route
    decision, status='resolved' from creation). scheduler.finish_task_lifecycle()
    records this audit trail as an additive side effect after close_task_done()
    on self-target PASS closures.
    
    Found and resolved a real SDD-internal conflict (confirmed with the user via
    AskUserQuestion) before wiring this up: supervisor-auto-rollback-design.md §1
    triggers Deploy Supervisor on self-target+Validator-PASS alone, but 03-C
    §3.11/04-P §4.6 literally gate it on an existing core_engine bug_record --
    and task_create.py confirms goal-type self-improvement tasks (the exact
    self-development-feasibility.md walkthrough scenario) never produce a
    bug_record on their happy path, which would silently defeat that whole task
    class under the literal reading. Resolved per user decision: trigger on
    self-target+PASS alone; the bug_record is a byproduct, not a gate.
    p_deploy_supervisor_blue_green (04-P §4.6) never touches task.status, so
    close_task_done() still runs unconditionally -- Deploy Supervisor is a fully
    decoupled state machine, matching §2's "no shared failure domain" principle.
    
    org_loop_route.py is intentionally untouched -- fast_lane/full_replan is
    FAIL-path retry routing, orthogonal to this PASS-path trigger; deployment
    row creation stays U-037's job per its own Done criterion.
    
    417 tests green; RealGitWorktreeIsolationTest (U-013/REQ-03's real git
    worktree regression) re-verified passing per this Unit's own Done criterion.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • 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>
    bboonnee authored
     
    Browse File »
  • 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>
    bboonnee authored
     
    Browse File »
  • 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>
    bboonnee authored
     
    Browse File »