# Cell inventory

Honest liquidity for an acquired **token** or **meme** cell. Not a treasury venue. Not a `$POOR` chart bot.

Strategy shape (inventory rebalance via Jupiter) follows [solana-mmaker](https://github.com/gianlucamazza/solana-mmaker). The bag lives in a **PDA vault**; a keeper quotes and submits; it cannot withdraw.

## Policy (constitution §4)

Allowed only if all of:

1. The cell JSON exists and `type` is `token`, `meme`, or `hybrid`.
2. `hook` is set and is not `failed_hook`.
3. Neither mint is the membership mint (`token_mint`).
4. Funding is the cell’s own bag — not dry powder, buffer, or holder-buyback.
5. `canon.allowlist.cell_ops` contains `jupiter_rebalance`.
6. `canon.deny` contains `membership_mm` and `treasury_mm` (must stay).

Squads is upgrade authority, pause, and the only withdraw destination.

## Program

Source: `programs/cell-inventory/`. PDA seeds `["inventory", cell_id_sha256]`. Vault PDA `["vault", config]`.

| Instruction | Who | What |
|---|---|---|
| `initialize` | Squads | Pair, denied membership mint, swap program, caps |
| `pause` | Squads | Freeze rebalance |
| `set_params` | Squads | Target bps, slippage, per-ix caps |
| `rebalance` | keeper | CPI to configured swap program; source and dest must belong to the vault and use a token program; other vault token accounts are rejected; spent ≤ cap and output ≥ caller minimum |
| `withdraw` | Squads | Tokens out only to the authority |

Build: `make mm-build`. Deploy: `make mm-deploy` (upgrade authority → Squads vault).

Live **devnet:** program [`3Tk4oNMuqv97USN3uoGiPF93hJJVjgtUjrvzfmDyBDxB`](https://explorer.solana.com/address/3Tk4oNMuqv97USN3uoGiPF93hJJVjgtUjrvzfmDyBDxB?cluster=devnet). Upgrade authority = Squads vault `6Xm8zdA2…`. No cell bag initialized (no owned token/meme cell).

The account checks above describe the local source change. The deployed devnet program has not been upgraded to this build. The Q32 rates are authority supplied, not oracle observations. This build rejects every `rebalance`, and `mm-deploy.sh` refuses deployment. Keep all inventory vaults unfunded. Enable execution only after an on-chain Pyth owner/feed/freshness/decimals check, an oracle-bound output floor, and adversarial CPI tests have passed. A missing feed for a cell leaves that cell quote-only.

## Keeper

```
python -m skills.mm check --cell <json> --mint-a <usdc> --mint-b <cell-mint>
python -m skills.cli mm check --cell <json> --mint-a <usdc> --mint-b <cell-mint>
node scripts/mm/keeper.mjs --cell <json> --mint-a <usdc> --mint-b <cell-mint>
```

Default is **simulation** (quote only). `--execute` is refused unless `ENABLE_TRADING=true` **and** the inventory program is initialized for that cell.

## What this is not

- Buyback (15% is USDC → membership → burn).
- Dry-powder yield.
- Market-making the membership ticker.
- Phase 1 cell/split program.
