You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The monitoring/alerting service is a test harness (probes, assertions,
alerting), not an operations service. Rename the directory, package
name (@copilotkit/showcase-ops → @copilotkit/showcase-harness), all
internal references (Dockerfile, Prometheus metric prefix
showcase_ops_ → showcase_harness_, orchestrator log messages, probe
YAML nameExcludes, test fixtures), and regenerate pnpm-lock.yaml.
Wire protocol names (X-Ops-* headers) and shell-dashboard internal
API naming (OPS_BASE_URL, ops-api.ts) are intentionally unchanged —
they are stable contracts between sender and receiver.
Copy file name to clipboardExpand all lines: showcase/harness/README.md
+27-27Lines changed: 27 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
# showcase-ops
1
+
# showcase-harness
2
2
3
3
In-cluster observability service for the showcase fleet. Runs on Railway, receives signed webhooks from GitHub Actions, executes cron-driven probes, persists state to PocketBase, classifies state transitions, and delivers alerts to Slack.
4
4
@@ -12,21 +12,21 @@ This section is for everyone who needs to add an alert rule, rotate a secret, or
12
12
13
13
## 1.1 Inspect a running instance
14
14
15
-
Production URL: `https://showcase-ops-production.up.railway.app`
15
+
Production URL: `https://showcase-harness-production.up.railway.app`
16
16
17
17
-**`GET /health`** — JSON: `{status, pb, loop, rules, schedulerJobs}`. `pb:"ok"` means PocketBase reachable; `loop:"ok"` means the scheduler tick has advanced in the last interval; `rules` is the count of successfully compiled YAMLs; `schedulerJobs` is the count of registered cron entries.
-`showcase_ops_rule_reloads` — increments on SIGHUP / file watcher reload
23
-
-`showcase_ops_webhook_rejections{reason=...}` — HMAC and payload-validation failures; `reason` is one of `stale`, `invalid-signature-format`, `invalid-signature`, `missing-signature`, `missing-timestamp`, `invalid-payload`, `unknown`
-`showcase_harness_rule_reloads` — increments on SIGHUP / file watcher reload
23
+
-`showcase_harness_webhook_rejections{reason=...}` — HMAC and payload-validation failures; `reason` is one of `stale`, `invalid-signature-format`, `invalid-signature`, `missing-signature`, `missing-timestamp`, `invalid-payload`, `unknown`
24
24
-**`POST /webhooks/deploy`** — HMAC-signed webhook ingest for `deploy.result` events. Canonical payload: `METHOD|PATH|TS|sha256(body)` with `sha256=<hex>` signature in `X-Ops-Signature`. Path must be the route constant (`/webhooks/deploy`), not `c.req.path`. 300s skew tolerance.
25
-
-**Logs** — `railway logs --service showcase-ops` or the Railway dashboard. All lines are structured JSON: `{level, msg, ts, ...fields}`. Grep targets: `alert-engine.bootstrap-suppress` (gate suppressed a send), `writer.failed` (PB persist failed, always re-emits on bus), `suppress.eval-failed` (a suppress DSL expression threw), `rules.reload.failed` (load-time validation rejected a YAML).
25
+
-**Logs** — `railway logs --service showcase-harness` or the Railway dashboard. All lines are structured JSON: `{level, msg, ts, ...fields}`. Grep targets: `alert-engine.bootstrap-suppress` (gate suppressed a send), `writer.failed` (PB persist failed, always re-emits on bus), `suppress.eval-failed` (a suppress DSL expression threw), `rules.reload.failed` (load-time validation rejected a YAML).
26
26
27
27
## 1.2 Environment variables
28
28
29
-
All read at boot unless marked otherwise. See `showcase/ops/src/orchestrator.ts`.
29
+
All read at boot unless marked otherwise. See `showcase/harness/src/orchestrator.ts`.
30
30
31
31
**Required in production:**
32
32
@@ -35,7 +35,7 @@ All read at boot unless marked otherwise. See `showcase/ops/src/orchestrator.ts`
35
35
|`POCKETBASE_URL`| Internal PB endpoint (`http://showcase-pocketbase.railway.internal:8090`). Boot refuses to start if unset when `NODE_ENV=production`. |
36
36
|`POCKETBASE_SUPERUSER_EMAIL`| Admin auth for ops to write status rows. |
37
37
|`POCKETBASE_SUPERUSER_PASSWORD`| Paired. |
38
-
|`SHARED_SECRET`| Current HMAC secret for `/webhooks/deploy`. 64-hex recommended. Signer side lives in repo secret `SHOWCASE_OPS_SHARED_SECRET`. |
38
+
|`SHARED_SECRET`| Current HMAC secret for `/webhooks/deploy`. 64-hex recommended. Signer side lives in repo secret `SHOWCASE_HARNESS_SHARED_SECRET`.|
39
39
40
40
**Optional:**
41
41
@@ -58,12 +58,12 @@ All read at boot unless marked otherwise. See `showcase/ops/src/orchestrator.ts`
|`SHOWCASE_OPS_URL`|`notify-ops` step in `showcase_deploy.yml`. |
62
-
|`SHOWCASE_OPS_SHARED_SECRET`| Same — paired with the service's `SHARED_SECRET`. |
61
+
|`SHOWCASE_HARNESS_URL`|`notify-harness` step in `showcase_deploy.yml`. |
62
+
|`SHOWCASE_HARNESS_SHARED_SECRET`| Same — paired with the service's `SHARED_SECRET`. |
63
63
64
64
## 1.3 Alert rule YAMLs
65
65
66
-
Location: `showcase/ops/config/alerts/*.yml`. The loader picks up every `.yml`/`.yaml` file except `_defaults.yml`, merges defaults in, compiles each rule through a Zod schema + structural validators, and hot-reloads on file changes (`chokidar`) or SIGHUP.
66
+
Location: `showcase/harness/config/alerts/*.yml`. The loader picks up every `.yml`/`.yaml` file except `_defaults.yml`, merges defaults in, compiles each rule through a Zod schema + structural validators, and hot-reloads on file changes (`chokidar`) or SIGHUP.
67
67
68
68
### File layout
69
69
@@ -189,7 +189,7 @@ Dedupe key is `alpha-sorted([rule.id, key, trigger1, trigger2, ...])` joined by
189
189
190
190
## 1.3a Probe configs
191
191
192
-
Location: `showcase/ops/config/probes/*.yml`. One YAML per probe. Loaded at startup + hot-reloaded via chokidar + SIGHUP, exactly like alert rules (`probes.reloaded` / `probes.reload.failed` emit on the bus on success/error).
192
+
Location: `showcase/harness/config/probes/*.yml`. One YAML per probe. Loaded at startup + hot-reloaded via chokidar + SIGHUP, exactly like alert rules (`probes.reloaded` / `probes.reload.failed` emit on the bus on success/error).
193
193
194
194
A probe config binds a `kind` (driver) to a `schedule` (cron) and a target shape. At each tick the scheduler calls the driver with one input per target; every driver invocation produces one `ProbeResult` which flows through `writer.write()` → `status.changed` → the alert engine. One YAML = one scheduler entry = N target invocations per tick.
195
195
@@ -289,13 +289,13 @@ First resolution per alias per process emits a `slack-webhook.alias-resolved` in
289
289
290
290
## 1.5 Shared-secret rotation
291
291
292
-
See `showcase/ops/docs/rotation-drill.md` for the full runbook. Summary: stage `SHARED_SECRET_PREV` = current, set `SHARED_SECRET` = new, rotate GitHub Actions secret `SHOWCASE_OPS_SHARED_SECRET`, drop `PREV` after one full CI cycle confirms the new key works.
292
+
See `showcase/harness/docs/rotation-drill.md` for the full runbook. Summary: stage `SHARED_SECRET_PREV` = current, set `SHARED_SECRET` = new, rotate GitHub Actions secret `SHOWCASE_HARNESS_SHARED_SECRET`, drop `PREV` after one full CI cycle confirms the new key works.
293
293
294
294
---
295
295
296
296
# Part 2 — Build it, run it, extend it
297
297
298
-
This section is for anyone touching `showcase/ops/src/` or the Dockerfile.
298
+
This section is for anyone touching `showcase/harness/src/` or the Dockerfile.
Railway service/environment IDs above are for the `showcase` project's production environment.
446
446
447
-
There is no CI workflow that auto-builds showcase-ops. Deploys are manual until a build job lands.
447
+
There is no CI workflow that auto-builds showcase-harness. Deploys are manual until a build job lands.
448
448
449
449
## 2.6 Adding things
450
450
@@ -464,20 +464,20 @@ There is no CI workflow that auto-builds showcase-ops. Deploys are manual until
464
464
465
465
-**PocketBase 0.22 auth** — superuser auth uses `/api/admins` (pre-0.23 endpoint); a warn-once log calls this out at boot. Upgrade path: drop the legacy fallback once deployed PB is 0.23+.
466
466
-**No integration tests** — `test/integration/` and `test/e2e/` dirs exist but are empty. Unit coverage is dense (675 tests across 37 files) but no test hits a live PB or posts a real Slack webhook end-to-end.
467
-
-**No auto-build workflow** — push to main does not produce a new `ghcr.io/copilotkit/showcase-ops:latest`; deploys are manual via §2.5.
467
+
-**No auto-build workflow** — push to main does not produce a new `ghcr.io/copilotkit/showcase-harness:latest`; deploys are manual via §2.5.
468
468
-**`/metrics` is unauthenticated** — intentional, gated by Railway private networking. If the service ever moves to a public mesh, add a scraper token.
469
469
-**Bootstrap window is 15m and not env-overridable** — shift requires a code change to `AlertEngineDeps.bootstrapWindowMs`.
470
470
471
471
## 2.8 Related
472
472
473
-
-`.github/workflows/showcase_deploy.yml` — sender side of the `/webhooks/deploy` handshake. `notify-ops` step signs and POSTs.
473
+
-`.github/workflows/showcase_deploy.yml` — sender side of the `/webhooks/deploy` handshake. `notify-harness` step signs and POSTs.
## 2.9 Legacy cron workflows — where their logic lives now
479
479
480
-
The four legacy GitHub Actions cron workflows (`showcase_smoke-monitor`, `showcase_drift-detection`, `showcase_drift-report`, `showcase_redirect-report`) are replaced by in-process probes driven by showcase-ops. Each legacy workflow lane maps to one YAML probe config + one driver in `src/probes/drivers/`:
480
+
The four legacy GitHub Actions cron workflows (`showcase_smoke-monitor`, `showcase_drift-detection`, `showcase_drift-report`, `showcase_redirect-report`) are replaced by in-process probes driven by showcase-harness. Each legacy workflow lane maps to one YAML probe config + one driver in `src/probes/drivers/`:
0 commit comments