Clankers exposes durable background work through the agent process tool. Use it for long-running builds, test suites, servers, and watchers instead of shell-level &, nohup, or disown.
The process tool accepts a backend field on start, list, poll, log, wait, kill, restart, adopt, and gc actions:
| Backend | Use when | Notes |
|---|---|---|
native |
You want the built-in local process registry. | Default backend. Tracks child processes, incremental logs, stdin, completion state, native restart, native GC, and daemon restart reconciliation. |
pueue |
You want queueing/group concurrency through pueue. | Set group and label on starts when useful. Existing pueue tasks can be adopted with pueue_task_id or backend_ref: "pueue:<id>". |
systemd |
You want transient systemd units and host-level resource controls. | Existing units can be adopted with systemd_unit or backend_ref: "systemd:<unit>". NixOS deployments can configure unitPrefix, resource limits, working directory, writable paths, and kill grace. |
Example tool payloads:
{ "action": "start", "backend": "native", "command": "cargo nextest run", "notify_on_complete": true }{ "action": "start", "backend": "pueue", "group": "clankers", "label": "slow-check", "command": "nix flake check" }{ "action": "start", "backend": "systemd", "label": "daemon-smoke", "program": "bash", "args": ["-lc", "./scripts/verify.sh"] }Every backend operation returns a typed receipt shape with operation, id, backend, status, backend_ref, log_refs, and a bounded human summary when those fields apply. Unsupported or unavailable backends fail explicitly instead of silently falling back: for example, a missing pueue binary/daemon or unavailable systemd runner is reported as a backend availability error, while invalid profile/backend policy is reported before backend dispatch.
Native restart stops the current Clankers-owned process group when it is still running, relaunches the original shell/direct-exec start request, preserves the stable Clankers process id, and updates the backend PID reference. Reconciled metadata-only records that no longer have a live process handle still fail closed instead of guessing a restart target.
notify_on_complete: true emits one notification when the job reaches a terminal state. Use this for builds, test suites, deploys, and other finite jobs.
watch_patterns is for rare readiness signals from long-lived jobs, such as Application startup complete. Matches are rate-limited and repeated noisy matches are suppressed. Do not use watch_patterns for end-of-run markers on finite jobs; prefer notify_on_complete.
Completed process/job records and retained logs are garbage-collected by policy. The gc/garbage_collect action accepts optional overrides:
{ "action": "gc", "max_age_days": 14, "max_records": 1000, "max_log_bytes": 1073741824 }List operations also apply the default retention policy before projecting results, so expired terminal records do not remain visible indefinitely. Passing backend: "native" to gc limits explicit cleanup to native process records; active native jobs are skipped and reported in the typed receipt.
The NixOS module enables durable process management under services.clankers-daemon.processManagement:
{
services.clankers-daemon = {
enable = true;
processManagement = {
enable = true;
defaultBackend = "native";
retention = {
maxAgeDays = 14;
maxRecords = 1000;
maxLogBytes = 1073741824;
};
pueue = {
enable = true;
groups.clankers = 4;
};
systemd = {
enable = true;
unitPrefix = "clankers-job";
runtimeMaxSec = 3600;
};
};
};
}The module creates the process-job registry and log directories below the daemon stateDir by default and can manage a dedicated pueue service when the pueue backend is enabled.
The process-job-profile-kit is the copyable brick for backend-neutral process-job manifests. Project-defined profiles parse into backend-neutral StartProcessJobRequest values before any backend dispatch. A profile manifest is versioned with schema_version: 1 and each profile must set exactly one of command or program; args is valid only with program.
Manifest discovery is deterministic and explicit: product shells collect global, workspace, and explicit manifest sources, then ProjectProcessJobProfiles::resolve_from_sources selects the highest-precedence source for the requested profile (explicit > workspace > global). Duplicate profile names at the same precedence fail closed instead of selecting by filesystem order.
Policy controls the default backend, allowed backends, maximum timeout/memory/CPU/log bounds, allowed environment-variable prefixes, allowed working-directory prefixes, and allowed writable-path prefixes. Secret-like environment keys such as APP_TOKEN, APP_SECRET, or APP_KEY fail closed before backend dispatch. Writable paths outside policy fail closed before backend dispatch.
Reusable behavior lives in ProjectProcessJobProfiles, ProjectProcessJobProfileManifestSource, ProjectProcessJobProfilePolicy, ProjectProcessJobProfileValidationError, StartProcessJobRequest, ProcessJobIdentityEnvelope, and ProcessJobRedactionPolicy. Product-owned behavior remains outside the brick: selecting a daemon/session, reading manifest files from disk, spawning native/pueue/systemd jobs, persisting receipts/logs, and notifying users. Resolving a profile is pure: it validates policy and returns a start request plus source/policy evidence, but does not spawn a process, contact pueue/systemd, or write storage.
Safe profile identity metadata is copied into the resolved start request under profile, identity.profile.schema_version, identity.profile.source, and identity.profile.policy. Those keys are eligible for BLAKE3 identity envelopes and receipt/projection surfaces; raw environment values and backend locators are not.
Profile JSON shape:
{
"schema_version": 1,
"profiles": {
"quick-check": {
"backend": "native",
"command": "cargo check --tests",
"cwd": "/home/example/project",
"writable_paths": ["/home/example/project/target"],
"notification_policy": { "notify_on_complete": true },
"metadata": { "purpose": "developer-smoke" }
}
}
}Profiles are pure configuration: resolving them validates policy and produces a start request; it does not spawn a process, contact pueue/systemd, or write storage by itself. The focused drift rail is scripts/check-process-job-profile-kit.rs.