AdResonance
Enter App
Developer Preview — 2026-04-22

The runtime model under GENYS.

Where decisions live, where policy runs, where history is kept, where vendor lines sit. /developers publishes the objects. /mcp publishes the execution path. This page publishes the shape they operate inside.

What you are reading

The runtime below is GENYS — a generic governed decision runtime. Its control plane, data planes, and event model apply to any vertical built on it. AdResonance is the first such vertical product: governed advertising decisions. Both read the same runtime; both conform to the same envelope.

This is the published artifact. Not the internal map.

Capabilities are named at the capability level, not by code path. Table names, schema layouts, and internal event-type vocabularies are deliberately withheld. If something below is not described here, assume it is internal and not part of the v1 public architecture.

Control plane

Five capabilities. Named, separated, adapter-backed.

The control plane is the layer between domain logic and vendor adapters. It is where policy runs before execution, where acting identity is checked, where durable workflows live, where runtime history is emitted, and where observability threads through. Each capability is a named module with its own contract; none of them lives inside any individual feature.

Policy engine

What it does

Evaluates every Decision against a versioned rule set before it executes. Returns one of three results: allow, require_approval, or deny.

Contract role

The approval boundary named on /mcp is enforced here. Every mutation tool passes through this engine; there is no second path.

Design note

Policy versions are immutable. Changing a rule creates a new version. Decisions cite the version they were evaluated under, so a later rule change does not silently reshape old decisions.

Authz boundary

What it does

Authorizes acting identities against typed action scopes — view, approve, override, publish, admin — before any state-changing work proceeds.

Contract role

Approvals and overrides on paused Workflow runs route through this boundary. The actor on every runtime event is attributable because authz runs before, not after, the action.

Design note

No anonymous mutations. Every state-changing call carries an identity, and that identity is logged against the event and the mutation entry it produces.

Durable workflow abstraction

What it does

Executes multi-step Decisions as durable runs with idempotency keys, pauseable-for-approval steps, and compensation on failure. Status moves through queued, running, paused_for_approval, completed, failed, timed_out, compensated.

Contract role

What /developers publishes as the Workflow primitive is this abstraction. Runs are resumable from paused_for_approval; failed runs can compensate earlier writes.

Design note

Adapter-pattern. The abstraction is vendor-neutral; the current default adapter is a local in-memory runner. An external durable-workflow integration sits on the Deferred list below — adopting it will not change the public contract.

Typed runtime events

What it does

Append-only typed event stream with envelope validation at the persistence boundary. Every state transition in the system produces one or more typed events.

Contract role

Mutation Log entries are one slice of this stream. Policy evaluations and approval actions are other slices. The decision_id published on /developers is the join key across all slices.

Design note

Untyped string logs are not the runtime-history record. Envelopes are validated at the boundary before persistence; malformed events fail at the edge, not deep in the store.

Observability

What it does

Shared span helpers wrap request handlers, workflow steps, connector calls, policy evaluations, and decision execution paths with trace context.

Contract role

A traceId is present on every runtime event envelope. Traces carry through the decision path into channel-API executions, so a single trace reconstructs the full lifecycle of a Decision.

Design note

Adapter-pattern. Domain modules depend on the observability interface, not on a specific telemetry vendor. The vendor behind it is an implementation detail we can change without touching the contract.

Data planes

Four planes. One does not write to another directly.

The most distinctive part of the runtime model is the separation of where state lives. Current transactional state, append-only history, longitudinal facts, and serving read models are four different planes with four different purposes. Keeping them separated is what makes the audit trail load-bearing and the serving surface rebuildable.

1

Operational

Transactional source of truth for current state.

Owns

Organizations, workspaces, campaigns, connectors, approvals, policy definitions, current runtime state.

Note

Optimized for transactional correctness and product reads/writes. Not used for long-horizon analytics.

2

Event-trace

Append-only history of what happened and why.

Owns

Runtime events, policy evaluations, execution attempts, decision-state snapshots, approval actions.

Note

