Skip to content
quarry Timeline
Login

Timeline

50 descendants and 50 ancestors of d9e0b43f4888b583

2026-09-01
21:39
chat: opaque menu panel, contained hit boxes, full-width editor, room for the sub-line check-in: cf5219f8c2 user: dmestas tags: trunk
19:13
chat: the linked message is one card; the channel names itself like the permalink check-in: b4c790db7a user: dmestas tags: trunk
18:59
chat: the permalink gets the same full-screen shell as the channel check-in: 04c64cf069 user: dmestas tags: trunk
18:43
chat: no focus ring on the composer; the caret is the indicator check-in: 618af32757 user: dmestas tags: trunk
18:10
chat: the retention note wraps instead of widening the whole column check-in: 0b98e8033f user: dmestas tags: trunk
18:09
chat: let the shell column shrink below its widest nowrap line check-in: 4b89f412f3 user: dmestas tags: trunk
18:06
chat: one clean control row in the composer, the retention note on its own line check-in: 2d3e5d3abd user: dmestas tags: trunk
18:03
chat: the composer as one soft panel with pill controls check-in: e05ece8598 user: dmestas tags: trunk
18:00
chat: the menu panel floats where script runs, stays in flow where it does not check-in: b7be8ff89c user: dmestas tags: trunk
17:55
chat: the jump pill stands down while a message menu is open check-in: 0173694500 user: dmestas tags: trunk
17:53
chat: assert the overflow by element, not by exact tag text check-in: 8d8a8a7178 user: dmestas tags: trunk
17:52
chat: an opened menu scrolls itself into view check-in: 0816e168e8 user: dmestas tags: trunk
17:48
chat: keep the icons level when a menu is open check-in: 4dca8ebdf7 user: dmestas tags: trunk
17:45
chat: correct the summary-display comments — a hazard guard, not an observed bug check-in: ae0053a8ff user: dmestas tags: trunk
17:43
chat: inline-grid for the icon box so it does not stretch the row check-in: 251d503dc1 user: dmestas tags: trunk
17:41
chat: never set display on a summary — it was rendering every edit form and delete confirm check-in: 569c21ffff user: dmestas tags: trunk
17:36
chat: reply and edit as icons, everything rare behind a native overflow menu check-in: d2fe2b04df user: dmestas tags: trunk
16:12
chat: message actions are visible without hovering, and jump-to-latest is one shape check-in: 2506a5cd05 user: dmestas tags: trunk
14:59
chat: the permalink stops drawing a second heading beside the layout's check-in: 84cbfce794 user: dmestas tags: trunk
14:56
chat: permalinks show the conversation around the linked message, and can reply to it check-in: 697499ff18 user: dmestas tags: trunk
14:34
chat: the unread badge ships hidden check-in: c6643d4e73 user: dmestas tags: trunk
14:29
chat: assert the composer enhancement by property, not by exact expression text check-in: 86e7514936 user: dmestas tags: trunk
14:27
chat: sending puts you at the end of the log check-in: 4db4342b44 user: dmestas tags: trunk
14:16
chat: use el, not document, in datastar expressions; a throw there killed every handler below the log check-in: 79adc68bef user: dmestas tags: trunk
14:13
chat: keep the newline between the composer's attributes; guard datastar attributes with a parse check-in: 7e1b7cf7b7 user: dmestas tags: trunk
14:09
chat: clear the composer from the server, and stop the CSP-unsafe expression that killed the submit handler check-in: cf198b1e73 user: dmestas tags: trunk
13:51
chat: match the jump pill on attribute presence, which is what datastar writes check-in: 74b8d2870a user: dmestas tags: trunk
13:50
chat: tighter gutter, glass jump pill that waits, and broker-side duplicate suppression check-in: e5893251c8 user: dmestas tags: trunk
13:35
chat: the jump caret knows it took you to the end check-in: 1fe790e3a4 user: dmestas tags: trunk
13:31
chat: full screen when either dimension is small; stop assuming this check-in: 1fcad105a9 user: dmestas tags: trunk
13:23
chat: an open disclosure keeps its toolbar clickable; quieter focus; smaller marks check-in: 8f561fc9b3 user: dmestas tags: trunk
13:20
chat: the log positions itself; a second data-init was being dropped check-in: d2944f300b user: dmestas tags: trunk
13:18
chat: let the debounce provide the delay instead of a callback check-in: 265a0df733 user: dmestas tags: trunk
13:17
chat: settle the jump caret after layout, not before it check-in: c0dfa5e76c user: dmestas tags: trunk
13:14
chat: caret jump, in-place edit, and full screen on a phone check-in: de05989a66 user: dmestas tags: trunk
13:04
chat: keep a lane under the log so the jump pill covers no message check-in: 22f0f8bb04 user: dmestas tags: trunk
13:03
chat: actually put the shell class on the body check-in: f272af3af5 user: dmestas tags: trunk
13:01
chat: the window is the frame — one scrolling region, composer always reachable check-in: 698a8406d3 user: dmestas tags: trunk
12:56
chat: read the scroll position at init instead of assuming it check-in: 3a9cd881ad user: dmestas tags: trunk
12:53
chat: open where the reading is, follow only at the end, guard delete without script check-in: b7d0dad12b user: dmestas tags: trunk
12:00
chat, inbox: move their rules into the served sheet; a strict CSP drops inline style check-in: 30cbca27bd user: dmestas tags: trunk
03:02
titles: capitalise page names and the account menu check-in: f9252b7e51 user: dmestas tags: trunk
02:39
people: a shared name is not one person; show each repository's own figures check-in: 98b2ed6061 user: dmestas tags: trunk
02:28
avatar: the identicon fills it, so one disc shows one colour check-in: 827a14be9d user: dmestas tags: trunk
02:00
harness: the edit form's triage arrives selected, not as input values check-in: eabac88d65 user: dmestas tags: trunk
01:58
tickets: one picker for every triage field, select plus a new-word box check-in: bcb4bba6a5 user: dmestas tags: trunk
01:49
new ticket: subsystem is a select with an Other field, working without script check-in: 52941e6f32 user: dmestas tags: trunk
01:42
new ticket: triage fields are selects; wide width follows the toggle check-in: 61b1aecc1d user: dmestas tags: trunk
01:34
a two-state toggle announces itself with aria-pressed, not aria-current check-in: 88fc824fd4 user: dmestas tags: trunk
01:33
board: order cards by the sort the reader chose; fix gofmt check-in: 9b8fbebfd0 user: dmestas tags: trunk
01:26
tickets: morph view switches, pushing the same URL a click would load check-in: d9e0b43f48 user: dmestas tags: trunk
01:18
tickets: sort works in every view; wide is a click; tabs hide zero counts check-in: c731025661 user: dmestas tags: trunk
01:01
ci worker: reuse a workspace per repo+task instead of a 94s clone per step check-in: 2d4b032823 user: dmestas tags: trunk
00:46
ci: honest run states — stalled, running vs queued, step timeouts check-in: d732f7b7ee user: dmestas tags: trunk
00:39
ci: stream a running step's logs instead of waiting for it to finish check-in: b127bafd1e user: dmestas tags: trunk
00:27
ci: 5s/15s/45s retry ladder with an explicit multiplier check-in: 06b6e1de88 user: dmestas tags: trunk
00:12
ci: retry each step; one transient clone failure should not red a run check-in: 854d0765c6 user: dmestas tags: trunk
2026-08-31
23:48
chat: Range from zero means DeliverAll, not StartSequence(0) check-in: 967c0a4c92 user: dmestas tags: trunk
23:20
web: rename fleetPage to explorePage; it is the public index, not the fleet check-in: b12d9b381a user: dmestas tags: trunk
23:17
health: fix the banner's duration call; pin it with a render test check-in: 575a4301d7 user: dmestas tags: trunk
23:14
health: watch dagnats and notify, journal outages, banner the fleet page check-in: ee62d06275 user: dmestas tags: trunk
23:03
exceptions: persist the journal so it survives restarts check-in: 1f6aaeac2d user: dmestas tags: trunk
22:45
exceptions: journal background job failures, not just log them check-in: 769040d377 user: dmestas tags: trunk
22:41
exceptions: register client-error on the outer mux, under the api subtree check-in: d79a667532 user: dmestas tags: trunk
22:39
exceptions: capture browser errors too, journal template failures, list layout check-in: 7126e45e7e user: dmestas tags: trunk
22:27
fleet: anchor the fold drawer to its own button check-in: 20b0ab77cc user: dmestas tags: trunk
22:24
fleet: title-case the name; fold Mirrors then Operations into a popover check-in: 637ba530a4 user: dmestas tags: trunk
22:22
fleet: fix settings page template error; $.SavedPanel inside the with-block check-in: e6502c71a8 user: dmestas tags: trunk
22:18
fleet: drop OwnH1 where the content no longer draws the heading check-in: 0712c3a786 user: dmestas tags: trunk
22:17
fleet: wear the repository bar — one name, plain tabs, no per-page h1 check-in: ccd9b10fc0 user: dmestas tags: trunk
22:08
dash: give the repository selector room above the feed check-in: ae3b86683c user: dmestas tags: trunk
21:58
web: one .list-card component; every row list wears the ticket listing's shape check-in: 98c3078224 user: dmestas tags: trunk
21:51
dash: read the repository facet from the query and keep it while paging check-in: 0cd361116e user: dmestas tags: trunk
21:49
dash: chip thresholds match each form's measured width check-in: 05ad2976e1 user: dmestas tags: trunk
21:47
dash: set the chip thresholds from measured column widths check-in: 98edfd7da1 user: dmestas tags: trunk
21:45
dash: tighten chip spacing so the count tier fits the column check-in: 994cb96578 user: dmestas tags: trunk
21:44
dash: key the chip ladder to the feed column, not the viewport check-in: 05689ed46d user: dmestas tags: trunk
21:42
dash: chips shed count, then icon, then wording as the screen narrows check-in: abeb8276b1 user: dmestas tags: trunk
21:36
dash: drop unselected chip counts on small phones check-in: 0ac19e0ebe user: dmestas tags: trunk
21:35
dash: on a phone only the selected activity chip keeps its label check-in: 809e6e9ce0 user: dmestas tags: trunk
21:33
dash: short chip labels and truncated hashes on narrow screens; repository facet check-in: 42d9e776de user: dmestas tags: trunk
21:24
fix the stray backslash from the previous commit check-in: 6723b7ea99 user: quarry tags: trunk
21:22
dashboard fragment renders from its own template check-in: e99997b8c1 user: quarry tags: trunk
21:19
dashboard: activity rows match the tracker, chips stop shrinking, tabs and paging morph check-in: e56c5ac558 user: quarry tags: trunk
21:02
warm four repositories at once, not two check-in: 7a4e0fcfc7 user: quarry tags: trunk
21:00
reap orphaned zit serve children at startup check-in: 0cb8f48a5f user: quarry tags: trunk
20:49
selection: underline means tab; toggles wear the button chip

