Back to the report center
[P] proposed [E] existing committed fact

Watch the machine change state.

This is the proposed Samora agent runtime, shown one function, transaction, row, signal, and decision at a time. It uses a campaign recovery goal because the same mechanism must operate across Samora, not only on leads.

Input to the trace
"Find why the September renewal campaign stalled. Retry only safe failures. Ask me before relaunching anything, then monitor the result."
Design trace, not production history. The agentic.* tables and every function marked [P] do not exist yet. Existing Samora rows are realistic examples based on verified code paths. PRODUCT DB WRITES TODAY: 0

Trace choice. This example activates a fully validated goal in the create transaction. The current technical specification describes creation as a draft. Samora must choose one contract. If draft remains the contract, insert a separate authenticated start transaction before the first outbox wake. A stored Temporal workflow ID reserves identity; it does not prove the workflow has started. Readable IDs such as goal_01, exec_77, and step_78 are trace aliases for UUID values.

STEP 01INTAKE

The user submits an objective

The chat holds the request long enough to send an authenticated goal command. Nothing durable exists yet.

NO WRITE correlation: corr_goal_01
01 / 52
Keyboard: left, right, space, home, end
User + API
Goal service + DB
Outbox + Temporal
Agent + policy
Executor + Samora
External reality

Rows at this step

0 operations

Causal and changed fields are shown. Routine timestamps and soft-delete fields are omitted unless they affect the transition.

Committed row ledger

0 rows

Function and transaction inspector

current frame
Function
Starts because
Reads
Transaction
Commit causes
If it fails
Temporary state
Why did this happen?
Activity row: none. The design uses agentic.events and the existing workflows.step_events audit row. It does not create a generic Activity record.

The facts that caused this frame

What happens when the clean path breaks

The system does not infer success from silence. Each branch leaves a durable reason for stopping, retrying, reconciling, or asking a person.

The only useful database trigger is a doorbell

Business orchestration does not belong in a PostgreSQL trigger. The transaction writes an outbox fact. An optional trigger can wake a relay sooner, but the relay still polls because notifications can disappear.

INSERT agentic.outboxThe row is still inside the business transaction.
agentic.notify_outbox_ready()The AFTER INSERT trigger queues pg_notify(outbox_id) inside the same transaction.
COMMITThe row becomes durable and PostgreSQL releases the best-effort notification. Rollback releases neither.
Outbox relayClaims pending rows, signals Temporal, records delivery, and polls to repair missed hints.

Tables the machine needs

[P] means proposed. [E] means Samora has the table or path now. Domain tables stay authoritative for campaigns and workflow executions.

[P]agentic.goals

The durable objective, status, owner, limits, request key, current revision, and reserved Temporal identity.

[P]agentic.goal_revisions

Immutable user wording, scope, authority, success, and stop rules.

[P]agentic.subject_runs

One independently progressing campaign, agent, conversation, lead, tool, or other typed subject.

[P]agentic.events

Append-only facts that explain every wake and state change.

[P]agentic.context_snapshots

The immutable evidence manifest used by one decision turn.

[P]agentic.decision_turns

Model, prompt, input hash, proposal, evidence, usage, and outcome.

[P]agentic.work_items

Authorized work with target, version, conflict key, repeat-protection key, lease owner, lease token, and lease expiry.

[P]agentic.work_dependencies

Approval and predecessor rules that keep blocked work from running.

[P]agentic.wait_conditions

Event match, deadline, state, and the event that satisfied the wait.

[P]agentic.action_attempts

A record written before each external effect, with the stable logical action key.

[P]agentic.approvals

The exact action, allowed decider, expiry, target version, and immutable decision.

[P]agentic.outbox

A delivery promise with next attempt, claim token, claim deadline, receipt, and guarded acknowledgement.

[E]campaigns.campaigns

Current campaign configuration and version. Agentic state references it, never copies it.

[E]campaigns.recipients

The campaign's per-contact projection and workflow execution link.

[E]workflows.executions

The read model for a ContactWorkflow. Temporal still owns progression.

[E]workflows.execution_steps

One channel attempt. It binds node, attempt, call or message, conversation, lifecycle, and result.

[E]workflows.step_events

The existing node audit line. A manual retry writes here after the new Temporal run starts.

[E]conversations.conversations

The conversation created for the retried channel action.

[E]conversations.conversation_assignments

The AI agent assignment created with the conversation when required.

[E]voice.calls

The authoritative voice call lifecycle. A status trigger publishes a best-effort notification after commit.

[E]dispatch.jobs

The provider job with producer key, claim lease, unknown state, and voice reconciliation.

Open data-model gaps

The technical specification names behaviors that its first table list does not fully store. These need explicit design before migrations.

Goal messages

The messages API says it writes a message, but no goal_messages table is defined.

Policy decisions

The audit section requires a rule-versioned policy result, but no separate policy-decision row exists.

Goal resolutions

Completion needs evidence and exceptions. A first-class resolution record is absent.

Event delivery

Outbox delivery exists, but per-consumer delivery and acknowledgement are not specified.

Budget and conflict claims

The runtime promises reservations and conflict keys without a durable reservation or claim ledger.

Resource versions

Campaigns have a numeric version. Several existing Samora resources do not yet have one for safe compare-and-set writes.

