Skip to content

Commit a4235d7

Browse files
Re-derive every quoted claim now that four of the five seams are closed
The docs had drifted from overclaiming to underclaiming: they still said `planner/` and `policy/` were imported by nothing, that no shipped code path drove the governed loop, that cost on a trace was always an estimate, and that the source was not on the public remote. All four had stopped being true. Every number here was re-derived by running it, not by reading the commit log: - tests 1,339 -> 1,381 passed, 10 deselected - wheel imports "93 modules" -> all 94 submodules with [all] - cli/ 1549 -> 1849, nine commands -> ten (plan) - test_planner_loop.py 62 -> 63 tests (two are parametrized; `def test_` undercounts) - six subsystem line counts in HANDOFF's tree listing - unpushed 14 -> none; the documented `git clone && uv sync` path now works, verified by cloning into a scratch dir and finding pyproject.toml Retracted across README, ROADMAP, HANDOFF, ARCHITECTURE and VISION: "imported by no other module", "nothing shipped drives this", "cost is an estimate on the trace", "you cannot install this". ROADMAP §11.7 and §12.1/12.2/ 12.4/12.5 marked done; §12 goes 0% -> ~80% and the overall count 65 -> 72 items. Its next-five list is rewritten around what is actually left, headed by §12.3 — the HTTP API still ships its own in-process session runtime beside the durable one, which is now the last seam. VISION keeps the prediction it got wrong rather than quietly fixing it: the blind spot was that "works" and "reachable" are different properties, and only the second is one a reader can see. Also wraps three over-long lines in tests/ that ruff flagged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent f767b6f commit a4235d7

7 files changed

Lines changed: 74 additions & 67 deletions

File tree

ARCHITECTURE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,9 @@ one well, the second one vaguely, and the third one not at all.
335335
## 7. Where we are against this
336336

337337
Re-derived on 2026-07-28 by executing each claim against the tree — not by
338-
reading the commit log. At that point `pytest` was **1,328 passed, 10
338+
reading the commit log. At that point `pytest` was **1,381 passed, 10
339339
deselected** (the live ones), `ruff check .` was clean, and the wheel built and
340-
imported all 93 modules in a clean virtualenv.
340+
imported all 94 submodules in a clean virtualenv.
341341

342342
| Stage | Status | The honest edge |
343343
|---|---|---|

HANDOFF.md

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ Full design: `ARCHITECTURE.md`. Thesis and honest scope: `VISION.md`.
4747
| Repo | `/home/shashank/Desktop/GraphARC`, branch `main` | |
4848
| Remote | `github.com/CodeGraphContext/GraphARC` | `git remote -v` |
4949
| HEAD | see `git log -1`; it moved four times during the last session | `git log -1` |
50-
| **Unpushed** | **14 commits.** `origin/main` is still at `feef03d` "Initial commit". | `git log origin/main..HEAD` |
51-
| Tests | **1,339 passed, 10 deselected** (live) | `.venv/bin/python -m pytest` |
50+
| **Unpushed** | **none** `origin/main` and `HEAD` agree; the source is public at last. | `git log origin/main..HEAD` |
51+
| Tests | **1,381 passed, 10 deselected** (live) | `.venv/bin/python -m pytest` |
5252
| Lint | clean | `.venv/bin/python -m ruff check .` |
53-
| Build | wheel + sdist; 93 modules import from the wheel in a clean venv | `uv build` |
53+
| Build | wheel + sdist; all 94 submodules import from the wheel with `[all]` | `uv build` |
5454
| Version | `0.1.0a0`**not yet bumped for release** | |
5555
| Python | 3.12+ declared; dev venv is 3.14 | |
5656

57-
**Pushing is safe and needs no force.** `origin/main` (`feef03d`) *is* an
58-
ancestor of HEAD, so a plain `git push` fast-forwards. This is worth stating
59-
because the history *was* rewritten (see below) — but only across commits the
60-
remote had never seen, so nothing on the remote is being overwritten. Verify
61-
before pushing: `git merge-base --is-ancestor origin/main HEAD && echo safe`.
57+
**The source is public now.** For most of this project's life `origin/main` held
58+
only `LICENSE`, `README.md` and `.gitignore`, so the documented `git clone && uv
59+
sync` failed and every other verified claim sat in a tree nobody could fetch.
60+
That was the ship-blocker; it is closed, and a fresh clone was checked to contain
61+
`pyproject.toml` and the package.
6262

