From 1cbe5ba0865c8b3aa3018db5caf463c6290415c1 Mon Sep 17 00:00:00 2001 From: teahubxyz Date: Wed, 14 Oct 2026 19:50:17 -0700 Subject: [PATCH] decisions + lineage: Taproot and SegWit for every account (key tree, Orgchain v1.3) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01H4upF5LVwmPDDqrhdUfnXh --- docs/decisions.md | 1 + docs/lineage.md | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index 68ec715..c36bfb5 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -53,3 +53,4 @@ Format: date · decision · why. Add at the bottom. Never edit an old entry; sup - 2026-10-15 · **Tea MCP 2.0: typed tools, pull requests, commits and Actions settings, all as the caller.** `mcp/tea_mcp/server.py` is rewritten (`fb8acb0`, then `fbb1159`): still one file, still acting only with the caller's own Gitea token, now 29 tools. Parameters are typed (patterns, ranges, enums), so a bad argument is refused before Gitea is asked and every limit shows in the tool's schema. New: `tea_pull_get/create/review/merge` (merge keeps the head branch), `tea_labels`, `tea_label`, `tea_commit` (up to 50 files, text or base64), `tea_branch_create`, `tea_repo_edit` (archive included), `tea_hook_create` (one hook per URL), `tea_secret_set` and `tea_variable_set`. Fixed: unknown labels are refused; create or update comes from looking the file up, not from "404" in an error message; org repositories are private by default like user ones; `tea_org_add_member` names its team; `more` and `truncated` come from Gitea's totals; comments page correctly. `tea_actions` had never worked, because Gitea 1.24 has no `/actions/runs`; it reads `/actions/tasks` now. 1.24 has no API that lists a run's jobs either, so there is no log tool yet. The Gitea on hb-5 (28.0.0) has that API, so upgrading prod's Gitea would bring it. 27 tests run against a fake Gitea, and every tool ran once against teahub.xyz in a scratch repo and org, both deleted after. Connectors that still hold 1.0's tool list keep working (2.0.1 also takes `labels` as a string). The old Tea MCP container on hb-5 (`teahub-mcp`, with its Phast sidecar), idle since the cutover, is stopped and set not to restart; it and its volume are kept. Boring's `boring_teahub_*` now operate `green-tea-mcp` (matcha/boring `122f0b3`, shipped by its own deploy workflow). `boring_teahub_deploy` shipped 2.0.1 from the exact main SHA, and status reads that SHA back from the image tag (`fresh: true`). Codex on hb-5 lists `tea` and `boring` as not logged in; `codex mcp login tea` signs it in. Token 43 (`tea-mcp-smoke-20261015`) ran the smoke test and the first push and was deleted by id (the API now answers 401 to it); token 45 (`tea-mcp-201-20261015`) pushed 2.0.1 and this line and is deleted by id right after. Both were `teahubxyz`'s, neither was printed, and the table is checked. Why: #9's audit and plan. - 2026-10-15 · **Orgchain v1.1: lineage's keys, merged from the tree branch.** The parallel session's key layer (`tree`, `2ea7884`) folds into v1: its `lineage-keys.js` and `handoff.js` come over as written, with their BIP-85, BIP-86 and NIP-06 spec vectors; its off-chain keyring and old UI stay behind, because v1's tree comes from the chain. Each holding gets its own 24-word lab root; every node holds its inscription at its lineage key (BIP-85 org seeds, agents as accounts 1..n of their org's seed, BIP-86 wallets, NIP-06 npubs); every act is signed by whichever key holds the authorizing inscription; graduation is a claim by the org's fresh root countersigned by its derived key, and the derived subtree re-keys under the new root, so the parent's line can no longer sign for it. Labs saved before keys still load and sign with the lab wallet. `lineage/orgchain` main `744c594`; 49 unit tests and Playwright 6/6, keys included. Token 46 (`orgchain-keys-20261015`, `write:repository`) did the pushes and is deleted right after; the table is checked. Why: the operator made this session the lead and asked for the two to be compared and whatever helped used; the tree was the half v1 had left for later, enforcement. - 2026-10-15 · **Orgchain v1.2: tapkeys and lineage's leaves.** The operator asked for the ssh, git and other keys in Orgchain, and for a tapkey rather than just an npub for each agent. A node's chain key is now its tapkey: its NIP-06 npub with the BIP-86 tweak, so one secret signs its nostr events and its chain spends, and its address follows from its npub (the tweak is checked against BIP-86's own vector). Its leaves hang off the same tree, HKDF-SHA256 with salt `lineage/v0`: an agent's ssh, git, dkim and wg keys from its nostr secret, an org's ssh-ca, mtls and noise keys from its seed. The unit tests hold values read off the key tree page for one mnemonic, and they match byte for byte. Inspect shows each node's tapkey, npub, derivation and leaves, with the public lines to paste (authorized key, `allowed_signers` line, DKIM record, WireGuard peer, CA key). Labs keyed by v1.1 keep their separate m/86' chain keys until they are reset. `@scure/base`, `bip32` and `bip39`, which came in with v1.1, now have their licenses in `public/licenses` and lines in `PROVENANCE.md`. `lineage/orgchain` main `00a3561`, time's `gh-pages` `0984f5a`; 53 unit tests and Playwright 6/6. Token 47 (`orgchain-tapkey-20261015`, `write:repository`) did the pushes and is deleted right after; the table is checked. Why: Orgchain showed lineage's keys only as far as the npub, and the operator wants agents with a key that holds and signs on chain. +- 2026-10-15 · **Taproot and SegWit for every lineage account, listed rather than derived.** The operator asked for Taproot in its own right (it is where inscriptions live, and no one should have to derive it from an npub) and for agents' other public Bitcoin addresses. Every account of an org's seed now has standard addresses at the same index as its NIP-06 key: BIP-86 Taproot for inscriptions and BIP-84 SegWit for payments (0 is the org, whose SegWit branch is its treasury; agents are 1..n). The lineage key tree page derives them on mainnet paths, adds the org's Taproot beside its treasury, and lists agents' addresses in their keyrings and in `lineage.json`; the org rows check against the BIP-84 and BIP-86 vectors, and agent addresses were cross-checked against tapscript. Orgchain v1.3 holds every node's inscription at its BIP-86 Taproot key on test paths (`m/86'/1'/…`) and shows Taproot, SegWit and npub with their paths. v1.2's tapkey (the npub's key with the BIP-86 tweak) is retired; labs keyed by v1.1 or v1.2 keep their keys until reset. Proposed for spec v0.1 in `docs/lineage.md`. `lineage/orgchain` main `0af51dc`, time's `gh-pages` `7e08cc5`; 54 unit tests and Playwright 6/6. Token 49 (`lineage-btc-20261015`, `write:repository`) did the pushes and is deleted right after; the table is checked. Why: inscriptions live at Taproot addresses, and an agent's addresses belong in what it publishes. diff --git a/docs/lineage.md b/docs/lineage.md index 7c4d493..80ec3fb 100644 --- a/docs/lineage.md +++ b/docs/lineage.md @@ -25,9 +25,10 @@ app ([`lineage/orgchain`](https://teahub.xyz/lineage/orgchain)). Found a holding belts, record decisions, graduate and close. Each act is a `lineage/v0` inscription whose parent is the node that authorizes it, on a private toy chain in the browser with pretend money. Time is a tempo (each act its own beat, or acts cued and landed together every 10, 30 or 60 s, or by hand), and a slider replays any holding beat by beat. Every -node holds its inscription at its tapkey, which is its npub with the BIP-86 tweak (a lab root per holding, BIP-85 org -seeds, seats as accounts), and shows its leaves as [the key tree](https://lineage.yolopreneur.lol/) derives them: ssh, -git, dkim and wg for agents; ssh-ca, mtls and noise for orgs. Each act is signed by whichever key holds the authorizing +node holds its inscription at its Taproot address (BIP-86 at its account: a lab root per holding, BIP-85 org seeds, +the org as account 0 and seats as accounts 1..n), lists its SegWit address and npub beside it, and shows its leaves as +[the key tree](https://lineage.yolopreneur.lol/) derives them: ssh, git, dkim and wg for agents; ssh-ca, mtls and noise +for orgs. Each act is signed by whichever key holds the authorizing inscription, and graduation is a claim by the org's fresh root, countersigned by its derived key, with the derived subtree re-keying under it. Closing is still a recorded event. @@ -56,6 +57,10 @@ subtree re-keying under it. Closing is still a recorded event. derived birth (kind 5). - `badge` — NIP-58: the org that runs the dojo publishes a badge definition per skill × belt (kind 30009) and awards it to a seat's npub (kind 8); the seat lists what it holds in its profile badges (kind 10008). +- `btc` — every account gets standard Bitcoin addresses at the same index as its NIP-06 key: BIP-86 Taproot + `m/86'/0'/'/0/0` for inscriptions and BIP-84 SegWit `m/84'/0'/'/0/0` for payments (i = 0 is the org, whose + SegWit branch is its treasury; agents are i ≥ 1). The keyring lists both (`key` = `taproot`, `segwit`), so no one + has to derive an address from an npub. ## Not built yet - The root (operator's decision).