2026-10-04 23:03:47 +00:00
|
|
|
# AGENTS.md
|
|
|
|
|
|
2026-10-14 17:28:33 -07:00
|
|
|
Orgchain is lineage's app for creating and operating lineage holdings on Super Testnet's toy chain.
|
|
|
|
|
|
|
|
|
|
- Test-only, always: no mainnet funds, no hidden signing, no custody, and nothing presented as a real key.
|
2026-10-15 02:04:35 -07:00
|
|
|
- Lineage semantics live in one place, `src/orgchain/lineage.js`, and `SPEC.md` says the same in words. The UI never
|
|
|
|
|
interprets events itself, and every act is vetted by that reducer before it is signed. A new op or rule means a
|
|
|
|
|
reducer change, its tests, the README's table and `SPEC.md`.
|
|
|
|
|
- Whatever signs must stay valid on real Bitcoin. After changing how transactions or envelopes are built, rerun the
|
|
|
|
|
regtest rehearsal and its comparison (`tools/regtest/README.md`) and refresh the fixture it records.
|
2026-10-14 17:28:33 -07:00
|
|
|
- The engine (`src/adapters`, `src/upstream`, `src/storage.js`, `src/miner.js`) is Super Testnet's. Compose with it
|
2026-10-14 23:16:03 -07:00
|
|
|
rather than rewriting it, and keep its tests passing. Preserve upstream licenses and provenance. Its local
|
2026-10-15 14:51:52 -07:00
|
|
|
changes are P2WPKH payments, a coinbase split across up to 64 outputs, ordinary spends of up to 64 inputs and
|
2026-10-15 15:48:31 -07:00
|
|
|
outputs whose key-path signatures may carry 0x83, a three-input reveal that inscribes on a sat another key holds
|
|
|
|
|
(a belt) and returns both coins unchanged, coins imported from a real chain, and BIP-341/342 checks of reveals'
|
|
|
|
|
script paths, all in `src/adapters/chain.js` (PROVENANCE.md); keep them small and tested.
|
2026-10-15 00:32:29 -07:00
|
|
|
- Money lives in `src/orgchain/money.js`: beats pay the holdings (split by hashrate, or all to the last act; under
|
|
|
|
|
Mainnet none mine, and the lab wallet funds them), sends spend SegWit coins only, so an inscription can never leave
|
|
|
|
|
as change, and balances are read off the chain, never stored. Gas (`src/orgchain/actions.js`): every act is paid by
|
|
|
|
|
the actor's own keys and checked before anything is signed; the lab wallet pays only for foundings and for holdings
|
|
|
|
|
that predate lab keys.
|
2026-10-15 13:32:29 -07:00
|
|
|
- Deals live in `src/orgchain/offers.js`, both sides of the PSBT: an offer (the buyer pre-signs the whole transaction
|
|
|
|
|
and the holder countersigns) and an ask (the holder signs the lot's input alone, SIGHASH_SINGLE|ANYONECANPAY, and any
|
|
|
|
|
buyer completes it behind a dummy of its own). Offers and asks are signatures kept in the lab, never chain state, and
|
2026-10-15 14:51:52 -07:00
|
|
|
who holds a lot is read off the chain, never from metadata. An org sells with its tree, and a holding whole, by its
|
|
|
|
|
owner (the lab wallet): cash-free, and frozen with everything in it while listed or sold (`actions.js` cashOut,
|
|
|
|
|
frozenWhy; a listed holding mines nothing). A tree travels as one output (`bundle` for an ask; an offer merges its
|
2026-10-15 15:48:31 -07:00
|
|
|
inputs) and splits back by the deal's layout once adopted (`unbundle`): one output per inscribed sat, never two
|
|
|
|
|
sats' inscriptions left sharing a coin, or selling one would sell the other. Its buyer's keys sign the adoption and
|
|
|
|
|
the split: never sign for the buyer at the seller's act.
|
2026-10-15 16:10:18 -07:00
|
|
|
- Belts are soulbound (`src/orgchain/belts.js`): a belt counts only when it is inscribed on its recipient's own sat
|
|
|
|
|
(the reducer compares sats with `satOf`: the lab's sat numbers, ord's, or else ord's satpoints), and the lab puts it
|
|
|
|
|
there in one three-input reveal that the recipient's key co-signs, so it goes wherever its node goes; a promotion is
|
|
|
|
|
another reinscription on that sat. Count and split coins by inscribed sat, never by inscription, since a node shares
|
|
|
|
|
its sat with its belts, and never make a belt a lot. The compare checks ord's satpoints and charms (`charmsOf` models
|
|
|
|
|
the ones lineage's inscriptions earn); keep that model in step with ord.
|
2026-10-15 13:32:29 -07:00
|
|
|
- Moves (`join`, `adopt`): neither half's effect may depend on their order within a block, since a miner may put them
|
|
|
|
|
either way; the move records both halves. An old parent keeps a moved child in `children` so its index is never
|
2026-10-15 14:51:52 -07:00
|
|
|
reused: walk children with `kidsOf`. A holding that moves becomes an org: its old root stays in `keys.roots` so old
|
|
|
|
|
keys still resolve (`money.js` keyAt), and graduation roots are kept by graduation event (`keys.adopted`), since a
|
|
|
|
|
node can graduate, move and graduate again. Inscription metadata is public and permanent, so never put a secret in it
|
|
|
|
|
(item notes included), and a charter carries a hash of the filings, never the filings.
|
2026-10-15 12:15:48 -07:00
|
|
|
- Charters (`src/orgchain/lineage.js`): legal form is an attribute of a node, and whether a charter stands is derived
|
|
|
|
|
from the tree (`standing`), never stored, so charters commute with graduations and closes.
|
2026-10-14 18:22:22 -07:00
|
|
|
- Keys follow the tree (`src/orgchain/keys.js`): store roots only (one per holding, one per graduated org) and derive
|
|
|
|
|
every other key from its position. Every act is signed by whichever key holds the authorizing inscription.
|
2026-10-14 19:49:05 -07:00
|
|
|
- A node's chain key is its account's BIP-86 Taproot key (`m/86'/1'/account'/0/0`); SegWit is BIP-84 at the same
|
2026-10-15 10:48:28 -07:00
|
|
|
account and holds its money; its Ethereum key is BIP-44 at `m/44'/60'/account'/0/0` (an org's, at account 0, is the
|
|
|
|
|
key tree page's legal-control key, and `tests/keyring.test.js` pins that page's vector). Leaves are HKDF-SHA256
|
|
|
|
|
(salt `lineage/v0`) and must stay byte for byte with lineage's key tree page; `tests/keys.test.js` holds values read
|
|
|
|
|
off that page.
|
|
|
|
|
- Keyrings (`src/orgchain/keyring.js`): every key signs the statement with its own chain's message standard (BIP-322,
|
|
|
|
|
EIP-191, a NIP-01 event), so real wallets can make and check the proofs. Keep those formats exact and their pinned
|
|
|
|
|
vectors passing; a new chain's key joins only with its own standard and a vector to pin.
|
2026-10-14 20:14:11 -07:00
|
|
|
- Secrets show only behind Reveal, reset on every selection, and match the key tree page byte for byte (the tests pin
|
|
|
|
|
hashes of the page's own output).
|
2026-10-14 17:28:33 -07:00
|
|
|
- The page makes no network requests; keep it that way (the deployed CSP sets `connect-src 'none'`).
|
|
|
|
|
- Before shipping: `npm test`, `npm run build`, `npm run test:e2e`.
|