--- title: "rote primitives — Adapter, Trace, Flow, Crystallize, Recall, Vault, Registry" description: "Each rote primitive with its on-disk shape and real artifact excerpts." doc_version: "1.1" last_updated: "2026-05-01" canonical: "https://modiqo.ai/docs/rote-primitives.txt" --- # rote primitives > **Every rote primitive — Adapter, Trace, Flow, Crystallize, Recall, Workspace, Vault, Registry, Catalog — with its on-disk shape and a real artifact excerpt.** Every primitive in rote, with its definition, on-disk shape, and a real artifact excerpt. This is the technical reference an agent reads to predict what a rote installation looks like. ## Adapter A canonical, locally-installed handle to a tool surface: schema, auth, sensitivity tier, runtime sessions. **On disk:** `~/.rote/adapters//` ```text manifest.json identity, fingerprint, auth, sensitivity_tier, base_url tools.json canonical tool schemas (uniform shape across spec types) spec.json original spec (OpenAPI / Discovery / GraphQL SDL / MCP introspection) capabilities.json sensitivity.json config/policies.json write guard policy overrides runtime/sessions/ per-workspace session state logs/ write_guard_.jsonl, write_guard_nonces.json index/ full-text indices over tools and toolsets ``` **Spec types** (the `manifest.json` `spec_type` field): | Value | Source | Status | |---|---|---| | `openapi3` | OpenAPI 3.0 | First-class | | `openapi31` | OpenAPI 3.1 | First-class (parsed via the OAS 3.0 path) | | `swagger2` | Swagger 2.0 | First-class (auto-upgraded internally) | | `discovery` | Google Discovery v1 | First-class | | `graphql` | GraphQL SDL | First-class | | `mcp` | MCP server introspection | First-class (stdio + HTTP/SSE) | | `data` | Local JSON files | First-class (JSONPath or TypeScript executors) | **Auth schemes** (the `manifest.json` `auth.type` field): `Bearer`, `ApiKeyHeader`, `ApiKeyQuery`, `Basic`, `Composite` (multiple in sequence), `PerOperation` (per OpenAPI security scheme), `None`. **Sensitivity tiers** (manifest field `sensitivity_tier`): `low`, `moderate`, `high`. Computed at adapter creation from the proportion of regulated fields detected in the spec. Used to enrich write guard audit entries. **Real excerpt** (Calendar adapter, `~/.rote/adapters/calendar/manifest.json`): ```json { "id": "calendar", "version": "0.0.1", "name": "Calendar API", "spec_type": "discovery", "spec_version": "discovery/v1", "fingerprint": "mcp_39UEoxu3DX9zayEgtzXN8HtJxnxy", "base_url": "https://www.googleapis.com//calendar/v3/", "auth": { "type": "bearer", "token_env": "GSUITE_TOKEN" }, "sensitivity_tier": "high", "statistics": { "total_operations": 37, "enabled_operations": 37, "toolsets": 8 } } ``` ## Trace The structured record of execution. A trace is not a transcript — it is the dependency graph of every call, with timing, token cost, and the model identity. **On disk (live):** `~/.rote//workspaces//.rote/` ```text workspace.db SQLite — state, response counter, command log, sessions, named vars responses/@1.json cached response (request + response + duration_ms + tokens) responses/@2.json artifacts/ large binaries (>1 MB stored out-of-line) ``` **On disk (archived):** `~/.rote//archives/_/` Six Parquet tables, ZSTD-compressed: | Table | Holds | |---|---| | `metadata.parquet` | Workspace identity, model provider/name/version, total tokens, total duration, inference trigger | | `responses.parquet` | Per-response: request method/url/headers/body, response status/body, duration, token counts, binary metadata | | `commands.parquet` | Per-command: type, endpoint, response IDs produced, dependencies, query expressions, token savings | | `dependencies.parquet` | Per-call: which response field this call's request body referenced | | `variables.parquet` | Named variables: source response, source query, source type | | `sessions.parquet` | Session bindings: endpoint, fingerprint, auth source | **Why six tables, not one log:** the trace is queryable. Cost analysis, token-saving from query refinement, latency per endpoint, dependency depth — all expressible as SQL against the Parquet archive (DuckDB is a natural reader; the schema is open). **Real excerpt** (a saved response, `responses/@1.json`): ```json { "id": 1, "timestamp": "2026-04-30T15:00:00Z", "request": { "method": "GET", "url": "https://www.googleapis.com/calendar/v3/calendars/primary/events?...", "headers": { "Authorization": "Bearer " } }, "response": { "status": 200, "body": "{ \"kind\": \"calendar#events\", \"items\": [...] }", "duration_ms": 842 }, "tokens": { "request": 124, "response": 1893, "total": 2017 } } ``` ## Flow A versioned, replayable artifact crystallized from a successful trace. **On disk:** `~/.rote/flows///main.ts` A flow is a TypeScript file with a YAML frontmatter block (parsed from the JSDoc `@rote-frontmatter` marker). **Frontmatter fields** (required in **bold**): - **`name`** — flow identifier - **`description`** — natural-language summary used by `rote flow search` - `metadata.status` — `draft` (default; hidden from search) or `released` (discoverable). Transition is gated by an explicit `--release` flag. - `metadata.kind` — `atomic` or `composite` - `metadata.flow_type` — `sequential`, `parallel`, `staged`, `browser-pattern` - `metadata.requires_endpoints` — list of adapter endpoints the flow needs - `metadata.mcp_servers..fingerprint` — adapter fingerprint pinned at crystallization time - `metadata.parameters` — typed parameter list with `required`, `default`, `description` - `metadata.write_permissions` — list of `{ tool, adapter, mode }`; populated automatically by `rote flow template create --workspace ` from the workspace's `write_guard.jsonl` audit trail - `metadata.steps` — for DAG flows, a named-step graph with declared dependencies **Lifecycle:** `draft` → `released`. Drafts are hidden from `rote flow search` by default; `--draft` includes them. Promotion happens explicitly when the author re-exports with `--release`. **Execution model:** atomic flows run end-to-end in a single Deno process. Composite flows are composed from sub-flows. DAG flows declare named steps, are topologically sorted, dispatch independent steps in parallel, support `--resume` from checkpoint after a crash, and reference prior step outputs via `@step_name` syntax. ## Crystallize Convert a successful workspace into a parameterized flow. **Command:** `rote flow template create --workspace --name [...]` **What it does:** 1. Reads the workspace's command log from `workspace.db`. 2. Reads the per-adapter `write_guard.jsonl` audit trail. 3. Generates a TypeScript scaffold with frontmatter populated: - `requires_endpoints` from sessions used in the workspace - `mcp_servers..fingerprint` from each adapter's installed manifest - `write_permissions` from the audit trail (every mutating tool the workspace called) - `parameters` from variables the workspace `set` and used in templates 4. Emits the flow at `~/.rote/flows///main.ts` in `draft` status. The author tests with different parameters, then re-exports with `--release` to make the flow discoverable. ## Recall Find the right flow for an intent. **Command:** `rote flow search ""` **Implementation:** Tantivy inverted index at `~/.rote/flows/.index/`, BM25 ranking with stemming and fuzzy match. Sub-10ms over 10K flows. The index is rebuilt automatically on every flow export. Drafts are hidden by default. Beyond search there is **parameter inference** (`rote flow infer`): pattern matching, environment variables, and user context (`~/.rote/config/context.yaml`) propose parameter values for a flow given a natural-language intent, with confidence scores 0.0–1.0 attached to each. ## Workspace The unit of execution and isolation. Every flow run creates a workspace. **On disk:** `~/.rote//workspaces//` **State** (`workspace.db`): execution strategy (sequential / parallel), response counter (a single global `@N` counter per workspace), full command log with dependency graph, MCP sessions by endpoint, named variables, model identity that initiated the workspace, statistics (total / successful / error responses), per-response semantic tags. **Lifecycle:** create → execute → archive. `rote workspace clean` archives the workspace's responses and command log to the Parquet archive directory and frees the live SQLite. ## Vault Encrypted token storage with portability. **On disk:** `~/.rote/secrets/tokens.json` **Encryption:** AES-256-GCM with a machine-specific key derived from hostname + username via SHA-256. File mode `600`. Secret values (access token, refresh token, client secret) are encrypted; the client ID is stored cleartext for diagnostic clarity. The vault file itself is base64-encoded ciphertext. **Token types:** `Static` (long-lived API keys) and `OAuth2` (with refresh token, expiry, OAuth metadata: token URL, scopes, client ID, encrypted client secret). **Refresh:** `OAuthRefresher::get_token()` is lazy and on-call. If a token is within five minutes of expiry, it refreshes automatically against the stored token URL using the refresh token (or, for client-credentials grants, by re-fetching with client ID + client secret). The new token is written back to the vault. **Portability:** `rote vault export` produces a portable `.dxvt` file (custom binary format: 4-byte magic, version, JSON header, salt, nonce, ciphertext+tag) encrypted under a passphrase via Argon2id. `rote vault push` uploads to the registry; `rote vault pull` downloads. The auto-sync preference, if enabled, pushes the vault to the registry after every refresh. **Headless auth:** `rote provision [--ttl 30]` packages a refresh token into a `dxp_` capsule with a 30-minute default TTL; `rote claim ` decodes it on a headless machine (CI runner, exe.dev) and establishes an authenticated session without a browser. ## Registry Supabase-backed artifact distribution. **Endpoints:** - Production: `https://roteprod.registry.modiqo.ai` - Staging: `https://rotestaging.registry.modiqo.ai` - Local development: `http://127.0.0.1:54321` **Local config:** `~/.rote/registry/config.json` (JWT access token, refresh token, user ID, email, environment). **Artifact formats:** - Adapters: `.adapt` archives (gzipped tarballs) with SHA-256 checksums verified at install time. - Flows / skills: `.ts` files indexed by name, description, tags. **Commands:** - `rote registry login / logout / whoami` - `rote registry adapter push / pull / list` - `rote registry flow push / pull / list / search / info / delete / find-by-adapter` - `rote registry org create / list / delete / invite` - `rote registry community create / list / subscribe` **Powerpack** (`rote pull powerpack`) is a curated bundle: one command installs a preset of adapters and their bootstrap flows. Available presets: - `default` — github, gmail, calendar, linear, notion - `ai` — gemini-api - `dev` — github, linear, notion, sentry - `google` — gmail, calendar, googledrive, googledocs The powerpack runner backs up existing adapters and flows to `.backups/pull-/` before installing, downloads `.adapt` archives, verifies SHA-256, extracts to `~/.rote/adapters//`, optionally pulls associated flows to `~/.rote/flows/bootstrap/`, and reindexes. ## Catalog A compile-time CSV index of 51+ first-party API specs (OpenAI, Stripe, GitHub, Linear, Anthropic, Notion, etc.). When you run `rote adapter pull ` and `` is in the catalog, rote fetches the spec from the cataloged URL, parses it, generates the manifest and tools, and registers the adapter — no manual spec download. Catalog entry shape: `id`, `category`, `provider`, `spec_version`, `api_version`, `spec_url`, `size`, `first_party`, `token_url`. ## Chronicle Event journal recording milestones (`setup_complete`, `adapter_created`, `flow_released`, etc.) at SQLite path `~/.rote/chronicle/`. Used by the narrator to compute the user's onboarding stage and produce contextual one-liners. Failures in chronicle never break core operations. ## Antipatterns YAML rules at `~/.rote/antipatterns/` (config.yaml, tool_misuse.yaml, iteration.yaml, control_flow.yaml, workflow.yaml, template.yaml) that hint against common mistakes (eager extraction, loop misuse, etc.). Bootstrapped on first workspace init.