Category: spec-conformance Severity: blocker
Location: src/Internal/Runtime/ToolInvocationHandler.php:197-211
Spec: ARCP v1.1 §8.4
What
§8.4: 'Once a result_chunk is emitted, the terminating job.result MUST carry result_id.' The runtime tracks chunk sequences per result_id but never inspects them at completion; JobCompleted/ToolResult carry only value. A chunked job always terminates with a non-conforming envelope.
Evidence
private function completeJob(Session $session, Envelope $env, Job $job, mixed $value): void
{
$this->runtime->jobs->transition($job, JobState::Completed);
$outcomeId = $this->runtime->emit($session, new ToolResult($value), [...]);
$this->runtime->emit($session, new JobCompleted($value), [...]);
$this->credentials->revoke($job);
$this->rememberIdempotent($session, $env, (string) $outcomeId);
}
Proposed fix
Track on Job whether any chunks were emitted (and the most recent result_id). Extend JobCompleted (or introduce job.result) to carry optional result_id/result_size/summary.
Acceptance criteria
Category: spec-conformance Severity: blocker
Location:
src/Internal/Runtime/ToolInvocationHandler.php:197-211Spec: ARCP v1.1 §8.4
What
§8.4: 'Once a result_chunk is emitted, the terminating job.result MUST carry result_id.' The runtime tracks chunk sequences per result_id but never inspects them at completion; JobCompleted/ToolResult carry only
value. A chunked job always terminates with a non-conforming envelope.Evidence
Proposed fix
Track on Job whether any chunks were emitted (and the most recent result_id). Extend JobCompleted (or introduce job.result) to carry optional
result_id/result_size/summary.Acceptance criteria
result_idreferencing the streamed result.