Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Preparing Ring Platform content
Preparing Ring Platform content
Preparing Ring Platform content
Use the Founder / Developer tabs in the docs sidebar to filter this page for your role. audience frontmatter controls content filtering within the page. Sidebar article visibility is controlled separately by lib/docs/audience-curated-docs.ts.
Vercel is a first-class Ring deploy target — equal in the backend matrix to Firebase Hosting / Cloud Run and k3s. The app runs as Next.js serverless route handlers (no custom server.ts). Platform Cron reads root vercel.json and invokes each ProcessConductor path on a UTC schedule.
| Concern | Vercel truth |
|---|---|
| Deploy flags | RING_DEPLOY_TARGET=vercel, NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel |
| Runtime | Serverless only — no custom Node server.ts |
| Tunnel | SSE + long-polling (no native WSS) |
| Cron catalog | vercel.json → crons[] — must list every ProcessConductor cronPath |
| Auth gate | Authorization: Bearer $CRON_SECRET on /api/cron/* |
ProcessConductor runs 19 background pipelines (email poll, cleanups, settlements, membership expiry, peer-game session expiry, Forgejo lab GC, and more). On Vercel, Platform Cron hits the same HTTP routes your Admin → Background Processes panel records. If CRON_SECRET is missing or crons[] is incomplete, those jobs silently never run.
CRON_SECRET.RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel.vercel.json crons[] lists every ProcessConductor path (schedule SSOT for all backends).Hosting on Firebase instead? Same cron URLs and schedules — trigger with Google Cloud Scheduler, using vercel.json as the catalog. See Firebase Integration.
Same-workflow: Firebase-hosted rings use Cloud Scheduler + this vercel.json catalog (firebase.json is not cron).
Depends-on: CRON_SECRET, RING_DEPLOY_TARGET, and backend secrets.
Next-step: Admin → Background Processes for recorded pipeline runs.
Same-workflow: email-processor and email-analytics cron pipelines.
Use the Founder / Developer tabs in the docs sidebar to filter this page for your role. audience frontmatter controls content filtering within the page. Sidebar article visibility is controlled separately by lib/docs/audience-curated-docs.ts.
Vercel is a first-class Ring deploy target — equal in the backend matrix to Firebase Hosting / Cloud Run and k3s. The app runs as Next.js serverless route handlers (no custom server.ts). Platform Cron reads root vercel.json and invokes each ProcessConductor path on a UTC schedule.
| Concern | Vercel truth |
|---|---|
| Deploy flags | RING_DEPLOY_TARGET=vercel, NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel |
| Runtime | Serverless only — no custom Node server.ts |
| Tunnel | SSE + long-polling (no native WSS) |
| Cron catalog | vercel.json → crons[] — must list every ProcessConductor cronPath |
| Auth gate | Authorization: Bearer $CRON_SECRET on /api/cron/* |
ProcessConductor runs 19 background pipelines (email poll, cleanups, settlements, membership expiry, peer-game session expiry, Forgejo lab GC, and more). On Vercel, Platform Cron hits the same HTTP routes your Admin → Background Processes panel records. If CRON_SECRET is missing or crons[] is incomplete, those jobs silently never run.
CRON_SECRET.RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel.vercel.json crons[] lists every ProcessConductor path (schedule SSOT for all backends).Hosting on Firebase instead? Same cron URLs and schedules — trigger with Google Cloud Scheduler, using vercel.json as the catalog. See Firebase Integration.
Same-workflow: Firebase-hosted rings use Cloud Scheduler + this vercel.json catalog (firebase.json is not cron).
Depends-on: CRON_SECRET, RING_DEPLOY_TARGET, and backend secrets.
Next-step: Admin → Background Processes for recorded pipeline runs.
Same-workflow: email-processor and email-analytics cron pipelines.
Use the Founder / Developer tabs in the docs sidebar to filter this page for your role. audience frontmatter controls content filtering within the page. Sidebar article visibility is controlled separately by lib/docs/audience-curated-docs.ts.
Vercel is a first-class Ring deploy target — equal in the backend matrix to Firebase Hosting / Cloud Run and k3s. The app runs as Next.js serverless route handlers (no custom server.ts). Platform Cron reads root vercel.json and invokes each ProcessConductor path on a UTC schedule.
| Concern | Vercel truth |
|---|---|
| Deploy flags | RING_DEPLOY_TARGET=vercel, NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel |
| Runtime | Serverless only — no custom Node server.ts |
| Tunnel | SSE + long-polling (no native WSS) |
| Cron catalog | vercel.json → crons[] — must list every ProcessConductor cronPath |
| Auth gate | Authorization: Bearer $CRON_SECRET on /api/cron/* |
ProcessConductor runs 19 background pipelines (email poll, cleanups, settlements, membership expiry, peer-game session expiry, Forgejo lab GC, and more). On Vercel, Platform Cron hits the same HTTP routes your Admin → Background Processes panel records. If CRON_SECRET is missing or crons[] is incomplete, those jobs silently never run.
CRON_SECRET.RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel.vercel.json crons[] lists every ProcessConductor path (schedule SSOT for all backends).Hosting on Firebase instead? Same cron URLs and schedules — trigger with Google Cloud Scheduler, using vercel.json as the catalog. See Firebase Integration.
Same-workflow: Firebase-hosted rings use Cloud Scheduler + this vercel.json catalog (firebase.json is not cron).
Depends-on: CRON_SECRET, RING_DEPLOY_TARGET, and backend secrets.
Next-step: Admin → Background Processes for recorded pipeline runs.
Same-workflow: email-processor and email-analytics cron pipelines.
| HTTP routes |
app/api/cron/<name>/route.ts — GET/POST |
| Schedule catalog | ring-platform.org/vercel.json → crons[] (UTC) |
| Ledger | ProcessConductor.recordRun |
| Admin copy | locales/*/modules/admin.json → processes.pipelines.* |
| Ops write-up | AI-RING/scripts/PIPELINES.md § ProcessConductor cron pipelines |
Parity rule: vercel.json must list every ProcessConductor cronPath. Firebase-hosted rings reuse this file as the schedule catalog for Cloud Scheduler. k3s uses per-job YAML under k8s/ (e.g. cronjob-email-processor.yaml) curling an in-cluster URL — not a single inventory file.
| Pipeline ID | cronPath | schedule |
|---|---|---|
| email-processor | /api/cron/email-processor | */5 * * * * |
| email-analytics | /api/cron/email-analytics | 0 6 * * * |
| refcodes-mint | /api/cron/refcodes-mint | */30 * * * * |
| cleanup-reservations | /api/cron/cleanup-reservations | */15 * * * * |
| cleanup-usernames | /api/cron/cleanup-usernames | */5 * * * * |
| cleanup-news-deleted | /api/cron/cleanup-news-deleted | 0 3 * * 0 |
| cleanup-email-tokens | /api/cron/cleanup-email-tokens | 0 */6 * * * |
| train | /api/cron/train | 0 2 * * * |
| settlement-payout | /api/cron/settlement-payout | 0 1 * * * |
| inventory-drift | /api/cron/inventory-drift | 0 */6 * * * |
| subscription-expiry-check | /api/cron/subscription-expiry | 0 0 * * * |
| credit-balance-monthly | /api/cron/credit-balance-monthly | 0 * * * * |
| subscription-payment | /api/cron/subscription-payment | 0 2 * * * |
| solana-batch-payment | /api/cron/solana-batch-payment | 0 3 * * * |
| nft-gate-expiry | /api/cron/nft-gate-expiry | 0 4 * * * |
| close-expired-polls | /api/cron/close-expired-polls | */5 * * * * |
| peer-game-session-expiry | /api/cron/peer-game-session-expiry | */5 * * * * |
| forgejo-robot-gc | /api/cron/forgejo-robot-gc | 0 4 * * 0 |
| forgejo-token-rotate | /api/cron/forgejo-token-rotate | 0 5 1 * * |
Example vercel.json shape (every ProcessConductor path must appear):
Fail-closed: missing/wrong bearer → 401.
lib/processes/registry.ts (PIPELINE_IDS + PIPELINE_REGISTRY with cronPath).app/api/cron/<name>/route.ts (Bearer gate + ProcessConductor.recordRun).locales/*/modules/admin.json → processes.pipelines.*.{ path, schedule } to vercel.json crons[].k8s/cronjob-<name>.yaml for cluster deploys.Ops notes: forgejo-robot-gc supports ?dryRun=1; forgejo-token-rotate uses FORGEJO_TOKEN_ROTATE_MAX_AGE_DAYS / FORGEJO_TOKEN_ROTATE_LIMIT.
See-also: k3s path with native WSS and per-job CronJob YAML.
RING_DEPLOY_TARGET=vercel
NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel
CRON_SECRET=generate-a-long-random-string
{
"crons": [
{ "path": "/api/cron/email-processor", "schedule": "*/5 * * * *" },
{ "path": "/api/cron/forgejo-robot-gc", "schedule": "0 4 * * 0" }
]
}
curl -sS -H "Authorization: Bearer $CRON_SECRET" \
"https://<your-deployment>/api/cron/email-processor"| HTTP routes |
app/api/cron/<name>/route.ts — GET/POST |
| Schedule catalog | ring-platform.org/vercel.json → crons[] (UTC) |
| Ledger | ProcessConductor.recordRun |
| Admin copy | locales/*/modules/admin.json → processes.pipelines.* |
| Ops write-up | AI-RING/scripts/PIPELINES.md § ProcessConductor cron pipelines |
Parity rule: vercel.json must list every ProcessConductor cronPath. Firebase-hosted rings reuse this file as the schedule catalog for Cloud Scheduler. k3s uses per-job YAML under k8s/ (e.g. cronjob-email-processor.yaml) curling an in-cluster URL — not a single inventory file.
| Pipeline ID | cronPath | schedule |
|---|---|---|
| email-processor | /api/cron/email-processor | */5 * * * * |
| email-analytics | /api/cron/email-analytics | 0 6 * * * |
| refcodes-mint | /api/cron/refcodes-mint | */30 * * * * |
| cleanup-reservations | /api/cron/cleanup-reservations | */15 * * * * |
| cleanup-usernames | /api/cron/cleanup-usernames | */5 * * * * |
| cleanup-news-deleted | /api/cron/cleanup-news-deleted | 0 3 * * 0 |
| cleanup-email-tokens | /api/cron/cleanup-email-tokens | 0 */6 * * * |
| train | /api/cron/train | 0 2 * * * |
| settlement-payout | /api/cron/settlement-payout | 0 1 * * * |
| inventory-drift | /api/cron/inventory-drift | 0 */6 * * * |
| subscription-expiry-check | /api/cron/subscription-expiry | 0 0 * * * |
| credit-balance-monthly | /api/cron/credit-balance-monthly | 0 * * * * |
| subscription-payment | /api/cron/subscription-payment | 0 2 * * * |
| solana-batch-payment | /api/cron/solana-batch-payment | 0 3 * * * |
| nft-gate-expiry | /api/cron/nft-gate-expiry | 0 4 * * * |
| close-expired-polls | /api/cron/close-expired-polls | */5 * * * * |
| peer-game-session-expiry | /api/cron/peer-game-session-expiry | */5 * * * * |
| forgejo-robot-gc | /api/cron/forgejo-robot-gc | 0 4 * * 0 |
| forgejo-token-rotate | /api/cron/forgejo-token-rotate | 0 5 1 * * |
Example vercel.json shape (every ProcessConductor path must appear):
Fail-closed: missing/wrong bearer → 401.
lib/processes/registry.ts (PIPELINE_IDS + PIPELINE_REGISTRY with cronPath).app/api/cron/<name>/route.ts (Bearer gate + ProcessConductor.recordRun).locales/*/modules/admin.json → processes.pipelines.*.{ path, schedule } to vercel.json crons[].k8s/cronjob-<name>.yaml for cluster deploys.Ops notes: forgejo-robot-gc supports ?dryRun=1; forgejo-token-rotate uses FORGEJO_TOKEN_ROTATE_MAX_AGE_DAYS / FORGEJO_TOKEN_ROTATE_LIMIT.
See-also: k3s path with native WSS and per-job CronJob YAML.
RING_DEPLOY_TARGET=vercel
NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel
CRON_SECRET=generate-a-long-random-string
{
"crons": [
{ "path": "/api/cron/email-processor", "schedule": "*/5 * * * *" },
{ "path": "/api/cron/forgejo-robot-gc", "schedule": "0 4 * * 0" }
]
}
curl -sS -H "Authorization: Bearer $CRON_SECRET" \
"https://<your-deployment>/api/cron/email-processor"| HTTP routes |
app/api/cron/<name>/route.ts — GET/POST |
| Schedule catalog | ring-platform.org/vercel.json → crons[] (UTC) |
| Ledger | ProcessConductor.recordRun |
| Admin copy | locales/*/modules/admin.json → processes.pipelines.* |
| Ops write-up | AI-RING/scripts/PIPELINES.md § ProcessConductor cron pipelines |
Parity rule: vercel.json must list every ProcessConductor cronPath. Firebase-hosted rings reuse this file as the schedule catalog for Cloud Scheduler. k3s uses per-job YAML under k8s/ (e.g. cronjob-email-processor.yaml) curling an in-cluster URL — not a single inventory file.
| Pipeline ID | cronPath | schedule |
|---|---|---|
| email-processor | /api/cron/email-processor | */5 * * * * |
| email-analytics | /api/cron/email-analytics | 0 6 * * * |
| refcodes-mint | /api/cron/refcodes-mint | */30 * * * * |
| cleanup-reservations | /api/cron/cleanup-reservations | */15 * * * * |
| cleanup-usernames | /api/cron/cleanup-usernames | */5 * * * * |
| cleanup-news-deleted | /api/cron/cleanup-news-deleted | 0 3 * * 0 |
| cleanup-email-tokens | /api/cron/cleanup-email-tokens | 0 */6 * * * |
| train | /api/cron/train | 0 2 * * * |
| settlement-payout | /api/cron/settlement-payout | 0 1 * * * |
| inventory-drift | /api/cron/inventory-drift | 0 */6 * * * |
| subscription-expiry-check | /api/cron/subscription-expiry | 0 0 * * * |
| credit-balance-monthly | /api/cron/credit-balance-monthly | 0 * * * * |
| subscription-payment | /api/cron/subscription-payment | 0 2 * * * |
| solana-batch-payment | /api/cron/solana-batch-payment | 0 3 * * * |
| nft-gate-expiry | /api/cron/nft-gate-expiry | 0 4 * * * |
| close-expired-polls | /api/cron/close-expired-polls | */5 * * * * |
| peer-game-session-expiry | /api/cron/peer-game-session-expiry | */5 * * * * |
| forgejo-robot-gc | /api/cron/forgejo-robot-gc | 0 4 * * 0 |
| forgejo-token-rotate | /api/cron/forgejo-token-rotate | 0 5 1 * * |
Example vercel.json shape (every ProcessConductor path must appear):
Fail-closed: missing/wrong bearer → 401.
lib/processes/registry.ts (PIPELINE_IDS + PIPELINE_REGISTRY with cronPath).app/api/cron/<name>/route.ts (Bearer gate + ProcessConductor.recordRun).locales/*/modules/admin.json → processes.pipelines.*.{ path, schedule } to vercel.json crons[].k8s/cronjob-<name>.yaml for cluster deploys.Ops notes: forgejo-robot-gc supports ?dryRun=1; forgejo-token-rotate uses FORGEJO_TOKEN_ROTATE_MAX_AGE_DAYS / FORGEJO_TOKEN_ROTATE_LIMIT.
See-also: k3s path with native WSS and per-job CronJob YAML.
RING_DEPLOY_TARGET=vercel
NEXT_PUBLIC_RING_DEPLOY_TARGET=vercel
CRON_SECRET=generate-a-long-random-string
{
"crons": [
{ "path": "/api/cron/email-processor", "schedule": "*/5 * * * *" },
{ "path": "/api/cron/forgejo-robot-gc", "schedule": "0 4 * * 0" }
]
}
curl -sS -H "Authorization: Bearer $CRON_SECRET" \
"https://<your-deployment>/api/cron/email-processor"