Skip to main content

Crate agentplane

Crate agentplane 

Source
Expand description

§agentplane

A durable, replayable, policy-governed runtime for agents whose steps invoke non-deterministic models and mutate real systems.

One sentence carries the rest:

The journal is the plan of record. Orchestration is deterministic and replayable; every non-deterministic act — inference, tool call, clock, RNG, deadline resolution — is an Effect performed at most once, journaled, and read back on replay.

§The determinism boundary

┌──────────────── DETERMINISTIC ZONE ────────────────┐
│ plan traversal · guards · retry decisions · budget  │
│ policy evaluation · label joins · record upcasting  │
│                                                     │
│ Replay re-executes this and MUST reproduce the      │
│ identical sequence of effect keys.                  │
└───────────────────────┬─────────────────────────────┘
                        │ cx.effect(…)
┌───────────────────────▼─────────────────────────────┐
│            NON-DETERMINISTIC ZONE                    │
│ inference · tools · clock · RNG · network · humans   │
│                                                      │
│ Executed at most once. Journaled. Replay reads.      │
└──────────────────────────────────────────────────────┘

Two layers enforce it, because convention is not enforcement:

  1. Lint gating — clippy.toml denies SystemTime::now, Instant::now, OffsetDateTime::now_utc, rand::random, rand::rng and Ulid::generate crate-wide. It covers this crate, not a skill compiled in yours.
  2. Effect-key verification — on replay, a recomputed key that differs from the journaled one quarantines the run rather than diverging silently (core::StepError::NonDeterminism).

§Example

use agentplane::core::{Outcome, Skill, SkillDescriptor, Tainted};
use agentplane::journal::JournalStore;
use agentplane::runtime::{Mode, RunStatus, Runtime, StepCtx};
use std::sync::Arc;

#[derive(Debug)]
struct Greet;

#[async_trait::async_trait]
impl Skill for Greet {
    fn descriptor(&self) -> SkillDescriptor {
        SkillDescriptor::new("greet").provides("demo.greet")
    }

    async fn invoke(
        &self,
        cx: &mut StepCtx<'_>,
        input: Tainted<serde_json::Value>,
    ) -> Result<Outcome, agentplane::core::SkillError> {
        // `now()` is a journaled effect: on replay it returns the recorded
        // instant rather than reading the clock again.
        let at = cx.now().await?;
        Ok(Outcome::done(input.map(|v| serde_json::json!({
            "greeted": v, "at": at.to_string(),
        }))))
    }
}

// With the default features, `agentplane::store::RedbStore` is one.
let runtime = Runtime::builder(store).skill(Greet).build();
// Runs are asked for by capability — what the skill `provides`.
let outcome = runtime.run("demo.greet", Tainted::trusted(serde_json::json!({"name": "world"}))).await?;
assert!(matches!(outcome.status, RunStatus::Succeeded), "{:?}", outcome.status);

// Replaying re-executes the deterministic zone and reads every effect back
// from the journal. No clock is read; no tool is called twice. `Strict`
// additionally fails if this build wants an effect the journal lacks.
runtime.replay(outcome.run_id, Mode::Strict).await?;

Re-exports§

pub use crate::core::Capability;
pub use crate::core::CaseId;
pub use crate::core::Digest;
pub use crate::core::EffectKey;
pub use crate::core::Label;
pub use crate::core::Outcome;
pub use crate::core::Recovery;
pub use crate::core::RunId;
pub use crate::core::RuntimeError;
pub use crate::core::Sensitivity;
pub use crate::core::Seq;
pub use crate::core::Skill;
pub use crate::core::SkillDescriptor;
pub use crate::core::SourceId;
pub use crate::core::StepId;
pub use crate::core::Tainted;
pub use crate::core::Trust;
pub use crate::journal::JournalStore;
pub use crate::journal::Record;
pub use crate::journal::RecordKind;
pub use crate::runtime::Runtime;
pub use crate::runtime::StepCtx;
pub use rand;
pub use schemars;

Modules§

api
An HTTP surface for the people who have to look after a plane.
audit
Checking a plane’s history without trusting the plane.
authority
Standing authority: a ceiling that outlives a run and is narrower than a tenant.
batch
Batch runs — one plan, many items, per-item durability.
blob
Content-addressed bytes, kept out of the chain.
case
Case storage: correlation, state, obligations, and inbound events.
content
Content rules: deterministic predicates a manifest declares over a value’s strings, applied at the boundaries the plane already owns.
core
Domain-agnostic types and traits. No I/O lives here.
disclosure
A matter leaving the plane: the disclosure act, the register that holds it, and the one function that writes a package only once the act is recorded.
drill
The live half of the case-layer drill: the questions no exported file can answer.
export
Getting the record out, in a form nothing here has to be present to read.
grader_verdict
A grader’s verdict, bound to the records it was reached from.
grants
The grants an agent never used, read from an export.
journal
The journal: append-only, hash-chained run history.
keyring
Envelope encryption, and the erasure it makes provable.
manifest
The declaration an agent is built from.
media
Governed remote-media ingestion.
memory
Memory an agent keeps between runs, and the rules that keep it survivable.
model
Calling a model.
netguard
What an outbound call may do to this process.
observe
Keeping a record beside an agent this plane does not execute.
peers
Calling other agents.
plan
The plan contract.
policy
Authorization engines, the requests the runtime asks them, and the offline re-derivation of those requests from an export.
prelude
The names every program needs, so the first one is one use line.
push
Push notifications: telling a peer’s webhook that its task moved.
quota
Per-tenant ceilings on concurrent work and spend.
retention
Time-windowed erasure: the retention verb, and what it honestly cannot do.
runtime
Execution: the step context, the effect protocol, and the executor.
store
Persistence backends.
subject
Where a subject’s data went.
testkit
Test facilities for embedders, and for this crate’s own assurance layers.
tools
Calling tools on other people’s servers.

Macros§

manifests
Embed a directory of single-agent manifests, keyed by declared name.