Orgchain v1.8: belts cross holdings, and a graduate becomes its own holding

From the operator's notes on trying v1.6.1. An award's recipient may sit in
any holding, so a registry like well-known can certify an agent it doesn't
hold (say, after the agent pays it). A graduated org already held its own
root; now it is a holding of its own too: it and its subtree re-root under
it, it joins the Holdings list with its own tree and timeline, mines its
share and can be funded, and its parent's tree keeps a row for it that opens
it. Events that touch two holdings (a belt across them, a graduation) show in
both timelines, and the holding that acted gets the last-act credit.

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 00:44:59 -07:00
1 parent 69a97544da
commit 7d981341ff
11 files changed
+122 -37

No files matched your search

+37 -4
View File
@@ -54,8 +54,10 @@ test('found a holding, then birth, award, decide, graduate and close at the defa
await expect(say(page)).toHaveText('studio decided “Ship weekly”, at beat 7.');
await verb(page, 'graduate');
await page.locator('#graduate-go').click();
await expect(say(page)).toHaveText('studio graduates from acme-holdings, at beat 8. Its edge is adopted now.');
await expect(say(page)).toHaveText("studio graduates from acme-holdings, at beat 8. It's a holding of its own now.");
await expect(row(page, 'studio')).toContainText('graduated');
await expect(page.locator('#holdings-list')).toContainText('from acme-holdings at beat 8');
await expect(row(page, 'bot')).toHaveCount(0); // its seats went with it
await row(page, 'acme-holdings').click();
await verb(page, 'close');
await page.locator('#close-go').click();
@@ -64,12 +66,16 @@ test('found a holding, then birth, award, decide, graduate and close at the defa
await expect(say(page)).toHaveText('acme-holdings is closed, at beat 9.');
await expect(row(page, 'acme-holdings')).toContainText('closed');
await expect(row(page, 'studio')).not.toContainText('closed'); // graduated: it holds its own root
await row(page, 'bot').click();
await verb(page, 'birth');
await expect(page.locator('#act-why')).toHaveText('Agents do not give birth.');
await page.locator('#timeline-list .ev', { hasText: 'Ship weekly' }).click();
await expect(page.locator('#inspect-body')).toContainText('"op": "decide"');
await expect(page.locator('#inspect-body')).toContainText('applied');
await row(page, 'studio').click();
await page.locator('#inspect-body').getByRole('button', { name: 'Open studio' }).click();
await expect(page.locator('#tree-sub')).toContainText('studio');
await expect(page.locator('#timeline-list')).toContainText('graduate studio from acme-holdings');
await row(page, 'bot').click();
await verb(page, 'birth');
await expect(page.locator('#act-why')).toHaveText('Agents do not give birth.');
expect(problems).toEqual([]);
});
@@ -300,3 +306,30 @@ test('the sample ends on a standing offer, and its holder accepts it', async ({
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true);
expect(problems).toEqual([]);
});
test('an agent pays a registry in another holding, and the registry awards it a belt', async ({ page }) => {
const problems = await open(page);
const hold = name => page.locator('#holdings-list .hold', { has: page.locator('.hn', { hasText: new RegExp(`^${name}$`) }) });
await found(page, 'well-known');
await expect(say(page)).toHaveText('well-known is founded, at beat 2.');
await found(page, 'acme');
await expect(say(page)).toHaveText('acme is founded, at beat 3.');
await birth(page, 'scout', 'agent');
await expect(say(page)).toHaveText('scout is born to acme, at beat 4.');
await pay(page, 'acme / scout (agent)', '1');
await expect(say(page)).toHaveText('acme sent 1 tBTC to scout, at beat 5.');
await row(page, 'scout').click();
await pay(page, 'well-known', '0.1');
await expect(say(page)).toHaveText('scout sent 0.1 tBTC to well-known, at beat 6.');
await hold('well-known').click();
await verb(page, 'award');
await page.locator('#award-to').selectOption({ label: 'acme / scout (agent)' });
await page.locator('#award-skill').fill('listen');
await submit(page, 'award');
await expect(say(page)).toHaveText('scout holds a white belt in listen, at beat 7.');
await expect(page.locator('#timeline-list')).toContainText('award listen · white → scout, from well-known');
await hold('acme').click();
await expect(page.locator('#timeline-list')).toContainText('award listen · white → scout, from well-known');
await expect(row(page, 'scout')).toContainText('listen');
expect(problems).toEqual([]);
});