Skip to content
quarry Timeline
Login

Timeline

50 ancestors of cd014ee9b5ad9f6e

2026-08-19
01:14
invalidate leaf memo only on real ingest; index the tag lookup check-in: cd014ee9b5 user: dmestas tags: trunk
00:36
leaf status from zit, not re-derived; index schema version check-in: a3814a4eb3 user: dmestas tags: trunk
00:06
detect lost artifacts, repair once, then report check-in: bd55e3a4cb user: dmestas tags: trunk
2026-08-18
23:56
detect and repair index gaps left by the bounded event window check-in: ff869515bd user: dmestas tags: trunk
23:05
fleet fragment test follows the controls out of the morph check-in: b5d1be0dc2 user: dmestas tags: trunk
23:04
live filter: debounced form-serialized stream, controls outside the morph check-in: dcbfa94c8f user: dmestas tags: trunk
22:45
fleet count against the fleet; replace the native search clear check-in: 8922b17a67 user: dmestas tags: trunk
22:34
fleet stream: send the same data the page rendered check-in: da11bb2f4e user: dmestas tags: trunk
22:13
morph safety test; refresh a stale header comment check-in: 6c88726c75 user: dmestas tags: trunk
22:12
assert morphed regions hold no stateful widgets check-in: a8ffd42e31 user: dmestas tags: trunk
22:09
tooltip: CSS-only, keyboard-reachable, after basecoat check-in: 8716bda9ab user: dmestas tags: trunk
21:57
footer: protect the render time, collapse brand and version first check-in: 976a0fbb1d user: dmestas tags: trunk
21:54
fleet: put the icon legend above the table it explains check-in: b0dcf5b184 user: dmestas tags: trunk
21:51
popover test: strip comments before scanning the rule check-in: d1f24b16f2 user: dmestas tags: trunk
21:51
popover: do not lay out a closed menu check-in: 0f80f70360 user: dmestas tags: trunk
21:45
favicon: embed the quarry mark check-in: c77e3a64e3 user: dmestas tags: trunk
21:28
fleet: drop the duplicate heading check-in: d08c109f36 user: dmestas tags: trunk
21:17
tickets: honour is_private; fix trigger conflict clause aborting refolds check-in: 55309263a2 user: dmestas tags: trunk
21:06
clone: offer fossil where the store has no submanifest; fix menu item overflow check-in: fdbe0098e1 user: dmestas tags: trunk
20:55
tickets: stop rendering fossil's private contact fields check-in: 3918395e1f user: dmestas tags: trunk
20:47
tickets: list open by default, closed opt-in check-in: c4080bd6b6 user: dmestas tags: trunk
20:23
content tables scroll themselves instead of the page check-in: f9278e8d03 user: dmestas tags: trunk
20:09
icon columns explained at every width; centre the footer text check-in: 7b59bbf957 user: dmestas tags: trunk
20:01
column headers: visible labels, not popover tooltips; page the people list check-in: 2ccee11f4f user: dmestas tags: trunk
19:56
fleet mirror rows, footer clearance, licenses page leads with our own check-in: e0a1db3b72 user: dmestas tags: trunk
19:37
footer: fixed full-width with legal links; licenses and privacy pages check-in: d8553b89a3 user: dmestas tags: trunk
19:21
repo header: stats strip, ref switcher popover, clone box with download menu check-in: e7fb66c4df user: dmestas tags: trunk
19:11
explore: repositories/people tabs, folded contributor table check-in: be4c4284f1 user: dmestas tags: trunk
18:51
chrome: lighter dark secondary, centred search, quiet focus ring, no duplicate home heading check-in: 90c75cd912 user: dmestas tags: trunk
18:40
tickets: record cmimetype on authored text check-in: f7ba4868d5 user: dmestas tags: trunk
18:31
chrome: neutral surface token, full-width bar, anchored animated popover, compact fleet counts check-in: 3c43c1de30 user: dmestas tags: trunk
18:25
header: full-width top bar, account popover with avatar check-in: b3ac263fee user: dmestas tags: trunk
18:19
palette: whiter dark text, muted orange, themed highlight tokens check-in: 1d80a6cffa user: dmestas tags: trunk
18:01
global search: fan out across repos with per-repo facets check-in: ae68223b22 user: dmestas tags: trunk
16:01
fleet: carry filter and sort into the live stream check-in: d54bc03817 user: dmestas tags: trunk
14:54
gruvbox palette, server-side theme switcher, context-scoped search check-in: 6d9997bbb4 user: dmestas tags: trunk
14:41
archive: disk cache, zip format, immutable ETag; tree-bar cleanup check-in: b8afd21148 user: dmestas tags: trunk
14:11
theme form controls; drop inline width overrides check-in: 93899cc429 user: dmestas tags: trunk
14:07
ticket detail: drop duplicate title, fields as a dl check-in: eb6cc56c07 user: dmestas tags: trunk
13:55
tickets: list layout, title first check-in: 3862cf6012 user: dmestas tags: trunk
13:48
dates: render relative everywhere; strip markup from list titles check-in: 414f5a0e06 user: dmestas tags: trunk
13:40
nav: pills with compact counts; stop long tokens overflowing

