Commit a5f1618eb6c9d5faa4227234afe4e7338f686a38

Authored by bboonnee
1 parent 5098fbe4

Rewrite CLAUDE.md to reflect current repo state, not PH0-era scaffolding

The original CLAUDE.md described a pre-scaffolding repo with no commits and
open questions about A-2/critical path -- stale since PH0. Updates it to
point at git log as the actual status record, document the two independent
unittest discover roots (src/ and supervisor/), the real backend_server.py
CLI, the .graphlemon-worktrees/ isolation mechanism and its three real
incident notes, and a full repo layout reflecting what's actually there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing 1 changed file with 134 additions and 63 deletions
CLAUDE.md
1 # CLAUDE.md 1 # CLAUDE.md
2 2
3 -This file orients Claude Code when working in this repository. Read this first, then follow the  
4 -pointers below — do not start writing code before reading `docs/development-plan.md` and the  
5 -current Unit's coverage references in `docs/sdd/`. 3 +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
  4 +
  5 +Read this first, then follow the pointers below — do not start writing code before reading
  6 +`docs/development-plan.md` and the current Unit's coverage references in `docs/sdd/`.
6 7
7 ## What this is 8 ## What this is
8 9
@@ -18,80 +19,125 @@ the MVCP (Model/View/Controller/Process) methodology from `docs/graphlemon_archi @@ -18,80 +19,125 @@ the MVCP (Model/View/Controller/Process) methodology from `docs/graphlemon_archi
18 equivalent input that produced the SDD. When they conflict, the SDD wins (it's newer and more 19 equivalent input that produced the SDD. When they conflict, the SDD wins (it's newer and more
19 detailed); if a conflict looks unresolved, stop and ask rather than picking one silently. 20 detailed); if a conflict looks unresolved, stop and ask rather than picking one silently.
20 21
  22 +## Status: all 43 planned Units (U-001~U-043, PH0~PH5) are implemented and committed
  23 +
  24 +`docs/development-plan.md` and `docs/sdd/unit_matrix.json` describe the plan as it read at
  25 +inception (2026-07-29) — they were **not** kept updated with "done" checkmarks as work landed, so
  26 +don't treat their prose as a live status board. `git log --oneline` is the actual record: every
  27 +Unit from U-001 through U-043 has a matching commit, plus many `U-0XX fix:`/`U-0XX follow-up:`
  28 +commits for bugs found during real (not mocked) runs, plus a long tail of `graphlemon: <artifact
  29 +type> for task <uuid>` / `graphlemon: auto-commit uncommitted changes for <id>` / `graphlemon:
  30 +merge <id>` commits — those are graphlemon **actually self-hosting**: running its own
  31 +Planner→Coder→Validator loop against its own repo (`target_folder_path` == this checkout,
  32 +`src/paths.is_self_target()`), with the Deploy Supervisor (`supervisor/`) staging, health-checking,
  33 +and cutting over its own code changes. PH5 (self-modification / auto-rollback) is real and running,
  34 +not future work — see "Two things named Supervisor" below and `supervisor/self_hosting_e2e.py`.
  35 +
  36 +When a `development-plan.md` line and the actual code disagree about what's done, trust the code
  37 +and `git log`, and — if it matters to the task at hand — flag the doc as stale rather than
  38 +silently trusting either source. `development-plan.md`'s per-Unit "实现补充"/"真实 bug" notes
  39 +(inline, added after-the-fact) are still valuable: they're a real incident log of bugs found
  40 +during self-hosting runs and how they were fixed (e.g. worktree commits being silently dropped,
  41 +`memory: project` writes landing on the wrong checkout) — read them before touching
  42 +`supervisor/isolation/`, `src/work_node_run.py`, or anything worktree-related.
  43 +
