Skip to content
quarry Timeline
Login

Timeline

50 descendants of 0d65af656c8d3838

2026-08-27
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:37
ops: the path actually requested, and two broken links

Recent renders showed the route pattern, so a dozen rows all read GET /r/{repo}/timeline and none could say which repository was slow. The URL is now recorded and shown, with the route beside it as the link to its drilldown.

Two bugs found by clicking through rather than by testing the parts:

queryesc double-encoded every URL it touched, because html/template already escapes a value in query context. The routes panel linked to its own drilldown with %252F for a slash, so every link 500'd. Six call sites, all wrong; the function is gone.

The days control I added with the trend forwarded an empty parameter, and a numeric field with a default takes it when the key is MISSING and refuses when it is present and empty.

Routes panel gains a filter and a sort; renders gain a deeper-history page reading the store rather than the ring. closed check-in: 2d033f106e user: dmestas tags: ops-paths

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

13:28
footer: shed the timing breakdown before it overlaps the links

At phone width the brand and version already retire, but the timing string alone still outran the viewport — and being flex:none it printed over the footer links rather than giving way. The per-store breakdown now retires at the same step the brand does; the total, which is what the footer is for, survives.

The collapse test pinned the whole media rule, so adding a part to a step read as a regression. It now matches the breakpoint and the parts within it, and asserts the total is never itself hidden. check-in: d7ff96b534 user: dmestas tags: trunk

13:13
landings: keep the reply badge and the state mark in one grid cell

t-row is a three-column grid. The reply badge made the state mark a fourth child, which wrapped to an implicit row under the glyph — the accepted pill dropped onto a line of its own. Both now sit in a t-tail cell, so neither can displace the other. check-in: f876bfc649 user: dmestas tags: trunk

13:09
landings: forum niceties — reply count, threading, per-post reply

The landing list carries a reply badge, the same .t-conv/#i-comment the ticket list uses; the count excludes state transitions, which are events rather than things anyone said.

The discussion renders as the thread it is: the forum's own forumPostRow, participant spectrum, hue edge, indentation and 'replying to' attribution. The threading walk moved out of the forum handler into threadShape so the two pages cannot drift.

A remark aimed at a post goes out via 'zit forum reply' — a landing thread is a forum thread of the same artifact kind, and that is the one verb that can point the I-card at something other than the opener. The target is checked against the record's own thread first.

Merges the superseded/CI work that landed on trunk meanwhile. check-in: 5815a2a7d8 user: dmestas tags: trunk

12:58
Accepted. Ordering by the DAG, one current landing per branch, and a verdict that was already an artifact. check-in: db0ed60824 user: dmestas tags: trunk
12:56
A landing's CI verdict: the branch tip's tag, nothing new minted

The ticket asked to decide the shape — forum reply or tag — before wiring the display. Neither is needed: a verdict is already a tag on a check-in, quarry already folds and reads them, and a landing proposes a branch whose tip is a check-in.

Better on its own terms too. The verdict stays attached to what was actually tested rather than to a discussion record, keeps the zit#127 invariant with no new vocabulary, and a retargeted or reopened landing inherits the right answer without anyone copying it across.

Read at render, never stored, so it cannot go stale against the branch it describes. No run leaves it empty, which reads as 'nothing has run' rather than as bad news. closed check-in: 1305bb9374 user: dmestas tags: landings-batch

12:53
One open landing per branch: refuse the second, and agree which wins

zit#127 left this as 'probably yes, refused by name on the second' and neither side enforced it, so two threads naming one branch produced two open landings with nothing saying which accept should honour.

Both halves, because refusing is not enough: two peers can each open one in separate clones and both are valid artifacts when they meet. landing.open refuses by name; the fold picks the newest root as current and marks the rest, recomputed each fold so a record revives if the one that displaced it is settled.

Settled landings never take part — a later proposal for the same branch is a new proposal, not a correction of a finished one. Nothing is deleted; a record somebody argued in is not noise. check-in: c2930a1351 user: dmestas tags: landings-batch

12:48
A landing's commits in ancestry order, not date order

The page listed the branch through the timeline, which orders by (date DESC, hash DESC). Two check-ins in the same second tie on date and then order by hash, which has nothing to do with which is the parent. Commits land back-to-back here routinely.

zit hit this in landing show and its fix is the one to inherit: the verb owns no ancestry ordering of its own. A recursive walk from the branch tip, ordered by longest path back, stopping where the branch diverges from its target.

