ValorSystem Docs

01 · The runtime spine

Bridge, worker, runner

Three moving parts turn a message into execution. The bridge hears you. The worker runs the queue. The runner does the thinking. Each stays in its lane, and the seams between them are what make the system durable.

Human Telegram · email Bridge Telethon · I/O only Redis AgentSession record Worker sole execution engine Session Runner claude -p per turn PM · Dev · Teammate message enqueues pulls queue runs turn output → Redis outbox → bridge delivers the reply heartbeats · recovery

The spine of the system. Everything between the human and the runner is a durable seam, not a function call.

1 · Ingestion

The bridge only listens

The bridge connects to Telegram (via Telethon) and email (IMAP/SMTP), receives each incoming message, and hands it off. That is all it does. It claims the message, decides whether it resumes an existing session or starts a fresh one, and enqueues an AgentSession for the worker.

The bridge knows nothing about the SDLC pipeline. Keeping ingestion deliberately dumb is what lets execution live somewhere else entirely: a session can run on a different machine than the one that received the message.

2 · Execution

The worker is the one engine

Once a session is queued, the standalone worker is the only thing that executes it. Its entry point configures logging, loads project config, and runs an async loop that pulls sessions off the queue, supervises heartbeats, and delivers output.

On startup it recovers orphaned or crashed work: it rebuilds indexes, cleans corrupted records, sweeps dead workers, and resumes sessions that were mid-flight when a process died. Because the worker is a separate service, a session survives a bridge restart.

3 · The record

AgentSession, the durable envelope

Everything the worker runs is an AgentSession: the saved record of one unit of work. It holds the session's identifiers, chat history, per-stage pipeline state, and lifecycle status across 14 states. The bridge, worker, hooks, and dashboard all read and write this one record.

Because the work is a record and not a live process, it can be paused, resumed, steered, and moved between machines.

4 · Thinking

The session runner, where it thinks

The runner drives a per-turn loop. Each turn spawns a fresh claude -p subprocess through the SDK client, which composes the persona system prompt and manages the headless Claude Code harness. At each turn boundary the loop drains steering messages and routes the output onward.

Three hats, one runner

The role_driver primes one of three personas for each turn.

RoleOwnsCharacter
PM Orchestration. Reads the conversation, decides what the work is, and routes it. Steers the SDLC pipeline stage by stage. Decides, delegates, reports back.
Dev Execution. A resumable subagent the PM spawns once and continues across turns. Writes the code, runs the tests, opens the PR. Full permissions, engineer persona.
Teammate Conversation. Answers questions and handles non-code requests. Source-code writes redirect to an Eng session. Open Bash, audit-logged, restricted writes.

5 · Foundations

Configuration and personas

The runner needs to know which model to use and which persona to wear. A Pydantic settings hierarchy defines every runtime configuration group: API keys, Telegram, Redis, models, features, paths. config/models.py resolves which generation model to use based on host RAM and cloud tags. The persona documents are the operating manuals injected into each turn.

These files are foundational. config/models.py has the highest fan-in in the whole graph: nearly everything depends on it.

6 · The return path

Output routing and steering

After a turn produces output, three pieces close the loop back to the human. output_router is pure decision logic: given the stop reason and nudge counts, it decides whether to deliver, nudge, or suppress a message. The steering module is a Redis-backed inbox for injecting mid-session messages into a running session, drained at turn boundaries. The message drafter composes and validates the actual user-facing reply, extracting open questions.

A session only pauses for a genuine open question. A status update with no question gets an automatic "continue", and the work keeps moving.

Previous← Overview NextThe Ten Layers →