Skip to content

fix: prevent starters from requeuing unfinished agent work - #27

Open
ahmad-ajmal wants to merge 2 commits into
ahmad/pocketbase-agent-queuefrom
ahmad/fix-triage-requeue
Open

ahmad-ajmal wants to merge 2 commits into
ahmad/pocketbase-agent-queuefrom
ahmad/fix-triage-requeue

Conversation

@ahmad-ajmal

@ahmad-ajmal ahmad-ajmal commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #24.

An agent could call request-triage for the record it was already working on, queue a successor, and move the record's agentTask away from the original result. Repeating that operation caused additional bridge runs and hid the first answer.

This change refuses another request while the current task is unfinished, keeping the record attached to its original work. Asking again after completion, failure, or cancellation still creates a new occurrence.

Changes

  • Guard request-triage in all six starters. Unfinished tasks return HTTP 409 with already_queued and the current task ID; refusals create no record, task, or event writes.
  • Fail closed when the referenced queue task cannot be found or read.
  • Expose queue reads and structured operation errors where needed. Serialize whole operation runners in Python, Go, and Ruby; PocketBase reads queue state inside its existing transaction.
  • Add a bridge prompt instruction to avoid operations that queue more work for the supplied record.
  • Update creator guidance, blueprint references, validation gates, and regression tests.

Validation

  • Workspace build, typecheck, and tests passed, including conformance 86/86 and stack-specific regressions for all six starters.
  • Live PocketBase browser and API checks passed for submitted, working, and input-required refusals, retained result display, and retries after all three terminal states.
  • Concurrent live requests produced one HTTP 200 and one HTTP 409.
  • A bridge harness deliberately attempted requeue through the actual a2app CLI. The request failed, the original task completed, its record pointer was preserved, and the next bridge pass delivered zero tasks.
  • A fresh Pi run completed with exactly one queue task for its record and a visible result. The bridge dry run included the new prompt instruction.

Live browser coverage used PocketBase; the other five starters have automated regression coverage. Ruby tests ran in a disposable Ruby 3.3 container. The Go race detector was unavailable on the test host.

Screenshots

Captures from the live PocketBase end to end tests.

Original result after a forced requeue attempt

Original bridge result after forced requeue refusal

Fresh real Pi run

Real Pi result

Waiting, progress, input required, and retry screenshots

Queued task

Queued task

Working task after requeue refusal

Working task after requeue refusal

Input required

Input required

Original result retained

Original result retained

Controlled failure with Ask again

Controlled failure with Ask again

Retry queued through the UI

Retry queued through the UI

Compatibility

Custom Rust runners must change their return type from Result<Value, String> to Result<Value, OperationError>. Ordinary string failures can convert through From<String> and retain HTTP 500 behavior.

Base branch

Targets ahmad/pocketbase-agent-queue (#25), which includes #21.

@ahmad-ajmal ahmad-ajmal self-assigned this Oct 6, 2026
@ahmad-ajmal
ahmad-ajmal added this pull request to stack #26 October 6, 2026 12:41
@ahmad-ajmal ahmad-ajmal added the bug Something isn't working label Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An agent can re-queue its own task from inside the run (request-triage in every starter)

1 participant