# Mini Me Infrastructure Architecture

## Goal

Build a private personal agent that can act for a user, with user-owned encrypted memory, on-chain data rights, and a path to decentralized model execution on unused compute.

## Current Infra Slice

This repo now has four minimum pieces:

- `packages/core`: encrypted private blocks, vault index, permission grants.
- `packages/runner-local`: local "order my usual" preparation runner.
- `packages/compute`: dead-compute provider interface and local stub.
- `packages/worker-local`: file-backed worker prototype that records result receipts.
- `packages/chain`: local rights-registry simulation matching contract fields.
- `contracts/MiniMeRightsRegistry.sol`: on-chain ownership and grant registry.
- `docs`: product brief, architecture, log.

## Data Model

```text
vault/
  raw/                 # source captures, encrypted later
  wiki/                # LLM-maintained markdown, encrypted later
  blocks/              # encrypted JSON blocks
  index.json           # commitments and metadata
  permissions.json     # local mirror of grants
```

Each private block is encrypted with AES-256-GCM. Its ciphertext hash becomes the commitment registered on-chain.

## Decentralized encrypted-brain storage

Aeonora can store encrypted brain envelopes on a self-hosted Kubo/IPFS node. Kubo returns a content-addressed `ipfs://` CID; `AeonoraRegistry.setBrainPointer` stores that CID, the ciphertext commitment, and a monotonic pointer version on-chain. The EVM stores the durable identity and verifiable pointer, not the full encrypted blob.

The hosted API mirrors to IPFS when `IPFS_API_URL` is configured. Portable CLI workspaces use IPFS directly with `AEONORA_BLOB_STORE=ipfs`. Kubo's administrative port stays private. Only peer traffic is public.

IPFS verifies content but does not promise retention. A credible deployment pins every CID on at least two independently operated nodes and renews Filecoin storage deals for long-term durability. Encrypted historical snapshots may remain retrievable after a user removes the mutable hosted-vault pointer.

## Rights Model

Rights are explicit:

- `read`
- `write`
- `derive`
- `share`
- `commercialize`
- `negotiate`
- `audit`

The first real executor should usually receive `derive`, not `read`: it gets only the fields needed to complete the task.

## Chain Layer

The contract stores:

- encrypted block commitments,
- owner address,
- grantee address,
- rights hash,
- scope hash,
- expiry,
- revocation state.
- worker job receipts,
- result commitments,
- attestation hashes.
- compute jobs,
- worker leases,
- job completion state.
- worker provider profiles,
- worker heartbeat timestamps.

The contract does not store plaintext personal data.

Grant IDs are deterministic:

```text
keccak256(abi.encode(owner, grantee, commitment, rightsHash, scopeHash, expiresAt))
```

Clients can compute `grantId` immediately after sending `createGrant`, so workers can reference grants without log decoding.

Compute job IDs are also deterministic:

```text
keccak256(abi.encode(requester, grantId, modelRefHash, privacyTierHash, maxPriceWei, jobSalt))
```

Clients can submit jobs and know `jobId` immediately. Workers can claim/complete that ID on-chain.

Current runnable mirror:

```bash
node packages/cli/mini-me.mjs init
node packages/cli/mini-me.mjs capture-usual-order examples/usual-order.json
node packages/cli/mini-me.mjs register-usual
node packages/cli/mini-me.mjs grant-usual food-order-executor
node packages/cli/mini-me.mjs submit-compute-job <grantId> local:mini-me-usual-order local "prepare usual order"
node packages/cli/mini-me.mjs claim-compute-job <jobId>
node packages/cli/mini-me.mjs complete-compute-job <jobId> 0xResultCommitment 0xAttestationHash
node packages/cli/mini-me.mjs get-result <jobId>
node packages/cli/mini-me.mjs run-dead-compute <grantId>
node packages/cli/mini-me.mjs order-my-usual
```

This simulates chain state locally in `vault/chain/registry.json`. Replace with live contract calls when deployment tooling lands.

Live RPC deploy path:

```bash
npm run compile:contracts
RPC_URL=http://127.0.0.1:8545 DEPLOYER=0xYourUnlockedDevAccount npm run deploy:rpc
```

