27 check-ins that include changes to files matching 'internal/obs/*'
|
2026-09-27
| ||
| 11:38 | Merge trunk into background-jobs-follow-the-lease check-in: cf04732cdd user: dmestas tags: background-jobs-follow-the-lease | |
| 11:27 | update node-identity-is-persisted from trunk closed check-in: f61888abaf user: zeitgeist tags: node-identity-is-persisted | |
| 11:23 | update ci-race-on-landings from trunk closed check-in: 3bfe3ae2d8 user: zeitgeist tags: ci-race-on-landings | |
| 11:12 | land ops-history-flush-off-request-path check-in: 1bcff88f59 user: dmestas tags: trunk | |
| 04:47 | Rows lost to a failed or cancelled write count as dropped, and the ops page shows the count check-in: 9f7e279623 user: dmestas tags: ops-history-flush-off-request-path | |
| 03:43 | Flush ops history off the request path and keep web renders in their own recent window check-in: 3bdf2f891d user: dmestas tags: ops-history-flush-off-request-path | |
| 03:23 | web: pages are opaque handles drawn only through a handler's hooks; register ciRunPage and personEditPage check-in: b67646c5ba user: dmestas tags: handler-owned-page-templates | |
| 02:46 | land api-ops-are-timed-at-the-registry check-in: 26de248275 user: dmestas tags: trunk | |
| 02:39 | Time every op at the registry and file API calls beside web renders, tagged by surface closed check-in: ccbcf4b34e user: dmestas tags: api-ops-are-timed-at-the-registry | |
|
2026-09-16
| ||
| 14:22 | land subprocess-attribution check-in: f4954b0794 user: dmestas tags: trunk | |
| 14:13 | Every store subprocess says which repository, and what asked for it closed check-in: 9638c1ae6d user: dmestas tags: subprocess-attribution | |
| 13:35 | land ops-sparklines check-in: 62a9e64488 user: dmestas tags: trunk | |
| 12:54 | A line on the ops cards: the shape behind the number closed check-in: 794d67bdee user: dmestas tags: ops-sparklines | |
|
2026-08-31
| ||
| 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 | |
|
2026-08-26
| ||
| 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 | |
| 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 | |
| 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:19 |
Analytics: say whether history is being kept, and stop keeping it for ever
The live panels read in-memory rings, so a forge whose store failed to open looked exactly like a healthy one. Sink.Err() existed and nothing asked it. The page now distinguishes three states: off, broken, and recording to a named path. Retention was 'append for ever', which is a default nobody was asked about. --analytics-keep sets the window, 14d by default, 0 keeps everything. Pruned at startup and daily. check-in: e2b74749b4 user: dmestas tags: fleet-census | |
| 21:53 | Accepted. It can now say which repo and which calls — which is the difference between finding a slow route and fixing one. check-in: 7059271e59 user: dmestas tags: trunk | |
| 21:45 |
ops: open a route up — which repository, and which store calls
The panel finds a slow route; this says why. Two things the roll-up cannot show. WHICH REPOSITORY. A route pattern folds pikchr and tcl into one line, and repository size is the dominant cost on this fleet — GET /r/{repo} at 420ms could be either, and the two differ by orders of magnitude. WHICH CALLS. Each recent request is listed with the store calls it made, in the order it made them, and what they cost together. A request with no calls listed spent its time somewhere else, which is itself the answer when the store is not to blame. Reads the same rings the panels read, so a request that has aged out simply is not there. That is the honest limit of a snapshot: this answers what a slow request just did, not what happened yesterday. check-in: bb6ec6b896 user: dmestas tags: ops-drill | |
| 21:42 |
ops: tie a store call to the request that caused it
The panel could find a slow route and never say why: the render list and the subprocess list were two independent tables, so 'GET /search took 1132ms' and 'zit artifact ran 499 times' could not be connected even when one caused the other. Every request is now tagged at the outermost middleware, and every store call records the tag. Work with no request behind it — ingest rounds, warm passes, the doc indexer — records the empty string, which is itself the useful distinction: store load with nothing to blame is background, and telling the two apart is most of what the subprocess panel is for. Also fixes a silent hole of the same shape as the route-pattern bug: Repo was read with req.PathValue in the outermost middleware, where the router has not set it — the values live on the request the mux passes DOWN. Every render recorded until now carried an empty repo, 61 of 61 rows in the analytics store, which made the numbers unattributable on a fleet where repository size is the dominant cost. Read from the path instead. check-in: bc35cc0c45 user: dmestas tags: ops-drill | |
| 21:09 | Accepted. The forge now tells you, rather than waiting to be asked. check-in: 3f238c575b user: dmestas tags: trunk | |
| 19:29 |
tests: add the budget guards, which the last commit left behind
Same mistake as before: extras was printed and then the commit ran without the add. Caught by checking the check-in rather than the worktree, which is the only check that works. closed check-in: 63ad319ef2 user: dmestas tags: ops-budget | |
| 19:29 |
ops: the budget is one number, and it notifies
500ms was a literal in a template and a constant nowhere. The panel coloured a p95 over it and nothing else knew, so the forge could show a route in red and tell no one. obs.Budget is now the single definition. The panel colours against it — sent on the wire rather than hardcoded, so the page and the threshold cannot disagree — and crossing it triggers a notification. First crossing only, on errlog's rule and for errlog's reason: the same page is slow on every request until somebody fixes it, and an alert channel that repeats itself gets muted. A muted channel is worse than none, because it reads as healthy. The decision is made under the lock, so two slow requests racing on one route cannot both report it. This is the difference between an operator watching the forge and the forge watching itself: the ops page has to be looked at; a notification arrives. check-in: fc8ef2165b user: dmestas tags: ops-budget | |
| 19:02 |
Add internal/obs, which trunk imports but did not carry
Check-in 2cacce9b01aa added obs.Default.Spawned, RecordSubprocess, RecordRender and Snapshot calls across zitcli, web and api, but the package itself was never added — so trunk did not compile at all. The files are the ones from the authoring session's tree, unmodified, tests included. Nothing here is my design; this only makes the import resolve so the tree builds again. check-in: 5229b05522 user: dmestas tags: trunk | |