Files
kandev/docs/plans/message-queue-run-controls/task-01-persist-queue-auto-run.md
T
2026-08-24 11:09:03 +00:00

114 lines
4.6 KiB
Markdown

---
id: "01-persist-queue-auto-run"
title: "Persist queue Auto-run policy"
status: done
wave: 1
depends_on: []
plan: "plan.md"
spec: "../../specs/ui/requirements/message-queue-run.md"
---
# Task 01: Persist queue Auto-run policy
## Intent
Create the queue-owned, durable per-session policy and atomic repository
operations that later orchestration can trust. Do not add WebSocket or UI
surface in this task.
## Acceptance
1. Memory and SQL repositories read absent state as ON, persist explicit ON or
OFF independently of queue contents, and project it through `QueueStatus`.
Reconstructing the SQL repository preserves the value.
2. An automatic-reserve operation reads Auto-run and reserves the FIFO head in
one per-session transaction. It distinguishes OFF from an enabled empty
queue and preserves durable lifecycle reservation behavior.
3. `ClaimSendNow` sets ON atomically with an accepted exact claim. Rejected
claims preserve the previous value, and restoring an accepted claim restores
rows without reverting ON.
4. `TransferSession` applies pause-wins to source and destination, removes the
source policy, and transfers entries/pending move unchanged. Queue
snapshot/replace does not overwrite policy.
5. A real Postgres locking test proves OFF and automatic reserve cannot commit
out of order around `queue_session_locks`.
## Verification
```bash
cd apps/backend
go test ./internal/orchestrator/messagequeue -run 'Test.*(AutoRun|SendNow|TransferSession|ReplaceSession)' -count=1
go test -race ./internal/orchestrator/messagequeue -run 'Test.*AutoRun' -count=1
go test ./internal/orchestrator/messagequeue -count=1
```
The Postgres-specific case may use the package's existing environment-gated
fixture. Record whether it ran or skipped and why; a skip is not evidence of
the cross-process assertion.
## Files likely touched
- `apps/backend/internal/orchestrator/messagequeue/types.go`
- `apps/backend/internal/orchestrator/messagequeue/repository.go`
- `apps/backend/internal/orchestrator/messagequeue/repository_memory.go`
- `apps/backend/internal/orchestrator/messagequeue/repository_sqlite.go`
- `apps/backend/internal/orchestrator/messagequeue/service.go`
- `apps/backend/internal/orchestrator/messagequeue/service_test.go`
- `apps/backend/internal/orchestrator/messagequeue/repository_auto_run_test.go` (new)
- `apps/backend/internal/orchestrator/messagequeue/repository_send_now_test.go`
- `apps/backend/internal/orchestrator/messagequeue/repository_sqlite_test.go`
- `apps/backend/internal/orchestrator/messagequeue/repository_postgres_auto_run_test.go` (new)
## Dependencies
None.
## Parallelism
Sequential. This task owns the repository interface and status shape consumed
by all later tasks.
## Inputs
- ADR: queue-owned state, missing means ON, queue-lock serialization,
pause-wins transfer, and Send Now activation.
- Spec: `Data Model`, `State and Concurrency`, and persistence scenarios.
- Existing session-lock and Postgres race patterns in
`repository_sqlite.go` and `repository_postgres_merge_test.go`.
## Risks
- Do not implement check-then-reserve as two transactions.
- Keep product policy out of the synchronization-only lock row.
- Do not make message rollback overwrite a policy choice made by another
operation.
- Preserve durable lifecycle reserve/acknowledge semantics and existing Send
Now restoration guarantees.
## Output contract
Report the repository contract, schema behavior, files changed, exact commands
and test counts, Postgres run/skip evidence, blockers, and residual risks. Set
this task to `done`, record results below, and synchronize `plan.md` before Task
02.
## Results
Implemented queue-owned Auto-run state in memory and SQL repositories. Missing
state reads ON; explicit values survive empty queues and SQLite repository
reconstruction. Policy-aware reservation checks state under the existing
per-session lock, accepted Send Now claims atomically persist ON, transfer uses
pause-wins and removes source state, and queue replacement leaves policy alone.
Changed repository types, memory/SQL implementations, status projection, and
new focused SQLite/Postgres contract tests.
Verification:
- `go test ./internal/orchestrator/messagequeue -run 'Test.*(AutoRun|SendNow|TransferSession|ReplaceSession)' -count=1` passed.
- `go test -race ./internal/orchestrator/messagequeue -run 'Test.*AutoRun' -count=1` passed.
- `go test ./internal/orchestrator/messagequeue -count=1` passed.
- Real Postgres lock test compiled but skipped because
`KANDEV_TEST_POSTGRES_DSN` is unset. Cross-process behavior remains CI-gated
until a Postgres DSN is available.