# Prototype Specification — Treasury Paper-Portfolio Harness for IMD Swarm

**Codename:** `treasury-paper`
**Version:** 0.1 (specification only — no implementation is authorised or delivered)
**Date:** 2026-09-23
**Companion document:** `research-report.md` (findings, evidence, mandate analysis)

---

## 0. Authorisation and scope

This task authorises **research only**. This document is a specification: a description of software that could be built, written so that a later, separately authorised engineering task could build it. Nothing here is implemented, and no component described below exists today.

**Hard safety property of the design itself:** Phase 1 holds **no private keys**, controls **no funds**, and cannot place a real order. Every "execution" is a simulated fill against observed market data. The custody integration in §10 is specified so that the boundary between paper and live is explicit and reviewable — not so that it can be crossed quickly.

---

## 1. Purpose

Build the smallest system that can answer, with evidence a sceptic can reconstruct:

> Does delegating treasury decisions to a swarm of agents produce better decisions than doing nothing — after honest costs, and with an audit trail that makes self-deception structurally impossible?

The research report concludes (§8.4) that at $100,000 notional over 26 weeks, return differences between the mandates will likely be indistinguishable from noise. The prototype is therefore optimised for **process integrity and decision provenance**, not for return. A build that produces beautiful returns and a reconstructible-only-by-trusting-us audit trail has failed.

### 1.1 Design theses

1. **Integrity is binary; return is continuous.** A single decision whose commit does not predate its fill invalidates the run. Design for that property first.
2. **Refusal to act is a first-class output.** `NO_ACTION` carries a reason code, is recorded, is scored, and is the expected output most weeks.
3. **Disagreement is the product.** The valuable artefact is a calibrated record of when panel members dissented and who turned out to be right — not an allocation.
4. **Costs must be pessimistic by construction.** The system may never price a fill at mid. See §7.
5. **Illegibility is a veto.** A proposal a human signer cannot follow is rejected regardless of merit.

---

## 2. What already exists vs. what this builds

Detailed evidence is in `research-report.md` §9.2. Summary:

**Reused from IMD (no new build):** job decomposition and distribution; ERC-8004 agent identity; multi-agent parallel execution; `oracle_assess` adversarial panels; verdict lifecycle (`accepted → working → submitted → stored → verdict`); reputation (seats, accepted/rejected, rank); effort tiering (economy/standard/premium); `MerkleDistributor` payout; the public read API and explorer for provenance.

**New in this prototype:** everything in §4. The load-bearing additions are the market-data oracle, the portfolio ledger, the policy engine (including `NO_ACTION`), the commit–reveal decision log, the pessimistic execution simulator, and the disagreement ledger.

**Dependency risk, stated up front:** ERC-8004 is a **Draft** standard (created 2025-08-13). `DecisionCommit` (§5.1) is designed to be independently useful if ERC-8004 changes, and the Validation Registry integration (§5.3) is explicitly optional.

---

## 3. Architecture

```
                         ┌──────────────────────────┐
   market venues ───────▶│  MarketDataOracle (M1)   │  quotes, yields, gas
   Treasury/Fed  ───────▶│  guards: staleness, dev. │  benchmark series
                         └────────────┬─────────────┘
                                      │ Observation
                                      ▼
  ┌────────────────┐        ┌──────────────────────┐        ┌──────────────────┐
  │ PortfolioLedger│◀──────▶│   PolicyEngine (P1)  │───────▶│ ProposalBuilder  │
  │     (L1)       │  NAV   │  bands · no-action   │ intent │      (P2)        │
  └────────┬───────┘        │  eligibility · limits│        └────────┬─────────┘
           │                └──────────┬───────────┘                 │ Proposal
           │                           │ HaltSignal                  ▼
           │                           ▼                  ┌──────────────────────┐
           │                ┌──────────────────────┐      │ IMD oracle panel     │
           │                │  CircuitBreaker (G1) │      │ (existing capability)│
           │                └──────────────────────┘      └────────┬─────────────┘
           │                                                       │ verdicts + dissent
           │                                                       ▼
           │                                            ┌──────────────────────┐
           │                                            │ DisagreementLedger   │
           │                                            │        (D1)          │
           │                                            └────────┬─────────────┘
           │                                                     │ approved
           │                                                     ▼
           │                                          ┌────────────────────────┐
           │                                          │ DecisionCommit (C1)    │
           │                                          │ commit → reveal        │
           │                                          └────────┬───────────────┘
           │                                                   │ revealed
           │        fills                                      ▼
           └──────────────────────────────────────◀ ┌────────────────────────┐
                                                    │ ExecutionSimulator(X1) │
                                                    │  PESSIMISTIC ONLY      │
                                                    └────────┬───────────────┘
                                                             │
                                ┌────────────────────────────┴──────────────┐
                                ▼                                           ▼
                     ┌────────────────────┐                    ┌────────────────────┐
                     │ BenchmarkEngine B1 │                    │ HumanReviewQueue H1│
                     └────────────────────┘                    └────────────────────┘
                                │                                           │
                                └──────────────┬────────────────────────────┘
                                               ▼
                                   ┌───────────────────────┐
                                   │  ReportGenerator R1   │
                                   └───────────────────────┘
```

