Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SelfServe
Decide whether self-service tenant provisioning is safe to run, and whether the job queue running it is healthy.
SelfServe does not provision anything. It is the gate around a provisioning
worker you already have, for example one that claims jobs with
FOR UPDATE SKIP LOCKED, renders a per-tenant stack, starts it and wires
DNS. Reimplementing that worker would be duplication. The missing half is the
part that decides whether to let it run, which is the part that keeps
self-service from turning into an outage.
It is pure, with no clock and no I/O. now is a parameter.
What it checks and why
- Dormant is not proven. Built, enabled and proven in production are three separate states. A worker that is switched off is NOT ASSESSED, never ready, and an enabled worker that has never completed a real tenant gets its own finding. Until one tenant has gone end to end, the first customer is the integration test.
- Self-service with no ceiling is a denial of service you run against
yourself. If every tenant is a stack on one host, a signup loop with no
quota fills that host, and a full disk on a shared host wedges every
container, not only the new one. Declaring no limits at all is a critical
failure: a quota that was never set was never considered.
preflight()also checks the host ceiling, the per-account ceiling and the free disk left after provisioning. Unmeasured disk, or a stack with no size estimate, is NOT ASSESSED. - A claimed job looks like progress. With
SKIP LOCKEDclaiming, a worker that dies mid-job leaves the job claimed forever. It is not queued, not failed, and nothing retries it, so no dashboard alarms on it.stuckJobs()finds jobs claimed for longer than a window (15 minutes by default). - Provisioned is not reachable. DNS wired and the stack up is not the same as the tenant's URL serving. Without a post-provision probe, the first person to discover a broken tenant is the tenant.
Usage
import { assessService, formatService, preflight, stuckJobs, type Job } from '@extant2000/self-serve'
const jobs: Job[] = [
{ id: 'j7', state: 'claimed', claimedAt: '2026-09-28T11:00:00Z', claimedBy: 'worker-1', where: 'jobs table' },
{ id: 'j8', state: 'queued', where: 'jobs table' },
]
const report = assessService(
{ workerEnabled: true, provenInProduction: false, verifiesReachability: true },
{
now: '2026-09-28T12:00:00Z',
request: { account: 'acme', tenantName: 'acme-prod', existingForAccount: 1, estimatedDiskBytes: 2e9, where: 'jobs table, j8' },
host: { tenants: 10, freeDiskBytes: null, where: 'df -P /data' },
limits: { maxTenants: 50, maxPerAccount: 3, minFreeDiskBytes: 10e9 },
jobs,
},
)
for (const f of report.findings) console.log(`${f.determination.padEnd(13)} ${f.id}: ${f.summary}`)
assessService() returns a CapabilityReport from
@extant2000/evidence-record, and formatService() renders it for a
terminal or CI log. preflight() and stuckJobs() can be used on their own.
Sample output
Produced by running the example above:
not-assessed worker/unproven: The worker is enabled but has never completed a real tenant
not-assessed capacity/disk: Disk headroom after provisioning cannot be computed
fail job/j7: job j7 has been claimed by worker-1 since 2026-09-28T11:00:00Z
Install
npm install @extant2000/self-serve
License
MIT. Copyright (c) 2026 Extant 2000 LLC. See LICENSE.