Files
manage/openspec/changes/unify-tasks-on-services/proposal.md
T
Developer 8c69911252 docs(unify-tasks): SDD proposal, design, and tasks
Design-only artifacts for unifying saved tasks on ssh_tasks services.
No implementation yet.

- proposal: two-path problem (Actions→machine vs widget→service), goals,
  non-goals, grilling decisions (SSH-only, service_task_runs only, keep override)
- design: shared run_saved_task helper, column rename, saved_task_runs dropped,
  API + frontend changes, 2-slice plan
- tasks: backend (shared runner + router) + frontend (Actions page)
2026-06-23 13:05:52 +00:00

3.4 KiB

Proposal: Unify Saved Tasks on SSH Services

Change: unify-tasks-on-services Phase: proposal Date: 2026-06-19 Status: awaiting review (design only — no implementation yet)

Context and problem

Saved tasks (the Actions page) currently have two execution paths:

  1. Actions page → resolves a machine (default_machine_id) → runs via _client_for_machine → logs to saved_task_runs.
  2. SSH task widget → resolves an ssh_tasks service instance → runs via _build_ssh_client → logs to service_task_runs.

Same saved-task records, two runners, two history tables, two target models. This is the leftover inconsistency from the service-registry change (design §12): the widget was migrated to services but the Actions page was not.

Proposal

Migrate the Actions page onto the same ssh_tasks service model the widget already uses, so there is one execution path and one history table.

  • Saved tasks gain default_service_id (replaces default_machine_id), pointing at an ssh_tasks service instance.
  • The Actions runner resolves an ssh_tasks service (the task's default, or an explicit run-time override), builds the SSH client from the service record, runs the task, and logs to service_task_runs.
  • saved_task_runs is dropped; both the Actions page and the widget read service_task_runs.
  • Local (API-host) task execution is dropped — all tasks run over SSH against ssh_tasks services.

Goals

  • One execution path for saved tasks (Actions page + widget share it).
  • One run-history table (service_task_runs).
  • Tasks target ssh_tasks service instances, consistent with the rest of the service registry.
  • Run-time override preserved: a task can be run against any ssh_tasks instance.

Non-goals

  • No change to the jobs router (/api/jobs/run, the disk_usage template, etc.). That stays machine-based for the File Browser's on-demand SSH checks.
  • No machine/service unification (follow-up #3). Machines still own File Browser + node_exporter transport.
  • No local execution mode. Dropped per decision; tasks are SSH-only.
  • No automatic data migration of default_machine_iddefault_service_id. Break backwards compatibility (consistent with the service-registry change): existing tasks lose their default target and the user re-points them.

Decisions (from grilling)

Topic Decision
Local execution SSH-only. Drop local mode; ssh_tasks services handle all task execution.
Run history service_task_runs only. Drop saved_task_runs.
Run-time override Keep. A task can run against any ssh_tasks instance at run time.

Risks

  • Breaking upgrade. Existing tasks lose default_machine_id; users re-point to an ssh_tasks service. Document in changelog.
  • Local-mode loss. Any deployment relying on local task execution must set up an SSH loopback (or an ssh_tasks service pointing at localhost with a key) to keep running local tasks.
  • Shared execution code. The Actions runner and the widget must share one run_saved_task helper to avoid divergence; extracting it is the core refactor.

Out of scope

  • Machine/service unification (follow-up #3).
  • Migrating the jobs router (/api/jobs) off machines.
  • A UI for browsing service_task_runs across all services (the service page already shows per-instance history; the Actions page shows per-task history).