How to Resolve Conflicting Policies in an AI Onboarding Company Brain

Do not let the model decide which policy governs. We recommend a precedence layer that runs after access filtering and before generation: it takes the employee's scope from trusted systems, picks the governing document from metadata and explicit links, and stops with a named handoff when two governing documents remain. Then run the same check offline, across every scope your company has, so you find the conflicts before a new hire does.
Retrieval finds candidates; it does not rank their authority
A new hire asks how to approve an expense. The company brain finds a current finance policy, an old team checklist and a regional exception. Semantic search ranks all three highly because they use the same words, and a procedure written for one country can look more relevant than the global policy. The model then receives evidence with no hierarchy and may pick the most detailed passage, merge the passages or hedge between them. A larger prompt keeps the conflict and makes the wrong answer sound more convincing.
Retrieval also returns whatever is still in the index. The AWS explanation of retrieval augmented generation advises updating documents and their embeddings asynchronously, through real-time processing or periodic batches. For policies, add a rule: when a document is superseded, that update must take it out of ordinary retrieval, or the replaced page keeps competing with its replacement.
Access control comes first. A conflict resolver must compare only documents the employee may open. It must not reveal that a restricted policy exists, quote it during comparison or let it shape the answer. Microsoft's document-level access guidance for Azure AI Search notes that filtering inside the search pipeline is faster than loading a larger result set into your application and trimming there. A resolver adds a second reason: anything that reaches the application can influence the comparison, so restricted policies must never reach it.
Make authority a metadata field
Create a small metadata contract for every source that can support an onboarding answer, and record it when content is published or ingested. Do not ask the model to infer these fields from writing style.
document_id: expense-policy-uk-v5
document_type: policy
policy_domain: expenses
jurisdiction: united-kingdom
audience_groups:
- all-uk-employees
owner: finance-operations
approver: chief-financial-officer
effective_from: 2026-06-01
expires_at: null
supersedes:
- expense-policy-uk-v4
status: approved
source_url: /handbook/finance/uk-expenses
last_reviewed_at: 2026-06-01The minimum useful fields are domain, scope, owner, approval state, effective date, replacement relationship and access policy. Add jurisdiction, employment type, business unit or product line only when the attribute changes which rule governs the employee. If your wiki already assigns a reviewer to each page, reuse that field as owner instead of building a second ownership list. Kipwise's guide to keeping a knowledge base up to date describes that setup: one named reviewer per page, with review intervals only on the pages people rely on. Store the approver separately when your governance model needs another person to approve an exception.
Document type sets the default order. A chat message may clarify an incident, but it should not silently override an approved policy, and recency alone is not authority: a new team note can be less authoritative than an older approved policy. Start from this order:
- Approved policy for the employee's applicable scope
- Approved exception that names that policy and scope
- Current procedure linked to the governing policy
- Current onboarding task or checklist linked to the procedure
- Informal guidance, used for discovery and never as the sole authority
This is an implementation rule, not a legal hierarchy. People operations, legal, security and each policy owner should approve the order for their domains. One layer sits above the list and outside the assistant: the employee's own signed terms and the law where they work. A handbook paragraph on leave, notice or working time may differ from a hire's offer, and the assistant should not decide which wins. For those topics, add a line to the answer: your contract may set different terms, and HR can confirm which applies to you.
Resolve scope from trusted systems
Determine the employee's context from trusted systems before retrieval: location, legal entity, department, employment type, role and start date. A chat prompt must not override identity or HR records. Suppose a new salesperson in London asks, "How much can I spend on a client dinner?" The resolver converts the question into a policy domain and trusted context:
{
"policy_domain": "expenses",
"user_context": {
"legal_entity": "example-uk-ltd",
"location": "united-kingdom",
"department": "sales",
"employment_type": "employee",
"groups": ["all-employees", "uk-employees", "sales"]
},
"as_of": "2026-07-27"
}Use the group list to enforce access, legal entity, location and employment type to select the applicable policy scope, and the question and department to improve relevance. Keeping those jobs separate stops a highly relevant restricted page from entering the candidate set. Real onboarding programs show why scope cannot be one list: the GitLab onboarding handbook keeps its employment templates by country and role. A company brain should preserve those relationships and know whether a page is an onboarding aid, a procedure or the governing rule.
Apply the precedence sequence
Run conflict resolution after authorization filtering and before answer generation:
def resolve_policy(question, user):
context = load_trusted_user_context(user)
candidates = retrieve(question, domain=domain_of(question), access_filter=context.groups)
candidates = keep_effective(candidates, today())
candidates = keep_applicable_scope(candidates, context)
governing = select_approved_policy(candidates)
if not governing:
return escalate_no_source(question, context)
if len(governing) > 1:
return escalate_conflict(governing, question, context)
policy = governing[0]
exceptions = select_applicable_exceptions(candidates, policy)
supporting = select_linked_procedures(candidates, policy)
if supporting_contradicts(policy, supporting):
flag_for_owner_review(supporting)
supporting = remove_contradictory(supporting)
return generate_cited_answer(policy, exceptions, supporting)First remove documents that are not effective on the answer date. An expired document can stay in the archive without staying eligible for ordinary retrieval. Next apply scope. A global policy and a country exception may both be valid, but the exception must name the rule it changes. Do not assume that a more specific page overrides a broad policy unless your metadata says so.
Then follow explicit relationships. supersedes, exception_to and implements are more reliable than text similarity: if the current procedure links to policy version 5, an old checklist linked to version 4 should not support the answer. Two approved, effective policies in the same domain and scope are a governance defect and not a ranking problem, so stop generation and route both to a person who can decide.
Name an arbiter before the first conflict
A conflict between documents with different owners has no natural recipient. If Finance owns the policy and a regional HR lead owns the exception, a ticket addressed to "the owner" bounces between two people who each believe their document governs. We recommend writing one arbiter per policy domain into your metadata, a role and not a person, who decides conflicts across owners and records the decision as a change to one of the documents. The NIST AI Risk Management Framework asks for the same clarity about AI risk under GOVERN 2.1: roles, responsibilities and lines of communication are documented and clear to individuals and teams throughout the organization. A decision that stays in the ticket leaves the next hire exposed to the same contradiction, so the arbiter closes the ticket only after the source metadata or content has changed. Repeated conflicts go to a maintenance queue.
Give new hires an answer they can inspect
A resolved answer states the applicable rule, the scope that made it applicable and the source, and separates mandatory policy from practical steps. For example:
For UK sales employees, client dinners up to the approved regional limit require manager approval in the expense system. This answer uses the UK expense policy effective 1 June 2026. Follow the linked submission procedure for receipt and cost center requirements.
Show the policy title, effective date, owner and direct link beside the answer, and cite a contributing procedure separately, so the employee sees that the rule and the workflow come from different documents. Skip synthetic confidence percentages unless real evaluations have calibrated them; use a status the system can verify instead: resolved, resolved with an applicable exception, or unresolved and escalated.
An unresolved answer should be useful without exposing restricted evidence. Tell the employee what is known, what remains unclear, who owns the decision and when to expect a response:
I found two current expense documents that may govern this request, so I cannot confirm the limit. I sent the question and the permitted source references to Finance Operations. Do not submit the expense until the owner confirms which policy applies.
The escalation record holds the question, the employee context needed for scope, the permitted candidate document IDs, the conflict reason and the assigned owner. Do not copy restricted passages into a ticket the employee can view.
Find the conflicts before the hire does
Scope fields are closed sets: a handful of legal entities, countries and employment types. That makes the conflict check enumerable. Build one synthetic profile for each combination in use, run your thirty most common onboarding questions against each, and list every domain where two approved, effective documents match the same scope. With four legal entities and three employment types that is 360 runs, which is cheap next to a new hire acting on the wrong limit. Each hit is a governance defect to fix at the source, and the runtime resolver still stops and escalates, but a new hire should rarely be the one who triggers it. Repeat the sweep whenever a policy change adds a scope.
Then keep a fixture set for regression. Each fixture holds the question, trusted user context, candidate sources, expected governing document, expected citations and expected action. Cover at least these cases:
- a current policy and an expired predecessor;
- a global policy and an explicit regional exception;
- a policy and a procedure that uses outdated limits;
- two current approved policies with the same scope;
- a relevant restricted policy and a less relevant permitted policy;
- a checklist that links to a superseded procedure;
- a question with no approved governing source.
For every case, verify that unauthorized documents never enter the generation context, the expected source wins only through metadata and relationships, the answer cites the rule separately from the procedure, and an unresolved conflict creates an owner task instead of a guess. Track conflict rate by policy domain, time to owner resolution and the share of answers backed by an approved governing source. Review samples of resolved answers as well as escalations, because a low escalation rate is not success if the system quietly chooses the wrong policy.
Pick the domain where a wrong answer hurts
Choose a domain such as expenses, access requests, leave or security reporting. Define its authority order, scope fields, owner, approver and arbiter, add five conflict fixtures, and refuse generation whenever two governing sources remain. If your team cannot decide outside the model which document governs each employee scope, the model should not decide it for a new hire.


-p-1080.jpg)
