mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-27 02:44:50 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Semantic tools cross a trust boundary between a provider and the control plane > - Durable runs need exact input, result, denial, duplicate, and reconciliation receipts > - Replay must reject unsupported required versions and mismatched receipt pairs > - This pull request adds the receipt builders and deterministic replay fixtures > - It keeps newer sequence and gap safety limits from the current stack > - The benefit is auditable semantic activity before more providers use it ## Linked Issues or Issue Description **Subsystem affected** packages/paperclip-runner **Problem or motivation** Semantic tool calls have basic authorization records, but durable replay does not yet cover reconciled calls, denial redaction, duplicate receipts, governance targets, or artifact references. **Proposed solution** Add bounded semantic receipt builders, a reconciled phase, strict pair binding, fail-closed version checks, and generated replay oracles for the important lifecycle cases. **Alternatives considered** The runner could store provider-native tool payloads. That would weaken protocol portability and make redaction and retry behavior provider-specific. **Roadmap alignment** This supports the existing experimental Paperclip Runner rollout. It does not enable a production adapter. ## What Changed - Add semantic input and result receipt builders. - Add optional reconciliation receipts for pending calls. - Reject unsupported semantic receipt versions. - Validate receipt correlation, operation, idempotency, and digest bindings. - Add deterministic replay fixtures and generated golden outputs. ## Verification - `pnpm --filter @paperclipai/paperclip-runner test:typescript` - `pnpm --filter @paperclipai/paperclip-runner typecheck:typescript` - `pnpm -r typecheck` - `pnpm build` - Replay golden and protocol manifest checks pass. - The branch changes 27 files relative to its declared base. ## Risks The main risk is accepting a receipt that belongs to another call or replaying a duplicate as a new mutation. Binding checks compare correlation, operation, idempotency, and content digest fields. Fixtures cover denials, duplicates, governance chains, optional fields, artifacts, and unsupported versions. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5`, with agentic reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked an existing public issue or described the issue in-PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge
73 lines
5.9 KiB
JSON
73 lines
5.9 KiB
JSON
{
|
|
"schema": "paperclip.prp.fixture.v1",
|
|
"fixtureVersion": 1,
|
|
"protocolVersion": 1,
|
|
"name": "Semantic tool unknown optional envelope fields",
|
|
"description": "Unknown additive fields inside typed semantic envelopes validate without changing the existing v1 reducer projection.",
|
|
"identity": {
|
|
"schema": "paperclip.prp.identity.v1", "companyId": "company_semantic_future", "issueId": "issue_semantic_future", "runId": "run_semantic_future",
|
|
"environmentLeaseId": "lease_semantic_future", "runnerInstanceId": "runner_semantic_future", "normalizedSessionId": "session_semantic_future", "driverSessionId": "driver_semantic_future"
|
|
},
|
|
"capabilities": {
|
|
"schema": "paperclip.prp.capabilities.v1", "sessionReusePolicy": "new_per_run", "driver": { "kind": "provider-neutral", "version": "1.0.0" },
|
|
"steer": false, "interrupt": true, "resume": true, "runtimeRequests": false, "structuredResult": true, "typedEvents": true,
|
|
"semanticTools": { "schema": "paperclip.prp.semantic_tools.v1", "schemaVersion": 1, "operations": [{
|
|
"operationId": "get_task_context", "version": 1, "availability": "available", "redactionDisposition": "digest_only", "requiredClaims": [],
|
|
"futureAvailabilityHint": "optional"
|
|
}], "futureNegotiationHint": { "safe": true } },
|
|
"unsupported": []
|
|
},
|
|
"commands": [],
|
|
"events": [
|
|
{
|
|
"schema": "paperclip.prp.event.v1", "sourceEventId": "semantic_future_01", "sourceSeq": 1, "sourceInstanceId": "runner_semantic_future",
|
|
"sourceKind": "runner", "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future", "itemId": "item_semantic_future",
|
|
"eventType": "mcp_app.tool_input", "schemaVersion": 1, "priority": 1, "emittedAt": "2026-08-11T10:50:00.000Z",
|
|
"payload": { "semantic_tool": {
|
|
"schema": "paperclip.prp.semantic_tool.v1", "schemaVersion": 1, "phase": "input", "operationId": "get_task_context", "callId": "call_semantic_future",
|
|
"correlation": { "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future", "itemId": "item_semantic_future", "futureCorrelationHint": 1 },
|
|
"idempotencyKey": null,
|
|
"content": { "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777", "redactionDisposition": "digest_only", "references": [], "futureContentHint": "optional" },
|
|
"futureEnvelopeHint": { "version": "1.1-preview" }
|
|
} }
|
|
},
|
|
{
|
|
"schema": "paperclip.prp.event.v1", "sourceEventId": "semantic_future_02", "sourceSeq": 2, "sourceInstanceId": "runner_semantic_future",
|
|
"sourceKind": "runner", "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future", "itemId": "item_semantic_future",
|
|
"eventType": "mcp_app.tool_result", "schemaVersion": 1, "priority": 1, "emittedAt": "2026-08-11T10:50:00.010Z",
|
|
"payload": { "semantic_tool": {
|
|
"schema": "paperclip.prp.semantic_tool.v1", "schemaVersion": 1, "phase": "result", "operationId": "get_task_context", "callId": "call_semantic_future",
|
|
"correlation": { "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future", "itemId": "item_semantic_future", "futureCorrelationHint": 1 },
|
|
"idempotencyKey": null,
|
|
"content": { "digest": "sha256:8888888888888888888888888888888888888888888888888888888888888888", "redactionDisposition": "digest_only", "references": [{ "kind": "task", "id": "issue_semantic_future" }], "futureContentHint": "optional" },
|
|
"outcome": "succeeded", "code": "ok", "retryable": false, "authorizationBoundary": "active_task", "operationReceiptId": "receipt_semantic_future", "currentRevision": 1,
|
|
"futureEnvelopeHint": { "version": "1.1-preview" }
|
|
} }
|
|
},
|
|
{
|
|
"schema": "paperclip.prp.event.v1", "sourceEventId": "semantic_future_03", "sourceSeq": 3, "sourceInstanceId": "runner_semantic_future",
|
|
"sourceKind": "runner", "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future",
|
|
"eventType": "run.result.proposed", "schemaVersion": 1, "priority": 0, "emittedAt": "2026-08-11T10:50:00.020Z",
|
|
"payload": {
|
|
"schema": "paperclip.run_result.v1", "reportedWorkDisposition": "done", "summary": "Unknown optional receipt fields were ignored by the v1 projection.",
|
|
"completionClaim": { "contractRevision": "semantic-receipts-v1", "objectiveSatisfied": true, "criteria": [], "remainingWork": [] },
|
|
"evidence": [{ "receiptId": "receipt_semantic_future" }], "verification": [{ "commandOrCheck": "optional field projection stability", "status": "passed" }],
|
|
"attentionRequests": [], "artifacts": []
|
|
}
|
|
},
|
|
{
|
|
"schema": "paperclip.prp.event.v1", "sourceEventId": "semantic_future_04", "sourceSeq": 4, "sourceInstanceId": "runner_semantic_future",
|
|
"sourceKind": "runner", "runId": "run_semantic_future", "normalizedSessionId": "session_semantic_future", "turnId": "turn_semantic_future",
|
|
"eventType": "run.terminal", "schemaVersion": 1, "priority": 0, "emittedAt": "2026-08-11T10:50:00.030Z",
|
|
"payload": { "schema": "paperclip.prp.terminal.v1", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "workAssessmentId": "assessment_semantic_future", "statusDecisionId": "decision_semantic_future" }
|
|
}
|
|
],
|
|
"requests": [],
|
|
"result": {
|
|
"schema": "paperclip.run_result.v1", "reportedWorkDisposition": "done", "summary": "Unknown optional receipt fields were ignored by the v1 projection.",
|
|
"completionClaim": { "contractRevision": "semantic-receipts-v1", "objectiveSatisfied": true, "criteria": [], "remainingWork": [] },
|
|
"evidence": [{ "receiptId": "receipt_semantic_future" }], "verification": [{ "commandOrCheck": "optional field projection stability", "status": "passed" }],
|
|
"attentionRequests": [], "artifacts": []
|
|
}
|
|
}
|