<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pure/prototypes/connections/test-module.c, 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-27T12:14:38Z</updated>
<entry>
<title>Lay Pure out as a core with the parts selected around it</title>
<updated>2026-09-27T12:14:38Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T12:14:38Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=37d3a1e152707d2da587440c4cea8601b9ef0fd2'/>
<id>urn:sha1:37d3a1e152707d2da587440c4cea8601b9ef0fd2</id>
<content type='text'>
The app model, the tree store and the HTTP host lived in
prototypes/connections among the earlier document runtime, the store was
known only by its format's name, and Vega compiled six Pure sources by path.
Now, as the README's principle has it:

  core/   runtime, flow and the app model (module*.c), with what the core
          asks of storage (state.h, store.h)
  store/  the tree store (PURETRE3, PUREREC1)
  serve/  pure-serve: HTTP host, outbound delivery, JSON in place
  cli/    pure-run, pure-edit-module

A top-level make builds libpure.a (app model and store, for hosts to link)
and the hosts; make check runs the store's and the app model's tests. The
earlier runtime still builds from prototypes/connections against core/ and
store/ (check, check-tree and check-core pass). Design 009 records the rule:
parts by role behind libraries; git repositories split by coupling, so the
store stays here while its contract moves with the core, and Vega stays apart.

</content>
</entry>
<entry>
<title>Deliver an app's saved sends over HTTP, in order and in batches (083)</title>
<updated>2026-09-27T07:09:40Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T07:09:40Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=5d3a7cefa27f3fe20a9c6991fb044815b38aac01'/>
<id>urn:sha1:5d3a7cefa27f3fe20a9c6991fb044815b38aac01</id>
<content type='text'>
pure-serve --send OUTPUT=http://host:port/path wires an output: after
every save the owner queues the new sends as JSON (fields and groups)
and a thread per output posts them in order with X-Pure-Source,
X-Pure-Sequence and Idempotency-Key. A 2xx, or a Pure receiver's
refusal, delivers; the owner then trims. 408, 429, 5xx and no answer
are sent again after a pause growing to 10 s, other answers every 10 s:
nothing is dropped. A Pure receiver applies a delivered message with
pure_app_deliver (now taking placed fields) and advertises
X-Pure-Batch: 256; the sender then posts up to that many numbers in a
row as one JSON array (X-Pure-Count), applied in order in one burst
with one save.

Delivery kept up with orders once batched (391 deliveries/s one at a
time; a backlog of 20,000 went at 60k/s). With four clients ordering,
killing the receiver and then the sender (-9) left the receiver's count
and total equal to what the sender saved, five times and under ASan.

</content>
</entry>
<entry>
<title>Send messages as part of events and apply delivered ones once (078)</title>
<updated>2026-09-27T06:54:35Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T06:54:35Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=01c87d2c204723905457f225b3113dac82eb0ced'/>
<id>urn:sha1:01c87d2c204723905457f225b3113dac82eb0ced</id>
<content type='text'>
An output (input kind 5) is a message the app sends; SEND (72) takes
an output's field values in order in a handler, lays them out as a
message's payload and keeps it, numbered per output from 1, with the
event's changes: a failed event sent nothing, and a failed save takes
back every send since the last save with its numbers. A host sees only
saved sends (pure_app_outbox) and trims what its receiver has saved
(pure_app_trim, gone with the next save). pure_app_deliver applies a
message from a named source once: a number heard before succeeds
without applying, a refused message counts as heard, a failed save
forgets what it heard.

Sends, numbers and heard numbers are the app's links state, stored
whole in one runtime document (PLK1) with the states, in the same
commit. Outputs follow their names across module changes; a module
that drops or retypes an output with sends left is refused, and a
dropped output's number is kept for when it returns. Killing the
process at every commit stage leaves an event and its send, or a
delivery and its effect, together or neither. pure-serve answers a
post to an output or a timer with 404 no_input.

</content>
</entry>
<entry>
<title>Name message fields by paths and take variable fields where they are</title>
<updated>2026-09-27T06:30:38Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-27T06:30:38Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=194d243165c2b78d64e0263f39f7a63dbe4a1310'/>
<id>urn:sha1:194d243165c2b78d64e0263f39f7a63dbe4a1310</id>
<content type='text'>
A message field's name may now be a path of identifiers joined by dots
(user.name, a field inside the group user); a module that names both a
field and a group (user and user.name) is refused, as are empty,
leading, trailing or digit-first segments. A module may have 64
message fields instead of 32 (PureModule 11.9 to 13.2 KiB).

pure_app_message_fields takes each variable field's start and size in
the payload, so a host that parsed a request in place passes the
fields' bytes where they are instead of laying them out after the
prefix. The runtime checks them as before: a field past the payload
fails with limit, a text that is not UTF-8 with encoding.

</content>
</entry>
<entry>
<title>Snapshot an app's saved states for readers on other threads</title>
<updated>2026-09-26T21:56:32Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T21:56:32Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=42021a500d19dbe091075338d1a621498a81f167'/>
<id>urn:sha1:42021a500d19dbe091075338d1a621498a81f167</id>
<content type='text'>
Right after a save, pure_app_snapshot makes a read-only snapshot of the
saved states: numbers are copied, text states are frozen drafts that
share the store mapping (pure_draft_freeze, no copy), and lists are
copies of their item pointers that share the items. An unchanged list
shares the last snapshot's copy. pure_app_read binds a reader app on
another thread to a snapshot so the existing view functions read it.

