Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Igor is a decentralized execution runtime for autonomous software agents. It pro
## About This Repository

**What:** Experimental infrastructure for autonomous agent survival
**Status:** Research-stage — Phase 3 (Autonomy) complete. Capability membrane, replay verification, agent SDK, and multi-node mobility testing validated. Phase 4 (Economics) next.
**Status:** Research-stage — Phases 2–4 complete, Phase 5 (Hardening) complete. Agents run, checkpoint, migrate, resume, meter cost, enforce capability membranes, replay-verify, support multi-node chain migration, sign checkpoint lineage, recover from migration failures, and enforce lease-based authority. Task 15 (Permissionless Hardening) next.
**Purpose:** Demonstrate that software can checkpoint, migrate, and self-fund execution

**Read first:**
Expand Down Expand Up @@ -133,16 +133,22 @@ Nodes operate autonomously without coordination.

### Checkpoints

Atomic snapshots preserving agent state, budget, and binary identity (57-byte header):
Atomic snapshots preserving agent state, budget, and binary identity (209-byte header):

```
Offset Size Field
0 1 Version (0x02)
0 1 Version (0x04)
1 8 Budget (int64 microcents, little-endian)
9 8 PricePerSecond (int64 microcents, little-endian)
17 8 TickNumber (uint64, little-endian)
25 32 WASMHash (SHA-256 of agent binary)
57 N Agent State (application-defined)
57 8 MajorVersion (uint64, little-endian)
65 8 LeaseGeneration (uint64, little-endian)
73 8 LeaseExpiry (int64, little-endian)
81 32 PrevHash (SHA-256 of previous checkpoint)
113 32 AgentPubKey (Ed25519 public key)
145 64 Signature (Ed25519, covers bytes 0–144)
209 N Agent State (application-defined)
```

Budget unit: 1 currency unit = 1,000,000 microcents. Integer arithmetic avoids float precision drift.
Expand Down
3 changes: 3 additions & 0 deletions agents/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ func (s *Survivor) Unmarshal(data []byte) {
s.BirthNano = d.Int64()
s.LastNano = d.Int64()
s.Luck = d.Uint32()
if err := d.Err(); err != nil {
panic("unmarshal checkpoint: " + err.Error())
}
}

func init() { igor.Run(&Survivor{}) }
Expand Down
3 changes: 3 additions & 0 deletions agents/reconciliation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ func (r *Reconciler) Unmarshal(data []byte) {
r.DetectNano = d.Int64()
r.FinalizeNano = d.Int64()
r.CompleteNano = d.Int64()
if err := d.Err(); err != nil {
panic("unmarshal checkpoint: " + err.Error())
}
}

// shortHex returns the first 8 hex chars of a byte slice (4 bytes).
Expand Down
30 changes: 18 additions & 12 deletions docs/runtime/BUDGET_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,19 @@ Tick 2: budget 9.999999 → cost 0.000001 → budget 9.999998
Budget is persisted in checkpoint:

```
Checkpoint Format:
[0] version (0x02)
[1-8] budget (int64 microcents)
[9-16] pricePerSecond (int64 microcents)
[17-24] tickNumber (uint64)
[25-56] wasmHash (SHA-256)
[57+] agent state
Checkpoint Format (v0x04, 209-byte header):
[0] version (0x04)
[1-8] budget (int64 microcents)
[9-16] pricePerSecond (int64 microcents)
[17-24] tickNumber (uint64)
[25-56] wasmHash (SHA-256)
[57-64] majorVersion (uint64)
[65-72] leaseGeneration (uint64)
[73-80] leaseExpiry (int64)
[81-112] prevHash (SHA-256 of previous checkpoint)
[113-144] agentPubKey (Ed25519 public key)
[145-208] signature (Ed25519)
[209+] agent state
```

### 4. Restoration
Expand Down Expand Up @@ -210,11 +216,11 @@ The checkpoint preserves the exhausted state, allowing inspection or potential r
Checkpoints include budget as metadata:

```
Binary Layout (57-byte header):
┌─────────┬──────────┬────────────────┬────────────┬──────────┬─────────────┐
│ Version │ Budget │ PricePerSecond │ TickNumber │ WASMHash │ Agent State │
│ (1 byte)│ (8 bytes)│ (8 bytes) │ (8 bytes) │(32 bytes)│ (N bytes) │
└─────────┴──────────┴────────────────┴────────────┴──────────┴─────────────┘
Binary Layout (209-byte header, v0x04):
┌─────────┬──────────┬────────────────┬────────────┬──────────┬──────────────┬─────────────────┬─────────────┬──────────┬─────────────┬───────────┬─────────────
│ Version │ Budget │ PricePerSecond │ TickNumber │ WASMHash │ MajorVersion │ LeaseGeneration │ LeaseExpiry │ PrevHash │ AgentPubKey │ Signature │ Agent State │
│ (1 byte)│ (8 bytes)│ (8 bytes) │ (8 bytes) │(32 bytes)│ (8 bytes) │ (8 bytes) │ (8 bytes) │(32 bytes)│ (32 bytes) │ (64 bytes)│ (N bytes) │
└─────────┴──────────┴────────────────┴────────────┴──────────┴──────────────┴─────────────────┴─────────────┴──────────┴─────────────┴───────────┴─────────────

Encoding: Little-endian integers (int64 microcents for budget/price, uint64 for tick)
```
Expand Down
6 changes: 3 additions & 3 deletions docs/runtime/MIGRATION_PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type AgentPackage struct {
AgentID string // Unique agent identifier
WASMBinary []byte // Compiled WASM module
WASMHash []byte // SHA-256 of WASMBinary for integrity verification
Checkpoint []byte // Serialized state + budget metadata (57-byte header)
Checkpoint []byte // Serialized state + budget metadata (209-byte header, v0x04)
ManifestData []byte // Capability manifest JSON
Budget int64 // Remaining budget in microcents
PricePerSecond int64 // Cost per second in microcents
Expand Down Expand Up @@ -373,9 +373,9 @@ Typical migration time (local network):

### Checkpoint Size

- Header: 57 bytes (version + budget + price + tick + wasmHash)
- Header: 209 bytes (version + budget + price + tick + wasmHash + majorVersion + leaseGeneration + leaseExpiry + prevHash + agentPubKey + signature)
- State: Agent-dependent
- Example agent: 65 bytes total (57 header + 8 state)
- Example agent: 237 bytes total (209 header + 28 state)

### WASM Transfer Size

Expand Down
2 changes: 1 addition & 1 deletion internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func HandleLeaseExpiry(ctx context.Context, instance *agent.Instance, leaseErr e
func HandleTickFailure(ctx context.Context, instance *agent.Instance, tickErr error, logger *slog.Logger) error {
if instance.Budget <= 0 {
logger.Info("Agent budget exhausted, terminating",
"agent_id", "local-agent",
"agent_id", instance.AgentID,
"reason", "budget_exhausted",
)
} else {
Expand Down