Explains why a decision happened, not just what the current state is. The forensic substrate of the product.

3

Analytical

Historical and transformed facts for longitudinal queries.

Owns

Daily summaries, longitudinal performance facts, audit marts, outcome rollups.

Note

Built from exported operational and event-trace data. Not written directly from request handlers.

4

Serving

Read models shaped for product surfaces and audit timelines.

Owns

Decision timeline, approval latency, override rate, execution outcomes, anomaly incidents.

Note

Rebuildable from the other three planes. No authoritative state lives here.

Flow direction: operational emits changes into event-trace; scheduled exports shape event-trace into analytical facts; serving read models are derivable from the three upstream planes. No plane takes transactional writes from a handler on another plane's behalf.

Runtime events — envelope schema

The shape of every event. Not the full vocabulary.

Every runtime event is a typed envelope carrying the fields below. The event-type vocabulary itself is not part of the v1 public contract — types are stable internally but will be published as a /developers extension when the vocabulary is frozen. What is committed in this preview is the envelope shape.

FieldRole
eventIdUnique identifier for this event.
orgIdOrganization scope. Present on every event.
workspaceIdWorkspace scope within the organization.
userIdActing identity. Nullable for system-originated events.
decisionIdJoin key to the Decision object published on /developers. Present on every decision-related event.
traceIdObservability trace identifier. Threads through the full decision lifecycle.
surfaceWhere the event originated — campaign dashboard, MCP tool call, cron evaluator, etc.
timestampServer-assigned event time, in UTC.
policyIdsPolicy rule identifiers that applied to this event. Empty array if none triggered.
beforeStateHashHash of state prior to the event. Nullable on read-only events.
afterStateHashHash of state after the event. Nullable on read-only events.
deltaSummaryShort human-readable description of the change — intended for audit timelines, not for reasoning.
payloadEvent-type-specific body. The type vocabulary is held out of the v1 public contract; see note below.

Boundary rules: envelopes are validated before persistence; the store is append-only; events link to the active trace where one exists; untyped string logs are not the primary runtime record.

Design rule

Vendor-specific code lives behind adapters.

Domain modules depend on interfaces, not specific telemetry, workflow, cron, or warehouse vendors. This is a durability rule, not a portability slogan. It means the control plane can swap a telemetry vendor, a cron runner, or a warehouse destination without altering the object contract on /developers or the execution path on /mcp.

The authentication vendor published on /developers is part of the contract; other adapter choices — telemetry, cron, warehouse — are implementation details that can change between previews.

Adapter landscape

Where the control plane sits next to ecosystem tools.

GENYS is a primitive set, not a composition of external tools. Each primitive has an interface; the design rule above keeps vendor-specific code behind that interface. The table below maps each primitive to the ecosystem category it fits inside and names example tools that could plug in — or, for some primitives, explains why no ecosystem equivalent exists. This is not a commitment to adopt any specific vendor. It is an honest map of where GENYS sits relative to the mature infrastructure already built.

GENYS primitiveEcosystem categoryExample toolsAdapter posture
Policy enginePolicy engines · authzOPA (Rego), Cedar, OpenFGA, Permit.io, Oso, TopazCustom TypeScript engine today, running in cron and dashboard paths. Interface admits external adapters. No specific vendor commitment on the public contract.
Durable workflow abstractionDurable execution enginesTemporal, Inngest, Restate, DBOS, AWS Step Functions, LangGraphLocal in-memory adapter today (flagged Scaffolded below). Vendor-neutralWorkflowAdapter interface. External adapter when durability pressure requires one.
Runtime events · event-trace planeLineage + observability standardsOpenLineage (Linux Foundation), OpenTelemetryInternal envelope shape today. Wire-format adapter is a roadmap decision — emitting runtime events as OpenLineage facets would make GENYS events queryable by Marquez / Airflow / Dagster / dbt / Flink out of the box.
ObservabilityVendor-neutral tracingOpenTelemetry, OpenLLMetry, Langfuse, LangSmith, Phoenix-Arize, HeliconeShared span helpers wired today. LLM-specific trace emission is planned infrastructure for when core-path model participation ships; OpenLLMetry is the vendor-neutral direction.
Upstream memoryMemory + retrieval infrastructureMem0, LangMem, LettaNot a GENYS primitive. Upstream context layer. Deferred integration until stateful multi-turn orchestration creates a concrete need. Memory is upstream context — not the decision record.
Artifact provenanceContent attestation · supply-chain attestationC2PA, Sigstore, in-totoNot active. Optional future layer relevant for signed creative artifacts, regulated-claim attestation, or attestable agent chains.
DecisionNo ecosystem equivalentRule engines (DMN, Drools, Kogito) predate agent architectures and do not model confidence, memory reads, or model attribution. GENYS-native; not adapter-replaceable.
Mutation LogNo ecosystem equivalentKeyed to the GENYS Decision object bydecision_id. No standard external equivalent exists. GENYS-native; not adapter-replaceable.

