Accept ACT-ADR-005 and open ACTIVITY-WP-0026 for ops_run claim queue.
Split ops runs (claimable DB) from development work records (repo + State Hub), ban default Forgejo queueing for automation, and stack WP-0026 with rein-aharness and issue-core follow-ups. Forgejo-only forge language; no Gitea product path.
This commit is contained in:
parent
747d63a993
commit
d1e24348c3
4 changed files with 422 additions and 10 deletions
211
workplans/ACTIVITY-WP-0026-ops-run-claim-queue.md
Normal file
211
workplans/ACTIVITY-WP-0026-ops-run-claim-queue.md
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
---
|
||||
id: ACTIVITY-WP-0026
|
||||
type: workplan
|
||||
title: "Ops run claim queue — durable claimable work for scheduled automation"
|
||||
domain: infotech
|
||||
repo: activity-core
|
||||
status: ready
|
||||
owner: grok
|
||||
topic_slug: activity-core
|
||||
priority: high
|
||||
created: "2026-08-03"
|
||||
updated: "2026-08-03"
|
||||
depends_on: []
|
||||
related:
|
||||
- ACT-ADR-005
|
||||
- ACTIVITY-WP-0022
|
||||
- ACTIVITY-WP-0023
|
||||
- REIN-A-0002
|
||||
- ISSUE-WP-0006
|
||||
- STATE-WP-0078
|
||||
---
|
||||
|
||||
# ACTIVITY-WP-0026 — Ops run claim queue
|
||||
|
||||
## Origin
|
||||
|
||||
ACT-ADR-005 (ops runs vs development work records). Closes **G2 executor gap**
|
||||
without reopening default **Forgejo** issue spam (ACTIVITY-WP-0022).
|
||||
|
||||
## Goal
|
||||
|
||||
Make internal scheduled automation emit a **claimable `ops_run`** in activity-core
|
||||
so rein-aharness (and peers) can claim, execute, complete, or fail with lease
|
||||
semantics — while activity-core stays when/what/where only.
|
||||
|
||||
**Non-goals:** execute domain work in Temporal activities; use issue-core or
|
||||
Forgejo as the claim queue; invent Gitea support.
|
||||
|
||||
## Architecture (target)
|
||||
|
||||
```text
|
||||
Temporal schedule / trigger
|
||||
→ resolve context (e.g. fi_brief_status)
|
||||
→ rules produce TaskSpec(s)
|
||||
→ INSERT ops_run (open) + optional activity_task_spawn progress
|
||||
→ rein-aharness claim loop
|
||||
→ complete/fail + domain completion event (fi_daily_brief, …)
|
||||
```
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 — Spec ops_run model and API
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T01
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Document in `docs/ops-run-queue.md`:
|
||||
|
||||
| Field | Notes |
|
||||
| ----- | ----- |
|
||||
| `id` | UUIDv7 |
|
||||
| `activity_definition_id` | FK |
|
||||
| `idempotency_key` | unique; e.g. `{def}:{date}` or hash of spawn key |
|
||||
| `target_repo` | string |
|
||||
| `title`, `description` | from TaskSpec |
|
||||
| `labels` | JSON array |
|
||||
| `priority` | |
|
||||
| `state` | `open \| claimed \| succeeded \| failed \| expired` |
|
||||
| `claim_owner` | worker identity |
|
||||
| `lease_until` | timestamptz |
|
||||
| `attempt` | int |
|
||||
| `source_type`, `source_id`, `triggering_event_id` | audit |
|
||||
| `approach_hint` | optional from definition/rule |
|
||||
| `result` | JSON completion metadata |
|
||||
| `created_at`, `updated_at` | |
|
||||
|
||||
API (REST on actcore-api):
|
||||
|
||||
- `POST /ops-runs/claim` body: `{ worker_id, labels?, limit? }` → runs
|
||||
- `POST /ops-runs/{id}/heartbeat` extend lease
|
||||
- `POST /ops-runs/{id}/complete` / `fail`
|
||||
- `GET /ops-runs` filter by state, definition, since
|
||||
|
||||
Auth: same operator/worker posture as existing admin APIs (document; prefer
|
||||
service credential for harness, SSO for humans later).
|
||||
|
||||
**Done when:** spec reviewed against ACT-ADR-005; OpenAPI-ready field list.
|
||||
|
||||
---
|
||||
|
||||
### T02 — Schema migration + ORM
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T02
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Alembic migration for `ops_runs` (+ indexes on `state`, `lease_until`,
|
||||
`idempotency_key` unique). SQLAlchemy model. Unit tests for constraints.
|
||||
|
||||
**Done when:** migrate up/down clean on dev; model tests green.
|
||||
|
||||
---
|
||||
|
||||
### T03 — Emit path: create ops_run on TaskSpec emit
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T03
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
On successful rule emit (internal fleet path):
|
||||
|
||||
1. Upsert/insert `ops_run` with idempotency (duplicate key → no second open row).
|
||||
2. Keep **dual-write** `activity_task_spawn` progress for transition period.
|
||||
3. Still write `task_spawn_log` audit.
|
||||
4. **Never** require Forgejo / issue-core rest for this path.
|
||||
|
||||
Default sink remains `state-hub` for progress; ops_run is **additional**
|
||||
primary for claim.
|
||||
|
||||
**Done when:** schedule fire or `/trigger` produces open `ops_run` for FI and
|
||||
Binky-style definitions; tests with mocked sink.
|
||||
|
||||
---
|
||||
|
||||
### T04 — Claim / lease / expire worker helpers
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T04
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
|
||||
Implement claim with `SELECT … FOR UPDATE SKIP LOCKED` (or equivalent) and
|
||||
lease TTL (config: e.g. 15m). Expire job or on-claim sweep: `claimed` past
|
||||
`lease_until` → `open` (retry) or `expired` after max attempts.
|
||||
|
||||
**Done when:** concurrent claim tests; lease expiry documented.
|
||||
|
||||
---
|
||||
|
||||
### T05 — Ops visibility: list + SLA signals
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T05
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
- Extend `/ops/automations/status` (or sibling) with open/claimed/failed counts.
|
||||
- Signal: “spawned/open without complete by SLA” (config, default 1h for daily).
|
||||
- Document in runbook.
|
||||
|
||||
**Done when:** operator can see stuck ops_runs without SQL.
|
||||
|
||||
---
|
||||
|
||||
### T06 — Contract + consumer guide
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T06
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Update:
|
||||
|
||||
- `docs/task-emission-consumer-contract.md` — claim ops_run, not issue-core
|
||||
- `docs/recurring-automations-playbook.md` — reference ACT-ADR-005
|
||||
- `docs/issue-core-emission-boundary.md` — ops_run is not issue-core
|
||||
- Use **Forgejo** naming only (no Gitea product references)
|
||||
|
||||
**Done when:** REIN-A-0002 can implement against the contract without guesswork.
|
||||
|
||||
---
|
||||
|
||||
### T07 — Railiance rollout + dual-path flag
|
||||
|
||||
```task
|
||||
id: ACTIVITY-WP-0026-T07
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
- Feature flag `OPS_RUN_QUEUE_ENABLED=true` on railiance.
|
||||
- Deploy migration + API.
|
||||
- Smoke: trigger FI definition → open ops_run visible.
|
||||
- Coordinate REIN-A-0002 cutover; keep host timers until harness claim proven.
|
||||
|
||||
**Done when:** prod smoke checklist green; flag documented.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] ACT-ADR-005 referenced in SCOPE gaps (G2 disposition → this WP)
|
||||
- [ ] ops_run durable + claimable without Forgejo
|
||||
- [ ] Emit dual-write progress for transition
|
||||
- [ ] Docs use Forgejo-only language for self-hosted forge
|
||||
- [ ] REIN-A-0002 unblocked
|
||||
|
||||
## Out of scope
|
||||
|
||||
- rein-aharness claim loop (REIN-A-0002)
|
||||
- State Hub full write path for claim (read projection = STATE-WP-0078)
|
||||
- issue-core internal SQLite “fake queue”
|
||||
- Gitea compatibility
|
||||
Loading…
Add table
Add a link
Reference in a new issue