Causal Decomposition Under Suspended Judgment: Two Cases from Keystone
When a governed AI system fails, the useful discipline is not debugging. It is refusing to commit to what the failure means until the actual mechanism emerges. Most production incidents get closed on the first plausible cause because that cause is fixable and the ticket needs to move. The two cases below are about what happens when you refuse to move the ticket. The first is a retrieval failure that looked like an embedding problem, was diagnosed by three separate causes, and got remediated at the layer that made the other two failure modes disappear. The second is a set of architectural decisions made before any code was written, driven by causal reasoning about the failure modes multi-agent systems will exhibit when they meet regulated production for the first time. Both are the same skill applied to different substrates.
Case one: FC-005 and the three-factor remediation
The bug looked simple. A query against keystone-core, running retrieval over an Alberta occupational health and safety corpus, asked what our greenhouse gas reporting requirements were under TIER. TIER is Alberta's Technology Innovation and Emissions Reduction regulation, the provincial industrial emissions framework. The correct answer is that TIER is not covered by the OHS corpus. What the system returned instead was five chunks from Part 36 (Mining) and Part 10 (Fire and Explosion Hazards), all about methane monitoring and flammable gas detectors in underground mine environments. It marked the response evidence_sufficient: true and generated a fluent, confident, verbatim-cited answer about countersigning mine gas reports. Wrong topic, wrong domain, wrong regulatory framework, presented as authoritative.
The naive diagnosis is that the embedding model is bad and the fix is a better embedding model. It is the diagnosis a debugging-mode engineer reaches for because it is a single knob, it is fixable in a sprint, and there is empirical evidence for it in the retrieval scores. The scores on those wrong chunks were high. The word gas appears in greenhouse gas reporting language and in flammable gas detector language, so the two vocabulary clusters overlapped in the embedding neighborhood. Ship a better embedding, retrain, ship again.
I did not ship a better embedding. What I did was pull the raw response JSON, walk through the retrieval scoring, the consistency gating, and the answer synthesis in sequence, and refuse to commit to a cause until I had accounted for every step in the pipeline. There were three separate contributing factors, not one, and only one of them was the embedding.
The first factor was the vocabulary cluster overlap. In an occupational health and safety corpus that has both a mining section and no greenhouse gas reporting section, the token gas carries mining-context weight in most of its occurrences. A regulatory-framework query about industrial emissions gets pulled into the mining neighborhood because that is where gas lives in this corpus. The embedding model was doing what embedding models do. This factor is real and it is the one debugging attention gravitates toward.
The second factor was more interesting. HHEM (Vectara), the factual consistency scorer, was checking whether the generated answer was consistent with the retrieved chunks. It was. The answer accurately reflected what those Part 36 chunks said about methane monitoring. HHEM does not check whether the chunks are relevant to the query. It checks answer-to-chunk consistency, not query-to-chunk relevance. So the consistency gate passed on an irrelevant retrieval, and the system rated its own confidence high, because its own confidence signal was measuring the wrong thing. This is the failure mode that gets ignored when you fix the embedding, because a better embedding might have hidden it for longer without eliminating it.
The third factor was the absence of domain scope. There was no signal anywhere in the pipeline that told the system TIER queries live in a regulatory-framework domain and Part 36 chunks live in an operational-safety domain. The pipeline was a flat retrieval-then-generate loop with no notion of what topic space the query belonged to. If the query had been about respirator fit-testing or excavation permits, it would have retrieved correctly. Because it was about an emissions framework that was not in the corpus, it retrieved plausibly wrong content.
The remediation shipped as FC-005, a pre-retrieval domain scope guard (case study and patch). Before retrieval runs, the query is classified against the corpus's actual domain coverage. Queries that fall outside the corpus's scope get routed to a fail-closed refusal path with a documented reason (out_of_scope: query domain not present in corpus) rather than being pushed through the retrieval-generate-consistency pipeline. Queries that fall inside scope get retrieval as before, plus an explicit domain tag that participates in retrieval ranking as a re-ranking signal.
The reason this remediation is worth the length of the description is what it does to the other two failure modes. The vocabulary cluster overlap still exists in the embedding space; embeddings are not going to be rewritten by us. But it no longer produces the failure, because queries whose domain is not present in the corpus never reach the retrieval layer where the overlap could bite. The consistency scorer is still measuring answer-to-chunk consistency and not query-to-chunk relevance; that architectural limitation of HHEM is intact. But it no longer matters, because queries that would have been retrieved into the wrong domain are not reaching the consistency check in the first place. A single architectural fix at the earliest layer eliminates the surface area for both of the other failure modes to exhibit themselves. This is what causal decomposition is for. If I had fixed the embedding, the consistency gate would still be measuring the wrong thing, and the next out-of-scope query with different vocabulary overlap would have failed in a new way. If I had patched the consistency gate to check query-to-chunk relevance, I would have moved the failure to a different metric without addressing the fact that the pipeline had no notion of scope. The fix that removes the class of failure, not the instance, is the one that shifts the space of future failures rather than pushing them one layer down.
There is a fourth thing worth naming about the remediation. It was published alongside the failing run. keystone-core/retrieval-v1 (formerly the passing eval) is preserved next to the pre-fix behavior in keystone-core/retrieval-v0-fc005-fail. Anyone can rerun the eval against either version. This is contact center quality management applied to LLM systems: bad calls are not hidden, they are analyzed, and the analysis stays part of the artifact set.
Case two: the day-one substrate as causal decomposition applied to organizational design
The second case looks nothing like a bug. It is a set of architectural decisions made in the first week of building keystone-engage, before there was a single deployed customer conversation. The decision looks obvious in retrospect and expensive to defend in the moment: build the schema, the interfaces, and the observability for a multi-agent system on day one, even though v1 ships with one agent operating at one tempo.
The causal reasoning behind that decision is direct, and the case history is thirteen years of watching the alternative play out at Genesys. Genesys built specialized engines per domain. A voice engine. A chat engine. A workforce management engine. A contact intelligence engine. Each was serious engineering. Each spoke its own protocols, had its own data model, its own state representation. None of them assumed the others existed. The integration story across engines was always the hard problem. Cross-engine capabilities that customers wanted, like routing decisions that considered voice availability and chat availability and the WFM schedule together, required either the customer building the integration or a system integrator being hired to build it. The engines did not naturally talk to each other. Every cross-engine feature request became a PM-to-PM negotiation, then a framework limitation, then a costed change request, then a partial or deferred outcome. Sometimes the customer got what they wanted in a year. Sometimes a workaround. Sometimes a lost deal to a competitor whose engines cooperated by design.
The failure was not that any engineer was bad. The engines were built well individually. The failure was structural and it played out in the organization, not the code. The protocol between engines became the protocol between teams. Teams whose engines had not been designed to cooperate had to negotiate cooperation across every request. The cost difference between "the schema already supports this" and "we need to add this field" is not five percent; it is closer to a factor of ten, paid in engineering time and roadmap slippage.
Multi-agent AI in 2026 is set up to make exactly this mistake at scale. Most teams are building agents in isolation, with custom tool interfaces, framework-specific state, and ad hoc inter-agent communication. The frameworks in the space (LangGraph, OpenAI Agents SDK, CrewAI, Microsoft Agent Framework) are still consolidating and none of them is committed enough to any specific schema for multi-agent state that a team can safely build against it and expect it to be there in 2028. Custom implementations proliferate. By 2028 there will be enterprise buyers paying integrators to bridge agents that were never designed to cooperate, and the buyers will be paying because the marginal cost of retrofit is enormous compared to the marginal cost of getting it right on day one.
Causal decomposition applied to that failure mode says: the retrofit cost is the observable outcome, but the underlying cause is the absence of four specific substrate dimensions that must be first-class from the first commit. If those dimensions are present, v2 populates them with more agents and the schema does not migrate. If they are absent, every future capability that touches them costs a schema change, a data migration, a redeploy, and a set of team negotiations. The four dimensions are agent identity, tempo, task state, and cost. Each of them maps to a distinct class of failure that multi-agent systems exhibit in regulated production.
Agent identity. Without agent identity as a first-class field on every audit entry, every state record, and every authorization decision, a multi-agent system cannot answer the question "which agent did this?" after the fact. It cannot answer "which agent is authorized to call this tool?" at dispatch time. It cannot answer "did the compliance agent verify what the retrieval agent claimed?" during a downstream review. Everything about multi-agent governance falls apart at scale when the substrate cannot name the actor. In v1 there is one agent, and the agent identity field always holds the same value. The field exists anyway.
Tempo. Different agents operate on different time horizons. A customer-facing engagement agent needs to respond in under a second. A compliance-gating agent that reviews a proposed action can take three to five seconds without breaking the interaction. An analytics agent that summarizes a day of interactions can take minutes or hours. A multi-agent system that treats all agents as interchangeable peers with the same tempo assumptions will fail as soon as it tries to compose fast and slow agents in the same workflow. Either the fast agents block on the slow ones and the customer-facing latency collapses, or the slow ones are excluded from the flow and the compliance guarantees they were meant to provide never fire. Tempo has to be a first-class dispatch parameter and a first-class field on every audit entry, so the orchestrator can route correctly and the reviewer can distinguish a fast agent that took too long from a slow agent that behaved normally. In v1 every entry has tempo fast. The field exists anyway.
Task state. When the orchestrator dispatches work to an agent, the work has to exist as a record in the data plane with explicit state: created, in_progress, completed, failed. Not to hedge against v1 needing it, but because the moment a second agent enters the system, the orchestrator has to be able to answer "is this task claimed, is it stuck, has it been completed but not yet verified, has it been rescheduled to a different agent?" Without task state, an agent that hangs, or hallucinates, or gets rate-limited by an upstream provider leaves the orchestrator with no way to detect the condition, no way to reassign, no way to recover. In v1 the state machine has four states and the transitions are trivial. The table exists anyway.
Cost. Every operation records what it consumed in input tokens, output tokens, latency, and dollars. Every dispatch carries a budget. The agent registry records a cost profile per agent so the orchestrator can make cost-aware routing decisions later. Anthropic's own engineering data (single agents use roughly four times the tokens of a conversational interaction; multi-agent systems use roughly fifteen times) tells you the economics of multi-agent are unbounded without explicit budget discipline. Frameworks built in 2023 and 2024 did not treat cost as a first-class signal because the cost was small and the focus was on whether agents could work at all. By 2028, enterprise buyers will be demanding cost-per-query reporting, cost-aware SLAs, and cost-bounded behavior. Systems where cost is a first-class field of every audit entry from day one will be ready. Systems where cost has to be retrofitted onto an existing schema will not. In v1 the fields are populated with measured values from real inference calls. The overhead is negligible.
The full day-one substrate package is ten specific additions to the week-one scaffolding: two new tables (agents, tasks), three new fields on the existing audit entry schema (agent_id, tempo, task_id), six cost fields on the audit entry schema, five parameters on the dispatch interface, two identities on the tool authorization check, six attributes on the OTel spans, and one column on the eval framework's result schema. Approximately eight to twelve hours of focused work in a single week. The eventual v2, v3, and PhD-era extensions become cheap additions instead of architectural refactors. That is the entire economic argument, and it is causal decomposition applied to a failure mode that has not yet happened, because the mechanism is knowable from thirteen years of watching the same failure play out on a different substrate.
The reason this is architectural rather than a checklist is that a checklist can be added later. If the field is on the schema, code that queries the schema can start using it. If the field is not on the schema, every future query against it triggers a migration, a backfill, a redeploy, and an organizational negotiation about whose team owns the change. Once the field exists, the argument about whether to use it becomes an engineering conversation. Before it exists, the argument is a roadmap conversation. Those are different conversations conducted by different people at different costs.
Why this matters
Causal decomposition under suspended judgment is not a buzzword. It is the skill behind both cases above, and it is the skill that produces work regulated employers can actually depend on. The doctrine underneath fiduciary-grade AI is that professional trust comes from permissioning, authoritative content, transparent outputs, and non-outsourceable accountability. Every one of those properties requires that the system's failure modes are understood at the mechanism level, not the symptom level. A retrieval failure that gets fixed at the embedding layer is a system whose failure modes are understood at the symptom level. A retrieval failure that gets fixed at the domain scope layer, with the failing run preserved next to the passing run, is a system whose failure modes are understood at the mechanism level. Only the second one is fiduciary-grade.
The same logic runs through the substrate case. A multi-agent system whose schema was built for one agent and expanded reactively is a system whose accountability chain has holes. Every gap in the schema is a place where "which agent did this and at what cost" cannot be answered after the fact. A multi-agent system whose schema was built on the four dimensions from day one is a system where the accountability chain is intact by construction. The auditability is not a feature, it is a consequence of the substrate decision.
Both cases are the same discipline. Refuse to commit to what the failure means until the mechanism emerges. Fix at the layer that changes the class of future failures, not the instance. Publish the failing run alongside the passing run so the reasoning stays part of the artifact set. That is what causal decomposition looks like when it is doing work.
Keystone Applied Intelligence is an independent engineering practice. The public eval ledger is at github.com/getkeystone/keystone-ledger. The keystone-engage repo is at github.com/getkeystone/keystone-engage.