<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/docs/design/011-pure-transport.md, branch master</title>
<subtitle>Verified execution runtime unifying state, persistence, and replication.
</subtitle>
<id>http://git.yeowoo.org/pure/atom?h=master</id>
<link rel='self' href='http://git.yeowoo.org/pure/atom?h=master'/>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/'/>
<updated>2026-09-29T17:15:11Z</updated>
<entry>
<title>Say what adopting the link took, and how it fares against ngtcp2 (102)</title>
<updated>2026-09-29T17:15:11Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T17:15:11Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b09bda62059e11ee43ae6d1fd62bf31e2e4fbde6'/>
<id>urn:sha1:b09bda62059e11ee43ae6d1fd62bf31e2e4fbde6</id>
<content type='text'>
102: the spec (012) and a receiver written from it alone; the four holes
writing it found (REFUSED, the record's size, a peer's run places, the
memo's places beside) and the credit M6 showed fixed at 1,024 records;
M6 with ngtcp2 as a third, two rounds. Under reordering Pure carries the
most (45 Mbit/s; ngtcp2 29-47, quinn 1-2), under random loss the three
are the same, on a clean bottleneck Pure carries 3-5 % less (its framing,
some 112 B a packet to QUIC's 41), and where loss and reordering meet
ngtcp2 carries 1.3-3.6 times as much: undoing a loss it took for
reordering, it restores the window a real loss had cut too (its log: 22
of 34 undos past the window before the last cut; none without
reordering). Shares beside TCP stay within 25 %.

011 and the status table say so; 012 also says that a receiver answers
within 25 ms (a sender's PTO counts on it), that a shape and a record's
bytes are the app's, and why a packet of the past does no harm.
</content>
</entry>
<entry>
<title>Specify the link (012) and make it the default between nodes (011)</title>
<updated>2026-09-29T15:46:19Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T15:46:19Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=2a9960f086eeccf2ee58decc11b6d3f2de13699e'/>
<id>urn:sha1:2a9960f086eeccf2ee58decc11b6d3f2de13699e</id>
<content type='text'>
012 says what goes on the wire, enough for another implementation: the
header, the key id, the version and why it is not negotiated on the
wire, the static secret, HKDF's salt and infos, the nonce, epochs'
chain, the thirteen frames byte by byte, what each side must do, the
values that are the spec's and those each side picks, the two words a
receiver says (LOST, REFUSED), what an attacker gets, and what is known
not to hold. A receiver written from it alone, in Python, links with a
pure-serve node through epoch 1 (check.py).

011's last row of its stop table is met: H1-H4 held, every check passes,
CPU within 10 % of QUIC at 61 B and 25 % under it from 1 KiB, the share
with TCP within 25 %, 3,097 lines of C. Links without connections are
now the default between Pure nodes; HTTP stays the boundary to others,
and relayed sealed sends stay as they are. 006, 009 and the README say
so.
</content>
</entry>
<entry>
<title>Say how the four limits left went: three solved, one measured away (101)</title>
<updated>2026-09-29T15:15:22Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T15:15:22Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=590cbb9d0c73c9e48ac4a637c2e88a7e99c7965f'/>
<id>urn:sha1:590cbb9d0c73c9e48ac4a637c2e88a7e99c7965f</id>
<content type='text'>
A path MTU black hole is seen and the link goes back to 1,200 bytes; a
receiver that lost its memo says LOST and M2 without a memo catches up
in 0.4-0.5 s, not 7.7; M5 stands beside ngtcp2 too (Pure 25 % lighter
than both QUIC from 1 KiB, 1.04 of ngtcp2 and 0.90 of quinn at 61 B);
and the stream's name in every packet, 096's guess for 61 B's gap, cost
nothing measurable, so it stays. 098 notes the one line LOST changes.
</content>
</entry>
<entry>
<title>Say that a receiver moved to another machine is followed, and how (100)</title>
<updated>2026-09-29T14:17:40Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T14:17:40Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=7ad006f6f2d52c105ce6767d34fbd8a7abed4012'/>
<id>urn:sha1:7ad006f6f2d52c105ce6767d34fbd8a7abed4012</id>
<content type='text'>
H3 of design 011 stands: with ten thousand devices sending 2,000 records
a second, the node's store, key and memo carried to another address,
nothing stopped for a 100 ms step, the moved node made no X25519, and
every record was applied once. Each device's first record after the move
waits one probe (30-45 ms here), as its first packet finds no way there.
The search found the listener answering from an address other than the
one a packet came to, and a link that looked for its receiver after its
probe went, losing every answer. H1-H4 are all measured now; 61 B's CPU
a delivery is at the edge of the criterion, to be looked at before step
5 (adoption and a specification).
</content>
</entry>
<entry>
<title>Say what epochs cost a link, and what the search for it found (099)</title>
<updated>2026-09-29T12:58:44Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T12:58:30Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=0bbc12658c63f5f5fce2683798d4ac08b1e26e08'/>
<id>urn:sha1:0bbc12658c63f5f5fce2683798d4ac08b1e26e08</id>
<content type='text'>
Forward secrecy, 098's first task left: keys that leak later open only
epoch 0. M2 after the epoch began and after a restart is as before it
(p50 0.4 ms, p99 0.8 ms, the same CPU, no X25519 on restart). It costs a
p50 of 0.7-1.0 ms more while ten thousand devices first meet and for
about 40 s of accepts after, and a receiver that lost its memo now
stalls 0.8 s and catches up in 7.7 s, not 0.2-0.7: it lost the epochs,
and each sender opens one again. The search also found a packet more a
device from each of M6's path probe and the security checks' challenge,
and a load generator whose own pass over its devices was the floor of
the latency it measured. 098's note that epochs narrow KCI to the first
epoch was wrong; corrected.
</content>
</entry>
<entry>
<title>Say what an attacker on the path could do to a link, and what now stops it (098)</title>
<updated>2026-09-29T11:07:02Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T11:07:02Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=f5ce5e2b6ff0f72cc506e464d0ebfad00bed3532'/>
<id>urn:sha1:f5ce5e2b6ff0f72cc506e464d0ebfad00bed3532</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Measure a link on paths of loss, reordering and a bottleneck, against quinn (097)</title>
<updated>2026-09-29T10:49:32Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T10:49:32Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=8140a59205911170e151c95ed5596db7aa0d5ba5'/>
<id>urn:sha1:8140a59205911170e151c95ed5596db7aa0d5ba5</id>
<content type='text'>
M6 of design 011: with a 50 Mbit/s bottleneck, a link carries 21-41
times quinn's goodput when packets reorder, the same under random loss,
and 1.3-3.5 times with both; its p99 at 50 records a second is the same
or shorter; beside TCP CUBIC it takes 0.48-0.55 of the path, inside the
guardrail. Only on a clean path is it 3-5% below quinn.
</content>
</entry>
<entry>
<title>Say why the links became a part, and not a repository (009, 011)</title>
<updated>2026-09-29T06:23:01Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T06:23:01Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=9c5471471711d904363de28827417da8836b8431'/>
<id>urn:sha1:9c5471471711d904363de28827417da8836b8431</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Measure the CPU a record costs a link, against quinn (096)</title>
<updated>2026-09-29T05:24:43Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-29T05:24:43Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=c97e4e1a203d13852d5f7cd4a404f88b44f4064f'/>
<id>urn:sha1:c97e4e1a203d13852d5f7cd4a404f88b44f4064f</id>
<content type='text'>
M5 of design 011. At first a link spent eight times quinn's CPU on a small
record: scans of the backlog, a system call and allocations a record, 19
bytes of framing. After the seven changes before this one, the transport
alone (transport.c; a backlog drained, every record checked) spends per
record 0.30 us for 61 bytes (quinn 0.27: 1.06 to 1.12 times over three
campaigns, at the design's 10 % line), 2.91 us for 1,013 bytes (quinn
3.88) and 45.2 us for 16,013 bytes (quinn 60.9): 25 % less for the larger
ones, and 30 % more records a second. What is left for small records is
per packet: the stream's names and the RECORDS head. quinn's numbers carry
no confirmation of storing and no exactly once.

Between two pure-serve nodes the links spend more per record, woken at
the receiving app's pace. Filling the sender showed the outbox is written
whole at every save, as the numbers heard were (094): the next thing to
change.

run.py gains --transport and --drain; the quinn service reads a drain a
chunk at a time and its client writes 64 KiB at a time.
</content>
</entry>
<entry>
<title>Measure a restart under load and a first contact (095)</title>
<updated>2026-09-28T18:57:27Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-28T18:57:27Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=5f8c14f774b81bd6d65d531035eae61b79b1d12c'/>
<id>urn:sha1:5f8c14f774b81bd6d65d531035eae61b79b1d12c</id>
<content type='text'>
M2 and M4 of design 011. Ten thousand devices send an order every five
seconds (2,000 a second); the receiver is killed (-9) at about 21 s and
started again at once. With its secrets remembered the node shows no
100 ms step without an order stored, catches up in 0.2 s, spends no more
CPU than before and makes no X25519; 34 orders were sent again, and
every order made was applied once (three rounds; on the SD card the
same, with 0.2 s silent). Without the memo it makes 10,000 X25519, 1.6 s
of CPU. quinn under the same load stops for 1.0 s and catches up after
10.9 s: 10,115 new connections, about 7 s more of the service's CPU and
8 s of the clients'. A first contact takes Pure one round trip and QUIC
two, at 10, 50 and 100 ms of RTT.

run.py --restart and --first-contact make them; the quinn harness gains
a fixed port with a reset key from its key, clients that connect again,
and a drain for M5.
</content>
</entry>
</feed>
