Skip to content

feat: wire metrics end to end, retire the Pages site, six executed tutorials - #44

Merged
sebyx07 merged 1 commit into
mainfrom
feat/docs-metrics-tutorials
Aug 11, 2026
Merged

sebyx07 merged 1 commit into
mainfrom
feat/docs-metrics-tutorials

Conversation

@sebyx07

@sebyx07 sebyx07 commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor

1. /metrics went from a constant to an actual scrape

1.1.0 shipped a metrics API and nothing called it. The Helm HPAs scaled sync on connections and worker on queue_depth — series nothing emitted, from pods that in the worker's case had no HTTP port at all.

Three call sites, each in the package that owns the event:

Recorder Where Why there
recordRequest pipeline.ts, a finally around execute execute absorbs app throws, but a finalize stage can still throw on its own. A finally is the only placement that counts every request exactly once
recordConnection SocketRegistry.add / remove that map is the only definition of a live connection on a node. sweepIdle deleted from the map directly — the one path that leaked the gauge
recordQueueDepth top of the worker's tick(), throttled 15s stats() aggregates the whole jobs table and a scrape reads it every ~15s anyway; per-tick would multiply the queue's read load by 60

/metrics is on its own port (METRICS_PORT, default 9090), not the role's HTTP port. The Helm ingress routes / Prefix to the web Service with no path exclusion — mounting it beside /healthz would publish your route patterns, request volumes and error rates to the internet. Nothing in the chart fronts 9090, so it is cluster-internal by construction rather than by an exclusion somebody has to remember to write. Every role, not just web, because worker/scheduler/replicator open no HTTP socket and queue_depth belongs to the worker.

Cardinality is guarded: labels are route patterns (/posts/:id), never concrete paths, and a scanner hitting /wp-admin and /.env collapses to one unmatched series.

Real scrape, not an assertion

connections 2
http_requests_total{method="GET",route="/posts/:id",status="2xx"} 4
http_requests_total{method="GET",route="unmatched",status="4xx"} 1
queue_depth{queue="default"} 12

Four distinct post ids → one series. Three sockets minus one abnormal close → connections 2.

2. The Pages site is gone; the wiki is the surface

site/, .github/workflows/pages.yml and the custom domain removed; repo homepage repointed. Three tests in scripts/verify.test.ts asserted the root tsconfig referenced ./site — they went with it.

Axiom 6 is unaffected: the site/ → app/ boundary in a generated app is a different thing with the same name, still a build error.

3. Six tutorials — executed, not imagined

Every command and every pasted output was run against the published 1.1.0 packages. That is how eleven undocumented defects surfaced. The worst:

x db gen and x db migrate fail in every scaffolded app. Both shell out to bunx drizzle-kit, which x new neither installs nor configures. This also breaks bin/setup — the scaffold's own documented first command.

Others: generateMigration mangles composite indexes; a two-statement migration cannot be applied; every generated entity fails typecheck, not just the example slice; x g task without --feature emits a slice that cannot load. All named in wiki/Known-Gaps.md with tested workarounds.

4. Docs that had drifted from the code

  • wiki/Theming.md and the admin dev server both hardcoded the pre-retune palette — including the line value that measured 1.16:1 in dark. The admin server now derives from colorTokens, so it cannot drift again.
  • Theming.md claimed "nine tokens is the whole palette". There are 24 roles, and it pointed every path at a file that does not exist.
  • ROLE=all was documented in three places and does not exist — it throws X_ROLE_UNKNOWN at boot.
  • x status, x deploy static --to, x build --target docker --helm were documented as shipped. None are.
  • X_MIGRATE_CONCURRENT was described as "ROLE=migrate takes no advisory lock, serialise them in your pipeline". The lock is real (pg_advisory_lock); the code has no throw site because concurrent migrators wait rather than race. That doc would have made someone build serialisation they already had.

Gate

bun run verify — 17/17 green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H7VehLeMPyirrfxLvu3Laf


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • New Features

    • Added a dedicated Prometheus metrics endpoint with request, connection, queue-depth, and duration metrics.
    • Added six tutorials, observability guidance, UI component documentation, and known-issues references.
    • Updated the development dashboard to use runtime theme colors.
    • Published measured realtime restart-recovery results for 50,000 connections.
  • Documentation

    • Updated documentation for version 1.1.0, deployment, configuration, caching, testing, theming, and scaling.
    • Consolidated public documentation in the GitHub Wiki.
  • Chores

    • Removed the separately published documentation website.

…cs true

## /metrics went from a constant to a scrape

1.1.0 shipped a metrics API and nothing called it. The Helm HPAs scaled `sync` on
`connections` and `worker` on `queue_depth` — series nothing emitted, from pods that
in the worker's case had no HTTP port at all.

