• Implements org-graph-unification-phase2-universal-self-planning-design.md
    §2.3, §3, §6 -- Coder's implement_code() no longer runs one hardcoded
    synthetic "implement" node; it self-plans via plan_work_graph(conn,
    "coder", ..., append_to_run_id=run_id), appending its own nodes onto
    Planner's existing work_graph_run instead of creating a separate one.
    
    - work_graph_plan.py: per-org_node suggested node-type catalogs
      (_CODER_NODE_CATALOG/_VALIDATOR_NODE_CATALOG, "starting points, not
      requirements" same as _PLANNER_NODE_CATALOG), new judgment/on_fail/
      promotes_to_artifact fields in the generic planning prompt. New
      plan_work_graph(..., append_to_run_id=...) parameter: merges newly
      planned nodes into an existing run (node_id collision -> raise, never
      silent overwrite), returns new_node_ids so callers can avoid
      reprocessing nodes an earlier stage already promoted to artifacts. New
      shared dispatch_build_prompt() for graphs mixing Planner-shaped
      (artifact_type) and Coder-shaped (task_prompt) nodes side by side.
    
    - e2e_pipeline.py: _write_completed_node_artifacts() now also promotes
      nodes declaring promotes_to_artifact (not just Planner's artifact_type
      nodes), with an only_node_ids scope so a merged-graph caller doesn't
      re-touch artifacts an earlier stage already wrote. implement_code()
      reworked around self-planning; code_diff stays Python-computed (a real
      git diff, not any node's own content -- no node can know the diff ahead
      of running it), test_report is promoted from whatever the self-planned
      graph declares, falling back to a synthesized concatenation if it
      declares none. needs_worktree=True now passed to run_graph() for Coder
      (found missing entirely during this rework -- harmless with the old
      single-node manifest, a real 03-C §3.6 gap once concurrent code-writing
      nodes are possible). Also fixed a real bug found while wiring this up:
      _review_planner_output_with_retries()'s "reuse existing artifacts"
      branch hardcoded run_id=None, even though every real artifact row
      already has a valid produced_by_run_id -- Coder had nothing to append
      into on that resume path.
    
    - work_graph_fork.py: _reconstruct_build_prompt now dispatches per-node
      (via the new shared dispatch_build_prompt) instead of requiring the
      whole graph to be one uniform shape -- a real regression Phase 2b would
      otherwise have introduced silently, since a forked merged graph can now
      genuinely mix both node shapes.
    
    Sequencing note (unchanged from Phase 2a's own finding): work_graph_run's
    org_node column removal and the ux_work_graph_run_active index narrowing
    (design doc §2.1/§2.2) stay deferred to Phase 2c -- Validator still
    creates its own separate run until Validator also appends into the shared
    one, so narrowing the index to task_id-only now would collide with it.
    
    python3 -m unittest discover -s src (752 tests) + discover -s supervisor
    -p "test_*.py" (126 tests) both green, zero regressions.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • Inserts Planner -> planner_reviewer -> Coder -> Validator into the fixed Org
    Graph flow (was Planner -> Coder -> Validator), per
    docs/todo/org-graph-unification-phase1-review-gate-design.md. A new
    planner_reviewer role independently judges whether Planner's BRD/PRD/SDD/
    Benchmark output is real structured content (not narrative prose) before
    Coder is allowed to start, with a 3-attempt retry loop and a narration
    heuristic informed by the real narrative-output incident
    (docs/todo/validator-test-script-narrative-output-issue.md).
    
    Also fixes, in the same code path:
    - The P0 bug in task-execution-resume-assumes-planner-artifacts-exist.md:
      resuming a task no longer assumes sdd/prd/benchmark artifacts exist --
      falls through to real replanning when they don't.
    - A fresh-run KeyError (not resume-specific) when a self-planned graph omits
      the prd/benchmark node types.
    - agent_profile.migrated_from_profile was NOT NULL, which broke as soon as a
      role with no legacy Hermes profile (planner_reviewer) was recorded.
    
    org_node_lifecycle._REQUIRED_ARTIFACTS["coder"] is narrowed from
    (brd,prd,sdd,benchmark) to (sdd,) -- the old 4-artifact gate never actually
    blocked anything since artifact_write.py sets validation_status='passed'
    unconditionally; planner_reviewer is the first real semantic gate.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »
  • …4843-main-checkout-drift
    graphlemon authored
     
    Browse File »


  • graphlemon authored
     
    Browse File »
  • Root cause traced (docs/implementation-gap-analysis.md): the Benchmark
    document Validator relies on for its verdict was frequently a narrative
    about the work session ("The planner workflow completed and produced a
    Benchmark defining 18 scenarios...") instead of the actual scenarios --
    found via a real skill-detail-page task's benchmark.md, then confirmed
    present since the earliest real self-hosting runs. Validator's own
    judgment was, in practice, resting on thin, sometimes-vacuous prose.
    
    Planner's work graph (brd->prd->sdd->benchmark) extends to
    benchmark->test_dataset->test_script: test_dataset/test_script are always
    present as nodes, but the generating subagent judges per-goal whether a
    real dataset/script applies (many goals, e.g. UI wiring, legitimately
    don't have one -- replying 'N/A: <reason>' is a real, expected answer, not
    a failure). test_script gets a genuinely mechanical verify_fn (real
    py_compile/node --check, not LLM judgment) -- the one node type where an
    objective check is actually possible. All four document prompts also gained
    an explicit anti-narration instruction (only 'brd' had a weaker version of
    this before).
    
    Coder's implementation prompt now receives the real benchmark/dataset/
    script and must make the Planner's real script pass for real, not just
    whatever tests it invents on its own.
    
    Validator gets its own 3-node Work Graph (validator_benchmark ->
    validator_test_dataset -> validator_test_script), generated independently
    from SDD/PRD -- deliberately NOT reusing Coder's or Planner's own copies,
    same reasoning as a held-out eval set vs. the dev set a model was tuned
    against. The resulting script, if real, is actually executed against the
    current repository state; a non-zero real exit code force-overrides the
    verdict to FAIL in code (user-confirmed hard gate: the script is not up
    for LLM debate on a failure, only on a pass can subjective judgment add
    INCONCLUSIVE/risk notes).
    
    schema.py: artifact.artifact_type's CHECK constraint gains the 5 new
    types, plus migrate_expand_artifact_types() -- SQLite has no ALTER-based
    constraint migration, so this is the standard rebuild-copy-swap dance,
    applied for real to the live ~/.graphlemon/graphlemon.db (42 rows,
    verified byte-identical count before/after, integrity_check clean).
    
    skills/qa-task-validation.md and skills/project-sdd-planning.md already
    gained a standing principle from this same incident: verify cross-task
    data dependencies against real system state, not seeded fixtures alone
    (see prior commit d7035fc) -- this commit is the mechanism-level half of
    the same fix, not just the prose-guidance half.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • Attempts 8 and 9 both hit "local changes would be overwritten by merge"
    again, despite the earlier _check_prd_consistency worktree-isolation fix.
    Root cause is deeper: git worktrees deliberately SHARE project identity
    with their main checkout (same .git, just another checkout) -- a real
    `claude -p` call's memory:project write doesn't reliably respect the cwd it
    was invoked with, and can land directly on the main checkout regardless of
    which specific call triggered it. Worktree-wrapping one call (as done for
    _check_prd_consistency) only moves around which call happens to trigger
    this; it doesn't fix the underlying issue.
    
    ensure_worktree_committed() now also runs against repo_path itself (not
    just the worktree) right before every merge_worktree() call, in both
    work_node_run.run_work_node() and e2e_pipeline._check_prd_consistency().
    Same already-tested mechanism, now applied generically regardless of which
    real call caused the drift or why.
    
    Fixing this surfaced a second real bug in the fix itself: running `git add
    -A` against repo_path while a node's own .graphlemon-worktrees/<id>/
    checkout is still present on disk picks it up as a gitlink-like entry,
    which then shows as "deleted" the instant remove_worktree() runs right
    after. Fixed by excluding .graphlemon-worktrees/ from both the dirty-check
    and the add via pathspec (not relying on the caller repo's own .gitignore),
    plus added it to graphlemon's own .gitignore for correctness generally.
    
    New regression test: test_drift_on_main_checkout_is_auto_committed_before_merge
    reproduces a run_fn writing directly to repo_path instead of its worktree,
    and confirms a second node's own merge isn't affected by it.
    
    562 tests green (441 src + 121 supervisor).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »
  • The 4th real self-hosting attempt (first to reach the actual doc-writing
    Work Graph after the previous three bugs) hit a real git merge failure:
    "local changes would be overwritten by merge", exit code 2.
    
    Root cause: _check_prd_consistency() calls execute_work_graph() directly
    against target_folder_path, completely bypassing work_node_run.run_work_node's
    worktree isolation. It uses agentType='planner' with memory:project, which
    writes a real update to .claude/agent-memory/planner/MEMORY.md in whatever
    cwd it runs with. Every prior real run of this check only ever targeted a
    throwaway clone, so this never mattered -- until self-targeting, where cwd
    IS the main checkout: the memory write landed as an uncommitted local
    change on master, which then blocked the SDD node's own (correctly
    isolated) worktree merge right after it.
    
    Fix: apply 05 §5.8's same unconditional self-target worktree rule here,
    reusing work_node_run's existing create_worktree/ensure_worktree_committed/
    merge_worktree/remove_worktree rather than inventing a new mechanism.
    Non-self-target calls are unaffected (verified by both regression tests).
    
    Also cleaned up the real, now-recovered state from the failed 4th attempt:
    merged a real SDD-node worktree branch that got stranded uncommitted
    (conflict was just two near-identical memory file wordings, resolved by
    hand), and removed three orphaned worktrees left by earlier test runs.
    
    557 tests green (437 src + 120 supervisor).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • CLAUDE.md is explicit that PH5 (self-modification/auto-rollback) must not
    start until PH4 has genuinely closed -- not just "all unit tests green,"
    but 06-验收与测试锚点.md's REQ-01~14 happy/boundary/failure cases actually
    covered. A REQ-by-REQ audit (the same discipline that caught U-031's
    integration gap) found 5 real gaps:
    
    - REQ-03 failure: work_node_execution.status jumped straight
      running->retrying, skipping 'reflecting' (declared in the schema enum,
      never once written by any code).
    - REQ-05 failure / REQ-09 boundary: the "scheduler keeps serving other
      queued tasks past one blocked_pending_human" scenario was never tested
      against a real scheduler -- the old test literally said "no scheduler
      exists yet to test against directly" (stale since U-032).
    - REQ-06 / REQ-07 / REQ-14 failure (the biggest gap, shared root cause):
      CorruptPersistedStateError, ClassifierBlockedError, and
      UsageLimitWaitTimeoutError were each correctly raised and each correctly
      marked their own work_node_execution 'blocked', but nothing ever routed
      that to task.status='blocked_pending_human' with the blocked_reason each
      REQ's acceptance text names. e2e_pipeline.run_end_to_end is split into
      run_task_lifecycle() so scheduler.py's run_goal_to_completion can create
      the task itself and catch these three specific exceptions, following the
      same UPDATE+execution_event pattern budget_guardrail.check_budget()
      already established for REQ-10.
    - REQ-02 boundary: PRD internal-contradiction check (verifying->reflecting)
      had no implementation anywhere -- artifact_write always marked
      validation_status='passed' unconditionally. Added an optional verify_fn
      hook to work_graph_orchestrate.run_graph() (one regeneration attempt,
      then ConsistencyCheckFailedError) and a real consistency-check agent()
      call scoped to the PRD node only. The first real run of this new call
      caught a genuine bug: the model returned "consistent": "false" as a JSON
      string, not a boolean, which `if ok:` silently treated as truthy -- fixed
      with explicit _coerce_bool().
    - REQ-13 failure: minor test-assertion weakness (WS 404 rejection test
      didn't check the JSON error body).
    
    384 tests green. REQ-01~14 now have real, exercised coverage rather than a
    "tests are green" assumption -- PH4 can be treated as genuinely closed.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

  • U-031: closes a structural integration gap found during the REQ-01~14 regression
    audit -- plan_work_graph/execute_work_graph/run_work_node were each individually
    tested but never actually called together in production code (e2e_pipeline.py's
    only validated closed loop bypassed all three via flat org_node_trigger calls).
    Adds work_graph_orchestrate.py (topological sort over graph_manifest + one
    one-node dynamic-workflow agent() call per Work Node, needed for REQ-06's
    per-node breakpoint recovery), rewires e2e_pipeline.py's plan_documents/
    implement_code onto the real chain, and fixes two bugs a real API run
    surfaced: graph_manifest's id/node_id/depends_on normalization
    (work_graph_plan._normalize_graph_manifest) and a missing repo_path in
    run_work_node's cwd resolution. work_node_run.py also now marks a node
    'blocked' instead of leaving it stuck 'running' on any unretryable run_fn
    exception.
    
    U-024.5: the regression audit also found REQ-12's reconnect boundary case
    (refetch a snapshot after a dropped WS reconnects) was never implemented --
    only the dashboard reacted to onStatusChange, and even it never refetched.
    Fixes mountDashboard/mountTaskBoard/mountTaskDetail (which embeds
    v_graph_visualizer) to refetch their current snapshot on reconnect.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse File »

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