---

## 4. Components

### M1 — MarketDataOracle
**Responsibility.** Fetch and normalise all external state into immutable, timestamped `Observation` records. Serve nothing that has not passed its guards.

**Inputs.** Stablecoin and risk-asset quotes from ≥2 independent venues per asset; protocol yields (Aave, Sky) from on-chain reads, never from marketing pages; tokenized-fund NAV/APY; gas base fee; the Treasury par yield curve for the reference benchmark.

**Guards — a failing guard produces `NO_ACTION`, never a fallback value.**

| Guard | Threshold | On breach |
|---|---|---|
| Staleness | > 60 min since fetch | Mark stale; block all dependent decisions |
| Cross-venue deviation | > 50 bp between two feeds for one asset | Mark disputed; escalate to H1 |
| Single-source | < 2 feeds available | Mark unverified; block trades in that asset |
| Implausibility | stablecoin outside [0.90, 1.10] | Mark anomalous; escalate to H1 |

**Critical prohibition.** M1 must never interpolate, forward-fill, or substitute a last-known-good value silently. Absence of data is a fact and must propagate as one. *(Rationale: the research report's §5.2 finding is that treating stablecoins as zero-volatility is the commonest modelling error in this domain; silent forward-fill is how that error enters a system.)*

### L1 — PortfolioLedger
Double-entry ledger of positions, cash flows and NAV for **five books in parallel**: Mandate A, Mandate B, Mandate C, Benchmark-Idle, Benchmark-Bill.

Append-only. Corrections are compensating entries, never edits. NAV is recomputed only from M1 observations that passed their guards; if any position lacks a valid observation, NAV is reported as `INDETERMINATE` rather than estimated.

**Also tracks the operating cost of the swarm itself** — agent compute, oracle panel cost, human review minutes — because that is subtracted before any performance claim (§8.2 of the report). Omitting it is the standard way these experiments flatter themselves.

### P1 — PolicyEngine
Evaluates each book against its mandate policy and emits exactly one of `REBALANCE`, `NO_ACTION`, or `ESCALATE`.

Policy is **declarative data, not code**, versioned and hash-committed at pre-registration. A policy change is a new version with a new hash and a governance record; the engine refuses to run against an uncommitted policy.

```yaml
policy_version: "1.0.0"
mandate: capital_preservation
unit_of_account: USD
eligible_universe:               # allow-list; anything absent is forbidden
  - {asset: USDC, venue: safe,      max_weight: 0.45}
  - {asset: USDC, venue: regulated_cex, max_weight: 0.25}
  - {asset: USD,  venue: bank,      max_weight: 0.40}
  - {asset: SECOND_STABLE, venue: safe, max_weight: 0.15}
targets: {usdc_safe: 0.35, usdc_cex: 0.20, usd_bank: 0.35, second_stable: 0.10}
bands:
  absolute_pct_points: 5.0
  relative_pct: 25.0
concentration_limits:
  max_single_issuer: 0.60        # see report §5.6 — issuer, not position
  max_single_protocol: 0.25
  max_single_chain: 0.80
cadence: {evaluate: weekly, act_min_interval_days: 30, min_trade_usd: 2500}
no_action_rules:                 # evaluated BEFORE any rebalance logic
  - within_bands
  - cost_exceeds_benefit
  - stablecoin_depegged_and_solvency_thesis_intact
  - price_feed_stale_or_disputed
  - within_48h_of_protocol_governance_change
  - active_unresolved_security_incident   # unless action is withdraw_to_safe
  - rationale_not_human_legible
escalation_rules:
  - {trigger: stablecoin_below, value: 0.995, sustained_minutes: 60}
  - {trigger: attestation_late_days, value: 5}
  - {trigger: exploit_in_held_or_shared_dependency_usd, value: 10000000}
  - {trigger: daily_nav_move_pct, value: 3.0}
  - {trigger: signer_set_change}
  - {trigger: redemption_gate_or_withdrawal_suspension}
  - {trigger: proposal_outside_eligible_universe}   # treated as a DEFECT
  - {trigger: cumulative_drawdown_pct, value: 10.0}
  - {trigger: members_below_wrapper_floor, value: 100}  # DUNA dissolution trigger, report §5.8
```

**Implementation requirements.**
- `no_action_rules` are evaluated **first**. `NO_ACTION` is the default; rebalancing must affirmatively earn its way past every rule.
- Every `NO_ACTION` emits a reason code and is persisted. Silence is not a record.
- An agent proposal outside `eligible_universe` is logged as a **defect against that agent**, investigated, and counted in its reputation — not merely discarded. A system that quietly drops invalid proposals cannot measure how often its agents try invalid things.
- The engine is **pure**: `(policy, ledger_state, observations) → decision`. No network calls, no clock reads, no model calls. This is what makes it replayable and therefore auditable.

### P2 — ProposalBuilder
Wraps a `REBALANCE` intent into a `Proposal` for panel review: intent, sizing, rationale in plain prose, expected cost from X1, stated confidence, the observations relied on (by hash), and the policy version.

**Human-legibility requirement.** A proposal must state, in one sentence a non-specialist signer can check: what moves, from where to where, how much, and why now. Failure to produce this is a `NO_ACTION` under `rationale_not_human_legible`. This is the software expression of the report's §5.3 finding that blind signing reduces a 3-of-5 to a 1-of-1.

### D1 — DisagreementLedger
**The most important new component.** Records, for every proposal, each panel member's agent ID, verdict, confidence, stated reasoning, and dissent.

Requirements:
- **Dissent is published even when overruled**, with equal prominence.
- Panel members must submit **independently**; no member sees another's verdict before submitting. Without this the "panel" is an echo and the disagreement record is worthless.
- Every disagreement is later **resolved against outcome** at a pre-declared horizon (30/90/180 days), and dissenter calibration is tracked per agent: *when the panel split, how often was the dissenter right?*
- Calibration feeds reputation but must **not** feed panel selection during the experiment — doing so would contaminate the measurement with selection effects.

### C1 — DecisionCommit
Commit–reveal so that look-ahead bias and post-hoc rationalisation are structurally impossible rather than discouraged.

1. **Commit:** publish `keccak256(abi.encode(decision_payload, nonce))` on-chain; record block number and timestamp.
2. **Reveal:** after the commit block is final, publish plaintext plus nonce.
3. **Fill:** X1 prices at the **next hourly close strictly after the reveal**.
4. **Verify:** an independent verifier recomputes every hash and asserts `commit_block < reveal_block` and `reveal_time < fill_time` for **every** decision.

**A single ordering violation fails the entire experiment run.** This is deliberately unforgiving; a probabilistic integrity guarantee is not an integrity guarantee.

Minimal contract surface:

```solidity
contract DecisionCommit {
    struct Commit { bytes32 hash; uint64 blockNumber; uint64 revealedAt; bytes payload; }
    mapping(uint256 => Commit) public commits;   // decisionId => Commit
    event Committed(uint256 indexed decisionId, bytes32 hash, uint64 blockNumber);
    event Revealed(uint256 indexed decisionId, bytes payload, uint64 revealedAt);
    function commit(uint256 decisionId, bytes32 hash) external onlyProposer;
    function reveal(uint256 decisionId, bytes calldata payload, bytes32 nonce) external;
    // reveal MUST verify keccak256(abi.encode(payload, nonce)) == commits[decisionId].hash
    // reveal MUST revert if block.number <= commits[decisionId].blockNumber
}
```

### X1 — ExecutionSimulator
Prices simulated fills **pessimistically, always**.

```
fill_price = reference_price
           ± spread_observed / 2            # always against the trade
           ± slippage(clip_size, venue_depth)
gas_cost   = gas_units × base_fee(fill_block) × asset_price(fill_block)
total_cost = spread + slippage + gas + venue_fee + (annual_product_fee × holding_fraction)
```

Rules:
- **Mid-price fills are prohibited.** Enforced by a test that fails if any recorded fill equals the reference mid.
- Reference price is the **next hourly close after reveal**, never the decision-time price.
- Slippage uses measured depth where available; where it uses the report's 1–5 bp assumption (§5.7), the fill is tagged `cost_basis: ASSUMED` and every report must show what fraction of costs rest on assumptions.
- Annualised product fees are accrued daily. The report's §5.7 finding is that fee drag (~60 bp/yr) dominates gas (~2.4 bp/yr) by roughly 25×; a cost model that captures gas precisely and fees vaguely is precise about the wrong thing.

### B1 — BenchmarkEngine
- **Primary: Benchmark-Idle** — 100% USDC in the Safe, 0% yield, zero transactions. The true counterfactual.
- **Reference: Benchmark-Bill** — rolling 13-week Treasury bill from the Treasury par yield series.
- **Net-of-operations line** — every mandate's return minus L1's recorded swarm operating cost. This is the number that decides §12.

### G1 — CircuitBreaker
Two-signer halt with no governance vote required. Halting moves all books to their `safe_state` and blocks P1 from emitting `REBALANCE`. **Un-halting always requires a full governance vote.** The asymmetry is deliberate: de-risking fast and cheap, re-risking slow and deliberate.

Auto-halt triggers: any H1 escalation unacknowledged beyond its SLA; M1 guard failure across more than half of tracked assets; any C1 ordering violation; ledger NAV `INDETERMINATE` for more than 24 hours.

### H1 — HumanReviewQueue
Escalations from P1/G1 with severity, SLA, assigned reviewer, and a recorded decision with reasoning.

| Severity | Example | SLA | On breach |
|---|---|---|---|
| P0 | Depeg > 60 min; exploit in a held protocol | 1 h | Auto-halt via G1 |
| P1 | Attestation late; governance proposal in held protocol | 24 h | Escalate to P0 |
| P2 | Band breach needing judgement | 7 d | Auto `NO_ACTION` |

**Unacknowledged escalations must not expire silently.** An SLA breach is itself an event that gets recorded and reported — the measured governance latency the report asks founders to establish by drill (§6.8) comes out of this data.

### R1 — ReportGenerator
Weekly and end-of-experiment reports: NAV per book, decisions with commit/reveal/fill timestamps, `NO_ACTION` reason-code distribution, realised vs expected costs, panel splits and dissent calibration, escalations and SLA performance, and performance vs both benchmarks gross and net of operating cost.

**Every figure carries its source and its epistemic tag** (`FACT` / `INFERENCE` / `ASSUMPTION` / `UNKNOWN`), matching the research report's convention. A figure that cannot be tagged cannot be published.

---

## 5. On-chain surface

| Contract | Purpose | Phase |
|---|---|---|
| `DecisionCommit` | Commit–reveal decision log | 1 |
| `PolicyRegistry` | Hash-commit of the active policy version | 1 |
| ERC-8004 Validation Registry | Optional anchor for panel verdicts | 2 |
| `TreasuryPolicyGuard` (Safe Guard) | Reject any transaction outside the eligible universe | 3 — **not authorised** |
| `TreasuryModule` (Safe Module) | Bounded execution within policy | 3 — **not authorised** |

Phase 3 is listed for completeness of the design and is explicitly outside the scope of this work. It requires its own authorisation, its own audit, and re-examination of ERC-8004's status.

---

## 6. Data model (core records)

```typescript
type Epistemic = "FACT" | "INFERENCE" | "ASSUMPTION" | "UNKNOWN";

interface Observation {
  id: string; asset: string; venue: string;
  value: number; unit: "USD" | "APY" | "GWEI";
  observedAt: string;          // ISO-8601 UTC
  sourceUrl: string; sourceClass: "primary" | "near-primary" | "unofficial";
  guards: { stale: boolean; disputed: boolean; singleSource: boolean; anomalous: boolean };
  epistemic: Epistemic;
}

interface Decision {
  id: string; book: BookId; policyVersion: string;
  action: "REBALANCE" | "NO_ACTION" | "ESCALATE";
  reasonCode: string;          // REQUIRED for NO_ACTION
  legs?: Leg[];
  rationale: string;           // must satisfy P2 legibility test
  confidence: number;          // 0..1, stated before outcome
  observationIds: string[];    // by hash — what it relied on
  proposerAgentId: string;     // ERC-8004 identity
  commitHash: string; commitBlock: number;
  revealedAt: string; filledAt?: string;
  expectedCostUsd: number; realisedCostUsd?: number;
  costBasis: "MEASURED" | "ASSUMED";
}

interface PanelVerdict {
  decisionId: string; agentId: string;
  verdict: "APPROVE" | "REJECT" | "ABSTAIN";
  confidence: number; reasoning: string;
  isDissent: boolean; submittedAt: string;
  independentSubmission: true;              // must be provably true
  outcomeResolvedAt?: string;
  dissenterWasRight?: boolean;              // filled at 30/90/180 days
}
```

---

## 7. Interfaces

```
GET  /observations?asset=&since=        → Observation[]
GET  /nav/:book                         → { nav, indeterminate, asOf, components[] }
POST /evaluate                          → Decision[]        (pure; replayable)
POST /proposals/:id/commit              → { commitHash, block }
POST /proposals/:id/reveal              → { payload, revealedAt }
POST /proposals/:id/simulate            → { fillPrice, costs, costBasis }
GET  /disagreements?resolved=           → PanelVerdict[]
GET  /escalations?severity=             → Escalation[]
POST /halt                              → requires 2 signer signatures
GET  /report/:week                      → Report
GET  /verify/integrity                  → { ok, violations[] }   ← the run's pass/fail
```

`POST /evaluate` must be deterministic: same policy + same ledger state + same observations ⇒ byte-identical decisions. This is testable and is the basis of every replay audit.

---

## 8. Failure modes the design must survive

| Failure | Design response |
|---|---|
| Oracle reports a stale price as current | Guards block; `NO_ACTION`; silent forward-fill prohibited (M1) |
| Agent hallucinates an asset or venue | Allow-list rejects; logged as a **defect** against the agent |
| Panel converges without real review | Independent submission enforced; suspiciously low dissent rate is itself reported |
| Fluent rationalisation of a bad trade | Commit–reveal fixes the rationale before the outcome is known |
| Look-ahead in backtest or paper fill | Fill priced strictly after reveal; integrity verifier is binary pass/fail |
| Costs under-modelled into fake alpha | Mid-price fills prohibited; assumed-cost fraction disclosed in every report |
| Depeg triggers panic selling | `stablecoin_depegged_and_solvency_thesis_intact` → `NO_ACTION` (report §5.5) |
| Exploit in a held protocol | P0 escalation, 1 h SLA, auto-halt on breach |
| Shared dependency across "diversified" protocols | Escalation trigger covers shared dependencies, not just held protocols (Curve/Vyper, report §5.4) |
| Signer cannot decode what they sign | Legibility test; illegible ⇒ `NO_ACTION` |
| Governance too slow to act | Two-signer kill switch bypasses the vote in one direction only |
| Swarm operating cost quietly exceeds alpha | L1 tracks it; B1 reports net-of-operations as the headline |
| Experiment quietly redefines success mid-flight | Pre-registration hash; amendments are dated, published records |

---

## 9. Acceptance tests

**Integrity (binary — any failure fails the run)**
1. For every decision: `commit_block < reveal_block < fill_block`.
2. Every commit hash recomputes from its revealed payload and nonce.
3. No fill price equals the reference mid.
4. No decision references an observation that failed a guard.
5. Replaying all decisions from stored policy + ledger + observations reproduces them byte-for-byte.
6. Every `NO_ACTION` has a reason code from the declared enumeration.
7. Every panel verdict carries `independentSubmission: true` with supporting evidence.
8. Every published figure carries an epistemic tag.

**Behavioural**
9. Injecting a stale feed produces `NO_ACTION`, not a trade.
10. Injecting a proposal outside the universe produces a logged defect, not a silent drop.
11. Injecting a sustained sub-$0.995 print produces a P0 escalation and no sell.
12. Injecting an unacknowledged P0 past SLA produces an auto-halt.
13. Un-halting without a governance record fails.
14. A band breach below `min_trade_usd` produces `NO_ACTION` with `cost_exceeds_benefit`.

**Reporting**
15. Net-of-operating-cost performance appears in every report, not only gross.
16. The fraction of costs tagged `ASSUMED` is disclosed.
17. Dissent appears in the report even where overruled.

---

## 10. Phasing

| Phase | Scope | Authorisation status |
|---|---|---|
| **0** | Pre-registration: publish hypotheses, policy v1.0.0, benchmarks, stopping rules; hash-commit on-chain | Covered by this research task as a *design*; publishing requires its own go-ahead |
| **1** | Paper only: M1, L1, P1, P2, D1, C1, X1, B1, G1, H1, R1. **No keys, no funds.** | **Not authorised — requires a separate engineering task** |
| **2** | ERC-8004 Validation Registry anchoring; extend to 52 weeks if Phase 1 passes all integrity tests | Not authorised |
| **3** | Safe Guard + Module, live custody, bounded real execution | **Not authorised; requires audit, legal review, and re-examination of ERC-8004's Draft status** |

**Gate between phases:** a phase may not begin until the previous phase has passed **all** integrity tests (§9.1–9.8) and its report has been reviewed by a human who did not build it.

---

## 11. Non-goals

- Alpha generation. The research report finds return differences at this size will be noise.
- Supporting assets beyond the declared universes.
- Real-time or intra-hour trading. Weekly evaluation is the design point.
- Tax lot accounting, statutory reporting, or anything requiring a legal entity's books.
- Multi-chain execution. One chain in Phase 1.
- Replacing human governance. The system proposes and records; humans decide.
- Answering whether the treasury is dollar- or native-token-denominated (research report §9.1). That is a founder question and it **blocks Phase 0**.

---

## 12. Success criteria for the prototype

The prototype succeeds if, at 26 weeks:

1. **All integrity tests pass** (§9.1–9.8). Necessary, non-negotiable, binary.
2. The full decision history is **reconstructible by an independent party** from on-chain commits plus published data, with no access to the operators.
3. The `NO_ACTION` reason-code distribution is coherent and the rate is high — the research report predicts most weeks warrant no action, and a system that trades every week has a bug in its policy engine or its incentives.
4. The disagreement ledger shows **measurable signal**: dissenter calibration distinguishable from chance at the declared horizons.
5. Measured governance latency from H1 is documented, which answers a founder question the research report could not (§6.8).

**And it fails — regardless of returns — if any integrity test fails.**

**[INFERENCE]** The most probable outcome is that the mandates finish within a few hundred dollars of the idle-USDC benchmark and net-of-cost performance is slightly negative, because the swarm costs something to run and the alpha at $100,000 is near zero. **That is a successful experiment.** It would establish that IMD can run an auditable decision process — which is the transferable result — while establishing that automated allocation at this notional is not worth its operating cost. Both halves are worth knowing, and the second is the one a system designed to flatter itself would never report.

---

**Scope reminder.** This document specifies software. It does not implement it, does not authorise implementation, and does not authorise the deployment of capital. Phase 1 is deliberately keyless.