Three call sites, each in the package that owns the event. `recordRequest` sits in a
`finally` around `execute` rather than after it: `execute` absorbs app throws, but a
finalize stage can still throw on its own, and a `finally` is the only placement that
counts every request exactly once. `recordConnection` hangs off `SocketRegistry`'s
add/remove because that map is the only definition of a live connection on a node —
and `sweepIdle` deleted from the map directly, which was the one path that leaked the
gauge. `recordQueueDepth` is throttled to 15s: `stats()` aggregates the whole jobs
table and a scrape reads it every ~15s anyway, so polling it per tick would multiply
the queue's read load by sixty.

`/metrics` is served by every role on `METRICS_PORT` (default 9090), not the role's
HTTP port. The Helm ingress routes `/` `Prefix` to the web Service with no path
exclusion, so mounting it beside `/healthz` publishes route patterns, request volumes
and error rates to the internet. Nothing in the chart fronts 9090, so it is
cluster-internal by construction rather than by an exclusion somebody has to remember
to write. Every role rather than just `web`, because worker, scheduler and replicator
open no HTTP socket and `queue_depth` belongs to the worker.

Labels are route patterns, never concrete paths — a scanner hitting /wp-admin and
/.env collapses to one `unmatched` series instead of minting one each.

## The site is gone; the wiki is the surface

`site/`, `pages.yml` and the custom domain removed, repo homepage repointed. Three
tests in scripts/verify.test.ts asserted the root tsconfig referenced ./site and that
site/tsconfig.json emptied `paths` — they went with it. Axiom 6 for generated apps is
unaffected: that is the `site/` -> `app/` boundary, a different thing with the same name,
still enforced by `boundaries`.

## Six tutorials, executed rather than imagined

Every command and every pasted output was run against the published 1.1.0 packages.
That is also how eleven undocumented defects surfaced, the worst being that `x db gen`
and `x db migrate` shell out to `bunx drizzle-kit` — which `x new` neither installs nor
configures — so both fail in every scaffolded app, and `bin/setup` fails with them.
They are named in wiki/Known-Gaps.md rather than left to be discovered.

## Docs that had drifted from the code

wiki/Theming.md and the admin dev server both hardcoded the pre-retune palette,
including the `line` value that measured 1.16:1 in dark; the admin server now derives
from `colorTokens` through the same cached dynamic import `/_x` already uses, so it
cannot drift again. `ROLE=all` was documented in three places and does not exist.
`X_MIGRATE_CONCURRENT` was described as "takes no advisory lock" — the lock is real,
the code simply has no throw site, because concurrent migrators wait rather than race.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7VehLeMPyirrfxLvu3Laf
@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 98bb1cde-2ef0-4a97-b587-77fa33be66d8

📥 Commits

Reviewing files that changed from the base of the PR and between 7a8b85f and 7748af0.

⛔ Files ignored due to path filters (2)
  • site/assets/logo.svg is excluded by !**/*.svg
  • site/assets/og.svg is excluded by !**/*.svg