See the wiki page [Selected states] for the states and the reasoning. check-in: baecdf8460 user: quarry tags: trunk

20:33
pin the nonce alphabet: a + in the attribute silently kills CSP mode check-in: 47064a1033 user: quarry tags: trunk
20:30
url-safe nonce: no + to escape in the attribute check-in: ce8dcd1ae6 user: quarry tags: trunk
20:02
a strict CSP: nonces, no unsafe-eval, no inline handlers

quarry served no page policy at all. The blocker was never the data-on:* attributes — script-src does not govern data attributes — it was unsafe-eval, because datastar compiled expressions with Function(). 1.0.3 takes a nonce instead.

Removed all 14 inline handlers: 11 identical onchange=this.form.submit() became data-on:change with requestSubmit (which validates, unlike submit), two selection handlers became expressions, and the copy-hash button moved to a delegated assets/copy.js. Scripts now carry content-hashed immutable URLs instead of revalidating daily.

The audit found the expressions already safe, for a reason worth pinning: html/template strips a data- prefix before classifying, so data-on:drop gets the JAVASCRIPT escaper. That matters because an HTML-escaped quote decodes back to a quote before any script reads the attribute, and a board column status comes from .quarry/tickets.json — upstream content on a mirror. check-in: ef352402f6 user: quarry tags: trunk