What this is

A map. Each GENYS primitive has an interface. External tools in the matching category can sit behind that interface as an adapter, not above it as a replacement. The control-plane contract stays on /developers; adapter choices are implementation details.

What this is not

A composition diagram positioning GENYS as an orchestrator of OPA + Temporal + OpenLineage + OpenLLMetry. That framing inverts the architecture. GENYS is the primitive set; the tools above are optional adapter choices — some planned, some deferred, some never. Nothing on this page commits adoption.

Developer Preview — 2026-04-22

Proof — durable execution under failure

The system acts, detects failure, and reverses.

This is a behavior proof, not a vertical proof. A Decision passes Policy, a Workflow starts executing, a downstream channel call fails, and the system compensates earlier successful steps to restore the platform to its prior state. The Mutation Log preserves all three mutations under one decision_id — the original, the failure, and the undo.

The visual centerpiece here is a populated timeline. Absence-as-evidence (the shape of the industrial proofs on /solutions/industrial) does not apply. This proof's shape is lineage-through-failure.

Context

A rebalance_spend Decision proposes shifting $800/day from Meta into Google on a rising search-intent signal. The Decision passes Policy evaluation cleanly; it is a non-territorial market-demand rebalance. The Workflow starts running.

{
  "id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4",
  "type": "rebalance_spend",
  "priority": "medium",
  "confidence": 0.74,
  "summary": "Shift $800/day from Meta to Google on rising search-intent signal",
  "reasoning": "Google auction density on industrial-circulation terms rose 12% week-over-week. Meta conversion signal is flat. Reallocating to match observed demand.",
  "auto_executable": true,
  "action": {
    "type": "rebalance_spend",
    "source_channel": "meta",
    "target_channel": "google",
    "amount": 800,
    "currency": "USD",
    "cadence": "daily",
    "scope": { "market": "all" },
    "reason": "rising_search_intent"
  },
  "computed_at": "2026-04-22T18:12:04Z",
  "policy_version": "budget_policy_v1"
}
Mutation Log timelinedecision_id: dec_01J1B7K9C8N3RXQK9VPYZW2QF4

Three mutations, one decision, deterministic reversal.

The populated Mutation Log is the centerpiece of this proof. Where Proofs 1 and 2 on /solutions/industrial close with an empty log (absence as evidence), Proof 3 closes with a populated log (lineage as evidence). Read the three rows as one trace.

1

Source-channel debit

success

platform: meta · −$800/day · actor: agent · 18:12:11Z

Original mutation. Platform state changed: Meta campaign budget reduced by $800/day. Mutation Log entry records status: "success".

2

Target-channel credit

failed

platform: google · +$800/day · actor: agent · 18:12:16Z

Target step returns a rate-limit error from the channel API. The Workflow does not retry indefinitely — retry policy limits are hit, and the step is marked failed. Platform state on Google does not change.

3

Source-channel credit (compensation)

rolled_back

platform: meta · +$800/day · actor: compensation · 18:12:21Z

