Skip to main content
Wildo.ai Coming soon

Background work

Give a background service a defined reach

Run a separate background service in always-up or scheduled mode, with explicit application-data access and independent platform permissions.

Example minion permissions: read tasks, no writes, and view its own schedule; scheduled triggers reach its separate process.

Give a background service a defined reach

Some background work deserves its own process. A minion runs beside the application with an explicitly declared set of resources it may read or write. Choose an always-up service or work triggered by a schedule.

Platform access is separate: permission to inspect its own schedule does not grant access to application records, or to another minion’s schedule. These declarations make a background service’s intended reach visible before reading its implementation.

Example — Read task information on a schedule without changing it

A reporting minion may read tasks but has no write permission. Its tick can inspect the permitted records and its own recent scheduled runs. Reaching an undeclared resource or attempting a write through the supplied services is refused.

For engineers

This selected entry comes from Wonder Todos’ wildo.saas.config.ts. The key marketingScrapper is the runtime identity used by its initialization; the package path identifies the separate process.

marketingScrapper: {
  path: './minions/marketing-scrapper',
  resourceAccess: {
    read: ['todos'],
    write: [],
  },
  platformAccess: {
    scopes: [MinionPlatformAccessScope.OWN_CRON_RECORDS],
  },
},

Read and write are independent allow-lists. Startup rejects unknown resource identifiers and substitutes a scoped services registry before accepting ticks. Its proxy recognizes allowed service methods and refuses unrecognized access rather than exposing a newly added method by default.

OWN_CRON_RECORDS permits the attested runtime’s own schedule and run history. The platform derives that identity from the attestation; the caller does not supply another minion’s identifier to widen the query.

Choose how the process receives work

ModeSchedule declarationExecution contract
cronRequiredThe platform sends signed ticks to this minion’s dedicated queue. Its registered onTick handler performs the work.
always-upOmittedThe runtime starts without a recurring platform schedule. Mode selection does not itself call onTick or install a repeating work loop.

Both modes bootstrap the headless backend and subscribe to the dedicated tick queue. Under normal operation, an always-up minion receives no scheduler ticks. Its continuously running work needs its own implementation and lifecycle; selecting the mode alone is not an implementation of that work.

The configuration rejects a cron minion without a schedule and an always-up minion with one. The following example uses cron mode.

Give the scheduled process its cadence

The package’s wildo.minion.config.ts declares this selected configuration fragment:

runtime: {
  type: 'docker',
  language: 'typescript',
},
mode: 'cron',
schedule: '0 */6 * * *',
resources: {
  cpu: '500m',
  memory: '512Mi',
},

That describes a six-hour cadence. Config synchronization and generated runtime configuration connect the authored package to deployment. Its entry point loads the application and provider configuration, then initializes through defineMinionInit with the matching runtime key and handler. A package declaration alone is not a running subscriber.

Use the scoped doors handed to the tick

This is a selected, shortened portion of the application’s actual handler in minion-init.ts. The full file builds and projects the backend initialization graph before passing this handler to defineMinionInit; its logging is omitted here.

onTick: async (token, { systemAccess, minionName, ownSchedule }) => {
  const todos = await systemAccess.listAsSystem<{ _id: string }>(
    TasksManager_ResourceType.TODOS,
    {},
  );

  const ownJobs = await ownSchedule.read();
},

The first call crosses organization boundaries only through the system-access contract. It still needs the minion’s resource allow-list and the target resource’s declared system-read policy. The MINION runtime profile also requires accountable access: inability to record the required system-access audit causes refusal. An allow-list is therefore one layer, not blanket database authority.

The second call exercises the independent platform permission. Removing OWN_CRON_RECORDS can leave the task read permitted while refusing the schedule read. That difference is useful when a process needs business data but no control-plane visibility.

Plan for delayed and overlapping ticks

BoundaryRuntime behaviorApplication responsibility
Queue setupThis minion declares its dedicated queue; the scheduler checks it exists before publishingRestore the runtime and its broker access when the queue is absent
Token freshnessSigned ticks have a five-minute lifetime, with the verifier’s clock tolerance; expired instructions are refusedRequest fresh work after recovery rather than replaying an expired token
Handler completionSuccess acknowledges the tick; verification or handler failure rejects it without requeueInspect the business effect and explicitly recover incomplete work
OverlapThe consumer awaits each handler but does not supply a per-business-operation lockCoordinate competing work and make repeatable effects safe

reinstantiation.policy governs replacement during deployment. In Kubernetes, kill_previous selects Recreate and let_run selects RollingUpdate; neither is a per-tick mutex or a promise to cancel a previous handler. The minion handler owns overlap and backpressure.

A later cron occurrence carries a fresh signed tick. It does not replay every missed occurrence or prove that an earlier partial effect was repaired. The explicit no-requeue failure rule also does not exclude redelivery after a broker or connection interruption. Use the resulting records or artifacts to decide what needs recovery before triggering work again.

Keep the execution lane distinct

The minion starts the backend lifecycle headlessly and subscribes to its own tick queue. Incoming scheduler tokens must identify this minion. It deliberately does not consume the application’s shared job queues, so adding a minion does not add queue-worker capacity.

The provided registry and system-access doors enforce the declared reach. They are not an operating-system sandbox for arbitrary code, independent database clients or external network calls. Keep the handler on the supplied access paths and grant only the resources and platform capability its job needs.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.