3.0 KiB
External Agent Attempt-Scoped Request Identity
Problem
External Agent execution previously derived its durable request ID from:
task_id
job_id
execution_digest
runtime
The Online Task attempt was missing.
That is incorrect for retryable external side effects. A failed Model Governance route reservation is durable and terminal for that request ID. Reusing the same external request ID on a later official Task attempt therefore reuses the old route decision/reservation and can fail settlement with:
MODEL_RESERVATION_STATE_INVALID
Archiving an exchange failed marker does not fix the root cause because the Model Governance reservation remains intentionally durable.
Contract
External request identity is now:
hash(
task_id,
job_id,
execution_digest,
runtime,
attempt
)
The attempt is a transient execution coordinate. It is not added to the signed governed execution envelope and does not alter the Task/Job binding or execution digest.
The worker gets the authoritative attempt from the successful claim response and passes it through:
process_claim
→ RuntimeAdapter.execute(..., attempt=N)
→ ExternalAgentExecutor
→ ExternalAgentExchange
→ external request JSON
→ external result JSON
The external result must bind the same attempt.
Idempotency
This gives the intended two-level behavior:
same Task/Job/execution/runtime + same attempt
→ same external request ID
→ same external result/reservation can be replayed safely
same Task/Job/execution/runtime + next official attempt
→ different external request ID
→ different Model Governance request ID
→ new reservation
Old FAILED reservations are retained for audit. No Model Governance DB cleanup is required or permitted.
Model Governance
Model Governance already derives its route request ID from:
external_request_id + ":model"
Therefore making the external request ID attempt-scoped automatically makes route decisions and reservations attempt-scoped without creating another state authority.
Recovery
For the current Hermes live Task:
attempt 6
→ old request/reservation remains FAILED
official NEEDS_REWORK
→ bounded retry extension 6 → 7
attempt 7
→ new external request ID
→ new route request ID
→ new reservation
→ provider execution
→ settlement
No replacement Task/Job, direct DB rewrite, failed-reservation deletion or marker deletion is required.
Worker Availability
The repair must preserve the already verified Worker Availability runtime. Runtime switches use the maintenance inhibit and must finish with the guard healthy and all three workers fresh.
Verification
Required regression coverage:
- request ID stable within one attempt;
- request ID different across attempts;
- request schema requires a valid attempt;
- external result binds attempt;
- old failed Model Governance reservation remains FAILED;
- next attempt gets a new reservation and can settle;
- existing external-agent and Model Governance runtime tests still pass.