Compensation step reverses mutation #1. Actor is compensation, not the agent. Linkage to the original mutation is carried inside payload.compensates_mutation_id. Status is rolled_back — the mutation itself executed successfully, but its role is to reverse an earlier successful mutation.

Raw query result

{
  "query": {
    "decision_id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4"
  },
  "entries": [
    {
      "mutation_id": "mut_01J1B7K9E0Q5TZNU1BNQQGW4RF",
      "decision_id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4",
      "platform": "meta",
      "mutation_type": "update_budget",
      "payload": { "daily_budget_delta_micros": -800000000 },
      "result": { "applied_at": "2026-04-22T18:12:11Z" },
      "status": "success",
      "actor_type": "agent:decision-runtime-cron",
      "created_at": "2026-04-22T18:12:10Z",
      "error_message": null
    },
    {
      "mutation_id": "mut_01J1B7K9F1R6UAOV2CPOQHX5SG",
      "decision_id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4",
      "platform": "google",
      "mutation_type": "update_budget",
      "payload": { "daily_budget_delta_micros": 800000000 },
      "result": null,
      "status": "failed",
      "actor_type": "agent:decision-runtime-cron",
      "created_at": "2026-04-22T18:12:16Z",
      "error_message": "google_ads_api: rate_limit_exceeded (code 429, retry_after=120s)"
    },
    {
      "mutation_id": "mut_01J1B7K9G2S7VBPW3DQORIY6TH",
      "decision_id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4",
      "platform": "meta",
      "mutation_type": "update_budget",
      "payload": {
        "daily_budget_delta_micros": 800000000,
        "compensates_mutation_id": "mut_01J1B7K9E0Q5TZNU1BNQQGW4RF",
        "compensation_reason": "downstream_step_failure"
      },
      "result": { "applied_at": "2026-04-22T18:12:21Z" },
      "status": "rolled_back",
      "actor_type": "compensation",
      "created_at": "2026-04-22T18:12:20Z",
      "error_message": null
    }
  ],
  "count": 3
}

Workflow run

The Workflow terminates in status: "compensated". This is a terminal state, not an intermediate one — the contract treats completed and compensated as the two legitimate terminal success/failure shapes of a run. A compensated run is not a failure. It is a run that reached a deterministic resting point by reversing earlier steps.

{
  "run_id": "wf_01J1B7K9D9P4SYMT0ANMPDX3QE",
  "workflow_id": "execute_rebalance_spend",
  "status": "compensated",
  "idempotency_key": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4-attempt-1",
  "current_step_id": "compensation_complete",
  "requested_by": "agent:decision-runtime-cron",
  "org_id": "org_01HW3T9P2Q8YXZ3N5B7C9DFA2V",
  "retry_count": 0,
  "awaiting_approval": false,
  "created_at": "2026-04-22T18:12:04Z",
  "updated_at": "2026-04-22T18:12:22Z"
}

Runtime event — event-trace plane

A compensation event lands on the event-trace plane with before_state_hash == after_state_hash. That equality is not an accident — compensation restored platform state to where it was before mutation #1 ran. Net change is zero. The three mutation entries are preserved under the decision_id so the lineage stays addressable, but the aggregate effect on the channel is nil.

{
  "event_id": "evt_01J1B7K9H3T8WCQX4ERPSJZ7UI",
  "org_id": "org_01HW3T9P2Q8YXZ3N5B7C9DFA2V",
  "workspace_id": "ws_01HW5RN8K2P7Q3VXY4Z5A6B7C8",
  "user_id": null,
  "decision_id": "dec_01J1B7K9C8N3RXQK9VPYZW2QF4",
  "trace_id": "trc_01J1B7K9I4U9XDRY5FSQTKA8VJ",
  "surface": "decision_runtime",
  "timestamp": "2026-04-22T18:12:21Z",
  "policy_ids": [],
  "before_state_hash": "h_d8e2f5a9b140",
  "after_state_hash": "h_d8e2f5a9b140",
  "delta_summary": "Workflow compensated after downstream step failure (google_ads rate_limit)",
  "payload": {
    "workflow_run_id": "wf_01J1B7K9D9P4SYMT0ANMPDX3QE",
    "terminal_status": "compensated",
    "failed_step_id": "credit_target_channel",
    "compensated_mutations": ["mut_01J1B7K9E0Q5TZNU1BNQQGW4RF"]
  }
}

