<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/tools/youtube-embed-test.js, branch master</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-10-07T19:02:51Z</updated>
<entry>
<title>Browser tests: public relays answered in the page, never reached</title>
<updated>2026-10-07T19:02:51Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-07T19:02:51Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=86d9818abfc160dac031bb292abe28d6f28fc624'/>
<id>urn:sha1:86d9818abfc160dac031bb292abe28d6f28fc624</id>
<content type='text'>
A suite run let ~90 throwaway test wallets subscribe and publish on public
relays from one home address, and nos.lol and relay.damus.io banned it.
tools/puppeteer.js wraps puppeteer-core: every socket to a non-local host
gets an in-page stand-in relay (EVENT -&gt; OK, REQ -&gt; EOSE). Tests that read
real content launch with { relays: 'read' } (real reads, publishes answered
in place); feed-live, chat-layout and cordn-ui launch with { relays: 'live' }.
LIVE_RELAYS=read|1|host,... overrides per run.

profile-key-qr: measure the QR again if a repaint swapped it out.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Feed, composer and zap tests follow today's app</title>
<updated>2026-10-07T15:27:40Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-07T15:27:40Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=dfb017c1b10cb52c24f4f0bcf745c6abea11b98f'/>
<id>urn:sha1:dfb017c1b10cb52c24f4f0bcf745c6abea11b98f</id>
<content type='text'>
- feed tests reach the Feed from the bottom nav (the chat-home row is
  gone) and seed this wallet's last feed as Following (new wallets open on
  Popular, c89050e) plus the author's profile (readiness gate)
- post-actions: its picture is made locally (it read another session's
  scratchpad), the post's own ⋯ (not the feed header's), a real tap on the
  DM picture (a tap beside a fitted picture is a tap on the post)
- composer-media / video-compress: intercept every public media host
  (ditto is first now; the tests were uploading for real)
- compose-preview: Preview is one toggle button (aria-pressed)
- thread-reply: harness has a wallet (else visitor: Reply asks to sign in),
  registers &lt;coinos-text&gt;, holds the root's id-only query; atomic send tap
- video-unmute: stubs what videoNode reaches outside its slice; preload
  none means the in-view clip is told to load
- zap-deep-profile: zap button scrolled to mid-screen (the bottom nav
  covered it)

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Media sources wait until the node is in the page; thumbnails use the cache.</title>
<updated>2026-09-27T06:42:50Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-27T06:42:50Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=93a95d1ce45d09cb833120cd61573fd88eb8ed26'/>
<id>urn:sha1:93a95d1ce45d09cb833120cd61573fd88eb8ed26</id>
<content type='text'>
Every render builds a fresh tree to diff against the live one, and a media
element starts downloading the moment its src is set, even off the
document: a sixteen-second feed scroll built 204 &lt;video&gt; and 1,416 &lt;img&gt;
elements whose loads the morph then threw away — 375 cancelled video
range requests, and full re-downloads from hosts that send no cache
headers. h() now puts the source on data-lazy-src and it becomes src only
once the node is in the page (render promotes it; a MutationObserver covers
nodes appended by hand); the morph treats the two as one attribute.

The thumbnail maker fetched every original with cache: 'reload' (38 MB in
one scroll); the face was just painted from that URL, so the cache serves.
holdScroll now recovers an anchor row that a large insert above pushed out
of the window, from the height cache. Tests: the YouTube test accepts the
in-view players autoplay loads; the stability test watches the notice for
the catch-up, since the new rows land inside the window's spacer.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
<entry>
<title>First run: "Create a new wallet" shows the twelve words at once.</title>
<updated>2026-09-21T19:04:25Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-21T19:04:25Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=9b4fa70a978e3685c9bb2b9a68f855626ac6f39e'/>
<id>urn:sha1:9b4fa70a978e3685c9bb2b9a68f855626ac6f39e</id>
<content type='text'>
No create/import tabs and no Generate button inside the wizard: the words
appear the moment the button is tapped. Underneath, "Have an existing seed
or entropy to import?" swaps to the import pane (which has its own entropy
door), and "Create a new wallet instead" swaps back with fresh words. The
create/import card elsewhere (adding an account) keeps its tabs. Tests
that entered through the old tab go through the new line.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
</content>
</entry>
<entry>
<title>The front door points at your own keys.</title>
<updated>2026-09-13T16:48:54Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-13T16:48:54Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=38b3d091e8e1bece958c0d7e80a5ee78434de933'/>
<id>urn:sha1:38b3d091e8e1bece958c0d7e80a5ee78434de933</id>
<content type='text'>
Four buttons of equal weight, and only the sign-in ones said what they
did. "Get started" said nothing, so the concrete offer on that screen was
Google — which is a convenience wrapped around a seed phrase, not an
alternative to one.

Now the page says what the wallet is before it offers a button, the way
in reads "Create a new wallet" with the cost under it (a minute, twelve
words), and the three sign-ins sit below a line labelled "or, if you
already have an account".

And the second half of the same problem: a wallet that arrives by sign-in
has a recovery phrase its owner has never seen and nobody can reissue.
So the wizard shows it once, right after the first login, while it still
reads as setting up rather than as a warning out of nowhere. "I've
written it down" is the way on; "Later" is a real answer, and the wallet
then keeps one quiet line — not a modal, not dismissible, gone the moment
the phrase is actually seen, here or in settings.

seedSeen records that per account: creating shows the words, importing
means they typed them, revealing in settings counts. Only a derived seed
starts false, which is exactly the case worth asking about.

tools/onboard-backup-test.js covers both halves, including that "Later"
leaves a reminder that survives a reload and leads somewhere.

The sixteen tests that clicked the old button by its text are updated,
and it has an id now so its copy can change without breaking them again.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
</content>
</entry>
<entry>
<title>A YouTube link in a post shows the video.</title>
<updated>2026-09-13T04:50:55Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-13T04:50:55Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6b396dc26c05a921e2387e16343a8e0e6adea9fb'/>
<id>urn:sha1:6b396dc26c05a921e2387e16343a8e0e6adea9fb</id>
<content type='text'>
All three shapes it comes in — youtube.com/watch?v=, youtu.be/, and a Shorts
link — become the video's still with a play button on it and a corner link
out to YouTube. A ?t= keeps its start time. Anything that merely looks like
one (example.com/watch?v=…) stays a link.

The player itself arrives on the first tap, not on render. A feed of ten
videos would otherwise load ten YouTube players, each one telling Google what
you're scrolling past before you've decided to watch anything — and on a
phone, ten players is the scroll. One tap and it plays in place, from
youtube-nocookie.com.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
</content>
</entry>
</feed>
