# Trinitite — Agent digest This file is the full digest of the redesigned core docs. It is generated by scripts/build-llms.mjs from the source mdx pages. Do not edit by hand; run `npm run build:llms` to regenerate. Most code that integrates with Trinitite is written by AI coding agents. This file is for them. The manifest is at https://docs.trinitite.ai/llms.txt. The human-readable agent guide is at https://docs.trinitite.ai/docs/agents. ================================================================================ Page: SDK URL: https://docs.trinitite.ai/docs/sdk ================================================================================ # SDK Set your house rules once. Group the AI that shares a goal together. Trinitite watches every call, lines it up with your compliance rules, learns from it, and keeps a signed receipt for every decision. You connect the AI you already use. We handle the rest. > **Status:** Stable · GA > **Companion docs:** [Get started](./get-started) · [Concepts](./concepts) · [Verdicts and modes](./verdicts) · [The closed loop](./closed-loop) · [Evals onboarding](./evals-onboarding) > **Source of truth:** the backend SDK Foundation DX contract. This section is the public, typed projection. When the two disagree, the contract wins. ## Two lines, and every call after is checked Wrap the model you already chose. Read the result. That is the whole integration. The baseline, the Guardian, and the signed receipt all appear on their own. ```python from trinitite import Trinitite tr = Trinitite # reads TRINITITE_API_KEY resp = tr.client("openai", credential="cred_openai_prod").chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "I want a refund for order #4821."}], ) r = tr.result(resp) # verdict + diff + violations + compliance + risk + receipt ``` > Diagram: a wrapped provider call goes through the Guardian and returns a governed result with verdict, diff, violations, compliance, risk, and receipt. The same shape works in TypeScript with `@trinitite/sdk`. The two SDKs share one contract, so they cannot drift. One layer, not ten tools: a Guardian, a proxy, an eval harness, an audit ledger, a red-teamer, and a policy engine all collapse into a single integration. > Stat banner: one layer, not ten tools. ## What you get back Every governed call returns one verdict, plus the diff, the violated controls, the compliance crosswalk, a risk read, and a signed receipt. The verdict is the legible source of truth. Emu is alongside it, never the only cue. > Diagram: the six verdicts as a tree (passed, corrected, blocked, masked, HiTL, failed). The same six, as a quick-reference table: > Quick-reference table of the Trinitite verdicts. See [Verdicts and modes](./verdicts) for the full taxonomy and the four ways to run: enforce, monitor, sampled, continuous. ## The shape of it Three nouns, one rule. The **baseline** is your house rules. A **scope** is a goal. An **asset** is a thing you connect. Get these and the rest of the SDK reads itself. > Diagram: the three-layer model. Baseline (house rules) -> Scope (goal carrier) -> Assets (things you connect). See [Concepts](./concepts) for the level 0 to 2 ladder and the three ways a result reaches you. ## Why it compounds The platform gets better on its own, per scope. Every governed call is captured, judged by a brain that returns the same answer every time, and fed back into a better Guardian. That sameness is not a feature you tick. It is the thing that lets the loop close. > Diagram: the closed loop. Bind rules -> Guardian enforces -> capture -> judge (same answer every time) -> distill a better Guardian. The dashed loop-back shows distill improving enforcement, per scope. See [The closed loop](./closed-loop) for the version vault, the rollback ripcord, and the deploy gate. ## Read the SDK [5 minutes Get started Install, get a key, make your first governed call, and test it for free.](./get-started) [Mental model Concepts The three-layer model: baseline, scope, asset. Why the goal lives where it does.](./concepts) [What comes back Verdicts and modes The six verdicts, the four modes, and the review loop for human-in-the-loop.](./verdicts) [Why it compounds The closed loop Govern, capture, eval, improve, and re-govern on one brain that returns the same answer every time.](./closed-loop) [Flagship onboarding Test your agent with our judge Point Trinitite at the agent you built or bought. We exercise it and score every interaction with a judge that returns the same bytes every time. The output is a signed, replayable receipt, not a dashboard number that moves.](./evals-onboarding) [Make it better Training Turn reviewed calls into a better Guardian or a focused model, with every version kept.](./training) [Ship with proof Release gates Run fixed cases before release and hold a deployment when the candidate regresses.](./gate) [Choose well Models and routing Compare models on your traffic, route within limits, and keep failover visible.](./models) [Follow the evidence Traces and graph Walk from a decision to its Guardian, identity, policy, controls, and receipt.](./graph) ## For your agent [The manifest /llms.txt A short list of links to every section.](https://trinitite.ai/llms.txt) [Full digest /llms-full.txt The redesigned core in one shot, about 80 KB.](https://trinitite.ai/llms-full.txt) [Agent guide For Agents → The loop and the copy-paste prompt library.](/docs/agents) ================================================================================ Page: SDK > Get started URL: https://docs.trinitite.ai/docs/sdk/get-started ================================================================================ # Get started Put one governed model call on the wire. You will get a clear result that your app can use right away. > **Status:** Beta · Python `0.0.3` · TypeScript `0.0.3` > **Companion docs:** [Authentication](./authentication) · [Language compatibility](./reference/compatibility) · [Result](./result) [Diagram: QuickstartRail] ## 1. Install Pick your language: ```bash pip install trinitite==0.0.3 ``` ```bash npm install @trinitite/sdk@0.0.3 ``` > Terminal: pip install trinitite (Python) or npm install @trinitite/sdk (TypeScript). ## 2. Choose an environment Set `TRINITITE_API_KEY`. The key prefix must match the environment: ```bash export TRINITITE_API_KEY="trnt_test_..." export TRINITITE_ENV="test" ``` [Diagram: EnvironmentKeyring] `prod` is the default. A mismatched key and environment stops at startup with `EnvironmentMismatchError`. This keeps a development key from reaching the production endpoint by mistake. Create the SDK client. The empty constructor reads the environment: ```python from trinitite import Trinitite tr = Trinitite() ``` ```typescript const tr = new Trinitite(); ``` Python calls use snake case. TypeScript calls use camel case and promises. ## 3. Make the call Use the provider and model you already chose. The wrapped call returns a response. Turn that response into a `GovernanceResult` with `tr.result(...)`. ```python response = tr.client( "openai", credential="cred_openai_prod", ).chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Refund order 4821."}], ) result = tr.result(response) ``` ```typescript const response = await tr.client("openai", { credential: "cred_openai_prod", }).chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "Refund order 4821." }], }); const result = tr.result(response); ``` > Diagram: a wrapped provider call goes through the Guardian and returns a governed result with verdict, diff, violations, compliance, risk, and receipt. You can call `tr.govern(...)` first when you want to set a baseline. In TypeScript, await it: ```typescript await tr.govern({ frameworks: ["soc2"], mode: "enforce" }); ``` The wrapped client accepts provider request fields, but it returns a fully materialized response. This guide does not treat provider token streaming as a supported response contract. ## 4. Read the result Branch on the lowercase wire verdict: ```python if result.verdict == "passed": print(result.body) elif result.verdict == "corrected": print(result.diff) elif result.verdict == "blocked": show_safe_fallback() elif result.verdict == "masked": keep_tokens_outside_the_trust_boundary() elif result.verdict == "hitl": queue_for_review() else: # failed follow_error_policy() ``` [Diagram: FirstResultInspector] Fields such as `risk`, `flow_id`, and `receipt` are optional. Check them before use. A receipt is a handle, not a `receipt_id` field on every result: ```python if result.receipt and result.receipt.get("id"): verification = result.receipt.verify() ``` TypeScript uses optional chaining and awaits follow-up network calls: ```typescript const receiptId = result.receipt?.get("id"); const verification = result.receipt ? await result.receipt.verify() : null; ``` For the structured trace, call the method: ```python trace_response = result.explain() ``` ```typescript const traceResponse = await result.explain(); ``` ## 5. Test every branch `force_verdict` is a development and test control on wrapped calls. The SDK rejects it in `prod` before network I/O. ```python test_tr = Trinitite(env="test") response = test_tr.client("openai").chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Test the blocked path."}], force_verdict="blocked", ) result = test_tr.result(response) ``` > Diagram: the test-mode key prefixes (trnt_dev_, trnt_test_, trnt_live_) and what each one allows. **Keep test controls out of production** > A production client raises `ForcedVerdictInProdError` when a wrapped call sets > `force_verdict`. Test mode does not bypass authentication, permissions, or > server-side capability checks. ## Where to go next - [Concepts](./concepts) explains baselines, scopes, assets, and result paths. - [Verdicts and modes](./verdicts) shows what your app should do for each result. - [Guardians](./guardian) shows how one focused guard protects each goal. - [Models and routing](./models) chooses a model within cost, latency, and risk limits. - [The closed loop](./closed-loop) connects governed traffic, evals, training, and gates. - [Evals onboarding](./evals-onboarding) starts a repeatable agent test. [Diagram: SdkAgentFooter] ================================================================================ Page: SDK > Concepts URL: https://docs.trinitite.ai/docs/sdk/concepts ================================================================================ # Concepts Set rules once, group work by goal, then connect the AI your team uses. > **Status:** Beta > **Companion docs:** [Get started](./get-started) · [Scopes and assets](./scopes-assets) · [Result](./result) ## Three layers keep setup clear Trinitite separates rules, goals, and connected systems. This keeps one setting from doing three jobs. > Diagram: the three-layer model. Baseline (house rules) -> Scope (goal carrier) -> Assets (things you connect). 1. A **baseline** holds the common rules for governed work. 2. A **scope** names a goal and groups work that shares it. 3. An **asset** is the model client, MCP server, CLI, skill, connector, sandbox, or RAG system that does the work. An asset at the root uses the baseline. An asset created from a scope also gets that scope's goal and settings. ```python from trinitite import Trinitite tr = Trinitite() tr.govern( frameworks=["soc2"], policies=["refund-policy"], mode="enforce", ) refunds = tr.scope( "refunds", goal="Resolve valid refunds without exposing customer data.", ) client = refunds.client("openai", credential="cred_openai_prod") ``` TypeScript has the same idea, with promises and camel case: ```typescript const tr = new Trinitite(); await tr.govern({ frameworks: ["soc2"], policies: ["refund-policy"], mode: "enforce", }); const refunds = await tr.scope("refunds", { goal: "Resolve valid refunds without exposing customer data.", }); const client = refunds.client("openai", { credential: "cred_openai_prod", }); ``` [Diagram: AssetConstellation] ## Start small, add detail when needed The common path is short. Add a baseline or scope when the work needs its own rules or goal. > Diagram: the level 0 to 2 ladder. Level 0 is one line. Level 1 adds a scope. Level 2 adds per-asset and per-call overrides. ### Use the wrapped client For a model call made by your code, use the wrapped client and normalize the response: ```python response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Refund order 4821."}], ) result = tr.result(response) ``` The provider response and the governance result are different objects. Keep the response for model output. Use the result for the verdict and evidence. ## A result can arrive three ways The right path depends on who owns the model call. > Diagram: three result-acquisition patterns. Inline (wrap), observed (intercept at the network layer), split-govern (two govern calls with your direct call in between). ### Inline Your code makes a wrapped call. Use `tr.result(response)` right away. ### Observed Another system makes the call. Query stored decisions with `tr.results.get`, `tr.results.list`, or correlation polling. ```python result = tr.results.wait_for_correlation( "refund-4821", poll_interval_seconds=0.5, max_wait_seconds=15, ) ``` TypeScript uses `await tr.results.waitForCorrelation(...)`. ### Split governance in Python Python can check input and output around a direct provider call: ```python input_result = tr.govern.input( instructions="Do not expose customer data.", input=messages, masking=["pii"], ) provider_messages = input_result.masked_body or messages provider_response = provider.chat.completions.create( model="gpt-4o", messages=provider_messages, ) output_result = tr.govern.output( flow_id=input_result.flow_id, instructions="Do not expose customer data.", input=provider_messages + [{ "role": "assistant", "content": provider_response.choices[0].message.content, }], ) ``` Send `masked_body` to the provider when it is present. Output governance checks the reply. It does not unmask it for you. Call `output_result.unmask(...)` inside the approved trust boundary. Split governance is Python-only. TypeScript supports wrapped calls and stored result lookup, but it does not expose `tr.govern.input(...)` or `tr.govern.output(...)`. ## One result shape Each path gives you a `GovernanceResult`. Common fields include `verdict`, `diff`, `violations`, `compliance`, and `risk`. Other fields appear only when that call produced them. [Diagram: GovernanceResultAnatomy] Follow-up work uses methods and optional handles: ```python trace_response = result.explain() if result.receipt and result.receipt.get("id"): verification = result.receipt.verify() ``` In TypeScript, use `await result.explain()` and `await result.receipt.verify()`. ## Where to go next - [Verdicts and modes](./verdicts) maps every wire verdict to an app action. - [Integration routes](./get-started) starts with the wrapped call path. - [The closed loop](./closed-loop) shows how results become repeatable tests. [Diagram: SdkAgentFooter] ================================================================================ Page: SDK > Verdicts and modes URL: https://docs.trinitite.ai/docs/sdk/verdicts ================================================================================ # Verdicts and modes Read one verdict, then take one clear app action. The verdict text is always the source of truth. > **Status:** Beta > **Companion docs:** [Result](./result) · [Human review](./human-review) · [Masking](./masking) ## Six verdicts, six app paths `result.verdict` uses one of six lowercase wire values: `passed` · `corrected` · `blocked` · `masked` · `hitl` · `failed` > Diagram: the six verdicts as a tree (passed, corrected, blocked, masked, HiTL, failed). > Quick-reference table of the Trinitite verdicts. Use the value in code, not a display label: ```python if result.verdict == "passed": use_response(result.body) elif result.verdict == "corrected": use_response(result.body) record_patch(result.diff) elif result.verdict == "blocked": show_safe_fallback() elif result.verdict == "masked": keep_masked_text_outside_the_trust_boundary() elif result.verdict == "hitl": wait_for_review(result.review) else: # failed follow_error_policy() ``` `governance_blocked` may appear in the wrapped-response status path. It is not a wire verdict. The result verdict is `blocked`. ## Inspect the reason and evidence The result carries common fields and optional context: [Diagram: GovernanceResultAnatomy] `diff`, `violations`, and `compliance` use empty collections when there is nothing to report. Fields such as `risk`, `retrieval`, `provenance`, `flow_id`, and `receipt` may be absent. Call `explain()`. Do not read it as a property: ```python trace_response = result.explain() if trace_response.ok: print(trace_response.body.get("steps", [])) ``` ```typescript const traceResponse = await result.explain(); if (traceResponse.ok) { console.log(traceResponse.body.steps ?? []); } ``` The call needs a result ID and the SDK client attached by `tr.result(...)`. ## Corrected means keep moving A corrected result can carry an RFC 6902 patch in `result.diff`. Your app can use the governed response and keep the patch for review. ```python if result.verdict == "corrected": for operation in result.diff: print(operation["op"], operation["path"]) ``` ## Masked means rehydrate later Masking keeps the original value away from the provider. Rehydrate only inside your approved trust boundary. > Diagram: two-way masking. Egress mask tokenizes the value, the model replies with the token, tr.unmask rehydrates the real value inside the trust boundary. ```python if result.verdict == "masked" and result.flow_id: masked_text = result.body["choices"][0]["message"]["content"] unmask_response = result.unmask(masked_text) if unmask_response.ok: internal_text = unmask_response.body["text"] ``` Output governance does not rehydrate content automatically. In TypeScript, `await result.unmask(maskedText)` returns the response. ## `hitl` means pause for a person A `hitl` result can carry `result.review`. Keep the app flow held until that review reaches a decision. > Diagram: the HiTL review loop. pending -> approved | rejected | escalated | expired, with three on-ramps (SDK methods, webhooks, drop-in reviewer portal). ```python if result.verdict == "hitl" and result.review is not None: result.review.assign(reviewer="finance-oncall") decision = result.review.approve( reason="Order and refund limit were verified.", ) ``` Review operations require the matching server permissions. A valid API key alone does not grant permission to assign or decide a review. ## Receipts are optional Some results include a signed receipt handle. Check for it before reading or verifying it: ```python if result.receipt and result.receipt.get("id"): verification = result.receipt.verify() print(verification.body.get("verified")) ``` ```typescript if (result.receipt?.get("id")) { const verification = await result.receipt.verify(); console.log(verification.body.verified); } ``` Receipt verification uses the public verification endpoint without your bearer token. ## Choose how governance runs > Diagram: the four modes (enforce, monitor, sampled, continuous) as a ladder. Set the mode on the baseline or the supported scoped call surface: - `enforce` makes the governance decision part of the app path. - `monitor` records and evaluates without making the verdict binding. - `sampled` evaluates selected traffic after the fact. - `continuous` supports ongoing assurance over live activity. Account capabilities and server permissions still decide which operations are available. ## Where to go next - [The closed loop](./closed-loop) turns reviewed results into repeatable checks. - [Human review](./human-review) covers the full review lifecycle. - [Receipts](./receipts) shows verification and graph access. [Diagram: SdkAgentFooter] ================================================================================ Page: SDK > The closed loop URL: https://docs.trinitite.ai/docs/sdk/closed-loop ================================================================================ # The closed loop Keep runtime decisions, test evidence, and release checks connected. Each step leaves an object you can inspect. > **Status:** Beta > **Companion docs:** [Evals onboarding](./evals-onboarding) · [Testing and CI](./testing-ci) · [Receipts](./receipts) ## The loop has a clear handoff A useful loop is not a promise that every change ships itself. It is a set of steps your team can inspect and control: 1. Bind a baseline, scope, and Guardian. 2. Govern calls and keep their results. 3. Turn selected traffic or fixed transcripts into eval cases. 4. Compare a candidate against a known run. 5. Use a gate before deployment. > Diagram: the closed loop. Bind rules -> Guardian enforces -> capture -> judge (same answer every time) -> distill a better Guardian. The dashed loop-back shows distill improving enforcement, per scope. The same scope ID keeps the goal and evidence tied together. A result may carry violations, corrections, routing context, and a receipt. Optional fields stay optional, so the loop must not depend on every result having every field. ## Scope each Guardian Different jobs can use different Guardian versions while one control plane keeps the assignments visible. [Diagram: WardenFleetFlow] Use a scope for the job: ```python refunds = tr.scope( "refunds", goal="Resolve valid refunds without exposing customer data.", ) response = refunds.client("openai").chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Refund order 4821."}], ) result = tr.result(response) ``` The result records `scope_id` when the service includes it. That gives later queries and evals a stable way to group the work. ## Keep versions addressable A candidate and an active Guardian are different release objects. Keeping their versions separate makes rollback and comparison possible. > Diagram: the Guardian version vault with rollback ripcord and deploy gate. Pin the Guardian on a scope when a run must use a known version: ```python refunds = tr.scope( "refunds", goal="Resolve valid refunds without exposing customer data.", guardian="guardian-refund-v3", ) ``` Do not treat a candidate as active just because it exists. Compare it, review the result, then choose whether to promote it. ## Compare completed eval runs Run the same approved scenarios against the baseline and candidate. Then compare the completed run IDs: ```python comparison = tr.eval.compare( a="evr_release_12", b="evr_release_13", ) print(comparison.body["deltas"]["regressed_scenarios"]) print(comparison.body["statistical"]["regression"]) ``` [Diagram: EvalComparison] Comparison pairs cases by `scenario_id`. Both runs must be complete. Receipt fields in the comparison can be empty when one of the runs has no receipt. ## Put a gate in front of release A gate runs a bound suite against thresholds. It keeps its run history and returns typed gate receipts. > Diagram: the egress and HiTL gate flow. Python can create a gate by calling `tr.gate(...)`: ```python gate = tr.gate( name="refund-release-gate", suite_id="suite_refunds", guardian_id="refund-guardian", thresholds={"accuracy": 0.95}, schedule="nightly", ) for receipt in gate.runs(limit=10): if receipt.passed is False: print(receipt.failures) ``` TypeScript uses `tr.gate.create(...)`: ```typescript const gate = await tr.gate.create({ name: "refund-release-gate", suiteId: "suite_refunds", guardianId: "refund-guardian", thresholds: { accuracy: 0.95 }, schedule: "nightly", }); ``` Gate receipts use the `gr_` family. A gate can be created, listed, read, updated, paused, resumed, deleted, and inspected through its run history. Permissions and account capabilities are enforced by the server. ## Keep CI simple Your CI job should run the test script and fail on the gate result: ```yaml name: Governance gate on: [push, pull_request] jobs: governance: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - run: pip install trinitite==0.0.3 - run: python ci/governance_gate.py env: TRINITITE_API_KEY: ${{ secrets.TRINITITE_TEST_API_KEY }} TRINITITE_ENV: test ``` ## Where to go next - [Training](./training) turns reviewed calls into a new Guardian or model candidate. - [Release gates](./gate) checks a candidate before promotion or deployment. - [Guardian](./guardian) covers version pinning, promotion, and rollback. - [Evals onboarding](./evals-onboarding) creates the first fixed test. - [Eval receipts](./evals/receipts) explains verification and run comparison. - [Schedule](./schedule) adds a readable cadence to recurring checks. [Diagram: SdkAgentFooter] ================================================================================ Page: SDK > Evals onboarding URL: https://docs.trinitite.ai/docs/sdk/evals-onboarding ================================================================================ # Evals onboarding Give your agent a clear rubric and fixed cases. Trinitite returns per-case results and a score you can compare with the next run. > **Status:** Stable · GA > **Companion docs:** [The closed loop](./closed-loop) · [Exercise modes](./evals/exercise-modes) · [Eval receipts](./evals/receipts) · [Evals API](/api-reference/evals) > **Source of truth:** [Evals API](/api-reference/evals). This SDK guide shows the typed workflow. ## Start with finished transcripts The quickest first eval uses `submitted` mode. Your app supplies completed transcripts. Trinitite judges them against one rubric. It does not call your agent in this mode. > Diagram: the eval flow. Define an Eval -> start a run -> exercise the AUT -> judge every turn at temperature 0 -> mint a signed eh_ receipt. You need four things: 1. A short name. 2. A rubric with clear pass and fail rules. 3. An Agent-Under-Test descriptor. 4. An evaluator Guardian ID. The server enforces the Evals capability and operation permissions. Handle a non-success response when the account or key cannot run an eval. ## Create the eval Python uses `tr.eval.create(...)` and snake case: ```python from trinitite import Trinitite tr = Trinitite() ev = tr.eval.create( "support-agent-refunds", rubric=( "Honor the 30-day refund window. " "Never reveal another customer's data." ), agent_under_test={ "kind": "openai_compatible", "model": "support-agent-v3", }, evaluator_guardian="guardian_eval_123", exercise_mode="submitted", ) ``` TypeScript uses promises, an options object, and camel case. Supply `evaluatorGuardian`; the TypeScript SDK requires it. ```typescript const tr = new Trinitite(); const ev = await tr.eval.create("support-agent-refunds", { rubric: "Honor the 30-day refund window. " + "Never reveal another customer's data.", agentUnderTest: { kind: "openai_compatible", model: "support-agent-v3", }, evaluatorGuardian: "guardian_eval_123", exerciseMode: "submitted", }); ``` Python allows `evaluator_guardian` to be omitted. Shared code examples should still provide it because TypeScript requires the matching field. ## Run two useful cases Give every case a stable `scenario_id`. That ID lets a later comparison pair the same case across runs. ```python run = ev.run( trajectories=[ { "scenario_id": "refund-in-window", "messages": [ {"role": "user", "content": "Refund my order from last week."}, {"role": "assistant", "content": "Your order is eligible."}, ], }, { "scenario_id": "refund-outside-window", "messages": [ {"role": "user", "content": "Refund my 45-day-old order."}, {"role": "assistant", "content": "I will make an exception."}, ], }, ], label="release-candidate", ) print(run.run_status) print(run.eval_score) print(run.pass_rate) ``` `submitted` runs complete in the request. Other exercise modes have a longer lifecycle. [Diagram: EvalRunStepper] ## Choose how the transcript arrives The rubric stays the same. The exercise mode changes how the transcript reaches the judge. > Diagram: the matrix of exercise_mode (submitted, proxy_capture, persona_sim) crossed with scenario_source (static, swarm, atlas). - `submitted` judges transcripts you send. - `proxy_capture` opens a run for tagged, captured traffic. Finalize the run when the capture window is done. - `persona_sim` drives the agent from scenario goals and completes in the background. Poll it with `run.wait()`. Persona conversations can vary. A receipt applies to the transcript that was judged, not to a new persona conversation. Scenario source is a separate choice. It can use caller-supplied static cases, generated cases, or the ATLAS probe catalog. Red-team work is represented inside the eval run lifecycle. ## Read the completed run The run handle exposes the parts most apps need: ```python print(run.run_id) # evr_... print(run.run_status) # completed print(run.eval_score) # aggregate score print(run.pass_rate) # passed cases / scenario count print(run.receipt_id) # eh_... or None ``` Keep the run ID even when there is no receipt. Run comparison uses run IDs, and a completed run may not have a receipt if signing did not finish. ## Compare before and after Both runs must be complete. The service aligns common `scenario_id` values and reports improvements and regressions. ```python comparison = tr.eval.compare( a="evr_release_12", b="evr_release_13", ) print(comparison.body["deltas"]["score_delta"]) print(comparison.body["deltas"]["regressed_scenarios"]) ``` [Diagram: EvalComparison] TypeScript awaits the call and uses an options object: ```typescript const comparison = await tr.eval.compare({ a: "evr_release_12", b: "evr_release_13", }); ``` ## Keep the receipt when present A completed run can include an eh_... receipt. Store it beside the run ID. > Diagram: the signed Eval Receipt envelope. Merkle-rooted over every per-item verdict, KMS-signed, replayable bit for bit. The receipt binds the eval contract, judged items, and result set. Verification checks the saved envelope and signature. It does not call the Agent-Under-Test, and it does not rerun the judge. [Diagram: ReceiptReplay] Replay is a separate workflow. It uses the fixed rubric, trajectories, and judge settings to reproduce the judged result. For `persona_sim`, replay starts from the transcript already captured in the run. ## Grow a useful suite A useful eval has a clear rubric, stable IDs, good paths, pressure cases, and real failures that should never return. > Diagram: a bad eval (a dashboard number that moves) versus a good eval (an evidence-graded score with localized failures, mapped controls, and a replayable receipt). Promote failed items into a versioned dataset, review them, then use the approved dataset version in the next run: ```python run.promote_failures(dataset_id="evds_refund_regressions") next_run = ev.run( dataset_id="evds_refund_regressions", dataset_version=3, label="next-release", ) ``` Pinning the dataset version keeps the comparison set stable. ## Add continuous checks when ready Both SDKs expose monitors, attestations, optimization runs, compile jobs, and dataset operations through the eval handles. Start with one fixed submitted run, then add capture or scheduled monitoring when the first result is useful. ## Where to go deeper - [Exercise modes](./evals/exercise-modes) covers submitted, capture, and persona runs. - [Eval receipts](./evals/receipts) covers verification, replay, and comparison. - [Release gates](./gate) blocks a deployment when a fixed case regresses. - [Schedule](./schedule) sets the cadence for recurring monitors and gates. - [The closed loop](./closed-loop) connects runtime results, evals, and release decisions. [Diagram: SdkAgentFooter] ================================================================================ Page: Products > Evals URL: https://docs.trinitite.ai/docs/products/evals ================================================================================ # Evals You shipped an agent. Everyone wants a number. Prove it is safe to ship, with a signed score a regulator can re-run, not a dashboard number that moves when the GPU gets busy. > **Status:** Stable · GA > **Companion docs:** [Evals onboarding](/docs/sdk/evals-onboarding) · [Red Team](./red-team) · [Evals API](/api-reference/evals) · [Eval Harness](./eval-harness) > **Source of truth:** the backend Evals onboarding guide. This page is the buyer-side pitch; the SDK onboarding is the developer how-to. ## The problem You shipped an agent. Your board wants to know it is safe. Your auditor wants evidence you tested it. Your customers want an SLA. So you ran an eval. It scored 91. The judge was a frontier LLM, and the score moved three points when you re-ran it on a busy afternoon. Which 91 is the real one? You cannot reproduce last quarter's run. You cannot prove the model under test was the one you claim. You cannot hand a regulator anything more durable than a screenshot of a dashboard. Every eval platform on the market is built for the pre-ship moment: a batch, a chart, a number that nobody can re-derive. The score is a vibe with a decimal point. ## The wedge Trinitite's judge returns the same bytes every time. The same model that powers our runtime governance also scores your agent, and it is batch-invariant. The same prompt, seed, model, and batch shape return the same bytes regardless of server load, time of day, or which GPU ran it. So an Eval Receipt is replayable bit for bit by a regulator or a counterparty. > Diagram: the Trinitite eval surface at a glance. Point Trinitite at the agent you built or bought, get a signed receipt back. > Diagram: the determinism wedge. The Trinitite judge returns the same bytes every time. A frontier-LLM judge drifts under load. ## The deliverable The deliverable is a signed `eh_` receipt. A screenshot of a dashboard is not evidence. An `eh_…` id, re-verifiable by anyone with the rubric and the trajectories, is. The receipt is the thing. Merkle-rooted over every per-item verdict, KMS-signed by Trinitite, and replayable by anyone. A regulator can re-run the judge and get the same bytes. That is what converts "trust us, the agent is safe" into "re-run receipt `eh_…` and you will get the same answer." - **Merkle-rooted.** Every per-item verdict is a leaf. Tampering with any one is detectable. - **KMS-signed.** Trinitite's signing key attests to the bytes. The verify path re-walks the signature. - **Replayable.** A regulator or a counterparty with the receipt can re-run the judge over the same rubric, trajectories, and judge config and get the same bytes. That is the wedge, surfaced as an artifact. - **Comparable.** Two runs align by `scenario_id`, run a paired statistical test on the pass/fail flips, and return the deltas. "Did the new prompt regress" is a signed answer, not an eyeball. ## Three ways to drive your agent Pick how the agent under test gets exercised. One line each. The full how-to lives in the [SDK onboarding](/docs/sdk/evals-onboarding). | Mode | How the agent runs | When to pick it | | ---- | ------------------ | --------------- | | **Submitted** | You post finished transcripts. We judge them. | First run. Cheapest, hermetic, CI-friendly. | | **Proxy capture** | The agent runs through a Trinitite perimeter in eval mode. Real captured traffic is judged. | Production-shape testing. Judge what your agent actually did. | | **Persona sim** | A digital human drives the agent multi-turn, adversarial by default. | Generative testing and red-team. Automated adversarial coverage. | Point the same judge at MITRE ATLAS red-team probes and the run crosswalks to a separate signed ATLAS attestation, in addition to the `eh_` receipt. One adversarial run yields both. ## The value, by role | Role | What this unlocks | | ---- | ----------------- | | **Head of AI / CTO** | A reproducible quality gate on the agent you ship. Re-run on every prompt or model change and diff signed verdicts, not noise. | | **AI product owner** | Find your agent's best prompt and model config with a reproducible search, instead of climbing against a judge that moves under you. | | **ML / platform engineer** | A versioned dataset and signed receipt loop that drops into CI. Run the suite, assert the score, compare against the last green run. | | **CISO / Compliance** | Your agent's behavioral compliance is a signed value, mapped to controls. Evidence, not a dashboard screenshot. | | **Vendor management** | Hold a third-party agent to a signed score you can re-verify, not the vendor's marketing benchmark. | | **Internal audit** | Reproducible, signed test evidence drawn against the real agent, re-verifiable by an external partner. | ## Go build it The four-line hero, the JSON envelope field by field, what a strong rubric looks like, and the composable top (persona_sim red-team, continuous evals, regulation-to-eval, reproducible prompt optimization) live in the developer onboarding. → **[Evals onboarding](/docs/sdk/evals-onboarding)**: the four-line hero to a signed receipt. → **[Red Team](./red-team)**: named adversarial patterns plus downloadable fixtures. → **[Evals API](/api-reference/evals)**: the full HTTP contract. → **[Eval Harness](./eval-harness)**: scale evals across cohorts and model swaps. ## For your agent [The manifest /llms.txt A short list of links to every section.](/llms.txt) [Full digest /llms-full.txt The redesigned core in one shot, about 80 KB.](/llms-full.txt) [Agent guide For Agents → The loop and the copy-paste prompt library.](/docs/agents) ================================================================================ Page: Emu URL: https://docs.trinitite.ai/docs/emu ================================================================================ # Emu Emu is the on-device guardian. It watches every AI interaction from your desktop, running the same governance as the Trinitite platform, beside you instead of in a data center. Think of it as a sidekick that guards the AI you already use. > **Status:** Stable · GA > **Companion docs:** [What Emu does](./what-emu-does) · [Modes](./modes) · [Privacy](./privacy) · [The Aviary](./aviary) · [Plans](./plans) · [Get started](./get-started) > **Siblings:** the [Warden](/docs/warden) commands Emu across a fleet. The [SDK](/docs/sdk) wraps the same governance in two lines of code. ## A sidekick that guards the AI you already use Today's AI apps do not just answer questions. They can read your files, run commands, push code, and talk to other services. Most of the time that is great. An AI that can act can also act wrongly: delete the wrong file, push over a teammate's branch, run a command that leaks a secret, or send a password to a third-party server. Emu is a desktop app you install once. After that, it sits between your AI apps and the internet and watches what they do. It runs on your computer, not in a data center. Your prompts stay on your machine. The only thing that leaves is a tiny "I'm still alive" ping every 60 seconds that carries no prompt content. ## The five jobs Emu does five things for you, all on this device: Watches and scores Every AI action, read and scored A chat turn in ChatGPT, a tool call in Cursor, a command in Claude Code, a request to an MCP server. Emu reads it, scores it 0 to 100 for risk, and records a short reason. Holds destructive actions The risky move waits for your yes Delete files, force-push over a branch, run a shell command, drop a database. Emu pauses it and shows you a small prompt: allow or block. If you are not around, the destructive action does not happen. Stops secrets from leaving Passwords and keys stay home If a request is about to send a password, API key, or credit card to an AI service, Emu stops it and asks: send anyway, remove the secret and send, or cancel. Masks personal information Your details never reach the AI provider Phone numbers, email addresses, credit cards, Social Security numbers, API keys, IBANs, and more get replaced with placeholders before they reach the AI service. You pick how aggressive the masking is. Keeps a private log and weekly recap A notebook that never leaves the house Every AI interaction is recorded locally so you can search it, get a weekly "your week in AI" summary, and ask Ask Emu questions about your own history. The notebook never leaves your computer. See [What Emu does](./what-emu-does) for the full walkthrough of each job, and [Modes](./modes) for the three ways Emu can treat an app (off, observe, guardian). ## The shock moment When an AI tries something risky, Emu does not beep or flash a red banner. A small card slides in from the top-right of your screen, even when you are in another app, with a painterly diorama, a short headline, and Emu's calm read of the risk. The dangerous move waits for your call. [Diagram: EmuShockMoment] You are always the one who decides. Emu never allows or blocks a risky action on its own. It just makes sure the dangerous ones stop and wait for you. See [What Emu does](./what-emu-does) for the full partnership promise. ## Read the section [The five jobs, in depth What Emu does Watch and score, hold destructive actions, stop secrets, mask personal info, keep a private log and weekly recap.](./what-emu-does) [Off, observe, guardian Modes and coverage The three per-app modes, the roughly 47 AI apps Emu watches, MCP interception, CLI setup, and the browser companion.](./modes) [Your data is yours Privacy What stays on your computer, the one thing that leaves, fail-open by default, fail-safe in exactly two spots, and the uninstaller that wipes everything.](./privacy) [Personal artifacts, not trophies The Aviary The landmark Emus, the Stories comics, the habitats, and the rhythm card. The rhythm only ever grows.](./aviary) [How far do you and Emu go Plans Free, Solo, Team, and Enterprise. Companions Skye and The Captain. The Roost for team admins.](./plans) [Five beats to protected Get started The five-beat onboarding, macOS and Windows system requirements, and the biometric opt-in.](./get-started) ## Where Emu fits Emu is the on-device guardian. The [Warden](/docs/warden) is the boss-class agent that commands a fleet of Emus across an organization, presiding over governance from a chat shell. The [SDK](/docs/sdk) wraps the same governance in two lines of code for the AI you build yourself. All three run the same deterministic kernel, so a verdict on the desktop, a verdict from the Warden, and a verdict from the SDK all read the same way. Go build it: pick [Get started](./get-started) for the five-beat install, or read [What Emu does](./what-emu-does) first if you want the full picture before you install. ================================================================================ Page: Warden URL: https://docs.trinitite.ai/docs/warden ================================================================================ # Warden The Warden is the boss-class Emu. It commands a fleet of guardians across your organization, presiding over governance, enforcing policy fleet-wide, and coordinating the Emu cast that watches each model and tool call. Ask in plain language and it sets up the guardrails, masks what is sensitive, and keeps a record you can review. > **Status:** Stable · GA > **Companion docs:** [Chat shell](./chat-shell) · [Named agents](./named-agents) · [Prompts](./prompts) · [Inline UI](./inline-ui) · [Memory](./memory) · [Receipts](./receipts) · [BYOK models](./byok-models) > **Siblings:** the [Emu desktop app](/docs/emu) is the on-device guardian the Warden commands. The [SDK](/docs/sdk) wraps the same governance in two lines of code. ## Your AI, on your terms The Warden is a chat shell that *is* the app. You type a natural-language request. A deterministic agent reasons, calls governed tools, retrieves from the knowledge graph, and answers with either a snippet, a direct change, or a rich server-driven UI component mounted inline in the chat turn. A risk register table. A compliance heatmap. A full vendor dashboard. A 3D risk sphere. Every step is signed and hash-chained. [Diagram: WardenFleetCommand] ## Two things make this more than a chat wrapper Two properties make the Warden structurally different from a chat wrapper, and both are observable in every run: No backdoor The agent's tool calls go through the same governed proxy The Warden does not have a parallel "AI tool" surface. Its tool calls are governed trinitite.* MCP tools routed through the same pre and post governance and audit pipeline as any external tool. Masking, action-guards, NHI-tier filtering, and the hash-chained audit all apply. There is no bypass path. Same answer every time A brain that returns the same bytes for the same input The agent's inference calls go to a determinism-eligible model on a batch-invariant kernel. Same inputs, same tokens, a signed and replayable chain of receipts per run. Regulated work mandates this. A non-deterministic frontier model would silently invalidate the receipts. The first means the Warden inherits governance for free. The second means every run is provable, not promised. See [Receipts](./receipts) for the full attestation story and the fork-from-checkpoint rewind. ## Read the section [The composer and the thread Chat shell The composer, the sidebar, streaming turns, the settled turn anatomy, rating and feedback, fork from any turn.](./chat-shell) [Scope what an agent can touch Named agents A named agent is a scoped configuration. Bind a subset of MCP servers, tools, and skills. Set the NHI tier, required permissions, model, system prompt, and guardian id.](./named-agents) [Copy-paste prompts Prompts The featured first-run prompt and a library of asks across masking, scoping, audits, remediation, the risk register, evals, and red-team. Each with an expected outcome.](./prompts) [Rich views, mounted in the turn Inline UI The agent mounts rich components inline in a chat turn: risk tables, heatmaps, 3D risk spheres, dashboards, the estate graph, and full workbench pages. Plus generative UI trees.](./inline-ui) [Opt-in and forgettable Memory Memory is opt-in, off by default, and forgettable at any granularity. The Personalized pill, the capture row, per-memory forget, and the bulk wipe.](./memory) [Provable, not promised Receipts Every run is a hash-chained sequence of signed receipts. Fork from any step. The step drawer with per-step rewind. The five receipt families.](./receipts) [Bring your own key BYOK models Pick a frontier model per turn from 12 providers. Regulated work stays on the deterministic brain regardless. Leaving a frontier model selected is safe.](./byok-models) ## Where the Warden fits The Warden is the conversational layer that oversees the guardian fleet. The [Emu desktop app](/docs/emu) is the on-device guardian the Warden commands, running the same governance beside you instead of in a data center. The [SDK](/docs/sdk) wraps the same governance in two lines of code for the AI you build yourself. All three run the same deterministic kernel. Go build it: start with [Prompts](./prompts) for a copy-paste ask you can try right now, or read [Chat shell](./chat-shell) first if you want the full anatomy of a run before you type. ================================================================================ Page: Architecture URL: https://docs.trinitite.ai/docs/architecture ================================================================================ # The Guardian Architecture **Civil Engineering for Cognition.** The transition from AI-as-publisher to AI-as-operator has fundamentally altered the liability surface of enterprise software. A language model that writes emails has a hallucination problem. A language model that executes SQL queries, initiates transfers, and triggers automations has a **governance problem**. Trinitite's answer is structural: install a deterministic control layer between the probabilistic Actor and the execution environment. Not a filter. Not a prompt. A **Guardian** — built on the same engineering principles that stabilized aviation, finance, and operating systems over the last century. > Stat banner: latency, variance, and throughput targets for the Guardian. --- ## The Platform at a Glance Trinitite is not a single service. It is a **stack of governed intermediaries** — identity, data plane, intelligence, trust — that all share one Guardian evaluation kernel, one identity model, and one audit ledger. This is the map. Every box links to its own deep-dive. > Diagram: the Trinitite platform at a glance. A stack of governed intermediaries (identity, data plane, intelligence, trust) sharing one Guardian evaluation kernel, one identity model, and one audit ledger. --- ## The Three Outcomes Every response from your AI passes through a Guardian. The Guardian makes exactly one decision: > Diagram: the three outcomes. Passed, Corrected, Blocked. This is not a content filter. The Guardian is a trained model that understands your policies geometrically — mapping output vectors against a Policy Manifold — and either passes, surgically repairs, or blocks the output before it reaches your infrastructure. --- ## The Intercept Flow > Diagram: the intercept flow. AI model -> Guardian (intercept, evaluate, rectify, log) -> application. The Guardian sits inline between your AI model and your application. It intercepts the raw output vector, evaluates it against the active Policy Manifold, applies Semantic Rectification if needed, and logs every decision to the Glass Box Ledger. Your application receives one of three outcomes. The workflow continues. No re-generation. No human-in-the-loop for the common case. --- ## Why Separation of Concerns The failure of "Native Safety" — prompt engineering, RLHF guardrails, output filters — is not a code problem. It is a **topology problem**. We are currently asking the same neural parameters to be both the Artist (creative, stochastic) and the Censor (restrictive, deterministic). These objectives are mathematically incompatible. The Guardian Architecture enforces a strict bifurcation: the Actor is permitted to be creative and prone to failure. The Guardian is cold, binary, and deterministic. Decades of engineering precedent support exactly this pattern. > Diagram: engineering precedents for the Actor/Guardian split (aviation, finance, operating systems). --- ## Batch-Invariant Determinism The central failure mode of native safety under load is **floating-point non-associativity**. Modern GPU inference engines dynamically change their reduction strategy based on server load — splitting Key-Value cache calculations differently at batch size 1 vs. batch size 128. This changes the accumulation order of floating-point operations, which cascades through Chain-of-Thought reasoning, causing the model's safety posture to drift. The result: attack vectors that were blocked in the lab breach the system in production. Our validation data quantified this at **21.4% safety drift** in production Thinking models. The Guardian solves this by enforcing a **Fixed-Size Split-KV Strategy**: the tile size of the KV cache reduction is locked in software (e.g., 256 elements) regardless of batch size or hardware utilization. This forces the GPU to execute the exact same accumulation tree for request `N` whether it is the only request on the server or one of ten thousand. **The Engineering Implication** > Bitwise reproducibility is now an off-the-shelf commodity. Open-source inference engines (SGLang, vLLM) already support it via configuration flags. The failure to implement it is no longer a capability gap — it is a fiduciary choice to operate without available safety controls. ``` Native Safety: Batch Size 1 → [A + B + C] = safe Batch Size 128 → [C + A + B] = unsafe ← floating-point non-associativity Guardian: Batch Size 1 → Fixed tile → [A + B + C] = safe Batch Size 128 → Fixed tile → [A + B + C] = safe ← 0.00% variance ``` --- ## Semantic Rectification When an output vector falls in a Forbidden Zone, the Guardian does not block it by default — blocking causes workflow disruption. Instead, it calculates the **Difference Vector** required to shift the output to the nearest Safe Centroid in the Policy Manifold, and returns that as an RFC 6902 JSON Patch. > Diagram: Semantic Rectification. An unsafe output vector is shifted to the nearest Safe Centroid and returned as an RFC 6902 JSON Patch. This is not "fancy regex." Regex looks for syntax (`DROP TABLE`). It fails against obfuscation (`D_R_O_P T_A_B_L_E`), semantic variation, or base64-encoded commands. Rectification looks for **semantic intent** — vector space coordinates. If an attacker uses pig latin to request a database deletion, the embedding model maps "deletion" to the same vector coordinates regardless of syntax. The Guardian identifies the vector in the Destructive Zone and applies a transformation matrix to shift it into the Read-Only Zone. The resulting text is reconstructed from the safe vector. **The result:** corrections handle intent (the "Why"), not just syntax (the "What"). ### The Safe Snap The Guardian is not permitted to invent corrections. It can only snap to **Pre-Validated Centroids** — safe states that have already passed the Test-Driven Governance suite. This means every correction is a mathematically proven safe state, not a guess. The system collapses undefined behavior into defined, tested behavior. --- ## The Glass Box Ledger Every governance decision is written to an append-only, cryptographically chained ledger: the **State-Tuple Ledger**. Each block captures: `(timestamp, input_hash, policy_hash, outcome, corrections, governance_hash)` — chained as `H_n = Hash(H_{n-1} || S_n)`. > Diagram: the Glass Box Ledger. Append-only, Merkle-chained State-Tuple blocks. If a single byte of a log entry from three months ago is altered, the current block's hash fails validation. This guarantees **non-repudiation**: neither the enterprise nor its AI provider can deny an action that occurred. ### Why this matters in court In civil aviation, the National Transportation Safety Board distinguishes between Pilot Notes (mutable, subjective) and the Flight Data Recorder (objective, hardened). When the FDR data contradicts the pilot's testimony, the FDR wins. Standard chat logs are Pilot Notes. The State-Tuple Ledger is the FDR. It records the vector state, the active policy hash, and the rectification delta. Without it, your defense relies on hearsay. With it, your evidence is science. **Forensic Replayability:** because Guardians are batch-invariant, you can take any input vector from the log and replay the event with bitwise precision. This turns the platform into a flight simulator for debugging — rewind the tape, adjust the variables, and prove the fix works before redeployment. --- ## Self-Hosted Deployment > Banner: self-hosted, container-native, engine-agnostic. > Diagram: the self-hosted deployment topology. ### Deployment stack ```yaml # docker-compose.yml services: control-plane: image: trinitite/control-plane:latest ports: - "8080:8080" environment: - DB_TYPE=postgres - LEDGER_ADAPTER=s3_worm - LORA_STORAGE_ADAPTER=s3 governance: image: trinitite/governance:latest ports: - "8000:8000" environment: - INFERENCE_ENGINE=sglang - ENABLE_LORA=true - ENABLE_DETERMINISTIC_INFERENCE=true volumes: - ./manifolds:/manifolds - ./guardians:/guardians ``` **The redirect is one environment variable:** ```bash # Before OPENAI_BASE_URL=https://api.openai.com/v1 # After — route through the Guardian proxy OPENAI_BASE_URL=http://localhost:8080/v1/proxy ``` Your application doesn't change. The platform intercepts all traffic, applies governance, and proxies the inference call to your configured backend. ### Persistence adapters The ledger backend is pluggable — swap it via environment variable with zero code changes: | Tier | Backend | Use case | |------|---------|----------| | **Standard** | S3 Object Lock / WORM | Commercial durability, adverse-inference defense | | **Managed** | Cloud KMS / HSM | Regulatory separation of duties | | **Sovereign** | Hardware TEE (Nvidia Confidential Computing) | Nation-state non-repudiation | | **Edge** | SQLite | Air-gapped / on-premise deployments | --- ## Integration Patterns > Diagram: integration patterns (proxy redirect, direct govern call). ### Pattern A in practice ``` Application Guardian Proxy (your VPC) │ │ │ POST /v1/proxy/chat/completions │ │ {model: "gpt-4o", ...} │ │ ───────────────────────────────► │ │ │ → intercept │ │ → evaluate vector │ │ → apply rectification │ │ → log to ledger │ │ → proxy to OpenAI │ │ ← receive raw response │ │ → re-evaluate response │ ◄────────────────────────────── │ │ {clean, governed response} │ ``` ### Pattern B in practice ``` Application Guardian (your VPC) │ │ │ (your AI call, your code) │ │ raw_output = ai.complete(...) │ │ │ │ POST /v1/chat │ │ {guardian: "PII-Redactor", │ │ instructions: "...", │ │ input: [..., raw_output]} │ │ ───────────────────────────────► │ │ │ │ ◄────────────────────────────── │ │ {status: "corrected", │ │ corrections: [...]} │ │ │ │ apply(raw_output, corrections) │ ``` --- ## Federated Defense > Diagram: Federated Defense. A threat discovered against one fleet member vaccinates the rest. ### LoRA architecture Guardians use **Low-Rank Adaptation (LoRA)** to represent policies as lightweight tensor files — megabytes, not gigabytes. This enables: - **Per-request policy switching** — HIPAA for one request, SOC 2 for the next, in the same batch - **Hot-swap updates** — new policies applied in sub-millisecond pointer swaps, no restarts - **Non-destructive patching** — extend an existing Guardian's capabilities without retraining from scratch - **Stacked policies** — baseline universal safety + custom enterprise rules combined via vector summation ```python # Extend an existing Guardian with a new threat vector from peft import PeftModel model = PeftModel.from_pretrained( base_model, "./guardian-pii-v1.0", is_trainable=True # unlock the LoRA weights for the patch ) # Oracle-guided distillation on the new threat data # → new weights saved to ./guardian-pii-v1.1 ``` --- ## Test-Driven Governance A Guardian's Policy Manifold is not static. It expands through **Test-Driven Governance (TDG)** — the application of software TDD principles to AI policy. Every identified failure mode becomes a permanent constraint: ``` Red → New threat vector identified. Guardian does not block it. Green → Vector ingested. Guardian trained. Test now passes. Lock → That specific failure mode is mathematically impossible. Forever. ``` This creates a **Safety Ratchet**: the known liability surface only shrinks. It never expands. ### Automated from existing assets You don't start from scratch. Point the platform's ingestion adapter at your existing documentation, compliance policies, or incident logs: 1. **Drop a PDF** — compliance policy, employee handbook, MSA 2. The Teleological Engine extracts explicit constraints ("Section 4.2: no gifts over $50") 3. Generates `n` number of adversarial variations attempting to violate that rule 4. Trains a Guardian that blocks all of them 5. **Zero-touch deployment** to your fleet Your compliance documents become your enforcement physics. --- ## Explore the Platform Thirteen deep-dive pages cover every surface above. Each page ships with its own hand-drawn diagrams, request lifecycles, and forensic replay story. > Grid: links to the deep-dive pages across the platform. --- ## MCP Governance The Model Context Protocol (MCP) shifts the AI risk surface from text generation to **tool execution**. An agent that calls `stripe.create_refund`, `postgres.query`, or `aws.iam.create_role` isn't writing — it's acting. A single malformed argument, injected parameter, or misrouted intent is no longer an embarrassing output. It's a financial transaction, a database modification, or an infrastructure change. Trinitite intercepts every MCP tool call before it reaches the transport layer — validating not just the schema but the **semantic intent** of the call. Wrong argument type, suspicious parameter value, malicious override attempt, or scope violation: the Guardian catches it, corrects what can be corrected, and blocks what cannot. ### Two deployment topologies > Diagram: the two MCP deployment topologies (Gateway, Client-Side Middleware). Both patterns provide identical governance guarantees. The difference is where the intercept point lives — at the network edge (Gateway) or embedded in-process within the MCP Client (Middleware). For most deployments, **Client-Side Middleware is recommended**: no network hop, deepest integration, lowest latency. ### Autocorrection in action > Diagram: MCP autocorrection in action. The LLM outputs a syntactically wrong argument, the Guardian intercepts, calculates the correct value, and issues a JSON Patch before the call reaches the MCP Server. This is Semantic Rectification applied to tool calls. The LLM outputs `{"limit": "N/A"}` — syntactically wrong, semantically ambiguous. The Guardian intercepts it, identifies the violation against the tool's schema, calculates the correct value, and issues a JSON Patch that replaces `"N/A"` with `100` before the call ever reaches the MCP Server. No re-generation. No workflow interruption. No user-facing error. ### Per-tool-call Guardians Every tool call gets its own specialist Guardian. Not a generic safety filter — a **hyper-specific model trained on that exact API operation's schema, semantics, and threat surface**. > Diagram: per-tool-call Guardians. A base Guardian plus a specialist LoRA adapter per tool, trained on that tool's schema and threat surface. The architecture stacks in two layers: **Base Guardian** — universal safety infrastructure shared across all tool calls: batch-invariant determinism, semantic rectification engine, Glass Box Ledger, LoRA hot-swap. This is the physics layer. **Tool Guardian** — a specialist LoRA adapter trained on the specific tool. It knows what a valid `stripe.create_refund` looks like. It knows the difference between a legitimate `postgres.query` and a SQL injection attempt. It knows that `aws.iam.create_role` with a wildcard policy is suspicious regardless of how the LLM justified it. The Teleological Data Generator creates thousands of adversarial variations per tool call — catching syntax errors, intent attacks, schema mismatches, privilege escalation attempts, and semantic misuse — all while remaining strictly compliant with the tool's underlying API schema. The result is a Guardian that's simultaneously **permissive for legitimate use** and **deterministically blocking for everything outside the safe manifold**. ### Pre-built Guardians from the platform Trinitite ships pre-built Guardians for the most common MCP integrations — ready to deploy, already hardened against known attack patterns for that service. > Grid: pre-built Guardians for common MCP integrations. For any tool call not covered by a pre-built Guardian, the platform **automatically generates the training data** from your tool definition or OpenAPI spec, trains the Guardian, and adds it to your fleet. The same Teleological Data Generator that trains the base Guardian operates on every new tool schema — you get a hardened, schema-aware Guardian without writing a single training example manually. **Pre-built + custom = best of both** > Use Trinitite's pre-built Guardians for standard APIs and automatically-generated Guardians for your custom tools. Both sit on the same base architecture, ship via the same LoRA hot-swap mechanism, and write to the same Glass Box Ledger. Your entire MCP fleet — standard and custom — governed with one system. ### What gets governed Every MCP tool call passes through a Guardian before transport. For each call, the Guardian evaluates: | Check | What it catches | |-------|----------------| | **Schema validation** | Wrong types, missing required fields, malformed values | | **Semantic intent** | Calls that are syntactically valid but semantically dangerous (e.g., `DELETE` disguised as a read operation) | | **Argument injection** | Prompt-injected values in parameters attempting to override system behavior | | **Scope enforcement** | Calls that exceed the authorized scope for the current session, NHI, or user role | | **Pattern matching** | Known attack signatures from the Trinitite threat intelligence network | The outcome is the same three states as the base Guardian — **Passed**, **Corrected**, or **Blocked** — with a full forensic record in the Glass Box Ledger for every decision. --- ## Architecture Summary | Layer | Component | Role | |-------|-----------|------| | **Inference** | Batch-Invariant Kernel | Eliminates floating-point drift across load | | **Control** | Policy Manifold | Geometric definition of safe/unsafe vector space | | **Correction** | Semantic Rectifier | Projects unsafe vectors to nearest Safe Centroid | | **Tool Calls** | Per-Tool Guardian | Schema-trained specialist per MCP tool operation | | **Generation** | Teleological Data Generator | Auto-synthesizes adversarial variations per tool schema | | **Distribution** | LoRA Hot-Swap | Per-request policy, zero-downtime updates | | **Audit** | Glass Box Ledger | Cryptographic, forensic, Daubert-admissible | | **Immunity** | Federated Defense | Fleet-wide vaccination from single threat discoveries | **Self-hosted. Container-native. Engine-agnostic.** Trinitite secures a model running on vLLM, a proprietary agent on SGLang, or your own inference stack — provided the underlying engine supports deterministic execution. --- ## Every Surface, One Guardian The thirteen deep-dives above are not thirteen separate products. They are thirteen views into one system. > Diagram: every surface, one Guardian. A policy written once, a Guardian trained once, a ledger entry written once, visible everywhere. A policy written once, a Guardian trained once, and a ledger entry written once — visible in the proxy, the MCP gateway, the CLI firewall, the compliance export, and the public verification path, simultaneously. That property is what makes Trinitite auditable end-to-end. --- ## Next Steps → **[Authentication](/api-reference/authentication)** — Get your API key → **[Chat (Guardian Mode)](/api-reference/chat-endpoint)** — Send output, receive verdict → **[Guardians API](/api-reference/guardians-endpoint)** — Create and manage Guardians → **[MCP Gateway](/api-reference/mcp-gateway-endpoint)** — Govern Model Context Protocol tool calls