Four precision primitives for multi-day, multi-agent runs.
- jouleclaw-contract: ValidationContract / Assertion / Feature /
Evidence / verify() -> ContractVerdict. Authored before code,
lives independently of implementation. Typed coverage matrix
with per-assertion rollup; must-have gaps block ship.
- jouleclaw-graph: RunEvent::HandoffRecorded variant +
WorkerHandoffEvent + HandoffCommand (BLAKE3 over NUL-joined
argv). Forces every agent to write down what happened; hash
chain protects against post-hoc edits.
- jouleclaw-mission: three-role Mission { contract, run,
evidence } with async Worker trait. Orchestrator authors,
Worker does, Validator judges. Serial-by-default dispatch;
validate() is a pure function of (contract, evidence).
- jouleclaw-hydra-client: ValueReport companion to CallReport.
Tracks closure rate (delivered / attempted) per call;
mean_closure_rate aggregates across a run. The activity-vs-
value gap closed at the dispatch layer.
Spec gains normative sections 16 (contract) / 17 (handoff) /
18 (mission) / 19 (value report). Vocab v1.jsonld + v1.ttl +
v1.shapes.ttl extended with the new classes, enumerations,
properties, and SHACL shapes.
Drive-by: jouleclaw-stack had jouleclaw-prov as a dev-dep while
using it in library code; promoted to [dependencies].
Tests: contract 17/17, graph 40/40 (+2 new), mission 6/6,
hydra-client 20/20 (+4 new). Two runnable examples
(missions_pass, three_role_demo).
Co-Authored-By: Claude Opus 4.7 <[email protected]>
213 lines
13 KiB
Turtle
213 lines
13 KiB
Turtle
@prefix jc: <https://jouleclaw.transaction.science/vocab/v1#> .
|
|
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
# JouleClaw v1 SHACL shapes
|
|
#
|
|
# Validates JouleClaw wire forms (cascade Receipt, PolicyReceipt,
|
|
# WorkspaceManifest, AgentIdentity, Action, Decision) against the
|
|
# v1 vocabulary. Any SHACL validator (pyshacl, Apache Jena, the
|
|
# bundled jouleclaw-shacl Rust validator) accepts this shape graph
|
|
# as input alongside a candidate document and returns sh:conforms
|
|
# plus a list of violations.
|
|
#
|
|
# The shapes use only the SHACL Core subset, no SPARQL constraints,
|
|
# so the lightweight validator in jouleclaw-shacl covers them
|
|
# without a SPARQL engine.
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
# ─── Cascade Receipt (schema "1") ────────────────────────────────────
|
|
|
|
jc:ReceiptShape a sh:NodeShape ;
|
|
sh:targetClass jc:Receipt ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "1" ) ] ;
|
|
sh:property [ sh:path jc:receiptId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:closedAt ; sh:datatype xsd:dateTime ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:inputHash ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] ;
|
|
sh:property [ sh:path jc:tier ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:Cache jc:Lawful jc:Embed jc:Model jc:Wire ) ] ;
|
|
sh:property [ sh:path jc:joulesMicrojoules ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:energyProvenance ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:HwShunt jc:ModelBased jc:Estimator ) ] ;
|
|
sh:property [ sh:path jc:steward ; sh:nodeKind sh:IRI ; sh:maxCount 1 ] .
|
|
|
|
# ─── Policy Receipt (schema "policy/1") ──────────────────────────────
|
|
|
|
jc:PolicyReceiptShape a sh:NodeShape ;
|
|
sh:targetClass jc:PolicyReceipt ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "policy/1" ) ] ;
|
|
sh:property [ sh:path jc:receiptId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:closedAt ; sh:datatype xsd:dateTime ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:steward ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:engineId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:auditSequence ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:policyVersion ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:agent ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:action ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:node jc:ActionShape ] ;
|
|
sh:property [ sh:path jc:decision ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:node jc:DecisionShape ] .
|
|
|
|
# ─── Action (filesystem / network / process) ─────────────────────────
|
|
|
|
jc:ActionShape a sh:NodeShape ;
|
|
sh:targetClass jc:Action ;
|
|
sh:property [ sh:path jc:kind ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:FsAction jc:NetAction jc:ProcAction ) ] .
|
|
|
|
jc:FsActionShape a sh:NodeShape ;
|
|
sh:targetClass jc:FsAction ;
|
|
sh:property [ sh:path jc:path ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:fsMode ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:FsRead jc:FsWrite jc:FsExecute jc:FsList ) ] .
|
|
|
|
jc:NetActionShape a sh:NodeShape ;
|
|
sh:targetClass jc:NetAction ;
|
|
sh:property [ sh:path jc:host ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:port ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:minInclusive 0 ; sh:maxInclusive 65535 ] ;
|
|
sh:property [ sh:path jc:netMethod ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:NetConnect jc:NetListen jc:NetResolve ) ] .
|
|
|
|
jc:ProcActionShape a sh:NodeShape ;
|
|
sh:targetClass jc:ProcAction ;
|
|
sh:property [ sh:path jc:binary ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:argv ; sh:nodeKind sh:Literal ] .
|
|
|
|
# ─── Decision (Allow / Deny) ─────────────────────────────────────────
|
|
|
|
jc:DecisionShape a sh:NodeShape ;
|
|
sh:targetClass jc:Decision ;
|
|
sh:property [ sh:path jc:kind ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:Allow jc:Deny ) ] .
|
|
|
|
jc:AllowShape a sh:NodeShape ;
|
|
sh:targetClass jc:Allow ;
|
|
sh:property [ sh:path jc:rule ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] .
|
|
|
|
jc:DenyShape a sh:NodeShape ;
|
|
sh:targetClass jc:Deny ;
|
|
sh:property [ sh:path jc:reason ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( "no_matching_allow" "explicit_deny" ) ] ;
|
|
sh:property [ sh:path jc:rule ; sh:datatype xsd:string ; sh:maxCount 1 ] .
|
|
|
|
# ─── Workspace Manifest (schema "workspace/1") ───────────────────────
|
|
|
|
jc:WorkspaceManifestShape a sh:NodeShape ;
|
|
sh:targetClass jc:WorkspaceManifest ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( "workspace/1" ) ] ;
|
|
sh:property [ sh:path jc:owner ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:node jc:AgentIdentityShape ] ;
|
|
sh:property [ sh:path jc:entries ; sh:node jc:WorkspaceEntryShape ] .
|
|
|
|
jc:WorkspaceEntryShape a sh:NodeShape ;
|
|
sh:targetClass jc:WorkspaceEntry ;
|
|
sh:property [ sh:path jc:path ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[^/].*$" ] ;
|
|
sh:property [ sh:path jc:contentHash ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] ;
|
|
sh:property [ sh:path jc:size ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:kind ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:Blob jc:Text jc:Structured ) ] .
|
|
|
|
# ─── Agent Identity (did:key + Ed25519) ──────────────────────────────
|
|
|
|
jc:AgentIdentityShape a sh:NodeShape ;
|
|
sh:targetClass jc:AgentIdentity ;
|
|
sh:property [ sh:path jc:handle ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^did:key:z[1-9A-HJ-NP-Za-km-z]+$" ] ;
|
|
sh:property [ sh:path jc:publicKey ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] .
|
|
|
|
# ─── Tool Touch + Claim Provenance ───────────────────────────────────
|
|
|
|
jc:ToolTouchShape a sh:NodeShape ;
|
|
sh:targetClass jc:ToolTouch ;
|
|
sh:property [ sh:path jc:toolId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:joulesMicrojoules ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:energyProvenance ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:HwShunt jc:ModelBased jc:Estimator ) ] .
|
|
|
|
jc:ClaimProvenanceShape a sh:NodeShape ;
|
|
sh:targetClass jc:ClaimProvenance ;
|
|
sh:property [ sh:path jc:source ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:contentHash ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] ;
|
|
sh:property [ sh:path jc:fetchedAt ; sh:datatype xsd:dateTime ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:trustTier ; sh:datatype xsd:nonNegativeInteger ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:minInclusive 0 ; sh:maxInclusive 10 ] .
|
|
|
|
# ─── Validation Contract (schema "contract/1") ───────────────────────
|
|
# Planning artifact a multi-step mission is judged against. Assertions
|
|
# carry a stable id, a priority, and a check kind; features claim
|
|
# assertion ids; the verifier mechanically computes the coverage matrix.
|
|
|
|
jc:ValidationContractShape a sh:NodeShape ;
|
|
sh:targetClass jc:ValidationContract ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( "contract/1" ) ] ;
|
|
sh:property [ sh:path jc:title ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:authoredBy ; sh:datatype xsd:string ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:assertions ; sh:node jc:AssertionShape ; sh:minCount 1 ] ;
|
|
sh:property [ sh:path jc:features ; sh:node jc:FeatureShape ] .
|
|
|
|
jc:AssertionShape a sh:NodeShape ;
|
|
sh:targetClass jc:Assertion ;
|
|
sh:property [ sh:path jc:assertionId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:title ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:priority ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:MustHave jc:ShouldHave jc:NiceToHave ) ] ;
|
|
sh:property [ sh:path jc:check ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:node jc:AssertionCheckShape ] .
|
|
|
|
jc:AssertionCheckShape a sh:NodeShape ;
|
|
sh:targetClass jc:AssertionCheck ;
|
|
sh:property [ sh:path jc:kind ; sh:nodeKind sh:IRI ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( jc:ToolCheck jc:ArtifactCheck jc:CommandCheck jc:CheckerCheck ) ] .
|
|
|
|
jc:FeatureShape a sh:NodeShape ;
|
|
sh:targetClass jc:Feature ;
|
|
sh:property [ sh:path jc:featureId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:title ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:claims ; sh:datatype xsd:string ] .
|
|
|
|
jc:ContractVerdictShape a sh:NodeShape ;
|
|
sh:targetClass jc:ContractVerdict ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( "verdict/1" ) ] ;
|
|
sh:property [ sh:path jc:contractHash ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] ;
|
|
sh:property [ sh:path jc:passed ; sh:datatype xsd:boolean ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:summary ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] .
|
|
|
|
# ─── Worker Handoff (schema "handoff/1") ─────────────────────────────
|
|
# Structured wire type that forces an agent to write down what
|
|
# actually happened: what got done, what was left undone, which
|
|
# commands ran with what exit codes, what issues were discovered,
|
|
# and which procedures were followed. The journal carries it as
|
|
# a HandoffRecorded event.
|
|
|
|
jc:WorkerHandoffShape a sh:NodeShape ;
|
|
sh:targetClass jc:WorkerHandoff ;
|
|
sh:property [ sh:path jc:schemaId ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:in ( "handoff/1" ) ] ;
|
|
sh:property [ sh:path jc:worker ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:featureId ; sh:datatype xsd:string ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:closedAt ; sh:datatype xsd:dateTime ; sh:minCount 1 ; sh:maxCount 1 ] ;
|
|
sh:property [ sh:path jc:completed ; sh:datatype xsd:string ] ;
|
|
sh:property [ sh:path jc:undone ; sh:datatype xsd:string ] ;
|
|
sh:property [ sh:path jc:issuesFound ; sh:datatype xsd:string ] ;
|
|
sh:property [ sh:path jc:proceduresFollowed ; sh:datatype xsd:string ] ;
|
|
sh:property [ sh:path jc:commands ; sh:node jc:HandoffCommandShape ] .
|
|
|
|
jc:HandoffCommandShape a sh:NodeShape ;
|
|
sh:targetClass jc:HandoffCommand ;
|
|
sh:property [ sh:path jc:commandHash ; sh:datatype xsd:string ; sh:minCount 1 ; sh:maxCount 1 ;
|
|
sh:pattern "^[a-f0-9]{64}$" ] ;
|
|
sh:property [ sh:path jc:argv ; sh:datatype xsd:string ] ;
|
|
sh:property [ sh:path jc:exitCode ; sh:datatype xsd:integer ; sh:minCount 1 ; sh:maxCount 1 ] .
|