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
2 changes: 1 addition & 1 deletion public/docs/scoped-execution-settlement.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
}</code></pre></article></div></section>
<section class="section"><div class="container grid"><article class="card"><h2>Selective disclosure</h2><p>The public receipt contains opaque references and commitments. A verifier that is authorized to see private payment details receives a disclosure package with the original payee data, private settlement metadata, and nonce/salt. VerifyAgent or another verifier hashes the disclosed data and compares it to the public <code>sha256:</code> commitment while checking the settlement attestation signature.</p></article><article class="card"><h2>VerifyAgent display</h2><p>VerifyAgent displays separate proof cards: <strong>Execution proof</strong> for the agent/runtime signature and <strong>Settlement proof</strong> for the rail/payer/settlement authority signature. A receipt can be execution-only, execution plus settlement, or invalid when a signer tries to cover fields outside its scope.</p><p style="margin-top:12px"><a class="btn btn-primary" href="/execution-receipt-demo.html">Open demo</a> <a class="btn btn-secondary" href="/verify.html">Verify paste flow</a></p></article></div></section>
<section class="section"><div class="container"><article class="card warn"><h2>Privacy warning</h2><ul class="list"><li>Do not publish <code>settlement.stealth_address</code>.</li><li>Do not publish a raw <code>0x...</code> payment transaction hash as <code>payment_ref</code>.</li><li>Use an opaque settlement reference.</li><li>Use a <code>sha256:</code> payee commitment.</li><li>Private payment linkage is verified through selective disclosure, not by exposing payment addresses or raw transaction hashes in public receipts.</li></ul></article></div></section>
<section class="section"><div class="container"><article class="card"><h2>Schema publication</h2><p>The runtime schema name is <code>clas.execution.receipt.v1</code>. Public schema sync for <code>/schemas/execution/execution.receipt.schema.json</code> is not wired in this site yet, so schema publication needs a follow-up sync. Until then, treat this page and the demo as public documentation for the receipt model.</p></article></div></section>
<section class="section"><div class="container"><article class="card"><h2>Schema publication</h2><p>The runtime schema name is <code>clas.execution.receipt.v1</code>. The public schema is available at <a href="/schemas/execution/execution.receipt.schema.json"><code>/schemas/execution/execution.receipt.schema.json</code></a>, and the execution schema manifest is available at <a href="/schemas/execution/manifest.json"><code>/schemas/execution/manifest.json</code></a>.</p></article></div></section>
</main>
<footer><div class="container footer-grid"><div><h4>Product</h4><a href="/protocol.html">Protocol</a><a href="/capabilities.html">Capabilities</a><a href="/receipts.html">Receipts</a><a href="/execution-receipt-demo.html">Execution Receipt Demo</a><a href="/proof.html">Live Proof</a><a href="/integrations.html">Integrations</a><a href="/sdk-records.html">SDK</a></div><div><h4>Developers</h4><a href="/docs.html">Docs</a><a href="/docs/wrap-your-agent.html">Wrap Your Agent</a><a href="/docs/scoped-execution-settlement.html">Scoped Execution + Settlement</a><a href="/runtime.html">Runtime</a><a href="/schemas.html">Schemas</a><a href="/api.html">API Reference</a></div><div><h4>Proof</h4><a href="/verify.html">Verifier</a><a href="/stack-proof-demo.html">Production Proof</a><a href="/receipts.html">Receipts</a><a href="/proof.html">Live Proof</a></div></div></footer>
</body>
Expand Down
96 changes: 96 additions & 0 deletions public/schemas/execution/execution.receipt.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://commandlayer.org/schemas/execution/execution.receipt.schema.json",
"title": "CLAS Execution Receipt v1",
"description": "Scoped execution and private settlement receipt for clas.execution.receipt.v1.",
"type": "object",
"additionalProperties": false,
"required": ["schema", "receipt_id", "verb", "agent", "action", "proofs"],
"properties": {
"schema": { "const": "clas.execution.receipt.v1" },
"receipt_id": { "type": "string", "minLength": 1 },
"parent_receipt_id": { "type": ["string", "null"], "minLength": 1 },
"root_receipt_id": { "type": ["string", "null"], "minLength": 1 },
"chain_id": { "type": ["string", "null"], "minLength": 1 },
"verb": { "type": "string", "minLength": 1 },
"agent": { "type": "string", "minLength": 1 },
"action": { "type": "string", "minLength": 1 },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow documented action objects in the schema

Both the scoped execution docs and the execution receipt demo model valid clas.execution.receipt.v1 receipts with action as an object containing fields like name and input_hash, but this newly published schema only accepts a non-empty string here. Consumers who fetch the public schema linked from the docs and validate those advertised receipt shapes will reject them before any proof-scope checks run, so the schema should accept the documented object shape or the examples should be changed.

Useful? React with 👍 / 👎.

"input": true,
"output": true,
"execution": {
"type": "object",
"additionalProperties": true,
"properties": {
"status": { "type": "string", "minLength": 1 },
"duration_ms": { "type": "integer", "minimum": 0 }
}
},
"settlement": {
"type": "object",
"additionalProperties": true,
"required": ["payment_ref", "payee_commitment"],
Comment on lines +29 to +31

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forbid sensitive settlement extras in public receipts

The privacy warning explicitly says not to publish fields such as settlement.stealth_address, but additionalProperties: true makes those fields schema-valid in the newly published public receipt schema. Builders using this schema as their pre-publication gate could therefore leak private payment linkage while still passing validation, so the public settlement object should be closed or explicitly reject known sensitive fields.

Useful? React with 👍 / 👎.

"properties": {
"payment_ref": { "type": "string", "minLength": 1 },
"payee_commitment": { "type": "string", "pattern": "^sha256:[A-Za-z0-9+/=_:-]+$" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Constrain payee commitments to real digests

The schema describes payee_commitment as a sha256: commitment, but this pattern accepts arbitrary non-empty base64-ish text such as sha256:not_a_digest. When a public receipt includes malformed commitment data, schema validation would still pass even though selective disclosure later cannot verify a real SHA-256 commitment, so this should enforce an actual digest format and length.

Useful? React with 👍 / 👎.

"amount": { "type": ["string", "number"] },
"currency": { "type": "string", "minLength": 1 },
"rail": { "type": "string", "minLength": 1 }
}
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"proofs": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/proof" }
Comment on lines +44 to +47

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require an execution proof before accepting receipts

Because proofs only requires one item of either proof type, a clas.execution.receipt.v1 receipt with only a settlement proof currently validates even though the documented valid states are execution-only or execution plus settlement. In that scenario, consumers using this public schema would accept an execution receipt that has no agent/runtime attestation for what actually executed, so the array should require at least one type: "execution" proof.

Useful? React with 👍 / 👎.

}
},
"$defs": {
"proof": {
"type": "object",
"additionalProperties": false,
"required": ["type", "covers", "signer_id", "signature"],
"properties": {
"type": { "enum": ["execution", "settlement"] },
"covers": {
"type": "array",
"minItems": 1,
"items": { "type": "string", "minLength": 1 }
},
"canonicalization": { "type": "string", "default": "json.sorted_keys.v1" },
"hash": {
"type": "object",
"additionalProperties": false,
"required": ["alg", "value"],
"properties": {
"alg": { "type": "string", "minLength": 1 },
"value": { "type": "string", "minLength": 1 }
}
},
"signer_id": { "type": "string", "minLength": 1 },
"signature": {
"type": "object",
"additionalProperties": false,
"required": ["alg", "value"],
"properties": {
"alg": { "type": "string", "minLength": 1 },
"kid": { "type": "string", "minLength": 1 },
"value": { "type": "string", "minLength": 1 }
}
}
},
"allOf": [
{
"if": { "properties": { "type": { "const": "execution" } }, "required": ["type"] },
"then": { "properties": { "covers": { "not": { "contains": { "const": "settlement" } } } } }
Comment on lines +86 to +87

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require execution proofs to cover execution fields

For type: "execution", this rule only prevents settlement from being covered; it still validates an execution proof whose covers is just ["receipt_id"]. In that case a receipt would pass the public schema without the agent/runtime signature covering verb, agent, or action, which undermines the documented execution attestation scope, so the execution branch should require the expected execution fields as well.

Useful? React with 👍 / 👎.

},
{
"if": { "properties": { "type": { "const": "settlement" } }, "required": ["type"] },
"then": { "properties": { "covers": { "contains": { "const": "settlement" } } } }
Comment on lines +90 to +91

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject extra settlement proof coverage

The docs describe the settlement signer as covering only receipt_id and settlement, but this rule only requires covers to contain settlement; a settlement proof with covers: ["receipt_id", "settlement", "action"] would still be schema-valid. That lets a settlement authority appear to attest execution fields despite the separate trust-boundary model, so settlement proof coverage should be constrained to the allowed fields.

Useful? React with 👍 / 👎.

}
]
}
}
}
14 changes: 14 additions & 0 deletions public/schemas/execution/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"family_id": "execution",
"family_name": "Execution Receipts",
"family_status": "live",
"version": "v1",
"schemas": [
{
"schema": "clas.execution.receipt.v1",
"kind": "receipt",
"path": "/schemas/execution/execution.receipt.schema.json",
"description": "Scoped execution receipt with optional private settlement attestation."
}
]
}
24 changes: 23 additions & 1 deletion public/schemas/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,33 @@
"family_id": "trust-verification",
"family_name": "Trust Verification v1",
"family_status": "live",
"verbs": ["verify","sign","attest","authorize","approve","reject","permit","grant","authenticate","endorse"],
"verbs": [
"verify",
"sign",
"attest",
"authorize",
"approve",
"reject",
"permit",
"grant",
"authenticate",
"endorse"
],
"request_schema_path_prefix": "/schemas/trust/",
"receipt_schema_path_prefix": "/schemas/trust/",
"manifest_path": "/capabilities/trust-verification/manifest.json",
"source_repo_url": "https://github.com/commandlayer/commandlayer-clas"
},
{
"family_id": "execution",
"family_name": "Execution Receipts v1",
"family_status": "live",
"receipt_schema_path_prefix": "/schemas/execution/",
"manifest_path": "/schemas/execution/manifest.json",
"schemas": [
"clas.execution.receipt.v1"
],
"source_repo_url": "https://github.com/commandlayer/commandlayer-clas"
}
]
}
35 changes: 23 additions & 12 deletions scripts/sync-clas-schemas.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
#!/usr/bin/env bash
set -euo pipefail

