This repository was archived by the owner on Jun 22, 2026. It is now read-only.
v2.27.0: admin — central cron-health dashboard (live Cloud Scheduler per tenant) - #157
Open
MyAlterLego wants to merge 4 commits into
Open
v2.27.0: admin — central cron-health dashboard (live Cloud Scheduler per tenant)#157MyAlterLego wants to merge 4 commits into
MyAlterLego wants to merge 4 commits into
Conversation
…per tenant) Queries Google Cloud Scheduler directly per tenant GCP project and diffs the actual jobs against a canonical expected-cron suite, so it catches missing or disabled crons even when nothing is running (RC + Eve are dark today). Per-tenant error isolation; distinct "scheduler not enabled / no access" state. Staff-gated page, fail-open per-project queries. Registers the Cron Health admin module. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…oard # Conflicts: # src/app/admin/page.tsx
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
What
A central Cron Health dashboard on platform admin (
/admin/modules/cron-health) so Triarch can see, per tenant, whether each project's scheduled jobs are registered, enabled, and succeeding.The platform queries Google Cloud Scheduler directly per tenant project via the list API and diffs the actual jobs against a canonical expected-cron suite. This catches missing / disabled crons even when nothing is running, which is the exact gap today: Revolution Cyber and Eve currently have zero scheduler jobs and will light up red.
How it authenticates (ADC note)
The task spec called for Application Default Credentials. This repo does not depend on
google-auth-library/googleapis; the established pattern for calling Google REST APIs here ismintFahAccessToken()insrc/lib/fah-rollout.ts— it signs an RS256 JWT with the platform service-account key (from the secrets vault:FAH_PROMOTER_SA_KEY), exchanges it atoauth2.googleapis.com/tokenfor acloud-platform-scoped access token, and caches it 50 min. I reused that helper rather than introducing a new auth dependency.cloud-platformscope covers Cloud Scheduler. (Deviation from "ADC" is documented below.)Reader calls, per tenant:
GET https://cloudscheduler.googleapis.com/v1/projects/{project}/locations/{location}/jobswithAuthorization: Bearer <token>.Files
src/lib/cron-health/tenants.ts— tenant registry +EXPECTED_CRON_JOBSsuitesrc/lib/cron-health/diff.ts— pure expected-vs-actual diff (no I/O)src/lib/cron-health/diff.test.ts— 16 unit tests for the diff logicsrc/lib/cron-health/reader.ts— per-tenant Cloud Scheduler reader, error-isolatedsrc/app/admin/modules/cron-health/page.tsx— staff-gated dashboardsrc/app/admin/page.tsx— registers the Cron Health module in the admin gridTenant registry (extend in
tenants.ts)triarchsecurity-atlasrevolutioncyber-triarchcrmevesecurity-triarchcrmExpected cron suite
connector-sync,event-dispatcher,workflow-dispatcher,workflow-enroll,workflow-tick,workflow-enrich,embedding-refresh,pipeline-snapshot,invoice-overdue-sweep,retention-purge,foundry-ledger-scan,llm-usage-report.Matched loosely by job-name suffix: an expected key matches an actual scheduler job id if the id equals the key or ends with
-<key>(case-insensitive). Soconnector-sync,triarch-connector-sync, andatlas-prod-connector-syncall matchconnector-sync.Diff / health logic
Per expected job → a status row:
status.codenon-zeroTenant rolls up to red if any missing/failing, amber if any paused/stale, else green. The top summary flags tenants with dark crons.
Distinct per-tenant "scheduler not enabled / no access" state: a
403/404from the list API is rendered as a dedicated red banner (this is the RC/Eve signal today), separate from an unexpected query error. Per-tenant isolation: one project failing never breaks the page (auth fail-closed, per-project queries fail-open).Operator steps (required before data shows for a tenant)
For each tenant project (
triarchsecurity-atlas,revolutioncyber-triarchcrm,evesecurity-triarchcrm):gcloud services enable cloudscheduler.googleapis.com --project <PROJECT>roles/cloudscheduler.viewer(or a custom role withcloudscheduler.jobs.list/.get) on the project:gcloud projects add-iam-policy-binding <PROJECT> --member="serviceAccount:<PLATFORM_RUNTIME_SA>" --role="roles/cloudscheduler.viewer"The
<PLATFORM_RUNTIME_SA>is the identity behindFAH_PROMOTER_SA_KEY(the SA used by the existing FAH rollout client). Until both are done, the tenant section shows the "scheduler not enabled / no access" state — which is itself useful signal.Verification
tsc --noEmit: zero new errors in changed files (6 pre-existing errors remain inpackages/triarch-shared/src/internal-hmac.test.ts, unrelated).vitest run src/lib/cron-health/diff.test.ts: 16/16 pass (missing detection, loose matching, all health classifications, extra-job surfacing).next build: compiled successfully;/admin/modules/cron-healthbuilds as a dynamic route.Deviations
mintFahAccessToken()(SA key from vault,cloud-platformscope) instead ofgoogle-auth-libraryADC, to match conventions and avoid a new dependency. Functionally equivalent for reaching the Scheduler API.llm-usagedashboard referenced as a look model is on an unmerged sibling branch and is not ondev, so I mirroredci-cd/page.tsx(same zinc/amber design language) instead.Do not merge/deploy — operator IAM + API-enable steps land first.
🤖 Generated with Claude Code