Capture sources, cite exact text and promote a candidate only when Rust verifies it against a host-pinned typed rule and the complete reviewed evidence set. RC5 adds this semantic-fact verification; a model assertion alone cannot promote a fact.
When to use this
Use this when a workpaper claim needs typed corroboration from an operator-reviewed complete source set, including contrary observations.
Install the matching API preview
These examples use the API 2 preview, not names promised by the public RC5 release. Existing RC5 entry points remain available. The Python wheel below is verified on Windows x64; it is not a cross-platform release.
python -m pip install https://docs.soterias.io/downloads/api-preview/soterias_local-0.1.0rc5%2Bapi2-cp311-abi3-win_amd64.whlnpm install https://docs.soterias.io/downloads/api-preview/soterias-core-0.1.0-rc.5-api.2.tgz
npm install --save-dev typescript@5.8.3 @types/node@24Python imports soterias. TypeScript imports @soterias/core. Use Python 3.11+ for this wheel and Node 22.23.4+ for these examples. For a .mts file, compile with npx tsc example.mts --target ES2022 --module NodeNext --moduleResolution NodeNext --skipLibCheck, then run the emitted .mjs file.
Before you run
The programs create synthetic ledger/bank files and their own encrypted native store. No model, server or account is required. The public unlock is for these disposable examples only. Origin independence is an operator assertion checked against the recorded source lineage, not something the SDK can discover universally.
Application walkthrough
Choose Python or TypeScript. Create example.py or example.mts and append that language's chunks in order. Each language forms one complete program; indentation and open blocks carry across chunks.
Import the packages
Import the SDK and standard-library helpers. These are the real package exports used by the executable program.
"""Local accounting corroboration through the native Rust verifier; no model/account."""
import json
from pathlib import Path
import tempfile
import time
from soterias import Citation, TrustedFactReference, SourceStore, SourceStoreError
root = Path(tempfile.mkdtemp(prefix="soterias-semantic-"))
started = time.perf_counter_ns()
now = time.time_ns() // 1_000_000
unlock = b"public-disposable-example-unlock"
store = SourceStore.create(root / "store", passphrase=unlock, tenant_id="demo", store_id="audit")
evidence = store.evidence(principal="auditor", purpose="transaction-testing")
sources, citations = [], []
for origin in ("ledger", "bank"):
text = json.dumps({"invoice": "INV-1", "total": 1200, "origin": origin})
path = root / (origin + ".json")
path.write_bytes(text.encode())
source = store.ingest_file(path, media="utf8_text", permitted_uses=["transaction-testing"], captured_at_ms=now)
evidence.register_source(source, identity=origin, revision="v1", readers=["auditor"],
stale_after_ms=now+600_000, retain_until_ms=now+1_200_000)
sources.append(source)
citations.append(Citation(source, start=0, end=len(text), quote=text))// Real encrypted accounting evidence, shared Rust semantics; no model/account.
import assert from 'node:assert/strict';
import {mkdtempSync,writeFileSync} from 'node:fs';
import {tmpdir} from 'node:os';
import {join} from 'node:path';
import {Citation, TrustedFactReference, SourceStore, SourceStoreError} from '@soterias/core';
import type {SourceReference} from '@soterias/core';
const started=performance.now(),root=mkdtempSync(join(tmpdir(),'soterias-semantic-')),now=Date.now();
const unlock=Buffer.from('public-disposable-example-unlock');
let store=SourceStore.create({directory:join(root,'store'),passphrase:unlock,tenantId:'demo',storeId:'audit'});
let evidence=store.evidence({principal:'auditor',purpose:'transaction-testing'});
const sources:SourceReference[]=[],citations:Citation[]=[];
for(const origin of ['ledger','bank']){
const text=JSON.stringify({invoice:'INV-1',total:1200,origin}),path=join(root,origin+'.json');
writeFileSync(path,text);
const source=store.ingestFile(path,{media:'utf8_text',permittedUses:['transaction-testing'],capturedAtMs:now});
evidence.registerSource(source,{identity:origin,revision:'v1',readers:['auditor'],staleAfterMs:now+600000,retainUntilMs:now+1200000});
sources.push(source);citations.push(new Citation(source,{start:0,end:[...text].length,quote:text}));
}
// Trusted application setup; never expose this rule or keys as agent tools.
const rule=evidence.installSemanticRule({predicate:'amount_minor_units',subjectPointer:'/invoice',valuePointer:'/total',sources:citations.map((citation,i)=>({origin:['ledger-origin','bank-origin'][i],citation}))});
const claim=JSON.stringify({subject:'INV-1',predicate:'amount_minor_units',value:{type:'integer',value:'1200'}});
const candidate=evidence.extractInterpretation(claim,{citations,uncertainty:[]});
const promotion=evidence.promoteFact(candidate,{rule});Step 2
Keep the exact acknowledged checkpoint. Reopening with an older pin is an error; do not silently discover and adopt newer state.
# Trusted application setup. The operator reviews independence and the complete
# evidence set. Agents must never receive this configuration or source-store keys.
rule = evidence.install_semantic_rule(predicate="amount_minor_units", subject_pointer="/invoice",
value_pointer="/total", sources=list(zip(("ledger-origin", "bank-origin"), citations)))
claim = json.dumps({"subject": "INV-1", "predicate": "amount_minor_units",
"value": {"type": "integer", "value": "1200"}})
# Empty uncertainty is a candidate assertion, never proof. Rust independently
# verifies the value under the preconfigured rule before persisting any promotion.
candidate = evidence.extract_interpretation(claim, citations=citations, uncertainty=())
promotion = evidence.promote_fact(candidate, rule=rule)
assert promotion["promoted"] is True
assert promotion["report"]["classification"] == "corroborated"
reference = TrustedFactReference(promotion["reference"]["digest"])
assert evidence.check_trusted_fact(reference)["report"]["truth"] == "proven"
checkpoint = store.checkpoint()
store.close()
store = SourceStore.open(root / "store", passphrase=unlock, checkpoint=checkpoint)
evidence = store.evidence(principal="auditor", purpose="transaction-testing")
assert evidence.check_trusted_fact(reference)["report"]["truth"] == "proven"
evidence.revoke_source(sources[0])
try:
evidence.check_trusted_fact(reference)
raise AssertionError("revoked source was accepted")
except SourceStoreError as error:assert(promotion.promoted);assert.equal(promotion.report.classification,'corroborated');
const reference=new TrustedFactReference(promotion.reference.digest);
const check=()=>{const result=evidence.checkTrustedFact(reference);assert('report' in result);return result.report;};
assert.equal(check().truth,'proven');
const checkpoint=store.checkpoint();store.close();
store=SourceStore.open({directory:join(root,'store'),passphrase:unlock,checkpoint});
evidence=store.evidence({principal:'auditor',purpose:'transaction-testing'});
assert.equal(check().truth,'proven');
evidence.revokeSource(sources[0]);
assert.throws(()=>evidence.checkTrustedFact(reference),e=>e instanceof SourceStoreError&&e.code==='evidence_source_revoked');
store.close();unlock.fill(0);
console.log(JSON.stringify({status:'PASS',root,elapsed_ms:performance.now()-started,model_calls:0,provider_tokens:null,reports_signed:false,scope:'host-pinned typed verification; not universal truth'}));Step 3
Check the result against independent evidence and retain refusals. The assertion makes this example fail if native verification behaves differently.
assert error.code == "evidence_source_revoked"
finally:
store.close()
print(json.dumps({"status":"PASS", "root":str(root), "elapsed_ms":(time.perf_counter_ns()-started)/1e6,
"model_calls":0, "provider_tokens":None, "reports_signed":False,
"scope":"host-pinned typed verification; not universal truth"}))MCP composition
This complete example creates a reviewed rule on the trusted host, then starts a loopback HTTP MCP host and calls its real semantic-fact tool. It checks that agent context cannot install or replace the rule. Save it as mcp.mjs and run node mcp.mjs. Its bearer is disposable application authentication; it is not a warrant or a grant of execution authority.
Install the matching adapter with npm install https://docs.soterias.io/downloads/api-preview/soterias-mcp-server-0.1.0-rc.5-api.2.tgz. Its SDK peer dependency shares the same native class identities as your installed preview.
mcp.mjs
Create mcp.mjs and append these chunks in order. Together they form one complete program; indentation carries across chunks.
Step 1
Import the SDK and standard-library helpers. These are the real package exports used by the executable program.
// Actual loopback HTTP/MCP component test, with real Rust-backed evidence.
// The bearer token is disposable application authentication, not a native warrant.
import assert from 'node:assert/strict';
import http from 'node:http';
import {randomBytes,timingSafeEqual} from 'node:crypto';
import {mkdtempSync,writeFileSync} from 'node:fs';
import {tmpdir} from 'node:os';
import {join} from 'node:path';
import {McpServer,createMcpHandler} from '@modelcontextprotocol/server';
import {toNodeHandler} from '@modelcontextprotocol/node';
import {Client,StreamableHTTPClientTransport} from '@modelcontextprotocol/client';
import {Citation,TrustedFactReference,SourceStore} from '@soterias/core';
import {registerSemanticFactTool} from '@soterias/mcp-server/semantic-facts';
const root=mkdtempSync(join(tmpdir(),'soterias-semantic-mcp-')),now=Date.now();
const store=SourceStore.create({directory:join(root,'store'),passphrase:Buffer.from('public-disposable-mcp-example'),tenantId:'demo',storeId:'audit'});
const evidence=store.evidence({principal:'auditor',purpose:'audit'}),sources=[],citations=[];
for(const origin of ['ledger','bank']){
const text=JSON.stringify({invoice:'INV-1',total:1200,origin}),file=join(root,origin+'.json');writeFileSync(file,text);
const source=store.ingestFile(file,{media:'utf8_text',permittedUses:['audit'],capturedAtMs:now});
evidence.registerSource(source,{identity:origin,revision:'v1',readers:['auditor'],staleAfterMs:now+600000,retainUntilMs:now+1200000});
sources.push(source);citations.push(new Citation(source,{start:0,end:text.length,quote:text}));
}
const rule=evidence.installSemanticRule({predicate:'amount_minor_units',subjectPointer:'/invoice',valuePointer:'/total',sources:citations.map((citation,i)=>({origin:['ledger-origin','bank-origin'][i],citation}))});
const candidate=evidence.extractInterpretation(JSON.stringify({subject:'INV-1',predicate:'amount_minor_units',value:{type:'integer',value:'1200'}}),{citations,uncertainty:[]});Step 2
Build the next part of the local workflow. Values defined in earlier chunks remain in scope; concatenate the chunks in their displayed order.
const promoted=evidence.promoteFact(candidate,{rule});assert.equal(promoted.promoted,true);
const reference=new TrustedFactReference(promoted.reference.digest);
const server=new McpServer({name:'soterias-semantic-component',version:'1.0.0'});
registerSemanticFactTool(server,{repository:evidence,facts:[{name:'invoice_amount',reference}]});
const handler=createMcpHandler(()=>server,{maxSubscriptions:0,maxRequestBodySize:16384,onerror:()=>{}});
const dispatch=toNodeHandler(handler,{maxRequestBodySize:16384,onerror:()=>{}});
const token=randomBytes(32).toString('base64url'),expected=Buffer.from('Bearer '+token);
const listener=http.createServer((req,res)=>{
const got=Buffer.from(req.headers.authorization??'');
if(got.length!==expected.length||!timingSafeEqual(got,expected)){res.writeHead(401);res.end();return;}
if(req.url!=='/mcp'){res.writeHead(404);res.end();return;}
void dispatch(req,res);
});
await new Promise((resolve,reject)=>{listener.once('error',reject);listener.listen(0,'127.0.0.1',resolve);});
const url=new URL('http://127.0.0.1:'+listener.address().port+'/mcp');
const client=new Client({name:'semantic-fact-component-test',version:'1.0.0'});
let checks=0;
try{
assert.equal((await fetch(url,{method:'POST',body:'{}'})).status,401);checks++;
await client.connect(new StreamableHTTPClientTransport(url,{requestInit:{headers:{Authorization:'Bearer '+token}}}),{timeout:15000});
const tools=await client.listTools();assert.deepEqual(tools.tools.map(t=>t.name),['check_trusted_fact']);checks++;
assert.equal(tools.tools[0].inputSchema.additionalProperties,false);checks++;
const result=await client.callTool({name:'check_trusted_fact',arguments:{fact:'invoice_amount'}});
assert.equal(result.structuredContent.report.truth,'proven');checks++;Step 3
Check the result against independent evidence and retain refusals. The assertion makes this example fail if native verification behaves differently.
const forged=await client.callTool({name:'check_trusted_fact',arguments:{fact:'invoice_amount',principal:'other',nowMs:now,trusted:true}});
assert(forged.isError);checks++;
const unknown=await client.callTool({name:'check_trusted_fact',arguments:{fact:'other_fact'}});assert(unknown.isError);checks++;
evidence.revokeSource(sources[0]);
const revoked=await client.callTool({name:'check_trusted_fact',arguments:{fact:'invoice_amount'}});
assert.equal(revoked.isError,true);assert.equal(revoked.structuredContent.error,'trusted_fact_unavailable');checks++;
console.log(JSON.stringify({status:'PASS_ACTUAL_HTTP_SEMANTIC_COMPONENT',checks,root,native_warrant_authentication:false,named_client_acceptance:false,reports_signed:false}));
}finally{
await client.close();await handler.close();listener.closeIdleConnections();
await new Promise((resolve,reject)=>listener.close(e=>e?reject(e):resolve()));store.close();
}Check the result
The application program prints a JSON result and preserves native refusals. For protected operations inspect status and target_observed: transport success does not imply a completed effect. The pure examples contain assertions for their exact expected values. Successful startup is not proof of production enrollment, a physical human review or current authority.
Put it into a workflow
Use the AML walkthrough for protected document reads, reviewed writes and signed outcome checks. Use multi-agent workflows for personal and enterprise orchestration. Keep each agent's proposals separate from operator authority.