`deploy:rpc` uses raw JSON-RPC and `eth_sendTransaction`, so the dev RPC must expose an unlocked account. This keeps signing dependencies out until wallet support is needed.

Live RPC contract call path:

- `packages/chain/rpc-registry.mjs` sends raw `eth_sendTransaction`.
- `packages/chain/abi.mjs` encodes only known registry functions.
- No generic ABI dependency yet.

Supported live calls:

- `registerMemory`
- `createGrant`
- `revokeGrant`
- `recordJobReceipt`
- `submitComputeJob`
- `claimComputeJob`
- `completeComputeJob`
- `registerWorker`
- `heartbeatWorker`

Live job discovery:

- `packages/chain/event-indexer.mjs` scans `ComputeJobSubmitted` logs.
- It returns `jobId`, `grantId`, requester, block number, and transaction hash.
- Workers can use this to discover chain-submitted work.
- `packages/chain/indexer-state.mjs` stores the last scanned block so workers poll incrementally.

Off-chain job specs:

- `packages/compute/spec-store.mjs` stores specs at `vault/compute/specs/<jobId>.json`.
- CLI writes spec after `submit-compute-job`.
- Registry worker reads spec by `jobId`.
- Spec includes `modelRef`, `privacyTier`, `prompt`, and `specCommitment`.
- Spec file is AES-256-GCM encrypted with `MINI_ME_PASSPHRASE`.
- Encrypted spec bodies are stored as content-addressed blobs under `vault/storage/blobs`.
- `vault/compute/specs/<jobId>.json` stores only pointer metadata.
- `MINI_ME_BLOB_STORE=ipfs` stores encrypted spec blobs through an IPFS-compatible HTTP API.
- Chain keeps `jobId`, hashes, rights, leases, receipts.

This keeps private prompt/task content off-chain while making job execution discoverable through chain logs.

Encrypted result blobs:

- `packages/compute/result-store.mjs` stores model outputs encrypted.
- Workers write `vault/compute/results/<jobId>.json` pointer metadata.
- Encrypted result body goes through same content-addressed blob layer as specs.
- Attestation includes `resultCid`.
- Chain stores `resultCommitment`, not plaintext output.

Completion discovery:

- `findCompletedJobs` scans `ComputeJobCompleted` logs.
- Agents can discover `jobId` + `resultCommitment`.
- Agent fetches/decrypts result blob by `jobId` if it has passphrase/rights.

Local result retrieval:

```bash
MINI_ME_AGENT_ID=agent-e2e node packages/cli/mini-me.mjs get-result <jobId>
```

Local registry enforces grant grantee when `MINI_ME_AGENT_ID` is set. Unset keeps dev-mode retrieval available.

RPC registry also supports result-access checks:

- reads `jobReceipts(jobId)` via `eth_call`,
- reads `grants(grantId)` via `eth_call`,
- rejects revoked/expired/wrong-grantee reads before decrypting local/IPFS result blob.

Key wrapping foundation:

- `packages/core/key-wrap.mjs` creates per-grant data keys.
- `packages/core/grant-key-store.mjs` stores wrapped data keys by `grantId`.
- Current implementation uses symmetric agent secret wrapping.
- `grant-usual` creates a per-grant key when `MINI_ME_GRANTEE_SECRET` is set.
- Workers encrypt results with the per-grant data key when available.
- `get-result` can decrypt with `MINI_ME_AGENT_SECRET`, without the owner vault passphrase.
- Next upgrade is wallet/public-key wrapping or threshold network decryption.

Signed user commands:

```bash
RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
USER_PRIVATE_KEY=0x... \
CHAIN_ID=31337 \
node packages/cli/mini-me.mjs register-usual

RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
USER_PRIVATE_KEY=0x... \
CHAIN_ID=31337 \
node packages/cli/mini-me.mjs grant-usual 0xExecutorAddress
```

## Dead Compute / Decentralized Model Layer

"Dead compute" means idle machines or GPUs contributed by users/operators. Mini Me should route model jobs to that pool later.