Campaign retry adapter

The existing retry endpoint accepts node_id and requested_by. It does not accept the agentic action key or campaign version. The adapter and store guard are required changes.

Existing signal durability

The current voice status router writes timeline rows and signals Temporal without an outbox transaction. Domain rows permit reconciliation, but generic repair is incomplete.

What changed this cycle

The animation now follows the full request through 52 frames. The changes are documentation only.

Trace data

tmp/agent-runtime-frames.json now carries 52 ordered frames, guarded replay keys, live claim checks, work leases, corrected timestamps, and the existing voice result path.

Animation report

This file embeds the same 52-frame payload. It shows staged rows, commits, reads, triggers, external calls, waits, reconciliations, and final receipts.

Technical specification

session-2026-09-04-samora-openai-agents-sdk-technical-spec.html now names the workspace-scoped request and event keys plus the fields needed for safe claims and acknowledgements.

Report hub

reports/index.html identifies this as a 52-step trace and keeps its search and category metadata.

Existing Samora behavior

The trace now mirrors the real conversation, assignment, call, dispatch job, execution step, step event, router, and reconciliation paths.

Product data

No application table changed. No generic Activity row was created. Every row on this page is an illustrative snapshot.

Decision made for this design

The database records truth. Temporal owns long waits. Short-lived workers reason or execute one bounded unit, then disappear.

Do not make an agent process the owner of a goal

Why: a goal can wait for hours or weeks. Keeping a model or worker alive wastes resources and loses continuity on deploy or crash.

Alternative rejected: one permanent agent per campaign or lead. Worker identity would become hidden state and would make failover unsafe.

Trade-off: Samora must build durable context assembly, decisions, work, waits, approvals, attempt records, outbox delivery, and reconciliation around the OpenAI Agents SDK.

Verified Samora paths behind the trace

These are plain source citations in this public copy. Service source is not uploaded.

  • pgxdb.WithinTransaction, transaction wrapper samora-be/database/pgxdb/pgxdb.go:34-86
  • transaction-aware job enqueue samora-be/jobs/enqueuer.go:20-147
  • Temporal owns progression; PostgreSQL is a read model samora-be/database/schemas/workflows.sql:1-18
  • workspace membership and role columns samora-be/database/schemas/auth.sql:87-108
  • workspace access and permission derivation samora-be/services/auth_service/service.go:899-935
  • execution-step and step-event rows samora-be/database/schemas/workflows.sql:177-255
  • dispatch job, lease, and result fields samora-be/database/schemas/dispatch.sql:85-130
  • the existing post-commit voice status notification samora-be/database/schemas/notifications.sql:103-132
  • conversation and AI assignment inserts samora-be/services/workflow_dispatch_service/dao.go:714-756
  • voice call creation samora-be/services/workflow_dispatch_service/dao.go:1196-1205
  • existing retry, Temporal start, run binding, and retry event samora-workflows/internal/httpapi/executions.go:74-170
  • execution-step creation and logical attempt key samora-workflows/internal/store/store.go:330-359
  • voice status routing and outcome signal samora-workflows/internal/triggers/router.go:138-223
  • dispatch job claim samora-dispatcher/internal/store/jobs.go:226-274
  • voice worker workspace selection and claim call chain samora-dispatcher/internal/voice/worker.go:140-224
  • unknown voice dispatch reconciliation samora-dispatcher/internal/reconcile/reconciler.go:287-349
  • step result and result event samora-workflows/internal/store/store.go:420-443
  • execution and recipient completion transaction samora-workflows/internal/store/store.go:213-250
  • proposed persistent data model in the technical specification

Acceptance quiz

PENDING · 0 / 8 ANSWERED

The user has not answered these yet. A score of 7/8 is required before this major documentation change can be accepted.

1. What becomes durable before Temporal starts the goal workflow?
User answer: not supplied.
Correct answer: the goal, immutable revision, request event, and pending outbox row commit first.
2. Why is pg_notify not the source of truth?
User answer: not supplied.
Correct answer: notifications may be missed or repeated. The committed outbox row is durable, and a poller repairs delivery.
3. Is an OpenAI Agents SDK worker alive while the system waits for approval?
User answer: not supplied.
Correct answer: no. The approval, wait, and context survive in PostgreSQL and Temporal.
4. What must exist before an external side effect starts?
User answer: not supplied.
Correct answer: an authorized work item and a running action-attempt row with the stable logical action key.
5. What happens if the campaign version changes after approval?
User answer: not supplied.
Correct answer: the final gate invalidates the stale approval and returns the run for reassessment. It does not execute the old proposal.
6. Which system owns lifecycle progression, and which system owns business facts?
User answer: not supplied.
Correct answer: Temporal owns progression, timers, and signals. PostgreSQL owns goals, decisions, approvals, work, events, attempts, and domain rows.
7. If an external outcome is unknown, may Samora create a fresh retry?
User answer: not supplied.
Correct answer: no. It must reconcile the same logical action first and reuse its idempotency key if a policy-approved retry becomes safe.
8. Did this documentation session change a product database row or create an Activity row?
User answer: not supplied.
Correct answer: no. It created documentation and a visualization only. The displayed database rows are proposed examples.