• Requested by user after today's incident retrospective: a manually-assignable
    execution-order hint across a project's tasks, shown as a new "执行顺序" column
    on v_task_board. Serial steps are whole numbers (1, 2, 3); parallel siblings of
    one step share the same integer part as decimals (2.1, 2.2). Purely advisory --
    nothing in the scheduler/dispatch loop reads it, it's a human/Boss-Agent-facing
    planning aid, not an enforcement mechanism.
    
    - schema.py: task.execution_priority REAL (nullable), migrate_add_task_execution_priority
      (plain ADD COLUMN, no CHECK constraint). Two earlier CHECK-rebuild migrations that
      also touch task (migrate_relax_org_node_constraints, migrate_add_reviewing_planner_
      output_status) now call it as a prerequisite and include the column in their own
      rebuilt task_new, same "depends on a later additive column" pattern
      migrate_relax_org_node_constraints already used for migrate_add_work_graph_fork_columns.
    - task_query.py: list_tasks/get_task expose it; new update_task_execution_priority
      (unlike update_task_goal_text, NOT gated to status='queued' -- it's a display hint,
      not a planning input, so it stays settable on in-flight/blocked tasks too).
    - backend_server.py: PUT /api/tasks/:id now accepts execution_priority independently
      of goal_text on the same endpoint.
    - frontend/app.js: new editable column on v_task_board, PUTs on change.
    
    Also adds docs/todo/append-run-node-id-collision-across-org-nodes-requirements.md,
    a third real finding from today's retrospective (task 911861fe: Coder and Validator's
    suggested node catalogs both converge on node_type="test_script", so their
    self-planned node_ids collide inside a shared merged work_graph_run -- PlanningFailedError,
    uncaught by _ROUTABLE_EXCEPTIONS, falls into the same generic execution_error bucket
    FR-7 already flagged).
    
    813/813 src tests, 134/134 supervisor tests, frontend smoke passes.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Real incident (2026-08-13, task 71868db6): ConcurrencyLimitReachedError isn't an
    error -- it just means this dispatch attempt found no free slot, which is normal,
    expected backpressure. Routing it through the same blocked_pending_human/
    execution_error bucket as a genuine failure was itself a bug: it forced a task
    that should just wait its turn into looking like it needs human judgment.
    
    _check_concurrency() raises before any task.status transition happens for this
    attempt, so task_execution.py::_mark_blocked() now leaves status untouched
    (still 'queued' for a fresh dispatch) instead of blocking -- the next
    new_goal_dispatch tick naturally retries it, no human/Boss Agent involvement
    needed. Still logged as a new 'concurrency_wait' execution_event (new
    migrate_add_concurrency_wait_event_type, same accumulated-CHECK-enum pattern as
    the existing event-type migrations) so the wait stays auditable, not silently
    invisible.
    
    This is the first concrete instance of FR-7 in
    docs/todo/boss-agent-autonomous-blocked-task-arbiter-requirements.md (system
    should emit distinguishable blocked_reasons/non-error states at the point of
    failure, not dump everything into one generic bucket).
    
    803/803 src tests, 134/134 supervisor tests.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • …a664-main-checkout-drift
    graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • …9856-main-checkout-drift
    graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • Two real findings from today's live self-hosting run, surfaced while diagnosing why
    bfd3ee82/71868db6 were blocked:
    
    1. trigger_org_node/trigger_org_node_structured use a fixed wall-clock
       subprocess.run(timeout=...) -- a long-running-but-genuinely-progressing agent call
       gets killed just for taking longer than a guessed constant (300s), which is exactly
       what happened to bfd3ee82's Validator planning call. Per an already-established
       (but never actually implemented) decision: an agent call should never be judged
       "stuck" by total duration alone, only by an extended period with no activity AND no
       error. New requirements doc:
       docs/todo/agent-call-liveness-not-fixed-duration-timeout-requirements.md.
    
    2. task_execution.py::_mark_blocked's catch-all dumps anything outside a small
       exception whitelist into blocked_reason='execution_error' -- including
       ConcurrencyLimitReachedError, which isn't an error at all, just normal backpressure.
       Boss Agent needs the system to emit distinct, meaningful reasons at the point of
       failure, not reverse-engineer root cause from a generic bucket -- added as FR-7 to
       the Boss Agent doc.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Requirements doc (BRD/PRD level) for a new org-level role that monitors
    blocked_pending_human tasks, does real diagnosis (not blind retry), and acts
    within an explicit authorization boundary instead of always waiting on a
    literal human -- generalizing the planner_reviewer precedent (an autonomous
    judgment agent already replacing a human review gate) to this surface.
    
    Motivated by today's real incident: 4 tasks blocked with the same generic
    execution_error reason but three genuinely different root causes (stale
    process, legacy narrative-output format, a real concurrency bug), all
    diagnosed by hand. Also documents watch_resume.py's real concurrency-race
    flaw as a requirement input (FR-6) so the eventual implementation doesn't
    repeat it.
    
    Deliberately does not pick the autonomy boundary per blocked_reason -- left
    as an open question for explicit user sign-off, not something Planner should
    infer silently.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • v_task_detail's org-strip only ever covered planner/coder/validator -- no way to
    see planner_reviewer's verdict trail from the task detail page at all, only from
    v_graph_console. Rather than maintain two parallel, drifting implementations of
    "org node status for this task", v_task_detail now reuses the same 4-stage Org
    meta-graph component (renderOrgMetaGraph/mountOrgMetaGraph) v_graph_console
    already has.
    
    mountOrgMetaGraph/renderOrgMetaStageDetailHtml gain an optional enableNodeClick
    option so v_task_detail's usage gets real per-node live log-tail expansion
    (wired through the existing activeLogViewers/closeAllLogViewers/mountLogViewer
    machinery) while v_graph_console keeps its existing read-only snapshot
    behavior unchanged. ORG_NODE_DETAIL_RE now also accepts planner_reviewer so
    deep links into the 4th stage are reachable; landing on one auto-expands and
    scrolls to it (focusOrgMetaStage), matching the old focusOrgNodePanel's
    behavior. Dashboard's own 3-node org-strip is untouched.
    
    Deleted the now-dead renderTaskDetailOrgStripHtml/renderOrgComboPanelContent/
    wireOrgComboArtifactClicks/focusOrgNodePanel.
    
    node frontend/test_graph_console_smoke.js passes (extended with coverage for
    the regex widening and the enableNodeClick threading), independently
    re-verified.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Real prod incident (2026-08-13): two live tasks crashed with sqlite3.IntegrityError
    UNIQUE constraint failed: work_graph_run.task_id right after a planner_reviewer
    FAIL/INCONCLUSIVE verdict. ux_work_graph_run_active (just added this session) allows
    only one non-terminal work_graph_run row per task_id, but a rejected review's retry
    called plan_documents() with no run_id, which always INSERTs a fresh row -- the
    rejected attempt's own row is never marked done/failed just because its content was
    rejected (Phase 2c: one run spans a task's whole lifecycle).
    
    plan_documents() gains append_to_run_id, threaded into plan_work_graph()'s existing
    append machinery (same convention implement_code() already uses for Coder).
    _review_planner_output_with_retries() now carries prior_run_id across retry attempts
    so a re-plan appends into the still-open run instead of colliding with it. The first
    attempt (no prior run) is unaffected.
    
    New test drives a real FAIL-then-PASS retry through the actual plan_work_graph()
    INSERT path and the real ux_work_graph_run_active index -- confirmed it reproduces
    the exact production traceback on the pre-fix code and passes post-fix.
    
    801/801 src tests, 127/127 supervisor tests, both independently re-verified.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Real self-hosting DB (2026-08-13) has 10 task_ids with multiple non-terminal
    work_graph_run rows each (legacy per-org_node-row leftovers from before the
    merged-graph architecture) -- the migration's final CREATE UNIQUE INDEX
    ux_work_graph_run_active ON work_graph_run(task_id) crashed against this real
    data (IntegrityError), and because executescript() commits each DDL statement
    individually, the crash left the live DB in a partially-migrated state:
    org_node column dropped, but the index never created, with the old
    idempotency check (`if "org_node" not in cols: return`) then permanently
    skipping any further attempt to create it.
    
    Adds _reconcile_duplicate_active_work_graph_runs(), which marks all but the
    most-recently-created non-terminal run per task_id as 'failed' (not 'blocked'
    -- the index's WHERE clause treats 'blocked' as still-active, which was the
    first fix attempt and still failed) before the index is created. Recency is
    ranked by rowid, not run_id: real data has started_at=NULL on every legacy
    row, so a run_id tiebreak would pick among duplicates by UUID string value,
    unrelated to actual insertion order.
    
    Also splits the idempotency check into column-drop and index-creation halves
    so a database already in the partially-migrated state (like the live one)
    gets the missing index created on the next run instead of being skipped.
    
    Dry-run verified against a copy of the live 36-row production DB before
    applying to the real ~/.graphlemon/graphlemon.db (backend_server was down for
    this, no concurrent writers).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • …0cd7-main-checkout-drift
    graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • graphlemon authored
     
    Browse Code »
  • …6f22-main-checkout-drift
    graphlemon authored
     
    Browse Code »
  • Real production gap found while resuming stuck self-hosting tasks:
    .claude/agents/planner_reviewer.md was never deployed after Phase 1 (Org
    Graph unification, commit ea19c7d) added the planner_reviewer role --
    role.json/SOUL.md/AGENTS.md all existed, but nobody re-ran
    agent_profile.deploy_agent_definitions() against this live checkout after
    adding the role, so every task reaching the planner_reviewer review stage
    failed immediately with "claude --agent 'planner_reviewer' not found" and
    landed on blocked_pending_human/execution_error. This has silently been
    blocking every task since Phase 1 shipped.
    
    Re-running deploy_agent_definitions() also caught coder.md/validator.md
    drifting out of sync with their role.json skills lists (missing
    design-dynamic-work-graph, work-graph-node-review, skill-defect-remediation,
    unknown-scope-defect-sweep -- accumulated from several sessions' worth of
    role.json edits that never got redeployed). planner.md was already in sync.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • This is a point-in-time snapshot doc (dated 2026-08-03) that's explicitly
    meant to be hand-edited in place as gaps close, not rewritten -- three
    entries had gone stale relative to work landed since: the Planner-output
    review gate (Phase 1, already done back in early August but never marked
    here), the Work Graph node execution deblackbox migration, and the new-Goal
    auto-dispatch scheduler loop. Updated each to ✅ and refreshed the "most
    worth watching" summary and the self-hosting task table row accordingly --
    the still-open Deploy Supervisor poll_fn gap is called out explicitly as a
    *different*, still-unsolved closed loop so it doesn't get conflated with
    the now-solved scheduler entry point gap.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Removed the "disabled" framing from docs/done/validator-test-script-
    narrative-output-issue.md (moved todo/ -> done/, root cause identified,
    structural fix landed, spot-check clean) -- the mechanism it described
    (_CANONICAL_DOC_CHAIN, e2e_pipeline._VALIDATOR_MANIFEST) no longer exists
    in production code, superseded by the 2026-08-08 self-planning rewrite and
    Org Graph unification Phase 2. Planner's and Validator's self-planning
    catalogs already carry test_script as a suggested (not required) option;
    _CODER_NODE_CATALOG was the one gap -- added a matching entry there
    (mechanical check_script_compiles judgment, same as Validator's). All three
    org agents now decide per-goal whether this node is worth planning, with
    no remaining "this node type is globally off" switch anywhere.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • org-graph-unification-and-universal-self-planning-requirements.md,
    org-graph-unification-phase2-universal-self-planning-design.md,
    scheduler-new-goal-dispatch-requirements.md, and
    work-graph-node-execution-deblackbox-requirements.md all moved
    docs/todo/ -> docs/done/ (already done in earlier commits via git mv) --
    this fixes the remaining docs/todo/ path references to these four files
    across the docs that cross-link them.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Spot-check (real API spend, user-authorized) of whether the historical
    "narrative text standing in for real output" failure mode
    (docs/todo/validator-test-script-narrative-output-issue.md) recurs now that
    Coder self-plans its implementation graph (Org Graph unification Phase 2).
    
    Built a non-self-target temp repo with a real rate-limiter module containing
    a planted bug, and a goal requiring Coder to read it and produce an audit
    report -- the same "explore then produce content" trigger condition the
    original incident's root-cause analysis identified. Ran the real production
    path (plan_work_graph + run_graph) with RUN_REAL_AGENT_E2E=1.
    
    Result: not reproduced. The self-planned node's content was a real,
    line-cited audit report (correctly found the planted bug plus four other
    genuine issues), not narration standing in for missing work -- despite the
    Coder catalog's "impl" entry having no suggested_judgment, the planning LLM
    voluntarily attached its own narrative-detection judgment, closely mirroring
    work-graph-node-review's methodology. Recorded as a new timeline entry with
    an explicit single-run-confidence caveat and a concrete next step
    (_NODE_REVIEW_JUDGE_PROMPT wired directly into the catalog) if a real
    recurrence shows up later.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • Implements docs/done/work-graph-node-execution-deblackbox-requirements.md
    end to end. The three documented call sites (e2e_pipeline.py::
    _check_prd_consistency, work_graph_orchestrate.py::_llm_judgment_verify_fn,
    work_graph_orchestrate.py::_make_run_fn) all used to render a one-off
    Dynamic Workflow .js script and run it via `claude -p 'Run /<name>...'`
    purely to get "agent identity + schema-shaped output" -- a workaround for
    --json-schema silently conflicting with --agent (05 §5.4.1.1). That
    workaround was never actually necessary: work_graph_plan.py::
    plan_work_graph() solved the identical problem from day one with a flat
    `claude --agent ... -p ...` call + ```json-fence extraction from free text,
    already validated in production.
    
    New org_node_trigger.trigger_org_node_structured() unifies all three call
    sites onto that same flat-call approach. extract_json_payload() generalizes
    work_graph_plan.py's fence-extraction algorithm; _extract_graph_manifest is
    now a thin wrapper over it. Two more call sites not in the original design
    doc (written before they existed) were found and migrated too:
    _run_reflection_perspective and _fix_skill_for_node (Phase 2a's
    Reflection-review/Fix-Skill). work_graph_fork.py needed no changes -- it
    only reaches _make_run_fn indirectly via run_graph(), so it benefits
    automatically.
    
    FR-4's real-agent verification (RUN_REAL_AGENT_E2E=1, mandatory, not
    optional -- src/test_org_node_trigger_e2e.py) confirmed persona loading,
    --model override, and JSON-fence extraction all work against a real model.
    
    write_workflow_script/execute_work_graph/execute_work_graph_with_usage_
    limit_retry are confirmed to have no remaining production callers;
    docstrings mark them historical, the file is kept (not deleted).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • New src/new_goal_dispatch.py (find_queued_tasks() + dispatch_once(), mirroring
    task_reconciliation.py's shape but deliberately a separate module/loop --
    scheduler-task-reconciliation-design.md §7 already established the "don't
    merge into one mega scheduler loop" principle, this follows it). Wired into
    backend_server.py::main() as its own daemon thread with
    --new-goal-dispatch-interval-seconds (default 45s, shorter than
    reconciliation's 300s to satisfy the near-real-time acceptance bar) and
    --disable-new-goal-dispatch-loop.
    
    Also added the matching --disable-new-goal-dispatch-loop flag to
    supervisor/deploy_stage.py::_launch_candidate() -- same reasoning as the
    existing --disable-reconciliation-loop flag there: a health-checking deploy
    candidate runs against a copy of the production DB and must stay passive
    until Deploy Supervisor decides it's live, otherwise it would start
    autonomously dispatching real Goals off stale/copied state.
    
    User-confirmed 2026-08-13: full auto-dispatch, not a conservative
    default-disabled rollout -- this was previously flagged as a standalone
    "changes the system's own autonomy boundary" decision requiring separate
    review (docs/done/scheduler-new-goal-dispatch-requirements.md), now resolved.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • FR-5a: a new, standalone four-stage Org meta-graph (renderOrgMetaGraph and
    friends) rather than extending the existing 3-node renderOrgGraphTopology
    (left untouched, it's pinned by test_graph_console_smoke.js). Each stage
    expands in place: planner/coder/validator reuse renderGraphVisualizerPanel
    unmodified against that stage's latest run (identified via org_nodes_involved,
    Phase 2c's replacement for the removed single-value org_node column);
    planner_reviewer has no self-planned work_graph_run, so it shows its
    planner_review_verdict execution_event history instead (new
    task_query.py::_planner_review_events_for_task(), mirroring the existing
    _loop_back_events_for_run() pattern).
    
    FR-5b: an attempt_number-ordered, click-to-reveal feedback timeline built
    from loop_back_events, which was already being fetched but never rendered.
    
    New frontend/test_org_meta_graph_smoke.js (35 assertions, same vm.Context
    sandbox convention as the existing 4 smoke tests).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • New skills/work-graph-node-review/SKILL.md documents the methodology for
    judging a self-planned Work Graph node's output (real structured content
    vs. narrative prose standing in for it) -- distilled from the real
    narrative-output incident (docs/todo/validator-test-script-narrative-
    output-issue.md §6) and the conditional-not-assertive phrasing lesson
    already applied in _NARRATION_RETRY_HINT. Scoped explicitly against
    planner-output-review (Planner's fixed doc chain, task-level gate),
    qa-task-validation (overall task acceptance), and skill-defect-remediation
    (rewriting a Skill file itself) -- this one judges a single self-planned
    node's output, nothing broader.
    
    Wired into roles/planner_reviewer, roles/coder, roles/validator role.json
    skills lists. .claude/agents/*.md left untouched -- that's a deploy-time
    artifact compiled from role.json by agent_profile.deploy_agent_definitions(),
    not hand-synced (confirmed stale already: coder.md is missing an even
    earlier Phase 2a skill addition).
    
    This completes Phase 2c (§2.1/§2.2/§6/§7.1 all implemented; §7.2's
    analysis was completed earlier without needing a code change).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »
  • A merged graph's one run genuinely spans several org_nodes now (Planner/
    Coder/Validator all append their own nodes into the SAME run) -- a single
    run-level org_node column was never accurate once Phase 2b/2c landed, and
    real per-node ownership already lives in work_node_execution.subagent_type.
    
    Schema: work_graph_run.org_node column removed; ux_work_graph_run_active
    narrowed from UNIQUE(task_id, org_node) to UNIQUE(task_id) WHERE status
    NOT IN ('done', 'failed') -- 'blocked' now counts as active on purpose,
    since resuming a blocked run always appends into the same row rather than
    inserting a fresh one. New migrate_drop_work_graph_run_org_node() handles
    already-populated databases, wired into backend_server.py's startup path.
    
    Call sites updated: work_graph_plan.py/work_graph_fork.py/
    root_cause_trace.py's INSERTs; work_graph_run_query.py/task_query.py now
    return "org_nodes_involved" (derived from work_node_execution.subagent_type)
    instead of the removed single-value "org_node"; frontend/app.js's org-strip
    and run-list rendering updated to the list-based shape.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »

  • Validator's terminal verdict is now a real self-planned node (node_type=
    'final_verdict', judgment.kind='mechanical', on_fail.action=
    'dynamic_loop_back') appended into the SAME shared work_graph_run Planner
    and Coder already contribute to (plan_work_graph(..., append_to_run_id=
    run_id)), instead of a flat post-graph org_node_trigger call against a
    separate hardcoded Validator manifest. This is what lets a failing verdict
    genuinely trigger Reflection-review + Fix-Skill + a precise loop back to
    whichever real ancestor node is at fault, reusing the existing
    dynamic_loop_back machinery instead of a parallel retry loop.
    
    The 2026-08-06 hard gate (a real non-zero exit from Validator's own test
    script force-overrides the verdict to FAIL, Python-enforced not just
    prompted) is preserved via a build_prompt wrapper + mechanical check
    closure sharing mutable state. INCONCLUSIVE is now treated the same as
    FAIL (triggers a bounded retry via dynamic_loop_back) rather than accepted
    as a terminal result.
    
    _VALIDATOR_MANIFEST/_VALIDATOR_DOC_PROMPTS/_VALIDATOR_VERDICT_PROMPT/
    _validator_prompt_builder are kept unused (same precedent as _CODER_PROMPT).
    org_node column removal (§2.1), index narrowing (§2.2), and the new
    work-graph-node-review skill (§7.1) remain for a later sub-phase.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    bboonnee authored
     
    Browse Code »