📒 Files selected for processing (106)
  • .claude/commands/feature.md
  • .github/workflows/pages.yml
  • CHANGELOG.md
  • CLAUDE.md
  • README.md
  • docs/README.md
  • docs/idea/01-stack.md
  • docs/idea/03-realtime.md
  • docs/idea/05-caching.md
  • docs/idea/10-testing.md
  • docs/idea/11-topology.md
  • docs/idea/12-build-deploy.md
  • docs/idea/13-dx.md
  • docs/idea/14-roadmap.md
  • docs/idea/16-app-targets.md
  • docs/idea/17-scale-ladder.md
  • docs/idea/README.md
  • docs/ops/01-kubernetes.md
  • docs/ops/README.md
  • llms.txt
  • packages/admin/src/dev/server.ts
  • packages/cli/src/cmd-dev.ts
  • packages/cli/src/dev-roles.test.ts
  • packages/cli/src/dev-roles.ts
  • packages/cli/src/errors.ts
  • packages/cli/src/index.ts
  • packages/cli/src/metrics-endpoint.test.ts
  • packages/cli/src/metrics-endpoint.ts
  • packages/cli/src/serve.live.test.ts
  • packages/cli/src/serve.test.ts
  • packages/cli/src/serve.ts
  • packages/core/CLAUDE.md
  • packages/core/README.md
  • packages/http/src/pipeline.test.ts
  • packages/http/src/pipeline.ts
  • packages/jobs/src/worker.test.ts
  • packages/jobs/src/worker.ts
  • packages/realtime/src/socket.test.ts
  • packages/realtime/src/socket.ts
  • scripts/manifest.test.ts
  • scripts/verify.test.ts
  • site/CNAME
  • site/README.md
  • site/build.ts
  • site/lib/assets.ts
  • site/lib/config.ts
  • site/lib/feed.ts
  • site/lib/highlight.ts
  • site/lib/html.ts
  • site/lib/markdown.ts
  • site/lib/seo.ts
  • site/lib/text.ts
  • site/pages/ai-first.md
  • site/pages/changelog.md
  • site/pages/deploy.md
  • site/pages/faq.md
  • site/pages/index.md
  • site/pages/jobs.md
  • site/pages/primitives.md
  • site/pages/pwa-offline.md
  • site/pages/quickstart.md
  • site/pages/realtime.md
  • site/pages/rendering-seo.md
  • site/pages/roadmap.md
  • site/scripts/theme.js
  • site/styles/base.scss
  • site/styles/components.scss
  • site/styles/layout.scss
  • site/styles/syntax.scss
  • site/styles/tokens.scss
  • site/templates/doc.html
  • site/templates/home.html
  • site/templates/layout.html
  • site/tsconfig.json
  • tsconfig.json
  • wiki/Admin-Dashboard.md
  • wiki/CLI-Reference.md
  • wiki/Caching-And-Invalidation.md
  • wiki/Configuration.md
  • wiki/Contributing.md
  • wiki/Deployment.md
  • wiki/FAQ.md
  • wiki/Getting-Started.md
  • wiki/Home.md
  • wiki/Jobs-And-Workflows.md
  • wiki/Known-Gaps.md
  • wiki/MCP-And-AI.md
  • wiki/Observability.md
  • wiki/PWA-And-Offline.md
  • wiki/Queries-And-Live-Queries.md
  • wiki/Realtime.md
  • wiki/Routes-And-Render-Modes.md
  • wiki/Scheduled-Tasks.md
  • wiki/Testing.md
  • wiki/Theming.md
  • wiki/Troubleshooting.md
  • wiki/Tutorial-01-First-App.md
  • wiki/Tutorial-02-First-Feature.md
  • wiki/Tutorial-03-Auth-And-Admin.md
  • wiki/Tutorial-04-Jobs-And-Realtime.md
  • wiki/Tutorial-05-Deploy-Free.md
  • wiki/Tutorial-06-Growing-Up.md
  • wiki/UI-Components.md
  • wiki/Upgrading.md
  • wiki/_Footer.md
  • wiki/_Sidebar.md

📝 Walkthrough

Walkthrough

The change adds dedicated Prometheus metrics endpoints and runtime metric recording, removes the GitHub Pages site, and updates the 1.1.0 release documentation. It also adds six Wiki tutorials, observability guidance, deployment limitations, testing details, and theming documentation.

Changes

Runtime observability

Layer / File(s) Summary
Metrics recording and endpoint lifecycle
packages/http/..., packages/realtime/..., packages/jobs/..., packages/cli/...
Requests, connections, and queue depth now emit metrics. Each role exposes a dedicated metrics endpoint with configurable port handling and shutdown cleanup.
Metrics validation
packages/*/src/*.test.ts
Tests cover Prometheus output, metric labels, endpoint isolation, queue depth, request failures, and connection replacement or cleanup.
Dashboard theming
packages/admin/src/dev/server.ts
The dashboard derives shell styles from typed UI color tokens for light, dark, and explicit themes.

Release and documentation

Layer / File(s) Summary
GitHub Pages removal
.github/workflows/pages.yml, site/*, tsconfig.json, docs/README.md, llms.txt
The Pages workflow and static site sources are removed. The Wiki becomes the sole public documentation surface.
Release and architecture status
README.md, CLAUDE.md, CHANGELOG.md, docs/idea/*, docs/ops/*
Release status, measured realtime recovery, deployment constraints, cache compatibility, testing behavior, scale guidance, and known gaps are updated for 1.1.0.
Wiki reference
wiki/*.md
CLI, configuration, deployment, observability, theming, realtime, testing, troubleshooting, and known-gap references are expanded or updated.
Tutorials and UI guidance
wiki/Tutorial-*.md, wiki/UI-Components.md, wiki/_Sidebar.md
Six tutorials and a UI components guide are added, with navigation updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant HTTPPipeline
  participant SocketRegistry
  participant JobWorker
  participant MetricsEndpoint
  HTTPPipeline->>MetricsEndpoint: record request metrics
  SocketRegistry->>MetricsEndpoint: record connection gauge
  JobWorker->>MetricsEndpoint: record queue depth
  MetricsEndpoint-->>MetricsEndpoint: serve Prometheus metrics
Loading

Possibly related PRs

Suggested labels: claudetm

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/docs-metrics-tutorials

Comment @coderabbitai help to get the list of available commands.

@sebyx07
sebyx07 merged commit 674fcf6 into main Aug 11, 2026
4 of 5 checks passed
@sebyx07
sebyx07 deleted the feat/docs-metrics-tutorials branch August 11, 2026 17:49
@sebyx07 sebyx07 mentioned this pull request Aug 11, 2026
@coderabbitai coderabbitai Bot added the claudetm Created by Claude Task Master label Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claudetm Created by Claude Task Master

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant