Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Translation pending
Not merely a system of record — a system of understanding. Cooperating AI Agents react to each other over a live event bus, led by an Orchestrator, conducting your business in perfect resonance. Ask i
Translation pending
BusinessPython · PHPGitHub @alanqin22OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Conscestra CRM — the conscious orchestration of customer intelligence. An AI-native CRM where an Orchestrator directs cooperating domain AI Agents (leads, contacts, accounts, opportunities, orders, accounting & more). Built on FastAPI, LangGraph & PostgreSQL with deterministic stored-procedure routing, session memory, and a verifiable audit trail.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Conscestra CRM — The Conscious Orchestration of Customer Intelligence
No signup required. Drop into any module and talk to the AI agents
directly, or use the inline forms — same experience either way.
Conscestra is a governed orchestration system for customer intelligence and
business execution. Specialized AI agents work from one shared business
context, act only through explicitly authorized capabilities, and are
coordinated toward outcomes the organization has defined.Read the full README ↗🚀 Live Demo → agentorc.ca
No signup required. Drop into any module and talk to the AI agents directly, or use the inline forms — same experience either way.
Conscestra is a governed orchestration system for customer intelligence and business execution. Specialized AI agents work from one shared business context, act only through explicitly authorized capabilities, and are coordinated toward outcomes the organization has defined.
Conscious describes contextual awareness, not sentience. Conscestra does not simply execute an instruction. It interprets that instruction within the state of the business — the relationships, history, current conditions, objectives, constraints, and authorization that surround it — and coordinates the appropriate intelligence and actions within defined boundaries.
Orchestration is the architecture, not the branding. An orchestra produces one coordinated performance from many specialized performers because they share a score, keep precise timing, and are coordinated toward a single outcome. Conscestra applies the same structural principle to enterprise AI:
| In an orchestra | In Conscestra |
|---|---|
| The objective the performance serves | Executive leadership establishes the business objective |
| The conductor | The Orchestrator coordinates agents, sequencing, dependencies and events |
| The musicians | AI agents perform specialized roles within a defined business domain |
| The score, and its boundaries | Governance and policy define what may be done, and under what conditions |
| What each performer needs to know | Business data and context — records, communications, workflows, history |
| Rhythm and timing | Events, deadlines, sequencing and workflow state |
| The recording | Audit and monitoring — what occurred, who acted, what resulted |
Authority is distributed across those layers rather than concentrated in one. An agent cannot invent a capability it was not granted, widen its own authorization, or act outside the scope its role defines. Consequential actions become proposals subject to independent evaluation and human approval.
Safe by default · Opt-in outreach · Fully audited · No sign-up to explore
agentorc.ca is six pages, ordered as one architectural argument — understand → contextualize → coordinate → execute → govern → verify → improve:
| Page | What it covers |
|---|---|
| Home | What Conscestra is, how it understands the business, shared context, coordinated intelligence |
| Capabilities | Business execution — multilingual voice, order self-service, customer portal, AI SDR, obligations, cases, routing, analytics |
| Governance & Trust | What AI is permitted to do — four layers of control, independent critic review, capability grants, consent, audit trail |
| Assurance | How those controls are proven — negative testing, runtime verification, database integrity, tested recovery |
| Integration & Adoption | Measured improvement, MCP tools under the same authorization model, provider failover, guided onboarding |
| Company | Agentorc.ca, services, the 14 connected business modules, contact |
The sections below follow the same order and carry the same headings as the site, so a section here and its page there are the same argument.
The capabilities below are in production, and each was verified against the published artifact after deployment rather than inferred from a successful release. Work that is written and published but not yet running in production is listed separately beneath them, so the two are never read as the same thing.
Order economics are complete before an invoice is issued. When an order reaches a shipping status, the invoice it produces is created from the order's final economics rather than from the order as it stood a moment earlier. Commercial rules that are evaluated once at issue — a free-shipping threshold, a tax base — therefore see the amounts the order actually carries. Settlement remains a separate authority: recalculating what an order is worth does not alter what has been paid against it, and an invoice whose economics have been sealed is not revised by a later change to the order behind it.
Cancelling an order is a governed operation, not a field update. A cancellation carries a requesting party, a durable authorization, and consequences for the customer and the invoice. Generic order-update paths refuse to write a cancelled status and return an actionable message naming the capability that owns the operation, so the refusal reads as a wrong-operation answer rather than a permissions error. Both routes by which a status can reach the order procedure are covered, and the refusal is tested by deliberately removing each guard to confirm the test fails when the control is absent.
Scheduled work runs once across a multi-process deployment. Background processing elects a single leader through a database lock, and the verification confirms that the elected instance performed the work rather than merely acquiring the lock.
Database operations run inside explicit privilege boundaries. The application connects as a non-superuser role, and independent verification uses a separate read-only role, in a session the server confirms is read-only before any state is read.
A deployed procedure can be checked against the artifact it claims to be. An operator control resolves the expected version from the repository's governance pin, confirms that version is published, and compares the deployed procedure body, its security context, and its published description against it. The structural expectations are derived from the published artifact rather than written into the control, so a later authorized change moves the expectation with it instead of turning the check into an assertion about an older release. The control states what it does not prove, including execution grants, which are not a property of the artifact. It is a verification tool for operators rather than a runtime feature.
Classification of historical financial evidence is a governed capability. The platform can record an evidentiary classification against a defined population of historical financial records — for example, invoices whose tax jurisdiction resolves no configured rate — without altering the amounts those records carry. The capability is registered and enabled in production, which makes it dispatchable. Registration and enablement are not authorization: the capability becomes usable only once a decision policy governs it, an approval is granted, and an accountable identity is named.
What the capability writes is bound to what was approved. The approval carries a proposition built from a closed set of declared fields and hashed over a canonical projection of those fields, so the authorization refers to one exact statement rather than to a description of one. The proposition also carries a census identity and fingerprints over the specific records in scope. At execution the population is measured again, and the capability refuses if the census no longer matches — a population that has grown since approval is not silently included, and a stale authorization is refused rather than repaired.
Execution is accountable, concurrent-safe, and repeatable. The accountable party is supplied by the caller as an assignable identity and is never chosen by the capability; a request that names no identity is refused outright. A transactional advisory lock is taken before the duplicate guard is evaluated, because the guard alone is not sufficient under the database's default isolation. Running the same approved classification twice records nothing the second time, and an interrupted run leaves no partial result. Verification is independent of execution: a read-only tool compares what was recorded against the approved manifest without reusing the code that produced it, so the check does not inherit the assumptions of the thing it is checking.
The following is written, reviewed, and published, and is deliberately not described above as current platform behaviour:
Conscestra operates as a symphony of specialized AI Agents, each responsible for its own domain while remaining continuously aware of the larger business context.
Standing above them all is the Orchestrator — an intelligent coordinating agent that continuously directs collaboration among every component of the system.
These agents do not operate as isolated silos. They cooperate over a live event architecture, responding to business events as a single adaptive organism.
When a visitor signs up and verifies an email address, Lead, Contact, and Account Agents transform that individual into an active customer in a single coordinated process.
When an order is placed, the Order Agent triggers confirmation messages while the Email Agent notifies the customer automatically. When shipping occurs, dispatch notifications follow immediately.
When an invoice becomes overdue, the Accounting Agent drafts an escalating reminder sequence for the Email Agent to deliver. Once payment arrives, the Activity Agent records the resolution and closes the loop automatically.
Alert storms are digested and consolidated before they become operational crises.
Every interaction becomes part of a governed memory architecture that is transparent, replayable, traceable, and fully auditable.
Powerful AI collaboration should never become an invisible black box.
Conscestra replaces complex navigation and dashboard hunting with conversation.
Executives simply ask questions in natural language. The Orchestrator responds with decision-grade answers regarding:
No report generation. No dashboard archaeology. No waiting for analysts.
Every answer is grounded in live business events, structured organizational knowledge, and verifiable evidence. When uncertainty exists, the system explicitly acknowledges it, because trustworthy AI begins with intellectual honesty rather than artificial confidence.
Every response includes a transparent audit trail explaining how conclusions were reached and which systems contributed to the answer.
Modern businesses operate far beyond a single database. Conscestra therefore extends beyond CRM records into the broader information ecosystem. Every AI Agent can reach the live internet to retrieve current information with fully cited sources.
Executives can request:
The result is a formal Web Intelligence Briefing containing clickable citations and source attribution.
The platform also integrates directly with calendars, accounting systems, and external AI ecosystems through the Model Context Protocol (MCP) — in both directions. Assistants such as Claude and other MCP-capable systems connect directly to Conscestra's agents, organizational memory, and capability registry; and Conscestra's own agents can call tools hosted on external MCP servers, under the same grants and guardrails as every native action.
Conscestra introduces what it calls AI 360 Summaries. With a single click, executives can generate decision-grade briefings for accounts, contacts, opportunities, or customers. These summaries combine:
The result is not merely a snapshot of where the business stands today, but a forecast of where attention should move next.
Traditional CRMs record state. Conscestra models trajectory.
And no agent starts a task blind. Whenever any agent begins work on a customer — an agent-to-agent request, an inbound email, a workflow step — it is born with context: a compact briefing assembled automatically from everything the platform already knows. The churn profile, open balances, running workflows, pending approvals, warnings other agents have posted, the last conversation. A customer who writes in is never greeted like a stranger, and no agent ever asks a question the CRM already knows the answer to.
Beyond the on-demand 360, Conscestra maintains a persistent customer intelligence profile, recomputed every night for every customer — no LLM cost, fully explainable:
Conscestra doesn't simply capture leads — it prepares them for your sales team.
Every new lead is automatically enriched, verified, and intelligently scored. Historical conversion data predicts the probability of closing, while AI recommends the best sales representative based on industry expertise, customer history, and current workload. External enrichment fills in missing business information without ever overwriting human-entered data, ensuring your CRM becomes more complete over time while preserving data integrity.
And the prediction itself learns. Once enough leads have settled, Conscestra trains a predictive win-probability model on your own outcomes — explainable down to each factor's contribution, measured against an honest baseline on held-out history. A model that can't beat "just guess the average" is never even proposed; one that can still goes through governance, where an executive activates it with one click and can roll it back just as easily. Until then, the platform says so plainly rather than inventing numbers.
When a hot lead replies, the agent doesn't stop at a to-do. It checks the representative's real calendar availability, books the meeting at a slot aligned to the customer's preferred hour, protects it on the calendar, and sends a signed calendar invite — a hot reply becomes a confirmed meeting with zero human latency, and a person confirms what the agent committed to.
Traditional automation reacts once.
Conscestra's AI Agents execute complete, multi-step business plays.
A promising lead automatically enters a personalized follow-up sequence. Emails are drafted, reminders scheduled, meetings proposed, and nurturing continues until the prospect responds or the opportunity closes.
These workflows are not straight lines — they branch on live business signals. A prospect who replies mid-sequence is routed to an immediate meeting-booking step while the momentum is hot. A churn-risk customer with an open complaint skips the discount offer entirely — a promotion on top of an unresolved grievance reads as tone-deaf — and escalates straight to an executive. And because playbooks are stored as governed data rather than code, a new cadence ships as a configuration change, validated against the registered building blocks, without a deployment.
Customers showing signs of churn trigger retention plays that combine customer history, support interactions, and AI-generated win-back campaigns. New orders, customer replies, or resolved issues automatically conclude the workflow.
Every inbound email becomes a live business signal — matched to the correct customer, recorded on the timeline, and capable of triggering the next intelligent action. Marketing campaigns are generated directly from customer segments, optimized through A/B testing, and always respect consent, suppression lists, verified recipients, and unsubscribe preferences.
And email is no longer the only channel. Conscestra learns each customer's preferred channel — and can now act on it: agents send SMS and place voice calls through the same governed rails, an inbound text is matched to its customer and answered from approved knowledge, and every touch lands on the CRM timeline regardless of medium.
Your business keeps moving — even while your team sleeps.
Most support knowledge evaporates the moment a ticket closes. Conscestra keeps it — and grows it from five inflows, all through one governed approval queue.
Resolved email threads are mined into draft articles. Support-call transcripts are distilled the same way — the caller's words become the problem, the agent's answer the resolution. Every question the assistants couldn't answer is logged as a knowledge gap: the nightly gap pass takes the most-asked ones, asks the owning module agent (or, when no agent owns the answer, the live internet — with citations), and proposes the article. And an administrator can simply upload a product manual or policy document — PDF, page, or URL — on the knowledge management page: it is chunked, drafted into articles grounded strictly in the document, and queued for approval, idempotently, with one-click removal if a policy changes. The fifth inflow requires no administrator at all: when a known customer emails a document — a spec sheet, a policy, a manual — the attachment flows through the same pipeline into governed proposals, while a stranger's file never reaches a model.
Nothing publishes itself. A human approves every article; the critic checks each one first; usage counters show which knowledge actually earns its keep. Once approved, the same answers serve email, SMS, web chat, and the phone within the minute.
And retrieval now understands meaning, not just words. Every article carries an embedding alongside full-text search, the two rankings fused — so "my package still hasn't shown up" finds the order-status answer they share no words with. A noisy voice transcript that misses entirely gets one corrective rewrite before the question is logged as a gap. The knowledge base itself is tiered — customer-facing articles on one side, agent-only playbook guidance on the other, enforced at retrieval so internal knowledge can never surface in a customer reply — and a weekly hygiene pass flags articles past their review date or never used, while a nightly evaluation measures retrieval precision and answer faithfulness against a golden query set.
Every resolved case makes the next answer better. The help desk compounds.
The worst failure of a customer-facing AI is not a wrong answer. It is a dropped one — the conversation where the customer asked for a manager, or the agent said "someone will get back to you," and then nothing happened. A transcript records that moment; it does not oblige anyone to act on it.
Conscestra turns those moments into first-class escalation objects with an owner and a clock. Two very different triggers create them. The first is what the customer asks for — a request for a human, a complaint, a legal or safety word, a refund demand, repeated failed attempts at the same question. The second is subtler and easier to miss: the agent's own promise. When the AI says it will follow up, that sentence is scanned as it goes out, and the commitment is opened as an obligation before the customer ever sees the reply. An AI that can make promises must be a system that can be held to them.
Each escalation carries a service-level deadline appropriate to its reason — a legal or safety flag is not given the same runway as a general question — and one is opened per conversation, so a frustrated customer who asks three times gets one owner rather than three tickets. Breaches surface on the platform's own health view, and resolving the conversation resolves the obligation.
The conversation can end. The obligation cannot, until someone closes it.
An escalation is an event — the moment something went wrong. The work that event creates is a different thing entirely, and it is the thing that survives. The customer hangs up, the chat window closes, the shift ends. A transcript remembers what was said. It does not remember what is still owed.
Conscestra makes that work a case: a durable record with an owner, a
priority, and a state machine that will not let it quietly disappear. The
lifecycle is five states and the transitions between them are the entire
grammar — new → in_progress → waiting ⇄ in_progress → resolved, with
resolved → in_progress as the one transition meaning this came back, and
closed genuinely terminal. There is one transition matrix, written once. An
invalid move is refused, not logged and applied.
Four distinctions are enforced because each one, collapsed, produces a different everyday failure:
| A conversation resolved ≠ a case resolved | The customer stopped typing; nobody fixed anything |
| A case created ≠ work accepted | It has an owner's name on it; the owner has not agreed |
| Work accepted ≠ work completed | Someone is on it; it is not done |
| Resolved ≠ closed | Fixed today; it can still come back, and reopening is a first-class event that increments a counter rather than pretending it never happened |
Every change to status, owner, or priority is written to an append-only field history by a single writer — one row per field that actually changed, inside the same transaction as the change itself, guarded by a database trigger that refuses updates and deletes. History that can be edited is not history. The set of tracked fields is deliberately narrow: a log that records everything records nothing, because nobody reads it.
Cases connect back to what created them and forward to what they teach. Resolution times, first-response times, reopen rates and backlog age become service analytics; a resolved case can be mined into a draft knowledge article through the same governed approval queue as every other inflow — never published automatically, because a resolved case is not an approved answer.
The case layer ships behind flags (CASES_ENABLED on, CASES_AUTO_OPEN and
CASES_KB_FEEDBACK off) so an organization decides when escalations start
creating cases on their own.
A case with an owner is only as good as the owner being right. Assignment by round-robin gives a French complaint to someone who doesn't speak French and a hardware fault to someone who has never seen one.
Conscestra routes on recorded attributes — language, skill, capacity — and the operative word is recorded. A person with no languages on file does not match a rule requiring French; the system reports "no recorded languages" rather than assuming. Absent data never fabricates a match, which is the difference between routing that degrades honestly and routing that is confidently wrong.
Rules are data, not code: an administrator writes the conditions, and a preview shows who would receive the work and — more useful — why everyone else was excluded, before the rule is saved. Every rule change is versioned. Live workload feeds the decision, so capacity is a real constraint rather than an aspiration.
Underneath sits a deliberate piece of plumbing: one assignable identity space. Ownership means a person who can be assigned work, which is not the same as a contact who happens to be in the CRM — and the system reports identity collisions rather than resolving them first-match-wins. Answering confidently with the wrong person's record is worse than declining to answer.
For everything the playbooks don't already cover, executives can hand the Orchestrator a novel goal in plain language — "reduce overdue receivables this week" — and get back a concrete multi-step plan.
The planner composes exclusively from the platform's registered agent capabilities: plans are hard-capped in size, validated before anything runs, read-only steps execute immediately, and every action with consequences is queued for human approval — reviewed by the independent critic, routed to the right executive, reversible like everything else. In testing, the critic has rejected the planner's own proposals when the data didn't support them — three autonomous layers checking each other before a human ever looks.
The AI supplies judgment. Deterministic rails supply safety.
Executives can also rehearse a decision before committing to it. Ask the Orchestrator "what if we cut overdue invoices by 30%?" and the simulator maps the scenario onto a registered business metric, grounds it in the live value, and re-judges every active business objective under the new number — status before and after, how much of the gap to target closes, and the proportional ripple onto related metrics.
The language model only parses the question; every projection is pure arithmetic over real data, and the whole exercise is read-only by construction — nothing is changed, proposed, or sent. Rehearse the move, then hand the winning scenario to the planner as a goal.
The support line (The Phone Line Is a Digital Employee, below) answers people who are already customers. The front door is staffed too — for the people who are not customers yet. A prospect landing on the store can open a chat and reach the autonomous SDR: it answers product questions from the approved knowledge base, captures who they are and what they need, creates the lead, and books the intro meeting on a real calendar slot, all in one conversation. The same brain can staff a spoken sales line of its own, turn by turn, on a number dedicated to it.
The two are deliberately not the same assistant. Support earns its way to a customer's data by verified possession; the SDR is talking to someone it has no record of, so it is given no CRM access at all — nothing to leak, whatever it is asked. Its design is conservative in the same spirit: a deterministic state machine — not the language model — owns every fact captured and every action taken. The model only writes the next sentence, grounded in approved knowledge, with no tools. Both channels sit behind their own on/off switches and rate limits, so the front door opens exactly as wide as you choose.
Chat to qualified lead to booked meeting — before a human ever says hello.
The same chat bubble on the store is now a Sales & Service agent that actually knows the shop. Ask it what a shopper asks — what a product does, how it compares, whether it's in stock — and it answers from the live catalog, with the real price, the genuine sale saving, and the exact units on hand, never an invented number. "What's the best computer under $2,000?" returns real in-stock laptops with reasons, then asks what you'll use it for.
It knows the rules, too. Shipping, returns, warranty and payment questions come from the approved policy base. On discounts it stays honest: it can surface a real, active coupon and apply it at checkout — reducing the order and recording the redemption — but it never invents an offer, and anything past the brand's discount cap routes to a human for approval.
And it can speak to you about your account — but only once it knows you are you. A signed-in shopper, or one who verifies with a code emailed to the address on file, can ask "where is my order?" or "what's my balance?" and get an answer scoped to their record alone, read-only — the identity proven by the session or the code, never by a name typed into a box.
Every shopper question — product, price, policy, or their own order — answered by one agent, grounded in real data.
For a long time the phone line did more for a verified caller than the website did for a signed-in one. A customer could log in and reach exactly two things: a health check and a sign-out button. Everything they might actually want to know — orders, invoices, open cases, outstanding quotes — existed, and was reachable by voice, and was invisible on the web.
Conscestra now gives customers a portal onto their own record: orders and their line items, invoices and balances, the cases they have open with real status, and the quotes they have been sent with real expiry dates. The same assistant answers questions about it in plain language — and the AI calls the same functions the pages do, so it is incapable of returning something the pages would not show. There is no second data path to keep in agreement.
The security model is the one the voice channel already proved, reused rather than reinvented — because a per-channel copy would drift, and the weakest copy would silently decide what every customer can see:
One detail matters more than it looks. A self-registered user is a lead, not yet a customer account — and they never get an empty Orders page. An empty list reads as "you have no orders" when the truth is "you are not linked yet," and that distinction is the whole difference between a working product and a broken one. They get an explicit onboarding state instead.
The number a prospect calls is also a command line for the people who run the business. Text it a question — "the latest order for David Chen?", "find the opportunity with account agentorc.ca" — and the orchestrator routes it to the owning agent, reads the live CRM, and texts back the answer condensed to a sentence. Accounts, contacts, leads, opportunities, orders, products, activities, accounting: what the fleet answers in the browser, it answers on a phone, with nothing installed.
Which makes authorization the entire problem. Inbound SMS is a public channel — the carrier signature proves a message came from the carrier, not who sent it, and caller ID is spoofable. So the CRM answers only the numbers on an explicit operator allowlist; every other sender gets the knowledge-grounded reply that never touches the database. An empty allowlist, the default, means nobody.
And the channel is read-only, enforced by PostgreSQL rather than by good intentions. An operator session runs inside a read-only transaction, so a misrouted word — a bare "yes" is enough for a language model to resolve a create — is refused by the database itself, whatever the agent chose to call it. Questions by text; changes stay in the app.
The CRM in your pocket, with the write path closed.
Customers can now call the company and reach a support agent that knows exactly how much to trust each caller. Anyone gets answers from the approved knowledge base. Staff on the operator allowlist get the live CRM, read-only. And a customer asking about their own account is verified first — not with security questions an AI could be talked out of, but by possession: a one-time code texted to the number on file, entered on the keypad, expiring in minutes, three attempts then a human follow-up.
This is the support line — for people who are already customers. Prospects who have not bought anything meet a different assistant with different powers (An SDR That Never Sleeps, above): one that can qualify them and book a meeting, and that is given no access to CRM data at all. Two callers, two jobs, two sets of keys.
A verified caller can hear their balance and open invoices, check recent orders, get payment help grounded in approved policy — with a payment summary emailed to the address on file — and ask to change their contact details, which becomes a governed proposal a human approves, never a direct write. There is exactly one thing the line changes on its own — a cancellation, under conditions the database enforces rather than the agent (The Agent Cancels the Order, below). The security is structural: while a verified-customer session is active, the database layer refuses every general query outright — the caller can only reach explicitly account-scoped lookups, and the tier is decided by deterministic code before any language model runs.
A real-time mode takes the same line further: audio streams both ways over the carrier's WebSocket, speech is recognized as the caller finishes a sentence, replies are synthesized in a natural voice, and the caller can interrupt the agent mid-sentence and be heard. Same brain, same tiers, same audit trail — and now the same four languages, the same keypad menu and the same live handover to a person, so choosing the faster call flow no longer costs a caller anything.
The line waits for a finished thought, not merely for silence. Ordinary speech has pauses in it — "tell me… the refund policy" — and a pause is not the end of a question. If the rest of a sentence arrives while an answer is already being composed, the half-formed reply is abandoned and the two halves are rejoined, so the caller is answered once, on what they actually asked, rather than twice on fragments of it.
It also knows its own voice when it hears it. On a speakerphone the handset plays the agent's reply back into its own microphone, and the line receives it as though the caller had spoken — so the agent interrupts itself, transcribes itself, and then tries to answer itself. The fix is not to ignore quiet audio, which would leave a softly-spoken caller unable to interrupt at all. It is that the agent knows exactly what it just sent, so a quarter second of incoming sound can be compared against the audio still playing. Something that matches is the agent's own voice returning and is discarded, at any volume; something that does not is the caller, and interrupting is exactly what they should be able to do.
The line also senses how a call felt, not just what was said: a caller who repeatedly talks over the agent or speaks fast and long reads as urgent, and that urgency lands on the customer's profile as a signal every other agent — the 360 summary, the standing supervisor — sees automatically. No audio ever leaves the call; the measures are behavioral, deterministic, and tunable.
And the line answers in the caller's own language — English, French, Mandarin Chinese, or Spanish. The caller chooses from a menu where each option is spoken by a native voice, because an option offered in a voice you cannot understand is not an option at all. Choosing switches both halves together: the speech recognizer and the synthesized voice. That pairing is not a detail — recognizing Mandarin with an English recognizer returns nonsense the agent would then answer confidently, so the system refuses to switch one without the other.
Language is declared, not guessed, and the reason is worth stating plainly: a phone line must commit to one recognizer before the caller speaks, so detecting the language from the transcript is circular — the words come back already filtered through the wrong language. Text channels can detect silently because the customer's own characters arrive intact. Voice cannot, so it asks. Once chosen, the choice holds for the whole call; an unclear "okay" never flips the accent mid-sentence. The keypad is what makes that work at all: a tone carries no accent, so it is understood even while the recognizer is still committed to the wrong language — which is precisely the moment a caller needs to be understood.
There is one exception, and it is the honest one. If the assistant answers in a language the caller did not declare — someone asks in English whether it speaks Mandarin, and it replies in Mandarin — the voice follows the words being spoken, not the question that prompted them. An English engine reading Chinese characters is the same broken half-switch in a different disguise, and it is not fixed by asking the caller again.
Nothing here is a translation layer. The knowledge base is written once, in English, and a Mandarin question reaches the English article that answers it because retrieval compares meaning, not words. Approve an article once and it serves all four languages the same minute.
Answering in a language is the easy half. The hard half is understanding what the caller says back, and that is where a multilingual line usually quietly stops being multilingual. A Mandarin caller asked for their street number says 一. A Mandarin caller giving their surname says 张. Both are exactly right, and both used to be worth nothing: the number reader knew only English words, and the name comparison stripped every non-Latin character before it compared anything — so a Chinese surname became an empty string and could never match the record it belonged to. The caller was told their details did not match, four times, while saying the correct thing each time.
So the line now reads numbers as they are actually spoken — 一 and 一百零二 and uno and quatorze — and knows that 张 is the surname stored as Zhang, Chang or Cheung, the spellings a Canadian record actually holds. A customer has now cancelled a real order start to finish in Mandarin, giving their surname in Chinese characters, and received the confirmation email. A line that cannot understand a number or a name in the language it just offered was only ever pretending to speak it.
When a human takes the call over from the console, the AI stands down — it stops answering, plays a hold message in the caller's language, and keeps the line open for the person joining. The customer is never talking to two agents at once.
And when a caller simply asks for a person, they get one. Inside business hours the call is transferred to a real phone and rings until it is answered; the person picking up hears who is calling before the lines join, so a transfer never arrives as an unexplained call. Outside those hours — or if nobody answers — the promise does not evaporate into a sentence. It becomes a callback obligation with an owner, recorded against the customer, because a line that offers a human and then quietly hangs up is worse than one that never offered.
Every call is a conversation with the whole CRM, in the caller's own language, on exactly the terms each caller has earned.
Speech is the expensive part of a phone call. Not the AI — measured on real traffic, the language model is about one percent of what a call costs, while recognizing the caller and speaking back is roughly sixty. That makes the speech vendor a commercial decision, and for a long time it was written into the code in four places, so changing it meant changing software.
It is now a line of configuration. Recognition and synthesis each walk an ordered list of providers, per language, and fall through to the next one when a provider fails or is not configured. That per-language part is not a refinement: a vendor that transcribes English and French beautifully can be useless in Mandarin, and the honest answer is often to use different engines for different languages rather than accept the worst of one across all four.
Because the vendors sit behind one seam, a second recognizer can listen to every call alongside the one actually serving it, and the pair of transcripts is kept. That is how a change like this gets decided on evidence instead of vendor claims — and it has already earned its keep twice: once proving a caller had been understood perfectly when the system said otherwise, and once producing the correct reading of a name the serving engine had mangled.
The intelligence is ours; the microphone is a supplier. Nothing above the seam — the tier ladder, the verification, the knowledge base, the governed writes, the audit trail — knows or cares which company heard the words.
A customer calls to cancel an order, and it is cancelled while they are still on the line. Not a ticket, not a callback, not someone will be in touch: the order number, three questions, a code to the phone on file, and it is done — with a confirmation email in their inbox before they hang up.
The interesting part is everything the agent is not permitted to do.
An order that has already shipped cannot be cancelled — and that rule does not
live in the agent's instructions, where a persuasive caller or a confused model
could reach it. It lives in the WHERE clause of the update itself. The
database is asked to change the order only if it is still pending, processing
or ready; if it is not, nothing changes. That distinction matters more than it
sounds. A rule written into a prompt is a request. A rule written into the
statement is a guarantee, and it holds against a prompt injection, a model slip,
and — the case nobody plans for — an order that ships in the seconds between
looking it up and cancelling it.
The agent is also not allowed to claim it happened. Success is not "the function returned" or "no error was raised"; it is the database reporting that exactly one row changed. When that count is zero, the caller is told plainly that it could not be completed and a colleague will call them back. An assistant that says "cancelled" while the record disagrees is worse than one that cannot cancel at all.
The confirmation email follows the same rule. It is composed only after the cancellation has committed, sent only to the verified address on the order — never to one offered during the call — and the agent may only repeat what the mail system actually recorded. There is no "sent" and no "delivered" in that vocabulary, because without delivery receipts neither can be known. If the mail fails, the order stays cancelled, the customer is told the confirmation did not go out, and a person picks it up. The cancellation is the customer's outcome; the email is an artefact of it, and one must never be rolled back for the other.
Identity is checked before anything is read back. The caller answers for the name, the address and the phone on the record, and the code goes to the number on file — not to the number they are calling from, so a borrowed or spoofed handset gains nothing. And whichever question fails, the caller hears the same sentence. That uniformity is not politeness: order numbers run in sequence, so an assistant that responds differently to "that order doesn't exist" than to "that name doesn't match" has become a tool for discovering which orders exist. One sentence for every failure, and the real reason recorded where the colleague picking it up can see it.
What speech recognition taught us here is worth saying out loud, because it changed the design. Exact matching against transcribed speech refuses honest customers as a matter of course: Alan comes back as Allen, a dictated email address collapses into nonsense, and a postcode arrives as two separate answers because people pause in the middle of saying one. So the questions became the ones a recogniser gets right — a single word and short runs of digits — and the matching became phonetic and tolerant. That is a real loosening, and it is affordable for one reason: those answers authorise nothing. The gate is the code sent to the phone. Their job is only to make sure a stranger cannot make someone else's phone ring.
Every cancellation leaves a trail that can be read without the application: what changed, from which state, how the caller was verified, when the provider accepted the email, and which colleague was told. The record of how identity was established is written into every one of those rows — so a cancellation made under a weaker regime can never later be mistaken for one where somebody proved who they were.
And a successful cancellation deliberately emails nobody internally. It has an audit trail, a customer confirmation and an entry in the console; asking a colleague to read about it adds nothing. What does reach a person is the exception — a cancellation that could not complete, a confirmation that never sent, an order in a state the agent refused to guess about. An alerting channel that carries things needing no action stops being read, and then it carries nothing.
The whole conversation runs in the caller's own language, end to end.
The model chooses the words. The database chooses the outcome.
The order confirmation now carries an Order Status button, and it opens the same order the email describes — number, items, total, shipping address, where it has got to — without a password, an account, or a sign-up. Most people who buy something never create an account, and a self-service page that begins by asking them to make one is not self-service.
The link is signed, so it cannot be edited into somebody else's order. Change a character and it stops resolving; the response is the same for a tampered link, an order that does not exist, and one that was deleted. Order numbers run in sequence, and a page that answers "no such order" differently from "not your order" has become a way to find out which orders exist.
But holding the link is not permission to change anything, and that is the distinction the whole design rests on. Confirmation emails get forwarded. Purchasing mailboxes are shared. So the link opens a page that can only be read, and cancelling requires a code sent to the address on the order — never to one the request supplies. Someone who has the link but not the mailbox can ask for codes all afternoon; every one of them lands with the customer, where it is evidence rather than access.
What happens next is not a second implementation of anything. Whether an order
may still be cancelled is decided by the same WHERE clause the phone line uses,
in the same function — pending, processing or ready, checked by the database
under a row lock at the moment of writing, not by the page and not by the agent.
The website and the phone cannot give a customer two different answers about the
same order, because there is only one answer and neither of them owns it. Ship
the order between loading the page and confirming the code, and the cancellation
simply does not happen; the customer is told so, and nothing is left half-done.
An order that has shipped is not met with a refusal and nothing else. It is met with the return policy — and that text is not written into the page. It is read from the same published article the phone assistant reads aloud, so editing it once moves the website, the phone line, the chat and the order page together. A policy that exists in two places is a policy that will eventually contradict itself in front of a customer who is trying to get their money back.
Before the code is sent, the customer is asked why. Not as a formality — the answer is written into the audit record alongside the cancellation, so the question "why are people cancelling?" is answerable from the data rather than from anecdote. The options come from the server, never from the page, and the browser sends back a key rather than a sentence; otherwise the answers arrive as a hundred near-identical strings that no report can add up. I'd rather not say is one of the choices, because a required field with no way out would stop someone cancelling their own order over a market-research question.
There is a chat box on the page, and it is worth saying exactly what it can do. It reads the order, it answers questions from approved knowledge, and when someone types "I've changed my mind" it does not cancel anything — it walks them to the same code-verification gate the button uses. A second path to a write is a second gate, and the weaker of the two would be the one that decides.
The reason a cancellation was made, how the customer proved who they were, and which channel they came through are recorded on every one of them. A cancellation confirmed by a code in an inbox must never be readable, later, as one somebody made over the phone.
Two front doors. One lock, and the database still holds the key.
A customer who explains a problem on the phone should not start over in the next email. When any conversation ends — a support call, an SDR chat, an SMS exchange, an email auto-reply — Conscestra distills it into one compact memory: what they wanted, whether it was resolved, what was promised, and the sentiment. Every promise the agent makes becomes an open task a human can see and fulfil, not a line buried in a transcript.
The next time that customer is identified on any channel, the same memory comes back: the verified caller is greeted with "last time you contacted us about order 1042 — we still owe you a follow-up", the email reply acknowledges the phone call, and every agent working the account starts already knowing what was last said. Recall follows the trust model — identity before memory, so an unverified visitor can never claim someone else's history.
Start the conversation anywhere. Continue it everywhere.
The channel is temporary; the relationship is permanent. Conscestra treats Voice, SMS, Email, WhatsApp, Slack, and Teams not as separate integrations but as instruments of one Unified Communication Layer — a common message envelope every channel adapter speaks, resolved to one person and threaded into one conversation.
Identity resolution maps any handle — a phone number, an email address, a Slack or Teams user id — to a single CRM party. A WhatsApp message and a later email from the same person are recognized as the same relationship, so the thread they share moves across channels. External conversations (customer ↔ business) and internal ones (employee ↔ business intelligence) sit on opposite sides of a boundary the Orchestrator polices — a customer never sees the internal escalation their message set off.
The layer is intelligent about how to respond, not merely where. Given an objective and a person, it chooses the best action: an urgent issue becomes a call, a formal proposal an email, a quick update a WhatsApp message, an internal alert a Slack post — weighing intent, relationship, urgency, the person's learned channel preference, and whether the matter is sensitive enough to demand a verified channel.
Capture is complete across the fleet: support calls thread into the conversation as one transcript, SDR voice calls and web chats thread turn by turn, and a caller's follow-up text lands in the same conversation as this morning's call. The per-session working memory is durable too — a server restart no longer costs an agent its place in the dialogue.
Anonymity is temporary as well: a website visitor who chats first and shares their email three messages in doesn't leave an orphaned thread behind — the moment identity appears, the anonymous conversation folds into their identified one, history intact, so the relationship record begins at "hello", not at the email address.
Start on WhatsApp at 9am, continue by phone at 10, receive a proposal by email that afternoon — one person, one conversation, one memory.
The unified layer runs inbound too, and the internal side turns Slack and
Teams into a seat at the CRM. An employee messages the bot — a direct question
in a DM, an @mention in a channel — and the Orchestrator answers from every
module: "what happened with Acme this week?", "company pulse." The reply
threads into the same governed conversation as every other channel.
Because that surface reaches the whole business, it is fail-closed by construction. Every request's signature is verified, and only a Slack or Teams id explicitly linked to an employee is answered at all — an unknown sender gets a refusal and never a row of CRM data, the same allowed-caller posture the phone line uses. In a shared channel the answer is audience-scoped: a direct message is already private, a channel you designate may post in the open, but anywhere else the reply is delivered ephemerally to the person who asked — so pipeline and financials are never broadcast to a room that may include people not entitled to them, and delivery fails closed rather than ever falling back to a public post. The bot is a well-behaved participant, answering only when addressed, and every message is rate-limited before it can spend a token.
Approvals live there as well. A governed action routed to an executive can arrive in Slack as native in-thread Approve / Reject buttons — carrying the same HMAC-signed, single-use decision the email does — and one tap drives it through the identical governance flow, updating the message in place. Agents also post on their own initiative: a morning briefing or a KPI-breach alert lands in the team channel, draft-first until you switch it on. On Teams, a one-to-one chat gets a real Bot Framework reply, while channel messages stay private under the very same rule.
The place your team already works becomes the place they command the CRM — on exactly the terms each person has earned.
Keyword routing is fast but literal — "what is my account balance?" contains the word "account", yet the answer lives with Accounting. The Orchestrator now classifies each request's intent with a small language model over a catalog of what every agent owns, and trusts the answer only when it names a real agent with real confidence. The keyword router remains underneath as the always-on fallback: if the model is down, hedging, or hallucinating, routing degrades to exactly the old behavior rather than breaking. Disagreements between the two are logged — the delta is the tuning signal.
Meaning first, keywords as the safety net — and every route annotated with how it was decided.
The Orchestrator is a conductor, not just a switchboard. A single lookup goes to one specialist; a multi-step goal — "recover our overdue receivables and re-engage the slipped deals this week" — is decomposed into a coordinated plan across several agents, its read steps executed immediately and its every write queued for human approval. The same planner works unprompted: when the standing supervisor detects a KPI breach, it hands the situation to the planner as a goal and lets it compose a governed response play — sense, decide, plan, propose, with a human on every outbound action.
Ask for a quote and the platform builds one the way a careful salesperson would: products matched exactly against the catalog (an ambiguous name is reported, never guessed), priced from the current retail pricing rows, totals computed deterministically — the language model writes only the greeting, never a number. The quotation states its validity window, rides the same outbound gates as every send (delivered only to a verified address under autosend; drafted as an owner task otherwise), carries the CASL footer, and lands in the activity log as the audit copy.
And then it stays. A quotation used to be composed, sent, and forgotten — a commercial commitment that existed only as the text of an email. Nobody could answer what did we offer this customer, and is it still good? Quotes are now durable records with their own lifecycle, and the prices are snapshotted at the moment of the offer: when the catalogue changes next week, the quote still says what was actually promised. A quote that re-prices itself is not a quote.
Validity is enforced rather than merely printed. A nightly pass expires quotations whose window has closed, so "still open" means it. Discounts record what was requested, what policy allowed, and what was granted — and a request past the cap becomes a governed approval rather than a silent clamp, because a customer who asked for 30% and quietly received 15% has been answered without being told. Offered-versus-ordered comparison closes the loop between what was promised and what was bought.
Once agents create work, someone must notice when work silently piles up. A weekly process-health scan checks five places where momentum dies: new leads nobody has touched, open deals nothing has happened to, overdue invoices no one has chased, open tasks long past due (by owner), and inbound messages that never got a reply. Findings are consolidated into one upserted notification — a heartbeat, not a pile — with the worst examples named.
The first real scan found two live code bugs and several hundred stranded tasks. The detector paid for itself on day one.
Beyond reacting to events, Conscestra's supervisor is goal-oriented. Leadership declares business objectives — cut overdue invoices in half in 90 days, lift lead conversion 20%, keep high-churn exposure below five accounts — and the agent fleet pursues them.
Each objective is projected along its path from baseline to target. Every supervisor cycle measures the live metric, judges the trajectory — achieved, on track, at risk, or off track — and records the daily history. Falling behind raises an alert with the numbers attached; an off-track objective can trigger its owning agent's recovery play, always through governance.
Thresholds watch symptoms. Objectives pursue outcomes.
AI should never act without accountability.
Every commercial action follows intelligent governance policies. Approval requests are automatically routed to the appropriate executive based on business function, approval authority, and financial limits. Executives can approve or reject requests from any device with secure one-click actions — no login required.
And no proposal arrives alone. Before an executive decides, an independent critic agent cross-checks every queued action against live business state: Does the campaign segment actually reach anyone? Do target customers have open complaints or overdue balances? Is this a duplicate request? The verdict — endorse, caution, or object — travels with the approval into the queue, the decision email, and the morning briefing. The critic never decides; it makes sure the human deciding sees what the proposer might have missed.
When the critic objects to a drafted artifact, the conversation doesn't end there. The drafting agent gets the findings back for one bounded revision, the critic re-reviews, and the human sees the final state with the revision honestly annotated — including when the fix didn't work. Proposer, critic, reviser, human: a real multi-agent deliberation with a hard iteration cap instead of an endless debate.
Where appropriate, actions can be reversed within configurable time windows, approval requests automatically expire, confidence thresholds determine when human review is required, and continuous health monitoring ensures every automation remains transparent and reliable.
Even the supervisors are supervised.
A consequential operation in Conscestra passes through five distinct stages, and each is granted separately. Code being present does not mean an action is permitted, and permission does not mean it has happened.
The stages are visible in the platform's own current state. The classification capability described above is registered and enabled in production, and at the time of writing no decision policy governs it, no approval exists, and no classification record has been written. That is the architecture behaving as intended rather than an incomplete release: a capability that is present and ungoverned is a capability that cannot act.
Absent governance is a refusal, not a default. When an operation of this class has no decision policy, the platform does not fall back to permissive behaviour. The resolved policy requires a human decision, records that no policy was declared, and reports that the action may not run automatically. The reason accompanies the refusal, so an operator sees why an action is waiting rather than discovering only that nothing happened.
Accountability is carried by an assignable identity — a durable record of the party answerable for an action. The identity model is independent of any particular organizational structure: it does not assume a specific set of executive titles, and it does not require that an accountable party be an employee. Where the governance model calls for human approval, approval authorities are the humans holding those roles in a given organization, and the roles themselves are configuration rather than architecture.
An accountable identity is always supplied to a governed operation by its caller. The platform does not select one on a caller's behalf, because an operation that chooses who will be answerable for it has not established accountability at all.
Consequential work separates concerns that are often collapsed into a single account:
Because these are distinct, the record of who was answerable for an action does not depend on which process performed it, and verification does not depend on the goodwill of the component being verified.
Autonomy is only as trustworthy as its boundaries, so Conscestra builds four distinct guardrail layers around every agent action:
The input side was already walled: natural-language write attempts are caught at the database choke point, personal data is masked before any model prompt, and unverified callers can never reach account-scoped answers.
All of this is visible and adjustable without touching code. The governance console shows every guardrail policy with its live value against the deployed default — thresholds move with a click and take effect immediately, no restart. Every agent capability appears with an enable/disable switch: turn one off and every dispatch of it refuses with a clean, explained, traced error until it is turned back on.
And nothing the fleet does is opaque. Every multi-agent play shares one correlation id, and one click reconstructs its full timeline — every agent-to-agent call with its latency, every bus event, every approval it queued, including the refusals. When an approved action finally executes, it lands in the same trace as the proposal that spawned it.
Leadership scales autonomy with a slider, not a leap of faith.
Conscestra continuously measures its own performance.
Predictions are compared against actual business outcomes. Churn forecasts, sales probabilities, marketing campaigns, and automated workflows are evaluated against real-world results, allowing the platform to recommend evidence-based improvements rather than relying on assumptions.
Each morning, executives receive a concise AI Performance Briefing highlighting conversion rates, customer retention, campaign effectiveness, prediction accuracy, and the measurable business impact delivered by every AI Agent.
When the evidence is strong enough, the platform goes one step further: it proposes its own tuning. If a month of real outcomes shows the churn model raising too many false alarms, Conscestra drafts a bounded threshold adjustment — evidence attached, reviewed by the critic, routed to the right executive — and applies it only when a human approves. Every change is reversible, rate-limited by a cooldown, and confined within hard safety bounds the system can never propose beyond.
Self-improvement without self-mutation: the system proposes, people ratify. Nothing changes without oversight.
And the AI accounts for its own costs. Every model call in the platform is metered — which agent, how many tokens, what it cost, how long it took — with optional per-agent daily budgets that degrade gracefully to the deterministic fallbacks rather than ever breaking a flow, and a cheaper model tier for high-volume wording. The morning briefing reports what the automation earned and what it burned.
An agent that can only explain things is a search box with better manners. Conscestra's no-code Studio lets a business user describe an agent in plain language — who it serves, what it knows, how it should sound — and that agent can then do the work, not just narrate it: log an activity, create a task, open a case, update a contact's own details.
What makes that safe is that the agent never gets a power; it gets a grant. Every action lives in a capability catalogue, and an authored agent holds an explicit, revocable grant to each one. Three independent checks decide any call, and any single one of them refuses: is this capability granted to this agent, is the caller allowed to trigger it, and does the data involved permit it. Nothing is implied by the fact that a capability exists — appearing in a catalogue is not permission.
The reason this matters is that anything an agent can do, a customer talking to that agent can attempt to make it do. So authored agents get the narrow, low-blast-radius actions by default, and anything that moves money, history, or another person's record does not execute — it becomes a governed proposal in the same approval queue as every other consequential action, with the same critic, the same audit trail, the same human.
The agent proposes in the customer's words. The platform decides in yours.
The moment a business user can create a customer-facing agent without an engineer, editing that agent becomes a deployment — and deployments need the discipline deployments get.
Every edit in the Studio is a draft version. Publishing runs a gate first: does the agent have a real instruction set, is its knowledge audience consistent with who can reach it, does it pass its evaluation scenarios. Only a version that clears the gate can go live, and the previously live version is kept intact, so rollback is a single action rather than a frantic attempt to remember what the prompt used to say.
One rule cannot be waived by anyone, and it is the one that caught a real bug here. An agent reachable by the public may read only the public knowledge tier. It is enforced when the draft is written, when it is evaluated, and again when it is published — not once, three times — because this exact misconfiguration once let an externally reachable agent answer from internal documentation. A gate you can talk your way past is a suggestion.
An urgent fix can still override the gate, but never invisibly: an override demands a written reason, and the version history shows the override, the reason, and the checks that were failing when it was forced — for as long as that version exists. Publishing under pressure is allowed. Publishing without a record is not.
Anyone can build an agent. No one can quietly ship a broken one.
Two standing agents keep the platform honest about its own weaknesses.
Every night, a behavior evaluation harness runs golden scenarios through the real customer-facing AI — does the SDR still qualify properly, does a prompt-injection attempt leak anything, does the auto-reply still answer from approved knowledge, does the planner stay inside its rails? Any drift — from a model update, a prompt change, a data regression — raises an alert before a customer ever sees it.
And a data-quality agent patrols the foundation everything else stands on: duplicate contacts, malformed phone numbers, unreachable records, ownerless accounts. The safe fixes arrive as governed, fully reversible proposals — every change records its before-state — while anything that moves money or history stays a human decision. Garbage in, governed out.
A control that has never been tested against the thing it is meant to stop is a belief, not a control. Conscestra proves its safeguards the way it proves its features: by planting the exact defect each one claims to detect and confirming it turns red.
A forged verification. An invalid signature. A disabled audit trigger. A memory whose supporting evidence no longer exists. An erased trail. Each is created deliberately, the safeguard is checked, and the system is restored. A safeguard that stays quiet under its own defect is reported for repair — it is never recorded as a pass.
The same discipline applies to measurement. Where a metric depends on sampling, the sample is deterministic, so a number that moves has moved for a reason and can be trended with confidence. And before any result counts, the test harness proves that the change it made is the change actually running — an instrument is only useful once you know it is measuring what you think it is.
A refusal only counts as evidence when you know which rule refused. Checking that the database rejected something proves less than it appears to: a table carries many rules, and any of them turning it away produces the same visible outcome. A safeguard was found that had passed its own test for the wrong reason — the test supplied a case that a different branch happened to catch, while the branch under examination stayed open for exactly the input it was written to stop. An audit of the suite found eighteen such checks, seventeen of which asserted only that something had gone wrong, not what.
Every one of them now names the rule it expects to fire, and each conversion was verified by naming the wrong rule and confirming the test then fails. A new check that does not name its reason is refused by the build. The handful that predate the rule are listed individually rather than waived as a group, so the backlog is visible and can only shrink.
Continuous integration establishes what a build server is well suited to establish: that every module imports cleanly, and that the memory derivation pipeline still produces identical results against a frozen corpus, so any change in clustering, attribution or trust scoring is caught before it ships.
The database-layer guarantees are then proven where the schema and the secrets actually exist. A single command runs against a deployed environment and gates on the result: the guarded secrets are confirmed strong and distinct, the database invariants are asserted directly in SQL, and a red team executes live attacks — forging an assertable claim, replaying a signature, approving its own work twice, attempting to erase the audit trail or disable a control — to confirm each one is refused.
It reports what the system actually did. An attack that could not be exercised is reported as such rather than counted as blocked, so a passing result means every control was genuinely engaged and genuinely held.
Every module in Conscestra reports on the business. None of them answered a different question: is the machinery under all of it actually working?
A platform health view answers it in three parts. Platform — is the event backbone draining or backing up, are events stranded with no handler to claim them, is any work retrying without ever succeeding, is there a second model provider standing by. Obligations — how many escalations are open, and how many have blown their deadline. Governance — how long approvals have been sitting, and whether any agent version was published by overriding its gate.
Two of those deserve emphasis because they are the failures that hide. A stranded event is worse than a failed one: nothing errored, nothing alerted, the work simply had no owner and sat silently — which is exactly what happened here when a restart's cutoff logic orphaned everything emitted while the platform was down. And a retry that never succeeds looks healthy from every angle except the one that counts.
The view is also honest about its own failure. "Not signed in as an administrator," "the server is unreachable," and "the query failed" are three different situations with three different responses, and a dashboard that collapses them into Failed to load has told you nothing. Each one says which it is.
A platform that can act on its own must be able to tell you when it can't.
Changing a setting and confirming a setting are not the same act, and the gap between them is where a system quietly does something other than what it was told.
Two live examples, both found and both closed. Asking the platform to run more than one worker process had no effect at all while a development flag was left on — the web server silently ignores the request in that mode, logs one line about it at startup, and carries on single-process. Nothing else in the application read that flag, so there was no way to tell from outside. And after switching retrieval to its hybrid mode, the only available check was comparing result counts against a different environment holding a different corpus — which is suggestive, and is not proof.
The platform now reports its own running configuration: which build is actually serving, how many workers are genuinely running as opposed to requested, which retrieval mode is in effect as opposed to configured, and whether the process is the one carrying the scheduled work. Each is read from the live process rather than inferred from its behaviour.
The distinction between requested and effective is deliberate and appears wherever the two can diverge. A deployment that asked for a capability it did not get should look different from one that got it — otherwise a silently degraded system reports success, which is the most expensive kind of green.
A queue is disposable work — process it, discard it. Progress is durable memory — it has to outlive the work it describes. Conscestra keeps the two apart.
The event consumer records how far it has got in its own durable store, independent of the queue it reads from. Housekeeping can sweep the queue as aggressively as it likes; a deploy can restart the platform mid-stream; the work can be archived entirely. The consumer still resumes at exactly the right point, and events that arrived while it was away are picked up rather than skipped.
The guarantee is proven the way every safeguard here is proven — by removing the thing it depends on. Delete every row of the queue, and the consumer still knows precisely where it was.
Restart-safe by construction, not by good timing.
Before anything irreversible runs, you see what it will do — including the records that follow the ones you named.
Business records travel in company. Retiring an event touches its queue entry, its notifications, the recipients of those notifications, its automation runs and every step within them. Conscestra's expiry preview walks that entire chain of consequence, to whatever depth it reaches, and reports three outcomes separately — because they carry three different risks. Some records are deleted. Some survive but are altered. Some would refuse the operation outright.
It is equally precise about its own limits, stating plainly that the per-run safety cap applies to the records you selected, not to the ones that follow them.
Know the full blast radius before you approve it, not after.
Performance work here starts with a number and ends with a number. Semantic search — the path behind agent recall, the knowledge base and the store assistant — was profiled under realistic concurrency rather than in a loop on an idle machine, and rewritten on what the profile showed.
Ranking candidate vectors was decoding them one at a time in Python. Replacing that with a single vectorised decode over one contiguous buffer took a search from 101 ms to 5 ms single-threaded, and — because the old path held Python's interpreter lock the whole way — from 9.2 to 573 searches per second across sixteen concurrent threads. Same inputs, byte-identical results, one change. Query embeddings are cached, so a repeated question costs a dictionary lookup instead of a model call.
Connections are pooled and bounded. When every slot is busy a request waits and then fails clearly, rather than opening an unbounded number of connections until the database refuses everyone — the failure mode where a slow minute turns into an outage. Every borrowed connection is validated before use, so a connection the server closed during a restart is replaced rather than handed to a caller.
The scalability plan reaches to a hundred million records and labels every line as measured, extrapolated, or estimated. Approximate-nearest-neighbour indexing was evaluated against the workload rather than adopted because it is fashionable, and the honest conclusion — at the current data volume the exact search is already faster than the index would be, and the threshold where that reverses is written down — is recorded with the numbers behind it.
Asking the memory a question used to mean searching the most recent slice of it. That is a reasonable default and a quiet ceiling: on a corpus of roughly thirteen thousand records the search ranked 4,000 of them — under a third — and said so in its own logs, because a system that can only see the recent past should admit it rather than present a partial answer as a complete one.
Retrieval now draws from two pools at once: the recency pool as before, and a semantic pool selected by vector similarity, unioned and then re-ranked exactly. A question phrased in the customer's words finds the record written in yours, whether it was filed yesterday or last quarter.
The gain was measured, not assumed. Across a fixed set of questions the same searches returned 44 results before and 104 after — 81 genuinely new — with zero true content loss. That last number is the one that mattered enough to define precisely: a result that drops out of the top ten because better matches arrived is displaced, and still reachable; a result the system can no longer return at any depth is lost. Seventeen were displaced. None were lost.
It is a setting, not a rewrite. Hybrid retrieval is opt-in, reversible by changing one value, and degrades honestly — if the semantic index is missing or incomplete the search falls back to recency rather than returning half an answer. The platform reports which of the two is actually running, not merely which was requested, because those are different questions and only one of them is the truth.
The tuning carries its own expiry. The size of the semantic pool was tuned against one corpus at one moment, and that fact is recorded alongside the number. The platform separately reports whether the corpus has since moved away from the state the tuning was validated against — and it reports the standing limitation too, rather than quietly rounding it off: one heavily-repeated template can very nearly fill the semantic pool on its own, and what covers that is the recency pool beside it. A caveat that is only true in a comment is a caveat nobody reads.
Powerful AI demands responsible governance.
Every automated action operates within transparent business policies. Communications respect customer consent, verified recipients, suppression lists, and unsubscribe preferences. Financial decisions follow approval hierarchies. Every action is logged, attributable, reviewable, and fully auditable.
AI Agents prepare. People remain in control.
Because autonomous systems create value only when they earn trust.
Data security represents the highest priority within Conscestra's architecture. Every layer of the platform — identity, authorization, transport, and session governance — is protected using a defense-in-depth model.
Every create, update, and delete operation requires authenticated authorization and is validated twice: once at the API boundary and again at the database layer. Even natural-language AI requests issued by anonymous visitors are prevented from executing privileged actions before any database operation occurs. Whether the command is "Generate invoice," "Record payment," or "Void invoice," the request is blocked unless authorization exists.
That second check matters more than it sounds. An agent resolves intent inside
the database — log_call becomes an insert, add_note becomes an insert —
so a gate that reads only the words in the request sees a harmless question.
Conscestra classifies the resolved operation instead, at the one choke
point every statement passes through, and a coverage test re-derives that
classification from the stored procedures themselves so the rule cannot drift
away from what the SQL actually does.
Public surfaces get a stronger guarantee still, because a list of forbidden verbs is only as good as the last person to update it. A channel declared read-only — inbound SMS today — runs every statement inside a database-enforced read-only transaction. The write is refused by PostgreSQL regardless of what the agent named it: authorization that does not depend on anyone remembering to classify tomorrow's verb.
The platform supports multiple security postures ranging from open demonstration environments to fully locked production deployments. Administrative email access always requires elevated authorization regardless of system posture.
A posture is chosen with one switch, and this is not a stylistic preference. Two independent flags mean four combinations, two of which are somebody's mistake, and the failure is silent: an operator sets the flag they remember, the other one decides, and the deployment is not what anyone believes it is. One switch cannot be half-set — and when a legacy flag is found beside it, startup names which setting won and which is inert rather than resolving the conflict quietly.
The posture is then checked before the application serves anything. A control that only engages when somebody remembers to set an environment variable is not a control; a deployed environment that is missing one refuses to start rather than serving unsecured data, because a failed deploy is recoverable in minutes and a public feed of customer names is not. Deliberate exceptions remain possible — an operator who genuinely wants a public feed can say so explicitly, which turns an accident into a decision. Local development is untouched: safety bought with developer friction gets switched off.
That guard is also held to its own standard. An early version of it read the configuration from the environment instead of from what the application had actually resolved, and so reported the wrong posture in both directions — including calling an application with no authentication at all clean. It now reports what the running process is genuinely using, and the two failure directions are regression-tested against the old implementation. A guard that misreports is worse than no guard, because it manufactures confidence.
Additional protections include:
Sessions store only cryptographic token hashes, expire automatically after inactivity, and remain constrained by absolute session lifetimes.
Privacy gets the same treatment. Before any customer-authored text reaches an external language model, Conscestra masks personal identifiers — email addresses, phone numbers, card-like digit sequences — while keeping what personalization genuinely needs. The model gets the meaning, never the identifiers. Operational sends remain governed by consent and autosend gates, so private data neither leaks into prompts nor out of them.
Security is not a feature layered onto the platform. Security is the architecture.
The live demonstration is deliberately open: anyone may read, without signing up, because a CRM you cannot look at explains nothing. That posture is a decision, and decisions need edges.
The absent case is no longer the dangerous one. An unset configuration used to select the posture that enforces nothing — where anonymous callers may create, update and delete, because all three write controls key off a role that posture never assigns. A typo in the variable name chose it silently. That posture now blocks release unless someone explicitly and separately affirms it, so the failure mode of forgetting is closed rather than wide open.
Open to read is not open to take. Anonymous reading is now rate-limited per caller, enforced at the single gate every data endpoint already passes through — rather than endpoint by endpoint, where a newly added route would be unprotected by default. A demonstration is a demonstration; it is not a bulk export channel. Signed-in callers are exempt, because being identified is what the limit stands in for.
Writes were, and remain, closed. Reading is anonymous; creating, updating and deleting require a signed-in account with a role that permits it, refused at the gate before anything executes. Administrative surfaces are refused outright.
And a credential stopped shipping in the source. A configuration default carried a working database password. It was reachable only from the same machine, but "nobody can reach it" is a property of a network, not of a published repository. Worse, it made a missing configuration look like a working one — the one case it applied in was the case where nothing had been configured at all. It is now empty, and an unconfigured system refuses to connect rather than guessing.
Every database-layer guarantee in Conscestra — the assertion gate that stops an unverified claim reaching a customer, the append-only verification trail, the undo log behind every governed deletion — is enforced by a trigger inside PostgreSQL. That is the right place for a control: it applies to every path, including the ones nobody remembered to check.
Controls in the database are only as strong as the account that reaches them, so the application connects as a role that owns nothing. It reads and writes business data and calls stored procedures exactly as it always has, while the rules it operates under sit outside its reach. Schema changes are administration, so they use a separate administrative account and look like what they are.
The safety controls are now materially more durable, more resilient, and more resistant to tampering than ever — and the application itself cannot alter or disable them. The application's own health endpoint reports which role it connected as, so the separation is something you can verify rather than something you were told.
Consent is usually built for whichever channel a product launched with, and then quietly fails to follow it anywhere else. Ours began as an email suppression list — one table keyed on an address — and when the phone line, SMS and WhatsApp arrived, they inherited nothing. An unsubscribe by email left the same person textable, and there was no way to unsubscribe from SMS at all, because nothing existed that could record it.
Consent is now a property of a channel and a person, not of an address. Every outbound path asks the same question through the same predicate, at the chokepoint above the carrier, so email, SMS, voice and WhatsApp cannot drift apart and neither can two telephony providers. "Unknown" is the absence of a record rather than a stored value, because never contacted and asked and never answered are different facts and should not be forced to share a row.
The posture is deliberate and per channel. Email keeps the suppression-list model it has always had, where absence means mailable — the standard the existing consent was lawfully built on. SMS, voice and WhatsApp start strict: no record means no commercial message. Nothing accumulated on those channels before, so beginning strict costs nothing and is the safe side of a question CASL actually asks.
Inbound STOP is now read before the assistant sees it. It used to be
treated as an ordinary question: the knowledge-grounded responder answered it,
and the reply went out — another message to someone who had just asked for
none. ARRÊT is recognised for the same reason the assistants answer in
French, accented or not, and so are the Spanish and Chinese equivalents. A
whole-message keyword is an opt-out; "stop sending me invoices at 3am" is a
complaint a human should read, and is deliberately left alone.
The acknowledgement is treated as an obligation rather than as outreach, so it is sent even when automatic sending is switched off — a withdrawal that is recorded but never confirmed is not a withdrawal the customer can trust. Every transition is written to an append-only log the application cannot edit or delete, which is what turns "they opted out" from an assertion into evidence, and a consent record about a person is part of that person's data: it is returned in their access request like anything else.
A customer asks to be forgotten. The law requires the data to go, and the same law requires you to be able to demonstrate that you handled the request properly. Conscestra satisfies both by keeping the event and destroying the content.
Every erasure records who performed it, when, for which record, how many rows, and under what declared reason. The statements, the evidence and the personal detail are genuinely gone. The fact that an erasure occurred is retained permanently and cannot be removed by anyone — the register refuses deletion outright, so the compliance history stays complete and gap-free.
A permanent register of erasure requests would, left alone, become a permanent index of who asked to be forgotten. So identifiers age out: after two years an automatic monthly pass strips the personal link and keeps everything else. Nothing is ever removed from the register, and it stops being a list of people. Accountability and data minimisation, both honoured, on the same record.
A person is entitled to a copy of their data — GDPR Article 15, Article 20 for portability, and the equivalent right under Canada's PIPEDA. Conscestra answers that in one command, and the interesting part is not the export. It is how the export knows it is complete.
The manifest is checked against the live database, not trusted. Every table carrying a subject link — a contact, an account, a lead, an email address — must be declared as either included or excluded-with-a-reason. A table nobody has declared does not get quietly skipped: the export refuses to run and names it. Adding a table that holds personal data therefore breaks the export loudly today, instead of silently narrowing what a person receives for months. It has already stopped two exports within minutes of a new table appearing.
Other people's data stays out of it. Several contacts can share one company account, so account-level records are released only when the requester is the sole contact on that account. Otherwise those sections are withheld and the withholding is reported inside the export, with the reason — Article 15(4) protects the rights of others, and a copy that quietly included a colleague's details would breach it while looking generous.
Subjects can ask for themselves from the portal. That request records the arrival time and starts a visible thirty-day clock; identity comes from the signed-in session and never from the request, so nobody can open a request against someone else. Every export that is actually released is written to an append-only register the application cannot edit.
Most backup systems tell you a file was written. That is a hypothesis, not a recovery plan — the only proof a dump restores is restoring it.
So every night Conscestra dumps production, restores that dump into a throwaway database, and compares all two hundred tables row by row against the source. The elapsed restore time is reported as a measured number rather than an estimate, and re-measured on every run. If any table disagrees, the run fails and says which — a dump that exists but does not reproduce production is worse than no dump, because it looks like protection.
The verified copy is then mirrored to a second physical device, and the run reports the age of that mirror, because a mirror that stopped updating is the thing you need to hear about. Success is also announced to an external dead-man's-switch service: if a backup ever silently stops running — the machine is off, a container is down, the job was removed — the absence of that announcement is itself the alert. No status check can detect a job that never started; only a missing heartbeat can.
The restore path is rehearsed rather than documented. Restoring over a populated database costs roughly twice what restoring into an empty one does, and the privilege grants must be re-applied afterwards — both facts were established by running it, and both are written down as steps rather than warnings.
Incident response is written for the jurisdiction the business is actually in. PIPEDA applies to every breach and requires a record of all of them — kept for twenty-four months, including the ones judged not notifiable, because a decision not to notify is only defensible if the reasoning was written down at the time. The GDPR seventy-two-hour clock applies additionally, and only where a European individual is affected.
That register is enforced by the database: a breach record may be revised as more is learned, because that is how investigations actually go, but the dates every statutory deadline is measured from cannot be moved and the record cannot be deleted.
The procedure is exercised, not just written. In a timed exercise against production, every forensic question a regulator asks — how many individuals, how many reachable directly, what categories of data, what changed during the window — was answered in under a second, and the exercise found and fixed a real gap the same day. The exercise record expires after twelve months, so readiness that has gone stale reports itself.
A CRM whose phone line, storefront, and help desk all think through one vendor's API has quietly made that vendor's worst day its own. Conscestra can fail over to a second model provider mid-request — but the interesting part is everything it refuses to fail over.
Retrying blindly is not resilience; it is an amplifier. So failures are sorted first. A timeout, a rate limit, an overloaded upstream — those are transient, and worth a second provider. An invalid API key, a malformed request, a refusal on safety grounds, a budget stop — those are decisions or defects, and re-asking a different vendor either changes nothing or launders an answer the first one deliberately declined. Only the first class ever moves.
Two boundaries hold regardless of how urgent the request is. Failing over sends your data to a different company, so anything classified as internally sensitive stays on the primary path or falls back to the local model — it does not get shipped elsewhere because the first API was slow. And the budget is checked once, before any provider is tried, so a failover can never spend past a ceiling by taking the second route.
Telemetry records both layers: the logical request the business made and each provider attempt underneath it, so cost, latency, and reliability per vendor are answerable questions rather than an averaged blur. Failover ships off by default and every provider is health-checked by actually calling it — because a model being listed in a vendor's catalogue is not the same as that model responding, and we learned that the direct way.
Resilience is knowing which failures deserve a second chance.
Conscestra already serves the Model Context Protocol, so assistants like Claude can work with the CRM directly. It now consumes MCP as well: the platform's own agents can call tools that live on external MCP servers, extending what they can do without waiting on a release here.
That is an enormous door, so it opens onto the governance that already exists rather than beside it. An external tool is projected into the same capability catalogue as every native action and is granted the same way. Building a second permission model for third-party tools would have guaranteed the two drifted — and the weaker one is the one attackers use.
Three gates apply, each sufficient on its own to refuse. The server must be explicitly registered and enabled — an allowlist, never whatever discovery happens to return. The individual tool must be enabled, because a server listing a tool is not permission to call it. And calling a third party is egress, so the same data-class rule from failover applies: internally sensitive data does not leave without an explicit opt-in.
External tools default to requiring approval, for a simple reason — their code cannot be reviewed here. Credentials are referenced by environment-variable name and never stored or returned. Disabling a server revokes its tools and the grants to them in the same motion, so turning something off means it is off.
New capabilities arrive as fast as the ecosystem builds them, under rules that never move.
An AI-native CRM has a harder problem than a traditional one. When many agents each query the database independently, they can all be correct and still disagree — because a business metric is a definition, not a column. A Trusted Semantic Core now sits between every agent and the data.
One metric, one definition, many time windows. Win rate used to be calculated separately by the exploration agent, the anomaly detectors, and the executive briefing. Each was defensible; together they could answer the same question three ways. A metric registry now holds the canonical definition — numerator, denominator, the event date it is measured by, and whether it may be summed at all — and every surface reads from it. The anomaly detector no longer redefines win rate; it asks the registry for the same metric over two windows. Every answer can state its own definition:
Win Rate: 89.1% — closed-won ÷ (closed-won + closed-lost) opportunities, excluding open deals, measured by decision date.
This also required a fact the schema never recorded: when a deal was actually decided. Period-over-period metrics had been measured by the record's last edit, so touching an old note could pull a months-old deal into "won this week." Deals now carry a true decision timestamp, set the moment they close and cleared if they reopen.
Reads are governed, not just writes. Approving an action was always governed; reading aggregate business data was not. Cross-record analytics — metrics, exploration, and the analytics agent itself — now pass through one authorization context, so company-wide revenue and win rate cannot be read by asking an agent nicely. Tenant isolation stays where it belongs, at the connection layer; the query layer decides row-level authority.
Every value can say where it came from. "Enterprise" typed by a person, imported from a spreadsheet, and inferred by an agent at 78% confidence are not the same fact. A provenance envelope — source type, source, confidence, and when the fact was observed — travels with custom field values, imported records and AI memories. Imports are stamped as a traceable batch. Where provenance is genuinely unknown, the system says so rather than assuming.
The AI knows whether its data can bear the weight. Readiness used to mean "are there rows?" It now scores seven dimensions — completeness, validity, consistency, uniqueness, integrity, freshness and provenance — and maps them to the decisions that depend on them, so the briefing can qualify itself:
Revenue reporting is reliable. Rep accountability is not — 52% of accounts have no owner.
That specific finding was real, and it was fixed: ownership was recovered by inference from the deals people were actually working, and the create path now inherits an owner instead of silently leaving records unassigned.
One customer, however many records. Exact-email matching never caught "Acme Inc", "Acme, Inc." and "ACME Incorporated." Identity resolution now combines name normalization with trigram similarity, scores each candidate, and sorts it into auto-link, review, or keep-separate. Crucially, confirmed duplicates are links, not merges: both records survive untouched, reads resolve through the link to a golden record that reports which record each field came from, and any link can be reversed. A physical merge is available, but it is a separate, governed, fully reversible action — because a wrong merge that cannot be undone is worse than a duplicate. Whichever channel someone arrives on, and whichever duplicate their handle was attached to, every conversation threads to the same canonical person.
Questions that cross entities. The semantic layer spans nine business areas and knows how they relate — an opportunity belongs to an account and is assigned to a representative; a payment settles an invoice. It can answer which representatives win most often or which industries buy the most but pay the slowest. It also refuses to answer wrongly: joining one record to many multiplies rows, so any total across such a join is blocked with an explanation rather than returned as a confidently incorrect number. Period-over-period comparison, rolling averages and year-over-year are semantic operations available everywhere — and for a rate, the correct pooled figure is reported alongside the naive average.
Erasure understands the copies. Deleting a person is not one delete. Personal data lives in custom fields, AI memories, transcripts and identity links, while invoices and audit trails must survive. Each store now has an explicit policy — delete, de-link, or retain — so an erasure request removes the personal data, keeps the financial and audit skeleton referentially intact, and deliberately preserves the record proving someone asked not to be emailed.
Scheduled intelligence knows which business it is serving. Background work now runs inside an explicit tenant and system-actor context, so proactive intelligence can never quietly serve only the first organization — and every automated action remains attributable to the job that took it.
A database can be correct and its history still be unreadable. The schema answers what is true now; nothing answered why, or whether anyone meant it. This platform now requires every piece of SQL to say which of two paths it belongs to, and refuses the ones that say nothing.
The silent path is closed. Two ways of applying SQL had always existed, and both are right: a governed migration is schema definition every database must have, while an out-of-band operation is a one-time repair a fresh database must never replay. What was missing was anything deciding which a given file was. The choice was made implicitly, by whichever command someone typed, and nothing recorded that a choice had been made. A schema change applied the informal way changed production and passed every check in silence — the migration checker iterates the manifest, the health report divides by the manifest, and the schema comparison looked only at tables.
Every one of the 268 SQL files now carries exactly one disposition: 41 governed migrations and 227 explicitly-classified operations, each with a written reason. A file in neither list is an error, not a default, and the migration runner refuses to touch a database while one exists. The two tools also refuse each other's work: a governed migration handed to the one-off path is rejected by name, and vice versa.
Out-of-band is not a demotion. For 101 of those files it is the only correct answer — a backfill repairs rows a clean database does not have, and replaying it would be actively wrong. Declaring everything a migration would convert one-time repairs into permanent obligations. The classification records what is true, not what is important.
What the checksum does and does not prove. The SQL corpus is deliberately kept out of source control — it carries operational history and seeded data that does not belong in a published repository. A recorded checksum therefore proves that an applied migration has not been altered since it ran; it does not prove this matches an independently reviewed artifact, because no second copy exists to disagree with. That limit is stated plainly rather than glossed over — and it is why the disposition manifest above, which is in source control, carries the written reason for every file it declares. The reasoning is published even where the SQL is not.
A demonstration system that anyone can browse and a system holding real customer data are the same software with entirely different obligations. Telling them apart afterwards turned out to be impossible: an earlier migration rewrote every address in the corpus, destroying the one signal that would have answered it.
So the answer is recorded rather than reconstructed. Each record carries a provenance state — synthetic, real, or ambiguous — with the rule that established it. What makes this a control rather than a spreadsheet is what the database refuses: the tempting inferences are rejected as check constraints, not discouraged in a document. An email domain, a name match, the window a record was created in, and a language model's opinion can none of them be written down as grounds for calling a person real. The wrong answer is not merely discouraged; it cannot be stored.
Absence means ambiguous, never unclassified. The classifier writes only what evidence supports — it will mark a record synthetic where the record itself says so, and it will never promote a record to real on its own. A real person is recorded by a named human, or not at all. Deriving real from a heuristic would be the same error pointed the other way.
The alarm is calibrated to be wrong in the safe direction. A separate tripwire watches for anything that merely looks like a real customer — an address outside the domains this deployment generates into — and it is deliberately over-sensitive. That signal is an alarm and can never become evidence; the schema makes writing it into the provenance record impossible. A false alarm costs somebody a glance at the configuration. A miss costs real customer records served to anyone with the hostname. The public demonstration posture blocks its own release if a record classified real is reachable anonymously.
Two records can look like the same person and not be. On this corpus, matching contacts to leads by name finds 121 pairs, of which 9 are real — a 92% false positive rate. Merging identities is irreversible: it rewrites references across every related table and retires the duplicate.
Nothing had merged. Nothing prevented it either — and the queue already held name and email matches sitting at confidence scores high enough to act on, with the merge itself available as a callable capability.
The fix is a distinction the schema now enforces:
A merge cannot be executed without having been confirmed, and that is a property of the table rather than of one call site. The twenty existing candidate pairs were left exactly where they are: rejecting them in bulk would hide genuine duplicates from future review, and they can no longer be acted on by their own evidence. Doing nothing was the correct action, so nothing is what was done.
Data outlives the feature that created it. Two tables retired long ago were still holding personal information — not referenced by anything, not visible in any screen, and not erased either, because nobody had ever been required to say what should happen to them.
Retirement now carries an explicit disposition. Personal data is erased before the table is dropped, the erasure is recorded with its row count in a permanent ledger, and erasure is the default that applies unless someone declares otherwise. Forty-six rows of personal detail were removed under that rule, on every database, with the record of it kept.
Absence must be declared, not merely observed. The subtle failure here was the obvious fix: if a missing table simply excused itself, then dropping a table would become the quietest way to silence the alarm watching it — the control would report all-clear at precisely the moment the data was destroyed. A table is therefore excused only when its retirement is recorded; a disposition still marked pending is not a decision, and an undeclared disappearance is treated as a failure to read the corpus, which fails closed.
An event that cannot be traced to the request that produced it is an observation without a cause. Business events now carry the correlation identifier of the interaction that triggered them, propagated at the database session rather than threaded by hand through every call site — so a notification, a queued action and the conversation that set them in motion can be reassembled after the fact rather than inferred from timestamps.
Declaring which path a change took closes the gap between two known ways of applying SQL. It does not close the third: someone connecting to the database and altering it directly. That change belongs to no manifest, so no manifest notices it.
The platform now records a fingerprint of the schema itself — every object, per database — at the moment each declared change is applied. A later comparison answers a question the manifest structurally cannot: has this database changed in a way nothing declared? Production currently reports 2,293 objects and clean, meaning the live schema is exactly what the declared history says it should be.
The per-database part is not incidental. The first implementation recorded a fingerprint of the local database while applying a change to the remote one — a check that was confidently reporting on the wrong subject. It now names which database each attestation describes, because an answer about the wrong system is worse than no answer.
A migration that is applied but unrecorded is indistinguishable from one that never ran. That window was real: the schema change and its ledger entry committed separately, so a crash between them left the database changed and the record silent.
They now share one transaction — the change and the proof of the change land
together or not at all. Making that true required more than a wrapper. Most
migrations wrap themselves in their own transaction, which is correct under a
psql session and quietly destructive under a driver that has already opened one:
the file's own COMMIT ends the caller's transaction, and everything after it
runs unprotected. One migration turned out to commit itself halfway through,
with sixty-two lines still to go. The runner now takes ownership of the
transaction, and refuses outright to apply any file whose transaction
control it cannot fully account for — an unverified guarantee is worse than
none, because it stops people looking.
A checksum is never invented. Where a historical migration was applied by hand and its content is genuinely unknown, the record says unverifiable and stays that way. The tooling used to quietly adopt today's file hash into such a row, which reads as diligence and is in fact a fabricated claim about the past. Every writer that can create a ledger entry — including one that lives in SQL rather than code — now either records a real hash or records nothing.
"Who did this?" is only answerable if the answer is allowed to be not a person. Approvals arrive from people, from named policies, from a scheduled expiry sweep, and from one-click links where the mailbox is proven and the individual is not. All four were once recorded identically, as a user.
Every action now carries a principal with its category told truthfully —
user, customer, service, policy, or token — and the invariant is
blunt: no automatic decision may be attributed to a human. The distinction
between a staff member and a portal customer survives the same way, and it fails
toward the cautious answer rather than inventing a new one.
A refusal is not a failure. Results now record an outcome — accepted, rejected, failed, or unknown — because an operator reading "failed" against an authorization refusal will retry it, and should not. The capability mesh is closed by default: an unregistered capability is refused, the registry arms itself at startup so a fresh deployment is never accidentally permissive, and an operator's decision to disable something survives every subsequent deploy.
Five executive authorities govern this platform — CEO, CRO, CFO, CTO and COO — and each one is a named person with an individual sign-in. Every action class routes to the officer accountable for it: revenue actions to the CRO, financial actions to the CFO, technology and data to the CTO, operations to the COO, with the CEO holding escalation.
Authority is bound to the authenticated session. When an executive approves something, the platform records the person who was signed in — their identity comes from the session, never from a field in the request. An administrator cannot act on an executive's behalf, and no approval is attributable to someone merely because their name was selected in a console.
Governance access is separate from platform administration. An executive's application role stays ordinary; their authority to decide comes from the executive register alone. This keeps the two powers independent: the people who approve business actions do not administer the platform, and the people who administer the platform do not approve business actions.
Each authority holds a distinct identity across five layers — the authority record, the owner identity that work is attributed to, directory membership, the sign-in credential, and the policy that names them as approver. The platform verifies all five and reports any that is incomplete, so an authority is either fully constituted or visibly pending.
Identity claims are attested, not inferred. An owner counts as a real person only when a named human has vouched for them on the record, and the platform reports how many of its authorized identities carry that attestation. Real accountability is asserted by a person and can be traced back to them.
Password recovery is self-service and evidence-based. An executive requests a code from the sign-in page, receives it in their own mailbox, and chooses a new password themselves. The platform never stores, displays, or transmits a password chosen by anyone else — each credential begins life with a secret that is generated and discarded unread, so the account holder is the first and only person to know their password.
Recovery codes are single-use and self-retiring: completing a reset invalidates every other outstanding code for that account, so a spare code left in an inbox stops working the moment the account is secured. Codes expire on a short timer, requests are rate-limited per account, and the request endpoint returns the same response whether or not an account exists, so it confirms nothing to an unknown caller. Every issued code is recorded, so recovery activity is fully auditable.
Comparing two databases by their tables answers a narrower question than it appears to. A stored function whose logic silently diverged has the same name on both sides, so a name-level comparison reports agreement — confidently, and wrongly.
Verification now covers an explicit inventory of eight object classes — tables, columns, indexes, constraints, functions, triggers, views and grants — with functions and views compared by the digest of their bodies, not their names. The first run found what the older check had called identical: seven functions whose text had been damaged in an old hand-deployment, and two business rules whose enforcement existed on one database and was simply never attached on the other. Both have since been repaired.
The inventory is deliberately explicit rather than exhaustive. PostgreSQL 18
records every NOT NULL as a catalogue row where PostgreSQL 17 does not, and
including them produced nine hundred phantom differences per run — a version
difference dressed up as drift. Nullability is compared where it is portable
instead. A check that cries wolf nine hundred times is one nobody reads.
Every morning, leadership receives a personalized executive briefing.
Every briefing combines internal business intelligence with live external data sources and includes citations for verification. At the same time, live dashboards continue tracking organizational movement throughout the day.
The briefing now carries a Customer Health & Operations pulse: customer sentiment across every channel — every distilled conversation, voice to email, carries a sentiment reading — a rolling satisfaction measure, and an inventory-risk line watching products short of their stock floor or of open-order demand. A negative conversation marks the account for every agent that touches it; a sustained sentiment slide or a stock shortfall becomes a supervisor breach that composes its own governed response play.
Each executive is modeled as a leadership role and an intelligence profile on top of their employee identity — never a duplicate person record. The profile captures what they need to know (authority domain, strategic priorities) and how they want to be reached (preferred channel, briefing hour, risk threshold). When an action needs a decision it routes to the executive whose authority owns it, and arrives the way their profile prefers — email, in-app, or a Slack message — carrying a plain-language summary of exactly what they are approving, an independent critic's second opinion, and a one-click, signed decision that needs no sign-in. Same underlying intelligence, a different perspective for each leader.
Business awareness becomes continuous rather than periodic.
As researchers such as Geoffrey Hinton continue expanding our understanding of intelligence and machine reasoning, Conscestra embraces a practical interpretation of machine awareness. Artificial intelligence should understand context, relationships, history, and evolving business conditions. It should not merely execute isolated commands.
Intelligence without awareness becomes automation. Awareness without accountability becomes risk. Conscestra seeks to unite both.
Conscestra CRM is not merely a repository of transactions. It is not simply another dashboard. It is not another database with an AI chatbot attached.
It is a system of understanding. A living network of cooperating intelligence. A transparent and accountable memory for the organization. A symphony of specialized AI Agents, conducted by an intelligent Orchestrator, continuously responding to the changing state of the business in real time.
Where traditional CRMs record the past, Conscestra orchestrates what happens next.
This is the architecture the industry now calls Autonomous Enterprise Architecture: a central conductor coordinating specialized agents, one unified customer memory, and one governed action layer where agents never touch the database directly. Conscestra implements that reference model end-to-end — supervisor, peer-to-peer event bus, and dynamic planner orchestration side by side; a live capability registry and policy-as-code guardrails you can tune without a deploy; full correlation tracing from proposal to approved execution; and a learning loop that turns every interaction into governed improvement proposals a human reviews.
Conscestra CRM is a full-stack AI CRM where every module is a conversational agent: ask in plain English, get the answer (and the chart), no menus to hunt through.
Listed in the same order as the launcher page on agentorc.ca — start at Store Home, work clockwise through the planets, end at the Orchestrator.
| Module | What to ask / try |
|---|---|
| 🛒 Store | CRM Universe Hub — the landing page. KPI tiles for Active Pipeline / Open Leads / Pending Orders / Unread Alerts, plus the module launcher |
| 🎯 Leads | "convert Maria's lead", "score this lead" — deterministic Fit + Intent lead scoring (Cold/Warm/Hot), inline forms on vague intent, one-click conversion, qualify/disqualify, duplicate merge, archive & restore |
| 👤 Accounts | "find Apple", "new prospect account" — voice typeahead, 360° timeline & financials, overdue-invoice and no-phone drill-downs |
| 📇 Contacts | "show me Bob Brown's contact details" — duplicate detection, account roll-up, archive & restore |
| 💼 Opportunities | "add product to opportunity" — stage pipeline, weighted forecast, win-rate analytics by owner & lead source |
| 📦 Products | "low stock under 70", "bulk stock adjustment", "price history for Lenovo" — wholesale-≤-retail enforced at DB level |
| 📑 Orders | "create order for ABC Corp" — line-item editor, status workflow, invoice generation |
| 💰 Accounting | "Accounting Summary" — AR aging, cashflow, account-margin analytics, product profitability, forecast accuracy — all real-time |
| 📝 Activities | "create task for Bob tomorrow" — typeahead Related-Name lookup across every entity |
| 📊 Analytics | KPI dashboards (Postgres SPs + Chart.js) plus ad-hoc self-service exploration ("win rate by lead source") over a governed semantic model, unified sales/service/marketing metrics, auto-detected trend anomalies, and a one-click "act on this" that queues a governed plan |
| 🔔 Notifications | Real-time activity stream with unread/read state |
| Outbound mail + inbox + autonomous inbound auto-reply (SMTP/IMAP + LangGraph), plus event-driven order-confirmation / shipped emails to verified customers | |
| 🧭 Orchestrator | "daily briefing", "pipeline health", "company pulse" — symphonic workflows that fan out to multiple agents and weave the results into one report, plus a curated executive Q&A bank for CEO/CFO-style questions |
AGENT_BUS_AUTOSEND=0 keeps it draft-only until you flip it on).agent_sequences + a sequence.step_due event loop) runs timed playbooks as graphs, not lines: hot-lead follow-up (intro draft → reminder → meeting offer → nurture) and the churn-save play (support context check → win-back draft → executive escalation), each exiting early on engagement, conversion, or a new order. Steps carry conditional routing — a mid-cadence reply routes to an urgent book-the-meeting step instead of just ending the run; an open complaint at offer time skips the discount and escalates. Deterministic conditions from a registry, loop-capped, and multi-day steps align to the customer's learned preferred hour.agent_playbooks table with the code built-ins as fallback: a new play (steps, waits, branch rules, signal routes) ships as a validated row via PUT /sequences/playbooks/{name} — no deploy. Every step action and branch condition must reference the registered handler registries, so data authors compose from vetted building blocks and arbitrary code can never enter through the table.business_objectives: metric, baseline → target, horizon, owning agent, optional recovery play) are evaluated every supervisor tick against a linear trajectory with slack: achieved / on_track / at_risk / off_track, plus trend from daily snapshots. Off-track objectives raise events and can trigger their agent's governed play; the CEO briefing carries a 🎯 objectives section. Detectors watch symptoms; objectives pursue outcomes.crm_agent/
├── main.py ← Top-level entry point
├── requirements.txt
├── .env ← Single config file for all agents
├── sp/ ← PostgreSQL stored procedures
├── scripts/ ← Verification tooling — run against a live database
│ ├── migrate.py ← Ordered migration manifest, applied idempotently
│ ├── verify_invariants.py ← Database-layer controls, asserted directly in SQL
│ ├── red_team.py ← Attacks EXECUTED against the live system
│ ├── postdeploy_verify.py ← Secrets → invariants → red team, as one gate
│ ├── mutation_audit.py ← Breaks the code to prove each gate can fail
│ ├── observability_audit.py ← Plants a defect per metric; reports any that stay green
│ └── test_guards.py ← Wrong-DSN and orphaned-row guards for the suite
├── *-mgmt.html ← One frontend per agent (incl. orchestrator-mgmt.html)
├── case-mgmt.html ← Case queue, lifecycle actions, field history
├── customer-portal.html ← Customer's own record (orders/invoices/cases/quotes)
├── platform-health.html ← Platform / obligations / governance health
└── app/
├── main.py ← FastAPI app — registers all routers
├── core/ ← Shared utilities (zero duplication)
│ ├── config.py ← Conscestra Settings (pydantic-settings)
│ ├── database.py ← Generic execute_sp() + test_connection()
│ ├── memory.py ← Shared session memory (rolling window)
│ ├── graph_utils.py ← AgentState, LLM factory, JSON parser,
│ │ build_standard_graph()
│ ├── agent_bus.py ← Event-bus consumer + cooperation handlers
│ ├── a2a.py / blackboard.py ← Agent-to-agent protocol + shared memory
│ ├── supervisor.py ← Proactive KPI-breach detection
│ ├── objectives.py ← Goal-oriented supervisor (business objectives)
│ ├── governance.py ← Confidence gates + executive approval routing
│ ├── critic.py ← Independent verifier on every queued approval
│ ├── sequences.py ← Branching timed playbooks (cadences as data)
│ ├── intelligence.py ← Nightly customer-intelligence profiles
│ ├── marketing.py ← Segment → draft (LLM) → A/B → CASL-gated launch → measure
│ ├── qualification.py ← Win probability + recommended-rep card
│ ├── learning.py ← Agent performance analytics + calibration
│ ├── tuning.py ← Calibration-proposed, human-ratified parameters
│ ├── context.py ← Context hydration ("born with context" packs)
│ ├── knowledge.py ← Service knowledge loop (mine → govern → retrieve)
│ ├── booking.py ← Real meeting booking (availability + signed .ics)
│ ├── planner.py ← Bounded goal→plan orchestration
│ ├── scoring.py ← Predictive lead scoring (governed activation)
│ ├── privacy.py ← PII masking before any LLM prompt
│ ├── telephony.py ← SMS + voice channel (Twilio/Telnyx, governed)
│ ├── sdr.py ← Autonomous SDR (public chat + voice loop)
│ ├── voice_support.py ← Customer support line (tiered trust + OTP
│ │ verification + account-scoped answers)
│ ├── voice_stream.py ← Real-time voice (media streams, VAD,
│ │ streaming STT/TTS, barge-in)
│ ├── customer_memory.py ← One cross-channel conversation memory
│ ├── identity.py ← (channel, handle) → one CRM party (canonical-aware)
│ ├── identity_resolution.py ← fuzzy duplicate candidates (normalize + trigram)
│ ├── identity_links.py ← reversible duplicate links + golden-record view
│ ├── metrics.py ← Metric Registry: one canonical definition per metric
│ ├── access.py ← DataAccessContext — governed reads (authorization)
│ ├── provenance.py ← source/confidence envelope for stored values
│ ├── data_readiness.py ← 7-dimension readiness scoring + decision reliability
│ ├── lifecycle.py ← erasure policy per store (delete/de-link/retain)
│ ├── conversations.py ← Unified cross-channel Conversation Object
│ ├── channel_adapters.py ← Channel inbound → one common envelope
│ ├── channel_selector.py ← Best channel/action for an objective
│ ├── intent_router.py ← LLM intent routing, keyword fallback
│ ├── semantic.py ← KB embeddings (hybrid meaning+keyword retrieval)
│ ├── simulator.py ← Read-only what-if over business objectives
│ ├── trace.py ← Correlation-id trace (one id → whole play)
│ ├── outbound_guard.py ← Deterministic triage on every outgoing message
│ ├── kb_ingest.py ← Document/URL/attachment → governed KB proposals
│ ├── cases.py ← Case lifecycle — the one transition matrix
│ ├── history.py ← The one append-only field-history writer
│ ├── case_analytics.py ← Service metrics + knowledge signals
│ ├── assignable.py ← One assignable-identity space (collision-aware)
│ ├── routing.py ← Rules as data: language/skill/capacity + preview
│ ├── portal.py ← Customer portal (read-only, one customer scope)
│ ├── release_guard.py ← Startup posture audit (refuses an unsafe deploy)
│ ├── quotes.py ← Quotation build + delivery + durable lifecycle
│ ├── web_tools.py ← Internet access (search + fetch + cite)
│ ├── llm_meter.py ← LLM usage metering, budgets, model tiering
│ ├── llm_router.py ← Provider failover (failure classes, egress
│ │ policy, health checks, attempt telemetry)
│ ├── escalation.py ← Escalation objects + SLAs + promised follow-ups
│ ├── custom_agents.py ← No-code authored agents (reach invariant)
│ ├── agent_versions.py ← Draft/publish gate, rollback, override log
│ ├── agent_capabilities.py ← Capability catalogue + per-agent grants
│ ├── mcp_client.py ← Consume external MCP servers (3 gates)
│ ├── platform_health.py ← Platform / obligations / governance health
│ ├── language.py ← Script + word language detection (zh/ja/ko safe)
│ ├── evals.py ← Nightly behavior evals (CI for prompts)
│ └── data_quality.py ← Data hygiene detectors + undoable fixes
└── agents/
│ ── 10 conversational AI agents (LangGraph + pre-router + LLM) ──
├── accounts/ prompt | pre_router | sql_builder | formatter | graph | router
├── contacts/
├── leads/
├── opportunities/
├── orders/
├── products/
├── activities/
├── notifications/
├── accounting/
├── analytics/
├── cases/ ← service cases (reads allow-listed; writes go through core/cases.py)
├── orchestrator/ ← symphony workflows + executive Q&A bank (router | executive)
│ ── 4 supporting modules ──
├── home/ ← sp_home_index dashboard (direct SP, no AI)
├── email/ ← SMTP/IMAP + LangGraph + autonomous auto-reply poller
├── store/ ← Commerce catalogue view (direct SP, no AI)
├── auth/ ← Signup / signin / password-reset (direct DB, no AI)
└── voice/ ← Azure Cognitive Services token mint for browser STT
python -m venv venv
.\venv\Scripts\activate
# 1. Install dependencies
pip install -r requirements.txt
# 2. Configure environment
cp .env .env.local # then edit .env with your DB_DSN, LLM settings
# OR just edit .env directly
# 3. Run
python main.py
# or
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
CI checks what a build server can check — that every module imports, and that the derivation pipeline still produces identical output against a frozen corpus. It has no database and no secrets, so it cannot exercise a single database-layer control. The evidence comes from the deployed environment:
# One gated result: secrets, DB invariants, executed red-team attacks,
# data-subject export coverage, runtime-DDL audit, and schema drift
python -m scripts.postdeploy_verify --target railway \
--app-url https://your-app.example.com/health
# Prove each gate can still fail (breaks the code on purpose, then restores it)
python -m scripts.mutation_audit
# Plant a defect per metric; report any that stay green
python -m scripts.observability_audit
# Dump, restore, and compare every table — the RTO is measured, not estimated
python -m scripts.backup_railway
# Kill the leader; measure how long until a survivor takes over
python -m scripts.chaos_leader
Pass --app-url so the check reads the application's own report of which
database role it connected as. That is what lets the red team judge the running
application rather than the administrative connection the harness itself uses —
and if the URL is given but does not answer, the run fails rather than
skipping, because every check downstream would otherwise be measuring the wrong
subject.
schema drift compares the live schemas of your working database and the deploy
target directly. It deliberately ignores the migration ledger: a ledger is only
as good as the discipline of whoever last applied a migration by hand, and
comparing what the two databases actually contain needs no discipline at all.
| Method | Path | Description |
|---|---|---|
| GET | / | Service info + endpoint catalogue |
| GET | /health | Aggregate health check (all modules + DB) |
| GET | /home-index | Home dashboard KPIs (direct SP) |
| POST | /account-chat | Accounts agent |
| POST | /contact-chat | Contacts agent |
| POST | /lead-chat (/leads-chat) | Leads agent |
| POST | /opportunity-chat | Opportunities agent |
| POST | /order-chat (/orders-chat) | Orders agent |
| POST | /prod-chat | Products agent |
| POST | /activity-chat | Activities agent |
| POST | /notifications-chat | Notifications agent |
| POST | /accounting-chat | Accounting agent |
| POST | /analytics-chat | Analytics agent (reports + ad-hoc explore + anomalies + service/marketing) |
| POST | /analytics/explore | Ad-hoc self-service query over the governed semantic model (read-only) |
| GET | /analytics/explore/catalog | The semantic model — explores + dimension/measure keys |
| GET | /analytics/anomalies | Live trend anomalies + thresholds (admin) |
| POST | /analytics/anomalies/act | Compose a governed plan for an anomaly (writes queue for approval) |
| POST | /case-chat | Cases agent (reads allow-listed; writes via the lifecycle) |
| POST | /orchestrator-chat | Orchestrator agent (symphony workflows + executive Q&A) |
| POST | /email-chat |
Each AI agent also exposes a matching GET /<name>-health endpoint that
returns graph_ready: true/false so a load balancer can verify the agent's
LangGraph compiled cleanly on boot.
Every agent follows the same deterministic-first pattern:
Request
└─► FastAPI router.py
└─► graph.py
└─► pre_router_node
├─[ROUTED]──► db_node ──► formatter_node ──► Response
└─[PASSTHRU]► ai_agent_node
└─► parse_output_node
├─[JSON found]──► db_node ──► formatter_node
└─[no JSON]─────► formatter_node
Shared utilities in app/core/:
Settings class, one .env fileexecute_sp(query) function works for any SPAgentState, LLM factory, JSON extractor,
build_standard_graph() — each agent calls this with its own nodesThe 10 conversational agents are all in place. To add an 11th:
app/agents/<name>/
__init__.py
prompt.py ← Domain-specific system prompt
pre_router.py ← Deterministic intent matchers (form-marker pattern supported)
sql_builder.py ← build_<name>_query() → sp_<name>(...) call
formatter.py ← format_response() → markdown the frontend renders
graph.py ← LangGraph nodes; call build_standard_graph()
router.py ← FastAPI POST /<name>-chat + GET /<name>-health
from app.agents.<name>.router import router as <name>_router
app.include_router(<name>_router)
No changes to app/core/ are ever needed — the shared utilities work for any agent.
All 15 modules pull from app/core/ rather than duplicating boilerplate.
| Concern | Per-agent duplicate (the old way) | Consolidated in crm_agent |
|---|---|---|
| Settings | app/config.py × 15 | app/core/config.py × 1 |
| DB connection | app/database.py × 15 | app/core/database.py × 1 |
| Session memory | app/memory.py × 15 | app/core/memory.py × 1 |
| LLM factory | _get_llm() duplicated × 15 | graph_utils._get_llm() × 1 |
| Ollama direct call | duplicated × 15 | graph_utils._call_ollama_direct() × 1 |
| JSON parser | duplicated × 15 | graph_utils.parse_ai_json() × 1 |
| Graph topology | duplicated × 15 | graph_utils.build_standard_graph() × 1 |
| Server entrypoint | main.py × 15 | app/main.py × 1 |
Domain-specific code (prompt, pre_router, sql_builder, formatter, graph nodes) remains completely isolated inside each agent's sub-package.
Conscestra CRM — AgentOrc.ca — Canadian AI orchestration platform.
| Office | Phone | Hours |
|---|---|---|
| 📍 Toronto | 289-800-4112 | 24/7 |
| 📍 Vancouver | 778-907-0989 | 24/7 |
| 📍 San Francisco | 650-912-1699 | 24/7 |
| 📍 New York | 332-456-4869 | 24/7 |
🏢 Headquarters — 416-477-9298 · 416-889-6638 Business Hours: 9:00 a.m. to 5:00 p.m., Monday through Friday — Toronto / New York (Eastern Time)
✉️ Email: [email protected]
objective.at_risktuning.adjust governance proposal with the evidence attached; approval writes the governed agent_tuning store the scorer reads live, undo reverts it, hard min/max bounds and a 14-day cooldown keep it conservative. The system proposes; people ratify.context.py) builds a compact ≤12-line briefing per customer (intelligence profile, blackboard signals, open money, running cadences, pending approvals with critic stances, last touches) and auto-injects it wherever an agent starts work: agent-to-agent dispatches, the inbound auto-reply, an inspection endpoint, and an A2A capability any agent can call.kb.publish, undo retires); the autonomous auto-reply then grounds its answers in approved articles via deterministic Postgres full-text retrieval (no embeddings infra), with per-article usage counters showing which knowledge earns its keep..ics invite delivered under the same autosend + verified-address gates as email; the cadence's engaged route auto-books and a confirm task keeps a human in the loop. Governed via A2A meeting.book; undo cancels.scoring.activate action with undo restoring the previous version, and consumers fall back to the band-history heuristic when no model is active.j***@domain, phones/cards → last-4; dates, money and invoice numbers stay readable) before reaching the LLM; operational agent commands are deliberately exempt so actions still work, and masking is idempotent with an instant kill switch.from: us|ca|<E.164>).@mention, answered by the Orchestrator and threaded like every other channel. Fail-closed to identity-linked staff (Slack signature verified with replay window; Teams shared-secret; unlinked senders refused with no CRM read); audience-scoped so a shared-channel answer is delivered ephemerally (an allow-list opens designated channels), never a public broadcast, and never a public fallback on failure; per-(channel, user) rate-limited before any DB/LLM work (ack < 3s, answered in the background so Slack never retries or disables the subscription). Routed approvals arrive as native in-thread Block-Kit Approve/Reject buttons driving the same HMAC-verified governance flow; agents post briefings/alerts into channels draft-first (SLACK_PROACTIVE_ENABLED); Teams 1:1 replies via the Bot Framework connector while channel replies stay withheld.GET /llm/usage and the briefing's AI-spend line report cost per agent.improved: false outcomes.wholesale ≤ retail trigger.semantic_model.py + semantic_query.py): the LLM emits a JSON spec referencing only curated dimension/measure keys — never SQL — which is validated against an allow-list and compiled to a parameterized, read-only query (filter values bound not inlined, single statement, clamped LIMIT, executed inside a Postgres read-only transaction with a statement timeout). Ask-Data flexibility with the safety of a stored procedure; new explores are a data edit in the registry.POST /analytics/anomalies/act) that composes a bounded multi-agent plan via the same planner bridge the supervisor uses — reads run, writes queue for governance approval, idempotent, nothing sent or changed automatically.setup.html Get-Started page) close it: (1) Governed CSV import (data_import.py) brings a customer's book of business in through the same entity create-path, SPs and audit as a hand-typed record — alias-mapped headers, a read-only dry-run preview (create / duplicate / error) then an idempotent commit (re-checks dedupe). (2) A Readiness Center (readiness.py → GET /setup/readiness) replaces a wall of zeros with a prioritized next-step checklist (DB / LLM / core-records / KB / email / executives + posture flags), every probe defensive. (3) A one-command demo (demo.py → POST /demo/seed) seeds a realistic sample business (reusing the importer) + shaped opportunities and returns the intelligence headline — "$595k open pipeline · 5 stalled · 3 slipped · 60% win rate · 12 leads" — then clear() removes it.customer_tier, renewal_date, RCM level, MLS #) with no schema change — a sidecar defs+values store (custom_fields.py) that touches zero existing tables or SPs. They're DB-, UI-, Agent- and Analytics-aware: injected into context.hydrate() and the AI 360 (an agent answering "show me Enterprise accounts" sees the field), and surfaced as dimensions/filters in the semantic layer ("total pipeline by customer tier") with filter values kept as bound params.industry_packs.py): pure data that reuses every existing writer to seed the right custom fields + knowledge base + goals + a grounded Q&A assistant. The CRM is unchanged; only the content fits the industry. Idempotent and fully removable.tenancy.py + a tenants registry): because all ~360 data-access sites funnel through one get_connection chokepoint, tenancy attaches in one place (schema-per-tenant via search_path, database-per-tenant for residency) with no stored-procedure or table changes — so a future SaaS deployment is a configuration path, not a rewrite (docs/multi_tenancy.md). Off by default; behaviour is byte-for-byte today's.fn_score_lead, rule_based_v1) replaces random scores with explainable, audited Cold/Warm/Hot ratings; the scoring function is a single swappable API, ready to drop in a predictive model later.escalation.py) — and so does the agent's own promise: outgoing text is scanned for "someone will follow up" and the commitment is opened before the customer sees the reply. One per conversation (partial unique index), SLA tiered by reason, breaches surfaced on platform health, resolved when the conversation is.agent_capabilities.py). Three independent checks each sufficient to refuse (granted · caller allowed · data class), listing is never permission, and anything consequential becomes a governed proposal in the existing approval queue rather than executing.agent_versions.py). The reach invariant — an externally reachable agent may read only the public KB tier — is enforced at write, evaluate and publish and cannot be forced (it caught a live misconfiguration where a public agent answered from internal docs). Overrides require a written reason and the history preserves the reason and the checks that were failing.platform_health.py + platform-health.html answer is the machinery working: event-bus drain rate, stranded events with no handler, retries that never succeed, failover readiness · open and breached escalations · approval age and gate overrides. Its own error states distinguish "not signed in as admin" from "server unreachable" from "query failed" instead of a bare Failed to load.llm_router.py classifies failures first: timeouts/rate-limits/overload are transient and worth a second provider; auth errors, malformed requests, safety refusals and budget stops are decisions or defects and never fail over. Egress policy holds — INTERNAL_SENSITIVE work never leaves for a second vendor — the budget is checked once before any provider, providers are health-checked by actually calling them, and telemetry separates the logical request from each provider attempt. Ships off by default (LLM_FAILOVER_ENABLED).mcp_client.py). Tools are projected into the same U4 capability catalogue rather than a second permission model, and three gates each refuse on their own: server registered and enabled (allowlist, not discovery) · tool enabled individually · egress data-class check. External tools default to requires_approval; credentials are referenced by env-var name and never stored; disabling a server revokes its tools and their grants.<Gather> must commit to a recognizer before the caller speaks; text channels detect silently via script detection (language.py) that correctly separates zh from ja/ko.| Email agent (SMTP/IMAP + LangGraph) |
| POST | /store-chat | Store catalogue (direct SP) |
| POST | /auth/{signin|signup|signout|...} | Auth (direct DB, no AI) |
| GET | /voice/azure-token | Azure Speech short-lived token for browser STT |
| POST | /sdr/chat | Public SDR web chat (gated + rate-limited) |
| POST | /voice/support/{inbound|turn|verify} | Support-line carrier webhooks (signature-verified) |
| WS | /voice/stream/{line} | Real-time media stream (HMAC-token authorized) |
| POST | /knowledge/ingest | Upload a document → governed KB proposals (admin) |
| GET | /knowledge/gaps | Questions the KB couldn't answer (admin) |
| GET | /learning/bottlenecks | Live process-health scan (admin) |
| GET | /customer-memory/{type}/{id} | Cross-channel conversation memory (admin) |
| GET | /simulate?q=… | Read-only what-if over live metrics + objectives (admin) |
| GET | /trace/{correlation_id} | One play's full timeline across a2a/events/approvals (admin) |
| GET/PUT | /governance/policies[/{key}] | Live guardrail policy overrides (admin) |
| GET/POST | /a2a/registry[/{intent}] | Capability enable/disable + caller ACL (admin) |
| GET | /outbound-guard/test?text=… | Dry-run the outbound message screen (admin) |
| POST | /calendar/import | Paste .ics → meeting activities, contact-matched (admin) |
| GET | /setup/readiness | New-org readiness — configured/populated + next step (admin) |
| POST | /import/{preview|commit} | Governed CSV import of accounts/contacts/leads (admin) |
| POST | /demo/{seed|clear} | Seed / remove a sample business + intelligence headline (admin) |
| GET/POST/DELETE | /custom-fields/defs · /custom-fields/values/{entity}/{id} | Custom-field definitions + record values (admin) |
| GET/POST | /industry/packs[/{id}/apply|remove] | Apply/remove an industry starter pack (admin) |
| GET | /platform/health[/section/{key}] | Platform / obligations / governance health (admin) |
| GET | /cases/analytics[/semantics] · /cases/knowledge-signals | Service metrics, backlog age, reopen rate, KB candidates (admin) |
| GET/POST/DELETE | /routing/rules[/{id}] | Routing rules as data, versioned (admin) |
| GET | /routing/recommend/{case_id} · /routing/preview | Who gets this work — and why everyone else was excluded (admin) |
| GET/POST/DELETE | /routing/directory[/attributes|/provision|/{email}] | Assignable identities + languages/skills/capacity (admin) |
| GET | /portal/{me|orders|invoices|cases|quotes} | Customer's own record — read-only, account-scoped (customer session) |
| GET | /portal/ask?q=… | Customer assistant over the same functions the pages use |
| GET/POST | /escalations | Open obligations + SLA state; assign / resolve (admin) |
| GET/POST | /agent-versions/{slug}[/draft|evaluate|publish|rollback] | Authored-agent draft/publish gate + history (admin) |
| GET/POST | /agent-capabilities[/catalog|/{slug}] | Capability catalogue + per-agent grants (admin) |
| GET/POST | /mcp/servers[/{name}/discover|enabled] | Register/enable external MCP servers + tools (admin) |
| POST | /mcp/call | Invoke an external MCP tool through the grants (admin) |
| GET | /sessions | List active memory sessions |
| DELETE | /sessions/{id} | Clear a session's memory |