T1: systemd --user units (ops-warden-worker.{service,timer}) + scripts/install-worker-timer.sh
(--enable opt-in, cron fallback documented) + examples/worker.env.example. Kill switch:
`systemctl --user disable --now ops-warden-worker.timer` or WORKER_ENABLED=0. Installed and
ENABLED — verified a real systemd run (Result=success, used the llm brain) and the timer is
active (next run +15min).
T2: hardened worker-tick.sh — State Hub /state/health precheck → graceful skip (exit 0) when
unreachable; worker-run failure logged but never fails the unit (retry next tick). Verified
hub-down skip and a live tick.
Conservative tier only; nothing auto-sent. Kill switch is one command.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.4 KiB
id, type, title, domain, repo, status, owner, topic_slug, planning_priority, planning_order, created, updated, state_hub_workstream_id
| id | type | title | domain | repo | status | owner | topic_slug | planning_priority | planning_order | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| WARDEN-WP-0021 | workplan | Enable the scheduled worker tick — conservative inbox triage, unattended | infotech | ops-warden | active | claude | custodian | high | 21 | 2026-06-30 | 2026-06-30 | 8c487014-b630-4016-a4f0-31b971a473d2 |
WARDEN-WP-0021 — Enable the scheduled worker tick
Goal: turn the WP-0020 conservative worker from built-but-disabled into a reliable, unattended schedule — so ops-warden's State Hub inbox is auto-triaged into a digest of drafted replies the operator reviews and approves, without anyone starting a session. This is the payoff of WP-0020: it ends the cross-session relay toil.
Posture (unchanged): schedule the conservative tier only — triage + draft, never
auto-send (Option A / build-stage decision 813899f9). The four guardrails hold. Easy
kill switch is a requirement, not an afterthought (recoverability).
What "enabled" means here: (1) the tick runs on a schedule and survives the failure modes (hub/llm-connect down → graceful degrade), (2) the operator actually sees new drafts, (3) the operator can act on a draft with one command, (4) it's trivial to stop.
Out of scope: the full-auto (auto-send) path; flipping policy.enabled; moving the
worker off the workstation.
Depends on / relates to: WP-0020 (the worker + scripts/worker-tick.sh); the State
Hub migration to railiance01 (cust-wp-0011/0038) may change WARDEN_HUB_URL later —
the tick already honors that env var.
Decisions to settle (first)
- Scheduler:
systemd --usertimer (recommended — clean logs viajournalctl,systemctl --user status, built-in scheduling) vs. plain cron (simplest) vs. activity-core (ecosystem-native durable trigger; heavier for build stage). Recommend the systemd user timer; cron documented as the one-liner fallback. - Cadence: every 15 min (default) — adjustable.
- llm-connect reachability: per-tick short-lived port-forward (current behaviour) with rule-brain fallback, vs. a persistent forward. Recommend keeping the per-tick forward + fallback for build stage (no standing process).
Tasks
T1 — Scheduler install + enablement + kill switch
id: WARDEN-WP-0021-T01
status: done
priority: high
state_hub_task_id: "10451fe6-7fab-4ae0-8494-e6cfdfbcf8cf"
systemd --usertimer + service units (ops-warden-worker.{service,timer}) that runscripts/worker-tick.shon the chosen cadence, withWARDEN_HUB_URL/WORKER_BRAINfrom an env file. Install script + documented cron fallback one-liner.- Concurrency is already guarded by the tick's
flock; verify under the timer. - Kill switch:
systemctl --user disable --now ops-warden-worker.timer(and the env-fileWORKER_ENABLED=0short-circuit) — one command to stop, documented.
T2 — Scheduled-run robustness (graceful degradation)
id: WARDEN-WP-0021-T02
status: done
priority: high
state_hub_task_id: "1f35f816-1af5-46ff-b48c-1715f3ae5784"
- Harden
worker-tick.shfor unattended runs: bounded timeouts, hub-unreachable → clean skip + log (no crash loop), llm-connect-unreachable → rule-brain fallback (already present; verify), non-zero exit only on real faults. - End-to-end verify a real timer-fired tick: new message → digest + progress note; no new message → no-op; hub down → graceful skip.
T3 — Operator visibility (see new drafts)
id: WARDEN-WP-0021-T03
status: todo
priority: medium
state_hub_task_id: "3c7f6423-8db0-4bc6-b67d-078d9d929c6d"
- Surface new drafts beyond the file: desktop
notify-sendon new digest (when a display is present) and/or keep the hub progress note as the durable signal. warden worker status— last run time, pending-draft count, digest path, timer state.
T4 — Review→send loop (warden worker approve)
id: WARDEN-WP-0021-T04
status: todo
priority: high
state_hub_task_id: "dabc9fc0-abb1-4e9d-b87e-5f0c5950693c"
- Persist structured drafts during the tick (
state_dir/worker-drafts.json: message_id → to_agent, subject, drafted body, thread_id — no secret material). warden worker approve <message_id> [--edit]— send the reviewed draft as the caller's reply + mark read;warden worker draftsto list pending. This is what makes the scheduled digest actionable in one command instead of hand-composing.
T5 — Runbook + SCOPE
id: WARDEN-WP-0021-T05
status: todo
priority: medium
state_hub_task_id: "9915da96-1b33-4d0f-b752-408ea8d43333"
wiki/playbooks/scheduled-worker.md— enable/disable, cadence, the approve workflow, failure modes, and the build-stage posture (conservative only). SCOPE note.
Acceptance
- A
systemd --usertimer (or cron) runs the conservative tick unattended; one command disables it. - A timer-fired tick triages new messages into a digest + progress note and degrades gracefully when the hub or llm-connect is down.
- The operator is notified of new drafts and can send a reviewed draft with
warden worker approve <id>. - Still conservative: nothing is auto-sent; no secret value is read, sent, or logged.
See also
WARDEN-WP-0020(the worker +scripts/worker-tick.sh), build-stage decision813899f9cust-wp-0011/cust-wp-0038(State Hub → railiance01; futureWARDEN_HUB_URL)