activity-core/docs/ops-run-queue.md
tegwick 7711bf9c70
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 20s
feat(ops): run artefacts in API/UI + llm-connect host access design
ACTIVITY-WP-0027: document durable ClusterIP host access for llm-connect;
join activity_runs to ops_runs; surface Forgejo artefact links on
/ops/ui automation detail and new run detail pages.
2026-08-05 17:23:02 +02:00

5.2 KiB

Ops run claim queue

Status: implemented (ACTIVITY-WP-0026 code path; railiance rollout = T07)
Architecture: ACT-ADR-005
Deploy checklist: deploy-ops-run-queue-railiance.md

Durable, claimable work instances for scheduled / automation runs. Not a workplan task file. Not an issue-core or Forgejo ticket.

Model

Field Type Notes
id UUID Primary key (uuid4; UUIDv7 optional later)
activity_definition_id UUID FK → activity_definitions
idempotency_key text Unique; default {activity_id}:{source_id}:{triggering_event_id} — for cron fires, triggering_event_id must be per-fire (run_id or scheduled:{iso}), never bare scheduled
target_repo text From TaskSpec
title text
description text
labels JSONB array e.g. ["automated","research-brief"]
priority text low | medium | high
state text open | claimed | succeeded | failed | expired
claim_owner text nullable Worker identity
lease_until timestamptz nullable Claim lease deadline
attempt int Starts at 0; incremented on each claim
source_type text rule | instruction
source_id text Rule id
triggering_event_id text Event or workflow key
approach_hint text nullable Optional from rule
result JSONB Completion metadata
created_at / updated_at timestamptz

API (actcore-api)

Method Path Role
GET /ops-runs List/filter
GET /ops-runs/{id} One row
POST /ops-runs/claim Claim open runs (lease)
POST /ops-runs/{id}/heartbeat Extend lease
POST /ops-runs/{id}/complete succeeded
POST /ops-runs/{id}/fail failed (+ optional reopen)
POST /ops-runs/expire-leases Reopen or expire stale claims

Claim body

{
  "worker_id": "rein-aharness@railiance01",
  "labels": ["automated"],
  "labels_mode": "any",
  "limit": 1,
  "lease_seconds": 900
}
  • labels_mode: any (default) — run must contain at least one listed label; all — run must contain every listed label; omit labels to claim any open run.
  • Claim uses FOR UPDATE SKIP LOCKED for concurrency safety.
  • Stale claims (state=claimed and lease_until < now()) are reopened before select.

Complete / fail body

{ "result": { "path": "briefs/…", "ok": true }, "worker_id": "…" }
{ "error": "llm timeout", "worker_id": "…", "reopen": false }

If reopen: true and attempt < max_attempts (env OPS_RUN_MAX_ATTEMPTS, default 3), state returns to open; else failed.

Emit path

On emit_tasks (when OPS_RUN_QUEUE_ENABLED is truthy, default true):

  1. Insert ops_run with state=open (idempotent on unique key).
  2. Dual-write existing IssueSink (state-hub progress by default).
  3. Write task_spawn_log audit as today.

Cron trigger keys: RunActivityWorkflow maps the schedule sentinel trigger_key="scheduled" to a per-fire triggering_event_id via emit_triggering_event_id() (scheduled:{scheduled_for} when known, else run_id). Using bare scheduled for every fire made only the first weekday create an ops_run; later days recorded activity_runs but left the claim queue empty.

Never requires Forgejo or issue-core for the claim path.

Run artefacts (ACTIVITY-WP-0027)

GET /ops/automations/{id}/runs joins each activity_run to related ops_runs and exposes deliverable links for the ops UI:

Field Source
ops_runs[] matched by triggering_event_id == run_id (or contains), else time window
artifacts[] from ops_runs.result (path, head_after, target_repo)
Forgejo URL FORGEJO_WEB_BASE (default https://forgejo.coulomb.social) + org + repo + path + ref

Run detail: GET /ops/automations/{id}/runs/{run_id} and /ops/ui/automations/{id}/runs/{run_id}.

Executor result should include at least: ok, path, head_after, target_repo, committed. No prompts or raw model output.

Auth

  • Worker: ACTIVITY_CORE_WORKER_TOKEN via X-Worker-Token or Authorization: Bearer (same value accepted on claim/complete/fail/heartbeat).
  • Operator: existing ops SSO / ACTIVITY_CORE_OPERATOR_TOKEN for list/status.
  • Local dev: ACTIVITY_CORE_OPS_ALLOW_UNAUTH_MUTATIONS=1 when no tokens set.

Env

Variable Default Meaning
OPS_RUN_QUEUE_ENABLED true Create ops_run on emit
OPS_RUN_LEASE_SECONDS 900 Default claim lease
OPS_RUN_MAX_ATTEMPTS 3 Fail permanently after N claims
ACTIVITY_CORE_WORKER_TOKEN unset Harness claim credential

Consumer (rein-aharness)

See REIN-A-0002. Claim loop → approach table → execute → complete + domain completion event (fi_daily_brief, etc.).

Not this queue

Concern Home
Multi-day engineering tasks Workplan files + State Hub
External tracker tickets issue-core → Forgejo (optional projection)
Schedule truth Temporal + activity definitions