AVALANCHEAI
Phase 1 liveUpstream
DocsRuntimeArchitecture12 min read

Avalanche AI Architecture

Avalanche AI is one shared agent runtime hosting seven Avalanche intelligence domains on top of the DeepSeek Harness. This document is the ordered map of that runtime: what each layer owns, how a task flows through it, and where each decision is enforced. It assumes the upstream composition model described in UPSTREAM_AUDIT.md.

Shape of the composition

dsh --profile avalanche
└── profile layers
    ├── @deepseek-ai/dsh-base          upstream: LLM, sessions, tools, prompts, approvals
    └── @deepseek-ai/dsh-avalanche-app fork: cordis.patch.yml (one insert block)
        ├── avalanche-context          layered execution context (project → execution)
        ├── avalanche-memory           layered memory (working → long-term)
        ├── avalanche-policy           default-deny capability policy + approvals
        ├── avalanche-verification     named verifier registry
        ├── avalanche-evidence         hash-chained ledger + receipts
        ├── avalanche-tooling          tool catalog + executor-level policy gate
        ├── avalanche-network          network registry + read-only RPC tools + chain-id verifier
        ├── avalanche-agents           domain descriptor registry + deterministic routing
        ├── avalanche-domain-developer … avalanche-domain-defi   (7 descriptor plugins)
        ├── avalanche-orchestrator     intent → policy → plan → tools → verify → receipt
        ├── avalanche-cli/startup      commander parser; publishes the accepted invocation
        └── avalanche-cli              runner; injects runtime services and executes it

Nothing in the list is a separate process or a separate runtime. Every domain is a data descriptor registered into the same avalancheDomains service; every tool is registered on the same ctx.tools; every policy check crosses the same avalanchePolicy; every record lands in the same avalancheEvidence ledger.

Services

ServicePackageResponsibility
avalancheContextavalanche-contextSix-layer context store (project, repository, network, user, task, execution) with precedence resolution and origin on every write
avalancheMemoryavalanche-memoryFive-tier memory (working, episodic, semantic, procedural, long-term) with deterministic lexical recall and optional durable store
avalanchePolicyavalanche-policyCapability-based, default-deny rule evaluation; approval request/decide/consume bound to a request fingerprint
avalancheVerificationavalanche-verificationNamed verifiers; unknown kind is unverifiable, never verified
avalancheEvidenceavalanche-evidenceAppend-only hash-chained ledger; subscribes to tools/result; issues tamper-evident receipts; optional JSONL mirror
avalancheToolingavalanche-toolingRisk-annotated tool catalog; registers tools on ctx.tools; tools/pre-execute gate; fails closed when policy is absent
avalancheNetworksavalanche-networkNetwork descriptors (fuji 43113, mainnet 43114, local 43112); read-only JSON-RPC allowlist; five read tools; chain-id verifier
avalancheDomainsavalanche-agentsDomain descriptor registry; keyword scoring and deterministic match()/best(); per-agent prompt and tool mask installation
avalancheOrchestratoravalanche-orchestratorTask lifecycle, durable task records, agent dispatch, verification, receipt issuance

Execution lifecycle

The runtime implements the fixed lifecycle the Avalanche AI brief requires:

INTENT → POLICY CHECK → EXECUTION PLAN → TOOL EXECUTION → SIMULATION → APPROVAL → EXECUTION → VERIFICATION → EVIDENCE RECEIPT

