Skip to main content

Environment variables

Do not use AGENT_FEEDBACK_READ_KEY in a product integration. Read keys are for the optional Epode dashboard MCP client and cannot sign feedback capabilities.

AEO execution providers

These variables belong on the Epode backend, not in a connected product or browser bundle. OpenAI runs set store: false, explicitly keep the web-search return budget at its provider default, and preserve returned URL citations. A response stopped by the configured output ceiling is terminal: retrying the same deterministic cap would duplicate spend. Authentication and other terminal failures are recorded without storing provider response bodies. webSearchUsed means at least one returned web_search_call had status exactly completed; attempted calls, known non-completed statuses, and missing or unrecognized statuses remain separately countable and are not promoted to completed search evidence. The safe defaults favor recurring visibility checks over deep research. A product can start at most two new runs in a rolling 24-hour window by default; replaying an existing idempotency key returns the original run and does not consume quota. low search context reduces the web material sent to the model but is not an exact input-token cap and can reduce source breadth. Raise context, run frequency, prompt count, tool calls, or output tokens only for a measured evaluation. Actual input/output tokens are stored per observation, rolled up on the run API, and emitted in the terminal run log so operators can set budgets from observed usage. Every configured value is validated during backend startup. Empty keys, malformed timestamps or numbers, out-of-range limits, and unknown context sizes stop startup rather than silently disabling a guardrail. Ollama runs execute a real model but are explicitly marked as local, non-web-grounded evidence; they must not be reported as consumer answer-engine coverage.

AEO execution safety

AEO_EXECUTION_ENABLED is the backend-wide emergency switch and defaults to false. Enable it only through the reviewed provider-enablement workflow after a disabled deployment has passed verification. A true gate is not sufficient: AEO_EXECUTION_AUTHORIZATION_EXPIRES_AT must also contain a future RFC 3339 instant. The backend evaluates that bound at enqueue, worker claim, scheduled admission, and immediately before every provider dispatch. An abandoned manual canary therefore stops authorizing new calls when its fixed 30-minute window elapses; an already in-flight request may still finish. AEO_EXECUTION_PRODUCT_ALLOWLIST is a second, fail-closed deployment boundary: an empty or missing list authorizes no products, and exact product UUID membership is enforced at manual enqueue, worker claim, and immediately before provider dispatch. Products have an independent stop/resume control: stopping prevents new provider work and cooperatively cancels queued or running runs for that product. Resuming does not enqueue runs; it only allows a later explicit request to do so. At enqueue time, a run stores an immutable snapshot of its prompts, provider settings, and execution limits. Changes made later do not alter that run. Cancellation is cooperative, so an already in-flight provider request may finish and may still be billed; any completed evidence remains available. Primary domains normalize to a lowercase hostname with a trailing dot removed. HTTP(S) input is accepted only when it has no credentials, port, path, query, or fragment. IP addresses, localhost, single-label hosts, and public-suffix-only values such as co.uk are rejected; registrable domains and their subdomains are accepted. Redacted provider-attempt and audit ledgers record execution and spend boundaries without credentials, raw request content, prompts, or provider response bodies. The worker never automatically retries an ambiguous or non-idempotent transport outcome after dispatch may have occurred. Only stale work proven to be pre-dispatch is reclaimable; uncertain attempts are retained for operator review rather than re-sent.

Weekly AEO scheduling

Scheduling is weekly only. Each product can store one schedule with a provider, locale, IANA timezone, local weekday and time, and an explicit non-empty list of active prompt IDs. Creating a schedule leaves it paused. Resume and pause are revision-fenced, idempotent commands; resume chooses the next actually due local slot and does not enqueue a run just because it was called. Timezone behavior is deterministic: a daylight-saving gap advances to the first valid local instant, while a repeated fold chooses the earlier instant. After downtime, the scheduler records only the latest due slot and a missed-slot count, never a burst of catch-up runs. An overlapping active run, a stopped product, an invalid prompt/configuration, or a UTC month cap produces a durable skipped occurrence with no provider call. Pausing a schedule does not cancel work that was already enqueued. AEO_SCHEDULING_ENABLED=false stops scheduler work but does not erase configuration. The provider-call caps are shared by manual and scheduled runs: every attempt counts, including an unknown outcome, and queued work reserves its prompt count transactionally. Redacted monthly counters remain until the UTC month closes so short content-retention settings cannot reopen a spend cap. The scheduled-run and product/team provider-call limits are hard admission caps, not alert thresholds. Rust is the sole supported AEO writer and serializes run creation, reservation transfer, attempt insertion, and UTC-month accounting in the authorizing transaction. Direct SQL writes are unsupported because they bypass those invariants. Use an expand-first rollout. Apply the single reviewed additive migration, 0045_product_aeo_foundation.sql, while the preceding API image is still deployed. The preceding image is safe on schema 45 because it ignores the new AEO tables; do not deploy the AEO image against schema 44. Verify the migration, then deploy this backend with AEO_EXECUTION_ENABLED=false and AEO_SCHEDULING_ENABLED=false. Verify API and worker health without provider dispatch, enable execution and verify a manual run, then enable scheduling separately. An application-image rollback leaves schema 45 and any AEO data in place for the preceding image to ignore. There is no down migration: do not replace or rerun the migration outside the reviewed migration workflow. Never retry an ambiguous or potentially post-dispatch provider request after a rollback or restart; only work durably proven to be pre-dispatch is reclaimable.

Customer enrichment options

The Node HTTP adapters automatically reserve and mount the company-owned enrichment relay at /_epode/v1/enrichment/consent and /_epode/v1/enrichment/answers. Do not implement application behavior on those paths.

Legacy feedback mode alignment

The SDK signs the initial feedback action locally so Epode never sits on the product response path. feedbackMode / AGENT_FEEDBACK_MODE therefore controls the question or report action agents see. The dashboard policy independently enforces what consent and reports Epode will accept. Keep both values aligned. After changing the dashboard policy, update AGENT_FEEDBACK_MODE in the product and redeploy it; Setup shows the exact current value. Until that deploy finishes, the backend fails closed when an older product action conflicts with the new policy, but agents may still see the old instruction. The envelope’s configuredMode helps diagnose this drift.

Common adapter options

Never use names, emails, prompts, raw caller inputs, agent/tool arguments, or unverified token claims. Do not pair customerRef with userRef alone or with a different accountRef. Identity and journey accessors add private, nonblocking telemetry context; they never add those references to the agent-facing feedback envelope.

Route patterns

Configure routes in code so configuration is reviewed and deployed with the product. Use exact paths for narrow surfaces and framework-supported wildcards for related routes. Do not instrument the entire application unless all successful responses are intended for customer agents.

Key rotation

Rotate a key from Setup. The previous key remains valid for one hour so you can deploy the replacement without dropping product traffic. Put the new value directly into the deployment secret manager and keep it out of browser storage, shell history, CI logs, repositories, MCP clients, and product-auth requests. Consent is product-scoped, so rotating a key does not expose or change the raw customer reference.