Skip to content
quarry Timeline
Login

Timeline

50 descendants and 28 ancestors of 81642956b545cc96

2026-08-16
12:53
markup: Pikchr diagrams via WebAssembly (fossil's third markup)

pikchr.c built to a standalone WASI module (-DPIKCHR_SHELL -sSTANDALONE_WASM) and run under wazero, so the CGO-free constraint holds. Its own CLI reads - and writes SVG, so the host ABI is a pipe: no memory marshalling to get wrong. Renders text/x-pikchr artifacts and pikchr fences inside markdown; a diagram that will not compile degrades to its source plus the compiler's message.

SVG does NOT ride the document policy. It gets a narrow allow-list derived by enumerating what the module actually emits (six elements, a closed geometry/paint attribute set, no script/href/foreignObject), so even a hole in Pikchr's own label escaping cannot reach a page. Fence placeholders are alphanumeric with a per-render nonce: an HTML parser rewrites control bytes, so a NUL-based marker does not survive sanitizing (caught by test). Provenance and the rebuild recipe are in the ledger. check-in: 58fe4cf214 user: dmestas tags: trunk

12:45
markup: render Fossil wiki format; fix mimetype dispatch; GFM completeness

An absent N card means text/x-fossil-wiki, not markdown — fossil's wiki_render_by_mimetype is explicit — but quarry rendered those as markdown, mangling 217 of libfossil's 443 wiki artifacts ([target|label] links came out as literal text). Adds a Fossil wiki renderer (the seven rules from fossil's own wiki.wiki: paragraphs, single-level * and # lists, indented paragraphs, [target|label] links through the existing Resolver, verbatim/nowiki, HTML pass-through gated by the sanitizer), dispatches on mimetype exactly as fossil does, and stores forum posts' N card so they dispatch too. Fossil site-relative targets quarry cannot serve render their label as text rather than showing wiki source.

Also GFM completeness: footnotes and auto heading IDs, with the sanitizer policy widened to admit what goldmark actually emits (a footnotes div, not section — caught by test). check-in: 45c96a506b user: dmestas tags: trunk

10:39
web: fit the timeline on phone widths

The card's metadata run was the widest line, so auto table layout preferred it, the table exceeded the viewport, and .tw scrolled sideways — putting the right-aligned check-in/user/branch off-screen on a 390px phone. Stack the meta items under 640px (max-content drops to the longest single item) and allow long comment titles to wrap. table-layout:fixed was tried first and rejected: it mis-sized the graph column to ~225px and squeezed cards to two words a line. Desktop is untouched; the graph lint stays clean at both widths. check-in: b43a9a7730 user: dmestas tags: trunk

10:29
technote: fold the C card and show it as the title

Technotes carry a C card (Fossil's timeline title) but the fold dropped it, so the timeline and listing showed raw 40-hex event ids — libfossil's real technotes read 'Technote: 0a83aac2...' instead of 'Project milestone: merge feature ported in'. Fold the comment, prefer it in the timeline and listing, and add it additively (ALTER, not a rebuild) for indexes created by the older schema. Also corrects a stale '-- C card' note on forum_post.body, which is the W card. check-in: 254d554df8 user: dmestas tags: trunk

10:21
rfcs: v2 write plane — all four record types web-authored check-in: 4acdda438c user: dmestas tags: trunk
10:21
write plane: web-authored forum and technotes (v2)

forum.post/forum.reply/technote.add Command ops on zit#76's verbs, lease-guarded with read-your-writes and activity triggers; new-thread, reply, new-technote and technote-edit forms, all gated. Two correctness points: technote.add widens an event-id prefix to the full id (a prefix would mint a NEW technote instead of editing), and forum.reply shares forum.get's {root} path parameter (differing names on one template is invalid OpenAPI — spec-lint caught it).

Fossil has the same surfaces (technoteedit, forumedit), so these are web faces of existing record types, not invented divergence. Wiki authoring already shipped earlier. Verified live in-browser: thread -> reply -> timeline, and technote edit superseding without duplicating. check-in: 4b68c8aae4 user: dmestas tags: trunk

10:05
untrack fixtures/out clones swept in by addremove (build outputs, not source) check-in: 5e8de4dd50 user: dmestas tags: trunk
09:59
remove stray quarry build artifact from tracking check-in: 6af3019d57 user: dmestas tags: trunk
09:57
chat: drop DAG archival — keep chat ephemeral like Fossil

Reversed 0001 §5's 'durability is the DAG': minting chat into synced, content-addressed forum artifacts writes casual chatter permanently into the DAG, the opposite of Fossil's deliberate chat ephemerality (server-local, auto-purged, never synced). Chat stays live + the 7-day JetStream window; durable archival becomes a future quarry-specific/S3 concern, not near-term. Removes internal/chatarchive, its wiring and flags, events.KV, and the zitcli forum/technote wrappers it used (they return with v2 web-authored forum). Chat itself is unchanged. check-in: 3d68e9b401 user: dmestas tags: trunk

05:17
rfcs: chat forum-archival shipped (zit#76 landed) check-in: db788a07c6 user: dmestas tags: trunk
05:16
chat archival: fold chat into forum-thread artifacts (0001 §5 durability)

internal/chatarchive: batches a channel's messages (per N or T) and mints them as a 'Chat archive' forum thread through zit forum post/reply (zit#76) — one thread per channel, each batch a reply carrying the transcript, so history clones with the repo. Minting runs only on the lease holder; non-holders drop their buffers (the holder's archive folds back to every node). zitcli gains ForumPost/ForumReply/ TechnoteAdd. --chat-archive on by default. Verified live: chat batches materialize as forum threads and reply to the same thread. check-in: bd91af3158 user: dmestas tags: trunk

05:11
zitcli: use diff -R on bare stores (zit#69); re-tighten write ordering (zit#75)

zit diff now accepts -R for --from/--to, so quarry diffs bare stores without a checkout. Millisecond D cards restore real same-second write order, so TestWriteOps asserts strict last-write-wins again. check-in: 76b09e7fb8 user: dmestas tags: trunk

05:04
rfcs: v1 shipped — chat and notify wiring complete check-in: f6f93c81cc user: dmestas tags: trunk
05:04
notify: fire mention and activity triggers to the notify companion (0001 §5)

internal/notify: a Novu-compatible POST /v1/events/trigger client (quarry triggers, notify owns delivery). chat.post parses @mentions and fires quarry-mention per handle; wiki/ticket write ops fire quarry-activity to a repo:<name> topic. All best-effort — a notify outage never fails the user action — with idempotency keys so replays dedup. --notify enables it (disabled by default). Verified live: mention and activity triggers POSTed with the right Novu shape. check-in: 37f62c9a82 user: dmestas tags: trunk

04:50
chat: per-repo live channel over NATS (0001 §5)

internal/chat: messages fan out over NATS with a 7-day JetStream window (replay on join), keyed by project code so a channel is shared across nodes. chat.history/chat.post ops (post is not lease-gated — it mutates no store); web page with on-load history, a plain post form (no-JS baseline), and an SSE append stream (Datastar enhancement). Verified live: form post + cross-connection SSE delivery in-browser, and cross-node fan-out on a shared external NATS. Durable forum-thread archival waits on zit forum verbs (zit#76); the window is interim durability. check-in: 5670d3643d user: dmestas tags: trunk

04:31
read plane: forum threads and technotes (v1 completion)

Fold Forum (G/H/I/W cards) and Technote (E/W cards) artifacts into forum_post/technote tables; forum.list/get and technote.list/get ops; threaded forum pages and technote pages through the sanitizer-gated markup pipeline; both kinds join the unified timeline (y=e|f) and nav. The parser already handled these types, so this is fold+render only. Verified against libfossil's real history: 35 forum threads, 26 technotes render, graph lint clean. check-in: c212383053 user: dmestas tags: trunk

04:06
reindex: --nats support for multi-node cluster rebuild

reindex was embedded-only, so a node's index could not be rebuilt in an external-NATS deployment (the durable position and shared cursor live in NATS, outside a node's --data). --nats routes reindex through the shared plane; the reset republishes the census that every node's fold absorbs. Validated on Linux/hetzner over external NATS. check-in: 87282e7532 user: dmestas tags: trunk

03:49
rfcs: external NATS shipped, retention correction, trio status check-in: 9781c03cea user: dmestas tags: trunk
03:48
scale-out: external NATS + multi-node fan-out (trio part 1)

events.Connect joins an external NATS so N nodes share one plane; --nats selects it (embedded stays the single-node default). Retention switched work-queue -> limits+cap: work-queue load-balanced one copy across nodes, leaving each index partial; limits fans out to per-node durables (name now carries a hashed node id) while MaxBytes/MaxAge keep disk bounded. Lease refusals surface as 503 (ops.ErrUnavailable), not 500. Verified live: two nodes on one external NATS + shared store, each folds the full store, the leased node writes while the other 503s and still folds the write cross-node. check-in: 89e4991bbf user: dmestas tags: trunk

02:34
rfcs: leases shipped; phase 4 complete; zit#74/#75 status check-in: 63ee2a682e user: dmestas tags: trunk
02:34
lease: single-writer coordination (0001 §3)

NATS KV TTL lease per store keyed by project code. Write ops and sync pushes route through Guard: renew-or-acquire, failover grace after displacing a holder, commit-point re-check before the write, and writes-refuse when the coordinator is unreachable (correctness over availability). Single-node holds its own lease with no grace delay; the machinery and failure posture are identical at N nodes. Tests: mutual exclusion, failover, coordinator-down refusal. check-in: d1436c2071 user: dmestas tags: trunk

02:18
security: close whitespace-card sync-gate bypass; write-op input 400s

Audit found a critical: scanRequest matched card keywords with a raw byte-prefix, so a push/login card indented by any Fossil-whitespace byte (SP/HTAB/VT/FF/CR) was invisible to the gate but still honored by the zit backend — an unauthenticated write to a gated repo. Now tokenizes exactly as zit's tokenizeCard (leading-whitespace-skipping), verified live. Also: gate GET edit/new pages (were ungated), reject control chars in wiki names (400 not 500), ticket.set no-fields 400 via new ops.ErrInvalid. check-in: 9db9b2ebae user: dmestas tags: trunk

02:07
rfcs: record shipped auth, retention, write path, interop status

0001 §7/§8: fossil-compatible §6 shared-secret login (not bearer tokens), work-queue stream retention, forge OLTP sync_user table. 0003: phase 0-4 status with cross-fossil interop results. check-in: 4788959dfa user: dmestas tags: trunk

01:05
write path: wiki/ticket ops, forms, Basic auth over sync secrets

wiki.save + ticket.new/set through zit#71 verbs with read-your-writes; edit/new pages; Token ops gate on HTTP Basic against the RFC-derived shared secret (same credentials as sync). Harness stores now carry authored wiki+tickets; wiki surfaces join disposability. check-in: 9005c16485 user: dmestas tags: trunk

2026-08-15
23:03
web: /docs page serving the registry-generated API reference check-in: 216d15e366 user: dmestas tags: trunk
23:02
docs: API reference generated from the registry; staleness gate

quarry docs + make docs; TestDocsCurrent fails when docs/api.md drifts (0003: documentation is a phase exit criterion). check-in: fb2f393a1e user: dmestas tags: trunk

21:51
oltp: drop redundant sqlite embed import check-in: cdb79b6675 user: dmestas tags: trunk
21:50
xfer: push gating with RFC §6 login verification; forge OLTP v1

quarry user add derives the shared secret via a clone handshake (project code, no .zit bytes) and stores it in oltp.db. Gated repos verify body or x-f-l-c cookie logins per request; pulls stay anonymous. Fossil pushes authenticate end-to-end; zit's client stops sending credentials after round 1 (zit#74) so its pushes fail closed until that lands. check-in: bcef58408e user: dmestas tags: trunk

21:30
xfer: sync fronting (0001 §7 v1 slice)

POST /r/{repo} (+/xfer alias) proxies to lazily-started per-repo zit serve children; dead children restart on the next request. E2E: clone through quarry, push back, watcher folds the push. Push auth waits for the forge-OLTP slice; leases stay v-next. check-in: 31b695c5cb user: dmestas tags: trunk

20:56
web: live fleet page; shared SSE patch loop

Home table morphs on any repo's change via Watch("*") wildcard. check-in: 0556d0b12c user: dmestas tags: trunk

20:54
ticket.list: cursor pagination (updated~ticket), default 50 check-in: 6d7151de29 user: dmestas tags: trunk
20:45
web: escape wiki titles in every generated link

tcl's '(Initi/Fin)alize' page broke path routing; %2F keeps a slashed title one mux segment. check-in: 739eb90269 user: dmestas tags: trunk

20:40
wiki: edit history and revision views

wiki.history op + rev param on wiki.get; history page, historical- revision banner, timeline wiki rows link their exact revision. check-in: cadca370c1 user: dmestas tags: trunk

20:36
events: work-queue retention on ZITEVT; migrate old streams

Acked events leave the stream, so disk tracks the in-flight backlog, not store history (was 5.6GB beside sqlite's 218MB). Old-config streams are dropped with their cursors; the census republishes and idempotent folds converge. check-in: 14b0c96b83 user: dmestas tags: trunk

20:26
index: SQL-side ticket list fold; targeted TicketByPrefix

Full-history fold in Go took 1.3s per request on tcl (8.9k tickets). List now newest-updated first. check-in: 3dbf1759f6 user: dmestas tags: trunk

20:19
index: ticket_change(ticket) index; refresh ticket docs once per batch

tcl's ticket corpus crawled at ~20 changes/s: refreshTicketDoc scanned the whole table per change. check-in: 83fc12d336 user: dmestas tags: trunk

19:36
ingest: consumer pending count decides drained, not a fetch timeout check-in: 29aa399eea user: dmestas tags: trunk
19:23
index: scale branch recompute to real stores

Indexed reverse parent edge + tag lookup; recursive walk lands in an indexed temp table before the UPDATE probe. sqlite.org's repo (36k check-ins) hung for 15+ min before; milliseconds path now. check-in: cd81fba74d user: dmestas tags: trunk

19:01
index: WAL + one branch recompute per fold round

Per-batch recursive-CTE recompute was quadratic over bulk ingest; rollback-journal mode locked readers out during folds. Adaptive fold MaxWait so backlog delivery lag isn't mistaken for drained. check-in: 6da2e08171 user: dmestas tags: trunk

18:48
events: 8MB NATS payload cap for large-store artifacts check-in: 881e7d475e user: dmestas tags: trunk
18:33
phase 3: live timeline via Datastar SSE (Principle 3 enhancement)

events.Watch coalesces per-repo change ticks; composition root hands web a Notifier interface (planes stay sealed); timeline.sse re-renders the tl-body fragment through the op path and morphs #tl; vendored datastar v1.0.0-RC.7 (MIT, ledger row) is the page's only script; the no-JS page is unchanged. data-init, not the removed data-on-load. check-in: 263cff2b6b user: dmestas tags: trunk

18:23
reindex: create the per-repo data dir check-in: 83dea2f98c user: dmestas tags: trunk
18:22
reindex verb: drop derived state and replay stores (0001 §5)

Pipeline.Reindex resets tables + deletes the KV cursor, then syncs; refolding streamed events is idempotent. CLI: quarry reindex --repo. check-in: 7124d5e366 user: dmestas tags: trunk

18:13
timeline: unified events — wiki and ticket rows interleave (y= filter)

Union query over checkin/wiki_edit/ticket_change (ticket titles from the folded search doc); composite date~hash cursor; flat event rows with badges, rails passing through; Show selector in controls. check-in: 4681b2fbc4 user: dmestas tags: trunk

18:04
timeline: branch lines one color fork-to-merge, uniform stroke

Look-ahead branch map colors merge rails by the commit they descend to; join curves keep their branch color to the fork; off-page parents render neutral, never a hashed hue for the empty name; drop vector-effect (zoom-variant thickness) for plain 2.5px strokes. Lint now checks color continuity at every cell boundary and stroke uniformity; unit tests pin the dev-line coloring end to end. check-in: 54f1834d26 user: dmestas tags: trunk

17:45
timeline: seamless graph tiling, date-row rail carry, mobile pass

Tail layer at fixed px width (was stretching to 100% — x misalign); head at top:0 with cy=24; date rows render active rails so pills sit beside an unbroken graph; 5px card gaps; mobile keeps vertical card padding so alignment holds. tools/timeline-verify.js is the browser geometric lint: 0 violations on all three demo repos at 1280 and 375. check-in: 994815316c user: dmestas tags: trunk

17:34
timeline: adopt fossil's comment-flow and card metrics

Paragraphs reflow to card width (newlines are not line breaks, fossil semantics); node/time top-aligned via fixed head SVG over stretching tail rails; card padding/radius/detail values from fossil default.css (BSD-2, ledger row added). check-in: 1529a698c5 user: dmestas tags: trunk

17:24
timeline: graph cell min-width (absolute-only content collapsed td) check-in: 81ee450484 user: dmestas tags: trunk
17:21
timeline UX: fossil-modern cards, continuous rails, controls

Card layout with title/body split and bottom-right metadata; date pills; stretchable rail SVG + fixed node dot (rails continuous through tall rows, leaf tips as rings); Max control with fossil's n= name. check-in: a74b77467d user: dmestas tags: trunk

17:04
timeline: fossil-shaped rows + server-side SVG DAG graph

Day dividers, HH:MM times, comment cell with metadata tail and leaf/merge badges, per-branch colors (cleanroom hash_color), rail assignment after graph.c's shape rendered as per-row inline SVG — no JavaScript. check-in: bdb20a06eb user: dmestas tags: trunk

16:56
fix: timeline truncated at first row (web entry missing Branch)

Template errors now buffer-render to a logged 500 instead of silent truncation; populated-timeline regression test added. check-in: 81642956b5 user: dmestas tags: trunk

16:50
branch labels: tag facts + wholesale recompute, timeline filter

Manifest/control T cards fold as dated tag rows; branches recomputed per batch via recursive CTE (order-independent; latest tag wins); timeline branch column + ?branch= filter; checkin page shows branch. check-in: 3e10e3f43b user: dmestas tags: trunk

16:41
rfc 0003: pin fleet-registry alignment with zit#70

Flags stay ephemeral until zit's global db; OLTP registry is forge metadata only, never store locations; #59+#70 unblock bare stores. check-in: 342f8f00b5 user: dmestas tags: trunk

16:38
fleet: multi-repo serving, /r/{repo} routes, pagination

repo.list op + fleet home; per-repo indexes and pipelines on one NATS; repeatable --repo name=path; timeline before= cursor with older-link; harness runs two stores and asserts isolation. check-in: 0b245645c7 user: dmestas tags: trunk

16:15
highlight: dark theme covers every light token class (030)

Classes github-dark omits get explicit overrides at the dark base color; regression test pins full coverage incl. nx/p/na/nb/bp. check-in: 4fe9a80214 user: dmestas tags: trunk

16:15
layout: persistent nav, code-block styling, single h1, a11y (010/100/110/120/140)

Header nav + search form in base; markdown headings demoted one level; pre gets --code-bg; tables scroll in .tw wrappers; th scope attrs. check-in: 3253bba7bb user: dmestas tags: trunk

16:13
search fixes: folded ticket docs, mark snippets, honest limit (050/060/080/130)

search_doc gains label; tickets one folded doc per id; ⟦⟧ markers become <mark> post-escape; default= validate rule fills absent keys. check-in: 839e3e756a user: dmestas tags: trunk

16:10
error taxonomy: 404s, themed error pages, message hygiene (tickets 020/040/070/090)

ops.ErrNotFound sentinel; router maps to 404, hides internals on 500; JSON 404 for unmatched API paths; themed web 404/500; zitcli.ErrNoEntry; clean codec parse messages; shunned-diff note. check-in: f073a79918 user: dmestas tags: trunk

14:30
search: FTS5 over check-ins, wiki, tickets

External-content fts via triggers on search_doc (immutable-artifact upserts stay idempotent); token-quoted queries; /search page + op; required-input ops get explicit harness surfaces. check-in: c650d85c33 user: dmestas tags: trunk

12:20
diff: checkin.diff op + colored diff page (zit diff --from/--to)

Root check-ins report their file set as all-adds; zit#69 filed for diff -R; per-checkin diff surfaces in harness. check-in: bb37910fbb user: dmestas tags: trunk

12:16
highlight: chroma wrapper, fenced-code + file-view highlighting

Cleanroom (their wrapper is settings-coupled); classes only, both themes in one stylesheet; sanitizer learns chroma token classes. check-in: 689d0692d7 user: dmestas tags: trunk

12:11
files: zit cat behind file.get op and /file page

Rest-wildcard route; binary detection keeps bytes out of JSON; tip-file surfaces in harness; spec paths drop the ... spelling. check-in: 0821146a78 user: dmestas tags: trunk

12:09
tickets: folded state, list/get ops, pages, hash resolution

Deterministic (date,hash) fold, latest field wins; TicketByPrefix joins ResolveHash; /ticket surfaces in harness. check-in: 70f2007847 user: dmestas tags: trunk

12:05
checkin: detail op + page, hash resolution, zit ls on demand

CheckinByPrefix (unique-only); file set via zit subprocess at request time; timeline links hashes; harness snapshots every check-in page. check-in: d0e80a9156 user: dmestas tags: trunk

11:42
wiki: list/get ops, rendered pages, index-backed resolver

Latest-edit-wins queries; markup.Render behind the wiki.get op; [[name]] resolves only to existing pages; /wiki in harness surfaces. check-in: ae50247ab0 user: dmestas tags: trunk

11:20
markup: goldmark + cleanroom sanitizer + resolver seam (0002 §2)

Two-lineage conformance corpus in third_party (ledger rows, inputs only); parse-oracle fuzz target; [[wiki]]/hash resolution post-sanitize. check-in: 5ba3499b8a user: dmestas tags: trunk

11:14
events: embedded NATS leg of the ingest pipeline (0001 §4)

Watcher publishes parsed artifacts to zit.evt..artifact; durable pull consumer folds; cursors in KV; reset event on store rewrite. check-in: b0dc69c9a7 user: dmestas tags: trunk

10:52
phase 1 tracer (minus NATS): index, watcher, timeline op + page

SQLite fold via ncruces driver; ingest.Sync with cursor-loss rebuild; serve --repo; harness wipe is now a real rm -rf + re-ingest. check-in: 83db19e8c7 user: dmestas tags: trunk

10:41
corpus test: skip directories in testdata glob check-in: 42d82a6cae user: dmestas tags: trunk
10:40
sterilize artifact testdata (RFC §4.1.2)

Raw structural artifacts committed as content join this repo's DAG; a '#' first line breaks the framing gate, test loader strips it. check-in: 90a052ba22 user: dmestas tags: trunk

10:40
artifact: structural-artifact parser per the artifact-format RFC

Framing gates, escape decoding, card grammar/ordering, type classification, Z verification; corpus testdata from the fixture. check-in: 3129a9afe0 user: dmestas tags: trunk

09:16
zitcli: subprocess client for zit frames (zit 0.1.3)

Bootstrap/incremental/invalid-cursor handling per exit codes 0/3/4; rfc 0003 ledger notes zit#66/#67 shipped. check-in: 35bd00468a user: dmestas tags: trunk

02:10
phase 0 exit: serve, HTML page via op, harness loop, provenance gate

API router + web page as registry consumers; disposability loop over all surfaces; third_party ledger enforced by arch test. check-in: bf969e9d1a user: dmestas tags: trunk

00:32
rfc 0003: record zit CLI audit results and filed issues zit#66/#67 check-in: a9c85998a6 user: dmestas tags: trunk
00:31
rfc: read-verb payload is the RFC'd artifact format

0001 §2 + 0003 §6: watcher verb streams raw spec-format artifacts; container stays private, no invented schema. check-in: c29316042d user: dmestas tags: trunk

2026-08-14
22:29
OpenAPI reflector over the registry (dagnats 0.0.13)

quarry spec subcommand, RegisterAll with meta.version, required Op.Doc, validate rules feed schemas; make spec-lint via vacuum. check-in: cfd3f85ff3 user: dmestas tags: trunk

20:40
semdiff core + fixture corpus tooling

Canonical DOM/JSON/timestamp diff (0001 §11); synthetic fixture via fossil serve-and-clone; make fixtures / fixtures-real. check-in: b9d8e3692c user: dmestas tags: trunk

20:33
ops: form/URL-values codec + tag-driven validator

Field names from json tags; validate tags checked at Register time. check-in: 939f072f70 user: dmestas tags: trunk

20:06
root: RFCs, Go skeleton, ops registry core with import-graph gate check-in: 7619ba9563 user: dmestas tags: trunk