17:10
datastar 1.0.0-RC.7 to 1.0.3

A release candidate was shipping in production. No breaking changes across the three patch releases; two fix things quarry leans on — select signal typing and dynamic multiple (the ticket sidebar and board are native selects) — and 1.0.3 adds the CSP mode that would let the forge drop unsafe-eval. check-in: e13cb74667 user: quarry tags: trunk

16:08
gzip what benefits, never the event streams

Nothing was compressed: a request carrying Accept-Encoding got byte-identical bytes back. Measured here, the timeline page is 309,584 to 36,599 (88%), a ticket list 84%, a highlighted source page 92%.

gzip rather than brotli deliberately — brotli q5 beat gzip 6 on both size and time, but that is a dependency for ~7% on a page already 88% smaller. SSE is excluded by content type: 22 stream writers, and a buffered stream is a live update that never arrives. check-in: d598ecafa3 user: quarry tags: trunk

15:49
serve the stylesheet instead of inlining it in every page

112,118 bytes of <style> rode on every response — 40% of a 309,584-byte timeline page, byte-identical each time and uncacheable because it had no URL, while the JS assets already carried Cache-Control. Now one hashed asset served immutable: a rule change mints a new URL, so a stale cache is impossible without anyone revalidating. check-in: eb4793ee8e user: quarry tags: trunk

