Trust-Split

Trust-Split in dist_agent_lang is not a pitch deck about “distributed consensus.” It is the observation that one language refuses to pretend every deployment wants the same blast radius. The compiler and runtime split what you are allowed to do based on @trust("centralized" | "hybrid" | "decentralized") and related attributes—and if that sounds heavy-handed, the test suite in tests/trust_split_validation_tests.rs is basically a bouncer with a clipboard.

This article explains how dist_agent_lang splits compile-time and runtime capabilities by trust posture—and why that is intentional, not accidental.

The three-way split: service posture

When the engine builds ServiceContext in src/runtime/engine.rs, it reads attributes like @trust("..."), @web, @ai, @chain(...), @admin, and @cloudadmin. From that it derives:

  • trust_model
  • Boolean privilege flags for web, AI, chain, admin, and cloudadmin

That split is intentional. Centralized services get a permissive trust-layer path for admin and cloudadmin validation. Hybrid services only get those powers if they explicitly asked for them with @admin or @cloudadmin. Decentralized services are the strictest: the runtime does not hand out elevated control-plane access unless the model explicitly permits a narrower path.

That is not cynicism; it is fail-closed by design. Unknown trust models fall through to no on those privilege booleans. The project would rather break your demo than accidentally give a typo’d posture a free pass.

The compiler split: not every syntax node ships everywhere

The trust_split_validation_tests file exists to prove that decentralized services do not get the full kitchen sink at parse or compile time. Real in-tree examples include:

  • fs:: and ai:: namespaces in a @trust("decentralized") service: parse error
  • Forced decentralized compile mode rejecting hybrid-style orchestration that pulls in ai:: even when source text says hybrid
  • Decentralized v1 rejecting some constructs, such as try/catch in mobile pipeline tests, while still allowing a minimal critical subset like arithmetic, conditionals, and returns

So the split is literal: not every syntax node ships to every trust target. One repo can still produce different programs depending on trust posture.

Splitting “who may do what” from “who is boss”

trust::authorize in src/stdlib/trust.rs implements a layered split:

  1. 1. key::check against the capability registry — explicit grants, expirations, strict-mode audit on denial
  2. 2. An in-memory admin registry driven by ADMIN_IDS and ADMIN_LEVEL_<id>
  3. 3. Built-in rules that are intentionally literal for certain hard-coded IDs used in tests

That stack is the project’s answer to “centralized vs decentralized” at the authorization layer: do not pick one mythology—compose capability checks with role fallbacks, and log admin authorization decisions.

Shell execution splits again: sh:: trust levels (off / sandboxed / confirmed / trusted) can be combined with optional key::check("sh", "run", ...) when an owner principal is configured in src/stdlib/sh.rs. The agent does not get a single dial labeled “trust”; it gets split knobs that interact.

IDE agents: the capability split you can actually see

In src/ide/agent_runner.rs, when a tool invocation is pending, the runner checks agent_ctx.is_capable(tool_name). If the tool is not in the configured capability list, the model gets an in-thread error string instead of silent failure or fake success. That is trust split as product behavior: the assistant’s desire to call a tool and the deployment’s willingness to allow it are different variables, and the code keeps them apart on purpose.

Compliance: an optional third split

Flip DAL_COMPLIANCE_KEY_GATE and kyc:: or aml:: operations may require key::check with DAL_COMPLIANCE_PRINCIPAL. That is another split: general runtime versus regulated surface, gated without rewriting the whole language.

Bottom line

Trust-Split here means: one toolchain, multiple trust postures, enforced at parse time, compile time, and runtime—plus capabilities and agent policy so “who is trusted” is never a single boolean you set once and forget.

If someone tells you their blockchain is “trustless” while quietly importing half the stdlib, dist_agent_lang’s tests exist to call that out, not to fund their Series A slide.