21 ## Where to start 44 ## Where to start
22 45
23 -1. Read `docs/development-plan.md` — Phase → Sub-phase → Unit breakdown (`docs/sdd/unit_matrix.json`  
24 - is the machine-readable mirror). Work is organized as Development Units, each classified  
25 - Value Path / Risk Gate / Enabler, each with explicit `depends_on` and a `done` criterion that  
26 - references a specific REQ in `docs/sdd/06-验收与测试锚点.md`.  
27 -2. The critical path starts at **U-001** (01-M schema) → U-002 → U-004 → ... Follow  
28 - `development-plan.md` §3 "关键路径" — do not skip ahead to later Units even if they look more  
29 - interesting; most have real `depends_on` edges.  
30 -3. **U-004 (A-2 assumption) is the next unvalidated risk on the critical path.** A-1 (dynamic  
31 - workflow programmatic invocation) was already spike-validated (`spikes/a1-dynamic-workflows/`,  
32 - confirmed 2026-07-29). A-2 (Hermes profile SOUL.md/AGENTS.md migrating cleanly into  
33 - `.claude/agents/*.md` without major rewrites) is not yet tested. Validate it early with a  
34 - minimal spike (per `development-plan.md`'s explicit recommendation) rather than discovering  
35 - problems after U-010/U-011 are fully built on top of it. 46 +1. Read `docs/development-plan.md` for the Phase → Sub-phase → Unit breakdown and the *design*
  47 + rationale behind each piece — but see Status above before trusting any "done"/"depends_on"
  48 + framing as current. `docs/sdd/unit_matrix.json` is its machine-readable mirror (also static).
  49 +2. `docs/sdd/06-验收与测试锚点.md` has REQ-01 through REQ-15, the acceptance anchors every Unit's
  50 + Done criterion cites. REQ-15 (PH5, Deploy Supervisor blue-green + auto-rollback) was added
  51 + 2026-07-30 after the original REQ-01~14 set.
  52 +3. For any specific behavior, prefer reading the actual module in `src/`/`supervisor/`/`agents/`
  53 + over the plan doc — the plan doc records intent at write-time and known deviations, the code is
  54 + truth.
36 55
37 ## Commands 56 ## Commands
38 57
39 -No build, lint, or test tooling exists yet — the repo is pre-scaffolding (PH0, no commits made  
40 -yet). `supervisor/isolation/` has no test suite of its own (that's U-036); `docs/` and `spikes/`  
41 -aren't packages. The one real executable entry point today: 58 +Two independent `unittest discover` roots — there is no single top-level `discover` that covers
  59 +both (deliberately: `supervisor/` was added later as PH5 landed, see
  60 +`development-plan.md`'s U-036 note):
42 61
43 ```bash 62 ```bash
44 -# A-1 spike: verify Claude Code dynamic workflows can be invoked headlessly (already validated,  
45 -# kept here for re-running / reference — see spikes/a1-dynamic-workflows/RESULTS.md)  
46 -./spikes/a1-dynamic-workflows/run-spike.sh /path/to/some/git/repo 63 +# graphlemon's own backend/schema/agent-orchestration code (441 tests as of U-043)
  64 +python3 -m unittest discover -s src
  65 +
  66 +# Deploy Supervisor + the isolate/diff/apply library it depends on
  67 +# (this also picks up supervisor/isolation/test_*.py — no separate invocation needed)
  68 +python3 -m unittest discover -s supervisor -p "test_*.py"
  69 +
  70 +# single test
  71 +python3 -m unittest src.test_work_graph_execute.SomeTestClass.test_method
  72 +```
  73 +
  74 +Both suites skip real-`claude`-subprocess tests by default (`skip_unless_env`, `src/test_support.py`)
  75 +— those need `RUN_REAL_AGENT_E2E=1` and real API spend, e.g.:
  76 +
  77 +```bash
  78 +RUN_REAL_AGENT_E2E=1 python3 -m unittest src.test_agent_e2e
47 ``` 79 ```
48 80
49 -Once U-002/U-003 scaffold `src/`, tests run via stdlib `unittest` only (see Testing below) — there  
50 -is no repo convention yet for a single-test invocation beyond the standard  
51 -`python3 -m unittest path.to.test_module.TestClass.test_method`; don't invent a different pattern. 81 +`supervisor/self_hosting_e2e.py`'s own real end-to-end scenario (`run_self_hosting_closed_loop`,
  82 +the literal 9-step self-development-feasibility.md walkthrough) is gated the same way in
  83 +`supervisor/test_self_hosting_e2e.py` — do not invoke it casually; it does a real self-targeted
  84 +Planner→Coder→Validator→stage→cutover→monitor run against **this repo**.
  85 +
  86 +No build step, no lint config, no package manager — pure stdlib Python, nothing to install.
  87 +
  88 +```bash
  89 +# A-1 spike (already validated 2026-07-29, kept for reference/re-running)
  90 +./spikes/a1-dynamic-workflows/run-spike.sh /path/to/some/git/repo
  91 +
  92 +# local console (U-007/U-008): backend serves the API, frontend is static no-build HTML/JS
  93 +python3 -m src.backend_server --port 8000 # default --port 0 means OS-assigned (fine for tests, not for browsing)
  94 +```
52 95
53 ## Hard constraints (do not relitigate these — they're settled decisions) 96 ## Hard constraints (do not relitigate these — they're settled decisions)
54 97
55 - **Execution backend**: Claude Code ACP only (`claude -p ... --output-format json --json-schema 98 - **Execution backend**: Claude Code ACP only (`claude -p ... --output-format json --json-schema
56 <schema> --permission-mode auto`, no `--bare`, no `--dangerously-skip-permissions`). See 99 <schema> --permission-mode auto`, no `--bare`, no `--dangerously-skip-permissions`). See
57 - 05 §5.3, §5.3.1, §5.4. 100 + 05 §5.3, §5.3.1, §5.4. One documented gotcha: `--agent` + `--json-schema` together silently drop
  101 + `structured_output` — see 05 §5.4.1.1 and `src/work_graph_plan.py`'s ```` ```json ```` fence
  102 + parsing workaround.
58 - **Implementation language**: graphlemon's own backend/frontend/Deploy Supervisor are **pure 103 - **Implementation language**: graphlemon's own backend/frontend/Deploy Supervisor are **pure
59 stdlib Python** — no Flask/FastAPI/Express/Node.js, no npm build step. This mirrors the 104 stdlib Python** — no Flask/FastAPI/Express/Node.js, no npm build step. This mirrors the
60 predecessor project graphloop's convention. See 05 §5.7. (This constraint is on graphlemon's 105 predecessor project graphloop's convention. See 05 §5.7. (This constraint is on graphlemon's
61 own implementation only — it does NOT apply to the code graphlemon generates for target 106 own implementation only — it does NOT apply to the code graphlemon generates for target
62 projects, which follows whatever stack that target project uses.) 107 projects, which follows whatever stack that target project uses.)
63 - **Testing**: stdlib `unittest` only, no pytest/fixtures. Mock the `subprocess`/`claude -p` 108 - **Testing**: stdlib `unittest` only, no pytest/fixtures. Mock the `subprocess`/`claude -p`
64 - boundary in normal tests; real end-to-end tests that actually shell out to `claude` should be  
65 - gated behind an explicit env var and skipped by default (mirror graphloop's  
66 - `RUN_REAL_AGENT_E2E=1` pattern) — this project doesn't have that harness yet, build it as part  
67 - of the relevant Unit rather than improvising a different pattern per test file.  
68 -- **Isolation**: parallel coding nodes must use `git_worktree_ref`. If `target_folder_path` is  
69 - graphlemon's own repo (self-hosting/self-modification, PH5 only), worktree is **unconditionally  
70 - mandatory** even for serial single-node changes — see 05 §5.8. 109 + boundary in normal tests; real end-to-end tests that actually shell out to `claude` are gated
  110 + behind `RUN_REAL_AGENT_E2E=1` (`src/test_support.py:skip_unless_env`, mirrors graphloop's
  111 + precedent) — reuse that helper, don't invent a per-file variant.
  112 +- **Isolation**: parallel coding nodes must use `git_worktree_ref` (`src/work_node_run.py`). If
  113 + `target_folder_path` is graphlemon's own repo (self-hosting/self-modification), worktree is
  114 + **unconditionally mandatory** even for serial single-node changes — see 05 §5.8,
  115 + `src/paths.is_self_target()`. Worktree checkouts live at `.graphlemon-worktrees/<node_exec_id>/`
  116 + **inside** the main repo's working tree while a node runs (gitignored — never let `git add -A`
  117 + on `repo_path` pick one up mid-run). Before touching this code, read the three `U-013` incident
  118 + notes in `development-plan.md` (uncommitted worktree changes silently dropped on merge, `memory:
  119 + project` writes landing on the main checkout instead of the worktree, and the pathspec-vs-gitignore
  120 + conflict that fixing the second one introduced) — `work_node_run.ensure_worktree_committed()` is
  121 + the fix for all three; don't re-solve the same problem a fourth way.