15:39
the zit figure's count suffix is two bytes, not one

The multiplication sign in 'zit 34.1ms×2' never matched a byte compare, so the duration parsed as zero and the store note appeared beside an identical zit figure — claiming a wait already accounted for. check-in: 433a022052 user: quarry tags: trunk

15:37
the footer names store wait the timing context missed

A call on context.Background() carries no timer, so a page blocking six seconds on a warm pass reported 'ops 11.09s, zit 32.9ms' — and the ops panel's claim that ops minus zit is index work was false while it did. Overlap catches what attribution misses: subprocess busy time inside the render window, unioned, reported only when it exceeds what was already attributed. check-in: 17454ef71f user: quarry tags: trunk

15:24
fold the branch summary instead of deriving it per request

branch.list grouped every check-in in the repository on every request: ~150ms in sqlite on tcl, 460-850ms through the driver, on a page whose budget is 500ms. A LIMIT could not help — the grouping happens before the limit applies. Same remedy as the ticket table: fold once when the shape changes, read by index. Refreshed in both fold paths, which the parity test insisted on. check-in: d6bf4e65b3 user: quarry tags: trunk

15:17
warm the default branch too, so ops minus zit means what it says

A subprocess on a render path is latency one reader pays for everybody, and one on a detached context is invisible in the footer while still counting toward the total — which is what sent the last investigation chasing SQL for an hour. check-in: 8c5b6e5392 user: quarry tags: trunk

13:25
leaf set keys on zit's abbreviation, not one subprocess per leaf

Leaves expanded every twelve-character hash zit printed into a full one with a zit info call each: 473 leaves on sqlite meant 357 spawns and 6.1s in a single page-load window. The one consumer asks a membership question, which a twelve-hex-character key answers. Contract test now pins the prefix contract and that a full hash finds its leaf. check-in: 00e90b88cc user: quarry tags: trunk

13:16
warm the leaf set instead of making a reader pay for it

zit leaves is 6.4s on sqlite, not the ~10ms this comment claimed, and the first reader paid it: 10.8s cold against 0.5s warm. Invisible in the footer too, since a detached context carries no timer. Warmed at registration and after each ingest; a reader arriving early gets no leaf marks rather than a six-second wait. check-in: e16d738900 user: quarry tags: trunk

13:14
prefix lookups seek instead of scanning; sqlite tuned for this workload

col LIKE ? || '%' cannot use an index: the pattern is not a literal when the statement is prepared, so finding ONE check-in by its full hash read all 36,853 rows of sqlite's tree. That was 10s on a first timeline render and 40ms after, which reads as cold I/O and is not. Half-open hex ranges seek. Also sets cache_size, mmap_size and temp_store, none of which were configured. check-in: 22346a81a7 user: quarry tags: trunk

12:57
name the slow op in the log

A ten-second page said 'ops 11.09s x8' and stopped there: the container is timed, its contents are not, so the slow one cannot be identified. Anything past 250ms now says which op it was. check-in: 3f926fafe8 user: quarry tags: trunk