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.