SRC_ROOT="${1:-../clas/schemas/trust-verification}"
DEST_ROOT="${2:-public/schemas/trust-verification}"
SRC_BASE="${1:-../clas/schemas}"
DEST_BASE="${2:-public/schemas}"
FAMILIES=("trust-verification" "execution")

if [[ ! -d "$SRC_ROOT" ]]; then
echo "Source directory not found: $SRC_ROOT" >&2
if [[ ! -d "$SRC_BASE" ]]; then
echo "Source directory not found: $SRC_BASE" >&2
exit 1
fi

mkdir -p "$(dirname "$DEST_ROOT")"
rm -rf "$DEST_ROOT"
mkdir -p "$DEST_ROOT"
mkdir -p "$DEST_BASE"

cp -a "$SRC_ROOT"/. "$DEST_ROOT"/
for family in "${FAMILIES[@]}"; do
src="$SRC_BASE/$family"
dest="$DEST_BASE/$family"

echo "Synced CLAS trust-verification schemas"
echo "Source: $SRC_ROOT"
echo "Destination: $DEST_ROOT"
find "$DEST_ROOT" -type f | sort
if [[ ! -d "$src" ]]; then
echo "Source family directory not found: $src" >&2
exit 1
fi

rm -rf "$dest"
mkdir -p "$dest"
cp -a "$src"/. "$dest"/

echo "Synced CLAS $family schemas"
echo "Source: $src"
echo "Destination: $dest"
find "$dest" -type f | sort
done
25 changes: 25 additions & 0 deletions tests/execution-schema-publication.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');

const schemaPath = path.join(process.cwd(), 'public', 'schemas', 'execution', 'execution.receipt.schema.json');
const manifestPath = path.join(process.cwd(), 'public', 'schemas', 'execution', 'manifest.json');
const indexPath = path.join(process.cwd(), 'public', 'schemas', 'index.json');

test('execution receipt schema is published under public schemas', () => {
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));

assert.equal(schema.properties.schema.const, 'clas.execution.receipt.v1');
assert.equal(schema.$id, 'https://commandlayer.org/schemas/execution/execution.receipt.schema.json');
assert.ok(schema.required.includes('proofs'));
});

test('execution manifest and schema index expose the execution family', () => {
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
const index = JSON.parse(fs.readFileSync(indexPath, 'utf8'));

assert.equal(manifest.family_id, 'execution');
assert.equal(manifest.schemas[0].path, '/schemas/execution/execution.receipt.schema.json');
assert.ok(index.families.some((family) => family.family_id === 'execution' && family.manifest_path === '/schemas/execution/manifest.json'));
});
Loading