Design rule:

- Chain coordinates ownership, payment, rights, and attestations.
- Dead-compute workers run models.
- Workers submit output commitments and attestations back to chain.
- Private inputs stay encrypted unless job privacy tier allows secure plaintext execution, such as local device or TEE.

This is still "literally decentralized" without pretending EVM bytecode should run LLM inference. Running model inference inside ordinary smart contracts is not economically or technically viable for the product.

Minimum interface:

```text
submitJob(inputCommitment, modelRef, privacyTier, maxPrice)
 -> jobId

fetchResult(jobId)
 -> resultCommitment, attestation
```

Privacy tiers:

- `local`: user device only.
- `tee`: trusted execution environment.
- `public-encrypted`: encrypted input/output only, no plaintext access.
- `public`: non-sensitive jobs only.

Ponytail rule: do not build marketplace yet. First prove local runner + rights registry.

Current code has `LocalDeadComputePool` as a stub. It proves job submission/result/attestation shape without pretending decentralized workers exist yet.

## Worker Network Shape

Minimum actors:

- `User`: owns encrypted memory and grants rights.
- `Agent`: requests jobs using scoped grants.
- `Scheduler`: matches jobs to idle/dead compute.
- `Worker`: runs model/inference task.
- `Verifier`: checks attestation, output commitment, payment conditions.
- `RightsRegistry`: on-chain contract that records rights and revocation.

Minimum worker flow:

1. User registers encrypted memory commitment.
2. User grants agent `derive` or `negotiate` rights.
3. Agent submits job referencing commitment + grant.
4. Worker claims job with a lease.
5. Worker runs model under privacy tier.
6. Worker returns result commitment + attestation.
7. Chain records result receipt.
8. Agent decrypts/uses result only if policy permits.

Current local queue supports:

- `pending` jobs,
- worker claims,
- lease expiry,
- reclaim by another worker,
- completion only by lease owner.

This is first step toward dead-compute scheduling: idle machines can compete for jobs without executing same job twice unless a lease expires.

## Decentralization Milestones

1. Local encrypted vault + local registry mirror. Done.
2. Live EVM rights registry deployment. Deploy script exists; needs running RPC.
3. Local dead-compute worker daemon.
4. Multi-worker scheduler over LAN.
5. Paid worker marketplace.
6. TEE/privacy worker path.
7. Decentralized storage for encrypted blocks.
8. Cross-agent negotiation protocol.

## Local CLI

The repo includes a tiny CLI:

```bash
node packages/cli/mini-me.mjs init
node packages/cli/mini-me.mjs capture-usual-order examples/usual-order.json
node packages/cli/mini-me.mjs register-usual
node packages/cli/mini-me.mjs grant-usual food-order-executor
node packages/cli/mini-me.mjs submit-compute-job <grantId> local:mini-me-usual-order local "prepare usual order"
node packages/cli/mini-me.mjs claim-compute-job <jobId>
node packages/cli/mini-me.mjs complete-compute-job <jobId> 0xResultCommitment 0xAttestationHash
node packages/cli/mini-me.mjs get-result <jobId>
node packages/cli/mini-me.mjs run-dead-compute <grantId>
node packages/cli/mini-me.mjs order-my-usual
```

Use `MINI_ME_VAULT` and `MINI_ME_PASSPHRASE` to change storage path and passphrase.

## Worker CLI

Any machine can act as local dead compute against a shared vault path:

```bash
MINI_ME_VAULT=vault MINI_ME_WORKER_ID=laptop-1 node packages/worker-local/cli.mjs
```

One-shot mode for tests:

```bash
MINI_ME_VAULT=vault MINI_ME_WORKER_ID=laptop-1 node packages/worker-local/cli.mjs --once
```

Current worker:

- polls file-backed queue,
- claims one job with lease,
- runs model adapter,
- produces output/result commitment,
- records receipt in rights registry mirror,
- completes job.

Worker provider registration:

```bash
MINI_ME_VAULT=vault MINI_ME_WORKER_ID=laptop-1 node packages/worker-local/cli.mjs --register
MINI_ME_VAULT=vault MINI_ME_WORKER_ID=laptop-1 node packages/worker-local/cli.mjs --heartbeat
```

