# Adeno Developer Documentation — Full Dump > Generated 2026-08-22T22:13:20Z from docs.adeno.ltd --- # PRODUCT: Adeno Platform (platform) # Adeno Platform Overview Adeno is a modular platform for autonomous AI workflows. Services share a common trust fabric (CAuth), a package ecosystem (APS + Uracil), an encrypted data hub (Corpus), and an inference gateway (Athena), so each product stays small and composable instead of becoming a monolith. ## Core principles - **Service isolation** — every capability is a separate service with explicit contracts. - **Shared trust** — one authentication and billing fabric across products. - **Consent-gated data** — user data moves only with explicit consent scopes and TTLs. - **Rootless least-privilege execution** — extensions run sandboxed with declared capabilities. - **Automation-first** — errors route to automated remediation before humans. ## The platform in layers | Layer | Components | Role | |---|---|---| | Trust & identity | CAuth | Authentication, accounts, usage accounting, billing | | Inference | Athena | LLM routing, model registry, GGUF/Neuron sidecars | | Data | Corpus | Encrypted consent-gated cross-service data hub | | Packages | APS + Uracil | `.aps` solution packages, `.ura` rootless bundles | | Orchestration | Arachne | Graph workflows, OAuth connectors, campaign orchestration | | Products | Keryx, Kairos, Mnemosyne | Outreach automation, productivity suite, sensor-fusion research | | Reliability | Eunomia | Error reporting, triage, AI patch → sandbox → gated promotion | | Clients | Hermes | Client-side hosting + OTA hot-patches in a WASM enclave | ## Cross-service integration Services are intentionally interoperable: - Keryx uses **CAuth** to authenticate users and **Athena** to run inference. - Keryx pushes memory and campaign context into **Corpus** for consented reuse. - **Arachne** orchestrates email and campaign actions across Keryx and Kairos. - **Eunomia** receives a bug report, asks Athena to generate a patch, sandboxes it in Uracil, then promotes it through CI/security/compliance gates. - APS packages are distributed by the registry and consumed by Uracil at runtime. ## CAuth transtokens All major services use CAuth transtokens for request authentication: - Transtokens are JWTs signed with `CAUTH_SECRET_KEY` (HS256). - Claims include `sub`, `iat`, `exp`, `type`, and `jti`. - `transtoken` lifetime ≈ 15 minutes; `anontoken` ≈ 2 days. - Attach as `Authorization: Bearer `. - Services validate tokens with the shared secret. ## Package and runtime model The Adeno Package Service (APS) distributes two package styles: - **Python packages** with `entry_point` and optional dependencies - **Uracil service bundles** with `runtime`, `service`, and `permissions` sections Uracil executes installed bundles with explicit permissions: each bundle carries a `manifest.json` describing identity, runtime ABI, permissions, and functions. Functions execute as subprocesses (Python or native C++). Campaigns provide persistent runtime contexts with cleanup semantics. ## Where to go next - Browse the [product catalog](/api/products) - Read the [AI-friendly index](/llms.txt) or the full dump at [/llms-full.txt](/llms-full.txt) --- # PRODUCT: CAuth (cauth) # CAuth Central authentication, user accounts, usage accounting, and billing for the Adeno platform. CAuth is the shared trust fabric for Adeno. Every service — Keryx, Kairos, Eunomia, APS, Arachne, and more — delegates login, account management, and billing to CAuth instead of implementing its own identity system. - **Host:** `https://adeno.ltd/cauth` (also mounted on product domains as needed) - **Token model:** JWT transtokens signed with `CAUTH_SECRET_KEY` (HS256) ## Token model | Token | Lifetime | Purpose | |---|---|---| | `transtoken` | ~15 minutes | Short-lived per-request auth across services | | `anontoken` | ~2 days | Anonymous/trial flows | Transtokens are JWTs with claims `sub`, `iat`, `exp`, `type`, and `jti`. Services validate them with the shared `CAUTH_SECRET_KEY` using HS256. ```http Authorization: Bearer ``` User-facing services obtain a transtoken via login or registration; internal services can also use shared secrets for backend-to-backend calls. ## Security features - Password hashing with PBKDF2-HMAC-SHA256 - Fernet encryption for server-side sensitive fields - Itemized pricing support for downstream service usage ## Core endpoints All endpoints are JSON in / JSON out. Errors return an HTTP status code plus a body with an `error` key. ### Authentication & accounts | Method | Path | Description | |--------|------|-------------| | POST | `/cauth/auth` | Login; returns a fresh transtoken | | POST | `/cauth/register` | Register a new account | | POST | `/cauth/verify-code` | Submit an email verification code | | POST | `/cauth/resend-code` | Resend a verification code | | GET | `/cauth/chkverify` | Check verification status | | GET | `/cauth/me` | Current user profile from a bearer token | | GET | `/cauth/userinfo` | User info lookup | | DELETE | `/cauth/account` | Delete the account (GDPR) | | GET | `/cauth/account/data` | Export account data (GDPR) | | GET/PUT | `/cauth/account/preferences` | Read/update preferences | Example: ```bash curl -X POST https://adeno.ltd/cauth/auth \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com", "password": "..."}' ``` A successful response contains a token to attach to subsequent service calls: ```json { "token": "", "uid": 123 } ``` ### Usage & credits | Method | Path | Description | |--------|------|-------------| | POST | `/cauth/account/usage/authorize` | Authorize an operation before it runs | | POST | `/cauth/account/usage/record` | Record itemized usage against a user | | GET | `/cauth/account/usage` | Usage summary | | GET | `/cauth/account/usage/itemized` | Itemized usage detail | | GET | `/cauth/account/credits` | Current credit balance | | POST | `/cauth/account/billing/purchase-bundle` | Buy a prepaid credit bundle | CAuth can authorize operations before they run; usage is priced per service-specific unit and billed through prepaid bundles or subscriptions. ### Billing & subscriptions | Method | Path | Description | |--------|------|-------------| | GET | `/cauth/pricing` | Public unit pricing | | GET | `/cauth/bundles` | Available credit bundles | | GET | `/cauth/subscriptions` | Subscription plans | | GET | `/cauth/account/billing` | Billing overview | | POST | `/cauth/account/billing/portal` | Stripe customer portal session | | GET | `/cauth/account/subscription` | Current subscription state | | POST | `/cauth/account/billing/mobile-subscription` | Google Play subscription verification | | POST | `/cauth/webhooks/stripe` | Stripe webhook receiver | ### API keys & services | Method | Path | Description | |--------|------|-------------| | GET/POST/DELETE | `/cauth/account/apikeys` | Manage personal API keys | | POST | `/cauth/services/request` | Request access for a new service | | POST | `/cauth/service/verify` | Verify a service token server-to-server | | GET/POST | `/cauth/admin/service-tokens` | Admin: issue/list service tokens | | DELETE | `/cauth/admin/service-tokens/` | Admin: revoke a service token | The `/cauth/service/verify` endpoint is how downstream Adeno services validate tokens presented by clients without holding user context themselves. ### Enterprise | Method | Path | Description | |--------|------|-------------| | GET/POST | `/cauth/enterprise/workspace` | Workspace configuration | | GET | `/cauth/enterprise/members` | List workspace members | | POST | `/cauth/enterprise/members/invite` | Invite a member | | GET | `/cauth/enterprise/audit-log` | Audit log stream | | GET/POST | `/cauth/enterprise/channels` | Notification channels (Jira/GitHub/Slack integrations) | ### Health | Method | Path | Description | |--------|------|-------------| | GET | `/health` | Liveness probe | | GET | `/cauth/health` | Service health + version info | ## Email relay Downstream services can send transactional email through CAuth's relay rather than holding SMTP credentials: | Method | Path | Description | |--------|------|-------------| | POST | `/cauth/email/relay` | Send email on behalf of an authenticated service | | GET | `/cauth/admin/email/log` | Admin: delivery log | | GET/POST/DELETE | `/cauth/admin/email/addresses` | Admin: allowlist management | ## Integrating a service with CAuth 1. Register your service (`POST /cauth/services/request`) or seed it as an internal client. 2. Accept CAuth tokens from users: validate the JWT with `CAUTH_SECRET_KEY` (HS256), checking `exp`, `type`, and audience. 3. For backend validation of client-presented tokens, call `POST /cauth/service/verify`. 4. Before metered operations, call `POST /cauth/account/usage/authorize`; after completion call `POST /cauth/account/usage/record` with itemized units. 5. Propagate base URLs via environment variables (e.g., `CAUTH_URL`) pointing at the same external FQDN used by browsers. --- # PRODUCT: APS (aps) # APS — Adeno Package Service **aps.adeno.ltd** — the package registry and URA distribution path for the Adeno platform. Athena can also front the same service at `athena.adeno.ltd/aps`. APS hosts `.aps` solution packages, Uracil `.ura` binaries, and device-authenticated admin workflows. Packages are ZIP archives containing a `manifest.json` and solution code. ## Components - **Backend** (`api/`): FastAPI service for package listing, device auth, uploads, and URA distribution - **CLI** (`cli/`): the `aps` command-line tool for login, install, upload, audit, and package management ## Package styles APS supports two package styles: - **Python packages** with `entry_point` and optional `dependencies` - **Uracil service bundles** with `runtime`, `service`, and `permissions` sections ## API endpoints | Method | Path | Description | |--------|------|-------------| | POST | `/api/auth/device/start` | Start a device-style APS login flow | | GET | `/api/auth/device/{session_id}` | Poll device auth status and retrieve token after approval | | GET | `/api/packages` | List all packages | | GET | `/api/packages/{name}` | Get package metadata | | GET | `/api/packages/{name}/{version}` | Download a specific version | | POST | `/api/packages` | Upload a new package (admin token required) | | DELETE | `/api/packages/{name}/{version}` | Remove a package version (admin token required) | ## APS format ``` solution.aps (ZIP) ├── manifest.json # package contract ├── main.py # python entry point (legacy python packages) ├── functions/ # uracil function snippets │ ├── *.py │ └── *.cpp └── lib/ # additional modules/helpers ``` ### Python package manifest ```json { "name": "weather-check", "version": "0.1.0", "description": "Example APS python package", "entry_point": "main.py", "dependencies": ["httpx"] } ``` ### Uracil service manifest ```json { "name": "weather-check-service", "version": "0.1.0", "description": "Example APS Uracil service package", "runtime": { "name": "uracil", "abi": "uracil.service.v1", "mode": "rootless", "hotswap_group": "weather-check-service", "payload_revision": "0.1.0", "target_env": "keryx-ami" }, "security": { "cauth": { "enabled": true, "mode": "adeno-cauth", "base_url": "https://adeno.ltd/cauth", "issuer": "https://adeno.ltd/cauth", "audience": "keryx", "token_env": "KERYX_TRANSTOKEN", "secret_key_env": "CAUTH_SECRET_KEY", "encryption_key_env": "CAUTH_ENCRYPTION_KEY" } }, "service": { "entry_function": "current-weather", "functions": [ { "name": "current-weather", "description": "Fetch the current weather for a city.", "snippet_path": "functions/current_weather.py", "required_permissions": ["net.client"] }, { "name": "current-weather-fast", "description": "Native C++ fast path for API-heavy weather checks.", "snippet_path": "functions/current_weather.cpp", "language": "cpp", "build": { "standard": "c++20", "flags": ["-O3"] }, "required_permissions": ["net.client"] } ] }, "permissions": { "requested": ["net.client"] }, "runner": { "kind": "gguf-http", "protocol": "http", "bind": "127.0.0.1:8088", "model": { "format": "gguf", "uri": "corpus://athena/models/weather-check.gguf" } } } ``` Uracil service functions can be authored as Python or native C++. For native functions, set `language` to `cpp`. The APS host runtime compiles them on demand for dynamic packages, and `ura_builder.py` embeds the compiled binary into `.ura` artifacts for target environments such as the Keryx AMI. When `security.cauth` is present, APS and Uracil project the CAuth contract into `URACIL_CAUTH_*` environment variables so service bundles can participate in Adeno-authenticated encrypted flows without hard-coding deployment secrets into the manifest. ## CLI The CLI defaults to `https://aps.adeno.ltd`. Set `APS_REGISTRY=https://athena.adeno.ltd/aps` to route package operations through Athena. ```bash aps login aps login --admin aps install weather-check aps install service weather-check-service aps upload dist/weather-check-service.aps aps audit weather-check-service aps audit weather-check-service --shell aps permissions weather-check-service aps grant weather-check-service net.client aps run weather-check-service --function current-weather London ``` ## Admin flow 1. Run `aps login --admin`. 2. Open the auth URL returned by the service. 3. Approve the request in the hosted login page. 4. Use the stored token for `aps upload` and other admin-gated operations. ## Relationship to Uracil APS is the distribution channel; [Uracil](/products/uracil/) is the runtime. A typical loop: publish an `.aps` bundle → `aps install service ` on the target → `uracil --bundle ~/.aps/packages/ grant ` → `uracil --bundle ... run `. Athena packages model-backed services as APS bundles first, then compiles them into `.ura` binaries carrying GGUF runner metadata. --- # PRODUCT: Uracil (uracil) # Uracil A hardware-agnostic, rootless microkernel runtime for native services. Uracil provides a minimal, capability-scoped execution environment for service bundles. Each bundle declares the permissions it needs; users grant only what they approve. The runtime refuses to execute any function whose requirements haven't been satisfied. ``` ┌──────────────────────────────────────┐ │ uracil runtime │ ├──────────────┬───────────────────────┤ │ permission │ bundle loader │ │ engine │ (JSON manifest → C) │ ├──────────────┼───────────────────────┤ │ grant store │ subprocess executor │ │ ~/.uracil/ │ (fork+exec python3) │ ├──────────────┴───────────────────────┤ │ host platform adapter │ │ (arch/host/) │ └──────────────────────────────────────┘ ``` ## Features - **Permission model** — services declare capabilities; users grant them explicitly - **Bundle manifest** — JSON contract describing service identity, functions, and permissions - **External bundle loader** — load any APS-installed service directory at runtime - **Subprocess executor** — run function snippets as isolated child processes - **Built-in JSON parser** — zero-dependency manifest loading - **Hot-swap metadata** — versioned payload groups for safe service updates - **Runner metadata passthrough** — `.ura` bundles can carry GGUF/API runner metadata for Athena-managed model services - **Campaign kernel** — persistent campaign-scoped state, artifact ownership, and cleanup under `~/.uracil/campaigns/` - **Host-first** — works on Linux x86_64 now, designed for additional ISAs later - **C11, zero external dependencies** — only libc and POSIX ## Build Requires CMake 3.20+ and a C11 compiler (GCC or Clang). ```bash cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build ``` Run the test suite: ```bash ctest --test-dir build --output-on-failure ``` ## Usage ### Built-in demo bundle The binary ships with a compiled-in sample service so the runtime is usable immediately: ```bash $ ./build/uracil describe service: aps.sample.echo-service version: 0.1.0 description: Sample APS-native service bundle running inside Uracil. runtime abi: uracil.service.v1 hot-swap group: aps.sample.echo-service payload rev: demo-001 rootless: true requested perms: fs.read, net.client, clock.read $ ./build/uracil grant fs.read clock.read updated grant manifest: fs.read, clock.read $ ./build/uracil run clock-now virtual clock reading: 2026-04-17 12:00:00 UTC ``` ### External bundles (APS packages) Load any service directory that contains a `manifest.json`: ```bash # Describe an APS-installed service ./build/uracil --bundle ~/.aps/packages/weather-check-service describe # Grant permissions ./build/uracil --bundle ~/.aps/packages/weather-check-service grant net.client # Run a function (executes functions/current_weather.py as a subprocess) ./build/uracil --bundle ~/.aps/packages/weather-check-service run current-weather London # Check permission state ./build/uracil --bundle ~/.aps/packages/weather-check-service permissions ``` The `--bundle` flag switches from the compiled demo to an external service. The runtime: 1. Reads `manifest.json` from the directory 2. Validates the bundle contract (name, version, ABI, functions) 3. Applies the same permission model as compiled bundles 4. Executes function snippets via `python3 functions/.py` 5. Sets `URACIL_*` environment variables for the subprocess ### Campaign kernel Uracil exposes a persistent campaign-kernel surface for multi-step coordinators and agent harnesses. Each campaign gets its own runtime root under `~/.uracil/campaigns//`, including an `artifacts/` directory for owned binaries and payloads that are cleaned up when the campaign finishes. ```bash # Bootstrap a campaign runtime root ./build/uracil campaign init demo-campaign keryx keryx-ami adeno-cauth # Attach a generated artifact for later cleanup ./build/uracil campaign attach-artifact demo-campaign artifacts/writer.ura # Transition to running ./build/uracil campaign start demo-campaign # Complete the campaign and clean registered artifacts ./build/uracil campaign complete demo-campaign # Remove the campaign kernel state entirely ./build/uracil campaign destroy demo-campaign ``` ## Permission Model Uracil separates **declared capabilities** from **user-granted permissions**. A service bundle's manifest lists every permission the service might need: ```json { "permissions": { "requested": ["fs.read", "net.client", "clock.read"] } } ``` Each function declares which subset it actually requires: ```json { "name": "current-weather", "description": "Fetch current weather for a city", "required_permissions": ["net.client"] } ``` The runtime will only execute a function if **every** permission in its `required_permissions` has been granted by the user. Grants are stored locally in `~/.uracil/grants/.perm`. ### Available permissions | Permission | Capability | |----------------|-----------------------------------| | `fs.read` | Read files from the host | | `fs.write` | Write files to the host | | `net.client` | Make outbound network connections | | `net.server` | Listen for inbound connections | | `proc.spawn` | Spawn child processes | | `clock.read` | Read the system clock | ### Grant lifecycle ```bash # View what's requested vs. granted uracil --bundle permissions # Grant specific permissions uracil --bundle grant net.client clock.read # Revoke a permission uracil --bundle revoke net.client # The runtime refuses to run functions with unmet requirements uracil --bundle run current-weather # → permission-denied ``` ## Bundle Manifest Every service bundle carries a `manifest.json` at its root: ```json { "name": "weather-check-service", "version": "0.1.0", "description": "Fetches weather through a permission-scoped function", "runtime": { "name": "uracil", "abi": "uracil.service.v1", "mode": "rootless", "hotswap_group": "weather-check-service", "payload_revision": "0.1.0", "target_env": "keryx-ami" }, "security": { "cauth": { "enabled": true, "mode": "adeno-cauth", "base_url": "https://adeno.ltd/cauth", "issuer": "https://adeno.ltd/cauth", "audience": "keryx", "token_env": "KERYX_TRANSTOKEN", "secret_key_env": "CAUTH_SECRET_KEY" } }, "service": { "entry_function": "current-weather", "functions": [ { "name": "current-weather", "description": "Fetch current weather for a city", "snippet_path": "functions/current_weather.py", "required_permissions": ["net.client"] }, { "name": "inspect-fs-native", "description": "List the working directory with a native helper", "snippet_path": "functions/inspect_fs.cpp", "language": "cpp", "build": { "standard": "c++20", "flags": ["-O3"] }, "required_permissions": ["fs.read"] } ] }, "permissions": { "requested": ["fs.read", "net.client", "clock.read"] } } ``` ### Manifest fields | Field | Required | Description | |-------|----------|-------------| | `name` | Yes | Globally unique service identifier | | `version` | Yes | Semantic version | | `description` | No | Human-readable summary | | `runtime.name` | No | Runtime target (`uracil`) | | `runtime.abi` | No | ABI version (`uracil.service.v1`) | | `runtime.mode` | No | Execution mode (`rootless`) | | `runtime.hotswap_group` | No | Group ID for safe payload updates | | `runtime.payload_revision` | No | Current payload version | | `runtime.target_env` | No | Deployment profile such as `keryx-ami` | | `security.cauth` | No | CAuth runtime metadata projected as `URACIL_CAUTH_*` | | `service.entry_function` | No | Default function to run | | `service.functions[]` | No | Array of function descriptors | | `service.functions[].language` | No | `python` (default) or `cpp` for native functions | | `service.functions[].build` | No | Optional native compile options | | `service.functions[].binary_path` | No | Prebuilt native binary path for compiled `.ura` bundles | | `permissions.requested` | No | Union of all permissions the service needs | ## Subprocess Execution When running an external bundle, Uracil executes function payloads as child processes: ``` uracil --bundle run [args...] │ ├── fork() │ └── child: chdir() setenv(URACIL_SERVICE_NAME, ...) setenv(URACIL_GRANTED_PERMISSIONS, ...) exec("python3", "functions/.py", args...) # Python exec("compiled/", args...) # Native C++ ``` ### Environment variables | Variable | Description | |----------|-------------| | `URACIL_SERVICE_NAME` | Service identifier from manifest | | `URACIL_SERVICE_VERSION` | Version string | | `URACIL_FUNCTION_NAME` | Name of the function being executed | | `URACIL_RUNTIME_ABI` | ABI version | | `URACIL_HOTSWAP_GROUP` | Hot-swap group identifier | | `URACIL_PAYLOAD_REVISION` | Current payload revision | | `URACIL_TARGET_ENV` | Deployment profile such as `keryx-ami` | | `URACIL_SERVICE_DIR` | Absolute path to the service directory | | `URACIL_STATE_DIR` | Path to `~/.uracil` | | `URACIL_ROOTLESS` | Always `true` in rootless mode | | `URACIL_REQUESTED_PERMISSIONS` | Comma-separated list | | `URACIL_GRANTED_PERMISSIONS` | Comma-separated list | | `URACIL_CAUTH_*` | Adeno CAuth runtime contract for token and envelope metadata | | `URACIL_RUNNER_*` | GGUF/API runner contract exposed to snippets and compiled `.ura` binaries | ## APS Integration Uracil is designed as a runtime target for the [APS](/products/aps/) package ecosystem: ``` ┌─────────────┐ codegen ┌────────────────┐ │ Keryx │──────────────→│ .aps archive │ │ (Devstral) │ │ manifest.json │ └─────────────┘ │ functions/*.py │ └───────┬────────┘ │ aps install service ▼ ┌────────────────┐ │ APS registry │ │ ~/.aps/pkgs/ │ └───────┬────────┘ │ uracil --bundle ▼ ┌────────────────┐ │ Uracil │ │ permission ──→ │ grant/deny │ subprocess ──→ │ execute └────────────────┘ ``` Typical workflow: ```bash aps install service weather-check-service aps audit weather-check-service # inspect locally without exposing secrets uracil --bundle ~/.aps/packages/weather-check-service describe uracil --bundle ~/.aps/packages/weather-check-service grant net.client uracil --bundle ~/.aps/packages/weather-check-service run current-weather London ``` ### GGUF service runners Athena packages model-backed services as APS bundles first, then compiles them into `.ura` binaries. For GGUF-backed services, include runner metadata in the manifest so the URA artifact carries the model contract alongside the function definitions: ```json { "runner": { "kind": "gguf-http", "protocol": "http", "bind": "127.0.0.1:8088", "model": { "format": "gguf", "uri": "corpus://athena/models/mistral-7b-instruct.gguf" } } } ``` For virtualized accelerator targets, keep the source model in GGUF while declaring the runtime target separately: ```json { "runner": { "kind": "gguf-neuron", "protocol": "http", "bind": "127.0.0.1:8091", "model": { "format": "gguf", "uri": "corpus://athena/models/mistral-7b-instruct.gguf" }, "virtualization": { "target": "aws-neuron-inf2", "accelerator": "neuron", "source_format": "gguf", "runtime_format": "neff" } } } ``` Both execution paths expose this contract to snippets via `URACIL_RUNNER_*` environment variables. ## Architecture ### Two-tier design 1. **C core** (`kernel/` + `arch/host/`) — compiled binary with embedded demo bundle demonstrating the permission engine, grant store, and function dispatch in native code. 2. **External loader** — loads service bundles from JSON manifests at runtime and executes function snippets as subprocesses. This is the path APS-installed packages take. Both tiers share the same permission model (requested → granted → enforced), the same grant store, the same bundle descriptor structure, and the same CLI interface. ### Design principles - **Capability-scoped** — no ambient authority; every function must declare what it needs. - **Rootless** — no elevated privileges; services run as the current user. - **Host-first** — establish the contract on Linux, then port to other targets. - **Zero dependencies** — the C runtime needs only libc and POSIX. - **Hot-swap ready** — payload revisions within a group can be updated safely. --- # PRODUCT: Eunomia (eunomia) # Eunomia **Adeno Error Reporting, DevOps Pipeline, and Automated Reconciliation Service** Portal: `https://eunomia.adeno.ltd` Eunomia is a pseudo-public Adeno service that centralises error reporting and automated remediation across the Adeno platform and authorised external services. ``` Service / External Client │ ▼ X-Eunomia-Key ┌────────────────────┐ │ Error Reporting │ POST /eunomia/report │ API │ └────────┬───────────┘ │ (background task) ▼ ┌────────────────────┐ │ Triage Router │ complexity score + novelty score └────────┬───────────┘ │ ┌────┴────┐ │ │ ▼ ▼ portal reconcile (manual) │ ▼ ┌────────────────────┐ │ Reconciliation │ Athena LLM → patch │ Service │ Uracil sandbox → test └────────┬───────────┘ │ ▼ ┌────────────────────┐ │ DeployCheck │ CI / Security / Compliance gates └────────────────────┘ ``` ## Components ### Error Reporting API Registered clients submit errors via `POST /eunomia/report` authenticated with an `X-Eunomia-Key` header. ### Triage Router Runs as a background task after each report is received. **Complexity formula:** $$t_{complexity} = \frac{\sum_{x=0}^{n}\!\left(t(x)_{time}\cdot\dfrac{t(x)_{priority}}{2}\right)}{n}$$ Where: - $t(x)_{time}$ — log-scaled recency/duration weight clamped to `[0, MAX_TIME_WEIGHT]` - $t(x)_{priority}$ — priority score 1–5 supplied by the submitting service - $n$ — number of related error instances (current + similar historical) **Routing:** | Condition | Route | |-----------|-------| | `complexity ≥ HIGH_COMPLEXITY_THRESHOLD` **and** `novelty ≥ HIGH_NOVELTY_THRESHOLD` | `portal` (human review) | | `complexity ≥ HIGH_COMPLEXITY_THRESHOLD × 1.5` | `portal` (high-impact override) | | Otherwise | `reconcile` (automated) | ### Reconciliation Service Calls Athena's development LLMs to generate a code patch, then boots a **Uracil** campaign to sandbox and test the patch before promotion. ### DeployCheck Internal service that validates generated patches through three gates before deployment: - **CI** — unit/integration tests (`DEPLOYCHECK_CI_CMD`) - **Security** — SAST + dependency vulnerability scan (`DEPLOYCHECK_SECURITY_CMD`) - **Compliance** — licence + policy checks (`DEPLOYCHECK_COMPLIANCE_CMD`) Runner strategies: `mock` (dev) | `script` (shell commands) | `http` (external webhook). ### Web Portal React SPA served at `/portal/` with pages for: - **Dashboard** — live statistics - **Reports** — full error report list with status management - **Triage** — complexity/novelty scores and routing decisions - **Reconciliations** — AI fix campaigns with patch viewer - **DeployCheck** — gate logs per pipeline run - **Clients** — service registration approval/revocation ## Quick start 1. Open the Eunomia portal and create or edit an EIDSpec. 2. For any zone using a FlashBack source, set `flashbackcredentials` to an exposed session token such as `cauth@"exposed-session-id"`. 3. Save the spec and trigger a deploy check or run. 4. Review the zone results and approve any gated steps. ### FlashBack credentials The FlashBack source needs an approved credential string so Eunomia can read the live snapshot stream: - Use the Exposed Sessions page in the Eunomia portal to mint a session token. - Paste the token into the `flashbackcredentials` field in the EIDSpec editor. - Admin users can use an approved session token for their own workspace without a separate billing path. ### Approval workflow Some zones require approval before promotion. When a zone waits on approval, Eunomia pauses at the approval step until an admin confirms or rejects the run. ## Configuration | Variable | Default | Description | |---|---|---| | `EUNOMIA_DATABASE_URL` | `sqlite:///data/eunomia.db` | SQLAlchemy URL | | `EUNOMIA_ADMIN_EMAIL` | `administration@adeno.ltd` | Admin CAuth account | | `EUNOMIA_INTERNAL_SECRET` | *(unset)* | Shared secret for internal service auth | | `CAUTH_URL` | `http://cauth:5000` | CAuth service URL | | `ATHENA_URL` | `http://athena:8001` | Athena LLM gateway | | `URACIL_HOST_RUNTIME_URL` | `http://uracil:8005` | Uracil sandbox host | | `DEPLOYCHECK_RUNNER` | `mock` | `mock` \| `script` \| `http` | | `DEPLOYCHECK_CI_CMD` | *(unset)* | Shell command for CI gate | | `DEPLOYCHECK_SECURITY_CMD` | *(unset)* | Shell command for security gate | | `DEPLOYCHECK_COMPLIANCE_CMD` | *(unset)* | Shell command for compliance gate | | `EUNOMIA_HIGH_COMPLEXITY_THRESHOLD` | `4.0` | Complexity threshold for portal escalation | | `EUNOMIA_HIGH_NOVELTY_THRESHOLD` | `0.65` | Novelty threshold for portal escalation | | `EUNOMIA_SEED_INTERNAL_CLIENTS` | `0` | Set `1` to auto-seed Adeno internal clients on startup | ## Running locally ```bash # Backend cd eunomia pip install -r requirements.txt mkdir -p data EUNOMIA_SEED_INTERNAL_CLIENTS=1 uvicorn app.main:app --reload --port 8006 # Portal (separate terminal) cd eunomia/portal && npm install && npm run dev ``` Interactive Swagger docs are available at `/eunomia/docs` on a running instance. ## Billing and trials Adeno uses CAuth and Stripe for billing: - New users can start with trial credits. - Access can be reviewed manually before billing is activated. - Once approved, the account can move from a trial state to a paid Stripe-backed plan. ## Need help? Contact [hello@adeno.ltd](mailto:hello@adeno.ltd) for a walkthrough or help configuring a spec. --- # PRODUCT: Kairos (kairos) # Kairos API Quickstart Use the hosted Kairos API to integrate tasks, smart notes, and workflows into your app. NOTE: the API is production-only — developers must call the hosted endpoint at `https://kairosapp.co/api` (the API is not available for local standalone use). Base URL: ``` https://kairosapp.co/api ``` ## Authentication (quick) Preferred: include a Bearer access token in the `Authorization` header: ``` Authorization: Bearer ``` If you don't have a token, use the Device Authorization flow or sign in at kairosapp.co. Device flow quick steps: 1. `POST /api/auth/device/init` → receive `device_code` and `user_code`. 2. User visits the provided verification URL and approves the device. 3. Poll `POST /api/auth/device/poll` with `device_code` until you receive `{ uid, auth }`. ## Quick examples Curl — Add tasks: ```bash curl -X POST "https://kairosapp.co/api/addTask" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"uid":123, "tasks":"Write summary for client meeting; Follow up with contract"}' ``` Python — Update/complete a task: ```python import requests resp = requests.post( 'https://kairosapp.co/api/updateEvent', headers={'Authorization': f'Bearer {ACCESS_TOKEN}'}, json={"uid":123, "id":456, "updates":{"status":"completed"}} ) print(resp.json()) ``` Node (fetch) — Trigger a workflow: ```js fetch('https://kairosapp.co/api/workflows/123/run', { method: 'POST', headers: { 'Authorization': `Bearer ${ACCESS_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ payload: { note: 'start' } }) }) ``` ## SPR / Shared-notes Writes to the SPR shared-notes runner are a premium feature and require the correct subscription tier and authenticated user. Example endpoint: `POST /api/spr/shared-notes-runner/execute`. See the [Full API Reference](/products/kairos/api/) for details on endpoints, request/response shapes, and auth flows. # Kairos API Reference The Kairos API is a production-hosted service. This documentation matches the live codebase in `backend/` and explains the supported authentication methods, common endpoints, and recommended request patterns for third-party developers. IMPORTANT: the API is only accessible at the hosted endpoint — you cannot run or access the same API locally for third-party integrations. Point all requests to the production Base URL and obtain tokens via the flows below. Base URL (production): ``` https://kairosapp.co/api ``` ## Authentication - Preferred: Bearer access tokens sent in the `Authorization` header. - Header: `Authorization: Bearer ` - The backend resolves users from bearer tokens and falls back to legacy `uid`+`auth` checks for some endpoints. - Device Authorization and OAuth provider flows are supported to obtain user-scoped tokens (see "Authentication flows"). - Compatibility: Some legacy endpoints accept `uid` and `auth` in the JSON body. For widest compatibility include both the `Authorization` header and `uid` when applicable. ## Error handling All responses are JSON. On error the API returns an HTTP status code (400, 401, 403, 404, 500) and a body with an `error` key, for example: ``` HTTP/1.1 401 Unauthorized Content-Type: application/json { "error": "Invalid Token" } ``` ## Authentication flows ### 1) Device Authorization Flow (recommended for headless clients) Start device flow: ``` POST https://kairosapp.co/api/auth/device/init Content-Type: application/json { "client_name": "My CLI" } ``` You will receive a `device_code` / `user_code` pair and a `verification_uri` where the end user authorizes the device. Poll the device token endpoint until approval: ``` POST https://kairosapp.co/api/auth/device/poll Content-Type: application/json { "device_code": "..." } ``` On success the poll returns `{ "uid": , "auth": "", "token_type": "bearer" }`. ### 2) OAuth provider login / provider exchanges - Redirect users to `/api/auth//login` (server performs provider redirect). - To store provider tokens for a user the server supports both server-side exchange (`POST /api/auth//exchange` with a `Bearer `) and a frontend-compatible exchange (`POST /api/oauth/exchange` with `uid` + `auth`). ### 3) Token refresh Refresh flows are provider-specific and handled by the backend's OAuth managers. Contact support for service-account or extended refresh behavior. ## Calling the API (recommended patterns) - Always prefer `Authorization: Bearer `. - If an endpoint requires a `uid` in the body (many task/notes and legacy endpoints do), include `uid` in the request payload even when using `Authorization`. - Respect production rate limits (applied per token/user). Contact support@kairosapp.co for quota increases. ## Selected endpoints | Method | Path | Description | |--------|------|-------------| | POST | `/api/addTask` | Create tasks for a user | | POST | `/api/updateEvent` | Update task/event fields | | POST | `/api/latestTasks` | Fetch latest tasks | | POST | `/api/refreshSchedule` | Refresh a user's schedule | | POST | `/api/readTask` | Read tasks | | POST | `/api/getNotifications` | Fetch notifications | | POST | `/api/workflows//run` | Manually trigger a workflow | | GET | `/api/spr/processes` | List SPR processes | | POST | `/api/spr/run/` | Run an SPR process | | POST | `/api/spr/shared-notes-runner/execute` | SPR shared-notes operations (write requires proper tier) | The live backend supports both modern bearer tokens and legacy `uid`/`auth` checks; including both is the most compatible pattern. For provider integrations (Google, Jira, Trello, Proton, Slack, GitHub) follow the OAuth/device flows above; provider tokens are persisted on the user account after exchange. ## Request / response examples Replace `ACCESS_TOKEN`, `uid`, and ids with real values from your integration. ### 1) Add tasks — `POST /api/addTask` Request: ``` POST https://kairosapp.co/api/addTask Headers: { "Authorization": "Bearer ", "Content-Type": "application/json" } Body: { "uid": 123, "tasks": "Prepare slides for meeting; Email Alice; Buy milk" } ``` Response (201/200): ```json { "tasks": [ { "id": 987, "task_name": "Prepare slides for meeting", "created_at": "2026-01-25T12:00:00Z", "status": "open" }, { "id": 988, "task_name": "Email Alice", "created_at": "2026-01-25T12:00:01Z", "status": "open" } ] } ``` Curl: ```bash curl -X POST "https://kairosapp.co/api/addTask" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"uid":123, "tasks":"Buy milk; Email Bob"}' ``` Python: ```python import requests resp = requests.post( "https://kairosapp.co/api/addTask", json={"uid": 123, "tasks": "Buy milk"}, headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}, ) print(resp.json()) ``` Node / fetch: ```js await fetch('https://kairosapp.co/api/addTask', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${ACCESS_TOKEN}` }, body: JSON.stringify({ uid: 123, tasks: 'Buy milk' }) }); ``` ### 2) Update / complete a task — `POST /api/updateEvent` Request: ```json { "uid": 123, "id": 987, "updates": { "status": "completed", "completed_at": "2026-01-25T15:30:00Z" } } ``` Response: ```json { "success": true, "updated": { "id": 987, "status": "completed", "completed_at": "2026-01-25T15:30:00Z" } } ``` ### 3) Manual workflow trigger — `POST /api/workflows//run` Request: ```json { "payload": { "report_name": "weekly_summary", "params": { "days": 7 } } } ``` Response: ```json { "success": true, "message": "Workflow run initiated" } ``` ### 4) Device auth (init + poll) Init response: ```json { "device_code": "abc123", "user_code": "ABCD-1234", "verification_uri": "https://kairosapp.co/device", "expires_in": 900, "interval": 5 } ``` Poll success response: ```json { "uid": 123, "auth": "", "token_type": "bearer", "expires_in": 3600 } ``` ### 5) Latest tasks — `POST /api/latestTasks` Request: ```json { "user_id": 123, "amount": 5 } ``` Response: ```json { "tasks": [ { "task_name": "Buy milk", "time_utc": "2026-01-25T16:00:00Z", "user_tz": "America/New_York", "priority": 2 }, { "task_name": "Call Alice", "time_utc": "2026-01-25T18:00:00Z", "user_tz": "America/New_York", "priority": 1 } ] } ``` ### 6) SPR shared-notes (premium) — `POST /api/spr/shared-notes-runner/execute` Request: ```json { "operation": "write", "user_id": 123, "user_tier": "pro", "data": [ { "title": "Meeting notes", "content": "Discuss Q1 roadmap" } ] } ``` Response (success): ```json { "status": "success", "usage_info": { "units_used": 12, "units_remaining": 988 } } ``` # Kairos **Kairos** is Adeno's web productivity suite: notes (Amphora), AI scheduling (Centaur), and team workspaces — with workflow automation, integrations, and a hosted public API for third-party developers. - **App:** `https://kairosapp.co` - **Public API:** `https://kairosapp.co/api` or `https://kairos.adeno.ltd` - **Support:** [support@kairosapp.co](mailto:support@kairosapp.co) The API is production-hosted only — third-party developers must use the hosted endpoint; local invocation of the service is not supported for external integrations. ## Documentation in this section - [API Reference](/products/kairos/api/) — authentication flows, endpoints, request/response examples - [API Quickstart](/products/kairos/api-quickstart/) — the short path to your first call - [Workflow Automation](/products/kairos/workflow/) — triggers, actions, templating ## Quick links - Device Authorization flow for headless clients (recommended) - Bearer token auth via `Authorization: Bearer ` - Integrations: Google, Jira, Trello, Proton, Slack, GitHub # Kairos Workflow Automation Kairos Workflows allow you to automate tasks by connecting Triggers, Actions, and Logic nodes in a visual editor. ## Core concepts * **Triggers:** Events that start a workflow (e.g., "Email Received", "Task Completed"). * **Actions:** Tasks performed by the system (e.g., "Send Email", "Add Row to Sheet"). * **Variables:** Data passed between nodes. You can access this data using **Templates**. ## Templating system You can inject dynamic data into Text fields (like Email Body or SQL Queries) using double curly braces: `{{ variable.path }}`. ### Common variables | Variable | Description | | --- | --- | | `{{ time.now }}` | Current date and time (YYYY-MM-DD HH:MM:SS) | | `{{ time.date }}` | Current date (YYYY-MM-DD) | | `{{ trigger.subject }}` | Subject of the email that triggered the workflow | | `{{ trigger.sender }}` | Sender address of the triggering email | | `{{ trigger.body }}` | Body content of the triggering email | | `{{ trigger.title }}` | Title of the task (for Task triggers) | | `{{ value.MyVar }}` | Custom variables defined in previous nodes | ### Date & time modifiers When working with date/time variables (like `time.now` or a Task's `start_time`), you can chain modifiers to format them. **Syntax:** `{{ variable.timezone.format }}` * **Timezones:** `.EST`, `.CST`, `.PST`, `.MST` (and their DST counterparts like EDT/PDT) * **Formatting:** + `.standard`: 12-hour format (e.g., "02:30 PM") + `.date`: Date only (YYYY-MM-DD) + `.time`: Time only (HH:MM:SS) + `.day_name`, `.month_name`: Full names (e.g., "Monday", "January") **Example:** `{{ trigger.value.Soonest_Match.time.pst.standard }}` *Result:* 02:30 PM (converted to Pacific Time) ## Integrations ### Google Sheets To use Google Sheets nodes, ensure you have connected your Google account in the Integrations settings. * **Add Row:** Appends data to the bottom of a sheet. Accepts a JSON array of values. * **Read Sheet:** Reads a range of cells. Returns data available as a variable. * **Run Macro:** Executes a Google Apps Script function. ### Email Triggers can listen for emails from specific senders or with specific subjects. Actions can send emails via Gmail (if connected) or standard system mail. --- # PRODUCT: Mnemosyne (mnemosyne) # Mnemosyne A sensor-fusion runtime that hot-plugs new input modalities into a frozen trained core. A new sensor is integrated by fine-tuning only a small adapter (~22 K params) while the core and fuser stay frozen, so adding a modality does not require retraining or redeploying the model. - **Runtime:** CPU-only; no GPU required. Inference under 200 MB RAM (int8-quantized). - **Requirements:** Python + PyTorch; the GGUF C loader (`c_loader/`) builds with any C compiler. - **Determinism:** single seed (`mnemosyne.SEED = 1337`) seeds torch/numpy/random; data windows derive from `(seed_base, sample_index)`, so identical seeds reproduce identical runs. ## Install & train ```bash pip install torch # CPU build is sufficient # Phase-1 warm start: train core + fuser + two known modalities (rf, spectrogram) python -m mnemosyne.train # writes checkpoints/ # Evaluate a never-seen modality end to end python -m mnemosyne.demo --eval-radar python -m mnemosyne.demo --eval-gesture ``` ## Core API ### FuserLoom The whole fusion system: backbone + fuser + ports + output head. ```python from mnemosyne.loom import FuserLoom loom = FuserLoom( dim=64, # core latent dim d_enc=32, # encoder output dim per port num_classes=5, core_vhdus=3, state_size=32, ) ``` Fused output = `head(backbone(fuser(fused_feature_stream)))`, where `fused_feature_stream` is the gate-weighted sum over active ports concatenated with the backbone's temporal read of the same stream. ### Port registry Each modality is a `ModalityPort` (encoder → dimension sandbox). Built-in encoders: | Name | Encoder | Input width (`d_in`) | |---|---|---| | `rf` | `RFEncoder` | 64 | | `spectrogram` | `SpectrogramEncoder` | 32 | | `radar` | `RadarEncoder` | 48 | | `vision` | `VisionEncoder` | 48 | | `gesture` | `GestureEncoder` | 24 | ```python from mnemosyne.ports import build_port port = build_port("radar", dim=64, d_enc=32) # -> ModalityPort ``` ### Adding a novel modality (QuickSwap) ```python from mnemosyne.quickswap import add_novel_port, quicklearn, quickremove, quickadd_and_learn # One-call version: report = quickadd_and_learn(loom, "radar", steps=250, lr=5e-3, device="cpu") # Step by step: add_novel_port(loom, "radar") # fresh random encoder + mixing gate quicklearn(loom, "radar", steps=250, # gradient steps (fuser-only fine-tune) lr=5e-3, drop_p=0.9, # known-sensor dropout probability seed_offset=0) # batch-stream offset for reproducibility quickremove(loom, "radar") # remove a port; other ports untouched ``` `quicklearn` trains only the target port's parameters plus its mixing gate; the backbone, fuser, and other ports stay frozen. Sensor dropout unplugs random subsets of known sensors per batch so the port must actually learn the new stream. ### Custom modality ports To integrate your own sensor, provide an encoder whose forward emits `(batch, seq_len, d_enc)` frames and wrap it as a port: ```python import torch.nn as nn from mnemosyne.ports import ModalityPort from mnemosyne.fuser import DimensionSandbox class MySensorEncoder(nn.Module): def __init__(self, d_in, d_enc): super().__init__() self.net = nn.Sequential( nn.Conv1d(d_in, 32, 3, padding=1), nn.GELU(), nn.AdaptiveAvgPool1d(1), ) self.proj = nn.Linear(32, d_enc) def forward(self, x): # x: (batch, seq_len, d_in) b, t, d = x.shape h = self.net(x.reshape(b * t, d, 1)).squeeze(-1) return self.proj(h).reshape(b, t, -1) encoder = MySensorEncoder(d_in=my_width, d_enc=loom.d_enc) adapter = DimensionSandbox(loom.d_enc, loom.dim) port = ModalityPort("mysensor", encoder, loom.d_enc, loom.dim) loom.add_port(port, known=False) # unknown provenance -> novel ``` Then run `quicklearn(loom, "mysensor", ...)` with windows from your sensor. Synthetic generators for the built-in modalities live in `mnemosyne.sensors` (`gen_rf_window`, `gen_spectrogram_window`, `gen_radar_window`, `gen_vision_window`, `gen_gesture_window`, `gen_batch`) if you need reference shapes. ## Persistence: GGUF bundle ```python import torch from mnemosyne.gguf import write_gguf, read_gguf write_gguf( "checkpoints/fusion.gguf", loom, fused_embedding=torch.zeros(loom.dim), metadata={"name": "fusion", "seed": 1337}, ) data = read_gguf("checkpoints/fusion.gguf") # dict of tensors + metadata KV ``` Bundle contents: - `fused_embedding` `(dim,)` — current fused semantic vector - `codebook` `(num_classes, dim)` — frozen retrieval targets - per-port tensors `{name}.{param}` — int8 weights when available, fp16 otherwise - metadata KV block: `name`, `seed`, `known[]`, `novel[]`, `class_names[]`, `port_info[]` (name, d_in, d_enc, params), `memory` A dependency-free reader (`c_loader/mnemosyne_loader.c`, stdio-only) reads the same files; build with `make -C c_loader`. Bundle size ≈ 94 KB for the default configuration. ## Quantized inference ```python from mnemosyne.eval import quantize_model qloom = quantize_model(loom) # int8 copy of the whole loom # same forward pass through dequantized weights: out = qloom(windows) ``` Measured cost: ~6–7 ms/sample, ~520 KB of weights, accuracy unchanged versus fp32 on the reference tasks. ## Enclave (licensing API) Session budgeting and license enforcement live inside the model weights (`enclave_state` buffers persist with the model). Relevant entry points: ```bash python -m mnemosyne.enclave_cli issue --kind dev --seats 4 --out seat.mnport # issuer side python -m mnemosyne.enclave_cli install seat.mnport # consumer side python -m mnemosyne.enclave_cli status # inspect state ``` ```python from mnemosyne.enclave import Enclave enclave = Enclave(loom) enclave.install_port("seat.mnport") # validates form, HMAC tag, checksum, seat binding, lifespan print(enclave.status()) # dict: kind, seats, lifespan, governor state ``` Programmatic issuance for site-side integrations: `mnemosyne.enclave.issue_port(kind="dev"|"prod", seats=N, seat_id=..., ...)` returns canonical single-line `.mnport` text; consumers may pass it via `mnemosyne.enclave.install_from_text(text, enclave)`. Port text is byte-canonical — re-wrapped or indented copies are rejected. ## Module map | Module | Role | |---|---| | `mnemosyne.vhdu` | causal selective SSM block (VHDU) | | `mnemosyne.nodeunits` | NodeUnit ensemble + Backbone (frozen core) | | `mnemosyne.fuser` | FuserBridge sandbox ladder, DimensionSandbox | | `mnemosyne.loom` | FuserLoom: port registry, mixing gates, OutputHead | | `mnemosyne.ports` | ModalityPort + built-in encoders + `PORT_REGISTRY` | | `mnemosyne.sensors` | deterministic synthetic window generators | | `mnemosyne.train` | phase-1 warm-start training | | `mnemosyne.quickswap` | `add_novel_port` / `quicklearn` / `quickremove` | | `mnemosyne.eval` | reproducible eval harness, int8 quantization | | `mnemosyne.gguf` | GGUF writer/reader | | `mnemosyne.enclave` | session budget, governor, license ports | | `mnemosyne.enclave_cli` | issue/install/status CLI | | `c_loader/` | dependency-free C GGUF reader |