Repository navigation
Conversation
Contributor
Author
Decision takenThe round 1 spec review asked for three decisions. I kept what the PR already does in each case: it is closest to the code and the easiest to undo.
The issue body records all three as pending the maintainer. Written by an agent. |
Contributor
Author
Review notesNot blocking, not verified. Each is one reviewer's claim.
Written by an agent. |
V3RON
marked this pull request as ready for review
October 19, 2026 10:05
V3RON
added this pull request to stack #691
October 19, 2026 10:05
V3RON
added a commit
that referenced
this pull request
Oct 19, 2026
…stats and console figures (#623) (#626) Delivers #623: the event history moves to `history.db`, with usage projections, `simlock stats`, `GET /v1/stats` and the console's figures. It also includes ADR 0032. This PR carries the whole feature. The stack's PRs were reviewed one by one, and then a stack sync pushed every branch to one commit. GitHub then marked them as merged into each other, never into `main`. Their reviews stay there: - ADR 0032 (this PR) - #635 → #690 - #636 → #692 - #637 → #693 - #629 → #694 - #630 → #695 - #631 → #711 - #632 → #724 - #633 → #727 - #634 → #731 After the sync onto `main`, a fix-check reviewed the conflict resolutions. Its fix makes `history.db` and its WAL/SHM files owner-only (0600), as #685 did for `events.jsonl`. Closes #629, closes #630, closes #631, closes #632, closes #633, closes #634, closes #635, closes #636, closes #637. ### Status Implement: done Review: per-task PRs passed; sync fix-check passed Hardware: n/a Gate: running ## Review Spec review: skipped. Code review: 4 blocking, 4 fixed, 1 notes. Claims review: 0 blocking, 0 fixed, 0 notes. Rounds: 1. Tokens: 29.0M. *Written by an agent.*
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #631
Status
Implement: done (all spec tests green, audit 6/6) Review: round 2, 0 open Hardware: n/a Gate: waiting for the stack
Done when
simlock stats --since 1hprints requests and grants by source; wait, held, turnaround, provisioning and boot p50/p95/max; rejections by reason and incidents; use per platform, worker and requester.--jsonprints the same figures, and the counts matchsimlock events --since 1hcounted by hand.simlock stats --from <before the run> --to <after it>, with--tobefore the stop, prints the same output, whole, aftersimlock daemon stopandsimlock daemon start.simlock stats --since 30don a fresh install printsFigures cover from <time>above the figures; a window ending before the oldest row exits 12 with theHISTORY_NOT_KEPTmessage.simlock statswhilehistory.dbcould not be opened exits 1 withHISTORY_UNAVAILABLE.docs/CLI.mddescribessimlock stats, its flags, the partial note and exits 12 and 1;docs/CLIENT.mddescribesusage.Assumptions
Assumption: where the figure tests drive the code — the counting, sampling, window, series and coverage claims drive
createUsageReaderover a realhistory.dband the real read thread (the module surface both handlers call); the claims that belong to a handler (labels, the worker's own entry,HISTORY_NOT_KEPTandHISTORY_UNAVAILABLEtext, the read thread's dedupe and crash) drive the worker and gateway dispatchers. This avoids repeating one figure test in two dispatcher harnesses.Assumption: how a dispatcher learns the history file — both dispatchers take an optional
historyPathand readeventHistory.status().opened(both already holdeventHistory), and build their own reader; green makeshistoryPathrequired anddispose()stop the reader.Assumption: the shared test rig (
usageRigand the event builders) lives insrc/history/testing.ts, the one place dependency rules let the daemon, gateway and core tests import it from.Assumption:
historyPathstays optional on both dispatchers (the red-stage note said green would make it required) — many existing harnesses build a dispatcher without a history file; with none,usage.getanswersHISTORY_UNAVAILABLE.main.tspasses it in both modes.DaemonServergained the same optionalhistoryPath, andcreateHarnessinserver.test.tsgained awithHistoryoption so the routing test runs over a real openhistory.db.Assumption: minute figures (slots, RAM, queue, series) read complete minutes only — the minute still running at
tois left out, because that row is stored as if its last value held to the minute's end and is cut at a stop, so the e2e's "same output after stop and start" cannot hold with it in. A window shorter than one minute has no slot, RAM or queue figure.Assumption: a mean is the sum of integrals over the sum of
knownMsof the buckets that hold that field — equal to the spec's wording when every bucket has it, and not pulled down by buckets that lack RAM or queue.Assumption:
bySource.unknownis counted on a gateway only (a grant with no source), as PR feat(usage): usage.get and simlock stats, the figures from the event history #356 did; a worker counts only warm, booted and provisioned.Assumption:
src/gateway/boundary.test.tscountsrepublishcallers outsidetesting.tshelpers, since the rig insrc/history/testing.tsrepublishes relayed events; and.oxlintrc.jsonlets the gateway importcreateUsageReaderandUsageReaderfrom core, the one place the dispatcher builds its reader.Assumption: a failed read (thread exit, SQLite error, no answer) reaches the caller as a
DispatchErrorwith codeINTERNAL, built inusageAnswer, so the code is on the error and the operation line logs it aterror.Assumption: under vitest the read thread runs
read-thread.tsitself, with--experimental-transform-typesand a resolve hook that maps.jsimports to.ts; built, it runsread-thread.js.Assumption: a time with a day the month lacks (
2026-02-31) or the hour 24 is a bad time —Date.parserolls both over to another instant, and a typo must not ask for another window; the smallest strict reading of ISO 8601.Assumption: the 500 ms read bound times a running read thread — the timing test makes one small read first, because a source run (CI measured 574 ms, 140 ms of it thread start-up) transpiles the thread's modules, which a built daemon does not; the 7-day read itself took about 70 ms.
Review
Spec review: 0 blocking, 0 fixed, 3 notes. Code review: 2 blocking, 2 fixed, 0 notes. Claims review: 3 blocking, 3 fixed, 1 notes.
Rounds: 2. Tokens: 14.7M.
Written by an agent.