Run this as a background subagent on the smallest available model. The subagent reads files and returns one JSON object. It does not edit files or dispatch verbs.
Inputs:
observations.jsonfiles:<repo>/.gm/dream-rsi/<session>/observations.json, each a JSON array of up to the newest 256 records withdispatch_id,verb,fingerprint,exit_code,gate_drift(bool),prd_open_count,mutable_open_count,quality(0..1),ts,reply_sha256, and optionallean_node. Orchestration verbs anddream-*dispatches are not recorded.- The gm graph:
skills/dream-rsi/gm-graph.json(nodes,edges; nodekindisprinciple,gate,tensionorterminal-- there is no phase node; edgekindisforwardorbackreference). A node is a book when itsbookis non-empty;book_indexnames each anchor book and the node that carries it. - Phase history:
.gm/turn-state.jsonphase_history. - Walk evidence:
.gm/lean-walk/<NODE>.json, one subagent record per node (node,applied,witness).
Part A: verb strategy
- Read every observation file. Count records. If there are fewer than
INSUFFICIENT_RECORD_THRESHOLDacross all sessions, return anInsufficientfor Part A. - Per verb, compute count, failure rate (
exit_code != 0), gate-drift rate, and meanquality. - Treat
qualitywith caution. Until the scoring fix in rs-plugkit lands,qualitymostly reflects the open PRD/mutable backlog rather than the dispatch outcome. Rank by failure rate weighted by count, not byquality. - Some non-zero exits are valid answers, not failures. A
grepexit 1 with no matches is a no-match result. The agent shall not propose a change for a verb until its failure exits are shown to be real errors. - For up to
MAX_PART_A_PROPOSALScandidates, write one proposal with the verb, the change, the counts and rates as evidence, and a measurable target on the same log.
Part B: gm-graph traversal
The goal is to walk every principle-kind gm-graph node and every edge, through real work. Each principle node is one hop run by a subagent that advocates that node's discipline at full strength (SKILL.md Section 1d). The hop scope is principle nodes only, the same scope as the gm walk loop (skills/gm/SKILL.md Section 1d).
- Load the graph. Traversable nodes are those whose
kindisprinciple. Edges are alledgesentries. - Load walk evidence. A node is walked when its
.gm/lean-walk/<NODE>.jsonhasapplied:trueand awitness. A missing file means no walk yet.phase_history(the node keys the runtime recorded) confirms the session reached that node. - Build the set of every
dispatch_idacross all observation files. - Verify each walk. A walk counts only if every
dispatch_idquoted in itswitnessappears in that set. Report any failure inrejected_walkswith the missing ids. The agent shall never count a rejected walk. - Coverage:
nodes_verifiedovertraversable_nodes.backreferences_verifiedover the number of backreference edges, counted only when thefromnode's evidence file hasapplied:trueand itswitnessnames the edge's condition.- Forward-edge coverage approximates a forward edge as covered when both endpoints have verified walks. Say that this is an approximation.
- Proposals: up to
MAX_PART_B_PROPOSALSunwalked nodes, in this priority order: nodes with no verified walk, then backreference edges never fired. For each, give the node id, the condition to walk it on the next real task, and the evidence that would count as a walk.
Part C: the discipline tree
The graph is one tree, not nine. Every book is its own node. book_index names
each anchor book and the node that carries it: 43 got a node of their own and 12
are the same book as a node the lean tree already carried, so they join it there
rather than duplicating it. Their provenance is the prose file that used to own
them, which is where they came from and nothing more: it groups nothing and gates nothing.
Traversal is nonlinear by construction. Every node can be reached, left and
re-entered, and no book is confined to the concern it was authored under: every book
has at least one edge to a book of another provenance, so a walk begun anywhere
can reach anywhere. There is no phase node -- nothing in the graph is a door
into a set of nodes.
The terminal is G_FIXPOINT ("sweep changed nothing"). G_SURFACE is the
halt, not the goal: it means the walk stopped and handed the ambiguity to a
human. Movement toward G_FIXPOINT is measured by convergence.measure,
unwalked_nodes + unfired_backreferences, and that measure is non-increasing
(MONOTONE): a step counts as movement only when it walks a node that had no
walk or fires a backreference that had never fired, so re-walking walked ground
is not progress. The terminal is reached when a full sweep changes nothing:
G_SWEEP found no reopened gate, no counterexample and no growth.
scripts/check-discipline-tree.mjs is the gate on all of the above. It counts
isolated nodes, unreachable nodes, dead-end nodes and provenance-partitioned books and
fails when any of those counts is non-zero. Run it after any edit to the graph;
CI runs it on every push and pull request to main.
Output
Constants:
INSUFFICIENT_RECORD_THRESHOLD = 20MAX_PART_A_PROPOSALS = 3MAX_PART_B_PROPOSALS = 5
Return exactly one DreamRsiResult:
DreamRsiResult = { status: "proposed", part_a: PartA | Insufficient, part_b: PartB }
Insufficient = { status: "insufficient", records: number } // records < INSUFFICIENT_RECORD_THRESHOLD
PartA = { records: number, per_verb: VerbStat[], proposals: VerbProposal[] } // proposals <= MAX_PART_A_PROPOSALS
VerbStat = { verb: string, count: number, failure_rate: number, gate_drift_rate: number }
VerbProposal = { verb: string, change: string, evidence: string, target: string }
PartB = { traversable_nodes: number, nodes_verified: number, backreference_edges: number,
backreferences_verified: number, forward_edge_coverage_approx: number,
rejected_walks: RejectedWalk[], proposals: NodeProposal[] } // proposals <= MAX_PART_B_PROPOSALS
RejectedWalk = { node: string, missing_dispatch_ids: string[] }
NodeProposal = { node: string, walk_when: string, evidence_that_counts: string }
A proposal is evidence-bound planning input. It is deployed only through the normal gate, authorization and evidence gates, never by this skill.