You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Click a node and it answers: the live graph grows an inspector (0.1.4)
Every node in the live view is now clickable: a click pins a card with the
node's status, executions, tokens (live "so far" spend while running),
recorded cost, duration, share of the run's tokens, each execution's window
on the timeline, the full error text, and every edge in and out with its
kind. The pin survives snapshot patches and clears when a replan drops the
node; Escape, the close button or the graph background dismisses it. The
exposure boundary did not move: state_delta contents still never reach a
live byte — the panel renders only fields the viewmodel already shipped.
Also ships the incident demo video (docs/media/grapharc-incident-demo.mp4
and .gif — one question in, a qwen3:8b-planned nine-node graph out, live in
the browser) and a short clip of the inspector.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ and "used to be true" — the two things a reader most needs kept apart.
7
7
8
8
Entries are newest-last within a release, matching the order they were written.
9
9
10
-
## Unreleased
10
+
## 0.1.4
11
11
12
12
- a run **stopped for overspending reported spending nothing**. Tokens were attributed from `end` events, and a node the budget interrupts emits `error` instead — so `grapharc metrics` answered `tokens: 0` for a run whose own enforcement message named the figure that stopped it (`max_tokens reached (51/5)`). The audit trail lost precisely the number the stop was about, and per-node attribution dropped the most expensive node in the run. Every `error` event is now stamped with what its node spent, exactly as `end` is, and both `summarize` and the cost report count it; sub-events inside a node remain a breakdown of its total rather than an addition, so the disjointness that kept `ends + orphans` from double-counting is unchanged, and `RunCost.tokens == RunMetrics.tokens` still holds.
13
13
- the `.env` credential loader **walked up parent directories to `/`**, while the config layer next door refuses exactly that on principle — so the file that *spends money* was discovered more eagerly than the one that *constrains* a run. A run started in a scratch subdirectory picked up an `OPENROUTER_API_KEY` from any ancestor: a `.env` in `$HOME` billed every user's experiment on a shared box to that key, a demo checked out under a client project quietly used the client's key, and since `redact()` is the only thing that ever prints a key, nothing in normal operation said *which file paid*. The rationale `cli/config.py` wrote down for `grapharc.toml` — "a run must never be silently governed by a file in a directory you didn't know about" — applies with more force to the file that pays than to the file that restrains, so `find_env_file` now reads the start directory (default: the working directory) and no ancestor of it. **This is a behaviour change:** anyone relying on a parent-directory `.env` must move it into the directory they run from, `export` the variable, or pass `env_file=` naming the file. Neither escape hatch moved — a real environment variable still beats any file, and an explicit `env_file=` still reads a file anywhere on disk — and no "search boundary" was added in place of the walk, because stopping at a git root is still an upward search.
@@ -23,6 +23,7 @@ Entries are newest-last within a release, matching the order they were written.
23
23
-**the CLI never joined the runs it starts to the live view that draws them.**`plan`'s default trace went to a tempdir no server serves, and no command printed a URL. Defaults compose now: traces land under `.grapharc/runs/<stamp>/`, `serve --live-root` writes a discovery marker (`.grapharc/live-server.json` — URL, root, pid, never the token; removed on clean shutdown), and `plan`/`go` end with a `watch :` line — the exact page URL when a marker names a server that answers one loopback connect, the command that would start one otherwise. The goal now rides the loop's topology and approval events (operator-supplied text, deliberately shown — the second state field after `termination_reason`), so the page can say what a graph is *for*; a parked run shows its proposed nodes in violet with a copy-ready `grapharc approve <dir>` banner.
24
24
-**`plan` planned nothing and executed everything** — the name lied. The verbs are split now: `grapharc plan` proposes, the gate admits, and the run STOPS with the admitted plan saved to `plan.json` next to its trace (exit 0, `stopped: planned`); `grapharc go` executes the newest saved plan (`go <run-dir>` for a specific one), replaying the stored proposal through the full governed loop so admission judges it again on the way in — a hand-edited plan.json is a new proposal, not a pre-approved one; `plan --go` (and `go "a goal"`) does both in one run. Looking at a plan and then typing `go`*is* the approval; `--approve` remains for parking one-shot runs mid-flight. Registry resolution is now one visible chain shared by both commands: flag/config first, else a `registry.py` in the directory (yours wins), else the built-in general-purpose kinds — with `--default` forcing the built-ins past everything.
25
25
-**new commands for the first hour**: bare `grapharc` orients instead of erroring (exit 0); `grapharc start` is the guided tour; `grapharc init` scaffolds a commented `registry.py` (whose first free run reproduces refuse-then-admit), a `grapharc.toml`, and `.grapharc/runs/` — refusing to overwrite either authored file, with no `--force`; `grapharc go` is plan with doing-defaults (the stdlib tool-using registry, `--model` required); `--registry path/to/file.py:attr` loads a registry file directly; `--workspace` confines the stdlib kinds' tools to a directory (refused when a registry cannot take one — never silently un-confined); `--model-arg KEY=VALUE` reaches the backend constructor. The stdlib planner is now *told* the deterministic completion rule (end with `summarize`) instead of discovering it by burning rounds.
26
+
- the live graph's nodes are **clickable now**. A click pins an inspector card to the node with everything the snapshot already carries about it: status, executions, tokens (a running node shows its live "so far" spend), recorded cost, duration, its share of the whole run's tokens, each execution's window on the run's timeline, the full error text, and every edge in and out with its kind. The pin survives snapshot patches — a running node's spend ticks in place — and clears itself when a replan produces a topology without that node; Escape, the × or a click on the graph background closes it. The exposure boundary did not move: `state_delta` contents still never reach a live byte — the panel renders only fields the viewmodel already shipped, and the test pinning that sentence is unchanged.
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ A planner *proposes* a subgraph, a deterministic checker *admits* it — or refu
21
21
-**The worst-case cost is known before a graph runs, and the exact per-node bill after — even when it fails.** Admission prices the worst case against what is *left* of the budget; at runtime each node's spend lands on its own trace event, error and cancellation included. `recorded_cost_usd` is never an estimate.
22
22
-**One append-only JSONL trace file is the whole truth.**`replay`, `diff`, `metrics`, `viz`, cost attribution, OTel export and the live browser view all read the same file — the dashboard cannot disagree with the audit trail, because they are the same record.
23
23
24
-
**Website:**[codegraphcontext.github.io/GraphARC](https://codegraphcontext.github.io/GraphARC/) · **Status:** early days (`0.1.3`) — the API is not stable yet. Known limits are listed in [Status and limits](#status-and-limits); closed ones are in [CHANGELOG.md](CHANGELOG.md).
24
+
**Website:**[codegraphcontext.github.io/GraphARC](https://codegraphcontext.github.io/GraphARC/) · **Status:** early days (`0.1.4`) — the API is not stable yet. Known limits are listed in [Status and limits](#status-and-limits); closed ones are in [CHANGELOG.md](CHANGELOG.md).
25
25
26
26

0 commit comments