Skip to content
quarry Timeline
Login

Timeline

50 descendants of b459791bbdf62b1a

2026-08-27
12:02
landing: a contained branch reads accepted, not claimed closed check-in: 938c28695e user: dmestas tags: contained-claim
11:42
Green against merged trunk: vet, build and the full suite. Clicking a doc tab now moves the address bar to the tab's own href, verified live. check-in: c2ccbb5e93 user: dmestas tags: trunk
11:42
Merge trunk

Current with the segment below, now landed. closed check-in: a50a6dee00 user: dmestas tags: url-sync-doctabs

11:41
Green against merged trunk: vet, build and the full suite. Emitted markup unchanged, so the diff toggle behaves exactly as before. check-in: e7d457d6d5 user: dmestas tags: trunk
11:41
Merge trunk

Keeps the segment current with the landing.update work before it lands. closed check-in: 645b11cd8a user: dmestas tags: url-sync-helper

11:41
web: the repository tabs read as labels, not as route names

Files, Timeline, Tickets, Docs, Landings, Forum, CI, Chat — and Repositories/People on the home tabs. CI is spelled, not capitalised: a text-transform would have rendered it Ci.

navlink matches the active tab on its section argument, so the label was only ever display text. check-in: 5a07f20dd6 user: dmestas tags: trunk

