Commit ecd06689064bf8f34c045a9a199bdbd352523ded
1 parent
68055d13
graphlemon: auto-commit uncommitted changes for 77def7e3-7be4-4dee-8657-3a65bd9d…
…6f22-main-checkout-drift
Showing
1 changed file
with
53 additions
and
17 deletions
CLAUDE.md
| @@ -8,10 +8,10 @@ Read this first, then follow the pointers below — do not start writing code be | @@ -8,10 +8,10 @@ Read this first, then follow the pointers below — do not start writing code be | ||
| 8 | ## What this is | 8 | ## What this is |
| 9 | 9 | ||
| 10 | **graphlemon** is a Level 5 autonomous "lights-out software factory": a two-layer Organizer Agent | 10 | **graphlemon** is a Level 5 autonomous "lights-out software factory": a two-layer Organizer Agent |
| 11 | -architecture (Org Graph = fixed Planner→Coder→Validator; Work Graph = dynamic per-task execution | ||
| 12 | -graph) that drives real software development end-to-end, backed entirely by Claude Code ACP | ||
| 13 | -(`claude -p` non-interactive calls) — there is no Hermes CLI execution backend in this project | ||
| 14 | -(decision, 2026-07-29, see `docs/sdd/05-实施约束与依赖.md` §5.3). | 11 | +architecture (Org Graph = fixed Planner→Planner-Reviewer→Coder→Validator; Work Graph = dynamic |
| 12 | +per-task execution graph) that drives real software development end-to-end, backed entirely by | ||
| 13 | +Claude Code ACP (`claude -p` non-interactive calls) — there is no Hermes CLI execution backend in | ||
| 14 | +this project (decision, 2026-07-29, see `docs/sdd/05-实施约束与依赖.md` §5.3). | ||
| 15 | 15 | ||
| 16 | The authoritative spec is `docs/sdd/` (00-06 + `docs/sdd/sdd-mvcp-contract.json`), generated via | 16 | The authoritative spec is `docs/sdd/` (00-06 + `docs/sdd/sdd-mvcp-contract.json`), generated via |
| 17 | the MVCP (Model/View/Controller/Process) methodology from `docs/graphlemon_architecture.md`. | 17 | the MVCP (Model/View/Controller/Process) methodology from `docs/graphlemon_architecture.md`. |
| @@ -28,10 +28,11 @@ Unit from U-001 through U-043 has a matching commit, plus many `U-0XX fix:`/`U-0 | @@ -28,10 +28,11 @@ Unit from U-001 through U-043 has a matching commit, plus many `U-0XX fix:`/`U-0 | ||
| 28 | commits for bugs found during real (not mocked) runs, plus a long tail of `graphlemon: <artifact | 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: | 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 | 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`. | 31 | +Planner→Planner-Reviewer→Coder→Validator loop against its own repo (`target_folder_path` == this |
| 32 | +checkout, `src/paths.is_self_target()`), with the Deploy Supervisor (`supervisor/`) staging, | ||
| 33 | +health-checking, and cutting over its own code changes. PH5 (self-modification / auto-rollback) is | ||
| 34 | +real and running, not future work — see "Two things named Supervisor" below and | ||
| 35 | +`supervisor/self_hosting_e2e.py`. | ||
| 35 | 36 | ||
| 36 | When a `development-plan.md` line and the actual code disagree about what's done, trust the code | 37 | 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 | and `git log`, and — if it matters to the task at hand — flag the doc as stale rather than |
| @@ -41,6 +42,17 @@ during self-hosting runs and how they were fixed (e.g. worktree commits being si | @@ -41,6 +42,17 @@ during self-hosting runs and how they were fixed (e.g. worktree commits being si | ||
| 41 | `memory: project` writes landing on the wrong checkout) — read them before touching | 42 | `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 | `supervisor/isolation/`, `src/work_node_run.py`, or anything worktree-related. |
| 43 | 44 | ||
| 45 | +Work beyond the original 43 Units is tracked the same `docs/todo/` → `docs/done/` way, not in | ||
| 46 | +`development-plan.md`: the `planner_reviewer` Org node (a read-only gate that judges whether | ||
| 47 | +Planner's BRD/PRD/SDD output is real structured content before Coder is allowed to start — | ||
| 48 | +`roles/planner_reviewer/role.json`, wired into the loop from `src/e2e_pipeline.py` and | ||
| 49 | +`src/task_execution.py`, task states `reviewing_planner_output`/`planning_brd_prd_sdd`) shipped as | ||
| 50 | +"Org Graph unification Phase 1" (commit `ea19c7d`); its design doc is still sitting in | ||
| 51 | +`docs/todo/org-graph-unification-phase1-review-gate-design.md` even though the code is live — | ||
| 52 | +another instance of code-vs-doc drift, not a sign the feature is unimplemented. Phase 2 (universal | ||
| 53 | +self-planning + merged graph + dynamic loop_back, `docs/todo/org-graph-unification-phase2-*`) is | ||
| 54 | +SDD-written but check `git log`/the actual Phase 2 code before assuming it's running. | ||
| 55 | + | ||
| 44 | ## Where to start | 56 | ## Where to start |
| 45 | 57 | ||
| 46 | 1. Read `docs/development-plan.md` for the Phase → Sub-phase → Unit breakdown and the *design* | 58 | 1. Read `docs/development-plan.md` for the Phase → Sub-phase → Unit breakdown and the *design* |
| @@ -91,6 +103,11 @@ No build step, no lint config, no package manager — pure stdlib Python, nothin | @@ -91,6 +103,11 @@ No build step, no lint config, no package manager — pure stdlib Python, nothin | ||
| 91 | 103 | ||
| 92 | # local console (U-007/U-008): backend serves the API, frontend is static no-build HTML/JS | 104 | # 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) | 105 | python3 -m src.backend_server --port 8000 # default --port 0 means OS-assigned (fine for tests, not for browsing) |
| 106 | + | ||
| 107 | +# frontend/app.js has no framework and no automated-test precedent per the SDD (manual browser | ||
| 108 | +# verification is the norm), but a few DOM-rendering functions do have plain-Node smoke tests | ||
| 109 | +# (vm.Context sandboxing, no npm deps) — run individually, there's no aggregate runner: | ||
| 110 | +node frontend/test_graph_console_smoke.js | ||
| 94 | ``` | 111 | ``` |
| 95 | 112 | ||
| 96 | ## Hard constraints (do not relitigate these — they're settled decisions) | 113 | ## Hard constraints (do not relitigate these — they're settled decisions) |
| @@ -170,16 +187,34 @@ directly; anything worth reusing has already been copied and adapted into this r | @@ -170,16 +187,34 @@ directly; anything worth reusing has already been copied and adapted into this r | ||
| 170 | - `docs/wireframes/` — static no-build HTML prototypes for the PH3 console views (`v_*.html`), | 187 | - `docs/wireframes/` — static no-build HTML prototypes for the PH3 console views (`v_*.html`), |
| 171 | referenced per-page from `docs/sdd/02-V-界面与交互.md` §2.1-2.13; DOM/class names map 1:1 to | 188 | referenced per-page from `docs/sdd/02-V-界面与交互.md` §2.1-2.13; DOM/class names map 1:1 to |
| 172 | that doc's field lists. | 189 | that doc's field lists. |
| 190 | +- `roles/<role_id>/role.json` — the Role Package abstraction (H, 2026-08-06, | ||
| 191 | + `docs/done/role-package-abstraction-design.md`): the declarative manifest for each Org node | ||
| 192 | + (`skills:`/`model:`/`permissions.tools`/etc., including the `skills:` frontmatter list for | ||
| 193 | + that role's `.claude/agents/*.md`). This **replaced** the old hardcoded | ||
| 194 | + `src/agent_profile.py::FRONTMATTER`/`_DESCRIPTIONS`/`_MIGRATED_FROM_PROFILE` Python dicts — | ||
| 195 | + edit `roles/<role_id>/role.json`, not `agent_profile.py`, to change a role's declared | ||
| 196 | + skills/model/tools. `ORG_NODES` is no longer a fixed 3-tuple; `src/agent_profile.py` discovers | ||
| 197 | + it by scanning `roles/` for directories containing a `role.json`, so adding a new Org role is | ||
| 198 | + one new JSON file, no `schema.py`/`agent_profile.py` edit. `role.json` is JSON (not YAML, | ||
| 199 | + despite Skill files using YAML frontmatter) because, unlike Skill frontmatter, this file is | ||
| 200 | + parsed by graphlemon's own Python code, not just by Claude Code. `identity.soul_md_path`/ | ||
| 201 | + `agents_md_path` in each `role.json` still point at the unmoved `agents/<org_node>/SOUL.md`/ | ||
| 202 | + `AGENTS.md` files below — `role.json` is a reference manifest, not a content copy. | ||
| 173 | - `skills/` — the Skill library (architecture doc §7.3): one directory per skill | 203 | - `skills/` — the Skill library (architecture doc §7.3): one directory per skill |
| 174 | (`skills/<name>/SKILL.md` + optional `references/`), migrated/adapted from the Hermes profiles | 204 | (`skills/<name>/SKILL.md` + optional `references/`), migrated/adapted from the Hermes profiles |
| 175 | - (§9's role mapping) and referenced by name from each Org Agent's `.claude/agents/*.md` | ||
| 176 | - `skills:` frontmatter list (`src/agent_profile.py::FRONTMATTER`, the canonical source of that | ||
| 177 | - list — edit it there, not by hand-editing the deployed `.claude/agents/*.md`). | ||
| 178 | -- `.claude/workflows/` — auto-generated, not hand-authored: real Dynamic Workflow scripts written | ||
| 179 | - by `src/work_graph_execute.py::write_workflow_script()`/`src/work_graph_orchestrate.py` (one | ||
| 180 | - script per Work Node execution) and by `e2e_pipeline.py`'s PRD-consistency check. Version- | ||
| 181 | - controlled because it's inside the target repo (self-target case: this repo), but treat the | ||
| 182 | - contents as execution artifacts, not source you maintain by hand. | 205 | + (§9's role mapping) and referenced by name from each Org role's `roles/<role_id>/role.json` |
| 206 | + `skills:` list, which is compiled into the deployed `.claude/agents/*.md` `skills:` frontmatter. | ||
| 207 | +- `.claude/workflows/` — **historical mechanism, 2026-08 onward**: used to hold auto-generated | ||
| 208 | + Dynamic Workflow scripts written by `src/work_graph_execute.py::write_workflow_script()`, one | ||
| 209 | + per Work Node execution (`work_graph_orchestrate.py`) plus `e2e_pipeline.py`'s PRD-consistency | ||
| 210 | + check. As of the work-graph-node-execution-deblackbox migration (2026-08, | ||
| 211 | + `docs/todo/work-graph-node-execution-deblackbox-requirements.md`), production code no longer | ||
| 212 | + writes new files here — every call site that used to render a one-off `.js` script purely to | ||
| 213 | + get "agent identity + schema-shaped output" now uses `org_node_trigger. | ||
| 214 | + trigger_org_node_structured()` (a flat `claude --agent` call + ```json-fence extraction, the | ||
| 215 | + same mechanism `work_graph_plan.py::plan_work_graph()` had already validated in production). | ||
| 216 | + Files already generated by real self-hosting runs before this migration are kept (execution | ||
| 217 | + artifacts, not source you maintain by hand) — this directory just stops growing. | ||
| 183 | - `src/` — graphlemon's own backend: `schema.py` (17-table SQLite schema — the original 01-M 15 | 218 | - `src/` — graphlemon's own backend: `schema.py` (17-table SQLite schema — the original 01-M 15 |
| 184 | entities plus PH5's `deployment`/`deploy_health_signal`), `backend_server.py` (stdlib | 219 | entities plus PH5's `deployment`/`deploy_health_signal`), `backend_server.py` (stdlib |
| 185 | `http.server` HTTP API + WebSocket-ish log/event streaming, no third-party deps), the Org Graph | 220 | `http.server` HTTP API + WebSocket-ish log/event streaming, no third-party deps), the Org Graph |
| @@ -198,7 +233,8 @@ directly; anything worth reusing has already been copied and adapted into this r | @@ -198,7 +233,8 @@ directly; anything worth reusing has already been copied and adapted into this r | ||
| 198 | `isolated_workspace.py`, `change_manifest.py`, `selective_apply.py`, `workspace_security.py`, | 233 | `isolated_workspace.py`, `change_manifest.py`, `selective_apply.py`, `workspace_security.py`, |
| 199 | adapted from graphloop). `supervisor/self_hosting_e2e.py` is the acceptance-scenario glue that | 234 | adapted from graphloop). `supervisor/self_hosting_e2e.py` is the acceptance-scenario glue that |
| 200 | wires Graph Engine scheduling + Deploy Supervisor into one real self-targeted run. | 235 | wires Graph Engine scheduling + Deploy Supervisor into one real self-targeted run. |
| 201 | -- `agents/{coder,planner,validator}/SOUL.md` — original Hermes-profile identity docs, migrated | 236 | +- `agents/{coder,planner,planner_reviewer,validator}/SOUL.md` — original Hermes-profile identity |
| 237 | + docs (`planner_reviewer` added 2026-08, see Org Graph unification note below), migrated | ||
| 202 | 2026-07-31 (A-2 assumption, "部分成立" — Coder's needed real rewriting to drop a hardcoded | 238 | 2026-07-31 (A-2 assumption, "部分成立" — Coder's needed real rewriting to drop a hardcoded |
| 203 | Feishu API token and a `--dangerously-skip-permissions` self-invocation; Planner/Validator were | 239 | Feishu API token and a `--dangerously-skip-permissions` self-invocation; Planner/Validator were |
| 204 | near-verbatim). These are the source-of-truth prose; `.claude/agents/*.md` is the actual | 240 | near-verbatim). These are the source-of-truth prose; `.claude/agents/*.md` is the actual |