Configure
Create or revise agents, channel instructions, escalation rules, tools, knowledge, and integrations.
Behavior-first architecture review
The machine Samora needs so a person can state an objective in chat, let the system operate any authorized part of Samora, watch it pause and wake as reality changes, and receive a traceable result.
Samora needs a persistent goal control plane that turns a user's objective into an explicit scope and authority contract, creates one or more subject runs, reacts to stored events and deadlines, asks short-lived agents for bounded decisions, and sends approved work through existing Samora services until the goal reaches a recorded resolution.
A user asks Samora to configure, operate, investigate, communicate, or coordinate. Samora keeps the objective alive even while no process is running.
Messages, calls, provider callbacks, people, timers, configuration changes, and failures arrive on their own schedule. The system must resume from stored facts.
In simple terms: the persistent machine is the goal plus its recorded state. An OpenAI agent is one temporary thinker inside that machine.
Goal is the outcome contract. Subject is the Samora thing being worked on. Event is a stored fact. Work is a bounded obligation. Wait is a stored condition that can be satisfied by an event or a deadline. Lease is a temporary worker claim. Idempotency key is a repeat-protection ID. Projection is a view that can be rebuilt from facts.
A permanent model does not need to own a goal or resource. A generated plan does not need to predict every future step. A model must not receive raw database access or provider credentials. A subagent is not a durable job. Chat history alone is not product state.
What happens. A goal names an outcome and a resource scope. The scope may contain contacts, campaigns, conversations, agents, tools, documents, integrations, workflow executions, queues, reports, or workspace settings. Samora creates only the subject runs needed to coordinate that goal.
Why. If the runtime is built around a lead ID, it cannot naturally handle "repair failed workflows," "configure this agent," or "attach the new pricing guide and verify it." The durable model must be about work on typed Samora resources.
Create or revise agents, channel instructions, escalation rules, tools, knowledge, and integrations.
Launch, pause, resume, cancel, retry, assign, hand off, schedule, and communicate.
Read conversations, histories, provider results, workflow state, reports, queue health, and failures.
Qualify, summarize, compare, diagnose, select next work, detect missing information, and assess completion.
| Goal example | Subject runs | Likely work that emerges |
|---|---|---|
| "Take these 100 contacts and convert interested people." | One run per business pursuit or contact, plus a goal-level coordinator. | Research, outreach, waits, replies, calls, approvals, handoffs, stop decisions. |
| "Set up a support agent for WhatsApp and web chat." | Agent run, channel-config runs, tool assignments, and knowledge-document runs. | Inspect current config, draft instructions, attach tools, test, request approval, publish, verify. |
| "Find why yesterday's campaign stalled and safely recover it." | Campaign run plus selected workflow-execution runs. | Inspect events, classify failure, propose repair, approve retry, watch outcomes, report exceptions. |
| "Connect Gmail and route billing messages to Priya's queue." | Integration run, routing-config run, and human-queue run. | Request the person's OAuth step, wait for callback, verify account, update routing, send a test, confirm receipt. |
A subject run is a coordination boundary, not a database mirror. A small settings change may need only the goal run. A campaign may need one run per recipient because each can wait and diverge. The goal compiler chooses the smallest set that can progress, wait, fail, and finish independently.
What happens. The user states an outcome rather than drawing every edge. Samora makes its interpretation visible, starts safe work, and chooses later work only after it observes what actually happened.
Why. The unknown is larger than replies. A provider can reject a template, an integration can require a person to sign in, a document can fail to index, another user can edit an agent, or a campaign can exceed its error budget. Any of those facts can change the next move.
A restart may delay work. It must not erase a goal, timer, provider result, approval, or action receipt.
A new fact can invalidate work that looked correct five minutes earlier. The plan is a hypothesis.
A reply, test failure, config drift, or human request can create work that did not exist when the goal began.
A callback is a fact. Interpreting it is analysis. Choosing is a decision. Mutating Samora is an action.
Authorization, consent, scope, quiet hours, budgets, destructive-change policy, and repeat prevention cannot depend on model persuasion.
"The command returned 200" does not mean "the goal succeeded." Each goal records its business and operational result.
What happens today. Samora already lets people configure agents, attach tools and knowledge, connect provider accounts, manage contacts and conversations, communicate across five channels, route work to people, build campaigns and workflow graphs, wait for outcomes, retry failures, and inspect operational history.
Why this matters. The new system should operate these product capabilities. It should not replace them. The missing part is a single control layer that can understand an objective, select authorized Samora actions, watch results, and decide again.
In simple terms: Samora has many working controls and execution paths. It does not yet have one persistent goal-directed operator above them.
This review covered samora-fe, samora-be, samora-workflows, samora-dispatcher, samora-voice-agent, samora-lambdas, and samora-form-portal. It also checked samora-landing-v2 and opencode-slack as adjacent products rather than core workspace services. "Working source" means the UI, API, durable records, and runtime path are evidenced in this checkout. It does not prove that every provider or deployment is configured. "Missing" means no first-class record or active path was found after schema, route, type, and UI review.
The agentic layer needs a governed way to operate more than contacts. The table below separates actions that exist in the current source from the new planning and continuity layer that does not.
| Subject | Actions evidenced today | What the goal system adds | Source |
|---|---|---|---|
| Agents | Create, read, update, delete, and configure channel instructions, runtime config, and escalation. | Reason about requested changes, preview impact, ask for approval, apply through the same permission checks, and verify the result. | samora-be/services/agent_service/init.go:20-48 |
| Tools | Create, test, update, delete, attach to agents, detach, and choose allowed channels. | Choose only from a versioned capability snapshot. Never let a model invent an endpoint or expand its own authority. | samora-be/services/tools_service/init.go:18-40 |
| Knowledge | Upload, list, delete, attach documents to agents, and limit those attachments by channel. | Plan a bounded knowledge update, confirm destructive changes, wait for indexing, and verify that the chosen agent can retrieve it. | samora-be/services/kbase_service/init.go:43-65 |
| Integrations | Discover providers, start a connection, inspect, update, verify, and delete a workspace account. | Diagnose configuration, request a human credential step, wait for callback, and continue without exposing secrets to the model. | samora-be/services/integrations_service/init.go:39-61 |
| Campaigns and workflows | Build versioned graphs, launch cohorts, pause, resume, cancel, retry, wait, and inspect per-subject execution. | Translate a higher-level outcome into work, adapt after facts arrive, and decide when the business objective is resolved. | samora-be/database/schemas/workflows.sql:1-18,74-170 |
| Conversations and people | Read histories, send through supported channels, claim work, reassign, escalate, take over, resolve, and transfer. | Coordinate actions across conversations and goals while consent, human ownership, and conflict rules stay authoritative. | samora-be/database/schemas/conversations.sql:11-156 |
| Outcomes and reporting | Store operational statuses, dispositions, campaign rollups, evaluations, exports, and queue metrics. | Distinguish execution success from goal success, preserve evidence, and explain exceptions. | samora-be/services/disposition_service/init.go:18-60 |
These routes are user-facing product APIs. They are not yet safe model tools. A tool gateway must keep the same workspace ownership and permission checks, add an immutable capability version, classify risk, require approvals where needed, and record each attempted side effect.
Samora has a workspace contact directory with create, import, edit, delete, search, multiple phone numbers, multiple email addresses, tags, and audience lists. Inbound channel code can find or create a contact by a normalized phone number or email. The frontend also contains a separate legacy dialer-contact model with folders and arbitrary metadata.
The modern backend stores identity in contacts.contacts and related phone, email, tag, list, and list-item rows. Channel conversations reuse contact_id. The legacy frontend calls a different /dialer/contacts API and exposes different fields. These two contact models are not shown as one synchronized record.
A stable identity lets calls, messages, campaign membership, and contact memory point to the same person. Lists and tags make audience selection possible.
There is no canonical lead or opportunity, pipeline, stage, score, value, source, consent history, next action, durable owner, or conversion timestamp. A contact is a person or address book entry. It is not the business pursuit called a lead. The two frontend contact families also create deduplication and data-drift risk.
samora-be/services/contacts_service/init.go:18-55; samora-be/services/contacts_service/models.go:53-163; samora-be/database/schemas/contacts.sql:22-69,71-159,179-203; samora-fe/src/api/queries/crm/contacts.ts:15-35; samora-fe/src/api/queries/contacts/workspace-contacts.ts:20-65
Users can route or reassign a conversation among an AI agent, receptionist, human queue, and human agent. They can configure which operators may handle which agents and queues. Assignment screens and channel threads show the active handler and past assignment journey.
Changing assignment ends the current active row and inserts a new row in one database transaction. Compare-and-set checks stop two people from claiming the same queue item. Queue membership, role, and channel state limit who may act. This ownership belongs to one conversation episode, not the whole relationship with the contact.
A reply can reach a capable person without losing the channel transcript. The assignment history explains who had responsibility at each point.
No record assigns the lead or opportunity itself to a salesperson. There is no owner history across channels, territory rule, owner-level service deadline, or rule saying one person owns every conversation for this lead. The same contact can have different owners in SMS, WhatsApp, email, and voice.
samora-be/database/schemas/conversations.sql:11-156; samora-be/services/conversations_service/dao.go:263-396; samora-fe/src/routes/company/hil/assignments.tsx:18-155; samora-be/services/human_operations_service/dispatch.go:173-226
Users can start a human browser call from a contact, work dialer lists, inspect call history, monitor live calls, listen, take over, transfer, or route a call to a human queue. Samora also supports AI calls, SIP origination, LiveKit sessions, transcripts, recordings, call attempts, and final call status.
The backend creates a shared conversation and call row. The dispatcher leases a durable job, reserves workspace and provider capacity, and starts the voice path. The voice agent selects its mode, runs the call, uploads optional artifacts, saves the final call, and ends assignment. Workflow code maps provider outcomes to results such as answered, voicemail, unanswered, rejected, or failed.
Voice gives Samora a live qualification path, reachability evidence, rich transcript context, and a direct handoff route to a salesperson.
Each call remains a channel episode. Saving a call does not move a canonical lead stage, create a general follow-up task, or record conversion. Transcript and recording writes are best effort. Some tool paths can send outside the central workflow and dispatch correlation path.
samora-be/services/voice_service/service.go:404-535,932-1017; samora-dispatcher/internal/voice/worker.go:313-565; samora-voice-agent/main.py:69-163; samora-voice-agent/tools/hangup.py:108-230,411-480; samora-fe/src/components/agents/human-agent-call-modal.tsx:60-96,230-410
Samora can receive SMS, create or reuse an open SMS conversation, store messages, route to AI or a person, reply, claim, reassign, resolve, and honor STOP and START. Workflows can send SMS. Operators act from Human Operations, while the Logs screen is intentionally read-only.
Inbound processing normalizes numbers, finds or creates the contact, deduplicates the provider message, writes message and routing state, and wakes AI only when AI owns the thread. A human reply requires active human ownership. Resolve closes the SMS conversation and assignment. A later inbound message starts a new episode.
SMS is a low-effort follow-up channel after a missed call. A reply can immediately reactivate work and move to a human handler.
The modern contact sheet marks SMS as coming soon. There is no contact-level reminder, next-action record, or lead outcome. India SMS is a separate template delivery path rather than the same conversation model. SMS reassignment contains an explicit role-enforcement TODO.
samora-be/services/sms_service/init.go:46-100; samora-be/services/sms_service/service.go:181-404,901-1145; samora-be/database/schemas/sms.sql:66-124,149-233,239-291; samora-fe/src/components/sms/sms-conversation-sheet.tsx:197-309,419-529; samora-fe/src/components/company/contacts/workspace-contact-details-sheet.tsx:565-599
Users can configure business numbers, manage templates, send an approved template from a contact, read and reply to conversations, assign or resolve work, run bulk broadcasts, inspect delivery and read state, and cancel queued broadcast recipients.
Inbound processing finds the number and contact, reuses or creates an open conversation, deduplicates the message, writes channel and shared assignment state, then wakes the active handler. Outbound production sends create durable dispatch work. A sandbox send ends without a provider job. Free-form replies depend on the active WhatsApp service window.
WhatsApp provides template-led first contact, persistent mobile follow-up, delivery and read evidence, and rapid escalation after a response.
The provider and template gates mean an agent cannot simply invent a free-form first message. A closed ticket does not reopen; the next interaction creates a new episode. No WhatsApp action alone changes lead stage, owner, next step, or conversion result.
samora-be/database/schemas/whatsapp.sql:29-157,179-301,321-377; samora-be/services/whatsapp_service/messaging.go:256-598; samora-be/services/whatsapp_service/service.go:932-1148; samora-fe/src/api/queries/whatsapp/whatsapp-v2.ts:458-654; samora-fe/src/routes/company/campaign-tabs/whatsapp-campaigns-tab.tsx:80-122,142-238,263-333
Users can connect a Gmail inbox, inspect threads and tickets, reply, close or reopen tickets, generate a draft, manage templates, and use email in campaigns. Actionable work lives in the escalation or ticket view; the generic log detail is read-only.
The webhook validates its signature and time window, deduplicates provider events, writes a durable email event, claims a processing lease, triages the message, then creates or links a ticket, contact, conversation, and assignment when routing requires them. Monitoring-only or unconfigured email can remain contactless.
Email supports long-form answers, pricing, documents, and follow-up that does not fit a short message.
The contact sheet Email action is disabled. Trigger mutation routes return 409 because the Channels page owns watches. Some mail is intentionally skipped before a contact or shared conversation exists. Email still has no canonical lead outcome or next-action record.
samora-be/services/email_service/init.go:53-121; samora-be/services/email_service/server.go:427-537; samora-be/services/email_service/service.go:883-1238,1267-1384; samora-be/database/schemas/email.sql:29-189,309-401; samora-fe/src/components/v1/omnichannel/gmail-tickets.tsx:88-169,192-279
A website visitor can start a chat through the widget. AI or a person can respond. Operators can inspect the transcript, observe unread state, see whether the conversation moved through AI, a queue, or a human, and close the conversation.
Chat writes a shared conversation, typed messages, timestamps, and assignment lifecycle. The system updates last-message and last-activity timestamps as messages arrive. Human queues and claims use the same shared assignment idea as the other conversation channels.
Chat captures high-intent visitors while they are present and lets AI hand the conversation to a person.
Chat history is still a channel thread, not a lead journey. It does not create a pipeline stage, due task, revenue outcome, or a cross-channel Activity record.
samora-be/services/chat_service/dao_transactions.go:330-371,1693-1731; samora-fe/src/routes/company/log-tabs/chat-logs-tab.tsx:89-113,181-235,318-386; samora-be/database/schemas/conversations.sql:11-65
A contact can have many calls, closed and open SMS or WhatsApp episodes, email threads, and chat conversations. Channel screens show their own messages, statuses, assignments, and timestamps. Workflow executions keep step attempts and events.
A shared parent identifies the contact and channel. Typed tables retain provider details. Assignment rows record who handled an episode. Closing SMS or WhatsApp ends that episode, and later inbound contact creates a new one. Workflow steps can point to the exact conversation and provider record.
Operators can review prior touches before replying, and automation can correlate an inbound message to the exact action that invited it.
No lead or opportunity groups all channel episodes under one commercial objective. The product does not show one raw, canonical cross-channel timeline with tasks, notes, stage changes, approvals, and revenue events.
samora-be/database/schemas/conversations.sql:11-156; samora-be/database/schemas/workflows.sql:152-255; samora-workflows/internal/store/replies.go:18-97,262-328; samora-fe/src/routes/company/central-campaigns/hub/contact-runs.tsx:16-121
Contact Memory stores a rolling summary, interaction count, last channel, profile facts, structured facts with provenance, and append-only memory events. Channel screens and workflow execution views also expose their own timelines.
Eligible conversation endings enqueue memory work. The memory service updates summary and facts while preserving source information. Workflow step_events, chat messages, call rows, and channel message tables each record part of the history. PostgreSQL notifications wake listeners but do not create an audit row.
Memory gives the next AI or human a compact account of earlier conversations and known facts.
Memory is derived context, not the authoritative business history. There is no generic Activity table covering message, call, note, task, stage, owner, approval, handoff, and conversion changes. A missed notification must be recovered from durable channel rows or a sweep.
samora-fe/src/api/types/memory/memory-types.ts:1-77; samora-fe/src/components/company/contacts/contact-memory-section.tsx:141-185,210-461; samora-be/database/schemas/workflows.sql:241-255; samora-be/database/schemas/notifications.sql:1-27,30-101,193-338
Users can configure disposition questions for call outcome, interest, lead quality, and follow-up requirements. Call details and analytics can show evaluation answers in supported paths. Campaigns and conversations have operational statuses such as running, completed, failed, open, or closed.
Disposition configuration can attach to agents or dialer folders. Some call evaluation paths produce answers and reports. Campaign status says whether processing finished, not whether the lead converted. A definition is a question to ask, not the business answer itself.
Outcome questions help a person judge interest and call quality. Operational statuses show whether outreach ran.
There is no governed lead stage, stage-transition history, canonical qualification result, won or lost reason, appointment outcome, or conversion record. Backend source did not show a current per-conversation disposition-result table. The advanced inbound frontend also replaces evaluation arrays with empty arrays on one path.
samora-be/database/schemas/dispositions.sql:12-58; samora-fe/src/routes/company/company-dispositions.tsx:65-145,147-269; samora-fe/src/components/analytics/outcome-analysis.tsx:75-220; samora-fe/src/hooks/data/analyse/use-inbound-calls.tsx:212-245,260-299; samora-be/database/schemas/campaigns.sql:32-53
A dialer-list item can hold notes and a status. The legacy contact model has remarks. Contact Memory can hold structured facts. Workflow nodes can also contain authoring notes.
These values remain attached to the dialer item, legacy record, memory fact, or workflow definition that created them. They do not appear as one chronological note stream for the lead.
A dialer operator can leave context for the next attempt. Memory facts can carry stable information into later conversations.
There is no general contact or lead note with author, visibility, created time, edit history, mention, attachment, or link to a goal and conversation. A memory fact is not a human note and should not be used as one.
samora-be/database/schemas/human_operations.sql:251-383; samora-fe/src/components/company/hil/dialer-list-contact-sheet.tsx:200-355; samora-fe/src/api/types/memory/memory-types.ts:1-77; samora-fe/src/api/types/crm/crm-types.ts:3-37
A workflow can wait, retry, wait for a reply, and run a later node. Campaigns can be scheduled. Dialer items can say callback required. Post-call code can send messages or alerts in some legacy paths.
A Temporal timer keeps workflow progression durable. A reply can beat the timer and choose another graph branch. These are execution mechanics inside one predefined graph. They are not a user-visible due task with assignee, priority, due time, snooze, completion reason, and dependencies.
Existing waits and retries prevent some multi-touch sequences from stopping after one attempt.
No generic task, reminder, follow-up, next-best-action queue, or overdue service deadline was found. Callback-required has no general due-time contract. New work cannot yet emerge as a durable product record merely because the model decided it is needed.
samora-workflows/internal/workflows/contact.go:364-459,604-672; samora-be/database/schemas/workflows.sql:102-134,209-255; samora-fe/src/components/company/hil/dialer-list-contact-sheet.tsx:200-355; samora-lambdas/post-call-actions/main.py:157-367
AI can escalate to a queue or person. Operators can claim, answer, reject, reassign, reply, resolve, take over a live call, transfer it, or end takeover. Queue screens show demand, available agents, wait time, answer rate, and service breaches.
Queue escalation changes shared assignment and enqueues dispatch in one transaction. Voice offers require online presence and a fresh heartbeat. Asynchronous email, WhatsApp, and SMS can assign the least-loaded active member without requiring live presence. Timeout and retry logic free abandoned offers.
An interested or confused lead can reach a salesperson. The assignment journey remains visible within the conversation.
Human approval of an autonomous action is not yet a general runtime concept. There is no durable request saying what decision is needed, who may answer, when it expires, and which pending work it blocks. Lead ownership also remains separate from conversation handoff.
samora-be/services/human_operations_service/dispatch.go:173-367,417-767; samora-be/services/human_operations_service/dispatch_dao.go:133-201,332-620; samora-fe/src/routes/company/hil/overview.tsx:245-320,399-525; samora-fe/src/api/queries/hil/workspace-queue-offers.ts:17-91,104-235
Users can draft and publish versioned graphs with voice, SMS, WhatsApp, email, wait, wait-for-reply, condition, split, retry, and end nodes. Campaigns select an audience, pin a workflow version, schedule or launch, pause, resume, cancel, inspect each recipient, and retry a failed node.
Temporal starts one contact workflow per campaign recipient. Each workflow follows a published edge graph. It checks suppression before every attempt, dispatches channel work, waits for a provider result or reply, records node runs and step events, then follows the matching edge. Timers and signals survive process restarts. Reconciliation repairs missed wake notifications.
Samora can already run cross-channel sequences for many contacts, correlate replies to the correct outbound attempt, retry safely, and expose execution history.
The next node still comes from a graph authored before execution. The system does not reconsider a high-level goal and invent new work after every event. A campaign objective is descriptive text, not an executable success contract. Current local workflow files also contain uncommitted work, so deployed parity must be checked separately.
samora-be/database/schemas/workflows.sql:1-18,102-255; samora-be/database/schemas/campaigns.sql:1-20,74-164; samora-workflows/internal/workflows/contact.go:180-320,675-840; samora-workflows/internal/triggers/router.go:408-526,927-1093; samora-workflows/cmd/worker/main.go:58-116
The frontend bell can load notifications, show unread count, mark one or all read, expand messages, and navigate using route templates. Channel screens also use polling, WebSockets, server-sent events, or database wake signals.
Backend database notifications are lightweight wake hints. A durable channel row or event remains the fact that a worker re-reads. The UI bell expects a notification API. Human queue offers use authenticated streaming events.
Users can notice work that needs attention and see live queue or conversation changes.
The standalone Notifications route is only placeholder text. A wake notification is not a business Activity record. Product and backend route parity for every bell item must be verified before calling this a complete alert center.
samora-fe/src/components/notifications/notification-bell.tsx:16-218; samora-fe/src/api/queries/notifications/notifications.ts:13-88; samora-fe/src/routes/notifications.tsx:1-3; samora-be/database/schemas/notifications.sql:1-338
Users can inspect calls, transcripts, recordings, campaign status, per-recipient execution, delivery and reply results, outcome-question distributions, queue metrics, workflow node history, and some legacy campaign analysis exports.
Campaign rollups aggregate operational counters such as dispatched, delivered, engaged, no answer, failed, and completed. Channel and workflow rows supply detailed drilldown. A report can say an execution finished even if no sale occurred.
Teams can find failed sends, unanswered calls, engaged recipients, slow queues, and weak campaign nodes.
There is no canonical conversion, source attribution, owner attribution, revenue, opportunity value, funnel stage, cohort, cost per converted lead, or multi-touch attribution record. Operational completion must not be reported as business success.
samora-be/database/schemas/campaigns.sql:147-164; samora-fe/src/routes/company/central-campaigns/hub/campaign-detail.tsx:60-131,162-225,292-417; samora-fe/src/components/analytics/agent-disposition.tsx:70-145,180-221; samora-lambdas/campaign-finished-analysis/main.py:26-72
Samora has workspace roles and named permissions across contacts, campaigns, calls, channels, memory, and human operations. Users can connect provider accounts through Composio and configure voice, SMS, WhatsApp, email, numbers, templates, queues, and agents.
Authentication establishes workspace and effective role before route permission checks. Services enforce current assignment and record scope. Integration rows keep provider identifiers and safe metadata while Composio owns credentials. Dispatch workers apply quotas, leases, retries, and unknown states rather than blindly sending twice.
These controls make real outreach possible while limiting access, cost, provider misuse, and duplicate delivery.
A goal-driven system still needs a single capability registry that tells the decision layer what is available now, for this workspace and lead. It also needs one policy decision for consent, quiet hours, budget, channel rules, approval, and human takeover before any model proposal can become a send.
samora-be/authorization/permissions.go:3-12,15-136; samora-be/authorization/policy.go:3-119; samora-be/services/integrations_service/service.go:143-369,448-503; samora-be/database/schemas/integrations.sql:1-47,127-149; samora-dispatcher/internal/store/jobs.go:194-274,393-503
The form portal has a separate case, invitation, OTP, form revision, interview workflow, extraction, review, approval, export, and DocuSign lifecycle. The frontend also contains legacy CRM, campaign, live-monitoring, and analytics screens. The landing application has a public voice demonstration. Operational Lambdas perform post-call actions, learning, memory, reporting, and alerts. The Slack bridge lets engineers operate a coding agent from Slack.
The form portal uses its own PostgreSQL source of truth and per-interview Temporal workflow. Calls and AI extraction are disabled by default until configuration is complete. The landing voice path demonstrates a public session rather than a lead record. The Slack bridge persists thread-to-coding-session mappings, not lead state. Several legacy frontend screens call older contracts or show explicit TODO text. Some Lambdas have separate retry and callback rules.
The form portal proves Samora can build durable, audited, human-reviewed work around a long-running customer case. Legacy screens and Lambdas contain reusable ideas and domain logic.
These parts do not form the current cross-channel lead lifecycle. The form portal is a separate vertical. The landing demo and Slack coding bridge are not CRM or conversion runtimes. Live views for non-voice channels, all logs, some campaign tabs, non-voice test, and analysis pages contain placeholders. A feature should count only when UI, API, durable records, and runtime path meet.
samora-form-portal/README.md:1-7,25-109; samora-form-portal/backend/app/applications.py:72-113; samora-form-portal/backend/app/routers.py:413-624,710-744; samora-landing-v2/src/VoiceAssistant.tsx:27-56; opencode-slack/src/index.ts:11-89; opencode-slack/src/bridge.ts:49-169; samora-fe/src/routes/company/company-live.tsx:68-79; samora-fe/src/routes/company/log-tabs/all-logs-tab.tsx:3-7; samora-fe/src/routes/agents/analyze-simple-page.tsx:5-10
Users can create, list, inspect, edit, and delete workspace agents. Each agent can carry separate instructions, runtime settings, developer settings, and escalation settings for voice, WhatsApp, email, chat, and SMS.
Agent identity and channel records are stored separately. Route middleware checks read or write permission before a handler runs. A channel update changes durable configuration used by later runtime calls.
A Samora-wide operator could create a specialist, change its guidance, or repair an escalation rule as part of a larger goal.
There is no versioned agent-change proposal, impact preview, goal link, approval record, rollback instruction, or post-change behavior check. Direct configuration writes are not yet an agentic work lifecycle.
samora-be/services/agent_service/init.go:20-48; samora-be/database/schemas/agents.sql:11-75; samora-fe/src/app.tsx:216-880
Users can create, test, inspect, edit, and delete workspace tools. They can attach tools to an agent, choose channels for the association, update that choice, and detach a tool.
Workspace tools store a name, description, and JSON configuration. A separate row joins one tool to one agent and records allowed channels. Unique indexes prevent two active tools with the same workspace name and two active copies of the same assignment.
This is the start of a capability catalog. The decision runtime can see a filtered, versioned description of actions available to the current user and subject.
The current generic configuration is not enough for autonomous use. Each callable capability still needs a strict input and output schema, risk class, authorization rule, timeout, retry rule, approval rule, secret policy, and repeat-protection key.
samora-be/services/tools_service/init.go:18-40; samora-be/database/schemas/tools.sql:1-85
Users can upload, list, and delete workspace documents. They can attach a document to an agent, detach it, and choose which channels may use it.
Samora stores document metadata and a retrieval identifier in PostgreSQL, file content in object storage, and searchable content through the vector service. Agent-document rows keep channel scope.
An agentic goal can prepare or repair an agent's knowledge set, wait for processing, and verify retrieval before the agent talks to customers.
Deletion and reassignment need explicit approval and impact checks. The goal runtime also needs an indexing result event and a version pinned to the decision that used the document.
samora-be/services/kbase_service/init.go:20-65; samora-be/database/schemas/kbase.sql:6-86
What happens now. Individual services know how to create agents, store documents, send messages, run workflow graphs, and manage conversations. No one durable record owns a free-form objective that crosses those services.
Why this blocks the desired behavior. Without a goal contract, resource scope, subject runs, event ledger, decision record, dynamic work, approval state, and completion test, a later worker cannot know why earlier actions happened or what remains.
Objective, revisions, selected subjects, pinned versions, authority, budget, success test, stop test, and result.
Decisions, work items, dependencies, waits, attempts, approvals, conflicts, cancellations, and settlement.
Events that link model proposals, policy decisions, Samora mutations, provider outcomes, human actions, and completion evidence.
A contact is not a lead. An agent is not its current configuration version. A campaign is not each recipient's execution. A conversation is not the full customer relationship. The new goal layer links these records. It must not collapse their meanings into one generic object.
What happens. A durable goal workflow owns the objective. It starts subject runs where independent progress is needed. Each run alternates among runnable work, blocked work, waiting, human attention, and resolved states. New events trigger a fresh bounded decision.
Why. This lets 100 contacts diverge while an agent configuration change remains one coordinated operation. Any worker can recover after a crash because ownership lives in records, not in process memory.
In simple terms: Temporal remembers when to wake. PostgreSQL remembers what is true. Agent workers think briefly. Existing services act.
What happens. These records survive every model call and worker. Each has one job. Together they answer why work exists, what it may touch, what happened, what is pending, and whether the objective is done.
Why. A single prompt, transcript, or JSON state blob cannot safely represent authorization, product truth, retries, waits, and audit history.
What happens. Samora turns the message into a goal contract, resolves exact resources and authority, creates the smallest useful run tree, then repeats context, decision, checked work, result, and waiting until resolution.
Store the user's words, identity, workspace, selected objects, attachments, and timestamp.
Calculate the user's current workspace role and permissions before asking a model what to do.
Extract outcome, scope, success, stop, deadline, budget, autonomy, approval rules, and unknowns.
Stop for information that cannot be safely inferred. For example, which production campaign may be retried or whether a customer-facing instruction may change.
Resolve IDs, filters, current versions, exclusions, and conflict keys. Record later scope changes as revisions.
A durable coordinator owns pause, resume, cancellation, budgets, aggregate progress, and completion.
Fan out only where pieces can progress or wait independently. Record parent and dependency links.
A run may start with inspection, research, validation, drafting, a direct safe action, or a human question.
Load authoritative facts and the smallest useful history. Remove secrets and unrelated personal data.
A short-lived OpenAI Agents SDK run may use read tools or specialist agents. It returns a schema-valid intent.
Fixed code rechecks permissions, scope, versions, conflicts, budgets, and approval rules before writing work.
A worker calls the existing domain service. It records the attempt, repeat-protection key, changed rows, receipt, and safe error.
Normalize fixed outcomes first. Use bounded language analysis only for content that needs interpretation.
Record event predicates and a deadline. Temporal sleeps. No model or worker remains assigned.
Store the incoming event, supersede stale work, rebuild context, and create a new decision turn.
Close only when terminal rules pass and required work, approvals, and waits have settled. Report business outcome separately from execution health.
What happens. A decision worker receives one versioned envelope. It compares the goal with the current subject, new events, prior results, other active work, waits, policy, available capabilities, and human instructions. It returns typed proposals, not executable prose.
Why. The component that understands a result should not automatically gain permission to mutate a resource. Keeping four stages apart gives Samora a clear audit trail and safe retries.
| Input | Question it answers | Source |
|---|---|---|
| Goal and current revision | What outcome and limits govern this turn? | Goal store |
| Subject reference and version | Which exact Samora object or case is being considered? | Domain service and scope snapshot |
| Recent facts and relevant history | What changed and what evidence led here? | Event ledger and domain records |
| Open work, dependencies, waits, and approvals | What is already happening or blocked? | Goal runtime records |
| Capability snapshot | Which typed operations exist for this actor and subject now? | Capability registry |
| Policy, budgets, risk, and conflicts | What may happen, what requires a person, and what is forbidden? | Authorization and policy service |
| Other goals touching conflict keys | Would this action contradict or duplicate other work? | Conflict index |
Keep the structured decision, short rationale, cited evidence, confidence, model and prompt version, policy result, and usage. Do not store private chain-of-thought. The next worker needs evidence and conclusions.
What happens. A wait records which events can satisfy it and when to reassess if none arrive. Temporal suspends the run without holding a worker. The first relevant event or deadline causes one serialized re-evaluation.
Why. A four-hour timer cannot ignore a reply after ten minutes. A provider callback cannot be lost because a model process exited. A human approval may take days.
| Waiting for | Early wake event | Deadline behavior |
|---|---|---|
| SMS, WhatsApp, email, or chat reply | Inbound message linked to conversation and attempt | Reassess silence and choose follow-up, another channel, or stop. |
| Call completion | Provider or voice-agent final result | Reconcile an unknown call state before retry. |
| Integration authorization | Verified provider connection callback | Remind the authorized user or stop without exposing credentials. |
| Knowledge processing | Indexing success or failure | Inspect status and escalate a stalled document. |
| Human approval or handoff | Approved, rejected, answered, accepted, or declined | Expire safely, notify, and choose a fallback. |
| Another work item | Dependency settled | Apply the recorded propagation rule. |
If an event and deadline arrive together, store both and serialize the next decision for that subject run. The context version and repeat-protection keys prevent two contradictory changes. A late relevant event can cause another decision.
What happens. Any compatible worker can claim a bounded item, load its durable context, run one agent turn or one deterministic action, write the result, and release the lease. The durable goal workflow is the coordinator. It is code, not a permanent language model.
Why. Permanent model ownership traps state inside a process, makes failover hard, and wastes compute while the system waits. The work queue should own availability. Records should own memory.
Start with one manager agent contract and a small set of narrow specialists. Add a specialist only when it needs different instructions, tools, output schema, risk policy, or evaluation. Do not create an agent for every database table. Use agents-as-tools for bounded research, classification, summarization, and drafting while the manager retains decision ownership. Use an SDK handoff only when another agent should own the rest of the current conversational turn.
The goal workflow is the durable main system. The SDK manager agent is temporary. Its subagents are even narrower and live only inside that turn. None owns a subject, timer, credential, or canonical memory.
What happens. Samora stores every fact needed to resume or explain a goal. Workers and agent call stacks may disappear after each bounded turn.
| Truth owner | Owns | Must not own |
|---|---|---|
| PostgreSQL | Product objects, goal contracts, directives, events, proposals, work, approvals, attempts, audit, and projections. | A sleeping process or hidden model memory. |
| Temporal | Durable progression, timers, signals, retries, cancellation, and serialized lifecycle transitions. | Contacts, agent settings, transcripts, or business outcome truth. |
| OpenAI Agents SDK | One bounded turn, tool loop, specialist calls, guardrails, structured output, and short approval continuation state. | Days-long product continuity, tenant policy, provider credentials, or canonical memory. |
| Existing Samora services | Authorized domain mutations and reads, provider adapters, and resource-specific validation. | High-level goal selection. |
In simple terms: if every model process stops tonight, Samora must know exactly what to do when an event arrives tomorrow.
What happens. An adapter authenticates and deduplicates an incoming event, stores it, correlates it to affected resources and goals, updates projections, then signals the relevant Temporal workflows. Each awakened run rebuilds context before deciding.
What happens. Samora creates a durable human request with the exact question, proposed change, evidence, choices, allowed responders, expiry, and blocked work. The answer is an authenticated event.
Why. Approval cannot be a transient chat message. Configuration changes, credentials, customer promises, destructive actions, uncertainty, and ownership transfers need accountable people.
| Human case | System behavior | After the response |
|---|---|---|
| Missing information | Ask a concrete question and block only dependent work. | Record a directive, rebuild context, continue. |
| Sensitive mutation | Show the exact resource diff, impact, and rollback before approval. | Recheck current version and permission, then execute or reject. |
| Integration credential step | Send the authorized user through the provider-owned connection flow. | Store only safe connection status and wake on verification. |
| Conversation or sales handoff | Transfer the conversation and relevant goal context, then wait for acceptance. | Change operational ownership and continue or resolve under the goal rule. |
| Manual override | Pause or cancel conflicting automated work before the person acts. | Record the human action and reconsider the remaining objective. |
If the user says "do not launch; update only the draft agent," Samora writes a new directive, blocks the launch, cancels work that has not started, preserves completed facts, and creates a fresh decision. It never rewrites history as though the first instruction did not exist.
What happens. Traditional automation selects the next prewritten edge. The desired runtime decides which work should exist after reading the current goal and facts.
The graph defines the possible future.
Facts are truth. Plans may change.
Agentic choice should sit above reliable automation. A decision may choose "launch this published campaign" or "send this approved WhatsApp template." Existing code still validates the campaign or template, dispatches it, handles callbacks, and records outcomes. Do not turn compliance and delivery mechanics into prompts.
What happens. Samora adds a goal control plane above current services. Temporal owns durable progression. PostgreSQL owns product and audit facts. A private OpenAI Agents SDK runtime performs one bounded reasoning turn. A fixed gate converts allowed proposals into durable work. Existing services execute it.
Why. Samora already has useful service APIs, durable contact workflows, timers, signals, retries, dispatch leases, provider correlation, human queues, and permission checks. Replacing those would create competing sources of truth.
The Agents SDK is the reasoning loop inside one activity. It is not the day-scale scheduler, database, authorization service, event bus, or provider executor. SDK session or resume state is a convenience checkpoint. It never replaces Samora's canonical records.
What happens. Existing projects can supply orchestration, agent loops, UI events, or tool protocols. None supplies Samora's complete product truth, workspace policy, channels, human lifecycle, and audit model.
Why. Selecting an "agent framework" by name can hide the hard requirements: durable events, event or deadline races, exactly-once intent, cross-goal conflicts, authorization, and business completion.
Durable workflows, timers, signals, retries, cancellation, and history.
The long-lived goal coordinator and logical subject workflows for the resources being changed or observed. Samora already uses it.
Goal records, context, decisions, policy, capability discovery, product audit views, and Samora domain semantics.
Best foundation. Keep it as the only lifecycle scheduler. A second scheduler would split timer and retry ownership.
A model-driven agent loop with tools, handoffs, guardrails, sessions, and tracing helpers.
One bounded decision turn, specialist delegation, structured tool use, and handoff patterns.
Days-long business continuity, event inbox, timers, product state, tenant authorization, duplicate-action controls, and Samora domain records.
Useful inside the decision service. It is not the durable goal runtime. Samora still owns storage, deployment, tools, approvals, and execution.
A stateful Python or TypeScript graph for agent reasoning, checkpoints, and human interrupts.
Complex reasoning inside one decision turn or a specialist analysis sidecar.
The product ledger, provider action safety, workspace policy, and current Temporal lifecycle.
Optional sidecar. Do not let it become a second scheduler for the same subject.
A task and agent orchestration service with durable waits, events, retries, concurrency, rate limits, and a web view.
Most orchestration mechanics in a greenfield product.
Samora-specific product truth, policy, channels, and migration from current Temporal histories.
Strong greenfield alternative. In Samora it duplicates an existing runtime, so adoption would be a migration project.
Durable execution, stateful services, events, timers, retries, and introspection.
A different durable base with a good Go fit.
All Samora domain semantics, policy, UI, and a safe migration from Temporal. License terms also need review.
Technically credible alternative, not an additive component. Do not run both for the same subject.
A standard protocol for exposing tools and context to a model client.
A capability adapter for approved Samora tools such as read contact, draft reply, or request handoff.
Scheduling, durable state, audit, policy, event correlation, waiting, and memory.
Use for tool interoperability if useful. Never mistake it for the machine.
An event protocol between agent backends and interactive user interfaces.
Streaming goal progress, work updates, approvals, and tool results to the chat control surface.
The canonical database, scheduler, authorization, and provider execution.
Optional transport. It can make the system visible but cannot keep it alive.
A chat-led workspace where a coordinating agent uses tools, delegates bounded work to subagents, asks for approval, and reports results.
The user mental model for goals, task trees, specialist workers, permissions, and visible artifacts.
Real-world product and customer events, day-scale waits, provider callbacks, consent, cross-goal conflict control, and CRM truth.
Copy the interaction contract, not the coding runtime. Codex is an analogy, not Samora's lifecycle engine.
A personal agent loop with tools, skills, memory, subagents, scheduled jobs, and messaging gateways.
A sandboxed operator assistant, research helper, or reference for bounded subagent delegation.
Multi-tenant goal state, reliable event waits, provider dedupe, fixed policy, business records, and product audit.
Useful for experiments. Do not give it permanent subject ownership or direct provider credentials.
Role-based agent crews, tools, and event-driven flows for coordinated model work.
Offline experiments, message drafting, research, or a bounded decision-sidecar implementation.
Durable timers, provider action safety, tenant policy, product truth, event correlation, and the complete lifecycle.
Use for evaluation or specialist reasoning, not as the lead runtime.
Visual integration workflows, connectors, webhooks, schedules, scripts, and internal automation.
One-off integrations, back-office glue, and low-risk operator automation.
The authoritative per-subject runtime, event truth, conflict rules, policy, and compliant action ledger.
Keep it at the edge. Its separate runtime and source-available license make it a poor lifecycle owner.
Scripts, jobs, flows, schedules, webhooks, forms, and internal operational tools.
Reconciliation utilities, admin tools, data repair, and isolated integration jobs.
Goal and subject continuity, event correlation, provider idempotency, product authorization, and audit truth.
Useful for internal tooling. Do not add its scheduler to the same subject lifecycle without a migration decision and license review.
Keep Temporal as the durable owner. Add the goal and subject records in PostgreSQL. Put a typed decision service behind a Temporal activity. Reuse existing Samora action paths and human queues. Add inbox and outbox records, reconciliation, a capability registry, fixed policy, and a product-safe event stream. Use the OpenAI Agents SDK only for bounded reasoning turns. Keep every durable wait, business record, authorization decision, and external side effect under Samora control. The separate technical specification gives the exact boundary.
What happens. The user talks to one goal thread while a visible work tree changes below it. Samora shows what it understood, what it will touch, what is running, why it is waiting, which decision needs a person, and how the goal ended.
Why. A Codex-like experience comes from persistent goals, tools, task state, evidence, approvals, and bounded specialists. It does not require a model process to remain alive.
User "Prepare a renewal agent for WhatsApp and web chat. Use the new pricing guide. Run a test. If it passes, launch the September renewal campaign." Samora stores Goal v1 and resolves the named agent, channels, document, workflow, campaign draft, permissions, current versions, and approval policy -> creates dependent runs for agent config, knowledge, test, and campaign -> an SDK turn proposes an instruction diff and document attachment -> fixed policy requires approval for customer-facing instruction change User approves -> Samora rechecks versions and applies through existing agent and KBase APIs -> waits for knowledge indexing event or deadline -> runs a test conversation through the approved tool set -> evaluates the recorded test result -> asks for launch approval if policy requires it -> launches through the existing campaign service -> waits on campaign events and reports completion
User "Find why yesterday's campaign stalled. Retry only safe failures." Samora resolves the campaign and affected workflow executions -> reads node events, provider results, dispatch attempts, and current state -> specialist agents classify failure patterns without changing anything -> manager proposes a recovery set with evidence and exclusions -> policy blocks unknown provider outcomes and destructive resets -> approved retry work uses existing workflow retry paths -> Samora waits for new results, then reports recovered and unresolved cases
User
"Qualify these 100 contacts and hand interested people to sales."
Samora
creates one goal and independent opportunity or contact runs
-> each run can send, call, wait, answer, stop, or ask for a person
-> inbound events wake only affected runs
-> contact and channel conflict keys prevent duplicate outreach
-> the goal aggregates results without placing 100 histories in one prompt
-> final report separates interested, handed off, unreachable, opted out,
failed, and unresolved outcomesWhat happened. This cycle broadened the model from lead conversion to authorized work across Samora and produced a separate OpenAI Agents SDK technical specification. It did not implement the runtime or change product data.
Build a general goal control plane. A goal scopes typed Samora subjects. Durable workflows own continuity. Short-lived agent turns propose next work. Fixed policy and existing services own execution.
A lead-only runtime, permanent model ownership, one giant workspace agent, raw model access to providers or SQL, a rigid generated workflow, and a second scheduler beside Temporal.
The system needs explicit records, version checks, event correlation, and a capability gateway. That cost buys recovery, audit, safe concurrency, and human control.
This report, the new technical specification, the report hub, and the two Markdown source-of-truth files. The full-server-URL rule was already present in AGENTS.md and CLAUDE.md, so it was verified rather than duplicated.
No Samora product source, dependency, database row, Activity row, provider, campaign, workflow execution, firewall, DNS record, or public-ingress rule changed.
The team site contains only an index and the two architecture documents. Repository source and the rest of the local report archive are not published. Deployed copies show file-path citations as text.
For the repository, remove the new report card and technical-spec file, then restore this report and the appended Markdown entries. For Pages, roll back to a prior successful production deployment in the dashboard or delete the isolated project.
Both reports must pass link, citation, HTML, responsive, and HTTP checks. The workspace quiz gate then requires at least 80%.
samora-fe/src/app.tsx:216-880samora-be/services/agent_service/init.go:20-48samora-be/services/tools_service/init.go:18-40samora-be/services/kbase_service/init.go:20-65samora-be/services/integrations_service/init.go:39-61samora-workflows/internal/workflows/contact.go:180-840samora-workflows/internal/triggers/router.go:927-1093samora-be/database/schemas/workflows.sql:1-255samora-be/services/human_operations_service/dispatch.go:173-767samora-be/services/realtime_service/broker.go:21-64,122-203Status: not accepted. Score: 0/8 pending. A passing score is 7/8.
Reply with answers numbered 1 through 8. The session stays open until the answers pass.
The durable goal workflow and its stored subject runs, events, work, waits, approvals, and results. A model process does not stay running.
Samora must also operate agents, tools, knowledge, integrations, campaigns, workflows, conversations, queues, and reports. A typed subject can represent any of them. A lead or opportunity is one subject type.
Store and deduplicate the event, correlate it, satisfy or supersede the wait, signal the durable run, rebuild current context, and decide again. Do not wait the remaining time.
They have different evidence, retry, security, and audit needs. A model may interpret and propose, but fixed code must authorize and existing services must perform side effects.
The goal and revisions, resource scope, subject runs, events, context references, decisions, work, dependencies, waits, attempts, approvals, policy and capability versions, and resolution state.
It runs one bounded reasoning turn with tools, specialists, guardrails, and structured output. It does not own long-lived scheduling, product truth, authorization, or provider side effects.
A resource-operation conflict key, expected resource version, serialized subject decision, current permission check, and repeat-protection key. A mismatch forces a fresh decision or human choice.
Reuse Temporal, PostgreSQL domain records, current services, dispatchers, provider adapters, conversations, human queues, auth, and configuration. Add goal and subject state, the event ledger, context builder, SDK decision runtime, capability and policy gate, dynamic work, waits, approvals, conflict control, and completion logic.