Neuro-symbolic runtime
Target architecture for OpenCradle as a neuro-symbolic runtime — agents propose, the runtime validates, policies permit, tools execute, verifiers confirm.
This document mixes current state with target architecture. Every section labels which is which, and "Current state" below is kept accurate as the code moves. Phases 1-3 are implemented; the ontology and semantic reasoning layers (§8, §9, Phases 4 and 6) are not.
1. Executive summary
OpenCradle is moving from "an on-premise platform that runs agents" to a controlled execution layer that sits between probabilistic agents and the systems they can affect.
The loop:
- agents generate proposals — candidate actions, plans and facts;
- the runtime evaluates those proposals against typed contracts;
- symbolic rules (policies, permissions, domain constraints) determine what may execute;
- tools execute and produce observations;
- verifiers determine whether the intended state transition actually occurred;
- everything is recorded as evidence with provenance.
Three separations carry the whole design:
A proposal is not a decision. Tool output is not verified truth. Execution success is not outcome verification.
This does not make a language model deterministic. It makes the consequences of a language model's output governed by explicit, inspectable rules.
Current state
Phases 1-3 of the roadmap in §19 are implemented, plus a first domain pack. What exists in the Cradle codebase:
| Capability | Where | Section |
|---|---|---|
Proposal / Decision / Observation / Verification as typed, persisted entities | src/core/runtime/ | §4 |
| Hash-chained append-only audit ledger, with tamper detection | src/core/runtime/audit.ts | §14 |
| Deterministic pre-execution gate: registration, blast-radius match, scopes, environment, idempotency | src/core/runtime/policy.ts | §6 |
| Tool registry — an unregistered tool is not callable | src/core/runtime/registry.ts | §6 |
| Single chokepoint for side effects, over MCP and over plain HTTP | src/core/runtime/gateway.ts | §16 |
HumanApproval with scope, expiry, single use, no self-approval | src/core/runtime/approvals.ts | §15 |
Post-execution verification, compensation, StateTransition | src/core/runtime/verification.ts | §6, §13 |
| First domain pack: three-valued evaluation of EAEU rules | src/domains/hs-router/ | §10, §11 |
| Two-tier risk assessment, operator inbox, scoped API keys, RAG citations | pre-existing triage engine | — |
What does not exist yet: the execution ontology as a vocabulary or graph (§9 and Phase 4 are untouched); RDF, OWL or SHACL anywhere (§8, Phase 6); a domain-pack manifest format and versioned distribution; rollback in the sense of restoring a snapshot — only compensation through a tool the provider offers.
Two limits worth stating plainly. The verifier registry ships empty: the
engine runs, but concrete verifiers arrive with domain packs, so an action
declaring postconditions today ends inconclusive and aborts. And the gateway
binds only the callers that use it — the agent tool-use loop goes through it,
one background sync still does not.
The pre-existing risk gate governs replies to humans. The runtime added here governs actions against systems; the two are not yet unified.
2. Problem statement
Agent systems built on language models share a set of failure modes that prompt engineering cannot remove:
- Probabilistic output. The same input can produce different actions.
- Prompts are not enforceable policies. An instruction in a system prompt is a suggestion the model may follow; it is not a constraint the system imposes.
- Schema-valid does not mean semantically valid. A perfectly typed
{"refund_amount": 480000}can still be a catastrophic business decision. - Hidden side effects. A tool may write more than its name implies.
- Stale state. The context an agent reasoned over may no longer describe the world at the moment of execution.
- Unauthorized actions. The identity that reasoned is not necessarily the identity permitted to act.
- Non-idempotent retries. A retried "create invoice" produces two invoices.
- Misread tool results.
200 OKis not "the thing I wanted happened". - Missing evidence. A conclusion with no traceable source cannot be audited or contested.
- No postcondition check. Most agent frameworks stop at "the tool did not throw", which is not a statement about the world.
Logs do not solve this. A log tells you what was called. It does not tell you whether the call was permitted, or whether its intended effect holds.
3. Design principles
- Agents propose; the runtime disposes. Generation and authorization are different subsystems.
- No uncontrolled side effects. Every effect goes through a gateway that knows its risk class.
- Separate reasoning from authorization. A model must never be the component that decides it is allowed.
- Validate before execution. Structure, identity, policy, preconditions.
- Verify after execution. Independently, against the target system.
- Every consequential claim needs evidence. Source, time, actor.
- Every state transition must be attributable. To a decision, and through it to an identity.
- Domain rules live outside prompts. In code, policies or constraint models — versioned and testable.
- Human approval is a first-class runtime object, not an escape hatch.
- Uncertainty is represented explicitly. Confidence,
unknown,needs_clarificationare legitimate values. - Failure has more than one shape. Reject, repair, retry, compensate, escalate.
- Local deployment and semantic safety are separate concerns. Running on your own hardware controls where data lives. It says nothing about whether an action was correct or authorized.
4. Core runtime model
Target architecture.
Agent · Task · Intent · Proposal · Plan · Action · Tool
Observation · Fact · Evidence
Policy · Permission · Constraint · Decision
Verification · StateTransition · HumanApproval · AuditEventEntities
Agent — an addressable reasoning unit. Fields: id, role, skills,
model_ref, permitted_scopes. Relations: proposes Proposals. Example: the
triage-support agent backed by a 7B local model.
Task — a unit of work with an origin. Fields: id, origin, input_ref,
status, deadline. Example: an inbound Telegram message.
Intent — the normalized interpretation of what is wanted. Fields: id,
task_id, intent_type, slots, confidence. Example:
refund_request{order_id: "A-119", amount: null}.
Proposal — an agent's candidate action, explicitly probabilistic. Fields:
id, task_id, agent_id, action, candidate_facts, evidence_refs,
confidence, alternatives. A Proposal never executes on its own.
Plan — an ordered set of Proposals with dependencies. Fields: id,
steps, ordering_constraints, abort_policy.
Action — the concrete operation a Proposal asks for. Fields: action_type,
target, arguments, side_effect_class, idempotency_key.
Tool — a registered capability with a declared contract. Fields: id,
version, input_schema, output_schema, side_effect_class,
required_scopes, supports_dry_run.
Observation — raw output from a tool or external system. Fields: id,
execution_id, tool_id, raw_ref, observed_at, reported_side_effects.
An Observation is data, not truth.
Fact — a normalized assertion the system has accepted. Fields: id,
subject, predicate, object, source_ref, asserted_at, confidence,
verification_status. A Fact is always attributable.
Evidence — the material backing a Fact or a Decision. Fields: id,
kind (document chunk, API response, screenshot, test run), content_ref,
hash, collected_at, collector.
Policy — a rule about what may happen. Fields: id, version, scope,
rule_ref, effect, obligations. Example: "any irreversible action in
production requires HumanApproval."
Permission — a grant binding an identity to actions on resources.
Fields: subject, action_type, resource_selector, conditions.
Constraint — a domain-level invariant. Fields: id, domain_pack,
expression, severity. Example: "an HS classification must reference at
least one currently valid legal source."
Decision — the runtime's verdict on a Proposal. Fields: id,
proposal_id, verdict, reasons, policy_results, required_actions,
decided_at, decided_by, policy_version. A Decision is the only thing
that authorizes execution.
Verification — a check that an expected state holds, performed
independently of the tool that claimed it. Fields: id, execution_id,
checks, status, evidence_refs.
StateTransition — a committed change to a resource. Fields: id,
resource_ref, from_state, to_state, decision_id, verification_id,
committed_at.
HumanApproval — an authorization act by a person. See §15.
AuditEvent — an append-only record of anything consequential. Fields:
id, kind, subject_ref, actor, at, payload_hash, prev_hash.
The distinctions that matter
| What it is | What it is not | |
|---|---|---|
| Proposal | Probabilistic suggestion from an agent | An authorization to act |
| Decision | Verdict from policies, permissions, constraints | A model's self-assessment |
| Observation | Raw data returned by a tool | A verified fact |
| Fact | Normalized assertion, attributed and dated | Ground truth |
| Evidence | Material supporting a Fact or Decision | An explanation |
| Verification | Independent check that a state holds | A successful tool return |
5. Execution lifecycle
Target architecture.
Receive input
→ Normalize context
→ Generate proposal
→ Validate proposal schema
→ Resolve identity and permissions
→ Evaluate policies
→ Check domain constraints
→ Build execution decision
→ Request human approval when required
→ Execute tool
→ Capture observation
→ Normalize candidate facts
→ Validate semantic consistency
→ Verify postconditions
→ Commit state transition
→ Emit audit event
→ Return resultEvery step can end the run. The possible outcomes:
| Step | Possible outcomes |
|---|---|
| Normalize context | proceed · clarify (context incomplete) · deny (stale beyond tolerance) |
| Generate proposal | proceed · clarify · escalate (no viable proposal) |
| Validate schema | allow · repair (return typed errors to the agent, bounded retries) · deny |
| Identity + permissions | allow · deny · escalate |
| Evaluate policies | allow · deny · require_approval · allow-with-obligations |
| Domain constraints | allow · repair · clarify (missing facts) · deny |
| Human approval | approved · rejected · changes_requested · expired |
| Execute tool | observation · error · timeout (→ retry if idempotent, else escalate) |
| Verify postconditions | verified · failed (→ compensate / rollback / escalate) · inconclusive |
| Commit transition | committed · aborted |
Two rules constrain the table: repair loops must be bounded (a fixed retry
budget, after which the outcome is escalate), and inconclusive is not
verified — it must never silently commit.
6. Two-gate architecture
Target architecture.
Gate 1 — pre-execution
Runs after a proposal exists and before any tool is touched.
class ExecutionProposal(BaseModel):
agent_id: str
task_id: str
action_type: str
target: ResourceRef
arguments: dict
evidence_refs: list[str]
confidence: float | None
idempotency_key: strChecks, in order of cost:
- Structural validation — schema, required fields, types, ranges, enums.
- Identity resolution — which subject is acting, on whose behalf.
- Authorization — does that subject hold a Permission for this action on this resource.
- Policy evaluation — organizational and environmental rules.
- Domain preconditions — constraints from the active domain pack.
- Evidence requirements — does this action class require supporting evidence, and is it present and fresh.
- Approval requirements — derived from risk level and side-effect class.
- Risk classification — Cradle's existing L1/L2 risk system generalised from "reply risk" to "action risk".
- Cost and rate limits — per task, per agent, per tenant, per window.
- Target environment — is
productioneven in scope for this run. - Idempotency — has this
idempotency_keyalready produced an effect.
Output is a RuntimeDecision, not a boolean.
Gate 2 — post-execution
Runs after the tool returns, before the transition is committed.
- Tool output schema — does the result match the declared contract.
- Expected resource existence — the thing that should now exist, does.
- Expected state — the resource is in the state the action requested.
- Domain invariants — the domain model is still internally consistent.
- No forbidden side effects — nothing outside the declared blast radius changed.
- Observation freshness — the verifying read is recent enough to matter.
- Evidence completeness — the claim is backed.
- Postconditions — the formal conditions attached to the action hold.
- Compensating action availability — if verification fails, is there a path back.
Critical: the verifier should read from an independent source wherever possible — not the same call that performed the write.
Post-validation does not make an irreversible action safe. If the tool has already burned the effect, Gate 2 can only tell you that you have a problem.
Which is why the architecture prefers, in order:
dry run → prepare / commit → transaction → staged write →
idempotency key → reversible action → compensation → approval before commit.
"Pure tool, no side effects" is a useful ideal. Real integrations — payment providers, email, deployments, third-party APIs — often cannot offer it. The architecture must be honest about that rather than assume it away.
7. Symbolic layer
Target architecture. The symbolic layer is deliberately plural. It is not one technology.
Schemas
Pydantic, JSON Schema, TypeScript types, Zod, typed domain models. These answer "is this well-formed?" They do not answer "is this right?"
Policy engine
Authorization, organizational policy, environment rules, action permissions, budget and risk controls. Candidate implementations: Open Policy Agent, Cedar, JSON Logic, or a small declarative policy format native to Cradle. No technology choice should be made before an audit of the current stack — Cradle is TypeScript/Node, which makes an embeddable evaluator more attractive than a sidecar.
Ontology and knowledge graph
RDF/RDFS, OWL, SHACL, property graphs, or plain relational modelling. The distinctions:
- an ontology defines classes, relations and constraints;
- a knowledge graph stores concrete entities and their relations;
- a reasoner infers consequences and detects contradictions;
- a validation engine checks whether data conforms to shapes.
These are four different jobs. Conflating them is the most common way ontology projects fail.
Domain validators
Ordinary code stays legitimate and is often the right answer: tax calculations, HS classification algorithms, threshold rules, date arithmetic, external authority lookups, transactional invariants. Do not try to express everything as axioms.
8. OWL, RDFS and SHACL — pragmatically
RDF represents knowledge as triples: subject → predicate → object.
RDFS defines a basic vocabulary: classes, subclasses, properties, domain, range.
OWL adds logical axioms: disjoint classes, cardinality, equivalence, inverse / transitive / symmetric / asymmetric / functional properties.
SHACL validates concrete data graphs: required properties, cardinality, datatypes, value ranges, graph shapes, custom messages.
The limitation that shapes our design:
OWL reasoners generally operate under the open-world assumption. The absence of a fact does not mean the fact is false. "No permit is recorded" is not "no permit exists".
Operational business logic is almost always closed-world: if the permit is not in the system, the action does not proceed. So OWL should not be presented as a universal business rule engine. For operational validation, prefer SHACL, a policy engine, database constraints, and application validators. Reserve OWL for what it is genuinely good at: classification, subsumption, consistency checking over a curated vocabulary.
9. Universal execution ontology
Target architecture. Cradle's own vocabulary — domain-independent, describing agent execution itself.
Agent proposes Proposal
Proposal contains Action
Action targets Resource
Action invokes Tool
Action requires Permission
Action isGovernedBy Policy
Policy evaluates Context
Tool produces Observation
Observation supports Fact
Fact isSupportedBy Evidence
Decision evaluates Proposal
Verification checks StateTransition
StateTransition changes ResourceState
HumanApproval authorizes Decision
AuditEvent records RuntimeEventConstraints over that vocabulary:
- every executed Action must reference a Decision with verdict
allow; - high-risk and irreversible Actions must reference a HumanApproval;
- every committed StateTransition must reference a Verification;
- every verified Fact must reference Evidence or a trusted source;
- an Observation may never be treated as a verified Fact;
- denied Proposals must never reach execution;
- the executing identity must equal the identity authorized by the Decision;
- repeated execution with the same
idempotency_keymust not duplicate effects.
Note that these constraints are checkable without any RDF. They are integrity rules over runtime records. A graph representation is one possible implementation, not a prerequisite.
10. Domain packs
Target architecture. The execution ontology is universal. Domain knowledge plugs in on top.
domain-pack/
manifest.yaml
ontology/
schemas/
policies/
validators/
tools/
verifiers/
examples/
tests/id: customs.hs-router
name: Customs and HS Classification
version: 0.1.0
entities:
- Product
- HSCode
- RegulatoryRule
- Permit
- Authority
- LegalSource
policies:
- source-priority
- restricted-goods-routing
- missing-attribute-escalation
verifiers:
- hs-code-exists
- legal-source-current
- required-permit-resolutionA pack is versioned, testable in isolation, and every Decision records which pack version produced it.
Candidate packs: customs and trade (products, HS codes, classification rules, permits, restrictions, authorities, legal sources), infrastructure and software quality (services, incidents, deployments, commits, environments, tests, approvals, rollback rules), healthcare (patients, observations, clinical actions, contraindications, roles, consent, escalation).
Domain packs demonstrate the architecture. They do not authorize the system to make legally or medically consequential decisions autonomously. Those domains impose their own regulatory requirements on top of anything the runtime provides.
11. Worked example — HS Router
- OCR extracts a goods description from a shipping document.
- An LLM normalizes it into structured product attributes.
- Attributes become candidate facts, each with a source reference.
- A candidate generator proposes several HS codes.
- Classification rules (ordinary code) test the distinguishing attributes.
- If required attributes are missing, the Decision is
needs_clarification— not a guess. - Legal sources are checked in priority order and for currency.
- Permits and restrictions are resolved from the regulatory model.
- The final Decision carries evidence and provenance.
- An LLM writes the human-readable explanation — and cannot alter the formal decision.
{
"proposal": {
"product_type": "unmanned_aerial_vehicle",
"candidate_hs_codes": ["8806.21", "8806.22"],
"confidence": 0.78
},
"decision": {
"status": "needs_clarification",
"missing_facts": [
"maximum_takeoff_weight",
"maximum_range"
],
"permitted_to_finalize": false
}
}Five stages stay separate: extraction, normalization, classification, regulatory evaluation, explanation. Collapsing them into one prompt is exactly the failure this architecture exists to prevent.
12. Worked example — UptimeHarbor
- Monitoring detects a failure.
- An agent proposes a diagnosis.
- The agent proposes a code or infrastructure change.
- Gate 1 validates repository, target environment and permissions.
- The change runs in an isolated environment.
- Tests and browser checks produce observations.
- A verifier checks whether the original incident is resolved.
- Production deployment requires an explicit policy decision and, if configured, human approval.
- Post-deploy verification checks service health and user-facing behaviour.
- Failed verification triggers rollback or escalation.
The formal rules that make this different from a CI pipeline with an LLM attached:
- test success ≠ incident resolution;
- staging verification does not authorize production deployment;
- production must not run an unverified commit;
- a deployment result must be verified from an independent source;
- the same incident must not spawn duplicate conflicting fixes.
13. Side-effect model
Target architecture. Every Tool declares a side_effect_class, and the class
determines the required controls.
| Class | Required controls |
|---|---|
| Pure computation | Automatic execution allowed. Audit optional. |
| Read-only observation | Permission check and audit required. |
| Reversible mutation | Preconditions, idempotency key, rollback path. |
| Compensatable mutation | All of the above plus a registered compensation plan. |
| Irreversible mutation | Human approval and strong post-verification; dry-run first where the provider supports it. |
Misdeclaring a class is a serious defect: the runtime's guarantees are only as good as the tool registry's honesty. Tool contracts should be reviewed like security boundaries.
14. Trust and provenance
Every consequential result carries:
source · actor · timestamp · model and version · tool and version ·
policy version · ontology / domain-pack version · input hash · output hash ·
evidence_refs · verification_status · confidence where meaningful
The audit ledger must be append-only, or otherwise protected against
silent modification — hash chaining (prev_hash per event) is the cheapest
credible mechanism and works on the existing SQLite storage.
Version fields are not bureaucracy. When a policy changes, you must still be able to explain a decision made last quarter under the rules that applied then.
15. Human-in-the-loop
A human is not a fallback for when the machine fails. Approval is a runtime object with its own lifecycle.
{
"approval_id": "approval_123",
"decision_id": "decision_456",
"approver_id": "user_789",
"scope": "production_deployment",
"status": "approved",
"expires_at": "2026-08-01T12:00:00Z"
}Supported forms: approve · reject · request changes · approve once · approve within scope · approve until expiration.
Cradle's existing operator inbox is the seed of this. The work is to generalise it from "approve a reply" to "approve a Decision", and to make scope and expiry explicit.
16. Proposed component architecture
Target architecture — logical components. Early on, these are modules in one application, not microservices.
- Agent Gateway — entry point for agent runs
- Context Resolver — assembles and freshness-stamps context
- Proposal Service — creates and stores Proposals
- Schema Validator — structural validation
- Identity and Permission Resolver — who is acting, on whose behalf
- Policy Engine — evaluates policies against context
- Domain Constraint Engine — pluggable: validators, SHACL, reasoners
- Ontology Registry — vocabulary versions
- Domain Pack Registry — pack discovery, loading, versioning
- Tool Gateway — the single chokepoint for all side effects
- Execution Sandbox — isolated execution for risky actions
- Observation Store — raw tool output
- Evidence Store — content-addressed artifacts
- Verification Engine — postcondition checks
- State Transition Manager — commit / abort
- Approval Service — human approvals
- Audit Ledger — append-only event log
- Repair Loop — bounded correction cycles
- Runtime API and SDK — the public contract
The single most valuable of these is the Tool Gateway. Without one chokepoint for side effects, every other guarantee is advisory.
17. Suggested APIs
Illustrated in Python for readability; Cradle is TypeScript, so the real contracts would be Zod schemas plus inferred types, following the existing codebase conventions.
class Proposal(BaseModel):
id: str
task_id: str
agent_id: str
action: ActionRequest
facts: list[CandidateFact]
evidence_refs: list[str]
confidence: float | None
class RuntimeDecision(BaseModel):
proposal_id: str
verdict: Literal["allow", "deny", "repair", "clarify", "require_approval"]
reasons: list[str]
policy_results: list[PolicyResult]
required_actions: list[str]
class ExecutionObservation(BaseModel):
execution_id: str
tool_id: str
raw_result_ref: str
observed_at: datetime
side_effects: list[ObservedSideEffect]
class VerificationResult(BaseModel):
execution_id: str
status: Literal["verified", "failed", "inconclusive"]
checks: list[VerificationCheck]
evidence_refs: list[str]18. Storage considerations
No single store fits. Split by job:
| Job | Store |
|---|---|
| Runtime state, transactions | Relational DB (Cradle already uses SQLite + Drizzle) |
| Artifacts, evidence blobs | Object storage, content-addressed |
| Audit | Append-only log, hash-chained |
| Graph traversal and reasoning | Graph store — only when actually needed |
| Semantic retrieval | Vector store (sqlite-vec today) |
| Ontologies, policies, packs | Version control or a registry |
Four things worth stating plainly:
- a vector database is not an ontology;
- a knowledge graph is not a replacement for transactional storage;
- an OWL reasoner is not an authorization engine;
- RAG is not verification.
19. Implementation roadmap
Phase 1 — typed execution contracts. ✅ Implemented. Proposal,
Decision, Observation, Verification as real persisted entities. Schema
validation. Explicit pre- and postconditions on actions. Audit events.
Phase 2 — policy-controlled tool gateway. ✅ Implemented. Centralized tool invocation, permissions, risk levels, idempotency keys, approval rules, dry-run support.
Phase 3 — verification runtime. ✅ Implemented, with an empty verifier registry. Independent postcondition checks, evidence capture, failure handling, compensation hooks. Rollback is compensation-only.
Phase 4 — execution ontology. Not started. Core vocabulary, domain-pack manifest, versioning, mapping runtime objects onto graph entities. A domain-pack registry exists in code, but no manifest format and no vocabulary.
Phase 5 — first domain pack. Partially implemented, ahead of Phase 4. HS
Router is the pilot: the pack evaluates EAEU provisions and exemptions in
three-valued logic against known product attributes, so a missing attribute
becomes an explicit question instead of a silent decision (§11). It wraps the
existing HS Codes Router service, whose endpoints register as read_only
tools. Still missing: the entity vocabulary as such, and packaging.
Phase 6 — optional semantic reasoning. Not started. RDF/RDFS, SHACL validation, OWL where the constraints genuinely suit it, graph-based provenance queries.
Do not start with a knowledge graph or a complete OWL ontology. That path spends months on modelling before the core value proposition — governed execution — has been tested once.
20. Risks and non-goals
Risks: ontology maintenance cost · stale rules · a false sense of safety · over-formalization · mismatch between open-world reasoning and closed-world business logic · inability to roll back external side effects · conflicting policies · added latency · evidence that is itself untrustworthy · version drift between packs, policies and code · the sheer difficulty of domain modelling.
Non-goals:
- making a language model deterministic;
- encoding all knowledge in OWL;
- replacing application code with an ontology;
- automatically approving every agent action;
- proving that an external system behaved correctly when no independent verification is available;
- treating local deployment as sufficient security.
21. Open questions
- What is the current internal tool abstraction, and can MCP serve as the single Tool Gateway?
- Where should policy evaluation run — in-process, or as a separate service?
- Which runtime objects already exist in the Drizzle schema, and which need new tables?
- How are agent runs persisted today, and is that record sufficient for audit?
- Is the existing operator inbox generalisable into the Approval Service?
- How should domain packs be versioned and distributed to on-premise installations?
- Which operations require strong transactions rather than compensation?
- Which facts require external verification, and from which authorities?
- Is RDF interoperability important for the first customer, or purely architectural taste?
- Should the initial graph be implemented relationally?
- Which pilot goes first — HS Router or UptimeHarbor?
- Which current system prompts contain business rules that should move into code or policies?
22. Minimal first implementation
One vertical slice, implementable without RDF, OWL or a graph store:
A policy-controlled tool call with postcondition verification.
- An agent proposes an action.
- Input is validated against a typed contract.
- The policy engine returns
allowordeny. - The tool executes through a centralized gateway.
- A verifier reads the target system independently.
- The runtime stores
Proposal,Decision,Observation,VerificationandAuditEvent. - Failed verification is returned as failure even when the tool itself reported success.
Step 7 is the whole thesis in one line. Everything else — domain packs, ontologies, semantic reasoning — is an extension of a loop that must first work in its simplest form.
Agent Proposal
↓
Typed Contract
↓
Policy Decision
↓
Controlled Tool Gateway
↓
Observation
↓
Independent Verification
↓
Verified State Transition23. Neighbouring systems
Current state. What Cradle is compared against, and what the comparison is actually about. The unit of comparison is a mechanism, not a product.
LangGraph is not a competitor
LangGraph is what the buyer already runs. Cradle sits underneath it, between
the graph and the tools. Its human-in-the-loop support is real: interrupt()
halts execution at a tool call, graph state survives through the persistence
layer, and a person approves, edits the arguments, or rejects.
What its documentation does not describe: bounds on that approval, an expiry, a single-use guarantee, a ban on self-approval, or a log that resists editing.
| Mechanism | LangGraph HITL | Cradle | File |
|---|---|---|---|
| Pause before a tool call | yes | yes | gateway.ts |
| Rule outside the agent, versioned | no — logic lives inside a graph node | yes, POLICY_VERSION is written into the decision | policy.ts |
| Unregistered tool is not callable | no | yes | registry.ts |
| Side-effect class as a property of the tool | no | lattice pure → irreversible | registry.ts |
| Approval with scope, expiry, single use, no self-approval | no | yes, four properties | approvals.ts |
| Idempotency with resumption after approval | hand-rolled | yes | gateway.ts |
| A log that cannot be quietly rewritten | no — traces are observability | append-only, SHA-256 chain, verifyAuditChain() | audit.ts |
One line: LangGraph answers how the agent got there. Cradle answers why it was allowed to.
AWS Dogwood is the real neighbour
Dogwood, opened under Apache 2.0 in August 2026, extends Cedar to sequences of tool calls, and is supported in Amazon Bedrock AgentCore Policy. It does what Cradle does: a deterministic layer outside the model, where a proposed call is accepted or rejected before execution.
AWS names its own limits, and they draw the line:
| Dogwood limitation | What it means here |
|---|---|
| The reference interpreter is "for learning the language, not production authorization" | a language, not a runtime |
| Requires trusted timestamps, authenticated events, durable event storage, logging | exactly the infrastructure Cradle already has under test |
| Formal policy analysis is lost once temporal conditions are used | Cedar's advantage disappears where agent scenarios begin |
| AgentCore Policy is a managed service in the AWS cloud | Cradle runs in your own perimeter, on your own hardware, with local models |
The consequence: running on your own hardware is not a secondary comfort. It is the dividing line against the closest neighbour.
What does not compare
A vector database is not an ontology. A knowledge graph does not replace transactional storage. An OWL reasoner is not an authorization engine. RAG is not verification.