| Artifact ID: | ef5084b7d3a9d592ac60b88aef2ddcbe33b1d546206748edcc0676744dd14946 |
|---|---|
| Page Name: | Audit after change |
| Date: | 2026-08-21 18:34:39 |
| Original User: | dmestas |
| Mimetype: | text/x-markdown |
| Next | bbad8c47a4f51dce832e827239f052ca1196e9b8333347ae7516c0a332b62dbe |
Audit after change
Features that are rarely reached in ordinary use, so a regression goes unnoticed until someone lands on the one page that exercises them. After any change touching the areas named, walk the relevant checklist by hand — the automated coverage is listed where it exists, and its gaps are the point of this page.
Add an entry when you build something that (a) only shows up on unusual data, (b) has a no-script or progressive-enhancement path, or (c) depends on a browser behaviour a unit test cannot see.
1. Large-diff windowing (check-in page, /diff, /diff.frag)
Why rare: only a check-in with more than ~3,000 diff lines triggers it. Most check-ins render in one window and the whole mechanism is invisible.
Canonical case: fossil 62b38332f7e0d122dd5d6b19b6a89033ea7612a3d38876972015db876cb34b44 — a 600-file, 216K-line merge.
- Check-in page:
/r/fossil/checkin/62b38332… - Single file, 54K lines:
/r/fossil/checkin/62b38332…/diff?file=extsrc%2Fsqlite3.c
Touch points: internal/diff.Window / LastWindow, checkin.diff op (offset, maxLines, file, nextOffset, lastOffset, totalLines), diffWindow() and the diff-body / diff-more / diff-pager templates in internal/web/web.go, the #diff-more sentinel, diffBudget.
Checklist
- [ ] With JS: first window renders; scrolling the
⋯sentinel into view appends the next window in place (row count grows, a(continued)section appears when a window opens mid-file); repeat to the end; no pager visible; no "continue" link visible. - [ ] Without JS (DevTools → "Disable JavaScript", reload): no "the rest loads as you scroll" note; pager shown at top and bottom of page 1;
Next ›goes to?after=N&prev=M;‹ Previousreturns;« StartandLast »land on the first and final windows. - [ ] Line readout
Lines a–b of T:Tis identical on every page of the chain, and on theLast »pageb == T. - [ ] A hand-typed mid-hunk
?after=snaps back to a hunk boundary (readout still sums toT). - [ ]
?file=with a slash in the path renders that file, not the file list (watch for double-encoding,%252F). - [ ]
?view=splitsurvives Next/Previous/fragment URLs. - [ ] Response time: warm page < 300 ms; cold first hit is bounded by
zit diffitself (zit#110 tracks path-filtered diffs).
Automated: internal/diff/window_test.go (contiguous chain, snapping, LastWindow agreement). Not automated: the intersect fetch, the <noscript> swap, the attribute name data-on-intersect (the data-on:intersect spelling silently does nothing in Datastar RC.7).
2. Changed-file list on very large check-ins
Why rare: same data as §1; lists under ~30 files look fine as a flat list, so a broken grouping only shows at scale.
Planned shape: directory tree with <details> groups collapsed past a threshold, A/M/D summary strip with status filters, multi-column rows inside open groups. When built, add its checklist here: groups collapsed/open by threshold, single-child directory compression, anchors still reach the diff sections (including not-yet-loaded windows), <details> works with scripting off.
3. Fleet fragment parity (/fleet.frag, /fleet.rev)
Why rare: the live fragment replaces the server-rendered listing moments after load; a field the fragment omits flashes and vanishes, which is easy to miss and looks like flicker.
Checklist
- [ ] Signed-in admin: "New repository" link, "N of M repositories" count, filter and sort all persist after the first live refresh.
- [ ] Anonymous: no admin-only controls appear at any point.
- [ ] Filter typed with JS on updates the list without a page load; with JS off, Enter submits a GET that lands on the explore view.
Automated: TestFleetFragmentCarriesEverythingThePageDoes.
4. Explore vs. personal dashboard routing
Why rare: / is the explore listing for anonymous readers and the personal dashboard for signed-in ones, so links that say / behave differently depending on who clicks them.
Checklist
- [ ] Signed in: explore tabs (repositories ↔ people) and the filter's
×clear link stay on?view=explore, never drop to the dashboard. - [ ] Anonymous: the same links land on the explore listing.
5. Repository posture: mirrors, detached stores, refused writes
Why rare: the mirror/native distinction only shows on a forge that mirrors other projects, and the failure and detach states need an upstream to go away or an operator to act. Most pages are native repos where none of this renders.
Canonical case: any mirrored repo (/r/fossil, /r/wapp); a failing one is made by pointing a test mirror at https://dead.invalid/home and pulling once. Branch mirror-posture.
Touch points: oltp.SetMirror/DetachMirror/SetMirrorWrites, api.posture/mirrorState/Writable/refuseUnlessWritable, ops.ErrForbidden, xfer.SetWriteGate, the posture type and repobar template in internal/web/web.go, /fleet mirror table and #mirror-form, /new kind radios.
Checklist
- [ ] Repo header on a mirror:
⟲ mirror of <host>chip linking to the upstream;· accepts writesonly when allowed. Detached store:forked from <host>. Native store: no chip. - [ ]
failingstate: a one-line notice under the bar ("upstream X unreachable (N attempts); showing content as of …");laggingstays silent;currentshows nothing. - [ ] Read-only mirror: "new ticket", "new thread", "edit" (wiki), "reply" become "… on <host> →" links to the upstream's
tktnew/forumnew/wikiedit?name=/forum. After "allow writes" they revert to local links. - [ ] API/xfer:
POST /api/v1/r/<mirror>/ticketreturns 403forbidden: <repo> mirrors <url> …; azit pushto a mirror gets the xfer error reply, whoever signed it. - [ ] Explore:
⟲glyph after mirrored names;kind=mirror|nativeselect filters and the count reads "n of served". - [ ]
/fleet: State column shows current/lagging/failing/detached from one derivation; Writes column; pull / edit / allow·refuse writes / detach per row; a detached row shows "detached from <url>" and a re-attach link;?edit=<repo>prefills the form and the button reads "Save mirror". - [ ] Posture changes: changing the URL clears failures; same URL keeps them; detach keeps the URL as
detachedFrom; re-attach clears it and returns writes to refused. - [ ]
/new: Start empty / Import and own (clone,noMirror) / Mirror (clone + interval) produce the expected posture onrepo.get.
Automated: internal/oltp/mirror_test.go, internal/api/mirror_posture_test.go. Not automated: the header/notice rendering, the link swaps, the fleet actions.
Conventions
- Keep the canonical repro URL for every entry; a feature that is hard to reach needs a shortcut to reach it.
- Prefer adding an automated test and then noting it here; leave the manual checks for what tests cannot see (scroll, no-script, timing).
- When a change makes an entry obsolete, delete it rather than leaving stale steps.