Skip to content

Ship a planning registry that reads, and let Slack name it - #28

Merged
Shashankss1205 merged 1 commit into
mainfrom
feat/plan-docs-registry
Jul 30, 2026
Merged

Ship a planning registry that reads, and let Slack name it#28
Shashankss1205 merged 1 commit into
mainfrom
feat/plan-docs-registry

Conversation

@Shashankss1205

Copy link
Copy Markdown
Collaborator

The gap this closes, demonstrated live today: plan "summarise the docs in this workspace" returned an honest negative (the incident registry has no kind that reads), while a vaguer goal produced a hollow goal_met from three stub nodes. The planner was never the problem — the registry vocabulary was.

grapharc/examples/plan_docs.py — three read-only kinds (survey, read, summarise) whose bodies really read documentation under Path.cwd():

  • deterministic operator code — the model plans, node bodies never call a model, so the scripted path produces the same real content the paid path does
  • confined: suffix-filtered (.md/.txt/.rst), capped (20 files, 40k chars), skip-listed dirs, and symlinks resolved and checked against the root before a byte is read
  • no argument surface: proposals name kinds, bodies take none — the issue-planner: the admission gate authorises a kind, not its arguments #10 gap doesn't open here
  • behaviour keys on NodeBuild.kind, not the planner-invented instance name; the loop test proposes docs_survey-of-kind-survey specifically to catch a name-keyed factory (it caught mine)

grapharc/cli/plan.py — the scripted planner's replies now come off the registry module when it exports scripted_planner_replies (incident replies stay the fallback). Without this, the free path against the docs registry was five rounds of unregistered_node and a planning_failed — verified before and after.

Slack gateplan --registry accepts exactly the two shipped registry modules via a new choice_flags mechanism; every other value (and the flag on run) stays refused, since its general form imports arbitrary code.

From Slack, free, no key needed:

@grapharc plan "summarise the docs in this workspace" --registry grapharc.examples.plan_docs:build_registry --trace docs.jsonl --run-id docs-1

Six new tests (registry confinement incl. symlink escape, kind-keyed factory via the governed loop, CLI scripted-path regression, gate allowlist). Full suite green, ruff clean.

🤖 Generated with Claude Code

plan_incident proves the governance with stub bodies, so "summarise the
docs in this workspace" got either an honest negative or a hollow
success depending on how vague the goal was. plan_docs closes that gap
for one bounded job: survey/read/summarise kinds whose bodies really
read documentation — read-only, confined to the working directory,
symlinks resolved and checked before a byte is read. The bodies are
deterministic operator code; the model plans, it does not read.

Behaviour keys on NodeBuild.kind, not the instance name the planner
invented — the loop test proposes docs_survey-of-kind-survey to pin
that. The scripted planner replies now come off the registry module
when it ships them (incident replies against the docs catalog were
five rounds of unregistered_node), so the free no-model path exercises
the same registry the paid one does.

From Slack, plan --registry accepts exactly the two registries the
package ships and nothing else: the flag's general form imports
arbitrary code, which stays refused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Shashankss1205
Shashankss1205 merged commit 53f7de0 into main Jul 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant