Skip to content

Managing Applications

In Geodesia G-1 Studio, an Application is the unit you manage: one upstream LLM with GLAD-Hummingbird in the middle, owning its own policy (6-axis thresholds + enforcement), threshold profile, RAG knowledge base, cost center, and governance record. You select the active Application from the topbar App switcher, and every other surface — Dashboard, Oversight, FRIA, Reports, Knowledge Base, Cost — scopes to it.

Studio is a backward-compatible evolution of the single-upstream gateway: an existing deployment surfaces as a single Application named default, with zero behaviour change.

Two planes, one engine

Applications live on the control plane (/v1/glad/apps/* — Applications, orgs, keys, policy, cost, metrics). The data plane is chat: resolve the Application, score the 6 axes, route to the Application's LLM, then log and cost the call. See the Control Plane API for the underlying routes.


Lifecycle states

Every Application is in exactly one of three states, stored in the status column:

State Meaning Effect on traffic
active Normal operation. Requests are scored and routed to the upstream.
paused Temporarily halted. Use to suspend an Application without losing its configuration, keys, or history.
killed Hard-stopped (kill-switch). The Application is retained for audit but treated as stopped.

Diagram

State transitions go through set_status, which only accepts active, paused, or killed. Pausing and resuming are the same operation with a different target state.

The default Application

The default Application is synthesised on first boot from your existing runs/gateway_config.json so a pre-existing single-upstream deployment keeps working unchanged. Treat it as your fallback Application — do not delete it. Deleting an Application also deletes all of its API keys.


Configuration model

Each Application stores a validated AppConfig JSON document (config_json), versioned by config_version (incremented on every config update). The document has four sections — binding, policy, cost, governance — plus two top-level fields. Missing axes are always back-filled with the defaults, so the 6-axis contract always holds downstream.

Top-level field Type Default Meaning
schema_version int 1 Config document schema version.
calibration_profile string "default" Calibration profile id for this Application's thresholds (set to the model key when seeded).
binding object see below Upstream LLM binding.
policy object see below Detection policy: thresholds + enforcement + options.
cost object see below Cost rates and budget (FinOps).
governance object see below Compliance and human-oversight settings.

binding — the upstream LLM

Field Type Default Meaning
upstream_type string "openai" Backend type. One of the allowed types below.
base_url string "" Base URL of the upstream (no trailing slash).
model string "" Model name to request from the upstream.
region string | null null Cloud region (e.g. for Bedrock / Vertex).
api_key_ref string | null null Reference to the upstream credential as secret://…never a plaintext key.
request_overrides dict[str, float] {} Per-request upstream parameter overrides (e.g. temperature).
logprobs string "auto" Log-probability handling: auto, require, or off.

Allowed upstream_type values: openai, ollama, vllm, sglang, trtllm, bedrock, vertex, azure-openai, internal.

Credentials are never stored in plaintext

api_key_ref holds a reference, not a secret: secret://app/<name>. The secrets provider resolves it at request time (environment variable → file → AWS Secrets Manager). Bedrock and Vertex use the host's IAM role / Application Default Credentials and need no key at all. The plaintext upstream key is never persisted in the Application config.

The logprobs setting governs the closed-book fabrication axis: require forces a logprob-capable path, off disables it, and auto (default) uses logprobs when the upstream offers them. See Detection Axes for why halluc_closedbook depends on per-token log-probabilities.

policy — detection thresholds and enforcement

The policy is scored across the six GLAD-Hummingbird axes. Each axis has its own threshold (probability space, 0.01.0) and its own enforcement mode.

Field Type Default Meaning
thresholds dict[str, float] see table Per-axis flag threshold; a score threshold flags the axis.
enforcement dict[str, str] see table Per-axis action: block, annotate, or off.
block_input bool true If true, a flagged prompt is refused before the upstream is called.
inject_system bool true If true, the Constitutional Intelligence system prompt is prepended to every request.
ci_prompt_ref string "docs/G1_Constitutional_Prompt_Compact.md" Reference to the CI system prompt to inject.
rag_collection string | null null RAG knowledge-base collection bound to this Application.
optional_detectors dict[str, bool] {causal_xai: false, self_consistency: false} Opt-in extra detectors.
streaming_brake dict {enabled: true, cadence_tokens: 32} Mid-stream re-scoring: whether the brake is on and how often (in tokens) it fires.

Default thresholds (DEFAULT_THRESHOLDS — serving-calibrated for gemma4-e2b at FPR ≈ 0.07, plus the rag_jailbreak firewall):

Axis Region Default threshold
prompt_safety prompt 0.70
jailbreak prompt 0.50
rag_jailbreak prompt / context 0.05
halluc_context answer 0.32
halluc_closedbook answer 0.58
answer_safety answer 0.90

Default enforcement (DEFAULT_ENFORCEMENT):

Axis Default enforcement
prompt_safety block
jailbreak block
rag_jailbreak block
halluc_context annotate
halluc_closedbook annotate
answer_safety annotate

Threshold direction

A higher threshold is more permissive (fewer flags); a lower threshold is stricter. The prompt-region axes default to block enforcement, while the answer-region hallucination/safety axes default to annotate so you can observe before you block. Validation rejects thresholds outside [0, 1], unknown axis names, and enforcement modes other than block / annotate / off.

The two optional_detectors are off by default: causal_xai adds causal token attribution (see Causal XAI), and self_consistency draws multiple samples to reduce closed-book fabrication false positives.

cost — rates and budget (FinOps)

Field Type Default Meaning
currency string "EUR" Currency for all rates and budgets.
input_per_mtok float 0.0 Cost per million input tokens.
output_per_mtok float 0.0 Cost per million output tokens.
glad_compute_per_mtok float 0.0 Cost per million tokens for GLAD scoring compute.
budget_month float 0.0 Monthly budget for this Application.
alert_pct list[float] [0.8, 1.0] Budget-fraction alert points; must be ascending.
on_budget_exceeded string "alert" Action when the budget is exceeded: alert or block.
alert_recipients list[string] [] Addresses carried inside the budget alert/block webhook payload — never SMTP, never a URL. Your relay at the other end of GEODESIA_ALERT_WEBHOOK turns them into email / Slack / PagerDuty. See Cost & Budget.

All rate fields must be ≥ 0; alert_pct is rejected if not ascending; on_budget_exceeded must be alert or block. The cost rate is snapshotted at call time so historical costs stay stable when you later change rates.

FinOps engine

These fields feed the per-Application usage ledger, daily roll-ups, and budget forecasting. See Cost & Budget for the FinOps engine and the forecasting models.

governance — compliance and oversight

Field Type Default Meaning
fria_id string | null null Linked Fundamental Rights Impact Assessment record.
applicable_laws list[string] ["EU_AI_ACT", "GDPR"] Legal frameworks this Application reports against.
retention_months int 6 Audit-data retention period in months.
risk_classification string "high" EU-AI-Act-style risk class for this Application.
human_oversight dict {auto_trigger: true, safety_threshold: 0.70, halluc_threshold: 0.75} Auto-escalation to human review.

Allowed risk_classification values (RISK_CLASSES): minimal, limited, high, unacceptable, unknown.

The human_oversight object controls when a call is auto-escalated for human review: auto_trigger enables it, and safety_threshold / halluc_threshold set the scores above which a call is routed to the oversight queue. See Human Oversight and FRIA.


API keys

Each Application has its own API keys. A key is the Application's runtime identity on the data plane: an invoke key sent as Authorization: Bearer g1k_live_… on a chat or RAG request now routes that request to its Application and scopes the request's policy, cost, quota, and compliance to it — even when no X-Geodesia-App header or application_id is supplied. (Previously an invoke key was control-plane-only — a read-only credential; it is now also the data-plane routing identity.) An explicit application_id / X-Geodesia-App still wins over the key. See Data-plane routing.

Property Value
Format g1k_live_… (prefix g1k_live_ + URL-safe random)
Storage Only the SHA-256 hash is persisted (key_hash).
Preview A non-reversible preview is stored: g1k_***<last4>.
Plaintext Returned exactly once, at creation time. It is never stored and cannot be retrieved again.
Roles invoke (call the Application) or admin (manage the Application). Defaults to invoke; an unknown role falls back to invoke.
Expiry Optional expires_at; an expired key fails verification.

Copy the key immediately

The plaintext g1k_live_… key is shown once when you create it. If you lose it, you cannot recover it — revoke the lost key and create a new one.

Operations:

  • Create — generates a new key, returns the plaintext once along with key_id, app_id, key_preview, and role.
  • List — returns key metadata (key_id, key_preview, role, active, created_at, last_used_at, expires_at) for an Application — never the plaintext or the hash.
  • Revoke — sets active = 0. Revoked and expired keys fail verification immediately.

A request authenticates by presenting the plaintext key; verification hashes it, looks up the active, unexpired record, touches last_used_at, and resolves it to {app_id, role}. The full create/list/revoke routes are documented in the Control Plane API.


Creating an Application from the UI

Open Applications (ApplicationsView) and click New Application to open the creation modal. The modal performs live model discovery against the upstream you choose, so you pick a real model instead of typing one:

Upstream Discovery source
Ollama GET /api/tags
vLLM / OpenAI (and OpenAI-compatible) GET /v1/models
Bedrock Curated AWS Bedrock model catalog
Vertex Curated Google Vertex model catalog

Discovery is served by the control-plane endpoint POST /v1/glad/apps/upstream/models, which returns the model list and its source (or an error you can act on).

In the same modal you set the cost for the Application — €/Mtok for input and output tokens — so the cost center is configured from the start.

Once created, the Application opens to its detail view, organised into tabs:

Tab What you configure
Model Upstream type, base URL, model, region, logprobs, and credential reference — with live model discovery and a Test connection probe (see below).
Policy The six-axis threshold sliders plus per-axis enforcement (block / annotate / off), block_input, CI injection, and the streaming brake.
Cost & Budget Per-Mtok rates, monthly budget, alert percentages, and the budget-exceeded action. See Cost & Budget.
Governance Applicable laws, risk classification, retention, FRIA link, and human-oversight thresholds.
API Keys Create, list, and revoke the Application's g1k_live_… keys.

Saving any tab validates the full AppConfig, bumps config_version, and takes effect on the next request.

Read-only Overview, then edit with auto-save

The detail view opens on a read-only Overview tab — a safe summary of the Application's binding, policy, cost, and governance that you can't change by accident. To make changes, click Modifica, which switches to the editable settings tabs: Model, Policy, Cost & Budget, Governance, and API Keys.

There is no "Save" button. Every change in those tabs is saved automatically, debounced shortly after you stop editing — adjust a threshold slider, change the budget, edit alert_recipients, and it persists on its own. An inline status indicator shows where each edit stands: "Saving…" while the debounced write is in flight, then "Saved ✓" once it lands (and the underlying config_version bumps). Because saving is automatic, dependent UI — such as the Cost & Budget projection chart — redraws immediately against the new values.

The Model tab: discover and test

The editable Model tab (under Modifica) does more than hold the binding fields — it lets you bind to a real upstream model with confidence:

  • Live model discovery. The Model field is an input backed by a datalist, so you can pick a discovered model or type your own. Models are discovered from the chosen upstream — Ollama (/api/tags), vLLM / OpenAI-compatible (/v1/models), or the curated Bedrock / Vertex catalogs — via POST /v1/glad/apps/upstream/models. Discovery runs automatically and debounced whenever you change the upstream type or the base URL (so a URL typed character-by-character only fires one query when you pause), and a ↻ discover button re-runs it on demand. An inline hint shows how many models were found, the source, or an actionable error if the upstream couldn't be listed.

  • Test connection. A Test connection button probes the bound upstream for reachability (with a latency reading) and runs a logprob probe that reports whether the closed-book axis is available or unavailable for that model — since halluc_closedbook depends on per-token log-probabilities. A reachable upstream also refreshes the discovered-model list.

The closed-book axis needs no per-model setup

The closed-book fabrication detector is cross-model — it works on any bound upstream out of the box, with no calibration or training step. Binding to a new model is just discover → test → save.

These controls are now per-Application

Test connection and model discovery used to live in the global Settings → Gateway card. In Studio they are per-Application, on the Model tab, so each Application is discovered and tested against its own bound upstream.

Where each setting lives: Applications vs. Settings

Studio splits configuration cleanly between the per-Application detail view and the platform-wide Settings page:

Configured per-Application (Applications → Modifica, auto-saved) Configured platform-wide (the Settings page)
Model binding (upstream, base URL, model, region, logprobs, credential ref) Plan & license
Detection policy & per-axis thresholds, enforcement, block_input, CI injection, streaming brake The platform Gateway card — the exposed API bind (host / port) and the numeric solver
RAG knowledge base Appearance (theme)
Cost rates, budget & governance Provider identity
System (server health / version)
Demo reset

Settings is platform-only

Anything specific to one Application — model, detection policy & thresholds, RAG, cost & governance — is set on that Application (and saved automatically). The global Settings page now keeps only platform-wide settings: plan & license, the platform gateway card (exposed API bind + numeric solver), appearance, provider identity, system, and demo reset.


Free-tier limit

The number of Applications an Organization may create is capped by its license entitlement (max_applications). On the free tier the cap is one Application, so the New Application button is disabled once the default Application exists — you can still fully configure, key, and operate that one Application.

Raising the cap

Lifting the limit (and unlocking additional Applications) is a licensing change. See Licensing for entitlement tiers and how max_applications is set.