50 descendants and 50 ancestors of 98c3078224515f4f
|
2026-09-01
| ||
| 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 | |
| 12:55 |
branch pickers ask for a picker, not every branch
The repository home fetched all 1,759 of sqlite's branches to draw a selector of twenty-five: 478ms of a 520ms page, spent building and marshalling rows nobody saw. branch.list gains limit and open, applied in SQL — the filter cannot follow the limit, or an old repository's first rows are all closed and the picker comes back empty. check-in: 1fc5dd6ba2 user: quarry tags: trunk | |
| 12:46 |
file pages draw a window, not the whole file
Chroma emits a span per token, so whole-file renders built DOMs nobody asked for: 198KB of build.c became 40,083 nodes and 137ms of parse. Lexing still starts at byte zero — a window opening inside a block comment cannot colour itself — but the iterator stops at the window's last line, so the tail is never tokenised. 103ms to 2.7ms for a first screen. Scroll fetches the next window; no-script gets a link. check-in: c517ec9464 user: quarry tags: trunk | |
| 12:35 | licences: x/sync is now a direct dependency check-in: 335c4703c3 user: quarry tags: trunk | |
| 12:34 |
collapse concurrent highlight misses into one tokenisation
A read-through memo only helps once a value exists: ten cold readers of sqlite's where.c each took 0.95s against 0.42s for one, all tokenising the same immutable bytes. Safe because the value is a pure function of its key. x/sync was already in the module graph. check-in: 05dbba300d user: quarry tags: trunk | |
| 12:25 |
the highlight gate is a safety valve, not a policy
256KB turned ten of sqlite's src files permanently grey, which trades the feature for the fix. Raised to 2MB; the per-blob cache carries the cost until windowing removes the need for a threshold at all. check-in: 937b10d6de user: quarry tags: trunk | |
| 12:18 |
large files arrive: size-gate the highlighter and cache it by content
Highlighting was paid on every request with no cache, and its cost tracks token density: sqlite's btree.c, 407KB of dense C, took 490ms and rendered 2.3MB of HTML. Past 256KB the lexer is skipped and the page says so; below it, identical content is highlighted once. check-in: f4e226e5a4 user: quarry tags: trunk | |
|
2026-08-30
| ||
| 15:50 | land landing-ping check-in: c53a183de9 user: dmestas tags: trunk | |
| 14:19 | notify the opener and branch owners when a landing settles closed check-in: ac8bd4b194 user: dmestas tags: landing-ping | |
| 13:24 |
selected reads as the accent, not a grey wash
nav.seg-box (the tickets tabs) filled a.here with --surface, which is one value for both themes by design and so lands heavy on the light paper — and hover used the same value, making a hovered tab and the current one identical. Tabs now carry an accent rule, rails an accent edge, matching the ink underline the repobar and explore tabs already use. check-in: abe111b60e user: dmestas tags: trunk | |
| 13:18 |
imports are visible: a cloning repository exists from the first second
repo.add registers the row, returns, and copies behind it. State is cloning until the store lands, failed with the reason if it does not, and a restart settles rows it interrupted rather than leaving them claiming to clone forever. The fleet page grows an Importing section. check-in: 58c34af8f6 user: dmestas tags: trunk | |
| 13:02 | record the branch-closed-tags merge: 84b8fed1 carried the content but not the merge edge check-in: 89a654bfba user: dmestas tags: trunk | |
| 12:53 | land ops-durability-1 check-in: 4af8540cf1 user: dmestas tags: trunk | |
| 11:40 | land branch-closed-tags: closed branches honour propagating and inherited tags check-in: 84b8fed157 user: dmestas tags: trunk | |
| 11:38 | docs: scratch-tree deploys, what survives a reboot, two more multi-agent rules closed check-in: 8d5610cacb user: dmestas tags: ops-durability-1 | |
| 11:33 | land ci-live-sse check-in: 97dd341966 user: dmestas tags: trunk | |
| 11:33 | land attention-dedupe check-in: 62731b2cac user: dmestas tags: trunk | |
| 11:12 | land fleet-tabs-1 check-in: 7b3c7f554f user: dmestas tags: trunk | |
| 11:07 | merge trunk into ci-live-sse closed check-in: 9f856b6148 user: dmestas tags: ci-live-sse | |
| 11:07 | merge trunk into attention-dedupe closed check-in: 3f44083712 user: dmestas tags: attention-dedupe | |
| 10:46 |
closed branches: honour propagating tags and inherited closure
The selector kept five finished branches because Branches() tested only a '+' tag on the tip: a 'closed:*' on the tip, or inherited from an ancestor, both read as open. closed check-in: c03438d3eb user: dmestas tags: branch-closed-tags | |
| 10:41 | merge trunk (clone-base + intake fixes) into fleet-tabs-1 closed check-in: 89d5dd7dec user: dmestas tags: fleet-tabs-1 | |