Specification + Parser path
- Front end = Specification. Backend = Parser and Executors.
What this means
- Specification (Spec) is a human and machine readable contract that defines Intents, Capabilities, Policies, Offers, Receipts, and message envelopes.
- Parser ingests a spec and generates runtime artifacts such as validators, codecs, routers, and negotiation logic.
Components
- Spec authoring format: JSON Schema or JSON-LD contexts with content addressing.
- Spec registry: CAS that stores versioned schemas and extension packs.
- Spec parser: builds parsers, type definitions, validators, and stubs.
- Runtime bindings: codegen for Python, Go.
- Policy hooks: pre, run, post evaluation stages.
- Verification suite: signature and hash checkers for all objects.
Developer workflow
- Author or import a spec for a domain capability.
- Run the parser to generate types, validators, and wire bindings.
- Implement capability logic behind the generated interface.
- Publish AdvertiseCapability with schema hashes.
- Verify Receipts with parser-generated checkers.
Strengths
- Strong correctness from codegen and validation.
- Rapid adoption by existing teams that prefer API like ergonomics.
- Predictable interop because schemas are explicit and versioned.
Tradeoffs
- Slower evolution when many specs must be updated together.
- Heavier governance for schema changes.
- Expressiveness limited by the schema language chosen.
Example
- Spec fragment for a capability:
{
"$id": "pl.schema/Capability.v1", // schema identifier
"type": "object", // this is an object schema
"properties": {
"id": { "type": "string" }, // capability identifier
"provider": { "type": "string" }, // capability provider
"io": {
"type": "object",
"properties": {
"input": { "type": "array" }, // inputs required
"output": { "type": "array" } // outputs produced
},
"required": ["input", "output"]
}
},
"required": ["id", "provider", "io"]
}
- Parser output: language bindings, a validator, and a negotiation stub that checks IO types, price, SLOs, and policy references.
Where this shines
- Regulated domains with heavy compliance.
- Large vendors that want stability and long term support.
- Interop programs between known counterparties.
DSL + Workflow path
- Front end = Domain Specific Language. Backend = Workflow Engine.
What this means
- DSL is a concise language to express Intents, Plans, Policies, and selection logic.
- Workflow engine compiles DSL to a Task DAG, performs discovery and negotiation, and executes with Receipts.
Components
- Pervasive DSL: minimal syntax for goals, constraints, utility, policy bindings, and feature flags.
- Planner: expands goals into a DAG with bindable capability slots.
- Scheduler: selects providers using trust, policy, cost, and SLO scores.
- State store: event log and memory.
- Verifiers: receipt and attestation checkers.
- Policy Engine: evaluates portable policy objects during planning and at runtime.
DSL sketch
goal: SummarizeDocument
inputs:
doc: cid:doc-123
constraints:
length: "<400w"
deadline: "PT30S"
policy:
require: [cid:pol-PII-no-exfil]
select:
optimize: [readability:0.6, coverage:0.4, price:0.2]
plan:
- map: FetchSections(doc)
- map: Summarize(section)
- reduce: MergeSummaries()
- join: AttachReferences()
Strengths
- High expressiveness for composition and planning.
- Fast iteration since plans evolve without schema releases.
- Good for high flux, evolving and open ended workflows.
Tradeoffs
- Higher runtime complexity in planner and scheduler.
- More moving parts for observability and debugging.
- Requires guardrails to keep DSL safe and predictable.
Where this shines
- Cross domain workflows with frequent change.
- Agent marketplaces and open ecosystems.
- Experimental planning and federated operators.
Interop between the two paths
- You can mix both paths in one network.
- Spec to DSL: a generator emits DSL stubs from specs. The DSL then composes these stubs into plans.
- DSL to Spec: stabilized DSL patterns can be frozen into new spec schemas for high assurance use.
- Common substrate: envelopes, identity, attestations, receipts, and policies are identical in both paths.
- Dual discovery: capability descriptors reference both schema ids and optional DSL signatures.
Choosing a path: decision matrix
Context | Prefer Spec + Parser | Prefer DSL + Workflow |
---|---|---|
Compliance heavy | Yes | Maybe |
Rapid iteration | Maybe | Yes |
Many independent vendors | Yes | Yes |
Evolving / Experimental | Maybe | Yes |
Tooling maturity needed | Yes | Maybe |
Complex composition | Maybe | Yes |
Governance and versioning
Spec path
- Version contracts: v1, v1.1 with strict compatibility rules.
- Change control: proposals, review, and test vectors.
- Deprecation: sunset schedules with auto negotiation.
DSL path
- Language stability tiers: core stable, experimental extensions.
- Capability libraries: published DSL macros with hashes.
- Feature flags: negotiate exact sets per Offer.
Security model alignment
- Both paths use the same envelope security: signatures, nonces, replay limits, and content hashes.
- Spec path prefers static allowlists and formal verification of schemas.
- DSL path prefers sandboxed planners, policy guards, and taint tracking during plan expansion.
Performance and scaling
Spec path
- Lower overhead per call, strong caching by schema id.
- Best for hot paths like inference or CRUD style ops.
DSL path
- Optimizes across the whole DAG.
- Good for map, reduce, join, and cross provider execution.
Concrete example end to end
Spec capability:
{
"id":"cid:cap-summarize-v1",
"schema":"pl.schema/Capability.v1",
"provider":"did:agent:B",
"io":{"input":[{"type":"text/plain"}],"output":[{"type":"text/markdown"}]},
"policy_requirements":["cid:pol-PII-no-exfil"]
}
DSL plan that composes it:
goal: BriefingPack
inputs: { docs: [cid:d1, cid:d2, cid:d3] }
plan:
- map: SummarizeDocument(docs[*]) using cid:cap-summarize-v1
- reduce: MergeSummaries()
- join: AttachCitations()
policy:
require: [cid:pol-PII-no-exfil]
select:
optimize: [latency:0.5, price:0.3, quality:0.2]
The workflow engine discovers providers for cid:cap-summarize-v1, negotiates Offers, executes map tasks, verifies Receipts, reduces, joins, and emits a final Receipt tied to the same trace.