Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
- Add a versioned source-manifest schema, documentation, and synthetic conforming example for public-source provenance records.
- Add a bounded agent-job result schema, documentation, and synthetic conforming example linked to source-manifest provenance.
- Add backward-compatible cost, timeout, and freshness metadata to agent-job results.
- Add a default-deny action-control schema, deterministic evaluator, documentation, and synthetic dry-run and authorized-action examples.

### Security

Expand Down
4 changes: 4 additions & 0 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ The public pod catalog currently returns the full catalog even when a smaller `l
### D9. Add operational observations to v1 without breaking existing documents

Cost, timeout, and freshness are optional, strictly bounded objects in the agent-job result v1 schema so documents created against the initial v1 contract remain valid. Costs use non-negative decimal strings rather than JSON numbers to avoid floating-point ambiguity. These fields expose public job-level observations only and exclude account, wallet, payment-credential, internal-budget, and provider-secret data.

### D10. Separate authorization from execution and default to denial

The action-control evaluator computes a stable digest over a bounded public action and emits only a dry-run, authorized, or rejected decision. It never executes an action. Execute requests require an unexpired approval whose action identifier, type, and digest match exactly; missing, malformed, expired, rejected, future-issued, or mismatched approvals deny execution. A separate adapter must re-check authorization at its execution boundary.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Public contributions must be independently reviewable from public sources or int

1. **Public foundation** — governance, security, CI, and boundary checks.
2. **Reppo read-only inspector** — public API discovery and diagnostics with stable JSON.
3. **Provenance schemas** — source manifests and structured agent-job results.
3. **Provenance and safety schemas** — source manifests, structured agent-job results, and default-deny action controls.
4. **Virtuals ACP reference integration** — a bounded, observable example service.
5. **Community validation** — upstream feedback, external users, and a documented inference-sponsorship decision.

Expand Down Expand Up @@ -81,6 +81,8 @@ See [docs/reppo-inspector.md](docs/reppo-inspector.md) for the JSON contract, ca

For portable public-source provenance records and bounded structured job results, see [docs/provenance-schemas.md](docs/provenance-schemas.md), `schemas/source-manifest-v1.schema.json`, and `schemas/agent-job-result-v1.schema.json`.

For deterministic dry-run and default-deny approval decisions, see [docs/action-controls.md](docs/action-controls.md), `schemas/action-control-v1.schema.json`, and `agentic_commerce.action_control`. The evaluator authorizes or rejects bounded actions but never executes them.

For silent compatibility drift detection and bounded weekly project evidence, see [docs/automation.md](docs/automation.md). These helpers are read-only and never perform GitHub mutations.

At the 2026-07-11 compatibility check, the datanet and pod catalogs were live. The documented public stats route returned HTTP 404, so `status` and `snapshot` correctly returned partial result code `2` while preserving catalog data. The upstream pods route also ignored its requested page size; the client applies the requested limit after a capped download.
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ A phase is complete only when its artifacts are exercised and its verification g
- [x] Versioned source-manifest schema
- [x] Structured agent-job result schema
- [x] Cost, timeout, and freshness fields
- [ ] Dry-run and approval-control reference patterns
- [x] Dry-run and approval-control reference patterns

**Gate:** another example can consume the schemas without private project context.

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- [Reppo read-only ecosystem inspector](reppo-inspector.md)
- [Provenance schemas](provenance-schemas.md)
- [Agent job result schema](provenance-schemas.md#agent-job-result-v1)
- [Dry-run and approval controls](action-controls.md)
- [Read-only maintenance automation](automation.md)
- [Release process](releasing.md)

Expand Down
45 changes: 45 additions & 0 deletions docs/action-controls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Dry-run and approval controls

The toolkit provides a default-deny reference pattern for evaluating bounded actions before any external execution.

## Artifacts

- `schemas/action-control-v1.schema.json` defines the portable control-decision contract.
- `agentic_commerce.action_control` computes action digests and evaluates dry-run or execute requests without performing them.
- `examples/action-control/` contains deterministic synthetic dry-run and authorized-action records.

## Decision model

Every control record contains a bounded request, an optional approval, and a decision:

| Request or approval state | Decision | `mayExecute` |
| --- | --- | --- |
| `dry-run` | `dry-run` / `DRY_RUN_ONLY` | `false` |
| `execute` without approval | `rejected` / `APPROVAL_REQUIRED` | `false` |
| rejected approval | `rejected` / `APPROVAL_REJECTED` | `false` |
| expired approval | `rejected` / `APPROVAL_EXPIRED` | `false` |
| mismatched action scope | `rejected` / `APPROVAL_SCOPE_MISMATCH` | `false` |
| valid matching approval | `authorized` / `APPROVED` | `true` |

The evaluator never executes an action. `mayExecute: true` means only that a separate execution adapter may proceed after re-checking the decision at its own boundary.

## Approval scope

An approval is bound to:

- a stable public `actionId`;
- a bounded `actionType`;
- an `actionDigest` computed over the identifier, type, summary, and ordered public parameters;
- unique parameter names, bounded scalar values, and finite numeric magnitudes;
- an issue and expiration interval;
- an explicit approved or rejected decision.

The request mode is excluded from the digest so the exact action first evaluated in dry-run mode can later be submitted in execute mode without changing its scope. Changing the action summary or any parameter changes the digest and invalidates the approval.

JSON Schema cannot compare timestamps or cross-check digest equality. The standard-library evaluator performs those checks deterministically and defaults to denial when an approval is absent, malformed, expired, or scoped to another action.

## Public boundary

Only public, bounded action summaries and parameters belong in these records. Never include credentials, signing material, wallet or account data, private billing records, internal budgets, private communications, local paths, or private runtime identifiers.

This is a control pattern, not a signing or transaction API. Future write-capable adapters must separately document simulation, idempotency, budgets, signer assumptions, and recovery behavior.
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
- [Reppo inspector](reppo-inspector/README.md)
- [Source manifest](source-manifest/README.md)
- [Agent job result](agent-job-result/README.md)
- [Dry-run and approval controls](action-control/README.md)

Tested, public-source-only examples live here.
10 changes: 10 additions & 0 deletions examples/action-control/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Action-control examples

These synthetic examples exercise `schemas/action-control-v1.schema.json` and the deterministic evaluator in `agentic_commerce.action_control`.

- `dry-run-v1.example.json` demonstrates that a dry-run never consumes an approval and always returns `mayExecute: false`.
- `authorized-action-v1.example.json` demonstrates an unexpired human approval scoped to the exact action identifier, type, summary, and bounded parameters through a SHA-256 action digest.

An `authorized` decision is not proof of execution and does not perform an action. A separate adapter would need to re-check the decision at its execution boundary. This repository does not provide a transaction writer, signer, wallet integration, or live mutation API.

The examples contain public synthetic identifiers and parameters only. Do not place credentials, wallet or account data, private runtime state, internal budgets, private communications, or local paths in action requests or approvals.
43 changes: 43 additions & 0 deletions examples/action-control/authorized-action-v1.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"schemaVersion": "1.0",
"controlId": "example:control:authorized:2026-07-14",
"evaluatedAt": "2026-07-14T13:00:00Z",
"request": {
"actionId": "example:catalog-update:2026-07-14",
"actionType": "example.catalog-update",
"actionDigest": "e17e5f2954ef59e20a5cbad2c0ef7825f8aad5937c37bddfc4acc1b44cad3223",
"mode": "execute",
"summary": "Prepare a synthetic update to a public example catalog.",
"parameters": [
{
"name": "catalog",
"value": "synthetic-public-examples"
},
{
"name": "itemCount",
"value": 2
}
]
},
"approval": {
"approvalId": "example:approval:catalog-update:2026-07-14",
"actionId": "example:catalog-update:2026-07-14",
"actionType": "example.catalog-update",
"actionDigest": "e17e5f2954ef59e20a5cbad2c0ef7825f8aad5937c37bddfc4acc1b44cad3223",
"decision": "approved",
"issuedAt": "2026-07-14T12:55:00Z",
"expiresAt": "2026-07-14T13:30:00Z",
"issuerType": "human",
"note": "Synthetic approval for the public reference example only."
},
"decision": {
"status": "authorized",
"mayExecute": true,
"reasonCode": "APPROVED",
"message": "The action is authorized for a separate execution adapter."
},
"limitations": [
"Authorization is not execution; a separate adapter must perform any approved action.",
"This control record must contain public inputs only and must not contain credentials, wallet data, account identifiers, or private runtime state."
]
}
33 changes: 33 additions & 0 deletions examples/action-control/dry-run-v1.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"schemaVersion": "1.0",
"controlId": "example:control:dry-run:2026-07-14",
"evaluatedAt": "2026-07-14T13:00:00Z",
"request": {
"actionId": "example:catalog-update:2026-07-14",
"actionType": "example.catalog-update",
"actionDigest": "e17e5f2954ef59e20a5cbad2c0ef7825f8aad5937c37bddfc4acc1b44cad3223",
"mode": "dry-run",
"summary": "Prepare a synthetic update to a public example catalog.",
"parameters": [
{
"name": "catalog",
"value": "synthetic-public-examples"
},
{
"name": "itemCount",
"value": 2
}
]
},
"approval": null,
"decision": {
"status": "dry-run",
"mayExecute": false,
"reasonCode": "DRY_RUN_ONLY",
"message": "The action was evaluated only; execution is not authorized."
},
"limitations": [
"Authorization is not execution; a separate adapter must perform any approved action.",
"This control record must contain public inputs only and must not contain credentials, wallet data, account identifiers, or private runtime state."
]
}
2 changes: 2 additions & 0 deletions schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
- `../examples/source-manifest/reppo-public-api-manifest-v1.example.json` — synthetic conforming source-manifest example validated in CI.
- `agent-job-result-v1.schema.json` — bounded public result envelope for structured agent jobs, including optional cost, timeout, and freshness metadata.
- `../examples/agent-job-result/reppo-inspection-result-v1.example.json` — synthetic conforming agent-job result validated in CI.
- `action-control-v1.schema.json` — default-deny dry-run and approval-control decision contract.
- `../examples/action-control/` — synthetic dry-run and authorized-action examples validated in CI.

Versioned JSON schemas for additional safety patterns will live here.
Loading