The test commits three times in one second with hashes whose order is the reverse of ancestry — the old sort gets it exactly backwards and looks plausible doing it. check-in: 21fde3240d user: dmestas tags: landings-batch

12:44
Accepted. A revision cannot go stale; a rendered row can. check-in: 105cfb9c18 user: dmestas tags: trunk
12:43
Timeline: a revision signal, not rendered rows

The stream carried the filter it was opened with, so every later tick repainted the reader's page with a view they had left. That is not a bug that gets fixed once — it shipped, was fixed this morning, and would come back the next time a default moved, because the shape makes it possible.

The fleet page was rebuilt around a revision number for this reason. The timeline now follows: the signal says THAT the repository changed, the client re-requests the listing and sends its own controls with it. Nothing can capture a filter and outlive it.

A fragment is delivered as SSE but is a render, so it is marked and still measured — otherwise the refresh path would have been the one route the ops panel could not see. closed check-in: 0f1c202c58 user: dmestas tags: tl-rev

12:41
A settled landing diffs against its fork, not the moving tip

An accepted landing showed an empty Changes section. Not an error — the right answer to a question nobody was asking.

While a landing is OPEN the useful base is the target's current tip: what would merging this change now. ForkPoint's comment says as much and calls the distinction deliberate. But once the record is SETTLED the branch is already contained in the target, so that question has a degenerate answer, and the only reading left is historical: what did this branch do. That is the fork point.

Base is chosen by state now. On the record that prompted this, the diff goes from 0 files to 12.

Second defect in the same block: the else branch says it exists so an empty Changes section never reads as 'no changes', but it only fires when the invoke FAILS. A call that succeeded and found nothing fell through to the success path and rendered exactly that blank. It now says so, naming both check-ins. check-in: 469dbab422 user: dmestas tags: trunk

11:24
Accepted. The link was in the DAG the whole time, and the history is finally being read. check-in: 23cec0f0fd user: dmestas tags: trunk
11:24
ops: read the history back — a route across days

The store recorded renders and nothing read them. The panels are one process's memory, so the page could say how fast a route is now and never whether it is worse than it was — which is the question after a deploy.

The drilldown gains a per-day table from the store: p50, p95, max. Nearest-rank percentiles, matching how the snapshot computes them, so two numbers on one page both called p95 agree.

Empty for no traffic and empty for history-off are different answers and the page gives the right one. closed check-in: a0fa952495 user: dmestas tags: landing-merge

11:19
Link a landing to the check-in it produced

settled_by names the reply that decided the state, not the commit, so this was assumed to need an upstream change. It does not: a merge check-in lists its primary parent first and the branches it merged after, so ord > 0 is the branch tip that landed, and the landing knows which branch it proposed. Structural, not a text or time heuristic. Resolves 18 of 18 accepted landings in this store.

Bounded by when the landing OPENED, not when it was accepted: the merge lands before the artifact recording it is written.

The landing page says what it landed as; a merge row on the timeline names the proposal and who approved it. Decorated, not collapsed — a merge is a real DAG node and hiding it would leave the graph drawing edges to a row the timeline does not show. check-in: 06475f5aee user: dmestas tags: landing-merge

10:05
Accepted. A decision record and a discussion thread are different things, and the timeline now says which is which. check-in: 349027e507 user: dmestas tags: trunk
10:02
Timeline: landings are landings, not forum posts

Landings are built on forum artifacts, so the forum trigger filed every comment and verdict as kind 'f' with a 'Forum: ' prefix — rows reading 'Forum: zit-landing-state: accepted Accepted. The forge now tells y'. quarry had already decided these are not forum content; the timeline was the surface that missed it.

Verdicts are kind 'l' and appear in a mixed timeline because they change the target branch. Comments are 'lc' and appear only under the new y=l. Both link to the landing rather than the post.

Classified in the fold, not the trigger: the trigger fires before the landing row exists, since the root post is what it is derived from. Backfilled for stores folded before this. closed check-in: 5d398dd22e user: dmestas tags: landing-timeline

09:37
Accepted. The panel found something real, and the two things it could not say about itself are now things it says. check-in: 13cb36d2e5 user: dmestas tags: trunk
2026-08-25
22:22
ops: name the untimed remainder instead of leaving it to subtraction

SQL has no timing category of its own and cannot easily get one: the sqlite driver builds its connector through an unexported constructor, so there is nothing to wrap. The panel's honest answer is subtraction, and subtraction the reader does in their head is not an answer.

'rest' is now a column, the lede says what the ops-minus-zit gap contains and why SQL is not split out. closed check-in: 0d65af656c user: dmestas tags: fleet-census