Orgchain v1.14.1: a belt counts only on its seat's own sat

Placement is now a rule of lineage/v0, not just how Orgchain inscribes:
an award counts only if it is inscribed on its recipient's own sat, so any
indexer can check that a belt is soulbound. The reducer compares sats
(satOf): the lab's sat numbers, ord's, or, without ord's sat index, its
satpoints, which two inscriptions share exactly when they share a sat. ord
events now carry the sat number when ord has one. Belts inscribed anywhere
else, as before v1.14, are rejected.

A promotion is another reinscription on the same sat, over the belt before
it: each badge keeps its skill's earlier belts, and Inspect shows the
ladder ("re-inscribed over white (beat 5)"). The sample's sol now goes
white, then green. An award and its recipient's own close no longer
conflict within a block, since both spend the recipient's inscription.

Rehearsed again on Bitcoin Core regtest from height 178: sixteen beats and
133 transactions; ord shows sol's sat carrying sol, its white belt and its
green belt, in order, each belt charmed reinscription and vindicated, and
the compare matches. The fixture is re-recorded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4upF5LVwmPDDqrhdUfnXh
This commit is contained in:
teahubxyzandClaude Opus 5.5 committed 2026-10-15 16:10:18 -07:00
1 parent c8c18b073e
commit 5a7f11e49d
17 files changed
+122 -67

No files matched your search

+12
View File
@@ -10,6 +10,7 @@ import { keyOf, scriptHex } from '../src/orgchain/keys.js';
import { askId } from '../src/orgchain/offers.js';
import { BELT_GAS, charmsOf } from '../src/orgchain/belts.js';
import { PROTOCOL } from '../src/orgchain/lineage.js';
import { InscriptionAdapter } from '../src/adapters/inscription.js';
import { Script, Tap, Tx } from '@cmdcode/tapscript';
import { FEE, envelope, tapleafOf } from '../src/adapters/inscription.js';
import { getVin, getVout } from '../src/upstream/primitives.js';
@@ -105,3 +106,14 @@ test('the chain takes a three-input reveal only to inscribe on a held sat: its p
assert.deepEqual([holderCoin(lab.chain, bot).inscriptions.length, satpoint(lab, belt)], [2, satpoint(lab, bot)]);
assert.deepEqual(lineageState(lab).nodes.get(bot).badges.map(b => [b.skill, b.belt]), [['launch', 'white']]);
});
test('a belt inscribed the old way, with postage on a sat of its own, does not count', () => {
const { lab, acme } = twoHoldings(), ops = act(lab, 'birth', acme, { name: 'ops' });
send(lab, acme, ops, SAT);
const bot = act(lab, 'birth', ops, { name: 'bot', kind: 'agent' }), s = lineageState(lab);
const id = new InscriptionAdapter(lab.chain, keyOf(lab.keys, s, s.nodes.get(ops)).wallet)
.inscribe('award launch white', ops, { op: 'award', to: bot, skill: 'launch', belt: 'white' }, { metaprotocol: PROTOCOL });
const after = lineageState(lab), entry = after.log.find(e => e.id === id);
assert.deepEqual([entry.ok, entry.why, after.nodes.get(bot).badges], [false, "a belt counts only on its recipient's own sat", []]);
assert.notEqual(satpoint(lab, id), satpoint(lab, bot));
});