What each stage means in this build, and where it happens:

  1. INTENT. avalancheOrchestrator.submit() turns the objective into an IntentSpec: id, objective, action, capability set derived from the owning domain descriptor, constraints, expected outcomes, risk, and optional network. The intent is recorded in the ledger before any decision.
  2. POLICY CHECK. avalanchePolicy.evaluate() unions the rules matching the requested capability classes and takes the strictest verdict (deny > require-approval > allow). Baseline rules allow chain:read, code:generate, and chain:simulate; park local:write, local:execute, tx:prepare, tx:sign, chain:write, infra:operate behind approval; deny tx:sign, chain:write, and infra:operate on mainnet; deny any uncovered capability (default-deny); and deny any request whose declared risk is below the risk of its capabilities (risk-understatement).
  3. EXECUTION PLAN. The orchestrator selects up to maxSteps domains through avalancheDomains.match() (or one forced domain) and creates one plan step per domain. Routing is lexical and deterministic: the same objective always produces the same plan, and the matched keywords are inspectable.
  4. TOOL EXECUTION. The orchestrator creates an agent through ctx.agents, installs the domain prompt section and tool mask in the agent scope, and drives one turn. Every tool call passes through avalancheTooling's tools/pre-execute gate, which builds the policy request from the tool's risk profile and the network argument the call names.
  5. SIMULATION. For read-only capabilities the simulation stage is empty by construction. chain:simulate is an allowed capability class reserved for later fork simulation; no simulation adapter ships in this phase.
  6. APPROVAL. A require-approval verdict parks the task in awaiting-approval with an approval record. avalanchePolicy.grant() performs an explicit operator request+decision; decide() refuses to overwrite a decision; consume() makes an approval single-use. Task resume after approval is Phase 5 work with the write execution path.
  7. EXECUTION. In this phase execution is read-only tool execution. Write, sign, and infrastructure execution are deliberately absent; the policy engine denies them at the gate before any executor exists.
  8. VERIFICATION. avalancheVerification.verify('chain-id', ...) asks the network registry what the endpoint reports and compares it with the descriptor's declared chain id. The verdict, detail, and observed facts are recorded. Unknown network, missing registry, or missing network on the task yields unverifiable, never verified.
  9. EVIDENCE RECEIPT. avalancheEvidence.issueReceipt() digests the receipt content (SHA-256 over canonical JSON of every other field), appends it to the ledger, and returns it. The receipt cites the evidence record ids that support it and carries the fixed disclaimer: it attests that policy evaluation passed and evidence is unmodified; it does not attest that model reasoning, generated code, or operator intent was correct.

Enforcement points

  • Tool registration: only avalancheTooling.register(spec) registers an Avalanche tool, and registration requires a risk profile. avalancheNetworks.registerTools() throws if the catalog is not mounted, so an uncatalogued tool cannot appear by accident.
  • Policy: the gate is a tools/pre-execute listener registered in AvalancheTooling[Service.init]. It runs in the executor pipeline, after tool lookup and before dispatch, for every caller. It is not a prompt instruction, not schema filtering, and not a UI state.
  • Network: the RPC transport refuses any method not on READ_ONLY_RPC_METHODS; the mainnet descriptor has writeEnabled: false; network-bound policy resolves the network named by the tool argument at call time and denies unresolvable or unknown networks.
  • Domain tool masks: AvalancheDomains.install(agentCtx, domainId) applies ctx.tools.restrict() inside the agent scope, so a domain cannot call tools outside its descriptor's allow/deny lists.
  • Secrets: the runtime never reads private keys and has no signing tool or key material in any schema. There is no field in the context, task, or receipt schema that can carry a private key.

Data and persistence

  • Task records: one JSON file per task under tasksDir when configured (the avalanche profile derives $DSH_HOME/profiles/avalanche/avalanche/tasks), written through a serialized queue and reloaded at startup.
  • Evidence ledger: in-memory hash chain mirrored to $DSH_HOME/profiles/avalanche/avalanche/evidence.jsonl; each record appends on commit in chain order; startup reloads and re-verifies the chain.
  • Receipts: stored both as queryable objects and as receipt-kind ledger records, so they survive process restarts.
  • Sessions: upstream session persistence records the agent conversation; evidence records the execution facts. The two are linked by task id but never conflated.

Model-provider neutrality

Nothing in the Avalanche layer names a provider. The orchestrator reads agentDefaultModel.currentSelection() and passes it to agents.create; the model selection itself is an upstream concern (AgentDefaultModelConfig or a profile override). Domain routing is lexical, not model-based. A different adapter, a local model, or a mock all work without changing any Avalanche package.

What is deliberately not built

  • No Next.js. The dashboard is Vite + React + TypeScript (Phase 4), and no Avalanche package depends on a server-side rendering framework.
  • No microservice split. The modular boundaries are packages and services in one process; a service can become a process boundary later without changing its consumers.
  • No write path, no signing, no key handling: denied by policy and absent from code.
  • No fabricated chain data: every chain fact in a task originates from a tool result recorded by the executor, and the verification verdict is independent of the model's text.

Package dependency direction

avalanche-schemas is the leaf (types, digests, risk ordering). avalanche-context, avalanche-memory, avalanche-policy, and avalanche-verification depend only on schemas (and Cordis). avalanche-evidence depends on schemas and the tools event types. avalanche-tooling depends on policy, schemas, and tools. avalanche-network depends on tooling, schemas, tools, and verification. avalanche-agents depends on schemas. The seven domain packages depend on avalanche-agents. avalanche-orchestrator depends on agents, evidence, network, policy, and verification types. avalanche-cli depends on every service package because it reads all of them. avalanche-app depends on the whole set and ships only cordis.patch.yml.