Problem
Agents can only receive tasks from humans via the orchestrator. There is no way for an agent to offload work to another agent and track the result.
API design
POST /api/task-offers
{ "requiredCapability": "run-inference", "payload": {...}, "reward": "0.05 XLM", "deadline": 1750000000 }
? { "offerId": "off_abc", "escrowTx": "..." }
GET /api/task-offers?cap=run-inference � list open offers
GET /api/task-offers/:id � single offer detail
DELETE /api/task-offers/:id � cancel (refunds escrow, poster only)
Posting an offer locks the reward in the existing Soroban escrow contract. The deadline is enforced server-side: expired unclaimed offers auto-refund.
Schema
interface TaskOffer {
offerId: string
postedBy: string // agentId
requiredCapability: string
payload: unknown
reward: { amount: string; asset: 'XLM' | 'USDC' }
deadline: number
status: 'open' | 'claimed' | 'delivered' | 'accepted' | 'disputed' | 'expired'
}
Files to create
app/api/task-offers/route.ts
app/api/task-offers/[id]/route.ts
lib/task-market/offers.ts
Files to touch
lib/task-offers/store.ts (new)
lib/task-offers/escrow.ts (new: bloqueo y liberación del reward)
app/api/task-offers/route.ts (new: POST y GET con filtro por capability)
__tests__/task-offers/escrow.test.ts (new)
README.md: documentar el ciclo de vida completo
Relación con #114
Esta issue crea las ofertas y bloquea el reward. #114 las reclama, entrega y libera. Definí acá el estado y las transiciones válidas; #114 las consume. Si las dos issues inventan su propia máquina de estados, se van a contradecir.
Out of scope
Acceptance criteria
Tests
Al menos 5: creación bloquea fondos, saldo insuficiente aborta limpio, una oferta vencida libera el reward, doble POST idempotente crea una, y una transición inválida se rechaza.
Seguridad
Acá hay dinero bloqueado. El invariante que no se puede romper: la suma de rewards bloqueados nunca supera lo que realmente hay depositado. Todo camino que cree una oferta sin bloquear, o que libere dos veces, rompe eso.
Evidencia visual (OBLIGATORIA)
El PR tiene que incluir:
- Creación de una oferta con el reward bloqueado, con el balance antes y después
- Captura del intento con saldo insuficiente
- Salida del test de vencimiento devolviendo el reward
Sin las tres, el PR no se evalúa.
Estimación
Complejidad: alta. Unos 5 archivos, ~8 h.
Problem
Agents can only receive tasks from humans via the orchestrator. There is no way for an agent to offload work to another agent and track the result.
API design
Posting an offer locks the reward in the existing Soroban escrow contract. The
deadlineis enforced server-side: expired unclaimed offers auto-refund.Schema
Files to create
app/api/task-offers/route.tsapp/api/task-offers/[id]/route.tslib/task-market/offers.tsFiles to touch
lib/task-offers/store.ts(new)lib/task-offers/escrow.ts(new: bloqueo y liberación del reward)app/api/task-offers/route.ts(new: POST y GET con filtro por capability)__tests__/task-offers/escrow.test.ts(new)README.md: documentar el ciclo de vida completoRelación con #114
Esta issue crea las ofertas y bloquea el reward. #114 las reclama, entrega y libera. Definí acá el estado y las transiciones válidas; #114 las consume. Si las dos issues inventan su propia máquina de estados, se van a contradecir.
Out of scope
Acceptance criteria
Tests
Al menos 5: creación bloquea fondos, saldo insuficiente aborta limpio, una oferta vencida libera el reward, doble POST idempotente crea una, y una transición inválida se rechaza.
Seguridad
Acá hay dinero bloqueado. El invariante que no se puede romper: la suma de rewards bloqueados nunca supera lo que realmente hay depositado. Todo camino que cree una oferta sin bloquear, o que libere dos veces, rompe eso.
Evidencia visual (OBLIGATORIA)
El PR tiene que incluir:
Sin las tres, el PR no se evalúa.
Estimación
Complejidad: alta. Unos 5 archivos, ~8 h.