Operations
Two features for background work and operator-controlled feature gates.

Status: ✅ Stable
What: Persistence and operator tooling for jobs registered with
r.job(...). Built on BullMQ + Redis with lane routing (runIn: "api" | "worker"). Every run is written to store_job_runs /
store_job_run_logs.
How it works: r.job(name, { trigger, runIn?, … }, handler)
registers a worker. Handler signature is (payload, context), not
(ctx) alone.
| Trigger | How it fires |
|---|---|
{ manual: true } | jobs:write:trigger (operator / SystemAdmin) or JobRunner.dispatch(name, payload) |
{ cron: "0 9 * * *" } | Leader-elected schedule |
{ on: writeHandlerOrEvent } | After the named write/event |
There is no ctx.jobs.enqueue. Manual runs go through the trigger
write handler or the job runner.
Example:
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";
defineFeature("ops", (r) => { r.job( "cleanup-old-attempts", { trigger: { cron: "0 3 * * *" }, runIn: "worker" }, async (_payload, ctx) => { // use ctx.db / ctx.notify / …, payload first, context second }, );
r.job( "send-incident-email", { trigger: { manual: true } }, async (payload, ctx) => { await ctx.notify!("incident-email", { to: payload["recipientId"] as string, data: { incidentId: payload["incidentId"] }, }); }, );});
// Trigger a manual job (SystemAdmin), not ctx.jobs.enqueueawait ctx.write("jobs:write:trigger", { jobName: "ops:job:send-incident-email", // qualified name as registered payload: { incidentId: id, recipientId },});feature-toggles
Section titled “feature-toggles”Status: ✅ Stable
What: Global (not per-tenant) enable/disable for features that
opt in with r.toggleable({ default }). Operators flip state via
feature-toggles:write:set; the dispatcher gates disabled features
(feature_disabled). State lives in store_global_feature_state.
How it works: Declare r.toggleable({ default: false }) once on
the feature. There is no ctx.toggles, when a feature is off, its
handlers are unreachable and cross-feature hooks owned by that feature
are skipped. Load createFeatureTogglesFeature({ getRuntime }) and wire
GlobalFeatureToggleRuntime into the server’s effectiveFeatures
callback (see the recipe).
Best practice: when a toggle is fully rolled out, delete it from code. In tests set toggle state explicitly.
Recipe: samples/recipes/feature-toggles
Example:
import { defineFeature } from "@cosmicdrift/kumiko-framework/engine";import { z } from "zod";
export const billingFeature = defineFeature("billing", (r) => { r.toggleable({ default: false });
// When "billing" is globally off, this handler never runs : // the dispatcher returns feature_disabled. No ctx.toggles check. r.queryHandler( "invoice-list", z.object({}), async (_query, ctx) => { /* list invoices */ }, { access: { roles: ["Admin"] } }, );});See also
Section titled “See also”- Bundled-features overview
- Audit & security
- Recipe
feature-toggles - Recipe
lane-routing, pin jobs to api/worker