The repo nav's width was a function of its numbers — tk's 25557 and 5809 made a visibly different nav from a small repo's, wrapping to three lines on a phone. Counts go compact (25K, 5.8K, 1.2M, four characters max) with the exact figure in the badge title, and each entry is a pill rather than a word beside a loose number. Nav width is now identical across repositories.

Separately: sqlite has wiki pages named after check-in hashes, 40-char unbreakable tokens that pushed the page 300px past a phone viewport. main now breaks over-long words; pre keeps its own scroll. check-in: 15c39013de user: dmestas tags: trunk

13:25
landing page: vendor octicons, real columns, description spans the row

Three fixes for one screenshot. The icons were CSS masks with inline data: URIs — valid in Chrome, invalid under iOS Safari's stricter parsing, so every icon rendered as a grey block. Now an SVG sprite of six Octicons (MIT, ledgered); no encoding to get wrong.

Alignment needed real table columns. CSS grid aligns within one grid, so a per-row grid gave every row its own widths and nothing lined up. Measured: stat cells now share right edges across rows exactly.

And the description spans the full row instead of sitting in column one, which had made that column as wide as the longest sentence and pushed the numbers off a phone. No horizontal scroll at 320-1280px; the mirror column drops below 30rem. check-in: 60e5e5ebb6 user: dmestas tags: trunk

13:11
landing page: stats as aligned badges, not a sentence

A sentence of stats is a different width in every row, so nothing lines up and the column is hard to scan. Four fixed slots — check-ins, contributors, mirror freshness, last activity — each an icon and a number, in a grid so the numbers align down the page.

Durations go compact (34m, 12h, 3d) for the same reason; the exact instant stays in the title and datetime. Every badge keeps a title, because an icon alone states nothing. check-in: 7bf20af78a user: dmestas tags: trunk

12:44
landing page: drop the commit message, show activity signals

An aggregator listing showed whatever the last commit happened to say — written for people already in that repo's context, the widest thing in the row, and on a phone one entry filled the screen. GitHub and Forgejo list description and activity and neither shows a commit message.

Replaced with what a stranger can use: last activity, check-ins, contributors, and mirror freshness. The last is there because mirroring created an ambiguity — a repo quiet upstream and a mirror failing for a week look identical if all you see is 'last activity'.

Contributors rides the memoized Counts, so it costs nothing per request. check-in: 012cdff6c9 user: dmestas tags: trunk

11:42
repo.delete: destroy a repository, with two brakes

Removing a repository's disk space meant going to the shell and doing it without quarry knowing, which is worse than quarry doing it. Deletion now purges the store, the derived index, and every forge row keyed to the repository — grants, sync users, mirror, webhooks, CI records — in one transaction, so a new repository of the same name cannot inherit somebody's credentials.

