Skip to content

M1-68 Server core metrics per catalogue

No Date Ruling Reason
M1-68/0 2026-10-18 Base int/m1-wave39 at 8489df6, branch feat/M1-68-core-metrics in its own worktree; the branch is not merged locally and not pushed, the integration lane ports it. Brief and spec were read from origin/main; the base carries the same catalogue rows and definitions (fan-out lag, client_error, bothy.authz.decisions without filters, job outcomes, layer rule 5) in its edition of the documents, so no contract commit was brought in. Instructions of the launcher, which override the brief's merge step.
M1-68/1 2026-10-18 db.client.operation.duration comes from the query tracer of platform/pg, not from otelpgx: otelpgx v0.13.0 records the raw first word of a statement and pgx.operation.type and no db.collection.name on query metrics, so the view drops every otelpgx instrument. db.operation.name is the first keyword (for WITH the main statement's) from a closed list, db.collection.name the table read or written, from the tables the embedded migrations create (the module register, held by register-check); anything else is other, without a table the key is absent. Only queries are measured, not batches or COPY FROM. Brief: "otherwise an own pgx query tracer"; the migrations are the closed table list platform/pg may read (migrations is used by pg in the register).
M1-68/2 2026-10-18 kernel/txn gains AfterCommit(ctx, fn): platform/pg runs the registered functions after a successful COMMIT of the outermost unit, never after a rollback, and a retried attempt starts without them. bothy.message.created and bothy.event.appended count through it. Both metrics count "after commit only" and the unit of work had no such step.
M1-68/3 2026-10-18 bothy.gateway.close counts once per connection: the code of the server's close, else the code of the client's close frame; a connection that ends without any close frame (a lost network) counts no close. 04 "Close codes" defines codes of close frames; a vanished TCP connection has none.
M1-68/4 2026-10-18 bothy.gateway.connect.duration before ready carries the actor's kind once identify or resume authenticated it (a later setup failure such as 4000 from the snapshot) and anonymous before; a refusal of Open (sync epoch unreadable, draining) records server_error and its close. signals.md 4.1 and the brief: kind anonymous before identification.
M1-68/5 2026-10-18 bothy.gateway.catchup.duration is recorded at catchup.complete and at resync_required; a connection attached at the head sends neither and records nothing. The metric measures the time to these two frames.
M1-68/6 2026-10-18 bothy.gateway.outbound.dropped with slow_consumer counts at a 4014 close the events of the hub's live buffer, the frames of the adapter's outbound queue, and the one frame that did not fit or missed gateway.write_timeout. Ephemeral frames dropped on a full queue (no close) are not counted. The brief: frames discarded at a 4014 close, live buffer included.
M1-68/7 2026-10-18 bothy.authz.decisions counts no check that failed with an error. An error is no decision of 05 2.5; it is audited as a decision error and an unknown action counts in bothy.authz.errors.
M1-68/8 2026-10-18 For bothy.event.fanout.lag an event "becomes known" when the sink of the log tail receives the batch read after a NOTIFY or a poll (Hub.Known). The tail reads after every wake-up; the time between a NOTIFY and its read is part of the read, not of the fan-out.
M1-68/9 2026-10-18 bothy.secrets.refresh.failures is declared in the registry but still created by platform/secrets with the same name, unit and description, and bothy.egress.blocked is declared without a recorder: no OTel implementation of egress.Metrics exists on the base. platform/otel depends on platform/secrets, so the register forbids the reverse edge; the view still holds the name and the attribute keys of both.
M1-68/10 2026-10-18 The registry also declares bothy.event.consumer.lag and bothy.event.consumer.pending_age (M2-01, on the base). Every instrument the server registers comes from the registry; the view drops undeclared ones.
M1-68/11 2026-10-18 Catalogue fixes the build proved: section 3 names the series target_info (used by a dashboard and an alert), the first row of 4.7 names the five app histograms of 4.6a, and the Source column of db.client.operation.duration names the query tracer. signal-check rules 1 and 2 fail without them; the files that use target_info are right.
M1-68/12 2026-10-18 bothy.db.pool.connections observes only the process pool: internal/wire calls Pool.RegisterMetrics once after Open; pools of migrations and tests are not observed. One pool per process (02 "Deadlines"); a second registration would report two series of the same state.
M1-68/13 2026-10-19 Port to main: the ticket's own commits on top of the ported M1 chain and M1-67; the documents take the ticket's additions in the English chapters of main, and the four docstrings of tools/signalcheck follow the stricter ruff rules of main. INT-W42/4 and /5 stay with M2-07. Superseded by M1-68/14. Only the ticket's own change lands.
M1-68/14 2026-10-21 Port onto main right after M1-66, without M1-67, which is not on main yet: the build files (Makefile, tools/pyproject.toml) and the logs take only the additions of this ticket (signal-check, tools/signalcheck), not the gates of later tickets that the chain carried next to them. M1-68 depends on M1-04, M1-50 and M1-66 only; the metric code uses nothing of M1-67.