11:22
Landed: Update from target, on the store. check-in: f64e1eb73a user: dmestas tags: trunk
11:22
landing.update: bring the target into the branch on the store (zit#152) closed check-in: ab5e011fc2 user: dmestas tags: landing-update
10:54
Doc tabs: keep the URL on the tab you are reading

Switching README to LICENSE swapped the panel and left the address bar behind, so the tab on screen was unlinkable and a reload dropped you back on README — even though /r/REPO?doc=LICENSE has always been a real route, and the anchor was already carrying it as its href.

Moves the tabs onto syncurl, which corrects the address bar to that same href before fetching the fragment. check-in: c2775268a4 user: dmestas tags: url-sync-doctabs

10:52
One definition of swap-the-body-and-fix-the-URL

The diff toggle carried the replaceState handler as literal text in two attributes, with the reasoning in a comment above them. Both move onto a syncurl helper, so the next surface that needs it gets the try/catch and the replaceState-not-pushState choice for free instead of by copy-paste. Emitted markup is unchanged.

The helper neutralizes quotes in the fragment URL: it lands inside a JS string inside an attribute built as HTMLAttr, where escaping is off. check-in: 058a2216c9 user: dmestas tags: url-sync-helper

10:08
Landed: the size cap on what is drawn. check-in: d05ac2958a user: dmestas tags: trunk
10:08
Landed: conflict steps; rungs above follow. check-in: 96d8fa7224 user: dmestas tags: trunk
10:08
Landed: the top rung's verdict is the stack's. check-in: 57dbf59e99 user: dmestas tags: trunk
10:08
Landed: landing.land, whole stack or bottom-N. check-in: d334dbfd92 user: dmestas tags: trunk
10:08
Landed: retarget replies read by the fold. check-in: 02bc605852 user: dmestas tags: trunk
02:53
strata: past twenty rungs, say how tall rather than draw closed check-in: e1557f4791 user: dmestas tags: strata-cap
02:51
landing: the steps for a conflicting rung; rungs above follow closed check-in: dcc39e7343 user: dmestas tags: strata-help
02:49
docs: regenerate api.md closed check-in: ca48cce188 user: dmestas tags: strata-verdict
02:48
strata: the top rung's verdict is the stack's check-in: f35fe25d54 user: dmestas tags: strata-verdict
02:48
landing.land: land a strata up to a rung, bottom-up closed check-in: c3d29faae3 user: dmestas tags: strata-land
02:48
landing: read zit#144 retarget replies (carried from in-flight work) closed check-in: f61dfbb349 user: dmestas tags: retarget-reply
02:37
strata: the top rung's verdict is the stack's closed check-in: e9e17d7eb3 user: dmestas tags: stack-2
02:35
landing.land: land a strata up to a rung, bottom-up closed check-in: 2478ddbc2b user: dmestas tags: stack-1
00:04
Landed: a strata that looks like one thing, because it is one thing. check-in: ca52fa73e4 user: ai-local tags: trunk
00:03
Landings: a strata is one row, and a map on the record

The open queue folds a stack under its base: a strata mark, the segment count, the landable end named, and the rungs in a details element with 1/N badges — no script. Settled views stay flat; a settled segment has left its chain.

The record page draws the map: every rung bottom-up, this one marked, the landable one named, a rejected base as a broken rung. Above the bottom the accept control is disabled and says the segment below lands first.

Proved with a real zit: two stacked landings count one decision; the top rung's accept is refused; accepting the base retargets the next onto trunk and it becomes the landable end, still one decision. closed check-in: 02f6aadcad user: dmestas tags: strata-ui

00:03
RFC 0006: the strata is derived, and the queue counts decisions

AttachStrata reads the chain from target -> branch across landings: base, position, depth, and why a chain cannot be walked — a cycle, or a rejected base. Derived at read time, never stored, so a segment retargeted by zit#144 after its base lands simply stops being one.

landing.list carries the reading and counts DECISIONS: a stack of five is one, the base's, because nothing above it can be acted on. landing.get carries the chain for the record's map and reports a rung above the bottom as stacked, which the merge probe must not overwrite: its answer is true and useless there. check-in: 3e3ad17751 user: dmestas tags: strata-ui

00:02
markup: fossil wiki resolves mentions and refs, like markdown does

An artifact with no N card IS fossil wiki — fossil's default, and what anything writing through the zit CLI produces. fossilInline resolved this dialect's own [target] links, but @mentions, [[wiki]] refs and bare hash refs are dialect-independent and were reaching only markdown bodies, so 62 of quarry's own 90 forum posts lost every mention in them.

The two passes run after sanitizing, as they do in Render: resolveRefs mints the identity mark and the policy would strip it. It parses HTML and skips a/code/pre, so the anchors fossilInline just built and every

 block are left alone — both asserted.

check-in: b00045e163 user: dmestas tags: trunk
2026-08-26
23:51
Landed layer 6: the heading gone, the strata proposal in RFC 0006. check-in: 2a95e40671 user: ai-local tags: trunk
23:51
Landed phase 5: every row of the RFC's table, proved the way a person would do it. check-in: 763b776f6f user: ai-local tags: trunk
23:51
Landed phase 4: the rule has a page, and the page says what it costs. check-in: 8f527acdb5 user: ai-local tags: trunk
23:51
Landed phase 3: the merge is the fact, the reply is the claim, accept asks MayJoin. check-in: 2d30e99800 user: ai-local tags: trunk
23:51
Landed phase 2: identity becomes a rule, the child enforces it. check-in: 8c6e2b5b59 user: ai-local tags: trunk
23:51
Landed phase 1: the policy table and the decision function. check-in: 4742a00a65 user: ai-local tags: trunk
23:31
Landings list: drop the h1; RFC 0006: how a strata is shown

The tab already says landings and the page's first line is the state chips; the heading said the same word a third time.

RFC 0006 gains the rendering proposal it deferred, written after this forge's first real strata listed as five independent open landings. Grounded in what GitHub (native stacks, July 2026), Gerrit (relation chain, submit whole topic) and Graphite do: a position on every member, a map on the record, one action at the landable end. quarry groups in the list because its list is a queue and a queue that shows five rows for one decision counts wrong. closed check-in: 3693d77992 user: dmestas tags: protect-6

23:24
RFC 0007 phase 5: the matrix, driven through the forge

Every row of the RFC's table, the way a person or a client would do it: the forge's accept through the API as owner and non-owner; a clone's accept pushed through the sync gate, refused whole with the branch named, then admitted for the owner with no reply posted; a stock fossil client's merge refused; branching off trunk and pushing to an unprotected branch admitted; a forged accepted reply recorded as a claim. A branch continued past its merge stays accepted.

Compatibility and disposability as the RFC states them: a clone's artifacts are identical with the row present or absent, and the record renders identically before and after the row, and across the section-11 wipe.

The disabled control with its reason is proved in the web package, where a viewer has an identity — and proving it found the landing page asking MayLand about nobody: the viewer now travels with the read. Three rows are proved elsewhere and named in the file so the matrix reads complete. closed check-in: 2a68c15ebf user: dmestas tags: protect-5

23:16
RFC 0007 phase 4: the settings surface, under a

Protected branches beside capabilities on the repository settings page: a branch or glob per row, owners as logins, every matching rule applies, blank the owners to remove one. The form rebuilds the stored set, so a renamed row is a delete and a write.

The cost is stated where the rule is set, because both things it changes surprise someone who knows fossil: on this forge i means less than it means in fossil, and a stock client can be refused a push its capability string says it may make. Policy of this forge, outside the repository; a clone is byte-identical to an unprotected one.

The section is not drawn on a forge with no policy store. closed check-in: 0d3bcdd784 user: dmestas tags: protect-4

23:13
RFC 0007 phase 3: the merge is the fact; accept asks MayJoin

The fold reads accepted from the DAG, for every landing: the earliest target check-in after opening whose non-primary parent is on the proposed branch. A reply asserting acceptance with nothing merged leaves the record open and is recorded as a claim; the page says so, the timeline files it as conversation. Rejection has no DAG fact and stays the reply's to say. Re-derived after every branch recompute — which now also invalidates the count memo, since it can settle a landing — so a merge pushed from a clone with no reply settles.

landing.accept refuses a non-owner on a protected target before writing, naming the owners. landing.get reports MayLand beside CanAccept so the page shows a disabled control with the reason.

Fourteen existing tests settled records by reply alone, or asserted a by-hand merge does not count; each now carries the merge it announces or asserts the RFC's reading. Giving the web fixture real check-ins exposed checkin.diff dereferencing a nil store; it now refuses, after the lookups so not-found still wins. closed check-in: 4832508615 user: dmestas tags: protect-3

22:59
RFC 0007 phase 2: the gate turns identity into a rule

The verified login — never the U card — becomes the per-request X-Zit-Protect the --fronted child enforces: the globs this pusher does not own, comma-separated as zit's glob lists are.

Sent on EVERY request, empty when nothing is refused. zit#151 reads an absent header as no rule, so absence is exactly what a forgotten code path would produce; here it cannot happen, and a test proves it against a fake child. The proxy builds a fresh request, so a client's header with that name never reaches the child. A rule source that cannot answer fails the push closed.

End to end with a real zit: a non-owner's push to trunk is refused with the branch named; the owner's identical push lands. closed check-in: daa9fc84b5 user: dmestas tags: protect-2

22:55
protect: the purge drops the rules, and the test asks the purge

The first test called DeleteRepo, which drops the repo row and leaves per-repository state to PurgeRepo — the cascade the rule was added to. Committed red because the run gating it used a regex that matched no test; caught by the suite. closed check-in: f30535d269 user: dmestas tags: protect-1

22:54
RFC 0007 phase 1: branch_protection and MayJoin

Forge policy beside repo_caps: a repository names protected branches (name or glob) and their owners. No trace in the repository; edited under 'a'; empty by default so an imported store behaves as it did.

MayJoin answers may-this-account-change-this-branch's-membership. Every matching rule applies, so a glob and a narrower name on one branch can only narrow. Refused lists the globs an account does not own — the per-request rule the sync gate will hand its child. A store that cannot answer says no: silence is not consent. check-in: 70d043b2e7 user: dmestas tags: protect-1

22:50
Accepted. The fold reads a fact; the gate owns the guarantee. check-in: c74cc272cb user: dmestas tags: trunk
21:17
RFC 0007: fold reads the merge unconditionally; the gate owns fail-closed

Three amendments from review, now that zit#151 has shipped.

The fold's DAG-based reading applied only to protected targets, so adding or deleting a protection row re-judged every landing on that branch — the thing Disposability forbids. It is now unconditional: a DAG fact is the same fact under any policy. The merge is identified structurally (non-primary parent on the proposed branch, bounded by the open date), not by tip ancestry, which breaks for a branch merged and then continued.

zit#151 shipped with an absent header meaning no rule. Correct for a bare server; behind a front it means a gate bug silently disables protection. The RFC now records that and places three obligations on the gate: always set the header, strip the inbound one, prove both.

Test matrix gains the missing rows; What-this-is-not records the supersede interaction; build order marks phase 0 done. closed check-in: 2eff0c5d61 user: dmestas tags: rfc-0007-review

16:33
comments: render fossil links in the timeline, and three routes that were dropped

The timeline printed check-in comments as escaped text, so fossil's own bracket links showed as markup. commentHTML already existed and was wired to the check-in page only; the timeline now uses it for the lead line and each paragraph. Flat rows keep plain titles — theirs are drawn inside a link already, and an anchor cannot nest.

Surveying every link form fossil writes turned up three quarry HAS a page for and dropped anyway: /info, /artifact and /whatis (21 citations across the corpus) reach the same page a bare [hash] does, and /tktview reaches the ticket. A hex tail is required, so /info/2020-06-02T17:38z keeps its documented fate.

An unlabelled route printed its own path as the link text — markup leaking into prose, the one thing this renderer must not do. Those now read as prose.

/forumpost still aims at the forum index on purpose: measured against the fossil clone, 303 of 304 cited forum hashes are not present locally, so a deep link would 404. check-in: 51930149be user: dmestas tags: trunk

15:46
landings: one write path for remarks again (zit#149)

zit landing comment grew --reply-to, so a parented remark no longer has to detour through forum reply. Both cases go through LandingSay, which means the landing-specific error handling below — conflict and refusal decoding — now covers every remark rather than half of them.

The same-thread check stays. zit refuses an out-of-thread target too, but here it is a capability boundary: quarry does not delegate its permission model to an upstream refusal.

Artifact cards verified unchanged: G=root, I=parent, identical to what the forum-reply path produced. check-in: 3886890ee7 user: dmestas tags: trunk

15:45
landings: one write path for remarks again (zit#149)

zit landing comment grew --reply-to, so a parented remark no longer has to detour through forum reply. Both cases go through LandingSay, which means the landing-specific error handling below — conflict and refusal decoding — now covers every remark rather than half of them.

The same-thread check stays. zit refuses an out-of-thread target too, but here it is a capability boundary: quarry does not delegate its permission model to an upstream refusal.

Verified the artifact cards are unchanged: G=root, I=parent, identical to what the forum-reply path produced. closed check-in: bda97ce3df user: dmestas tags: protected-branches

13:49
Accepted. The pattern hid two pages; the panel showed which one was slow once it stopped showing the pattern. check-in: 7ec507a60e user: dmestas tags: trunk
13:49
Dashboard: memoise the per-kind census; stop filing assets as renders

Two things the ops history surfaced.

GET /{$} serves two pages: the fleet for anonymous readers and the dashboard for signed-in ones. The census fix landed earlier addressed the fleet listing, so the spike a signed-in reader sees was never touched — the route pattern hid two different pages, which is the thing the drilldown exists to expose.

Measured cold across this fleet, EventKinds is 610ms of that page: a full covering-index scan of every artifact, per repository, for numbers that only move when a fold does. Memoised beside the other two, invalidated with them. TicketCounts measured 110ms and was left alone.

Asset requests are file serving, not renders. The browser asks for a sourcemap nobody ships, so /assets/datastar.js.map fell to the catch-all and filed a 404 against route '/' several times per page view. closed check-in: 9bc994bada user: dmestas tags: ops-noise

13:45
land protected-branches check-in: caaa75e5e6 user: dmestas tags: trunk
13:41
RFC 0007: protected branches — ownership enforced where identity is a fact

A check-in joins a protected branch only by an owner's hand; accepting a landing on it follows from that rather than being a second rule. Policy lives in OLTP beside caps, is evaluated at the xfer gate and the accept op, and writes nothing to the repository — fossil compatibility is a normative section, not a hope. The one zit change is drafted in Appendix A. check-in: d4cf4acf26 user: dmestas tags: protected-branches

13:37
Accepted. Clicking through found what testing the parts did not. check-in: 111491a3a9 user: dmestas tags: trunk
13:35
landings: mark the two-verb remark path as blocked on zit#149

Filed upstream: landing comment sets G and I to the record root, so it cannot aim a reply. The forum-reply route stays until that lands; quarry ticket 6f4c8579f0b5 tracks collapsing the fork. check-in: b459791bbd user: dmestas tags: trunk