Two brakes. confirm must equal the name: a yes/no prompt is answered reflexively, typing the name requires having read which repository is about to go. And the store is removed ONLY when it lives under this node's repositories root — quarry serves stores it did not create, and this forge runs on a corpus of exactly those, so deleting one named by --repo would destroy a checkout somebody else manages. Verified: the attempt on pikchr refuses and says to unregister instead. check-in: a8d2831bf4 user: dmestas tags: trunk

11:33
repo.add: seed a new repository's first check-in

A repository with no check-ins has an unborn trunk, so the timeline, the file tree and every clone instruction have nothing to point at. Optional README, license (MIT or BSD-2) and .zitignore give it a born trunk, which is why GitHub offers the same three at creation.

The copyright line is left as <copyright holder> rather than filled with the account name: a copyright naming the wrong person is worse than one that is visibly unfinished, and an account is a login, not a legal entity. Seeding is refused on a clone, which arrives with its own history, and paths are checked against the repository root before anything is written. check-in: c5b6d979e2 user: dmestas tags: trunk

11:17
repo.list: filter, sort and page the listing

The front page rendered every repository unsorted and unbounded — the same shape that made the timeline unusable, and it is at 23 now. Adds a name filter, sort by name, recent activity or size, and a limit, with Total alongside Count so a page can say '5 of 23'.

Sorting happens BEFORE the limit. The other order gives an arbitrary subset in the right sequence, which reads as correct and is not.

Activity comes from the event table's index — one walk stopping at the first row — so the column that makes a forge listing worth reading costs nothing.

Adds repo.get, so the settings page and the CLI stop scanning the whole listing to read one repository's settings. check-in: 4a3165db34 user: dmestas tags: trunk

11:06
repo: settings page, descriptions everywhere

repo.update replaces repo.visibility and applies a repository's settings whole — a settings form submits every field it manages, so partial-update semantics would only add a way for the two to disagree about what absent means. The CLI reads current settings before writing, so 'repo private' no longer blanks the description.

A settings page at /r/{repo}/settings, admin-gated, and the description now appears on the repository itself rather than only in the listing: a reader arriving from a link otherwise sees nav and a file tree and no statement of what the project is. check-in: a41b410958 user: dmestas tags: trunk

10:54
repo: private repositories

Visibility on the registry, gated at every read path: pages, API, search, file reads and the sync endpoint all answer 404 for a repository the caller may not see. 404 and not 403 — a 403 confirms the repository exists, which is the one thing a private repository must not confirm.

The listing filters by visibility too. A list that names a private repository has leaked it whatever the page then refuses to show.

The gate lives in Deps.repoFor, where d.repo already resolved the store, so a new op cannot forget it. The API router now resolves identity for ANONYMOUS ops as well: a read op that never looks at credentials cannot tell a repository's own collaborators from strangers, and would lock them out of their own repository.

Two faults found while verifying. Repositories named by --repo had no registry row, so taking one private updated nothing and reported success — a security control that claims to work while doing nothing. They are recorded now, and SetRepoVisibility refuses a name it does not hold. Second, the sync path was ungated: a private repository whose pages refuse anonymous readers while zit clone hands over every artifact is not private.

Verified: anonymous and unprivileged accounts get 404 everywhere and a short list; a collaborator with read sees it; admins see everything. check-in: f88e97a9fd user: dmestas tags: trunk

02:09
account: manage identity through the API, and stop lying about why

Six ops (account.list/add/passwd/delete/grant/revoke, admin) plus quarry accounts on top of them. Creating a login or granting someone read on a repository no longer needs shell access on the server.

quarry account still opens OLTP directly and has to: the FIRST account must exist before any server runs or any admin exists to authenticate as. Everything after that is the API, so the CLI has no privileged path.

The verifier never crosses the seam in either direction, and account.add /passwd scrub the password out of any error before it travels — an error is the one value that reaches a log, an HTTP body and a terminal at once.

Verify returns a three-valued Decision instead of a bool. Denied and Insufficient are not the same thing and the wire has separate codes for them: an authenticated client short of a capability was being told 401 with a challenge, which invites it to retry the same password forever. Now 403, and deliberately without a challenge. A harness test pinned the old behaviour and was updated with the reason. check-in: 86880118d5 user: dmestas tags: trunk