71 122
72 ## Two things named "Supervisor" — do not confuse them 123 ## Two things named "Supervisor" — do not confuse them
73 124
74 1. **"Supervisor(调度子 Agent)"** — an in-process monitoring node inside the Coder Work Graph 125 1. **"Supervisor(调度子 Agent)"** — an in-process monitoring node inside the Coder Work Graph
75 (architecture doc, existing concept). Watches Work Node execution, triggers reflection/ 126 (architecture doc, existing concept). Watches Work Node execution, triggers reflection/
76 rescheduling. Part of the Graph Engine itself. 127 rescheduling. Part of the Graph Engine itself.
77 -2. **"Deploy Supervisor"** — an independent OS process, entirely outside the Graph Engine, that  
78 - handles blue-green deployment and automatic rollback when graphlemon modifies its own code  
79 - (PH5 only). See `docs/supervisor-auto-rollback-design.md` for the full design and the  
80 - disambiguation note at the top of that file. 128 +2. **"Deploy Supervisor"** (`supervisor/`) — an independent OS process (`python3 -m
  129 + supervisor.deploy_supervisor`), entirely outside the Graph Engine, that handles blue-green
  130 + deployment and automatic rollback when graphlemon modifies its own code. Fully implemented
  131 + (U-034~U-043): `deploy_stage.py` (stage a candidate), `deploy_health_check.py` (poll for
  132 + startup readiness, not one-shot — see U-038 fix), `deploy_cutover.py`, `deploy_monitor.py`,
  133 + `deploy_rollback.py`. Fail-closed, never-auto-restart philosophy adapted (not imported) from
  134 + graphloop's `hermes_watchdog.py`. See `docs/supervisor-auto-rollback-design.md` for the full
  135 + design and the disambiguation note at the top of that file.
