Reality — the failure catalog you will walk into
Why RAG fails in production
Build enough to be dangerous
Why this matters for a delivery manager
This is the day that makes you more useful than a solutions engineer who has only done happy-path POCs. Production RAG fails in operations: who updates the index, who owns a wrong answer, what happens when a policy is superseded at 4pm. That is a delivery manager's native terrain.
The catalog is not a scare list. It is the RAID you should have written before the CEO demo. Stale and conflicting SOPs, ACL leaks, junk chunks, builder-written evals, citation theatre, no knowledge owner, cost at 10× — each row has a symptom, a cause, and a delivery move. If you cannot fill the move, you are not ready to ingest.
The practice is eight RAID rows and a six-sentence no-go memo for 'all of Confluence in two weeks.' Calm, specific, with a thinner slice. Keep both for day 21 and for interviews. People who have been burned by a wiki bot will recognize the memo. That is the point.
You will be able to
- Name the top failure modes: stale index, ACL leaks, junk ingest, eval-on-demo-questions, citation theatre
- Write mitigations as RAID items, not as 'we'll monitor'
- Design a re-index and ownership model
- Practice saying no to a corpus that is not ready
2-hour clock
120:00
Now: Read the failure catalog · 50m
The 2-hour session
Concepts, in full
This block is a slow read — about an hour with the diagrams. After each concept, write one sentence in notes (what you already do vs what is new) and tick annotated. Do not skim the last concept.
01
Stale, duplicate, and conflicting truth
Wikis contain the 2019 SOP and the 2024 SOP. Vector search will happily retrieve both. The generator will average them into a new policy that never existed. That averaged policy will be fluent, cited (badly), and wrong. Mitigation is not 'we'll tell the model to prefer recent.' Mitigation is metadata dates, a prefer-latest rule in retrieve, deprecation flags, and a knowledge owner who archives. If nobody archives, the index is a museum and a trap.
Duplicates are the quiet version. The same SOP pasted into three spaces, a PDF and a wiki page, an email attachment that became a page. Hybrid search returns three near-copies, k is used up, the actual exception clause in a fourth document never appears. De-duplicate at ingest by canonical URL or content hash. Retrieval that cannot say 'this is the same document' is how recall looks fine on paper (the gold is in the index five times) and fails in practice (the useful neighbor was crowded out).
Conflicting truth is a knowledge problem first. Two teams published opposite rules. The bot is the messenger. Your delivery move is to surface the conflict: retrieve both, show both dates, refuse to pick, name the owner who must archive one. Hoping the generator 'picks the latest' is how you launder a governance failure through a chatbot and then get blamed for the chatbot.
Re-index is a job with an SLA, not a cron nobody watches. When a source changes, either event-driven update or a documented lag ('answers may be 24h stale') that the UI shows. Silent staleness is how you get a 'the bot said we still do X' incident. The SLA has a number, an owner, a probe (a canary document you change and then query), and a page in the runbook for 'the connector died.'
Supersession at 4pm is the test. Policy owner updates SOP-14. Who notices. Who upserts. Who invalidates the old vectors. Who tells the UI. If the answer is 'nightly job, maybe,' then for 18 hours you will retrieve the old rule. For some corpora that is acceptable if printed. For safety, access, or customer commitments, it is not. Say which class this corpus is before you agree to nightly.
Versioned documents need a retrieve rule: current only, unless the user asks for history. Default current. Store archived chunks with a flag and a date, do not delete immediately (you will want history for audit), but do not let them into the default top-k. The stale-trap row in yesterday's eval exists to catch this. If that row fails, you do not have a date policy. You have a pile.
RAID this as: 'Index serves superseded SOP as current.' Impact: wrong operational guidance, possible compliance event. Owner: knowledge owner + index engineer. Trigger: canary page not reflected within SLA, or two current docs disagree. Mitigation: dates, deprecation, prefer-latest, UI lag banner, archive workflow. That is a row. 'We'll monitor' is not.
Stale, duplicate, and conflicting truth are knowledge problems wearing a chatbot. Dates, prefer-latest, deprecation flags, de-duplication by canonical URL or hash, a retrieve rule that defaults to current, and a knowledge owner who archives — those are the moves. Re-index is a job with an SLA, a canary document, and a UI banner when lag is real. Silent staleness is an incident class. Supersession at 4pm is the test; if the answer is 'nightly, maybe,' say which corpus class can tolerate that before you agree. Hoping the generator picks the latest is how you launder a governance failure through a bot and then get blamed for the bot. Surface the conflict. Refuse to pick. Name the owner. That is delivery. Averaging two SOPs into a third policy that never existed is not.
| Row | Statement | Trigger you can observe | Mitigation |
|---|---|---|---|
| Stale current | Index serves a superseded SOP as current | Canary page not reflected within SLA | Event-driven upsert or printed lag; prefer-latest; UI banner |
| Duplicate | Same SOP in three spaces crowds out the exception clause | Top-5 are near-copies of one heading | Canonical URL / hash at ingest; de-dupe before retrieve |
| Conflict | Two current SOPs disagree; bot averages them | Two 'current' docs for one question in eval | Surface both dates, refuse to pick, owner archives one |
| Connector dead | Silent staleness while the job looks 'green' | Canary probe fails or lag exceeds SLA | Runbook: banner vs go dark; named owner; page the connector |
| No archive | 2019 and 2024 both retrieve as if live | Stale-trap eval row fails | Deprecation flag; default filter archived=false; knowledge owner |
Re-index and stale-truth RAID — paste into the practice table and put names in the owner column
02
ACL leaks are a career-class incident
If the index was built with a service account that can see everything, retrieval will return the CEO's folder to an intern. Filter by the user's identity at query time, or maintain per-permission indexes. This is not a v2 item. It is a go-live item or you do not go live. A wrong paragraph is an error. A retrieval leak is a data incident, often worse.
The leak flow is simple and it keeps happening. Connector authenticates as a god account so ingest is 'easy.' Chunks are stored without permission groups, or with a group that means 'everyone in the tenant.' Query time uses the same god account. The intern asks a question that happens to be close, in meaning-space, to a strategy deck. The generator cites it. Screenshot in Slack. Now you have a problem that is not 'the answer was a bit off.'
Consumer chat UIs that 'just upload the drive' fail this test by construction. Enterprise search teams already know permission-aware retrieval. Invite them before you invent a worse version. If your company has an existing search ACL model, reuse it. Do not build a parallel permission universe because the vector DB tutorial did not mention users.
Query-time filtering is the usual pattern: every chunk carries a permission group (or ACL list). The request carries the user's groups from SSO. The index query includes a filter: permission in user_groups. Miss a group, you over-block (annoying, visible). Miss the filter, you leak (quiet, career-class). Over-blocking is the correct failure direction. Users will complain. Good. Complaints are cheaper than leaks.
Citations inherit ACL, as of yesterday. A deep-link that bypasses the wiki's own permissions is the leak with extra steps. The click goes through the same check. Cached pages, 'shared demo tenants,' exported PDFs of the index — all side doors. Side doors are in scope for security review. If security is not in the RACI, add them before ingest, not after the intern's screenshot.
POCs often index a copy of production with ACLs stripped 'to make it work.' That copy becomes the production pattern because it was easier, and because the demo went well. Kill it in writing. The no-go memo later today includes this sentence: we will not go live on a corpus whose permissions are not the production permissions. If the POC cannot work with ACLs on, the POC is lying about readiness.
Test the leak. Pick a user who should not see folder F. Ask a question whose gold lives only in F. Success: refuse or empty, not a redacted hint, not a title leak in the citation list. Title leaks count. 'I cannot show you the CEO_comp_review.pdf' is still a leak of existence and name. Eval this. Do not assume the filter works because the engineer said it was on.
ACL leaks are career-class because they are data incidents, not wrong paragraphs. God-account ingest plus query-as-service plus a citation is the flow; an intern plus a screenshot is the end. Query-time filter on the user's SSO groups, citations that inherit the same check, over-block rather than leak, leak-test as a go-live gate, no stripped-ACL POC that becomes production. Title leaks count. Invite enterprise search before you invent a worse permission universe because a vector tutorial skipped users. Kill the shared demo tenant in writing. If the POC cannot work with ACLs on, the POC is lying about readiness. This is not v2. This is go-live or you do not go live. Write that in the no-go even if it makes the date slip. Dates slip. Careers do not un-slip.
Diagram
The ACL leak, start to screenshot
God-account ingest
Connector uses a service principal that can read every space. Convenient. Fatal if it defines production.
Chunks without user ACL
Index stores text and source, not permission group — or stores 'all-tenant.'
Query as the service
Retrieve does not filter by the caller's SSO groups. Nearest neighbors include the CEO folder.
Generator cites it
Fluent answer, maybe a filename in the footer. Looks like a good demo.
Screenshot / share
Existence leak or content leak. Now it is a data incident, not a model-quality ticket.
Every arrow is a choice you can refuse. The POC that strips ACLs 'to make it work' is arrow one. Kill it in writing.
03
Garbage in, fluent garbage out
Nav chrome, cookie banners, 'click here,' scanned PDFs with no OCR, Excel dumps, meeting notes with no decision. Ingest must drop or flag these. A delivery lead can demand a sample of 20 chunks on a slide before funding the rest of ingest. If the sample contains a cookie banner, the index will retrieve a cookie banner, and the generator will quote it as policy. That is funny once. It is not funny in steering.
OCR and scans are a workstream. If half the SOPs are pictures of pages, you do not have a RAG corpus. You have a scanning project. Name it. Budget it. Do not hide it inside 'we'll embed Confluence.' Unreadable text still gets a vector. The vector is a vector of garbage. Neighbors of garbage are more garbage.
Meeting notes without decisions are a corpus smell. They retrieve well for 'what did we talk about' and badly for 'what did we decide.' If you index them, tag them as notes, not as SOP, and teach retrieve to prefer decision logs for decision questions. Better: do not index them in v1. Non-goal it. The knowledge owner will thank you when the bot stops quoting a joke from standup as a rule.
Eval questions written by the builder are too kind. Sit with three actual users and harvest questions from their last week of Slack. That set will hurt. Good. Demo-only evals are how you get 90% on the slide and 40% on Monday. Put 'eval set source: builders vs users' on the RAID. Trigger: more than half the questions originated in the demo script.
Junk also includes secrets that should never have been in the wiki: keys, customer lists, pastes from ticketing. Ingest is a chance to detect and drop, not a chance to vectorize a password. If you find secrets, you rotate them and you tell security. You do not 'just skip that page' quietly. The page is still in the wiki, and the next connector will find it.
A chunk quality gate is allowed: drop chunks below N characters, drop chunks that are >80% boilerplate, flag chunks with no heading. You will over-drop at first. That is the correct direction, same as ACL over-block. Adding a page back is easy. Explaining why the bot cited 'Skip to content' is not.
RAID this as: 'Index is fluent junk.' Impact: user distrust, steering mockery, silent wrong answers. Owner: knowledge owner on corpus hygiene, engineer on drop rules. Trigger: sample of 20 chunks fails review; cookie banner in a citation. Mitigation: sample gate before ingest scale-up, drop lists, OCR workstream or out-of-scope.
Fluent garbage is a sample-gate failure. Twenty chunks on a slide before ingest scale-up. Drop nav, cookies, empty scans, meeting notes with no decision if v1 cannot tag them. OCR is a workstream or it is out of scope — it is not hidden inside 'we'll embed Confluence.' Secrets found at ingest are rotated and reported, not quietly skipped. Builder-written evals are too kind; harvest from users. A chunk quality gate that over-drops is the correct direction, same as ACL over-block. Adding a page back is easy. Explaining why the bot cited 'Skip to content' in steering is not. Demand the sample. Fund ingest only after it passes. That one habit prevents a quarter of the catalog on this page.
04
Citation theatre and over-promise
The UI shows a source; the sentence came from the model's prior. Groundedness evals catch this. So does a 'click the source and see the highlight' UX. If you cannot highlight, you cannot claim citation. Theatre is worse than no citation because it trains users and auditors to trust the footnote. A missing footnote at least looks unfinished.
Models learn to sprinkle [S1] because you asked. They will sprinkle it on a sentence the chunk does not support. Claim-level eval, two columns: grounded, cited-right. A score that only checks 'did any source id appear' is how theatre gets a green dashboard. Require the id to match the chunk that holds the claim, or mark it fail.
Over-promise is the sponsor version of theatre. 'The bot will just know.' Your no-go memo exists to kill that sentence: we will not index personal drives, we will not answer HR case questions, we will not skip ACLs, we will not go live with recall@5 under the agreed bar, we will not RAG the ERP. Each 'will not' is a steering slide. People remember the demo. They need the memo in the same pack.
Helpful tone makes theatre worse. A refuse that sounds ashamed will be patched by a product manager into a guess. Keep the refuse sentence plain. Do not apologize the model into improvising. UX can offer 'ask a human' or 'request ingest' without offering a made-up clause.
Screenshot culture is part of the threat model. Users will paste the answer into a ticket as if it were policy. The footer 'this is not a decision' is not legal magic, but it is a speed bump and it is evidence you warned them. Combine it with citations that actually open. Combine it with an owner of wrong answers (who the user writes to). If nobody owns a wrong answer, every wrong answer becomes your personal incident.
Vendor claims ('grounded by design,' 'citations included') are not evals. Ask for the split numbers on your questions. If they will not run your 10-question table, they are not ready, or they know something about their retrieve they do not want on a slide. Either way you run the eval.
RAID this as: 'UI cites sources that do not support the sentence.' Impact: false trust, audit failure, possible customer commitment on invented policy. Owner: you on eval, engineer on highlight UX, product on footer. Trigger: groundedness or citation-correctness below bar on the frozen set. Mitigation: claim-level eval, highlight-or-no-cite rule, refuse sentence frozen, no-go if bar not met.
Citation theatre is a footer that does not support the sentence. Catch it with claim-level groundedness, a cited-right column, and highlight-or-no-cite. A score that only checks whether any source id appeared is how theatre gets a green dashboard. Helpful tone makes it worse; keep refuse plain. Screenshot culture means users will paste the answer as policy — footer, real citations, and an owner of wrong answers are the speed bumps. Vendor 'grounded by design' is not your eval. Over-promise is the sponsor version of theatre; the no-go memo exists to kill 'the bot will just know.' If you cannot highlight, you cannot claim citation. If you claim it anyway, you trained the auditor.
05
The no-go memo and the thinner slice
Saying no is the job. The form is a short memo, not a fight. Six sentences is enough: what was asked, why it is not ready, the conditions to proceed, the thinner slice you will do instead, who owns the corpus, when you re-evaluate. Calm. Specific. No adjectives about 'reckless' or 'transformational.' Steering can hear this. They cannot hear a rant.
What was asked: 'Index all of Confluence in two weeks and demo to the CEO.' Why not: no knowledge owner, ACLs would be stripped or ignored to hit the date, no user-written eval, ingest would include HR-adjacent spaces, re-index SLA unnamed, citation UX would be a filename footer. You do not need all of those to be true. Two are enough to no-go. List the ones that are true.
Conditions to proceed: named owner, ACLs on, one space, sample of 20 chunks reviewed, 40 eval questions harvested from real PMs (10 is the design floor; 40 is a live bar), recall@5 at agreed number, groundedness on 20 answers, refuse path visible, retention and logging signed by Legal. This is not bureaucracy. This is the thinnest set that prevents the catalog above.
Thinner slice: Atlas space, SOPs + decision log + RAID, PMs only, read-only, citations that open H2, 24h lag printed, no personal drives, no finance folders, no writes. Demo to the sponsor of Atlas, not to the CEO, until the eval bar holds for two weeks. The slice should still be impressive if the wiki is real. If the only impressive demo is 'everything,' the corpus is the problem.
Who owns the corpus: a named role, not 'the PMO.' If you cannot name them, that is row 9 in the RAID and it is sufficient to no-go by itself. Unowned wikis do not become owned because you added vectors. They become higher-confidence unowned wikis.
When you re-evaluate: a date. Conditions are either met or they are not. Do not leave a floating 'when ingest is ready.' Ready means the conditions. Dates make owners move. Floating readiness makes you the blocker in other people's stories.
Tone: you are protecting the sponsor from a screenshot. You are not blocking innovation. Offer the slice in the same memo so the energy has a place to go. People who only say no get routed around. People who say 'not this; this, by this date, with these gates' stay in the room.
The no-go memo is six sentences: what was asked, why not, conditions to proceed, thinner slice, named owner, re-evaluate date. Calm. Specific. No adjectives. Offer the slice in the same memo so the energy has a place to go. People who only say no get routed around. People who say 'not this; this, by this date, with these gates' stay in the room. If you cannot name the knowledge owner, that alone is sufficient to no-go. Unowned wikis do not become owned because you added vectors. They become higher-confidence unowned wikis. Write the memo as if you will send it. You will, or you will wish you had. Keep it for day 21 and for interviews. People who have been burned by a wiki bot will recognize it. That is the point of the day.
06
Re-index, ownership, and the RAID you actually run
The practice wants eight rows. Use the catalog: stale docs, ACL, junk chunks, conflicting SOPs, no owner, demo-only eval, citation theatre, cost at 10×. Each row: statement, impact, owner, trigger, mitigation. Triggers are observable (canary lag, leak-test fail, sample-chunk review fail, recall@5 drop, spend > envelope). If the trigger is 'we'll know it when we see it,' you wrote a worry, not a RAID item.
Cost at 10× belongs even if the POC is tiny. Embed plus generate plus re-embed on churn. A busy wiki re-indexed on every save can cost more than chat. Put a cap and a kill switch (day 9) in the same row. Finance will not be kinder because the spend was 'just tokens.'
Ownership model: knowledge owner (corpus current, in-scope, conflicts archived), platform owner (index, SLA, ACLs as implemented), delivery lead (evals, go-live, RAID), security (permission model, leak test), Legal (logs, retention). Write the names. If two boxes share a name, fine. If a box has no name, that box is the no-go.
Wrong-answer ownership is a row people skip. When the bot is wrong, who does the user tell, who patches the corpus or the prompt, in what SLA. If the answer is 'file a ticket to the AI team,' you will drown and the corpus will not improve. Route corpus errors to the knowledge owner. Route product errors to you. Publish that.
Re-index runbook: connector health probe, canary document, lag banner, what we do if Confluence API rate-limits, what we do if embedder is down (serve stale with banner vs go dark). Dark is allowed. Silent stale is not. Pick per corpus class.
You will reuse this RAID on day 14 and day 21. Write it as if someone else has to run it next quarter. That is the quality bar. Cute shorthand ('ACL!!') is not a row.
If the program still wants the CEO demo on the original date, the memo plus the RAID is what you send. You do not quietly strip ACLs to be a team player. That is the whole day.
Eight RAID rows, triggers you can observe, owners as hats, a re-index runbook, a wrong-answer route that does not dump every complaint on 'the AI team,' and cost at 10x with a kill switch. If the trigger is 'we'll know it when we see it,' you wrote a worry. If a box has no name, that box is the no-go. You will reuse this RAID on day 14 and day 21. Write it as if someone else has to run it next quarter. Cute shorthand is not a row. If the program still wants the CEO demo on the original date, the memo plus the RAID is what you send. You do not quietly strip ACLs to be a team player. That sentence is the whole day, and it is the reason a delivery manager is in this workstream at all.
Diagram
RAG failure catalog — symptom, cause, delivery move
| Symptom | Cause | Delivery move | |
|---|---|---|---|
| Stale / conflict | Bot teaches a superseded SOP, or averages two | No dates, no archive, nightly hope | Prefer-latest, deprecation flag, canary SLA, owner archives |
| ACL leak | Intern sees CEO folder; title leak in citations | God-account ingest; no query filter | Query-time ACL, leak-test eval, ACLs on in the POC |
| Junk ingest | Cookie banner cited as policy | No sample gate, scans without OCR | 20-chunk review, drop rules, OCR workstream or out-of-scope |
| Demo eval | 90% on the slide, 40% on Monday | Builder-written happy-path questions | Harvest from users; include empty, ID, table, stale trap |
| Citation theatre | Footer source does not support the sentence | No claim-level eval; no highlight | Groundedness + cited-right; highlight-or-no-cite |
| No owner | Nobody archives; nobody takes a wrong answer | RACI says 'AI team' | Named knowledge owner or no-go; wrong-answer route published |
Steal the rows into RAID. The move is a control with an owner, not 'we'll monitor.' Empty move means no-go.
Worked case · stay here ~20 minutes
The ACL leak that did not quite happen
Wednesday, 4:10 p.m. Atlas POC. Priya is preparing a demo for an intern-heavy office hours tomorrow. She indexed the Confluence export with a service principal that can read every space, so ingest is easy. You sit down to try three questions as a PM. The third one is a trap you brought: a question whose gold lives only in the CEO staff folder. The citation list paints the filename before you hit send.
You are not trying to be clever. You are doing the leak-test this morning's concept told you to do before anyone else does it by accident. Account: a PM identity, not Priya's god account. Question: what did the board decide about the Orion divestiture. Gold lives in a CEO staff space that Atlas PMs cannot open in Confluence. You watch the retrieve panel because Priya left debug on. Top hit: a board-divestiture PDF in a CEO-staff path, score 0.81. The citation chip is already rendered, filename visible, before generate runs. You do not send. You take a screenshot of the retrieve panel only, for the ticket, not for Slack. Title leak. Existence leak. The intern tomorrow would have had a chip they could screenshot even if generate refused. That is the incident, already, if this were production. It is not production. It is a POC that was about to teach twenty people the wrong permission model. You have tonight. You close the debug panel before anyone walks in behind you. Then you write the filename on paper, not in a channel the intern is in.
The flow is the one on today's diagram, and seeing it in a panel does not make it theoretical. Connector authenticated as a service principal that can read every space. Chunks stored with source path and text, permission group either missing or set to all-tenant. Query ran as the service, not as the PM. Nearest neighbors included the CEO folder because meaning-space does not know who you are. Generator would have cited it, fluently, maybe with a hedge. Screenshot. Data incident, not a quality ticket. Priya's reason is the usual: ACLs made the connector fail on some pages, the tutorial did not mention users, the demo tenant is a copy with permissions stripped so it would work. That copy is about to become the architecture because office hours would have gone well. You kill it in writing before 5 p.m. If the POC cannot work with ACLs on, the POC is lying about readiness. Say that to Priya first, not to Marcus, so she can be in the sentence when you tell him. She is not the villain. The god account is. Convenience is.
Query-time filtering is the pattern you name so the fix is not 'we will prompt the model not to mention CEO files.' Every chunk carries a permission group from Confluence. The request carries the user's groups from SSO. The index query includes permission in user_groups. Miss a group, you over-block, which is annoying and visible. Miss the filter, you leak, which is quiet and career-class. Over-blocking is the correct failure direction. Users will complain. Good. Complaints are cheaper than leaks. Citations inherit the same check. A deep-link that dumps a document the user could not retrieve is the leak with extra steps. Cached pages, shared demo tenants, exported PDFs of the index are side doors, and side doors are in scope for security. Security is not in the RACI. You add them before office hours, not after an intern's screenshot. Enterprise search already knows permission-aware retrieval. Invite them. Do not invent a worse universe because a vector tutorial skipped users. Priya can add a filter this evening if the chunks have a group. They do not. That is the ingest bug.
You run the rest of the leak-test while the index is still dirty, so you know the shape of the failure. Same PM user. Question whose gold is only in folder F: refuse or empty, no title in the citation list, no filename in the trace the UI shows. Today: fail, fail, fail. Second user: you, with Atlas access. Same question: still should refuse, because you are not in CEO staff either. Third: Priya's admin identity. The file may appear. That is not a pass for the product; that is a pass for admin debug, and admin debug should not be the office-hours path. You also try a question that is in Atlas and should hit. If turning ACLs on would make the happy path empty because ingest never stored groups, that is information: the POC has been demoing a lie. Better to find it Wednesday. Write the three rows as eval, not as a scare. Success criteria in one line: user who should not see F does not see F's titles, snippets, or embeddings-derived hedges. Redacted hints count. I cannot show you the CEO file counts.
Marcus gets a short message, not a novel. We are not running office hours tomorrow. The POC index was built with a service account and no query-time ACL. A PM query surfaced a CEO-staff filename in the citation list. We will not go live, and we will not demo, on a corpus whose permissions are not the production permissions. Restart ingest with groups, filter at query, leak-test with a user who should not see folder F, Security in the RACI. Thinner slice still Atlas, PMs, ACLs on. I need Priya and a search-platform owner tomorrow morning. He will be angry about the intern event. Let him. He would have been a different kind of angry if the intern had the chip. You attach the screenshot of the retrieve panel, cropped to the filename and the user identity, no document body. You do not attach the PDF. You do not put the filename in Slack beyond the people who already have Confluence access to that space. If they do not, you write a space outside Atlas and you show him in a room. Need-to-know applies to your incident report.
Priya wants to just filter the demo questions so office hours can proceed, and to fix ACL next sprint. That is how the stripped tenant becomes production. You say no, twice, once to the filter-the-questions idea and once to next sprint. Leak-test is a go-live gate and a go-demo gate. A wrong paragraph is an error. A retrieval leak is a data incident, often worse. The intern event is a demo, which is a distribution channel. Twenty people plus laptops plus Slack is a publication. You will not be a team player by publishing a CEO filename. She can have a demo tomorrow if we re-ingest Atlas-only, with groups, and the leak-test passes on a throwaway user. That is an evening. It is not a sprint. If groups cannot be pulled by morning, office hours slips. Dates slip. Careers do not un-slip. You offer to sit with her on the connector, not to write the filter yourself unless you are FDE-shaped and you actually can. Pairing is fine. Quietly editing the demo set so the intern only asks Atlas questions is not pairing. It is hiding. Name it.
Security's first question, when they join Thursday, will be who can query the logs. The retrieve panel you screenshot lives in a debug UI that half the engineering Slack can open. Prompt logs and traces are often wider than the source ACL. A platform team, a vendor success manager, and an observability tool can all see text the page owner never approved. You put those audiences on a one-box diagram: user, app, index, logs, vendor. The leak was in the index, but the screenshot was a log-shaped object. Retention, accessors, redaction — day 9's table — come back as the same incident class. If Legal cannot answer DSAR from your page, you will answer it from a panic. Do this once per program. Features inherit. A copilot that logs to the shared bucket because the last app did is how you build a second CRM with worse ACLs. You already knew not to put passwords in the RAID. Prompt logs and retrieved chunks are closer to email. Treat them that way in the write-up. Security will hear you if you sound like you have done incidents. You have.
Re-ingest is a job with a spec, not a hope that the connector supports ACL. Pull Atlas space only. Drop CEO, HR, finance, personal drives at the connector, not in a prompt. Store permission group on every chunk. Fail ingest on a page with no group rather than defaulting to all-tenant. Query filter required in code review, with a test: user U, folder F, question Q, expect empty. Canary: a page only U2 can see, queried as U1, must not appear, including title. Priya wants to keep the old index around for comparison. Quarantine it, do not serve it, delete it when the new one passes. Comparison against a leaking index is how someone points the UI at the old collection because recall looked better, which it did, because it could see everything. Recall at 5 on a god index is a vanity number. Report recall only on the permissioned path, even if the number drops. The drop is the truth. The old number was a lie you were about to put on a slide for interns. Write that in the RAID: eval measured on ACL-stripped index.
The no-go memo you were going to write as homework writes itself, and you send a six-sentence version tonight. You asked to index broadly so the intern demo would feel smart. We will not. The index was built with a god account, ACLs were off, and a PM query leaked a filename from a space outside Atlas. Conditions to proceed: named knowledge owner, ACLs on, query-time filter, leak-test passing, sample chunks reviewed, Security on the RACI. Instead we will RAG the Atlas space for PMs, read-only, with citations, after the leak-test holds. I need a search-platform owner named by Thursday noon or the slice does not restart. Calm. Specific. No adjectives about reckless. Offer the slice so the energy has a place to go. People who only say no get routed around. People who say not this, this, by this date, with these gates, stay in the room. You just earned the room by catching the chip. Do not spend the earning on a rant. Spend it on the gate. Marcus can cancel office hours. That is the cost of the catch. It is a cheap cost.
Office hours, if it happens Friday, is a different product. Atlas questions only, ACLs on, leak-test shown once at the start as a feature: watch us ask something we should not see; we should get a refuse and no filename. That demo is more impressive to anyone who has been burned than a fluent plant. If the room is intern-heavy, say title leaks count, do not paste answers into Slack as policy, footer is not-a-decision. You are not being a schoolteacher. You are setting the threat model. Screenshot culture is how this near-miss would have left the building. The footer is a speed bump. Real citations that fail closed are the control. An owner of wrong answers — the PMO lead — is the route. If nobody owns a wrong answer, every wrong answer becomes your personal incident, and every leak becomes yours too. Publish the route. Then let Priya drive. You do not need to be the hero in the room. You needed to be the person who closed the debug panel at 4:10. Already done. Sit down.
What you put in RAID before you leave: ACL leak, statement PM retrieve can see outside Atlas, including titles. Impact: data incident, regulator-class if the file is what its name says. Owner: Priya plus Security. Trigger: leak-test fail, or any citation chip from a space not in the in-scope list. Mitigation: query-time SSO filter, groups at ingest, fail-closed, leak-test in CI, no stripped tenant. Second row: god-account ingest. Third: debug UI wider than source ACL. Triggers observable. If the trigger is we will know it when we see it, you wrote a worry. You saw it. Write the trigger as the test you ran. You will reuse this RAID on day 14 and day 21. Write it as if someone else has to run it next quarter. Cute shorthand is not a row. If the program still wants the intern demo on the original morning, the memo plus the RAID is what you send. You do not quietly strip ACLs to be a team player. That sentence is the whole day. It is why a delivery manager is in this workstream at all. Send the rows.
The interview version is calm and specific, and it does not make Priya the punchline. POC index was built with a service account. A query as a PM showed a filename from a space the user could not open. We cancelled the demo, re-ingested with groups, put query-time ACL and a leak-test in as go-live gates, and added Security to the RACI. Title leaks count. We did not filter the question set to hide it. Interviewers who have shipped this will lean forward at title leaks count. That is the sentence that separates people who have read a blog from people who have sat in the 4 p.m. panel. If you have not sat there yet, you sat there in this case. Steal the test: user who should not see F, question whose gold is only in F, success is refuse and no title. Put it in every RAG design you write this month. If a vendor cannot run it, they are not ready, or they know something about their retrieve they do not want on a slide. Either way you run the test.
Diagram
Near-miss, 4:10 p.m. to a gate
Leak-test as a PM
Gold lives only in folder F. Retrieve panel shows F's filename. Do not send. Screenshot the panel, not the body.
Name the flow
God-account ingest, chunks without groups, query as the service, citation chip. Not a prompt problem.
Kill the demo
Office hours is a publication. Memo to Marcus. No stripped tenant. No next sprint.
Re-ingest fail-closed
Atlas only, groups required, query filter, canary user, burn the god-index numbers.
Leak-test in the pack
Go-live and go-demo gate. Title leaks count. Security on the RACI. RAID row with an observable trigger.
The chip on the retrieve panel is already the incident if this were production. Treat the POC as if it were, minus the press release.
Practice
RAG RAID + a no-go memo
45 minutesThe program wants to index 'all of Confluence' in two weeks and demo to the CEO.
- Write 8 RAID rows: stale docs, ACL, junk chunks, conflicting SOPs, no owner, demo-only eval, citation theatre, cost at 10×. Each: statement, impact, owner, trigger, mitigation.
- Write a six-sentence no-go / conditions-to-proceed memo to the sponsor. Calm, specific, with a thinner slice (one space, 200 pages, 40 eval questions, ACLs on).
- Name the knowledge owner. If you cannot, that is row 9.
Done looks like: A RAID table and a memo you would actually send. Keep both for day 21 and interviews.
Check yourself
Attempt in your notes first. Reveal is for after, not during.
What do you do when two SOPs conflict in the index?
Why are ACLs a go-live gate, not a v2?
Who should write the eval questions?
What is citation theatre?
What belongs in a six-sentence no-go?
What is a re-index SLA for?
Terms from this day
- Re-index SLA
- The promised maximum lag between a source changing and answers reflecting it.
- Permission-aware retrieval
- Retrieval that only returns chunks the current user is allowed to see.
- Knowledge owner
- The human accountable for whether a corpus is current, non-conflicting, and in-scope.
- Citation theatre
- Showing sources that do not actually support the generated sentence.
Your notes for day 12
Saved on this device. Use this as the start of the artifact.