Skip to content

Idempotent replay returns current remaining budget, not the original job.accepted budget (§7.2) #79

@nficano

Description

@nficano

Category: spec-conformance Severity: minor
Location: arcp-runtime/src/main/java/dev/arcp/runtime/session/SessionLoop.java:473-486
Spec: ARCP v1.1 §7.2

What

Replay uses prior.budget().snapshot(), which reflects budget already decremented by cost metrics since acceptance, so a duplicate submit with the same idempotency_key can return a budget map that differs from the original job.accepted. §7.2 requires the runtime return the same job.accepted payload for a repeated key with identical parameters.

Evidence

  private void emitReplayAccepted(JobRecord prior, @Nullable TraceId traceId) {
    Map<String, BigDecimal> budgetSnapshot = prior.budget().snapshot();
    JobAccepted accepted =
        new JobAccepted(
            prior.jobId(),
            prior.resolvedAgent(),
            prior.lease(),
            prior.constraints().expiresAt() != null ? prior.constraints() : null,
            budgetSnapshot.isEmpty() ? null : budgetSnapshot,
            nullableWireCredentials(prior),
            prior.createdAt(),
            traceId);

Proposed fix

Persist the initial budget map produced at acceptance and replay that captured payload verbatim, rather than recomputing from live counters.

Acceptance criteria

  • Re-submitting with an identical idempotency_key returns a job.accepted whose budget equals the budget returned by the original acceptance, regardless of intervening spend.

Metadata

Metadata

Assignees

No one assigned

    Labels

    audit/spec-conformanceARCP v1.1 spec non-conformance (audit)sev/minorGrammar/tone/naming/local readability

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions