• 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>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »
  • frontend/{index.html,app.js,style.css}: no build step, no npm, vanilla JS
    hash router (05 §5.7). Real page content is PH3 (U-022+, starting from
    docs/wireframes/); this is only the empty shell + working navigation the
    Done criterion asks for.
    
    backend_server.py serves the 3 files via an exact-path whitelist (not a
    generic static-file/directory server) -- no path-traversal surface to
    reason about for 3 fixed files.
    
    Verified in an actual browser this session (navigated to localhost, clicked
    all 3 nav links, screenshotted each) rather than only trusting stdlib
    tests -- a Python-only test can't exercise real hashchange/DOM behavior
    without a JS engine. Nav highlighting and content swap both confirmed
    working, no page reload, no build step.
    
    7 new stdlib unittest cases covering what the server is actually
    responsible for (static files served with correct content-type, 404 on
    unknown GET path). 66 total across U-001-008, all passing.
    
    This closes out PH0 (U-001~U-008) -- all three Phase-acceptance criteria
    now hold for real: target-project directory scaffold, 15-table schema with
    constraint tests, and a real claude --agent round-trip.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Pure stdlib http.server (ThreadingHTTPServer), zero third-party deps --
    enforced by an AST-based test that parses backend_server.py's own imports
    and checks each against sys.stdlib_module_names, so this can't silently rot
    if someone adds a dependency later (05 §5.7).
    
    pick_folder(): macOS via `osascript 'choose folder'`; user-cancel maps to
    {"selected_path": null} (03-C §3.-1: not an error), non-macOS or any other
    osascript failure raises DialogUnavailableError -> HTTP 422
    DIALOG_UNAVAILABLE. Windows/Linux native dialogs are PH3 (U-022).
    
    Known gap, noted rather than papered over: the Done criterion asks for a
    real popped dialog returning a real path, which needs an actual human
    click -- not something this agent can do non-interactively. Verified
    `osascript` itself is present and executes on this machine, and every code
    path is covered by mocked tests, but the literal "did a human click a real
    folder and get the right path back" check is still open for whoever runs
    this interactively next.
    
    12 new stdlib unittest cases (server start/stop, pick_folder success/
    cancel/non-macOS/other-failure, the same 4 cases through the HTTP route,
    zero-third-party-import check). 62 total across U-001-007 (60 real + 2
    gated), all passing.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • write_workflow_script(): writes an orchestration script to
    <target>/.claude/workflows/<name>.js -- versioned with the target project's
    own git history, not graphlemon's (03-C §3.5 step 1).
    
    execute_work_graph(): `claude -p 'Run /<name> with args {...}' --output-format
    json --json-schema <schema> --permission-mode auto`, no `--bare` (A-1 spike:
    skips credential discovery, breaks headless invocation), never
    bypassPermissions. Returns structured_output. No budget-usage bookkeeping
    or CLASSIFIER_BLOCKED handling yet -- U-012's job ("骨架" here).
    
    Real-call coverage reuses spikes/a1-dynamic-workflows/workflow-under-test.js
    verbatim (read from that file, not retyped) through the new wrapper --
    "直接复用已验证的代码路径" per development-plan.md U-006, not just citing the
    old spike as prior art. Confirmed passing for real: same result as the
    original spike (sum=29 for [2,3,4]).
    
    8 new mocked stdlib unittest cases + 1 gated real-agent test. 53 total
    mocked tests across U-001-006, all passing; both gated real-agent tests
    (U-004/U-005's planner call, U-006's reused spike workflow) re-verified
    manually this session.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • trigger_org_node(org_node, prompt, target_folder_path): shells out
    `claude --agent <org_node> -p ... --permission-mode auto` with cwd=target
    project, parses the JSON result, raises OrgNodeTriggerError on nonzero exit
    or is_error. Skeleton only, per development-plan.md ("不含完整状态机") --
    TASK_NOT_READY/CONCURRENCY_LIMIT_REACHED/USAGE_LIMIT_REACHED handling is
    U-010's job.
    
    Also refactors test_agent_e2e.py (U-004) to call this real function instead
    of its own ad-hoc subprocess invocation, so the gated real-agent test now
    exercises U-005's actual production code path -- confirmed still passing
    against a real `claude --agent planner` call.
    
    5 new mocked stdlib unittest cases (CLAUDE.md Testing constraint: mock the
    subprocess boundary in normal tests). 46 total across U-001-005, all
    passing; the 1 gated real-agent test re-verified manually.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »

  • Implements docs/sdd/01-M-模型设计.md §1.0-1.14 as stdlib sqlite3 DDL in src/
    (deployment/deploy_health_signal §1.15-1.16 are PH5/U-034, deliberately
    excluded). Covers all entities' fields, enum CHECK constraints, FKs, and
    the two non-trivial unique indexes (work_graph_run's per-(task_id,org_node)
    active-run partial index, artifact's (task_id,artifact_type,git_commit_sha)
    composite key).
    
    Per user decision (2026-07-30): bug_record.root_cause_category excludes
    'core_engine' for now -- that value is PH5-scoped and development-plan.md
    assigns adding it to U-034, not U-001; a test locks this in.
    
    14 stdlib unittest cases in src/test_schema.py cover table creation and the
    Done criterion's named constraint classes (unique/FK/enum), all passing.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • 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>
    bboonnee authored
     
    Browse Code »