| PSP: | 000008 |
| Title: | SRBN Agent SDK, Coding Domain Package, and Mutable Work Graph |
| Author: | Vikrant Rathore (@vikrantrathore) |
| Status: | Final |
| Type: | Enhancement |
| Created: | 2026-06-20 |
| Discussion-To: | https://github.com/eonseed/perspt/discussions/150 |
| Extends: | 000005, 000007 |
Abstract
This PSP defines the next implementation phase for Perspt’s SRBN agent as an SDK-first platform. Perspt is designed to build a reusable SRBN agent SDK around residual-directed verification, read-only exploration, domain-provided verifier suites, a mutable parallel work graph, deterministic capability/admissibility, replay, and observability. The coding agent becomes the first domain package built on that SDK rather than the place where the control plane is hardcoded. The same SDK should support later research, website-builder, and task-specific agents without duplicating SRBN scheduling, residual, capability, ledger, or dashboard machinery.
Motivation
Perspt already implements major parts of PSP 000005 and PSP 000007: project-first execution, plugin-driven verification, typed artifact bundles, correction-attempt telemetry, budget checks, V_boot activation, plan validation, and graph rewrite primitives. That progress is necessary, but it is not yet sufficient for reliable long-running coding and task agents.
The reviewed SRBN material points to the missing layer:
Paper I states the single-agent stability contract: define a proxy state, measure verifier residuals, aggregate them into a Lyapunov energy, correct dominant residuals through an independent barrier, and commit only accepted states to immutable history.
Paper II turns that into a harness contract: every candidate is observed, only hard-pass or energy-descending candidates enter the accepted trajectory, and correction exhaustion must terminate with a residual certificate rather than a success claim.
Paper III lifts the harness to a platform: stochastic actors emit proposals, deterministic capabilities mediate effects, authority can only attenuate, risk budgets are recorded and calibrated, recovery classification is total, replay is deterministic, and only non-commuting durable commits require serialization.
The Rust
srbncrate expresses the executable kernel in minimal form:runandstabilizeloops, finite non-negative residual scores,BarrierResultevidence and correction fields, descent-gated stopping, attempt traces, and explicit terminal statuses.
The current Perspt implementation has the right vocabulary, but several gaps remain:
SRBNOrchestrator::run_orchestrationandrun_resumed_innerstill take a topological snapshot and walk it once. Graph rewrite methods can split nodes, insert interface nodes, or reset subgraphs, but the active scheduler may not revisit reset nodes or execute newly inserted nodes.apply_repair_actionoften marks a node asRetryor mutates graph topology, whileexecute_nodeimmediately returnsNodeOutcome::Escalated. The repair action does not become a durable scheduler command.Verification is still mostly stage-result based. It lacks a first-class residual taxonomy that can explain why a compiler, LSP, AST query, test, formatter, coreutils command, or logical validator failed and what correction direction it recommends.
Language plugins select verifier commands, but they do not yet own a complete verifier suite: parser/AST extraction, symbol inventory, dependency graph, import graph, build target selection, test attribution, tree-search repair candidates, and structured correction directions.
The plugin-first architecture is too narrow as the primary extension model. A language plugin is a good place for Rust, Python, or TypeScript-specific sensors, but it is the wrong place for domain-neutral SRBN machinery such as scheduling, replay, capabilities, residual scoring, dashboard projections, exploration budgets, and model routing. Those mechanisms should be SDK contracts used by coding, research, website-building, and task-specific packages.
Existing-codebase exploration is not first-class. The agent needs a cheap, read-only way to map unfamiliar repositories before planning or mutation without spending architect-tier tokens on every file and symbol question.
Agent phases are mostly serialized even when they are independent. Repository scans, symbol extraction, verifier runs, and unrelated node work should be parallelizable, while dependent work must wait on explicit edges, locks, state witnesses, or residual seals.
Command and file effects are policy-checked, but the platform model is not yet explicit. The agent can still route broad shell strings through
sh -cafter sanitization. That is not the same thing as capability-constrained proposals whose effects, scope, risk, and approval state are ledgered.The prompt compiler exists, but some prompt families still render through legacy static template strings. The compiler should become the single typed interface from residual evidence to correction prompts.
The ledger stores many useful records, including
srbn_step_recordsandcorrection_attempts, but it is not yet an event-sourced replay contract for every proposal, rejection, approval, effect, verifier observation, graph revision, and rollback.
The product requirement is reusable reliability. A coding agent needs repository exploration, fast search and read tools, precise edits, plan/build/review workflows, tests, language-server feedback, permission gates, resumability, and clear status. A research agent needs source gathering, citation validation, claim residuals, and evidence provenance. A website-builder agent needs asset, accessibility, build, responsive-layout, and deployment verifiers. These should not be three separate orchestration systems. Perspt should provide one SRBN SDK and multiple domain packages.
Proposed Changes
Functional Specification
Perspt implements an SDK-first SRBN agent platform composed of nine load-bearing systems:
a domain-neutral SRBN agent SDK,
a coding domain package built on that SDK,
an SRBN kernel adapter for state stabilization,
a read-only exploration and model-routing layer,
a mutable parallel work graph scheduler,
SDK verifier/sensor suites with coding language adapters,
a residual evidence and correction-direction model,
a capability-constrained admissibility kernel,
a replayable ledger and observability surface that exposes graph, residual, capability, worker, verifier, and replay state.
![digraph psp8_control_loop {
bgcolor="transparent";
splines=ortho;
node [shape=box, style="rounded,filled", fontname="Arial", fontsize=10, margin="0.18,0.10"];
edge [fontname="Arial", fontsize=9, color="#546E7A", fontcolor="#455A64"];
// Nodes
task [label="User task\nsession charter", fillcolor="#E3F2FD", color="#1E88E5"];
explore [label="Explorer\nread-only evidence", fillcolor="#E8F5E9", color="#43A047"];
profile [label="Project profile\ncontext witnesses", fillcolor="#F1F8E9", color="#689F38"];
workgraph [label="Mutable WorkGraph\nrevision N", fillcolor="#FFF3E0", color="#FB8C00"];
implement [label="Implementer\ncandidate patch", fillcolor="#E1F5FE", color="#039BE5"];
admissible [label="Admissibility kernel\ncapabilities + leases", fillcolor="#F3E5F5", color="#8E24AA"];
verify [label="Verifier suites\ncompiler + LSP + tests", fillcolor="#FCE4EC", color="#D81B60"];
residuals [label="Residual vector\nenergy + directions", fillcolor="#FFEBEE", color="#E53935"];
srbn [label="SRBN kernel\nhard pass or descent", fillcolor="#ECEFF1", color="#607D8B"];
accept [label="Accepted state\ncommit boundary", fillcolor="#DCEDC8", color="#558B2F"];
revise [label="Repair or graph revision\nnew node generation", fillcolor="#FFF8E1", color="#F9A825"];
cert [label="Residual certificate\nhonest stop", fillcolor="#FBE9E7", color="#D84315"];
ledger [label="Replay ledger\nMerkle history", fillcolor="#E0F2F1", color="#00897B"];
dashboard [label="Web dashboard\nlive observability", fillcolor="#EDE7F6", color="#5E35B1"];
// Setup ranking to keep layout symmetric and portrait
{ rank=same; verify; residuals; }
{ rank=same; accept; revise; cert; }
// Edges
task -> explore;
explore -> profile;
profile -> workgraph;
workgraph -> implement;
implement -> admissible;
admissible -> verify [label="allowed effect"];
admissible -> residuals [label="denied effect"];
verify -> residuals;
residuals -> srbn;
srbn -> accept [label="stable / descent"];
srbn -> revise [label="correct / replan"];
srbn -> cert [label="exhausted"];
revise -> workgraph [label="revision N+1", constraint=false];
accept -> ledger;
cert -> ledger;
workgraph -> ledger [label="revision event", constraint=false];
ledger -> dashboard;
}](_images/graphviz-b325762464af1919b675ecc22baf4c1afdd2e031.png)
SRBN Coding-Agent Control Loop
The systems below are normative for this PSP.
1. SDK-First Architecture
This proposal uses an SDK-first design. The SDK owns the domain-neutral control plane, while domain packages provide task-specific semantics.
The review conclusion is:
plugin-first is useful for language-specific sensors but too narrow for the overall architecture;
SDK-first is the better boundary because SRBN stabilization, mutable graph scheduling, residual evidence, capability confinement, replay, model routing, and dashboard projections are reusable across domains;
coding should become the first production domain package built with the SDK;
language plugins should become coding-domain adapters that implement SDK verifier and correction contracts;
research, website-builder, and task-specific packages should use the same SDK instead of forking the coding agent.
Perspt adds a public perspt-sdk crate. The SDK exposes stable
interfaces for:
SRBN state adapters and barrier results;
integration with the published
srbnandsrbn-serdecrates for stabilization loops, barrier outcomes, attempt traces, and trace serialization;work graph nodes, edges, revisions, leases, and scheduler effects;
agent roles, activities, and model routes;
domain exploration reports and context packages;
verifier/sensor suites and residual events;
correction-direction contracts;
effect proposals, capabilities, command IR, and admissibility decisions;
event-ledger records, replay observations, and dashboard projections;
benchmark harnesses and mechanism checks.
The SDK does not hardcode coding-specific concepts such as Cargo.toml,
pytest, TypeScript exports, AST import graphs, package-lock policies, or
source-edit bundles beyond generic artifact operations. Those belong to the
coding package.
Perspt adds a first-party coding domain package, named
perspt-coding unless implementation experience suggests a clearer crate
name. The coding package provides:
repository and language detection;
coding-specific project profiles;
language adapters for Rust, Python, and JavaScript/TypeScript;
compiler, LSP, AST, import graph, symbol graph, formatter, build, and test sensors;
source-edit artifact bundle helpers;
language-specific residual classes and correction-direction mappers;
dependency and manifest mutation policies;
coding benchmark fixtures and mechanism checks.
The SDK/domain split is visible in the CLI and may introduce breaking changes. The preferred entry point should make the selected domain explicit,
for example perspt agent --domain coding "<task>" or a dedicated
domain-oriented command. Legacy command aliases are out of scope for this PSP.
Domain selection is a routing decision; it does not bypass the SDK’s
admissibility, residual, scheduler, ledger, or dashboard contracts.
The extension stack is layered:
![digraph psp8_extension_stack {
bgcolor="transparent";
splines=ortho;
node [shape=box, style="rounded,filled", fontname="Arial", fontsize=10, margin="0.18,0.10"];
edge [fontname="Arial", fontsize=9, color="#546E7A", fontcolor="#455A64"];
// Nodes
ui [label="perspt-cli / perspt-tui / perspt-dashboard", fillcolor="#ECEFF1", color="#607D8B"];
runtime [label="generic perspt-agent runtime", fillcolor="#E3F2FD", color="#1E88E5"];
sdk [label="perspt-sdk", fillcolor="#FFF3E0", color="#FB8C00"];
coding [label="perspt-coding", fillcolor="#E1F5FE", color="#039BE5"];
research [label="perspt-research", fillcolor="#E8F5E9", color="#43A047"];
website [label="perspt-website", fillcolor="#EDE7F6", color="#5E35B1"];
adapters [label="Rust/Python/TypeScript\nlanguage adapters", fillcolor="#FCE4EC", color="#D81B60"];
// Edges
ui -> runtime;
runtime -> sdk;
sdk -> coding;
sdk -> research;
sdk -> website;
coding -> adapters;
}](_images/graphviz-f552b9831a2890501b69d0c2086465e028fac9c6.png)
Perspt Extension Stack Layered Architecture
Initial implementations may compile first-party domain packages in-process for simplicity. The SDK defines process boundaries clearly enough that future WASM or process-isolated packages can be added without redefining residual, capability, graph, or ledger semantics.
2. SRBN Kernel Semantics
Perspt makes the SRBN kernel semantics explicit in code rather than treating them as documentation terms.
The SDK proxy state consists of:
the current workspace state or sandbox branch,
the current work graph revision,
the active node generation,
the ledger head,
the capability set granted to the current actor,
the verifier residual vector for the current candidate, and
the candidate artifact, patch, command, or domain action proposal under review.
Every generated artifact, patch, command, graph rewrite, dependency mutation, research claim set, website build action, or domain-specific action is a candidate state first. A candidate enters the accepted trajectory only if it passes one of the accepted-state gates:
Hard pass: all required verifiers for the node scope pass and all hard policy constraints pass.
Measured descent: the candidate reduces the energy below the best accepted energy by at least
rho_gateand remains inside policy, budget, and capability bounds.Certified stop: the system cannot reach stability, so it terminates with a residual certificate naming the remaining residuals, verifier routes, budget state, and ledger head.
Perspt distinguishes the observed trajectory from the accepted trajectory:
observed attempts include malformed bundles, stripped bundles, denied commands, non-descending patches, failed tests, and rejected graph revisions;
accepted attempts include only hard-pass or descent-gated states;
rejected attempts are retained as training/audit data but are never treated as committed progress.
Residual scores are finite and non-negative. A sensor failure produces either a V_boot residual or an explicit degraded-validation stop, and is never silently interpreted as zero energy.
Mathematical SRBN Contract
The SDK implements the paper theory as a measurable runtime contract. The theory is conditional: Perspt claims SRBN stability only for a declared domain, state proxy, residual schema, verifier route, correction channel, disturbance estimate, and accepted trajectory.
For a WorkGraph revision with nodes N and typed edges E, each executable
node or sealed interface contributes a local state component x_i. Each edge
e = (i, j) has a restriction or comparison map rho_e supplied by the
domain package. The domain package maps verifier evidence into residuals:
and the SDK computes the canonical non-negative weighted energy:
This weighted sum of squared edge residuals is the single energy that gates acceptance, feeds the finite-decision bound, and is recorded for replay.
Each ResidualEvent stores the raw residual magnitude r_e >= 0; the
SDK squares and weights it when computing V. The component aggregates
V_syn, V_str, V_log, V_boot, and V_sheaf are derived
rollups of this same quadratic energy, grouped by EnergyComponent:
The component rollups are user-visible projections only. They do not carry independent weights and are not summed through a second weighting pass.
Every edge residual carries an explicit weight w_e; no component defaults to an implicit weight of 1 while others are weighted.
The safe set for the declared proxy is the zero-energy set:
For coding, an edge residual may be a compiler diagnostic cluster, import graph mismatch, public signature mismatch, failing test attribution, formatter residual, or policy residual. For research, the same equation can use claim-to- source residuals. For website-building, it can use build, accessibility, visual-layout, and deployment residuals. The SDK owns the energy equation and trace; domain packages own the residual construction and weights.
Perspt’s primary contract is the measured discrete energy and gate. The
continuous embedding-space constants alpha (correction strength), beta
(drift strength), delta (persistent disturbance), L (smoothness), and
eta (step size) require a gradient field v(x) = -alpha grad V(x) and a
drift field f(x) on an exposed or estimated continuous coordinate. The
coding domain operates on discrete verifier residuals and exposes no such
coordinate, so these constants are expected to remain NotClaimed for it. The
SDK treats alpha, beta, delta, L, and eta as optional records that a domain package may register only when it can instrument them; it does not require them, build acceptance on them, or display analytic floors derived from them unless they are registered with evidence.
When a domain can expose or estimate a continuous correction coordinate, the paper model uses transverse error dynamics:
The runtime does not assume these equations hold globally. It records the declared constants and evidence for the local analysis domain when a domain package claims them:
When these conditions are justified on the analyzed sublevel set, the SDK may report the input-to-state-stability energy floor:
The implementation treats V_infty as a declared or estimated floor, not
as a magical success condition. A candidate above the floor still requires hard
checks, measured descent, or a residual certificate.
The energy-slope constant mu is the exception: for the quadratic residual
energy V(x) = x^T A x with A = B^T W B, it is combinatorial rather than
embedding-dependent and is computable from the WorkGraph verification
structure:
the smallest non-zero eigenvalue of A. In the identity-restriction case
A reduces to the weighted Laplacian of the verification graph and mu is
its algebraic connectivity (Fiedler value). The SDK exposes mu as a
spectral diagnostic of the active verification graph and is able to report
the change in mu produced by adding a candidate verifier edge, so that an
independent verifier that raises the spectral gap is distinguishable from a
redundant verifier that does not.
mu is a diagnostic, not an input to the acceptance gate. It is computed off the critical path – on graph-revision commit, when the graph
structure stabilizes, or asynchronously – and does not block worker dispatch,
candidate verification, or the acceptance-gate decision. During high graph
churn the SDK may report the last computed mu with its source revision.
For discrete corrections, the SDK stores the proposed step size eta and
may validate it against the paper’s sufficient bound when the domain provides
the smoothness constant L:
Under that declared model, the expected geometric factor is:
The acceptance gate used by Perspt is the measured discrete contract from the harness paper, and it applies even when the continuous assumptions are not available:
Descent is measured against the best accepted energy V(x_k^best), not
the most recent accepted energy. There is a single descent tolerance
rho_gate > 0. min_descent is not a second gate threshold; where a domain
records a predicted analytic decrease, it is advisory only and does not relax
or replace rho_gate in the gate decision.
Otherwise the candidate is rejected for the accepted trajectory:
With V >= 0, descent threshold rho_gate > 0, baseline energy V_0,
and finite rejection budget B, a run has the finite-decision bound:
The SDK exposes this bound in telemetry whenever the run has a fixed
rho_gate and correction budget.
At platform level, every effect proposal must satisfy the capability
admissibility predicate before any durable effect occurs. For proposal
p = (a, c, i, y, e, \mu_p) and candidate next state x':
only if all of the following hold:
The capability attenuation preorder is represented explicitly:
Delegation must only create capabilities satisfying the preorder. Payload data, model text, or generated code does not mint authority.
For scheduler and dashboard observability, the SDK computes backlog potential from active work:
Phi(W) is presented as a backlog and remaining-work gauge for the
dashboard and for ETA projection. The platform-level Foster-Lyapunov drift
condition
requires a stochastic workflow arrival process with a measurable sub-critical
load alpha_load < 1. A single-session run has no arrival process, so its
potential is monotone non-increasing and the drift condition is trivially
satisfied. Perspt does not present the drift condition as a conformance result
in single-session execution. A deployment may record alpha_load and check
the drift condition only in a multi-session or server mode where the arrival
process exists.
The implementation distinguishes between measured SRBN conformance and
analytic stability claims. Measured conformance is mandatory: Perspt must
compute residuals, energy, gate decisions, correction directions, residual
certificates, and replay records for every run. Analytic claims are stricter:
Perspt may display V_infty, step-size certificates, or platform drift claims
only when the domain package provides the corresponding constants, evidence, and
ledger measurements. A missing constant is not a soft pass; it is an explicit
NotClaimed analytic status.
SRBN Conformance Gates
Implementation may be staged, but each stage is a named conformance gate, not a relaxation of the PSP. Perspt does not present a run, release, or benchmark as PSP-8-complete unless all applicable gates below pass.
- Gate A: Kernel and energy conformance
perspt-sdkusessrbnandsrbn-serdefor stabilization traces where applicable. Every candidate has a finite non-negative residual vector, a declaredEnergyModel, a computed energy, and a gate decision. The measured acceptance gate is mandatory.- Gate B: Harness conformance
Observed and accepted trajectories are separated. Non-descending candidates are retained as observations and excluded from accepted progress. Exhaustion yields a residual certificate. The prompt compiler receives dominant residuals and correction directions, never undirected retry text.
- Gate C: Mutable graph conformance
WorkGraph revisions are acyclic, revisioned, and replayable. Repair actions become scheduler effects. Inserted, split, reset, or requeued nodes are executable in the same session when dependencies and leases permit.
- Gate D: Coding-domain verifier conformance
perspt-codingimplements SDK-native verifier suites for Rust, Python, and JavaScript/TypeScript. Each suite provides parser/AST or structural evidence, symbol/import/interface extraction where available, compiler/type/test/build sensors, degraded-sensor residuals, and correction-direction mappers.- Gate E: Capability platform conformance
Every effect is mediated by an admissibility witness. Authority, contract, effect scope, barrier/risk clauses, attenuation, idempotency, and state witnesses are checked outside generated code.
- Gate F: Durable replay conformance
The event ledger records proposals, observations, residuals, energy models, gate decisions, verifier outputs, effects, graph revisions, capability changes, workflow potentials, and rollback/undo. Replay reconstructs the same accepted trajectory from recorded observations without re-running stochastic sources.
- Gate G: Spectral and analytic-claim conformance
The SDK computes the spectral energy-slope constant
mu = 2 lambda_min+(A)from the quadratic residual energy and exposes it as a verification-graph diagnostic. This spectral computation is required, computed off the critical path so that it never blocks dispatch or the acceptance gate. The continuous and stochastic analytic claims are optional and not required for PSP-8 completion: a run that claims them must register aStabilityClaimwith the relevant constants, the analysis domain, and evidence references, after which the SDK computesV_inftyand step-size checks; a run without those constants remains measured-conformant and analyticallyNotClaimed. The coding domain is expected to remainNotClaimedfor the continuous constants.- Gate H: Backlog-potential conformance
Active work exposes per-item potential
phi_iand aggregate potentialPhi(W)as a backlog gauge. This gauge is required. Platform-level Foster-Lyapunov drift claims are optional and apply only to a multi-session or server deployment with a measurable sub-critical load; they are not required for single-session PSP-8 completion.- Gate I: Calibrated risk-budget conformance
When a deployment enables autonomous commitment without per-effect approval, validator acceptance thresholds are calibrated from the deployment’s own ledger by conformal risk control so that the marginal accepted-unsafe rate is bounded by the declared budget. A drift monitor compares the live validator score distribution against the calibration distribution and flags the calibration stale when they diverge. A stale flag degrades gracefully to a conservative back-off plus risk-class approval and an uncertified status, never a hard halt, and triggers background recalibration. This gate is required only when autonomous commitment is enabled.
Paper object |
SDK representation |
Required implementation evidence |
|---|---|---|
Proxy state |
|
State witnesses and input digests recorded before proposal, verifier, and commit |
Sheaf residual |
|
Raw tool/LSP/test/AST/policy evidence normalized into finite non-negative residual score |
Energy |
|
Weights, residual vector, component totals, and total energy recorded for every candidate |
Safe set |
Hard gates plus zero/tolerance energy condition |
Hard-check results, degraded sensors, and declared tolerance recorded with gate decision |
Correction field |
|
Dominant residual cluster, selected correction route, model/tool route, and follow-up verifier result |
Accepted trajectory |
|
Observed candidates retained; accepted states only hard-pass or satisfy measured descent |
Residual certificate |
|
Final residuals, final energy, exhausted budgets, verifier routes, rejected attempts, and ledger head |
Merkle history |
Event-sourced ledger with cryptographic hashes |
Append-only proposal, decision, effect, verifier, graph, and rollback events |
Capability |
|
Authority, scope, contract, barrier, and risk clauses evaluated outside generated code |
Attenuation |
Capability delegation rule |
Delegated effect scope, call budget, expiry, and delegability are no greater than source capability |
Platform potential |
|
Accepted energy, remaining budget, per-workflow potential, aggregate potential, and load estimate |
Durable execution obligations |
Replay ledger, command IR, idempotency keys, noncommuting leases |
Recorded nondeterminism, deterministic replay, write-ahead external effects, and serialized durable conflicts |
perspt-sdk uses the published srbn crate as the canonical SRBN
kernel dependency where the crate’s run/stabilize and
BarrierResult contracts fit the SDK loop. perspt-sdk uses srbn-serde for serializing SRBN traces and barrier records when those
records enter the Perspt ledger. Perspt should NOT fork the SRBN kernel logic
inside the agent runtime. If the current crate API is too small for Perspt’s
domain packages, Perspt should add a narrow adapter in perspt-sdk and feed
the reusable improvement back into the SRBN crate rather than creating a second
kernel.
The adapter boundary should keep Perspt-specific WorkGraph, capability, command IR, and ledger types outside the SRBN crate. The SRBN crate owns the generic stabilization contract; Perspt owns the domain runtime around that contract.
The SDK-side adapter should expose types equivalent to:
pub struct AgentBarrierResult {
pub ok: bool,
pub score: f64,
pub residuals: ResidualVector,
pub feedback: CorrectionDirectionSet,
pub evidence: VerificationEvidence,
}
pub enum AgentStabilizationStatus {
Stable,
Descended,
Stopped,
Exhausted,
Degraded,
ReplanRequired,
}
pub struct StabilityParameters {
pub energy_tolerance: f64,
pub rho_gate: f64, // single descent tolerance for the gate
pub predicted_descent: Option<f64>, // advisory analytic decrease only
pub mu: Option<f64>, // spectral, computed from the graph
pub alpha: Option<f64>, // optional; coding domain: NotClaimed
pub beta: Option<f64>, // optional; coding domain: NotClaimed
pub delta: Option<f64>, // optional; coding domain: NotClaimed
pub smoothness_l: Option<f64>, // optional; coding domain: NotClaimed
pub eta: Option<f64>, // optional; coding domain: NotClaimed
pub ultimate_floor: Option<f64>, // optional; requires alpha,beta,delta,mu
}
pub struct EnergyTracePoint {
pub attempt: u32,
pub observed_energy: f64,
pub accepted_energy_before: f64,
pub accepted_energy_after: Option<f64>,
pub decision: GateDecision,
pub dominant_residuals: Vec<ResidualEventRef>,
}
pub enum GateDecision {
HardPass,
AcceptedByDescent { delta_v: f64 },
RejectedNonDescending { delta_v: f64 },
StoppedAtDeclaredFloor,
ExhaustedWithCertificate { certificate_id: String },
}
pub struct ResidualCertificate {
pub certificate_id: String,
pub ledger_head: String,
pub final_energy: f64,
pub final_residuals: ResidualVector,
pub exhausted_budgets: Vec<BudgetRef>,
pub verifier_routes: Vec<IndependenceRoute>,
pub rejected_attempts: Vec<String>,
pub next_correction_directions: Vec<CorrectionDirection>,
}
The adapter is used by the generic runtime, the coding package, and correction retries so that Perspt has one stabilization contract.
3. Exploration and Model Routing
Perspt treats unfamiliar existing codebases as a distinct control problem: before the agent proposes durable mutations, it needs a cheap, bounded, read-only understanding of the repository. This exploration phase is evidence gathering, not implementation.
Exploration runs with read/search/list/LSP/query capabilities by default. It does not write files, mutate dependencies, run package-manager writes, change graph policy, or apply patches. If an exploration step discovers that a mutation may be required, it emits a residual, graph hint, or capability request rather than performing the mutation.
Exploration outputs are structured artifacts:
project map: languages, package roots, build systems, entry points, and ownership patterns;
domain-package and coding-adapter activation evidence plus missing-tool residuals;
symbol and import inventory requests;
dependency graph and public-interface hints;
test layout, fixture layout, and likely targeted test commands;
risk hotspots such as generated code, migrations, unsafe blocks, FFI, production configuration, or global state;
files-to-read and files-to-avoid recommendations;
WorkGraph seed nodes, edge hints, and verifier-suite recommendations.
Exploration evidence is advisory unless backed by deterministic tool output, structural digests, compiler/LSP observations, or repository-local metadata. A cheap model may summarize or rank evidence, but it does not become an independent correctness barrier merely because it observed the codebase.
Model routing is phase-aware:
Perspt supports an explicit exploration model override through
explorer_modelin config and--explorer-modelon the CLI.If no exploration model is configured, exploration defaults to the cheapest configured tier suitable for read-only summarization. In the current Perspt tier model this should be
speculator_model.Implementations may avoid adding a fifth
ModelTierby treating Explorer as a phase routed toModelTier::Speculatorby default.Implementations may expose
--explorer-tierwith values such asspeculator,verifier,actuator, andarchitectfor users who want exploration to reuse one of the existing tier models.--modelcontinues to set all tiers unless a phase-specific override is provided.Exploration has independent budgets: file count, token count, tool calls, wall-clock time, and maximum parallel workers.
--exploration-onlyshould run the read-only inventory and write a project profile or exploration report without entering build mode.
Exploration is parallel by default where safe:
file tree scans,
rg/git grepsearches, package metadata reads, LSP symbol requests, AST extraction, and test discovery may run concurrently;model summarization of independent repository slices may run concurrently under the exploration budget;
each exploration task records its model route, capability use, input digests, and output evidence;
planner prompts receive summarized exploration artifacts with provenance, not unbounded raw repository text.
This layer directly supports the user need that an existing codebase often must be explored before useful planning is possible, and that this work can use a lower-cost model without weakening SRBN acceptance gates.
4. Mutable Work Graph
Perspt replaces static “plan DAG execution” with a mutable, revisioned work graph. Each graph revision is acyclic, but the session as a whole may add, retire, split, merge, update, or requeue nodes as verifier evidence changes. The scheduler runs independent work in parallel and serialize only work that conflicts through dependencies, leases, or non-commuting durable effects.
This resolves the central limitation: software tasks are not known completely at planning time. A compiler error may reveal a missing module. A test failure may require a fixture node. An AST search may reveal a wider API migration. A dependency conflict may require a manifest repair node. A static DAG cannot faithfully model this; a revisioned acyclic work graph can.
Perspt distinguishes:
PlanGraph: the architect’s current hypothesis about task decomposition.
WorkGraph: the scheduler’s executable graph with node generations, leases, locks, ownership, and verifier status.
GraphRevision: a durable version of the WorkGraph produced by planning, local repair, scope expansion, or user edit.
NodeGeneration: an immutable incarnation of a node. Updating a node creates a new generation instead of mutating the old one in place.
RetiredNode: a node generation that remains in the ledger but is no longer executable.
The scheduler does not precompute one vector of topological indices and walk it to completion. It uses a dependency-aware mutable ready queue:
load active graph revision;
select executable nodes whose dependencies are stable, blocked sensors are resolved, and required leases are available;
execute one or more non-conflicting node generations through speculate, verify, converge, sheaf pre-check, sheaf validate, and commit;
convert repair outcomes into durable scheduler commands;
apply graph revisions atomically;
recompute the ready queue;
repeat until every active node is stable, certified stopped, or escalated.
![digraph psp8_scheduler {
rankdir=TB;
bgcolor="transparent";
splines=ortho;
node [shape=box, style="rounded,filled", fontname="Arial", fontsize=10, margin="0.18,0.10"];
edge [fontname="Arial", fontsize=9, color="#546E7A", fontcolor="#455A64"];
revision [label="Active WorkGraph\nacyclic revision", fillcolor="#FFF3E0", color="#FB8C00"];
ready [label="Mutable ready queue\ndependencies satisfied", fillcolor="#E3F2FD", color="#1E88E5"];
leases [label="Lease table\nfiles, interfaces, tools", fillcolor="#EDE7F6", color="#5E35B1"];
worker_pool [label="Worker pool\nbounded parallelism", fillcolor="#ECEFF1", color="#607D8B"];
explorer [label="Explorer workers\nread/search/LSP", fillcolor="#E8F5E9", color="#43A047"];
verifier [label="Verifier workers\nbuild/test/AST", fillcolor="#FCE4EC", color="#D81B60"];
implementer [label="Implementer workers\ncandidate bundles", fillcolor="#E1F5FE", color="#039BE5"];
effects [label="Scheduler effects\ncommit, retry, split, stop", fillcolor="#FFF8E1", color="#F9A825"];
validate [label="Revision validation\nacyclic + witnessed", fillcolor="#E0F2F1", color="#00897B"];
ledger [label="Event ledger\nspawn/join/cancel", fillcolor="#F1F8E9", color="#689F38"];
revision -> ready;
ready -> leases [label="request"];
leases -> worker_pool [label="grant / wait"];
worker_pool -> explorer;
worker_pool -> verifier;
worker_pool -> implementer;
explorer -> effects;
verifier -> effects;
implementer -> effects;
effects -> validate [label="graph-changing"];
validate -> revision [label="revision N+1"];
effects -> ready [label="requeue / spawn"];
effects -> ledger;
leases -> ledger;
worker_pool -> ledger;
}](_images/graphviz-12c1c442c266cf6a136089f96ea8397f05e21631.png)
Mutable Parallel Scheduler
Two durable turns commute, and therefore need no relative order, only when their semantic read and write footprints are disjoint:
The conflict footprint includes durable platform state, not only workspace files. The capability table, risk budgets, fresh-identifier allocation, and the ledger root are modeled as read/write state components. Because admissibility reads the capability table, any capability grant, attenuation, or revocation conflicts with every commit that touches the affected capabilities and serializes against them. Any turn that reads or updates a risk budget, allocates a fresh identifier, or advances the ledger root is ordered against other turns with an overlapping footprint.
Parallel scheduling rules:
read-only exploration, verifier, symbol-index, and search tasks may run concurrently when their read/write footprints are disjoint;
implementation nodes may run concurrently only when their output targets, dependency interfaces, toolchain locks, state witnesses, capability grants, and budget reads do not conflict;
correction attempts for unrelated residual clusters may run concurrently, but accepted artifact commits serialize if they touch overlapping files, public interfaces, dependency manifests, lockfiles, migrations, shared test fixtures, capabilities, budgets, or the ledger root;
graph revisions acquire a graph-write lease and are serialized against other graph revisions;
package-manager writes, formatter writes, generated-code refreshes, and database/schema migrations use explicit toolchain or resource leases;
scheduler fairness prevents a flood of cheap exploration tasks from starving verifier or commit tasks.
Perspt exposes concurrency controls:
max_parallel: total worker limit;max_parallel_exploration: read-only exploration worker limit;max_parallel_verifiers: verifier/tool worker limit;max_parallel_model_calls: concurrent LLM call limit;max_parallel_mutations: artifact-application limit, defaulting to 1.
Every parallel task has a parent activity, worker id, model route if any, capability set, lease set, input witnesses, cancellation policy, and join event. If a dependency changes while a task is running, the task is cancelled, revalidated, or converted into an observed rejected attempt before any effect is accepted.
Repair actions return scheduler work items:
RetryNode(node_generation, evidence)ExpandScope(node_generation, added_paths, reason)SplitNode(node_generation, child_specs)InsertInterfaceNode(boundary_spec)AddNode(node_spec, edges, reason)RetireNode(node_generation, reason)ReplanSubgraph(root, affected_nodes, evidence)StopNode(node_generation, residual_certificate)
execute_node does not return Escalated after a local repair action has
successfully produced new executable work. It returns a scheduler effect
that is consumed by the ready-queue loop.
Graph revision rules:
every revision validates acyclicity before activation;
edge creation is serialized as a graph-write conflict;
a node may be updated only by creating a new generation;
descendants whose structural dependencies changed are requeued or retired;
graph revisions consume the revision budget;
graph churn is bounded by lineage and by session;
graph revisions include the verifier evidence that justified them;
replay reconstructs the same active graph sequence.
Edges carry typed semantics:
RequiresArtifact: destination reads a file produced by source;RequiresInterface: destination relies on a sealed signature/schema/symbol;Tests: destination test node validates source implementation node;Integrates: destination reconciles cross-node, cross-domain, or cross-adapter boundaries;ConflictsWith: nodes touch non-commuting durable state and must serialize;DerivedFrom: graph-rewrite lineage edge for audit;BlocksOnSensor: node cannot execute until a required verifier sensor exists or is explicitly downgraded.
5. SDK Domain Packages and Coding Verifier Suites
The SDK defines domain-package contracts instead of making language plugins the root extension point. A domain package provides:
domain detection and activation evidence;
domain-specific project/profile generation;
exploration tasks and context packers;
verifier/sensor suites;
residual classifiers and correction-direction mappers;
artifact bundle schemas and validation;
capability templates and policy defaults;
graph node templates and edge inference;
benchmark fixtures and mechanism checks;
dashboard projection labels and domain-specific summaries.
The core SDK trait should look like this, with exact names left to implementation:
pub trait AgentDomainPackage: Send + Sync {
fn domain_id(&self) -> DomainId;
fn detect(&self, workspace: &WorkspaceSnapshot) -> DomainDetection;
fn residual_schema(&self, scope: &DomainScope) -> ResidualSchema;
fn energy_model(&self, scope: &DomainScope) -> EnergyModel;
fn exploration_plan(&self, task: &TaskCharter) -> Vec<ExplorationWork>;
fn verifier_suites(&self, scope: &DomainScope) -> Vec<Box<dyn VerifierSuite>>;
fn hard_gates(&self, scope: &DomainScope) -> Vec<Box<dyn HardGate>>;
fn context_package(&self, request: ContextRequest) -> ContextPackage;
fn correction_directions(&self, residuals: &[ResidualEvent]) -> Vec<CorrectionDirection>;
fn capability_policy(&self) -> DomainCapabilityPolicy;
fn graph_hints(&self, evidence: &ExplorationReport) -> Vec<GraphHint>;
}
The ResidualSchema and EnergyModel declare:
residual classes and their allowed sensors;
normalization from raw tool output to finite non-negative scores;
residual weights
w_eand hard-check thresholds;the mapping from residuals into
V_syn,V_str,V_log,V_boot, andV_sheaf;the default
rho_gate, energy tolerance, and correction budgets;optional local stability constants
alpha,beta,delta,mu,L, andetawhen the domain claims a mathematical energy tube rather than only measured descent.
perspt-coding implements this trait. Inside perspt-coding,
language adapters evolve from command selectors into verifier-suite
providers. A coding language adapter provides:
repository detection and ownership patterns;
parser or AST provider;
symbol inventory extraction;
import/dependency graph extraction;
public-interface extraction and structural digesting;
LSP diagnostics and code intelligence;
compiler/typechecker commands;
build commands;
test discovery and targeted test commands;
lint/formatter commands;
dependency manager commands and manifest mutation policy;
tree-search repair candidates;
logical validators for language-specific invariants;
degraded-sensor fallback policy;
correction-direction mappers for all verifier evidence.
First-party coding adapter milestones include:
- Rust
rust-analyzerdiagnostics,cargo metadata,cargo check,cargo test, optionalcargo clippy,cargo fmt --check, module graph extraction, public item/trait signature extraction, missing crate detection, feature-flag conflict detection, workspace package target selection, and correction directions for unresolved imports, trait bounds, borrow errors, visibility errors, missing module declarations, and failing tests.- Python
tyorpyrightdiagnostics,uvenvironment checks,pytestdiscovery, optionalruffandmypy/pyrightfallback, import graph extraction, package/module layout detection, fixture/test attribution, dependency sync checks, and correction directions for missing modules, signature mismatches, packaging errors, fixture failures, and import cycles.- JavaScript/TypeScript
package-manager detection,
tsc --noEmitor project-defined typecheck, package build/test scripts, ESLint/Prettier where available, import graph and export signature extraction, framework-aware test discovery, and correction directions for missing exports, tsconfig path aliases, package lock drift, bundler failures, and runtime test failures.
Additional coding language adapters may follow for Go, Java, C/C++, Ruby, Swift, and shell, but they use the same SDK verifier-suite interface.
Other first-party domain packages should follow the same SDK contracts:
- Research
Source discovery, citation provenance, claim extraction, quote bounds, contradiction checks, source freshness, bibliography generation, and residuals for unsupported claims, stale evidence, source mismatch, and citation gaps.
- Website builder
Route discovery, component inventory, build commands, screenshot checks, responsive layout validation, accessibility checks, asset validation, deployment previews, and residuals for build failure, visual overlap, broken assets, accessibility regressions, and deployment-policy denial.
- Task-specific packages
Domain authors may provide narrow packages for data cleanup, documentation, migrations, release automation, or compliance review. They reuse SDK graph, residual, capability, ledger, and dashboard contracts.
Verifiers are not limited to compilers and LSPs. A domain package or coding adapter may use:
AST queries;
bounded tree search over imports, symbols, package versions, or migration paths;
SAT/SMT or property checks;
repository-local scripts and make targets;
git diff,git grep,rg,find,sort,uniq,comm,xargs;awkandsedas read-only or patch-preview analyzers;test shard selection;
snapshot/regression validators;
generated fixtures;
documentation and API schema validators.
These tools produce typed residual evidence. They should not directly edit the repository unless invoked through an approved artifact or command effect.
6. Residual Evidence Model
Perspt introduces a first-class residual model. A residual is not just a log line; it is the measured reason the current state is unsafe or incomplete.
pub struct ResidualEvent {
pub residual_id: String,
pub node_id: String,
pub generation: u32,
pub component: EnergyComponent,
pub class: ResidualClass,
pub severity: ResidualSeverity,
pub score: f64,
pub sensor: SensorRef,
pub evidence: EvidencePayload,
pub affected_paths: Vec<PathBuf>,
pub affected_symbols: Vec<SymbolRef>,
pub correction_directions: Vec<CorrectionDirection>,
pub independence_route: IndependenceRoute,
}
pub enum ResidualClass {
Syntax,
Type,
Build,
TestFailure,
Lint,
Format,
Runtime,
Dependency,
Manifest,
ImportGraph,
SymbolMismatch,
InterfaceMismatch,
OwnershipViolation,
ContextDrift,
Regression,
Policy,
SensorUnavailable,
ToolFailure,
SheafInconsistency,
CapabilityDenied,
BudgetExhausted,
}
Each verifier residual maps into one SRBN energy component, which is the rollup that groups its squared weighted residual:
V_syn: syntax, parser, typechecker, and compiler diagnostics caused by the candidate;
V_str: structural contract, ownership, import graph, symbol, interface, formatting, lint, and invariant residuals;
V_log: failing tests, snapshots, property checks, and behavioral validators;
V_boot: toolchain, dependency, package sync, sandbox, missing binary, and degraded-sensor residuals;
V_sheaf: cross-node, cross-domain, and cross-adapter consistency residuals.
The energy components are the derived rollups defined in System 2; they are telemetry projections of the single quadratic residual energy.
CapabilityDenied and BudgetExhausted are admissibility outcomes, not
verifier consistency residuals. They are recorded on a separate blocked
channel and are not summed into the Lyapunov energy V or treated as a
residual to be corrected by regeneration.
A degraded sensor means the energy for its component is unknown, not low. When a
required sensor is unavailable, the node takes a degraded-validation stop
and emit a residual certificate rather than accepting descent on an energy that
is missing a required component. A V_boot residual for a degraded sensor is
permitted only for sensors that are not required for the node scope.
Correction prompts are generated from dominant residuals:
sort residuals by weighted score and dependency order;
cluster residuals by likely root cause;
choose correction directions from domain-package or coding-adapter mappers;
include the minimal structural context required by those directions;
ask the model to produce a bundle addressing the named residuals;
verify whether the same residuals decreased or disappeared.
Undirected retries are considered a bug. If Perspt cannot produce a correction direction, it reports this and either run another verifier, ask a bounded question, or escalate with a residual certificate.
Verifier independence is recorded for every residual:
deterministic tool;
compiler/typechecker;
LSP;
test oracle;
formal/logical solver;
repository script;
external API;
separate model/provider;
same-model critique.
Dashboard and status views make same-model critique visibly weaker than deterministic or independent routes. Same-model critique does not contribute a full-weight descent acceptance.
Verifier independence is measured, not assumed. The ledger retains
each validator’s verdict per candidate so that pairwise miss rates q_i and
miss correlation kappa_ij are computable from history. For a conjunctive
verifier gate the effective ensemble miss bound is
Residual weights w_e are reduced for verifiers whose measured
correlation with an already-counted verifier is high, so that a redundant
validator does not contribute the weight of an independent one. Duplicate
validators are not counted as independent merely because they appear twice,
and status views surface rho_eff rather than a raw count of validators.
7. Capability-Constrained Admissibility
Perspt adopts Paper III’s platform rule: stochastic components emit proposals, never unmediated effects.
Every effect passes through an admissibility kernel before execution:
pub struct EffectProposal {
pub proposal_id: String,
pub actor: ActorId,
pub node_id: String,
pub generation: u32,
pub effect: EffectKind,
pub scope: EffectScope,
pub risk: RiskClass,
pub idempotency_key: String,
pub preconditions: Vec<StateWitness>,
pub evidence: Vec<ResidualEventRef>,
}
pub struct Capability {
pub capability_id: String,
pub holder: ActorId,
pub effects: Vec<EffectKind>,
pub path_scope: Vec<PathPattern>,
pub command_scope: Vec<CommandPattern>,
pub network_scope: Vec<NetworkPattern>,
pub max_calls: Option<u32>,
pub expires_at: Option<i64>,
pub may_delegate: bool,
pub risk_budget: Option<RiskBudget>,
pub approval_policy: ApprovalPolicy,
}
Effect classes include:
ReadFileSearchListLspQueryWriteArtifactApplyPatchMoveFileDeleteFileRunVerifierRunFormatterRunTestRunBuildMutateDependenciesRunRepoScriptRunShellGitReadGitWriteNetworkFetchAskUserSpawnAgentUpdateGraphUpdatePolicy
The kernel evaluates:
actor holds a matching capability;
requested effect is in capability scope;
path and command scopes are workspace-bounded unless the user explicitly grants external scope;
capability call budget is not exhausted;
risk budget is not exhausted;
approval policy is satisfied;
state witnesses still match at execution time;
policy rules do not deny the effect;
command parsing is canonical and not hidden inside shell composition unless a
RunShellcapability explicitly permits it;the proposal is idempotent or guarded by a unique idempotency key.
Default policy:
read/search/list/LSP query effects may be allowed in workspace scope;
write/patch/move/delete effects require either user approval or an approved session policy;
dependency mutations require domain-package policy and approval unless explicitly delegated in the session charter;
arbitrary
RunShelldefaults to ask;network effects default to ask;
graph and policy updates are privileged effects;
self-modifying agents cannot grant themselves new capabilities.
Perspt keeps perspt-policy as the deterministic trusted base for the
kernel. Generated code, prompts, domain packages, adapters, and subagents are
be outside that trusted base.
Calibrated Risk Budgets
A capability risk budget is not an asserted constant when autonomous commitment without per-effect approval is enabled. The kernel calibrates each validator acceptance threshold from the deployment’s own ledger by conformal risk control.
For a validator that emits a safety score s(p) and accepts when
s(p) > theta, the kernel holds a calibration set of
(score, outcome) pairs in which an outcome is marked unsafe when a later
independent verifier, regression, or reverted commit contradicts the accepted
state. For a target budget rho, the conformal threshold is
where R_n(theta) is the empirical accepted-unsafe rate on the calibration
set. The deployed kernel accepts only when s(p) > theta_hat, which
bounds the marginal accepted-unsafe rate by rho.
The delayed unsafe label should be sourced from the undo/redo boundary and regression residuals already recorded in the ledger. The kernel runs a drift monitor that compares the live validator score distribution against the calibration distribution with a two-sample statistic; when they diverge, the calibration is flagged stale and background recalibration is triggered.
A stale flag does not hard-halt autonomous execution. Software tasks shift
regime routinely, so the runtime degrades gracefully rather than drop out
of auto mode. While a calibration is stale the kernel applies a
conservative back-off – inflating the accepted threshold and continuing
autonomous commitment for low-risk effects – while routing high-risk effects to
the risk-class approval policy, and continues background recalibration.
During the stale window the conformal bound is not asserted: the marginal accepted-unsafe guarantee holds only under exchangeability, so the back-off window is uncertified and is reported as such. Acceptance in that window rests on the measured gate and the risk-class approval policy, not on a calibrated budget. When recalibration restores exchangeability, the kernel resumes asserting the bound.
8. Tool and Command Governance
The current AgentTools API is split into typed tools and command IR.
sh -c does not remain as an implicit compatibility path. Shell execution is
allowed only as an explicit RunShell effect with declared scope,
capability, state witnesses, and ledgered approval.
Command proposals are parsed into:
pub enum CommandInvocation {
Program {
program: String,
args: Vec<String>,
cwd: PathBuf,
env: BTreeMap<String, String>,
},
Shell {
script: String,
cwd: PathBuf,
declared_reads: Vec<PathBuf>,
declared_writes: Vec<PathBuf>,
},
}
Verifier commands prefer Program form. Shell form requires a
capability that names shell execution.
Coreutils, awk, and sed are modeled in three tiers:
Inspection: read-only commands such as
rg,git grep,find,sort,uniq,wc,awkfilters, andsed -n. These can produce residual evidence.Patch preview: transformations that produce a proposed diff but do not mutate files. These can feed artifact bundles.
Mutation: commands that directly modify the workspace, such as
sed -i, generated scripts, package-manager writes, or build-system rewrites. These require mutation capabilities and state witnesses.
Every command result is attached to one of:
verifier evidence;
correction evidence;
artifact application;
policy denial;
residual certificate.
9. Agent Roles and Modes
Perspt’s “agents” mode becomes a capability-bounded role system. Roles are not trusted because they are named; they are trusted only through capabilities.
Required roles:
Explorer/Scout: performs read-only repository exploration, usually routed to the configured exploration model or Speculator tier.
Planner: produces and revises WorkGraph proposals.
Implementer: produces artifact bundles for one node generation.
Verifier: maps tool output into residual events and correction directions.
Repair Planner: chooses scheduler work items from non-convergence evidence.
Researcher: fetches external documentation when allowed.
Reviewer: summarizes diffs, risk, and residual state for the user.
Formatter/Test Runner: executes deterministic repo-native verification effects.
Modes:
planmode disables mutation effects and produce graph proposals, residual expectations, and verification plans.buildmode allows artifact and verifier effects inside the approved session policy.reviewmode runs read-only verifiers and produce critique without workspace mutation.automode requires an explicit session charter naming allowed effects, scopes, and budgets.
Subagents receive attenuated capabilities. A verifier subagent should not receive artifact-write permissions; a researcher should not receive repository write permissions; an implementer should not receive policy-update permissions. Explorer subagents start read-only and are budgeted separately from Planner and Implementer agents.
10. Project Knowledge and Context
Perspt introduces a project profile similar in purpose to AGENTS.md but
owned by Perspt:
default path:
.perspt/project.mdorAGENTS.mdif the project already uses it and the user approves importing it;contains project architecture, coding conventions, verifier commands, package manager choices, test layout, unsafe operations, and known invariants;
generated by a read-only initialization pass, optionally using parallel exploration and the configured exploration model;
committed only with user approval;
hashed and referenced by context provenance.
Context assembly remains graph-derived. Large repositories are not stuffed into prompts. Context packages provide:
node-owned files;
sealed interfaces and structural digests of dependencies;
residual evidence for the active correction;
symbol/import slices selected by domain-package or coding-adapter analyzers;
relevant tests and fixtures;
project profile excerpts with hashes;
prior accepted ledger summaries, not raw conversational history.
Context drift produces a residual. If the file, digest, or project profile used to generate a prompt no longer matches the workspace, the candidate is rejected or revalidated before application.
11. Durable Ledger and Replay
The ledger becomes an event-sourced replay contract. It is possible to reconstruct:
the active graph revision at every point;
every candidate bundle and command proposal;
every admissibility decision;
every verifier observation;
every residual vector and energy snapshot;
every energy model, weight table, and stability claim used for scoring;
every accepted-trajectory gate decision;
every correction direction;
every graph rewrite;
every accepted commit;
every rejected or stripped candidate;
every rollback and undo action;
every capability grant, attenuation, expiry, and consumption.
New ledger events include:
proposal_observedadmissibility_checkedeffect_appliedeffect_deniedverifier_startedverifier_completedresidual_emittedenergy_model_registeredenergy_scoredstability_claim_recordedgate_decision_recordedcandidate_acceptedcandidate_rejectedcorrection_direction_selectedsrbn_trace_recordedgraph_revision_proposedgraph_revision_acceptedgraph_revision_rejectednode_generation_retiredresidual_certificate_issuedrollback_appliedcapability_grantedcapability_consumedcapability_revokedmodel_route_selectedparallel_task_spawnedparallel_task_joinedparallel_task_cancelledworkflow_potential_recordedlease_acquiredlease_released
Perspt uses cryptographic hashes for durable commitments. Non-cryptographic
hashes such as DefaultHasher may be used only for in-memory maps or tests,
not for Merkle, replay, or provenance claims.
Replay is deterministic over recorded observations. If a verifier used randomness, wall-clock time, network data, or an external service, the ledger records the realized observation needed for replay. Replay reads the recorded observation, not re-run the external source.
The admissibility kernel refuses to commit any transition that references an observation lacking a ledger record. Recording every stochastic observation before it is used is what makes replay deterministic; the kernel-refusal rule enforces it rather than relying on convention.
This rule is a static architectural guarantee at the SDK effect and capability
boundary, not a dynamic operating-system interceptor. The SDK is not
required to trace syscalls or network reads. Instead, domain packages and
adapters obtain every observation by awaiting SDK-managed Effect
results, and the SDK records each observation before returning it. A
transition therefore references observations only by their recorded handles or
content addresses, and the kernel refuses any transition that references an
observation with no such record. Structurally confining observation to the
effect API is what discharges the recording obligation; an adapter that reaches
around the effect API for nondeterministic data is outside the contract and its
commits are inadmissible.
The runtime satisfies six durable-execution obligations:
Obligation |
Requirement |
Owning crate |
|---|---|---|
R1 durable single-assignment outcomes |
Every proposal and every commit or rejection outcome is written once and never reassigned; redelivery of the same idempotency key with equivalent content returns the prior result, and key reuse for different content is invalid |
|
R2 recorded nondeterminism |
Every stochastic observation a transition depends on is committed to the ledger before it is used |
|
R3 deterministic transition |
The committed transition is a deterministic function of the prior state and the recorded event |
|
R4 unforgeable capability transport |
Capabilities are minted and checked by the kernel; payload data cannot denote authority; every delegation applies the attenuation check |
|
R5 write-ahead external effects |
Every irreversible external effect is bracketed by intent, result, and where defined compensation records under a stable idempotency key |
|
R6 ordered non-commuting durable turns |
Non-commuting durable turns are totally ordered; weaker coordination is permitted only for read-only, monotone, commutative, or causally independent work before it crosses a durable boundary |
|
12. User Experience
The user experience exposes SRBN evidence rather than hiding it. The existing web interface is the primary live observability surface for long-running agent sessions; TUI, CLI, and headless output are compact projections over the same ledgered events.
TUI and headless output show:
active mode: plan, build, review, auto;
current graph revision and node generation;
active workers, worker roles, model routes, and blocked wait reasons;
active capabilities and pending approval requests;
current verifier suite and degraded sensors;
grouped diff for the candidate;
residual vector with dominant residuals first;
energy before/after candidate;
correction direction;
scheduler decision: retry, expand scope, split, insert interface, replan, stop, or commit;
budget state: attempts, steps, graph revisions, cost, and risk if enabled.
The web dashboard adds:
graph revision timeline;
parallel worker timeline and blocked-dependency view;
observed vs accepted trajectory;
residual heatmap by class, domain package, and adapter;
verifier independence routes;
capability grants and denials;
replay/rollback timeline;
non-commuting durable commits;
unstable nodes with suggested next action.
The dashboard also shows what Perspt is doing under the hood while work is active: current agent role, model route, tool invocation, lease wait, verifier stage, residual cluster, graph revision proposal, admissibility decision, and the exact reason a worker is blocked or cancelled. These views are powered by read-only projections of the event ledger so monitoring cannot mutate the running session.
Perspt supports undo/redo at the accepted candidate boundary:
undo reverts the last accepted artifact commit or graph revision;
undo creates a new ledger event and never deletes history;
redo reapplies an undone accepted event only if state witnesses still match;
undo/redo does not rewrite the Merkle history.
13. Evaluation and Benchmarks
Perspt does not claim SRBN reliability from implementation alone. It ships mechanism checks and coding benchmarks that can falsify this PSP’s claims.
Mechanism checks:
SRBN crate integration: the SDK adapter uses
srbnfor a minimal stabilize/run loop, records terminal status, and serializes the attempt trace throughsrbn-serdeinto the Perspt ledger;finite energy: every residual vector maps to a finite non-negative energy and sensor failure creates V_boot or degraded stop, never zero energy;
energy equation: a synthetic graph with known residuals verifies
V = sum_e w_e r_e^2and rejects negative, NaN, or infinite weights/scores;acceptance gate: a hard-pass candidate commits, a candidate with
V_next <= V_accepted - rho_gatecommits by descent, and a non-descending candidate remains observed-only;finite-decision bound: with
V_0,rho_gate, and budgetB, the run cannot exceedfloor(V_0 / rho_gate) + B + 1gate decisions before terminal classification;residual certificate: budget exhaustion emits a certificate with final residuals, final energy, verifier routes, rejected attempts, correction directions, and ledger head;
stability-claim validation: when a domain declares
alpha,beta,delta,mu,L, andeta, the SDK computesV_inftyand checks the discrete step-size precondition before displaying a mathematical stability claim;admissibility witness: every committed effect records authority, contract, effect, barrier-increment, and risk-budget decisions;
attenuation preorder: delegated capabilities can only shrink effect scope, call budget, expiry, or delegability;
platform potential: active workflows expose
phi_iandPhi(W)so the dashboard can show backlog potential and sub-critical load estimates;static graph snapshot bug: a local graph rewrite inserts a node and the scheduler executes it in the same session;
reset-node bug: a subgraph replan resets descendants and the scheduler revisits them;
parallel ready queue: two independent read-only or verifier tasks run concurrently while a dependent task waits on its edge;
exploration model routing: read-only repository exploration uses the configured exploration model or Speculator-tier fallback and records that route;
conflict lease denial: two mutation tasks touching the same manifest, lockfile, or public interface cannot commit concurrently;
no false stability: missing compiler/test tool creates V_boot or degraded stop;
residual direction: a Rust unresolved import produces an import/dependency correction direction, not an undirected retry;
capability confinement: a subagent with read-only capability cannot write;
shell confinement:
sed -iorrmis denied without mutation capability;replay determinism: replayed event stream reconstructs graph, residuals, and accepted commits;
recovery termination: every failure class maps to a bounded recovery path.
Coding benchmark suites:
Rust crate fixture tasks: add module, refactor API, fix borrow checker error, add dependency, preserve public interface, update tests.
Python package fixture tasks: add module, fix import layout, add dependency, update tests, preserve CLI/API behavior.
TypeScript fixture tasks: add route/component, fix export path, update tests, preserve package scripts.
Polyglot fixture tasks: update schema/client/server boundary.
Real repository tasks selected from SWE-bench Lite style issues where tests are runnable in the local environment.
Metrics:
final hard-pass rate;
residual-certified termination rate;
false-stability rate;
accepted-energy descent count;
non-descending candidate rejection count;
graph revisions per task;
verifier calls and wall-clock time;
parallel speedup versus serialized execution;
blocked-worker time and dominant wait reasons;
exploration cost, exploration token use, and exploration cache hit rate;
wasted speculative work cancelled by dependency or witness changes;
cost and token use;
capability denials;
user approvals requested;
regression count after commit;
replay success rate;
SRBN trace serialization round-trip rate;
accepted energy floor estimate and
V_inftywhen declared;gate-decision bound utilization;
platform potential
Phi(W)and load estimatealpha_load;same-model critique ablation versus independent verifier route.
No benchmark report omits failed runs. Residual certificates are first-class outcomes, not discarded failures.
UI/UX Design
This PSP changes the agent UX from “DAG run with logs” to “stability dashboard for a mutable coding workflow.”
User goals:
ask for a feature or bug fix in a real repository;
inspect the plan before mutation;
understand exactly which tools verified or rejected each candidate;
approve capabilities at the right granularity;
see when the agent changed its plan and why;
recover from wrong turns without history rewriting;
receive a residual certificate when Perspt cannot finish.
Interaction flow:
User runs
perspt agent --mode plan "<task>"or starts in default interactive mode.Perspt selects the coding domain package, activates relevant language adapters, and explores the repository with read-only capabilities, using the configured exploration model or Speculator-tier fallback for cheap summaries.
Planner proposes an initial WorkGraph and verifier suite.
User approves build mode or edits the graph/session charter.
Scheduler executes ready nodes through candidate generation, admissibility, verification, correction, and commit.
If evidence reveals missing work, Perspt proposes a graph revision and shows why it is needed.
User can approve, reject, or ask for a narrower revision.
Perspt completes with hard-pass success, partial success, or a residual certificate.
Headless mode remains useful in CI or scripted contexts. It prints structured stage lines and write all rich evidence to the ledger.
Technical Specification
Crate-level changes:
- perspt-core
Keep only low-level shared types, configuration, providers, and event primitives that are not part of the agent SDK. The existing language-plugin registry may be removed or reduced to a temporary migration aid. Public domain-neutral agent contracts should move to
perspt-sdkinstead of accumulating inperspt-core.- perspt-sdk
Add the reusable SRBN agent SDK: kernel adapter types, residual model, correction-direction types, WorkGraph/GraphRevision/NodeGeneration types, capability types, admissibility decision types, scheduler effect enums, command IR, replay event enums, model-route types, exploration report types, parallel-task/lease types, domain-package traits, verifier-suite traits, context-package traits, benchmark harness traits, and dashboard projection types. Depend on
srbnfor the generic stabilization loop andsrbn-serdefor serializing SRBN traces that enter the ledger.- perspt-agent
Become the generic SDK runtime. Load the selected domain package, add a read-only exploration runner, replace topological snapshot loops with a dependency-aware parallel ready-queue scheduler, convert repair actions into scheduler effects, integrate residual-directed correction, route all candidate effects through the admissibility kernel, and remove remaining legacy prompt-template entry points in favor of typed prompt compiler calls.
- perspt-coding
New first-party domain package for coding work. Move coding-specific project initialization, repository detection, language adapters, compiler/LSP/test sensors, AST/symbol/import graph extraction, source-edit artifact bundle helpers, dependency policies, coding correction mappers, and coding benchmark fixtures out of the generic runtime. The existing Rust, Python, and JavaScript/TypeScript language plugins may inform the implementation, but the new adapters should implement SDK verifier-suite traits directly rather than preserving the old plugin ABI.
- perspt-policy
Implement the deterministic admissibility kernel, capability attenuation, command IR canonicalization, state witness validation, idempotency checks, and risk/approval evaluation.
- perspt-store
Add event-sourced tables for proposals, admissibility decisions, residuals, capabilities, graph revisions, node generations, replay observations, rollback events, exploration reports, parallel worker lifecycle events, leases, and residual certificates. The event stream is canonical. Existing PSP-7
srbn_step_recordsandcorrection_attemptstables may be dropped, migrated forward, or regenerated as new projections; this PSP does not require old stored sessions to remain readable.- perspt-sandbox
Add sandbox state witnesses, command manifests, verifier execution profiles, and crash-safe compensation hooks for partially applied effects.
- perspt-tui
Add plan/build/review mode indicators, graph revision UI, residual vector UI, capability approval prompts, undo/redo, and residual certificate rendering.
- perspt-dashboard
Extend the existing web monitoring interface with graph revision timeline, residual heatmap, parallel worker timeline, blocked-dependency view, capability/audit views, verifier independence routes, model-route telemetry, replay status, rollback history, and observed-versus-accepted trajectory views. The dashboard remains a read-only observer over the agent event stream.
- perspt-cli
Add flags and commands for modes, capabilities, graph revisions, residual certificates, replay verification, exploration, model routing, domain selection, concurrency, and benchmark mechanism checks.
- future domain packages
Research, website-builder, and task-specific packages should use
perspt-sdkcontracts directly. They must not fork the scheduler, admissibility kernel, residual model, replay ledger, or dashboard event model.
Core data structures:
pub struct WorkGraphRevision {
pub revision_id: String,
pub sequence: u32,
pub parent_revision_id: Option<String>,
pub reason: GraphRevisionReason,
pub nodes: Vec<WorkNode>,
pub edges: Vec<WorkEdge>,
pub validation: GraphValidationReport,
pub evidence: Vec<ResidualEventRef>,
}
pub struct WorkNode {
pub node_id: String,
pub generation: u32,
pub goal: String,
pub node_class: NodeClass,
pub owner_domains: Vec<DomainId>,
pub owner_adapters: Vec<AdapterId>,
pub output_targets: Vec<PathBuf>,
pub context_requirements: Vec<ContextRequirement>,
pub verifier_suite: VerifierSuiteRef,
pub state: WorkNodeState,
}
pub struct VerifierRun {
pub verifier_run_id: String,
pub node_id: String,
pub generation: u32,
pub domain: DomainId,
pub adapter: Option<AdapterId>,
pub sensors: Vec<SensorOutcome>,
pub residuals: Vec<ResidualEvent>,
pub energy: EnergyComponents,
pub degraded: bool,
}
pub struct EnergyModel {
pub model_id: String,
pub domain: DomainId,
pub residual_weights: Vec<ResidualWeight>,
pub rho_gate: f64,
pub energy_tolerance: f64,
pub correction_budget: u32,
pub stability_claim: Option<StabilityClaim>,
}
pub struct ResidualWeight {
pub class: ResidualClass,
pub sensor: Option<SensorRef>,
pub component: EnergyComponent,
pub weight: f64,
pub hard_threshold: Option<f64>,
}
pub struct StabilityClaim {
pub claim_id: String,
pub analysis_domain: String,
pub alpha: Option<f64>,
pub beta: Option<f64>,
pub delta: Option<f64>,
pub mu: Option<f64>,
pub smoothness_l: Option<f64>,
pub eta: Option<f64>,
pub ultimate_floor: Option<f64>,
pub evidence_refs: Vec<String>,
}
pub struct AcceptedTrajectoryRecord {
pub node_id: String,
pub generation: u32,
pub baseline_energy: f64,
pub current_accepted_energy: f64,
pub gate_decisions: Vec<GateDecisionRef>,
pub max_gate_decisions: Option<u32>,
}
pub struct AdmissibilityWitness {
pub proposal_id: String,
pub actor: ActorId,
pub capability_id: String,
pub authority_ok: bool,
pub contract_ok: bool,
pub effect_ok: bool,
pub barrier_increment_ok: bool,
pub risk_budget_ok: bool,
pub decision: AdmissibilityDecision,
pub recovery_class: Option<RecoveryClass>,
}
pub struct WorkflowPotential {
pub workflow_id: String,
pub accepted_energy: f64,
pub rho_gate: f64,
pub remaining_budget: u32,
pub potential: f64,
}
pub struct ModelRoute {
pub phase: AgentPhase,
pub requested_tier: Option<ModelTier>,
pub resolved_tier: ModelTier,
pub model: String,
pub fallback_model: Option<String>,
pub budget: ModelBudget,
pub reason: String,
}
pub struct ExplorationReport {
pub report_id: String,
pub model_route: Option<ModelRoute>,
pub project_map: ProjectMap,
pub domain_evidence: Vec<DomainActivationEvidence>,
pub adapter_evidence: Vec<AdapterActivationEvidence>,
pub graph_hints: Vec<GraphHint>,
pub verifier_recommendations: Vec<VerifierSuiteRef>,
pub input_witnesses: Vec<StateWitness>,
}
pub struct ParallelWorkItem {
pub work_id: String,
pub parent_activity_id: String,
pub node_id: Option<String>,
pub generation: Option<u32>,
pub role: AgentRole,
pub dependencies: Vec<WorkDependency>,
pub required_leases: Vec<LeaseRequest>,
pub capability_refs: Vec<String>,
pub model_route: Option<ModelRoute>,
}
pub struct ExecutionLease {
pub lease_id: String,
pub holder_work_id: String,
pub kind: LeaseKind,
pub scope: LeaseScope,
pub expires_at: Option<i64>,
}
pub enum SchedulerEffect {
CommitNode { node_id: String, generation: u32 },
RequeueNode { node_id: String, generation: u32, reason: String },
ApplyGraphRevision { revision_id: String },
SpawnWork { work_id: String },
CancelWork { work_id: String, reason: String },
RequestApproval { proposal_id: String },
StopWithCertificate { certificate_id: String },
}
Implementation phases are SDK-first: perspt-sdk is the foundation and
perspt-coding is its first consumer, so every contract is exercised by a
real domain package and an SDK contract test as it lands rather than designed
ahead of any consumer. Later domain packages reuse the same contracts. Each
phase is independently shippable, is independently useful, and activates a named
conformance gate.
- Phase 0: Audit, SDK Skeleton, and Contract Tests
Add the
perspt-sdkandperspt-codingcrates with the domain-package trait surface, and wireperspt-sdktosrbnandsrbn-serdefor the stabilization loop and trace serialization in place of hand-rolled kernel logic. Add failing tests for static topo snapshot execution, repair-action requeue, capability denial, replay reconstruction, and SDK/domain boundary violations. These tests define the bug surface and the SDK boundary before the capabilities below are built.- Phase 1: Quadratic Residual Energy and Measured Gate
In
perspt-sdkadd residual types with raw non-negative magnitudes, finite-score validation, and the canonical energyV = sum_e w_e r_e^2with component rollups as derived projections. Map existing verification results into residual events through the coding package. AddEnergyModel, gate-decision, accepted-trajectory, residual-certificate, and finite-decision-bound records, comparing descent against the best accepted energy. Wire the kernel adapter and the prompt compiler to dominant residuals. This phase activates Gate A and Gate B.- Phase 2: Parallel Mutable Scheduler
Replace the topological snapshot loops with a dependency-aware ready-queue scheduler in the SDK runtime. Add worker pools, leases, cancellation, and join events. Convert repair actions into scheduler effects and graph revisions. Ensure inserted or reset nodes execute. Parallelism is complete only when noncommuting durable effects serialize on the read/write footprint and commuting read-only/verifier work can proceed concurrently with replayable spawn/join/cancel events. This phase activates Gate C.
- Phase 3: Capability Kernel
Add capability records, command IR, admissibility decisions, attenuation checks, and state witnesses in
perspt-policy, with coding capability templates supplied byperspt-coding. Route all tool effects through the kernel. This phase activates Gate E.- Phase 4: Replay Ledger and Durable Obligations
Add event-sourced persistence, the kernel-refusal rule enforced at the SDK effect boundary, the replay verifier, and the six durable-execution obligations. Convert existing step, correction, energy, and artifact tables into the new event stream or replace them with projections over it. This phase activates Gate F.
- Phase 5: Spectral Diagnostic and Verifier Independence
Compute the spectral energy-slope constant
mufrom the verification graph off the critical path and expose its sensitivity to candidate verifier edges. Measure pairwise validator miss correlation from the ledger and weight residuals by measured independence, surfacingrho_eff. This phase activates the required portion of Gate G.- Phase 6: Coding Verifier Suites
In
perspt-codingimplement the Rust verifier suite first, then Python and JavaScript/TypeScript, with AST/symbol/import graph extraction and correction-direction mappers through the SDK verifier-suite traits. PSP completion requires the first-party Rust, Python, and JavaScript/TypeScript suites to satisfy Gate D, even if Rust is implemented first.- Phase 7: Exploration and Model Routing
Add read-only exploration reports,
explorer_modelconfig,--explorer-model,--explorer-tier,--exploration-only, and exploration budgets. Default Explorer routing to the Speculator tier unless explicitly configured. Exploration output must be structured evidence with input witnesses, not free-form summary text that bypasses residual scoring.- Phase 8: Calibrated Risk Budgets
Add conformal calibration of validator acceptance thresholds from the ledger, the delayed unsafe label sourced from undo/redo and regression residuals, and the calibration drift monitor with graceful back-off. This phase activates Gate I and is required only when autonomous commitment without per-effect approval is enabled.
- Phase 9: UX and Web Observability
Expose graph revisions, residuals, capabilities, active workers, blocked dependencies, model routes, observed/accepted trajectory, the backlog gauge, and residual certificates in TUI, CLI, and dashboard. This phase activates Gate H.
- Phase 10: CLI Domain Routing and Second-Domain Readiness
Make domain selection explicit in the CLI and confirm the SDK contracts admit a second domain package without forking the scheduler, admissibility kernel, residual model, replay ledger, or dashboard event model. A research or website-builder package skeleton should compile against the SDK as the readiness check for later domains.
- Phase 11: Mechanism Checks and Benchmarks
Ship deterministic mechanism checks, SDK contract tests, and coding language fixture benchmarks. Publish results with failures preserved.
Implementation Status
Note
This section tracks what is actually wired into the live perspt agent
execution path as of 2026-06-22, so the phase list above can be used as a
review checklist. The distinction that matters is SDK contract implemented
(a module exists and is unit-tested in perspt-sdk) versus wired into the
orchestrator (invoked during a real run in
perspt-agent::orchestrator). Several contracts are implemented in the SDK
but not yet consumed on the live path; these are marked Not wired.
Phase |
Gate |
Status |
Notes |
|---|---|---|---|
0 — Audit, SDK skeleton, contract tests |
— |
Done |
|
1 — Quadratic residual energy + measured gate |
A, B |
Done |
V = ∑ewe‖re‖2 via |
2 — Parallel mutable scheduler |
C |
Partial |
Mutable ready-queue ( |
3 — Capability kernel |
E |
Partial |
|
4 — Replay ledger + durable obligations |
F |
Partial |
A Merkle ledger, durable session store, and resume exist
( |
5 — Spectral diagnostic + verifier independence |
G |
Not wired |
|
6 — Coding verifier suites |
D |
Done |
Rust, Python, and JavaScript/TypeScript language adapters
( |
7 — Exploration + model routing |
— |
Not started |
No |
8 — Calibrated risk budgets |
I |
Not wired |
The SDK |
9 — UX + web observability |
H |
Partial |
|
10 — CLI domain routing + second-domain readiness |
— |
Partial |
|
11 — Mechanism checks + benchmarks |
— |
Partial |
SDK |
Resolving Gate G
Gate G’s spectral and independence computation is a Phase-5 task and is explicitly a diagnostic, not an acceptance-gate input — it must be computed off the critical path and must never block dispatch or the gate (see Gate G above). Wiring it into active execution therefore requires no change to the acceptance gate, only the addition of an off-path diagnostic emitter:
Assemble the verification graph per revision. Map each node’s residual sensors — already tagged with
IndependenceRoute— tospectral::VerificationEdgevalues weighted by theEnergyModelclass weights, and build aVerificationGraphon each graph-revision commit.Compute and record
graph.mu(tol)(andedge_mu_sensitivityfor candidate verifier edges, to distinguish an independent verifier that raises the spectral gap from a redundant one). Persistmuwith its source revision to the ledger (StabilityClaim.mu).Compute
rho_effviaindependence::computefrom the ledger’s per-validator verdict history and surface it inperspt statusand the dashboard in place of any raw validator count.
All three run asynchronously / on revision commit and never gate a node, so they can land without touching convergence semantics.
Conformance Acceptance Criteria
The PSP implementation is accepted only when the conformance gates above are backed by tests and observable ledger evidence. In particular:
every supported domain package declares a residual schema and energy model;
every verifier output is converted into typed residual evidence or an explicit degraded-sensor residual;
every candidate has a recorded energy score, gate decision, correction route, and accepted/observed trajectory classification;
every residual certificate contains final residuals, energy, budgets, verifier routes, rejected attempts, correction directions, and ledger head;
every effect has an admissibility witness and capability consumption record;
every graph revision validates acyclicity and records the evidence that caused it;
every replay reads recorded observations rather than re-running nondeterminism;
every dashboard projection is derived from ledger events, not side-channel runtime state;
every analytic stability display is backed by a
StabilityClaimor markedNotClaimed.
Requirement-to-code trace:
Requirement |
Current surface |
Required change |
|---|---|---|
SDK/domain split |
Domain-neutral SRBN control plane is mixed with coding-agent and language-plugin concerns |
Add |
Mutable work graph |
|
Introduce ready-queue scheduler and graph revisions |
Cheap repository exploration |
Planning and speculator lookahead exist, but no read-only exploration phase or exploration model route |
Add Explorer/Scout phase using |
Parallel dependent work |
Node execution and repair flow are effectively serialized around one topo walk |
Add dependency-aware worker pool, leases, cancellation, join events, and concurrency limits |
Repair actions create executable work |
|
Return scheduler effects and requeue/execute new generations |
Residual-directed correction |
Verification results and diagnostics feed prompt text |
Persist typed residual events and correction directions |
Coding verifier suites |
Language plugins expose verifier commands and correction contracts |
Move language adapters into |
Capability kernel |
Tools and commands pass through sanitization/policy checks |
Add proposal/effect split, capabilities, state witnesses, risk budgets, and command IR |
Deterministic replay |
Ledger stores sessions, energy, steps, corrections, bundles, rewrites |
Add event-sourced replay log covering every proposal, observation, decision, and effect |
SRBN kernel semantics |
Energy/convergence implemented directly in orchestrator |
Introduce shared kernel adapter with finite scores, descent gate, statuses, and traces |
Useful coding-agent UX |
TUI/dashboard show logs, DAG, energy, decisions |
Add plan/build/review modes, residual vectors, graph revisions, capability prompts, undo/redo |
Rationale
Why SDK-first rather than plugin-first? The SRBN papers describe a control discipline, not a language-extension mechanism. Mutable scheduling, residual scoring, capability confinement, replay, model routing, and dashboard projections are useful for coding, research, website building, and other long-running task domains. If those concepts live behind language plugins, every non-coding domain either misuses the plugin layer or reimplements the control plane. SDK-first keeps the stability contract central and lets each domain package define SDK-native adapters for its own sensors, artifacts, and correction routes.
Why a mutable graph instead of abandoning DAGs? The SRBN papers use a DAG because each accepted graph revision needs an acyclic dependency topology. The problem is not acyclicity; the problem is pretending the initial graph is final. A revisioned acyclic work graph preserves the sheaf/topology discipline while allowing real coding discoveries to change scope.
Why residuals instead of raw logs? Logs are evidence for humans. Residuals are evidence for control. SRBN needs measurable residuals with scores, components, sensors, and correction directions so the controller can target the dominant failure instead of issuing a generic retry.
Why a cheap exploration phase? Existing repositories usually require broad orientation before the right node boundaries, verifiers, and context slices are known. That orientation is mostly read-only summarization and indexing, so it should be able to use a lower-cost model such as the Speculator tier without weakening acceptance gates, which still depend on deterministic barriers and residual descent.
Why parallelism with leases? Paper III only requires serialization for non-commuting durable commits. Repository search, LSP queries, AST extraction, independent verifier runs, and unrelated node attempts can safely overlap if their dependencies, capabilities, and state witnesses are explicit. Leases make the boundary auditable instead of relying on informal scheduling discipline.
Why capabilities instead of more command allowlists? Paper III’s confinement results require authority to be an explicit attenuable value. A command allowlist is useful, but it does not by itself answer who proposed the effect, which node needed it, which scope it touches, whether the state changed since approval, or whether the actor delegated authority safely.
Why coding language adapters? Useful coding agents succeed or fail on
repository-native feedback. Rust, Python, and TypeScript have different module
systems, package managers, test discovery, and correction patterns. Hardcoding
those in the orchestrator weakens reliability, while making them the global
plugin architecture weakens reuse. They belong in perspt-coding as SDK
verifier-suite adapters.
Why keep coding-agent ergonomics in scope? The SRBN system still needs usable workflows: plan mode, project instructions, search/read/edit tools, approval, undo, and clear status. These are not theoretical luxuries; they are the daily ergonomics that make users trust a coding agent. Perspt’s goal is to make those workflows reliable through accepted-state gates, residual-directed correction, capability confinement, and replayable history.
Alternatives considered:
Keep the static DAG and only improve verifiers. Rejected: verifier evidence often proves the graph itself is wrong.
Keep plugin-first architecture and add more plugin traits. Rejected: language plugins are suitable for compiler/LSP/test integration, but not for research evidence, website screenshots, deployment checks, replay schemas, or capability confinement. A growing plugin trait would become an accidental SDK with weaker boundaries.
Use Architect for all repository exploration. Rejected: broad read-only orientation should not consume the most expensive tier by default, and acceptance should not depend on the exploration model’s authority.
Run every ready node in parallel. Rejected: “ready” by dependency order is not enough. Nodes can still conflict through files, manifests, public interfaces, toolchains, migrations, or state witnesses.
Use an unconstrained dynamic task list. Rejected: loses the SRBN topology, ownership, and sheaf validation contracts.
Let the LLM directly choose shell commands. Rejected: too much authority is hidden in strings, and replay/admissibility become weak.
Rely on same-model self-critique as verifier. Rejected: it is a useful fallback but not an independent barrier.
Hide residual details from users. Rejected: Perspt’s differentiator is inspectable stability, not opaque autonomy.
Breaking Changes and Migration
This PSP intentionally permits breaking changes. The SDK/domain split is a clean architecture boundary, not a compatibility layer over the current orchestrator and language-plugin model.
Required breaking changes:
perspt-sdkbecomes the canonical public agent API for SRBN state, residuals, graph scheduling, capabilities, replay, and domain packages.perspt-codingbecomes the owner of coding-specific behavior. Rust, Python, and JavaScript/TypeScript integrations move out of the generic runtime.The existing language-plugin ABI may be removed. New coding adapters implement SDK verifier-suite traits directly.
The old topological scheduler may be removed once the mutable ready-queue scheduler is available behind tests.
The old session/event schema does not need to remain readable. A one-way migration command may be provided, but replay correctness applies only to the new event-sourced ledger.
Command policy configuration may be replaced by capability policies and command IR rules.
Direct shell execution behavior becomes stricter and routes through explicit
RunShellproposals.Legacy prompt-template entry points may be deleted once the typed prompt compiler owns all prompt families.
CLI defaults may change to expose explicit domain selection, concurrency, and capability policy.
Dashboard and TUI views may be rebuilt on top of new ledger projections rather than preserving old event shapes.
Migration guidance:
Preserve concepts from PSP-5 and PSP-7 when they remain valid: artifact bundles, typed parse states, budget envelopes, energy components, correction telemetry, and dashboard observability.
Do not preserve old module boundaries merely to avoid churn. Move behavior to the crate that owns the new responsibility.
Treat old tables, events, plugin methods, and command strings as source material for migration tests, not as stable APIs.
Provide clear release notes and config validation errors for removed fields, but prefer a correct SDK architecture over silent compatibility behavior.
Users should see stricter denials and more explicit residual certificates. That is intentional. False success is worse than visible non-convergence.
Reference Implementation
Initial implementation should be narrow and test-driven, SDK-first, with
perspt-coding as the first consumer that exercises each contract as it
lands:
Add the
perspt-sdkandperspt-codingcrates with the domain-package trait surface, and wireperspt-sdktosrbnandsrbn-serde.Add
ResidualEventwith raw non-negative magnitudes and map existingVerificationResultinto residuals through the coding package.Implement the canonical energy
V = sum_e w_e r_e^2with component rollups as derived projections, the measured gate against the best accepted energy, gate decisions, accepted trajectory records, residual certificates, and the finite-decision bound.Add a failing unit/integration test showing that a node inserted by
NodeSplitorInterfaceInsertionis not executed by the current topo snapshot loop.Add a ready-queue scheduler behind an experimental flag:
--scheduler mutable.Convert
RewriteActionhandling to produceSchedulerEffect.Add worker-pool and lease tests for two independent verifier tasks, one dependent task, and two conflicting manifest mutations, including capability and budget footprints.
Add capability records for read/search/write/run-verifier/run-shell and route
AgentToolsthrough admissibility checks.Add event rows for proposal, admissibility, residual, graph revision, exploration report, parallel task lifecycle, lease lifecycle, and accepted candidate, with the kernel-refusal rule for unrecorded observations.
Compute the spectral constant
mufor a synthetic verification graph and measure validator miss correlation from the ledger.Implement Rust unresolved-import and missing-module correction directions.
Add an exploration model-routing test showing
--explorer-modelwins overspeculator_modeland that absent overrides route Explorer to Speculator.Add a read-only exploration report for Rust workspaces: package roots,
cargo metadatasummary, module/test hints, and adapter activation evidence.Add dashboard panels for residuals, graph revisions, active workers, blocked dependencies, the backlog gauge, and model routes.
Make domain selection explicit in the CLI and confirm a second domain package compiles against the SDK contracts without forking the scheduler, kernel, residual model, ledger, or dashboard event model.
Add mechanism checks as CI tests, then remove the experimental flag after parity with current project mode is reached.
Testing strategy:
unit tests for residual scoring and non-negative finite validation;
unit tests for
V = sum_e w_e r_e^2with deterministic synthetic residuals;unit tests for hard-pass, descent-pass, non-descending rejection, declared floor, and exhausted-certificate gate decisions;
unit tests for the finite-decision bound
floor(V_0 / rho_gate) + B + 1;unit tests for
srbnadapter terminal statuses andsrbn-serdetrace serialization round trips;unit tests for stability-claim calculations:
V_inftyand discrete step-size precondition checks;SDK contract tests for domain package registration, context packages, verifier suites, residual mapping, and dashboard projections;
unit tests for exploration model routing and budget enforcement;
unit tests proving read-only exploration cannot acquire mutation capabilities;
unit tests for graph revision acyclicity and node generation lineage;
scheduler tests for inserted-node execution, requeued descendants, and budget exhaustion;
scheduler tests for parallel ready work, dependent wait states, lease conflicts, task cancellation, and accepted-commit serialization;
coding-adapter tests for Rust/Python/TypeScript verifier-suite residuals;
command IR canonicalization tests;
admissibility-witness tests covering authority, contract, effect, barrier-increment, and risk-budget clauses;
capability attenuation and denial tests;
replay round-trip tests;
TUI/dashboard snapshot tests for residual and graph revision rendering;
end-to-end fixture tasks for each first-party coding language adapter.
Open Issues
Graph merge semantics: Node splitting is straightforward; merging sibling nodes after discovering a shared root cause needs careful ownership rules.
Risk budgets: Paper III supports calibrated budgets, but Perspt may start with deterministic risk classes and add statistical calibration later.
External documentation access: Researcher agents need web/documentation capabilities, but network access should remain explicit and scoped.
Domain package ABI: The first implementation can use in-process Rust packages, but the SDK should preserve enough isolation boundaries to support future WASM or process-isolated packages.
Explorer tier shape: Explorer can be a first-class
ModelTieror a phase routed to Speculator. The first implementation should probably avoid a new tier until routing pressure proves it is needed.Parallel conflict granularity: File-level leases are simple but may be too conservative. Symbol/interface-level leases are more precise but require stronger coding-adapter evidence.
Event schema size: Full replay logs can grow quickly. Perspt needs compaction that preserves accepted trajectory and replay-critical observations.
Learned barriers: This PSP focuses on deterministic and tool-based barriers. Learned verifier models can be added later if their independence, calibration, and evidence routes are recorded.
Project instruction import: Perspt should read existing project instructions when useful, but it must hash and provenance-track any imported instructions.
References
The paper references point to local PDF builds until the manuscripts have stable publisher metadata. Future revisions should replace these entries with DOI, publisher, or archival metadata when available.
Rathore, Vikrant. Stability is All You Need I. Forthcoming. Reviewed PDF:
../../insan.ai/sayn/paper/dist/stability_is_all_you_need_I.pdf. Relevant concepts: SRBN foundations, sheaf consistency, Lyapunov energy, accepted trajectory, Merkleized state, discrete stability, and validation protocol.Rathore, Vikrant. Stability is All You Need II. Forthcoming. Reviewed PDF:
../../insan.ai/sayn/paper/dist/stability_is_all_you_need_II.pdf. Relevant concepts: harness contract, residual vectors, observable descent gate, provider portability, verifier independence, and residual-certified termination.Rathore, Vikrant. Stability is All You Need III. Forthcoming. Reviewed PDF:
../../insan.ai/sayn/paper/dist/stability_is_all_you_need_III.pdf. Relevant concepts: platform contract, capability-constrained control, admissibility kernel, recovery termination, replay determinism, coordination minimality, and platform-level Foster-Lyapunov stability.srbncrate, reviewed local version0.1.1. Published package: crates.io/crates/srbn. Source repository: codeberg.org/insanai/srbn-rust. Reviewed source:../../insan.ai/sayn/projects/rust/srbn. Relevant concepts: minimal SRBN kernel,run/stabilizeloops, finite residual scores, barrier results, attempt traces, and terminal statuses.srbn-serdecrate, reviewed local version0.1.1. Published package: crates.io/crates/srbn-serde. Source repository: codeberg.org/insanai/srbn-rust. Reviewed source:../../insan.ai/sayn/projects/rust/srbn-serde. Relevant concepts: serde and serde_json helpers for SRBN trace types.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.