Skip to main content

Crate fno_agents

Crate fno_agents 

Source
Expand description

fno-agents substrate crate (Phase 6, ab-a09e1eaf).

This crate is the Rust substrate for PTY-managed agents (codex / gemini / future OpenCode). It is split per the design’s Locked Decisions:

§Scope of Wave 1 (this PR)

Wave 0’s smoke prototype (cli/scripts/smoke/pty-survival/) refuted the “direct daemon-owned PTY survives daemon restart” assertion: a child on a PTY whose master the supervisor owns is SIGHUP’d and dies the instant the master closes. The locked outcome (Outcome B) is a per-agent worker process that owns the master and outlives the daemon. The substrate in this crate is therefore written worker-side: pty::PtySession is what a worker owns; the daemon (Wave 3) reconnects to workers over their sockets.

Deliberately deferred (documented seams, not gaps):

  • alacritty_terminal grid wiring + per-CLI readiness::ReadinessDetector impls -> Wave 2, alongside the smoke captures that define the grid patterns (the trait operates over readiness::ScreenView so Wave 2 only adds impls).
  • tokio runtime integration -> Wave 3 (the daemon is its only consumer; the substrate stays runtime-agnostic and is driven from spawn_blocking).

§Scope of Wave 2 (this PR)

Wave 2 fills the seams Wave 1 left:

Modules§

active_backlog
Active backlog dispatcher: the drain-tick core + circuit breaker (node x-c070).
agents_config
Read config.agents.<provider>.headless_yolo from settings.yaml (bounded-posture amendment).
claude_ask
Client-side claude --bg ask path (ab-cc926b4e).
client
Client side of the daemon protocol (Wave 3): lazy-start the daemon, connect, and forward one request. Kept in the library so it is exercised by the integration tests without shelling out to the compiled binary.
client_verbs
Client-side fno-agents verbs ported from the Python fno agents app (the “Python-only verbs” bucket: drive-authority, trace, ping, attach, resume, plus the non-streaming logs paths).
codex_ask
Client-side codex exec ask path (ab-0429c6e1).
daemon
The supervisor daemon (Wave 3, tasks 3.0 + 3.4).
drift
Daemon binary-version drift detection (ab-1891cdff).
drive
Drive surface (Wave 4, ab-8d258ddb): WebSocket-backed interactive / watch / step takeover of a PTY-managed agent.
drive_client
Client side of fno-agents drive (Wave 4, ab-8d258ddb).
envelope
Structural anti-injection envelope (design module envelope.rs, LD15).
events
Operator-facing events.jsonl emitter (Wave 3, task 3.2).
finalize
fno-agents finalize (control-plane step 6, ab-f8e5f214): the terminal-only WRITER the stop-hook shim invokes on a terminal-allow loop-check decision.
gemini_ask
Client-side gemini -p ask path (ab-73da4ac2).
grid
fno agents grid - client-side TUI compositor (ab-3c063856).
kill_criteria
fno-agents kill-check verb — Rust port of scripts/lib/kill-criteria.sh (packaging EPIC ab-8bdb4642, eliminate-don’t-vendor leg).
logs
Daemon-side agent.logs streaming handler (Category C / ab-d82655d7).
logs_client
Client side of fno agents logs <name> --follow for codex/gemini (Category C / ab-d82655d7).
loop_dispatch
Shellout dispatcher that wraps the bash driver-lib contract.
loop_megatron
Megatron driver: MegatronQueue + MegatronDispatcher + the loop run --driver megatron verb glue (group 3 of ab-ed61946d, node ab-9fd662c6).
loop_megawalk
Megawalk driver: MegawalkQueue + MegawalkDispatcher + the loop run --driver megawalk arm.
loop_runtime
Unified loop runtime primitive for target, megawalk, and megatron drivers.
loop_target
Target driver: TargetQueue + the loop run CLI verb.
loopcheck
fno-agents loop-check verb (Task 1.1, ab-d0337fbc).
nudge
P2 loop-boundary inbox nudge (ab-098967b4).
paths
~/.fno/agents/ filesystem layout (Wave 3).
protocol
Unix-socket wire format (Wave 3, task 3.1).
provider
The Provider abstraction (design module provider.rs, LD8).
pty
PTY spawn + bounded-ring output drainer (design module pty.rs).
readiness
Readiness detection (design module readiness.rs).
screen
Terminal-grid construction behind the ScreenView seam (Wave 2).
state
Shared state files (Wave 3): registry.json (schema v4) and per-agent state.json (schema v1), plus the flock-protected, atomic read/modify/write helpers the daemon and worker share.
stream_worker
Per-session stream-json worker (Group 1, Outcome B) — the claude analog of the PTY crate::worker.
subprocess_ask
Shared one-shot-subprocess primitives for the client-side ask ports (codex + gemini). Extracted from codex_ask.rs (ab-73da4ac2) so the SIGINT forwarding, process-group kill, grace reap, watchdog, and output tee live in ONE place and the PR #371/#372 hardening carveouts apply to every provider:
supervisor
Restart policy state machine (design module supervisor.rs).
verify_evidence
fno-agents verify-evidence verb — Rust port of scripts/lib/verify-event-evidence.sh (packaging EPIC ab-8bdb4642, eliminate-don’t-vendor leg).
worker
Per-agent worker shim (Wave 3, task 3.3 — Outcome B).
write_queue
Bounded-backpressure stdin queue (design module write_queue.rs).

Structs§

MonotonicTimestamp
A monotonic timestamp that counts during system sleep, used for drive-window heartbeat math (LD17 + Domain Pitfall: macOS/Linux suspend divergence).
ShortId

Enums§

AgentStatus
Agent lifecycle status. state.status is canonical; registry.status is a denormalized projection of it (LD10). Serialized snake_case for the JSON state files and the cross-language schemas.
ParsedEvent
Sealed event vocabulary every provider parses INTO (LD9). Variant additions are a one-line crate-wide change; no per-provider enums. #[serde(tag="kind")] matches the wire shape in the design’s Architecture section.
ShortIdError
A short, opaque agent identifier (e.g. wkA). Stored in the registry and used to name per-agent state directories. Validation is intentionally light at this layer; dispatch-layer validation (US1 invariant) owns argv rules.

Constants§

KNOWN_EVENT_KINDS
All real operator-facing event kinds emitted by the Rust supervisor. Excludes test-only kinds (tick, heartbeat).

Functions§

emit_schema_json
Build the Branch B (Rust/fno-agents) envelope JSON Schema and the status-v1 AgentState schema as static JSON objects.