Releases: CodeGraphContext/GraphARC
Release list
0.1.7
Published to PyPI: https://pypi.org/project/grapharc/0.1.7/
pip install --upgrade grapharc
Two defects closed, both found by re-verifying a stale bug backlog against main rather than from a report.
admission accepted a sentinel pointing the wrong way (#108)
START is the graph's entry and END its exit, but the endpoint check tested only whether an endpoint was a sentinel, never which side of the edge it sat on. END -> x and x -> START were admitted and then died in Materializer.
The run doesn't proceed either way — what was wrong is where the failure landed. GovernedLoop charges a MaterializationError to max_consecutive_execution_failures (2) rather than max_consecutive_rejections (3), so a planner got fewer retries for a mistake admission is supposed to catch than for one it does catch, and two in a row ended the run as EXECUTION_FAILED — a stop reason claiming the graph ran when nothing had. It also reached the planner as prose scraped off an exception rather than a code and a remedy, with nothing on the admission event's failed-check list, because admission hadn't failed.
a dead sandbox child escaped as a bare EOFError (#111)
poll() is true when the pipe is readable, and a closed pipe is readable — so a child killed rather than raising (os._exit, a segfault, an OOM-kill) fell through the timeout guard into recv(). AgentNode catches it under its blanket except Exception and renders f"TOOL_ERROR: {exc}", and str(EOFError('')) is '' — so the model was handed TOOL_ERROR: with nothing after the colon, and the trace recorded a failure it couldn't explain either.
Now a RuntimeError naming the tool and the exit code, with a negative one rendered as the signal that killed it. Deliberately still not a SandboxViolation: a child dying is not evidence it tried to escape confinement.
Full detail in CHANGELOG.md.
0.1.6
Published to PyPI: https://pypi.org/project/grapharc/0.1.6/
pip install --upgrade grapharc
What ships
grapharc[mcp]was broken on arrival (#101).mcp>=1.2resolved to 2.0, wheremcp.server.fastmcpno longer exists, so a fresh install could not import the server.uv.lockpinned 1.28 and hid it from every local test; only a resolver starting frompyproject.toml— a real user — ever saw it. Nowmcp>=1.2,<2, withgrapharc/mcp/__init__.pyresolving the SDK-backed names lazily so the subpackage imports without the extra.grapharc go <run-dir>silently re-executed an already-executed plan (#100). Baregoalways skipped executed plans; the named-directory form did not, so re-issuing it ran the whole graph again at exit 0 and overwrote the stamp. Two fixes: the record accumulatesexecuted_run_idsinstead of clobbering a scalar, and — the one that matters — a plan carrying anexecuted_run_idis now refused with exit 2 before anything runs, unless--againsays so. An approval binds to a fingerprint that does not change between runs, so this was one human yes authorising N executions of amutatingplan.- The deep dive's Verified this pass figures rotted, twice (#42). They are now what one command re-derives, and
tests/test_deep_dive.pyfails the line rather than letting it drift — including a guard that an unowned figure appearing on the line is itself a failure. - Five
max_secondstiming tests failed only on a loaded machine (#40). The deadline machinery was never what failed; the assertions were. Every wall-clock bound now sits between the deadline and the uninterrupted body, verified 20/20 under three parallel suites at load average 33-35. - Novita joins the model gateway (#102) — thanks @jax-novita. A fifth OpenAI-wire backend behind a
novitaextra, probed bygrapharc models --checklike the others.
Behaviour change
A second grapharc go <run-dir> on an executed plan now exits 2 instead of 0. That is the fix rather than a side effect; --again restores the old behaviour explicitly.
Full detail for every entry is in CHANGELOG.md.