A shared item never changes again: a list stamps each item with its
share count, copies a shared item it changes, and retires shared items
it lets go instead of freeing them. Snapshots form a chain that goes
oldest first, and items retired while a snapshot was the newest go
with it. References are atomic and may be released on any thread.

test-module checks that each snapshot equals the app, that kept
snapshots stay as made through changes, removals, a module switch, the
app stopping and the store closing, that a failed save's snapshot
equals the one before, and that two threads read the newest snapshots
while the app goes on (also under ASan, UBSan and LeakSanitizer).

</content>
</entry>
<entry>
<title>Add time: timers, now, floor and a floored modulo</title>
<updated>2026-09-26T16:55:14Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T16:55:14Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=ef7ac7332f330fddc2de6194f926e0c0a84ca2b4'/>
<id>urn:sha1:ef7ac7332f330fddc2de6194f926e0c0a84ca2b4</id>
<content type='text'>
An input may be a timer (kind 4, its period of 1 ms to a day in place of
a key name): pure_app_tick delivers a tick, an event saved like a key's.
NOW gives handlers the time the host set in PureApp.now (milliseconds
since 1970, UTC), so a script replays any time and views stay functions
of state; FLOOR and MOD take times apart, MOD taking the divisor's sign as
floor division leaves it, a zero too. pure-run gains time MS and tick NAME.

</content>
</entry>
<entry>
<title>Take messages of number and text fields, several variable ones, as JSON</title>
<updated>2026-09-26T16:48:09Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T16:48:09Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=ae48b510c9eec3e47ea551b4c4cad640d13310cd'/>
<id>urn:sha1:ae48b510c9eec3e47ea551b4c4cad640d13310cd</id>
<content type='text'>
A message field is now a u32, a number (binary64), bytes or text, and
variable fields may be several and anywhere: the payload's prefix holds
the fixed fields and each variable field's length but the last one's,
which takes the rest; a module whose one bytes field came last is laid
out as before. On arrival a length past the payload, a text that is not
UTF-8 or a number that is not finite fails the message.

pure-serve fills an input's message from a JSON object body
(Content-Type: application/json) on the connection thread before the
request is ready, so the owner never parses and replies are still
borrowed: the ingress is [u32 payload size][payload][the JSON as it
came]. A missing, unknown, doubled or mistyped field, or text that is not
JSON, answers 400 and the request never runs. Numbers may come in the
query too.

</content>
</entry>
<entry>
<title>Add keyed lists and text comparison</title>
<updated>2026-09-26T15:38:12Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T15:38:12Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=b6061fa10436bad78d7601a36712101dfe873643'/>
<id>urn:sha1:b6061fa10436bad78d7601a36712101dfe873643</id>
<content type='text'>
A list state may name a key field of its record (the flags word of its
entry: field + 1). A keyed list keeps its items in key order, numbers by
value and texts by their bytes, each key once: LIST_APPEND places an item
by halving and fails with the new fault exists (PURE_CONFLICT) when the
key is there; LIST_FIND gives the index of a key's item and LIST_HAS
whether it is there. The verifier refuses inserting by position and
changing a key. Maps, sets and sorted maps are one list with an order
rule, so tables, filters, folds, indices, storage and replacement stay
as they are.

A module that opens over a list not in its key order (one that was not
keyed, keyed by another field, or stored so) puts it in order, moves its
indices with their items and stores it again; two items with one key
refuse the module rather than drop one.

TEXT_COMPARE compares two texts by their bytes under one of the six
relations.

</content>
</entry>
<entry>
<title>Add first: the index of the first item a block keeps</title>
<updated>2026-09-26T10:35:20Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T10:35:20Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=92f5545efb7aab0b3a4a4c73a65364ef519cd5d4'/>
<id>urn:sha1:92f5545efb7aab0b3a4a4c73a65364ef519cd5d4</id>
<content type='text'>
A fifth fold kind, first, runs its block over the items until one leaves
a non-zero number and pushes that item's index, typed as an index of the
list, or fails not_found when none does. Handlers can so find the item to
change by a condition, as a message naming a task by its title would.

</content>
</entry>
<entry>
<title>Filter a table's rows</title>
<updated>2026-09-26T10:28:13Z</updated>
<author>
<name>eunhhu</name>
<email>necpition205@gmail.com</email>
</author>
<published>2026-09-26T10:28:13Z</published>
<link rel='alternate' type='text/html' href='http://git.yeowoo.org/pure/commit/?id=ee0791397be3dc6d5b56611b505a312f1d8350a0'/>
<id>urn:sha1:ee0791397be3dc6d5b56611b505a312f1d8350a0</id>
<content type='text'>
A table view can now carry a filter: its list goes in the byte after the
view's type (list + 1) and its code range is a block run as a column of
the list, leaving one number; the table has a row for each item the block
keeps, in the list's order. Columns read the item (ROW is the item's
position, not the row's). The filter runs once per item after a change of
the app's states, counted by a new number that never goes back (events,
points, a failed save's undo, a module replacement), and its rows serve
every cell until the next change.

pure_app_row_item and pure_app_item_row turn a table's rows into items
and back, so a host shows a focus (an index names an item) on the row it
is in and points at the item a clicked row shows. pure_app_rows now takes
a mutable app.

The checks cover rows, cells, the mapping both ways as items leave and
come back, six refusals, and 20,000 damaged filter modules.

</content>
</entry>
</feed>