81 136
82 These are unrelated components that happen to share a root word in casual English. Identifiers 137 These are unrelated components that happen to share a root word in casual English. Identifiers
83 for #2 are always prefixed `c_deploy_supervisor_*` / `deploy_health_signal` — never abbreviate to 138 for #2 are always prefixed `c_deploy_supervisor_*` / `deploy_health_signal` — never abbreviate to
84 just "supervisor" in code or docs. 139 just "supervisor" in code or docs.
85 140
86 -## PH5 (Deploy Supervisor / self-hosting) is not in scope yet  
87 -  
88 -`docs/development-plan.md` PH5 (Units U-034~U-043) depends on PH4 closing first — self-modification  
89 -safety only makes sense once the base system has passed full regression. Don't build any of  
90 -U-034~U-043 before PH0-PH4 are done, even though the design (`docs/supervisor-auto-rollback-design.md`)  
91 -and its four reusable isolation modules (`supervisor/isolation/`) are already staged. Those modules  
92 -were adapted from graphloop and have had exactly one manual smoke test — they still need a real  
93 -`unittest` suite (U-036) before anyone should trust them in a real rollback path.  
94 -  
95 ## Prior art worth reading, not worth copying wholesale 141 ## Prior art worth reading, not worth copying wholesale
96 142
97 `/Users/yibo/Documents/lemonAI/graphloop` is an earlier, unmaintained attempt at this same 143 `/Users/yibo/Documents/lemonAI/graphloop` is an earlier, unmaintained attempt at this same
@@ -104,20 +150,45 @@ worth reading for the &quot;fail-closed, deterministic, never-auto-restart&quot; supervisi @@ -104,20 +150,45 @@ worth reading for the &quot;fail-closed, deterministic, never-auto-restart&quot; supervisi
104 (graphlemon's Deploy Supervisor deliberately extends this into auto-rollback rather than just 150 (graphlemon's Deploy Supervisor deliberately extends this into auto-rollback rather than just
105 auto-halt — see `docs/supervisor-design-comparison.md` for why). Do not import graphloop code 151 auto-halt — see `docs/supervisor-design-comparison.md` for why). Do not import graphloop code
106 directly; anything worth reusing has already been copied and adapted into this repo 152 directly; anything worth reusing has already been copied and adapted into this repo
107 -(`supervisor/isolation/`).  
108 -  
109 -## Repo layout (as of PH0, before scaffolding exists)  
110 -  
111 -- `docs/` — architecture, SDD, development plan (see above)  
112 -- `docs/wireframes/` — static no-build HTML prototypes for the PH3 console views (`v_*.html`), referenced  
113 - per-page from `docs/sdd/02-V-界面与交互.md` §2.1-2.13 — implementation starting point once PH3 begins,  
114 - DOM/class names map 1:1 to that doc's field lists.  
115 -- `supervisor/isolation/` — staged utility library (isolate/diff/apply), not yet wired to anything  
116 -- `spikes/` — one-off validation spikes (currently just A-1)  
117 -- `src/` (created by U-001) — graphlemon's own backend source (schema, then U-007+ HTTP/WebSocket server).  
118 - **Not the same `src/` a target project already has in its own repo** — a target project's `src/` is  
119 - its own pre-existing source tree; graphlemon does not create or restructure it (see 05-实施约束与依赖.md  
120 - §5.7 and architecture doc §13.2 — U-002 only creates `.graphlemon/` inside a target project, corrected  
121 - 2026-07-31 after finding development-plan.md's U-002 line had cited the wrong architecture section).  
122 -- Everything else (`.claude/agents/`, `skills/`, `runs/`, per-target-project scaffolding) gets created by  
123 - U-002/U-003 — it doesn't exist yet, and that's expected at this stage. 153 +(`supervisor/isolation/`, adapted verbatim per the U-036 note in `development-plan.md`).
  154 +
  155 +## Repo layout
  156 +
  157 +- `docs/` — architecture doc, SDD (`docs/sdd/`), development plan, self-hosting design docs. See
  158 + Status above for how stale the plan/unit-matrix "done" framing is relative to the real code.
  159 +- `docs/wireframes/` — static no-build HTML prototypes for the PH3 console views (`v_*.html`),
  160 + referenced per-page from `docs/sdd/02-V-界面与交互.md` §2.1-2.13; DOM/class names map 1:1 to
  161 + that doc's field lists.
  162 +- `src/` — graphlemon's own backend: `schema.py` (17-table SQLite schema — the original 01-M 15
  163 + entities plus PH5's `deployment`/`deploy_health_signal`), `backend_server.py` (stdlib
  164 + `http.server` HTTP API + WebSocket-ish log/event streaming, no third-party deps), the Org Graph
  165 + layer (`org_node_trigger.py`, `org_node_lifecycle.py`, `org_loop_route.py`, `org_level_loop.py`),
  166 + the Work Graph layer (`work_graph_plan.py`, `work_graph_execute.py`, `work_graph_orchestrate.py`,
  167 + `work_node_run.py`), root-cause tracing (`root_cause_trace.py`), skills (`skill_update.py`,
  168 + `skill_query.py`), budget/scheduling (`budget_guardrail.py`, `scheduler.py`), and `paths.py`
  169 + (graphlemon's own runtime home — `~/.graphlemon` by default, override via `GRAPHLEMON_HOME`,
  170 + deliberately outside this repo checkout so logs/db never enter this repo's own git history).
  171 + **This is not the same kind of `src/` a target project has in its own repo** — a target
  172 + project's own `src/` is its pre-existing source tree; graphlemon doesn't create or restructure
  173 + it (05 §5.7, architecture doc §13.2). Each `src/x.py` has a same-directory `src/test_x.py` (and
  174 + sometimes `src/test_x_e2e.py` for the gated real-agent variant) — that pairing is the repo
  175 + convention, keep it when adding modules.
  176 +- `supervisor/` — Deploy Supervisor process + its isolation library (`supervisor/isolation/`:
  177 + `isolated_workspace.py`, `change_manifest.py`, `selective_apply.py`, `workspace_security.py`,
  178 + adapted from graphloop). `supervisor/self_hosting_e2e.py` is the acceptance-scenario glue that
  179 + wires Graph Engine scheduling + Deploy Supervisor into one real self-targeted run.
  180 +- `agents/{coder,planner,validator}/SOUL.md` — original Hermes-profile identity docs, migrated
  181 + 2026-07-31 (A-2 assumption, "部分成立" — Coder's needed real rewriting to drop a hardcoded
  182 + Feishu API token and a `--dangerously-skip-permissions` self-invocation; Planner/Validator were
  183 + near-verbatim). These are the source-of-truth prose; `.claude/agents/*.md` is the actual
  184 + Claude-Code-discoverable wrapper (frontmatter: `skills:`/`memory: project`/`tools:`/`model:`)
  185 + that Claude Code loads — if you change agent behavior, both need to move together, and the
  186 + `.claude/agents/*.md` frontmatter comment block records exactly what changed between them.
  187 +- `frontend/` — the PH3 console: static `index.html`/`app.js`/`style.css`, no build step, no npm.
  188 +- `spikes/` — one-off validation spikes (`a1-dynamic-workflows/`, confirmed 2026-07-29).
  189 +- `.claude/agent-memory/{coder,planner,validator}/` — per-agent `memory: project` files, tracked
  190 + in git on purpose (architecture doc §8 decision: memory must leave a git trail, not be silently
  191 + mutable local state).
  192 +- `.graphlemon/runs/<task_id>/` — real Artifacts (brd/prd/sdd/benchmark/code_diff/test_report)
  193 + from actual self-hosting runs against this repo. `.graphlemon-worktrees/` (gitignored, see
  194 + Isolation above) is the transient per-node worktree checkout directory, not persistent state.