Use the scheduler and maintenance jobs
The scheduler is the background organism: a daemon plus scheduler_job objects. It is useful for every project that wants the kernel to keep running after the shell closes. It is not a source-code linter. Lint, policy, and integrity timers are an optional source-code pack you turn on only when this checkout has code you intend to gate.
Daily commands
./bin/zqk scheduler start
./bin/zqk scheduler status
./bin/zqk scheduler list
./bin/zqk scheduler history --job-id SCH-retention-tolerance
./bin/zqk scheduler trigger SCH-retention-tolerance
./bin/zqk scheduler issues
One-shot work (tests, a long command, anything you should not block a chat on):
./bin/zqk scheduler submit "./bin/zqk system check" --title "kernel check" --max-runtime 600
./bin/zqk test run --all
CRUD, object list, and whats-next work without the daemon. Start it when you want timers, retention, and one-shots to keep running.
Ensure the kernel survival jobs exist (idempotent):
./bin/zqk system ensure-retention-jobs
init --with-maintenance-jobs is the same ensure step at first-run.
Two layers (do not mix them)
| Layer | Purpose | Who needs it |
|---|---|---|
| Kernel survival | Keep CAS, caches, retention, and object validation healthy | Every project that runs the daemon |
| Source-code pack | Lint, logging/policy, kernel-integrity timers that feed git hooks | Checkouts that contain product source you gate before commit |
| One-shots | submit you ask for |
Anyone with a long command |
A knowledge-only or orchestration project (backlog, Gantt, feed, no product tree) should run kernel survival and skip the source-code pack. Shipping those timers as required is how you get exit 126 on missing scripts/pre-commit-*.sh.
The list of jobs ensure-retention-jobs will mint lives in .zqk/specs/configs/scheduler_maintenance_config.yaml (required_jobs). That file is the contract. Templates live under scripts/scheduler_jobs/.
Kernel survival (required on this SKU)
Read title, not the opaque id. scheduler list shows both. The id is a handle for trigger / history; the title is what the job does.
| Id (today) | Title | What it is for |
|---|---|---|
SCH-val |
Background Object Validations | Re-check objects after create/update/delete |
SCH-evag |
Scheduler Events Aggregation | Roll diagnostics into a metrics summary |
SCH-cache-prewarm |
(template title) | Warm kernel caches so first reads are not cold |
SCH-retention-tolerance |
Retention catch-all | Enforce retention policy across kinds |
SCH-audit-event-aggregation |
Audit aggregation | Compact audit events |
SCH-scheduler-job-retention |
Scheduler job retention | Reap completed one-shot SCH-* rows |
SCH-cleanup |
Cleanup | On-demand filesystem / lock hygiene |
SCH-maintenance-wal |
WAL maintenance | Storage write-ahead maintenance |
SCH-objcount-report |
Object-count report | Hourly count snapshot |
SCH-autofix-batch-cleanup |
Autofix batch cleanup | Drop processed autofix batches |
SCH-passive-test-sweeper |
Passive test sweeper | Idle test-bundle hygiene |
SCH-cap-orchestrator |
CAP orchestrator | Continuous agent loop tick (when CAP is in use) |
If a custom job's command or script is not present on your system, park it or disable it rather than leaving an erroring timer:
# Preferred: park the job so it is safely deferred
./bin/zqk object park SCH-that-job --to deferred
# Alternative: disable execution flag directly
./bin/zqk object update SCH-that-job --field "enabled=false"
Source-Code Verification Jobs (Optional Pack)
These scheduled jobs are optional and provide automated test and lint checks. They cache output under .zqk/pre-commit/ for fast evaluation during commit hooks:
| Id | What you think it is | What it actually is |
|---|---|---|
SCH-pre-commit-lint |
βRequired maintenanceβ | Timer: scripts/pre-commit-lint.sh (golangci-lint / go vet) |
SCH-pre-commit-policy |
βRequired maintenanceβ | Timer: logging + architecture policy scripts |
SCH-pre-commit-integrity |
βRequired maintenanceβ | Timer: system check snapshot for the hook |
Turn them on only if (1) this project has source you gate, and (2) the matching scripts exist and are executable.
test -x scripts/pre-commit-lint.sh && \
./bin/zqk object create scheduler_job --file scripts/scheduler_jobs/pre_commit_lint.yaml --keep-file --force
test -x scripts/pre-commit-policy.sh && \
./bin/zqk object create scheduler_job --file scripts/scheduler_jobs/pre_commit_policy.yaml --keep-file --force
test -x scripts/pre-commit-integrity.sh && \
./bin/zqk object create scheduler_job --file scripts/scheduler_jobs/pre_commit_integrity.yaml --keep-file --force
./bin/zqk object update SCH-pre-commit-lint --field "enabled=true"
Force a hook-shaped run (writes the pre-commit aggregate the git hook reads):
./bin/zqk scheduler trigger SCH-pre-commit-lint --pre-commit
Leave them off for non-code orchestrations, knowledge-only kernels, and this Community SKU until you add those scripts. Missing scripts are not a configuration mystery β the job was never meant for that project shape.
If you need a one-off check without a timer:
./bin/zqk scheduler submit "./bin/zqk system check" --title "integrity once" --max-runtime 600
That is the orchestration-friendly substitute for SCH-pre-commit-integrity.
Job Naming Conventions
Scheduled jobs follow clear naming patterns:
- Format:
SCH-<scope>-<noun>using lowercase kebab-case (e.g.,SCH-retention-tolerance,SCH-cache-prewarm,SCH-audit-event-aggregation). - Scope:
kernel: Core system maintenance, retention, and storage hygiene.source: Codebase verification, automated testing, or linting.-
Title: Human-readable summary displayed in
zqk scheduler list. -
Examples:
SCH-retention-tolerance,SCH-cache-prewarm,SCH-audit-event-aggregation.
Job Layers and Categories
- Does the command path live under
scripts/pre-commit-*.shor a language linter? β source pack. - Does it mention retention, WAL, cache, object validation, audit aggregation? β kernel survival.
- Did you type
scheduler submitthis session? β one-shot; it will get its ownSCH-*and should be reaped by job-retention.
zqk scheduler issues is the inbox for failed timers. Clear it after you have fixed or disabled the job, not to hide a missing script.
Logs
Per-job output: .zqk/logs/scheduler/jobs/<JOB-ID>/. Daemon events: .zqk/logs/scheduler/log-events.json.
See also
- Templates:
scripts/scheduler_jobs/README.md - Contract:
.zqk/specs/configs/scheduler_maintenance_config.yaml - First-run daemon: Community first-run