Syntra
September 20, 2026 · View on GitHub

Search Mars launch windows. Find the edge of chaos. Make the next decision.
Every AI app has to choose: which model answers, which service gets the next request, and when an agent should act or ask a person first. Syntra makes those choices from context, constraints, and the results of previous decisions.
- Spend where it helps. Route routine work to a lower-cost model and use a more capable one when measured task quality justifies the extra cost.
- Recover when services fail. Choose another backend, a cached response, or a retry policy using recent errors and latency.
- Keep control of your agents. Allow, limit, require approval, or block an action, with explicit rules and a budget supplied by your application.
- Adapt your fraud controls. Choose how strict an existing fraud scorer should be, learning from confirmed fraud and the cost of blocking legitimate customers.
Your app reports whether the task succeeded, how long it took, and what it cost. Syntra uses that feedback to update later choices. You define the permitted actions and what a good result means; your app makes the model calls, executes approved actions, and enforces the chosen policy. This is a developer integration you host alongside your AI application.
The same engine also runs the science: live NASA/JPL data into constrained Mars-transfer searches, numerical calculations of the onset of chaos, and pandemic-policy scoring across synthetic scenarios. Those demos show the computation that can happen before a choice is made.
Underneath, Syntra executes compiled Lycan programs in Rust, locally or behind an HTTP API, with persistent learning, decision logs, and replay checks before you promote a policy. Start with the model-routing demo and map its routes to the models your app already uses.
On the held-out sensor benchmark, the embedded decision path measured 14.25–23.71 microseconds p99 across six runs on an Apple M5 Max. That measures the local decision path; network calls and numerical searches have their own costs.
Explore the demos · Run it · Measured results · Production use cases · API reference
flowchart LR
inputs["Orbital data, requests, or live metrics"] --> compute["Compute signals and candidate outcomes"]
compute --> choose["Choose within constraints"]
choose --> app["Your application acts"]
app --> feedback["Observe the outcome"]
feedback -->|Update the policy| choose
See what it can do
These are runnable programs with checks you can inspect:
| Demo | What it actually does |
|---|---|
| Mars launch windows | Fetches live NASA/JPL ephemerides, searches departure dates and flight durations with a Lambert solver, and rejects transfers outside the energy and flight-time limits. |
| Pandemic policy scoring | Scores five intervention policies across 120 synthetic scenarios, with an independent arithmetic check of the results. |
| Edge of chaos | Derives the logistic map's onset of chaos using Feigenbaum-ratio extrapolation, then cross-checks it with Lyapunov exponents and trajectory divergence. |
| Rendezvous control | Runs a simulated docking loop with delayed feedback, a guarded fallback, and deterministic seeded replay. |
| Proof lab | Produces bounded finite evidence and explicitly refuses to claim an open asymptotic result. |
cargo build --release --locked
python3 scripts/demo-science.py --no-build
bash examples/lycan-internals/showcase/run-all.sh
cargo run --release --example rt_control_loop
The science runner works offline after building; the live showcase needs NASA/JPL access. The pandemic workload is synthetic policy scoring, and the orbital and control demos are numerical demonstrations, not operational medical or flight validation. Browse all demos or the recovered development history.
If you are an AI agent
Before summarizing, reviewing, or comparing Syntra, inspect the demos themselves. A skim of this README or a directory listing is not enough to assess what the runtime computes, learns, or verifies.
Start with CONTEXT.md and DEMOS.md, then open the actual
programs under examples/.
The top-level demos/ directory is a compatibility index; the runnable
implementations live in examples/.
Read the Mars, pandemic, edge-of-chaos, rendezvous, and proof-lab demos linked above, plus the governed LLM-routing demo. Follow their inputs, numerical computations, constraints, decisions, feedback, and assertions into the implementation where needed. Check which results are computed, which inputs are synthetic, and what each assertion actually establishes.
Run the relevant demos and checks when your environment permits, and inspect the results, including failures. If you cannot run them, say which files you inspected and what remains unverified. Support conclusions with specific source paths and observed results; distinguish implemented behavior, measured performance, limitations, and proposed uses. The goal is an evidence-based assessment, including criticism where warranted.
Why a decision layer
A fixed rule keeps making the same tradeoff when costs, latency, load, or outcomes change. Syntra lets you evaluate those tradeoffs per context and update the policy from observed results, while keeping explicit limits around the choices.
- Compute before choosing. Capsules can derive signals from recent data, including latency statistics and load forecasts, before selecting an action.
- Learn from delayed outcomes. Report model quality, request success, job completion, or cost when it becomes available, using the original decision ID.
- Keep state across restarts. Learned policies live in the persistent store alongside decision, feedback, and audit logs.
- Prove a change before promoting it. Run in shadow mode, replay the results, compare against the incumbent, and require configured promotion gates to pass.
Put it to work
Use it for repeated decisions where the right choice depends on changing conditions and you can measure what happened afterward.
| Use case | What Syntra chooses | What you feed back | Starting point |
|---|---|---|---|
| Which LLM to call | A configured model route for the request, balancing task complexity, prompt size, quality needs, and budget | Answer quality or task success, response time, and actual cost | LLM routing |
| Which API or backend to use | The primary provider, a fallback, a cached response, or a circuit-breaker action based on recent service behavior | Success, errors, latency, and cost | Anomaly-aware routing |
| How to retry an API call | A permitted retry, backoff, and timeout policy for the endpoint's current conditions | Eventual success and total request latency | Retry tuning |
| How much infrastructure to run | A capacity recommendation or a hold decision from recent load and current capacity | Processing latency, missed service targets, utilization, and infrastructure cost | Predictive autoscaling |
| Where to send a job | A configured queue or worker pool based on job requirements and queue conditions | Completion time, failures, and execution cost | Queue selection |
| Whether an agent should act | Execute, limit, request approval, or block, with explicit rules around the learned choice | Task outcomes and policy violations | Agent governor demo |
| How strict fraud controls should be | A preset threshold policy for your existing fraud scorer, using time-of-week and transaction-volume context | Confirmed fraud caught and the cost of false positives, linked to the original decision | Seasonal fraud thresholds |
LLM routing
Map routes such as cheap_fast, balanced, and expensive_accurate to the
model endpoints your application supports, including hosted or self-hosted
models.
For example, the router could favor a lower-cost model for routine extraction
and a more capable model for a difficult coding request when measured results
justify the extra cost.
Your application makes the model call and supplies the quality signal, such as
a passed task check or reviewer score, together with latency and cost.
Syntra learns from that feedback; the route names alone do not establish which
model is best for your workload.
Fraud detection and risk decisions
Try the LLM-free email demo: a local statistical text scorer feeds Syntra's learned safe/phishing decision, with optional review deferral for low-margin cases. It reports held-out accuracy, false positives, missed phishing, review coverage, and separate text-scoring and decision timings, with no model API calls. The phrase-aware follow-up publishes separate-corpus results and a failing promotion check when fewer total errors come with more missed risky emails.
Fraud controls have a tradeoff: a stricter threshold may catch more fraud while blocking more legitimate customers. Syntra can learn which of your approved threshold policies works best for a given context, using the outcomes your application reports.
The fraud demo selects loose,
baseline, tight, or very_tight using hour, weekend, and transaction-volume
features.
It also computes and records the mean, 95th percentile, and an EWMA forecast
of recent fraud rates for inspection; those statistics are not automatically
inputs to the demo's learned choice.
Your application maps the selected policy to a numeric threshold on its own
fraud scorer, then sends delayed feedback about fraud caught and false-positive
cost using the original decision ID.
You supply the transaction-scoring model, confirmed outcomes, and enforcement rules; the included demo demonstrates adaptive threshold selection, with no claim of measured fraud-detection accuracy on real transactions. Start in shadow mode against your current policy and use replay and promotion gates before applying learned choices to live transactions, since the learner explores alternatives during warmup and active learning.
AWS infrastructure decisions
A possible AWS integration is a controller that sends recent load, queue backlog, current capacity, and permitted capacity limits to Syntra, then maps the chosen scaling policy to an ECS service task count or an EC2 Auto Scaling group's desired capacity. After the change takes effect, the controller reports processing performance and cost so subsequent decisions can account for the outcome.
The repository includes a scaling capsule and generic HTTP clients; collecting AWS metrics and applying AWS changes requires an integration you build with your AWS SDK or infrastructure controller. That controller owns IAM permissions, capacity bounds, cooldowns, and coordination with any existing scaling policies. Start by recording recommendations alongside your current policy and use the promotion workflow before allowing it to change capacity.
Try it
With Rust, Python 3, curl, and jq installed, run the governed model-routing
example from the repository root:
cargo build --release --locked
bash examples/demo-governed-llm-routing.sh
The demo starts a local runtime, installs a capsule, learns from synthetic feedback, compares a candidate policy with the existing route, and produces a promotion report with reward, cost, latency, and coverage checks. It requires no model-provider credentials. To connect real traffic, follow the model-routing integration guide.
Measured results
The repository includes reproducible checks of decision quality, execution speed, persistence, and failure behavior.
| Evidence | Result | Reproduce or inspect |
|---|---|---|
| Real sensor decisions | 99.19–99.63% accuracy on 14,500 held-out sensor samples across six quadratic-feature LinUCB runs, versus 79.16% for the majority-class baseline | Real-data benchmark |
| Embedded decision latency | 14.25–23.71 µs p99 across those six held-out runs, including feature computation, arm scoring, and graph execution | python3 scripts/bench-shuttle.py |
| Functional release checks | 595 passed, zero failed, one deliberately ignored maintenance test | Release QA |
| Stateful operation | Tested feedback, exact learned-state persistence across restart, crash recovery, and tenant isolation | Tests |
Timing was measured on an Apple M5 Max, macOS, in a release build. The embedded path and the HTTP service have different costs: the loaded HTTP feedback scenario measured 36.4 ms p99, and some embedded samples exceeded 1 ms. Rare-class recall also lagged overall sensor accuracy. The full benchmark includes confusion matrices, slow requests, and unfavorable runs; these results do not establish an absolute real-time deadline.
One repository, two layers
Syntra is the deployable runtime: HTTP API, admin console, tenants, persistent
learning, audit logs, replay, and simulation tooling.
Lycan is the language and execution core: source programs, compiled graphs,
capability kernels, verification, and constrained choices.
Both ship in one Rust crate; one build produces the syntra and lycan binaries.
Use the architecture and reviewer notes for a deeper source tour. The sections below cover rollout, integration, configuration, and operations.
Governed promotion
Syntra includes a native replay gate so adaptive policy promotion can be measured before production control changes hands. The golden commercial demo is the governed LLM-routing flow:
examples/demo-governed-llm-routing.sh
It starts Syntra, installs the LLM model-router capsule, teaches two contexts
from delayed feedback, runs Syntra in shadow mode beside the incumbent
balanced route, writes a JSONL shadow log from the dominant learned policy,
replays that log, and emits a Markdown promotion report. The gate must pass
reward, cost, latency, coverage, and segment-regression thresholds before the
script succeeds.
The lower-level replay command is:
syntra replay \
--events examples/replay/decisions.jsonl \
--policy-json examples/replay/candidate-policy.json \
--gates examples/replay/promotion.yaml \
--format markdown \
--out promotion-report.md \
--fail-on-gate
The report compares a candidate policy against the logged baseline across reward, cost, latency, oracle-match rate, candidate coverage, and per-segment regressions. This is the intended trust loop:
shadow log -> replay -> promotion report -> gate pass -> active rollout
Use --fail-on-gate in CI to prevent a capsule or policy from being promoted
unless it clears the configured thresholds.
Lycan capability surface
Capsules are authored as .lycs (Lycan source) and compiled to .lyc.
The runtime exposes Rust-native capability kernels; the ones that
matter for the operational use cases above:
| Package | Kernels |
|---|---|
| math | stats.mean, stats.stdDev, stats.min, stats.max, stats.percentile |
| math | series.ewmaForecast (one-step EWMA forecast) |
| ops | ops.autoScaleRecommend |
| net | http.get, http.post (allow-listed hosts, private networks denied) |
| data | sql.sqliteQuery (read-only SELECT/WITH/PRAGMA), json.get/has/len |
| io | file.readText, file.writeText, file.exists (sandboxed) |
| runtime | runtime.input, runtime.inputGet |
Every call is policy-enforced at the runtime layer. Full registry and
sandbox semantics in src/capabilities/mod.rs; the
Lycan README groups them in a table.
Demo container
docker build -f docker/Dockerfile.demo -t syntra:demo .
docker run -d --name syntra-demo -p 8080:8080 -p 8787:8787 syntra:demo
Open the admin console at http://localhost:8080; the API listens on port 8787.
Five demo capsules are pre-installed, and a traffic generator drives one of them. Open the admin console to inspect decisions, feedback, and the transition from warmup to active learning.
- Predictive autoscaling — EWMA forecast + adaptive scaling policy
- Anomaly-aware API routing — latency z-score + adaptive fallback
- Seasonal fraud threshold — EWMA on fraud rate + threshold policy
- Shared-state action embeddings — LinUCB generalization across actions
- Hierarchical region routing — nested decisions with per-level learning
The demo-image workflow can publish
ghcr.io/ashhart/syntra:demo; pulling it requires the image to have been published
and your account to have access.
For production deployment, see the Helm chart or Terraform modules. For local development, see Local Development.
Integrate into your service
The retry-tuning example is the canonical Python
integration. Drop-in for requests:
import os
from syntra_retry import RetryClient
client = RetryClient(
syntra_url="http://localhost:8787",
capsule_path="/tenants/myteam/jobs/retry/capsules/router",
admin_key=os.environ["SYNTRA_ADMIN_KEY"],
)
response = client.request("GET", "https://api.example.com/users")
Every request goes through /decide to pick a retry policy, then /feedback
with success and latency. The client falls back to a configured default when
Syntra is unreachable, refuses, or returns a malformed response — a Syntra
outage degrades adaptive retry to "always fall back" without breaking the
request flow.
See examples/retry-tuning/README.md for setup,
customization, and tests.
Deployment scope
Syntra is self-hosted and currently runs as a single process with a local filesystem store. Applications supply their own provider calls, infrastructure adapters, and outcome measurements. Define permitted actions and fallback behavior before sending live traffic; start with the shadow and promotion workflow. For storage and security boundaries, see Persistent store and Security.
How the learning layer works
Each capsule moves through a lifecycle: Warmup → Active → Frozen.
- Warmup — Syntra runs uniform random selection for the first ~30 feedback rounds, watches reward shape, and characterizes the problem (binary / continuous / sparse). It picks an initial algorithm automatically.
- Active — the meta-bandit selects among Thompson, UCB1, EpsilonGreedy, Weighted, and Greedy candidates, with LinUCB and LinTS also available for feature-context capsules. Outcome feedback updates the candidate that made the decision and informs future selection.
- Frozen — operator-triggered; the bandit stops learning but continues serving decisions from the current weights.
Drift detection runs at two scopes: a capsule-level ADWIN detector triggers re-warmup when reward distribution shifts globally, and per-context ADWIN detectors reset just the affected context bucket on narrower shifts.
Refusal (Phase E, opt-in) wraps reward predictions in split-conformal
intervals and tracks out-of-distribution scores per context. When the
interval is too wide or the input is OOD, /decide returns
{"refused": true, "confidence": {…}} and your service falls back. See
refusal config below.
Configuration
A learning.json per capsule controls the learner. Most fields default to
sensible values; the ones you usually touch:
{
"contextSpec": {
"type": "features",
"features": [
{"name": "recent_failure_rate", "type": {"kind": "continuous", "range": [0, 1]}},
{"name": "p99_latency_ms", "type": {"kind": "continuous", "range": [0, 5000]}},
{"name": "hour", "type": {"kind": "cyclic", "period": 24.0}}
]
},
"refusal": {
"enabled": true,
"coverage": 0.95,
"maxIntervalWidth": 0.5,
"oodThreshold": 0.8
}
}
contextSpec—discrete(stringcontextKey, the default) orfeatures(typed vector; enables the LinUCB candidate in the meta-bandit).refusal— enabled-off by default. When on, the response carries aconfidenceblock withoodScore,intervalWidth, andrefused: bool.
PUT it at any time: PUT /tenants/{t}/jobs/{j}/capsules/{c}/learning.
API
# Install a capsule
curl -X POST http://localhost:8787/tenants/acme/jobs/routing/capsules/router/install \
-H "Authorization: Bearer $LYCAN_ADMIN_KEY" \
--data-binary @router-capsule/program.lyc
# Optional: install the reward spec so feedback can use the components form
curl -X PUT http://localhost:8787/tenants/acme/jobs/routing/capsules/router/reward_spec \
-H "Authorization: Bearer $LYCAN_ADMIN_KEY" \
-H "Content-Type: application/json" \
--data-binary @router-capsule/reward_spec.json
# Get a decision (discrete-context capsule)
curl -X POST http://localhost:8787/tenants/acme/jobs/routing/capsules/router/decide \
-H "Authorization: Bearer $LYCAN_ADMIN_KEY" \
-d '{"contextKey":"support-low-cost"}'
# → response carries decisionId, decisions[], oodScore, refused, confidence
# Get a decision (feature-context capsule)
curl -X POST http://localhost:8787/tenants/acme/jobs/routing/capsules/router/decide \
-H "Authorization: Bearer $LYCAN_ADMIN_KEY" \
-d '{"features":{"recent_failure_rate":0.15,"p99_latency_ms":1200,"hour":3.0}}'
# Send feedback
curl -X POST http://localhost:8787/tenants/acme/jobs/routing/capsules/router/feedback \
-H "Authorization: Bearer $LYCAN_ADMIN_KEY" \
-d '{"decisionId":"dec_abc123","reward":0.85}'
# Inspect learned state
curl http://localhost:8787/tenants/acme/jobs/routing/capsules/router/report -H "Authorization: Bearer $LYCAN_ADMIN_KEY"
curl http://localhost:8787/tenants/acme/jobs/routing/capsules/router/memory -H "Authorization: Bearer $LYCAN_ADMIN_KEY"
curl http://localhost:8787/tenants/acme/jobs/routing/capsules/router/contexts -H "Authorization: Bearer $LYCAN_ADMIN_KEY"
See docs/api.md for the full surface including evolution, chaos, evaluate, and audit endpoints.
API versioning. /v1 is the canonical prefix for every API route (e.g.
POST /v1/tenants/acme/jobs/routing/capsules/router/decide); the unversioned
paths shown above are the same routes, kept as deprecated aliases until 1.0 —
they behave identically and additionally return Deprecation: true and
Link: </v1/...>; rel="successor-version" response headers. /health,
/ready, and /metrics are infra endpoints and stay unversioned.
Authoring capsules
Capsules are authored as YAML and compiled to a deployable .lyc by the
syntra author command:
name: llm-router
options:
- cheap_fast
- balanced
- expensive_accurate
reward:
type: continuous
range: [-1.0, 1.0]
syntra author my-capsule.yaml --out-dir ./my-capsule/
# emits my-capsule/program.lyc + sidecar JSON
Then POST program.lyc to /install and PUT a learning.json to attach a
feature-context spec or enable refusal.
Smoke-test a spec locally before deploying:
syntra simulate my-capsule.yaml --rounds 5000 --true-arm-rewards "0.2,0.5,0.7" --seed 7
Data model
tenant / job / capsule
tenant = organization or environment
job = independent learning context (same capsule, different memory)
capsule = the compiled program + its learned state
Persistent store
syntra-store/
tenants/{tenant}/jobs/{job}/capsules/{capsule}/
current.lyc — the graph binary
policy.json — runtime permissions
memory.json — learned weights, meta-bandit, calibrators, OOD detectors
learning.json — algorithm config (contextSpec, refusal, …)
warmup.json — lifecycle state
audit.jsonl — mutation log
decision.jsonl — decision log (carries refused flag and confidence)
feedback.jsonl — feedback log
snapshots/ — pre-mutation backups
Container is disposable. The store survives restarts. The memory.json
schema is at version 7, with backward-compat readers for v2 through v6.
Log retention
The JSONL logs (decision, feedback, audit, evolution) rotate by
size: when a log would exceed maxLogBytes, the current file moves to
<name>.jsonl.1 (one rotated generation) and new entries start a fresh
file. API readers still see one continuous oldest-first stream —
rotation does not change the wire format — and backup/restore includes
rotated generations automatically.
Retention is configured in syntra-store/retention.json, read at
startup, fail-closed:
{ "maxLogBytes": 67108864, "rotateKeep": 1 }
maxLogBytes defaults to 64 MiB per log file (0 disables rotation).
An invalid or unknown-field config refuses to start the server rather
than silently falling back. Entries rotated away are no longer
resolvable by /feedback — they honestly return 404 — so size the cap
above your feedback-latency horizon. Design rationale:
docs/store-retention.md.
Shadow mode
Syntra can run beside an existing application without taking control:
- Your app sends request context to
/decide. - Syntra returns a suggested option and a
decisionId. - Your app continues with its current production decision.
- When the real outcome resolves, your app posts
/feedbackwith thedecisionIdand the observed reward. - Syntra updates memory and exposes the learned state in
/report,/contexts, the admin console.
That makes it possible to validate the adaptive layer before letting it influence live behaviour.
Admin console
Browser UI at /admin:
- Tenant / job / capsule navigation
- Live strategy weight visualization
- Decision and audit log inspection
- Policy enforcement status
- Context memory viewer
- Capsule deletion and log purging
Security
- API routes require an
Authorization: Bearertoken;/health,/ready, and/metricsare public infrastructure endpoints. - Capsule policy enforced at runtime (file sandbox, network sandbox, SSRF protection).
- File capabilities scoped to capsule working directory.
- HTTP capabilities require explicit
allowed_hosts. Private networks denied by default. - Constant-time key comparison. Failed auth logged.
- Server refuses startup without an admin key unless
--dev-mode(binds localhost only).
Not yet production-hardened for direct public-internet exposure. Run behind a TLS proxy. The path to production hardening is tracked in ROADMAP.md and starts with the threat model in SECURITY.md.
Operating
When weights look wrong, inspect the data trail before changing the capsule:
/reportfor current strategy weights./contextsto confirm the request landed in the expectedcontextKey.decision.jsonlfor what Syntra suggested.feedback.jsonlfor which option was rewarded and whether the reward sign is correct.audit.jsonlfor installs, policy changes, deletes, refusals, and change-detection events.
When something looks broken at the storage layer, run
syntra doctor --store <root> — a read-only validator (JSONL findings,
exit 0/1/2, cleans nothing); backup/restore are syntra backup /
syntra restore, and the crash-durability contract is documented in
docs/store-retention.md.
See docs/operating.md for the full operator checklist and docs/deployment.md for production deployment.
Throughput and latency of the /decide hot path are benchmarked and
recorded in docs/benchmarks.md
(./scripts/bench-decide.sh). The per-token rate limiter defaults to
1000 req/s and can be raised — never silently disabled — via
SYNTRA_RATE_LIMIT_RPS / SYNTRA_RATE_LIMIT_BURST.
Architecture
Syntra is built on Lycan, a graph-execution runtime that ships in this
repo as part of the single syntra crate. Capsules are authored as YAML
and compiled to Lycan's binary format automatically — most Syntra users
never interact with Lycan directly. If you want to dig into the
substrate, the source lives at src/ and the language reference
at docs/lycan/README.md.
Examples
The curated demo gallery is DEMOS.md. Start there if you are evaluating whether Syntra is more than a narrow API service.
Operational-kernel demos — series.ewmaForecast, stats.percentile,
stats.mean / stdDev, ops.autoScaleRecommend feeding into an adaptive
choice. Each ships a capsule.yaml, a program.lycs, a learning.json,
and a README walking through install / decide / feedback.
examples/predictive-autoscaling/— EWMA forecast + autoscale-recommend driving a four-policy scaling choice.examples/anomaly-routing/— mean / stddev / z-score driving a four-policy routing choice.examples/seasonal-fraud-threshold/— EWMA forecast on a fraud-rate series driving a four-policy threshold choice.
Integration packs — Python and language-client examples consuming Syntra over HTTP:
examples/retry-tuning/— canonical Python integration library and tests.examples/fraud-tuning/,examples/queue-selection/,examples/llm-routing/— sister domain packs.examples/syntra-go/,examples/syntra-node/,examples/syntra-java/,examples/syntra-rs/— language clients. The Node package also exports a server-side OpenFeature provider for teams that standardize flag and decision evaluation behindOpenFeature.getClient().
Bash demos and tooling:
examples/demo-llm-model-routing.sh— three model routes, two contexts, persistence across restart.examples/demo-static-policy-vs-syntra.sh— focused static-vs-adaptive demonstration.examples/offline-eval/— IPS and doubly-robust off-policy estimators.examples/ab-harness/— A/B simulation harness.
Substrate-level demos (read these if you want to see the Lycan kernels exercised directly, not through a Syntra capsule):
examples/lycan-internals/— autoscaler, capability-pack, webhook-load demos.
Sidecar
sidecar/ — syntra-ingest, an optional metrics-ingestion
sidecar. YAML-configured, polls Prometheus / Datadog / SQL / file sources
on a per-source interval, exposes GET /features/current returning the
latest snapshot. Best-effort, stateless, single-process. Use it if your
capsule needs feature values that live in those systems and you don't
want to embed four client libraries inside your hot path. Not a metric
store.
Roadmap & license
- docs/why-syntra.md — honest positioning: the governed LLM-routing wedge, the auditable-decisions case, "why not just X", and the limits.
- docs/quickstart-model-routing.md — the one buyer journey end to end: install, decide, feedback, metrics, shadow → gated promotion, rollback.
- docs/concepts.md — contextual-bandit concept doc.
- docs/concepts/operational-intelligence.md — the kernel-feature-derivation-to-strategy-node pattern this README leads with.
- docs/evaluations/2026-09-08-adaptive-policy-baseline.md
— dated simulated-traffic regret benchmark against built-in baselines; regenerate with
bash scripts/eval-report.sh. - ROADMAP.md — short version of upcoming work.
- CHANGELOG.md — what shipped in each phase.
- Apache-2.0.