Three mutations written. Zero net change to platform state. The record shows both the action and the undo — one decision, one trace, both halves addressable.

A dashboard logs what happened. A control plane reverses what should not have.

Footnotes

Compensation linkage. The reference from the compensating mutation back to the original is carried inside payload.compensates_mutation_id. The top- level payload field is published as open- shape on the Mutation Log primitive; this convention for compensation linkage is illustrative of how the system represents the link today, not yet a committed top-level schema. If the linkage is ever elevated to a named top-level field, it ships as a /developers extension under a new dated preview.

Workflow adapter. The active workflow adapter is a local in-memory runner, as noted in the Status band below. The compensation semantics demonstrated here — idempotency_key, compensating steps, terminal compensated state — are vendor-neutral and hold regardless of which durable-workflow engine eventually ships behind the adapter interface.

Scenario and IDs. The rebalance_spend and rate-limit specifics are illustrative of durable-execution shape under channel-API failure. All identifiers, timestamps, state hashes, and textual content are sanitized stand-ins; values do not correspond to any real account, campaign, or channel event.

Status

What is live. What is scaffolded. What is deferred.

The honesty band. Live means running in production today. Scaffolded means designed and partly wired but not the primary path yet. Deferred means explicitly out of v1.

Live
  • Typed runtime events with append-only persistence

    Typed envelopes, boundary validation, trace-aware emission, and persistence are live. The event stream is the runtime-history record today.

  • Policy engine in cron and dashboard paths

    Policy evaluation is wired into scheduled decision evaluation and dashboard action paths. Mutation actions pass through it today, not aspirationally.

  • Durable workflow abstraction

    The workflow primitive — pauseable, resumable, idempotent, compensatable — is in production behind a vendor-neutral interface. The active adapter is a local in-memory runner.

  • Observability spans and trace context

    Shared span helpers wrap handlers, workflows, connectors, policy, and execution paths. Trace IDs flow through runtime events.

  • Authz boundary for view/approve/override/publish/admin

    Typed action scopes enforce acting-identity authorization before state-changing work proceeds.

  • Operational data plane

    The transactional source of truth is live and the primary substrate for product reads and writes.

Scaffolded
  • Event-trace plane on holding tables

    Runtime events persist today in a transactional-side append-only layer. The path to a separate lakehouse destination is designed but not yet writing real exports.

  • Medallion-style lakehouse pattern

    The bronze / silver / gold lineage from raw runtime events through cleaned facts to serving aggregates is scaffolded as a pattern. Real writers and partition automation are not yet live.

  • Serving plane read models

    Decision timeline, approval latency, override rate, and related serving models are designed. Some are wired for internal surfaces; a public serving API is not part of v1.

  • External durable-workflow integration

    The adapter interface supports an external durable-workflow engine. The current production adapter is local; swapping it is an operational change, not a contract change.

Deferred
  • Full policy-definition storage UI

    Policy rules are currently onboarded in code and through controlled engagement. A full authoring surface is deferred until the descriptor format is ready to publish.

  • Event replay API

    The append-only stream is retained, but a public replay API — addressable by decision_id, policy_version, or input_hash — is explicitly out of v1.

  • Long-term partitioning and export automation

    Retention, partitioning, and scheduled export automation for the runtime-history store are not yet in the v1 operational model.

  • External durable-workflow engine selection

    We have not selected a specific external engine. The adapter surface keeps that decision reversible.

The three surfaces, one runtime.

The object contract lives on /developers. The agent execution model lives on /mcp. This page describes the runtime they share. For partner engagement or architecture review beyond what is published here, go through enterprise intake.

Infrastructure for advertising capital.

Pay on what the system governs. Scale without upgrading.