Ship lineage.yolopreneur.lol (key tree page) #55

Closed
opened 2026-10-14 21:11:44 +00:00 by teahubxyz · 1 comment
Owner

Operator asked for the Lineage key tree to live at its own venture subdomain.

What it is: one BIP-39 seed derives the whole org tree in the browser — ETH key for legal control (Otoco NFT), BTC treasury, the org's nostr identity, agents (NIP-06 accounts) with HKDF ssh/git/dkim/wg leaves, and node keys (SSH CA, mTLS, Headscale noise). Agents get org-signed birth certificates and self-signed keyring events (kind 30078); revocation is a NIP-09 deletion. The page also renders the nostr.json / lineage.json you'd publish and the spec v0 it runs.

Shipping it the venture way: static, ventures/lineage/ on gh-pages, served by Teahub pages at the wildcard. Nothing else provisioned.

  • index.html with a strict CSP: default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'none' (the page can't send anything; the browser enforces it)
  • assets/: lineage.css, app.js, and the crypto libraries as four same-origin scripts (lc-1-hashes, lc-2-base, lc-3-curves, lc-4-keys), built from @noble/curves, @noble/hashes, @scure/bip32, @scure/bip39, @scure/base at tag 2.4.0

Checked before commit (60 checks): BIP-84, ETH and NIP-06 test vectors; an independent Python re-derivation of every key (BIP-39/BIP-32/HKDF/Ed25519/X25519) and every event signature (BIP-340); OpenSSH/PEM files load in cryptography; CSP-on run blocks outbound and same-origin fetch; no horizontal scroll at 320px.

Not in scope: a ventures.json entry for the index (needs a screenshot).

DONE: https://lineage.yolopreneur.lol/ serves the page and all six assets with 200s and the right content types, the served bytes match the committed git blobs, receipt here.

Operator asked for the Lineage key tree to live at its own venture subdomain. What it is: one BIP-39 seed derives the whole org tree in the browser — ETH key for legal control (Otoco NFT), BTC treasury, the org's nostr identity, agents (NIP-06 accounts) with HKDF ssh/git/dkim/wg leaves, and node keys (SSH CA, mTLS, Headscale noise). Agents get org-signed birth certificates and self-signed keyring events (kind 30078); revocation is a NIP-09 deletion. The page also renders the nostr.json / lineage.json you'd publish and the spec v0 it runs. Shipping it the venture way: static, `ventures/lineage/` on `gh-pages`, served by Teahub pages at the wildcard. Nothing else provisioned. - `index.html` with a strict CSP: `default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'none'` (the page can't send anything; the browser enforces it) - `assets/`: `lineage.css`, `app.js`, and the crypto libraries as four same-origin scripts (`lc-1-hashes`, `lc-2-base`, `lc-3-curves`, `lc-4-keys`), built from @noble/curves, @noble/hashes, @scure/bip32, @scure/bip39, @scure/base at tag 2.4.0 Checked before commit (60 checks): BIP-84, ETH and NIP-06 test vectors; an independent Python re-derivation of every key (BIP-39/BIP-32/HKDF/Ed25519/X25519) and every event signature (BIP-340); OpenSSH/PEM files load in `cryptography`; CSP-on run blocks outbound and same-origin fetch; no horizontal scroll at 320px. Not in scope: a `ventures.json` entry for the index (needs a screenshot). DONE: https://lineage.yolopreneur.lol/ serves the page and all six assets with 200s and the right content types, the served bytes match the committed git blobs, receipt here.
teahubxyz referenced this issue from a commit 2026-10-14 21:12:35 +00:00
time added the queued label 2026-10-14 21:22:16 +00:00
Author
Owner

Shipped: https://lineage.yolopreneur.lol/ is live, served from ventures/lineage/ on gh-pages.

Commits (gh-pages)

Served vs committed
Fetched with curl from hb-5. For every path, the live sha256 equals the sha256 of the raw blob on gh-pages.

path status content-type bytes sha256
/ 200 text/html; charset=utf-8 5809 8e3a195cfc5aea6d14d7ecc4067b5e389274a81b4a430445e7e0ec3cbc565f4e
/assets/lineage.css 200 text/css; charset=utf-8 12695 02398cd126aa2af15994c17c80d14a361db2e648b858a21783824851c432333f
/assets/lc-1-hashes.js 200 text/javascript; charset=utf-8 39111 e80f4fcb094312febe4300dc38134214795b9138ed17b0e2b48190108e766c0b
/assets/lc-2-base.js 200 text/javascript; charset=utf-8 16944 f4aa86caf89fb0315a4344fcd8902428e1c14a29dfab6686b770113d3ace4108
/assets/lc-3-curves.js 200 text/javascript; charset=utf-8 59021 92df6c518fc0a5ba4cafda69dbeb1192fe3cd3b8802162aac6ce0ad29e303824
/assets/lc-4-keys.js 200 text/javascript; charset=utf-8 25561 d97cd652b0021df799af65ee569d83ea1f9d5836f25539e1b6780f9a6f65a8d6
/assets/app.js 200 text/javascript; charset=utf-8 35607 1ce5df6c8e7cfd12133db7d939b79029594d16a1c012f2b1bbb483c2851b82c9

Headers

  • The pages server adds no CSP header, so the page's meta CSP is the only policy.
  • cache-control: public, max-age=60.
  • JS is served with x-content-type-options: nosniff.

Live browser check
Playwright 1.63.0, headless Chromium on hb-5, CSP enforced:

  • The tree renders: 12 words, 15 rows.
  • The BIP-84 vector gives bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu, the published zpub, 0x9858EfFD232B4033E47d90003D41EC34EcaEda94 and fingerprint 73c5da0a.
  • The NIP-06 vector gives npub1zutzeysacnf9rru6zqwmxd54mud0k44tst6l70ja5mhv8jjumytsd2x7nu.
  • Both of agent-a's signed events verify.
  • All 7 requests go to lineage.yolopreneur.lol.
  • There are no page or console errors.
  • A fetch from the page is blocked by connect-src.
  • There is no horizontal scroll at 390px.

Two checks failed on the first run because they read innerText, which the CSS uppercases. Read with textContent, both pass.

Still open (out of scope above): a ventures.json entry for the index.

Shipped: https://lineage.yolopreneur.lol/ is live, served from `ventures/lineage/` on `gh-pages`. **Commits (gh-pages)** - 77a1714cfe53 `assets/lineage.css` - d5659a0f89f5 `assets/lc-2-base.js`: second commit. The first copy lost an invisible DEL (0x7f) character, so this one writes it as the escape `\x7f`, which is the same JavaScript. - 0402ffeb0604 `assets/lc-4-keys.js` - 15fc5035aa1b `assets/lc-1-hashes.js` - 55df34174993 `assets/lc-3-curves.js` - e944a70cfbaa `assets/app.js` - ddb3a61dee4a `index.html` **Served vs committed** Fetched with curl from hb-5. For every path, the live sha256 equals the sha256 of the raw blob on `gh-pages`. | path | status | content-type | bytes | sha256 | |---|---|---|---|---| | `/` | 200 | text/html; charset=utf-8 | 5809 | `8e3a195cfc5aea6d14d7ecc4067b5e389274a81b4a430445e7e0ec3cbc565f4e` | | `/assets/lineage.css` | 200 | text/css; charset=utf-8 | 12695 | `02398cd126aa2af15994c17c80d14a361db2e648b858a21783824851c432333f` | | `/assets/lc-1-hashes.js` | 200 | text/javascript; charset=utf-8 | 39111 | `e80f4fcb094312febe4300dc38134214795b9138ed17b0e2b48190108e766c0b` | | `/assets/lc-2-base.js` | 200 | text/javascript; charset=utf-8 | 16944 | `f4aa86caf89fb0315a4344fcd8902428e1c14a29dfab6686b770113d3ace4108` | | `/assets/lc-3-curves.js` | 200 | text/javascript; charset=utf-8 | 59021 | `92df6c518fc0a5ba4cafda69dbeb1192fe3cd3b8802162aac6ce0ad29e303824` | | `/assets/lc-4-keys.js` | 200 | text/javascript; charset=utf-8 | 25561 | `d97cd652b0021df799af65ee569d83ea1f9d5836f25539e1b6780f9a6f65a8d6` | | `/assets/app.js` | 200 | text/javascript; charset=utf-8 | 35607 | `1ce5df6c8e7cfd12133db7d939b79029594d16a1c012f2b1bbb483c2851b82c9` | **Headers** - The pages server adds no CSP header, so the page's meta CSP is the only policy. - `cache-control: public, max-age=60`. - JS is served with `x-content-type-options: nosniff`. **Live browser check** Playwright 1.63.0, headless Chromium on hb-5, CSP enforced: - The tree renders: 12 words, 15 rows. - The BIP-84 vector gives bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu, the published zpub, 0x9858EfFD232B4033E47d90003D41EC34EcaEda94 and fingerprint 73c5da0a. - The NIP-06 vector gives npub1zutzeysacnf9rru6zqwmxd54mud0k44tst6l70ja5mhv8jjumytsd2x7nu. - Both of agent-a's signed events verify. - All 7 requests go to lineage.yolopreneur.lol. - There are no page or console errors. - A `fetch` from the page is blocked by `connect-src`. - There is no horizontal scroll at 390px. Two checks failed on the first run because they read `innerText`, which the CSS uppercases. Read with `textContent`, both pass. **Still open** (out of scope above): a `ventures.json` entry for the index.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: teahubxyz/time#55