Worker profiles include capability hash and endpoint hash on-chain/local registry. Actual capability JSON stays off-chain.

Capability-aware matching:

- Worker env declares supported models with `MINI_ME_WORKER_MODELS`.
- Worker env declares privacy tiers with `MINI_ME_WORKER_PRIVACY_TIERS`.
- Registry worker decrypts each job spec and only claims compatible jobs.
- Incompatible jobs remain open for another worker.

Example:

```bash
MINI_ME_WORKER_MODELS=local:mini-me-usual-order MINI_ME_WORKER_PRIVACY_TIERS=local node packages/worker-local/cli.mjs --registry --once
```

Registry-backed worker mode:

```bash
MINI_ME_VAULT=vault MINI_ME_WORKER_ID=laptop-1 node packages/worker-local/cli.mjs --registry
```

This consumes compute jobs submitted to the registry mirror instead of file queue. Live RPC mode can claim/complete known job IDs, but full live chain job discovery still needs event indexing.

Chain-index worker mode:

```bash
RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
WORKER_TX_FROM=0xUnlockedWorker \
MINI_ME_VAULT=vault \
MINI_ME_WORKER_ID=laptop-1 \
MINI_ME_WORKER_MODELS=local:mini-me-usual-order \
MINI_ME_WORKER_PRIVACY_TIERS=local \
node packages/worker-local/cli.mjs --chain-index
```

Signed chain-index worker:

```bash
RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
WORKER_PRIVATE_KEY=0x... \
CHAIN_ID=31337 \
MINI_ME_VAULT=vault \
MINI_ME_WORKER_ID=laptop-1 \
MINI_ME_WORKER_MODELS=local:mini-me-usual-order \
MINI_ME_WORKER_PRIVACY_TIERS=local \
node packages/worker-local/cli.mjs --chain-index
```

This mode:

1. polls `ComputeJobSubmitted` logs,
2. advances local indexer cursor,
3. loads encrypted spec by `jobId`,
4. checks worker capabilities,
5. claims job on-chain,
6. runs model,
7. completes job on-chain with result/attestation commitment.

Model adapters:

- default `EchoModel` for deterministic tests,
- `OllamaModel` for real local inference over HTTP.

Run real local model worker:

```bash
MINI_ME_MODEL_PROVIDER=ollama \
OLLAMA_MODEL=llama3.2 \
MINI_ME_VAULT=vault \
MINI_ME_WORKER_ID=laptop-1 \
node packages/worker-local/cli.mjs
```

Ollama must already be running on that machine.

Run worker with live chain receipts:

```bash
RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
WORKER_TX_FROM=0xUnlockedWorker \
MINI_ME_MODEL_PROVIDER=ollama \
OLLAMA_MODEL=llama3.2 \
MINI_ME_VAULT=vault \
MINI_ME_WORKER_ID=laptop-1 \
node packages/worker-local/cli.mjs
```

Signed worker, no unlocked RPC account:

```bash
RPC_URL=http://127.0.0.1:8545 \
REGISTRY_ADDRESS=0xRegistry \
WORKER_PRIVATE_KEY=0x... \
CHAIN_ID=31337 \
MINI_ME_MODEL_PROVIDER=ollama \
OLLAMA_MODEL=llama3.2 \
MINI_ME_VAULT=vault \
MINI_ME_WORKER_ID=laptop-1 \
node packages/worker-local/cli.mjs
```

## Next Build Step

Replace symmetric `MINI_ME_AGENT_SECRET` with wallet/public-key wrapping.

IPFS-compatible blob storage:

```bash
MINI_ME_BLOB_STORE=ipfs IPFS_API_URL=http://127.0.0.1:5001 node packages/cli/mini-me.mjs submit-compute-job <grantId> local:test local "prompt"
MINI_ME_BLOB_STORE=ipfs IPFS_API_URL=http://127.0.0.1:5001 node packages/worker-local/cli.mjs --registry --once
```

Only encrypted JSON is sent to IPFS.
