| 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. |