6363
**Environment:** `.env` holds an OpenRouter key (gitignored, never committed).
6464
The user has a Claude Max 20x subscription and **no Anthropic API key** — which
@@ -132,24 +132,24 @@ Source lines excluding tests (`find grapharc/<pkg> -name '*.py' | xargs cat | wc
132132
```
133133
grapharc/
134134
planner/ 2696 proposals, admission, materialisation, the governed loop
135-
harness/ 2165 tool registry, permissions, sandbox, container executor, AgentNode
135+
harness/ 2189 tool registry, permissions, sandbox, container executor, AgentNode
136136
memory/ 2165 claims with provenance, SQLite, traversal, contradiction detection
137137
session/ 2084 long-lived, cross-process resume, interrupt, human approval
138-
runtime/ 1921 graph kernel: typed state, declared writes, budgets, async, traces
139-
observe/ 1708 JSONL traces, replay, metrics, OTel, cost attribution
140-
cli/ 1549 nine commands (run agent serve models replay diff trace metrics viz), --json on each
138+
runtime/ 1960 graph kernel: typed state, declared writes, budgets, async, traces
139+
observe/ 1801 JSONL traces, replay, metrics, OTel, cost attribution
140+
cli/ 1849 ten commands (run plan agent serve models replay diff trace metrics viz), --json on each
141141
server/ 1320 FastAPI + SSE
142-
examples/ 1244 stages 0-6, capstone, agent_fixit
143-
gateway/ 1215 model plane: Claude CLI + OpenRouter, retries, cost ceilings
142+
examples/ 1445 stages 0-6, capstone, agent_fixit, plan_incident
143+
gateway/ 1223 model plane: Claude CLI + OpenRouter, retries, cost ceilings
144144
tools/ 1054 seven core tools with workspace confinement
145-
policy/ 867 TOML rules, approval routing, decision audit
145+
policy/ 908 TOML rules, approval routing, decision audit
146146
```
147147

148148
`planner/` is now the **largest** subsystem. One handoff ago it was 1,409 lines
149149
and ranked sixth *smallest* of twelve — not the thinnest, but the one whose
150150
central claim was unbuilt. That inversion is the story of the last session.
151151

152-
38 test files. `tests/test_planner_loop.py` (62 tests) is the one to read first
152+
38 test files. `tests/test_planner_loop.py` (63 tests) is the one to read first
153153
if you are touching the gate. The seven core tools are `read_file`,
154154
`write_file`, `edit_file`, `list_dir`, `glob`, `grep`, `run_command`
155155
(`grapharc.tools.CORE_TOOL_NAMES`).
@@ -305,9 +305,9 @@ Four of the five gaps that version named are now closed. What is left:
305305
seam, and the highest-value thing left** (ROADMAP §12.3).
306306
2. **Admission authorises a kind, not its arguments** — a boundary, not a seam,
307307
and the one most likely to be over-read. See *Known limits*.
308-
3. **The source is not on the public remote.** 15 commits unpushed; the
309-
documented install fails at `uv sync`. `origin/main` is an ancestor of HEAD,
310-
so a plain `git push` fast-forwards.
308+
3. **Not on PyPI.** The wheel builds, installs and runs;
309+
`.github/workflows/release.yml` fails closed until a human does the
310+
browser-side Trusted Publishing setup. See *Suggested next steps*.
311311

312312
Closed since, each with a shipped caller and tests:
313313

@@ -417,14 +417,13 @@ here.
417417

418418
## Suggested next steps
419419

420-
1. **Give the loop a surface.** A `grapharc plan` command or an example graph
421-
that a reader can run and watch. This converts the project's single most
422-
defensible claim from a test fixture into a demo. Nothing else comes close in
423-
value. (ROADMAP §12.1)
424-
2. **Decide the version and push.** 14 commits are unpushed, and they are the
425-
whole project — there is no second copy anywhere. I would argue for
426-
`0.1.0`, not `1.0.0` — a 1.0 implies API stability and several subsystems are
427-
days old.
420+
1. **Put the HTTP API on the real session layer** (ROADMAP §12.3). The last
421+
seam: `grapharc/server` has its own `InProcessRuntime` whose sessions die
422+
with the process and whose approvals are recorded without being delivered,
423+
while the durable `grapharc/session` sits next to it unused.
424+
`create_app(runtime=…)` already takes any `SessionRuntime`.
425+
2. **Decide the version.** `0.1.0a0` today. I would argue for `0.1.0`, not
426+
`1.0.0` — a 1.0 implies API stability and several subsystems are days old.
428427
3. **Publish to PyPI.** `.github/workflows/release.yml` is tag-driven
429428
(`v*`) and uses Trusted Publishing, so **no token exists anywhere**. Before a
430429
tag can publish, a human must do two things in a browser:

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**A governed agent runtime built on [LangGraph](https://github.com/langchain-ai/langgraph).** A planner *proposes* a subgraph, a deterministic checker *admits* it, and only then does anything execute — so every transition was permitted, every loop was bounded, and afterwards you can prove what happened and why it stopped. Underneath that sits the discipline layer it grew out of: typed state contracts, per-node write permissions, enforced budgets, and JSONL traces that double as replay points.
44

5-
Alpha (`0.1.0a0`). **Not installable yet** — see [Install](#install), which is honest about why.
5+
Alpha (`0.1.0a0`). Installable from source; not on PyPI yet — see [Install](#install).
66

77
> *Graph engineering*: when one agent loop stops being enough, coordination becomes the engineering. Nodes do work (agent loops, model calls, deterministic functions, humans approving things), edges decide what runs next, and a typed shared state flows between them. GraphARC implements the discipline that makes such graphs production-grade rather than demos — the ideas emerging from the July 2026 loops-vs-graphs debate (Steinberger, Ng, et al.), the "Two Graphs, Two Jobs" split, and twenty years of pre-AI graph systems where every edge means something and every path can be explained.
88
@@ -58,9 +58,7 @@ Three of those need their edges stated, because the gap is where people get hurt
5858

5959
## Install
6060

61-
**This does not work yet, and pretending otherwise is the fastest way to lose a reader.** The public remote — `github.com/CodeGraphContext/GraphARC` — is at commit `feef03d` and contains `LICENSE`, `README.md` and `.gitignore`. There is no `pyproject.toml` and no `grapharc/` package there, so a fresh clone followed by `uv sync` fails with *"No pyproject.toml found in current directory or any parent directory."* Everything else on this page was verified by running it against a local tree that has not been pushed. That is [ROADMAP.md](ROADMAP.md) §11.7, and it is the top of the fix list.
62-
63-
Once the source is on the remote, this is the path — it is the one CI uses, so it is exercised, just not from a clone:
61+
This works now. It did not for most of the project's life — the public remote held only `LICENSE`, `README.md` and `.gitignore`, so a clone had no `pyproject.toml` to sync and the instruction below was fiction. The source is pushed; a fresh clone was verified to contain `pyproject.toml` and the `grapharc/` package.
6462

6563
```bash
6664
git clone https://github.com/CodeGraphContext/GraphARC
@@ -69,7 +67,7 @@ uv sync --group dev # Python >= 3.12
6967
uv sync --all-extras --group dev # everything: openrouter, server, otel, mcp, api
7068
```
7169

72-
Not on PyPI either. The wheel does build: `uv build` produces one that installs into a clean virtualenv, imports 86 of the package's 93 modules bare (`gateway.openrouter` and the whole `server` package need their extras; `[all]` imports all 93), and runs `grapharc run stage0`.
70+
Not on PyPI yet. The wheel does build: `uv build` produces one that installs into a clean virtualenv, imports every one of the package's 94 submodules with `[all]` (`gateway.openrouter` and the whole `server` package need their extras, so a bare install imports fewer), and runs `grapharc run stage0`.
7371

7472
## Quickstart
7573

@@ -365,8 +363,8 @@ Re-derived on 2026-07-28 by running each item, not by reading the commit log.
365363

366364
**Distribution**
367365

368-
- **You cannot install this.** The source is not on the public remote — see [Install](#install). Nothing else on this page matters until that is fixed.
369-
- **Not on PyPI.** The wheel builds and works; nobody can fetch it.
366+
- **Not on PyPI.** The wheel builds, installs and runs; `.github/workflows/release.yml` is tag-driven with Trusted Publishing and fails closed until a human does the browser-side setup (a GitHub environment named `pypi`, and a PyPI trusted publisher naming this repo and workflow).
367+
- *Fixed:* the source **is** on the public remote now, so the documented `git clone && uv sync` path works. It was the ship-blocker for most of this project's life.
370368

371369
**Built and unreachable** — this used to be the honest headline, four subsystems deep. One seam is left.
372370

@@ -384,7 +382,7 @@ Re-derived on 2026-07-28 by running each item, not by reading the commit log.
384382
- **The Claude CLI backend is completion-only.** Tool calling and structured output need OpenRouter.
385383
- **A session turn is synchronous**, and a runner claim is a claim rather than a lease — nothing reclaims a session whose runner died holding it.
386384

387-
**Verified this pass:** `pytest` → 1,328 passed, 10 deselected (the live ones); `ruff check .` clean; all eight `grapharc run` stages green; the wheel builds and imports all 93 modules in a clean virtualenv with `[all]`. The test count is a snapshot, not a property of the project — `pytest` re-derives it in one command, which is the only reason it is quoted.
385+
**Verified this pass:** `pytest` → 1,381 passed, 10 deselected (the live ones); `ruff check .` clean; all eight `grapharc run` stages green and `grapharc plan` green; the wheel builds and imports all 94 submodules in a clean virtualenv with `[all]`. The test count is a snapshot, not a property of the project — `pytest` re-derives it in one command, which is the only reason it is quoted.
388386

389387
[ROADMAP.md](ROADMAP.md) tracks what is built and what is not, item by item. [ASSESSMENT.md](ASSESSMENT.md) is an outside review that argued much of this repo is a thin wrapper on LangGraph — it describes an earlier state of the tree and is kept unedited on purpose, because the parts it got right are worth more than the parts it has outlived.
390388

ROADMAP.md

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ described in [VISION.md](VISION.md). Status is measured, not aspirational.
66
**Legend:** `[x]` done · `[~]` partial · `[ ]` not started · **B** blocks other
77
work · **!** known-false claim shipping today
88

9-
Overall: **~69% of the list below** (71 of 103 enumerated items). Re-derived on 2026-07-28 by executing every
9+
Overall: **~70% of the list below** (72 of 103 enumerated items). Re-derived on 2026-07-28 by executing every
1010
claim against the tree rather than reading the commit log — the percentage is
1111
the fraction of *enumerated items* verified done, section by section, which is
1212
this project's own definition of scope and not the industry's.
1313

14-
At that point: `pytest`**1,328 passed, 10 deselected** (the live ones);
15-
`ruff check .` clean; the wheel builds and imports all 93 modules in a clean
14+
At that point: `pytest`**1,381 passed, 10 deselected** (the live ones);
15+
`ruff check .` clean; the wheel builds and imports all 94 submodules in a clean
1616
virtualenv. Treat the test count as a snapshot rather than a fact about the
1717
project — `pytest` re-derives it in one command, which is the only reason it is
1818
quoted at all.
@@ -35,29 +35,25 @@ to a reader, which is what §12 exists to count.
3535

3636
In order.
3737

38-
1. **Push the code to the public remote** (§11.7) — **!**. Now the only
39-
ship-blocker, and the first thing a reader hits. The install instruction in
40-
the README does not work: `github.com/CodeGraphContext/GraphARC` `main` is at
41-
`feef03d`, holding `LICENSE`, `README.md` and `.gitignore` and no source.
42-
`git clone && uv sync --group dev` fails with *"No pyproject.toml found"*.
43-
Everything else on this page is verified against a local tree the world
44-
cannot fetch. 15 commits unpushed; `origin/main` is an ancestor of `HEAD`, so
45-
a plain `git push` fast-forwards and needs no force.
46-
2. **Put the HTTP API on the real session layer** (§12.3) — the last seam.
38+
1. **Put the HTTP API on the real session layer** (§12.3) — the last seam.
4739
`session/` is durable and resumes across processes; `server/` uses its own
4840
`InProcessRuntime` that does neither, and records approvals without
4941
delivering them. Two session layers, one seam.
50-
3. **Let admission constrain arguments** (§5.6) — **!**. The gap most likely to
42+
2. **Let admission constrain arguments** (§5.6) — **!**. The gap most likely to
5143
be over-read: a rule reaches a node's *kind* and never its `args`, so
5244
`args={"path": "/etc/passwd"}` is admitted on the strength of the kind.
5345
`Materializer` drops args by default, which makes the default safe and the
5446
opt-in sharp.
55-
4. **Route the tool plane through the document** (§7.5 remainder) — the edge
47+
3. **Route the tool plane through the document** (§7.5 remainder) — the edge
5648
side now compiles to the admission gate, but nothing calls
5749
`permission_policy()`, so `grapharc agent` is still governed by Python
5850
objects rather than by the TOML file.
59-
5. **Publish to PyPI** (§11.1) — the workflow is tag-driven with Trusted
60-
Publishing and fails closed without the browser-side setup; do §11.7 first.
51+
4. **Publish to PyPI** (§11.1) — the workflow is tag-driven with Trusted
52+
Publishing and fails closed until a human creates a GitHub environment named
53+
`pypi` and a PyPI trusted publisher naming this repo and `release.yml`. Prove
54+
it first with `workflow_dispatch` + `dry_run: true`.
55+
5. **Decide the version.** `0.1.0a0` today; `0.1.0` is the honest next step —
56+
a `1.0` implies API stability that several days-old subsystems do not have.
6157

6258
---
6359

@@ -392,7 +388,7 @@ Everything here works and nothing calls it.
392388
404 on an unknown session or graph and 422 on input that fails the
393389
graph's state schema. Behind the `server` extra; importing the rest of
394390
GraphARC does not import FastAPI.
395-
- [x] **9.2 — Real CLI: nine commands**, `run` / `agent` / `serve` / `models` /
391+
- [x] **9.2 — Real CLI: ten commands**, `run` / `plan` / `agent` / `serve` / `models` /
396392
`replay` / `diff` / `trace` / `metrics` / `viz`, every one of them with
397393
`--json`. In JSON mode the failure is the document rather than a line on
398394
stderr, and exit codes are part of the interface: `0` did the job, `1` ran
@@ -438,8 +434,8 @@ Everything here works and nothing calls it.
438434

439435
## 11. Product & distribution — `[~] ~35%`
440436

441-
- [x] Builds a clean wheel; **1,328 tests**; CI; ruff clean. Verified in a fresh
442-
virtualenv: a bare wheel install imports 86 of 93 modules and runs
437+
- [x] Builds a clean wheel; **1,381 tests**; CI; ruff clean. Verified in a fresh
438+
virtualenv: a bare wheel install imports most of the 94 submodules and runs
443439
`grapharc run stage0``gateway.openrouter` and the whole `server`
444440
package need their extras — and installing `[all]` imports all 93.
445441
- [x] **11.6 — Classifiers, `[project.urls]`, contribution guide.** Every URL
@@ -449,11 +445,13 @@ Everything here works and nothing calls it.
449445
deselected by default. CI wiring still pending (it needs a key in secrets).
450446
- [~] **11.2 — Docs site.** A cookbook is landing under `docs/cookbook/`; no
451447
published site.
452-
- [ ] **! 11.7 — Push the source to the public remote.** `origin/main` is at
453-
`feef03d` and holds `LICENSE`, `README.md` and `.gitignore` — no
454-
`pyproject.toml` and no `grapharc/`. The documented install path therefore
455-
fails at `uv sync`. This is the single most consequential false claim in
456-
the tree, because it is the first one a reader tests.
448+
- [x] **11.7 — The source is on the public remote.** `git clone
449+
https://github.com/CodeGraphContext/GraphARC && uv sync --group dev` works;
450+
verified by cloning into a scratch directory and finding `pyproject.toml`
451+
and the `grapharc/` package. This was the single most consequential false
452+
claim in the tree for most of the project's life, because it was the first
453+
one a reader hit.
454+
457455
- [ ] **11.1 — Publish to PyPI.**
458456
- [ ] **11.4 — Benchmarks, including published losses.**
459457
- [ ] **11.5 — External security review** (the audit-hook sandbox is defense in

VISION.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,16 @@ Three predictions that did **not** come true, which is the part worth keeping:
174174
- **Nothing predicted the seams.** The failure mode this document warned about
175175
was writing the essay before the code. The one it actually hit is subtler:
176176
building four subsystems that each work and wiring none of them to each
177-
other. `planner/` and `policy/` are imported by no other module in the
178-
package. That is not a design flaw and it is not vapour — it is a fifth of
179-
the remaining work, and it was invisible from here.
177+
other. For a while `planner/` and `policy/` were imported by no other module
178+
in the package — the governed loop had no command driving it and the policy
179+
document had no path to the gate it was written for. That was never a design
180+
flaw and never vapour; it was a fifth of the remaining work, and it was
181+
invisible from here. Four of the five seams are now closed (`grapharc plan`,
182+
`PolicyEngine.edge_policy()`, `grapharc run --memory`, `cost_usd` on trace
183+
events) and one is left: the HTTP API still runs its own in-process session
184+
layer beside the durable one. The lesson to carry is not the fix but the
185+
blind spot — "works" and "reachable" are different properties, and only the
186+
second one a reader can see.
180187

181188
---
182189

0 commit comments

Comments
 (0)