# GATE E: PHASE 2, THE HUMAN GATE Rewritten in full, 30 July 2026, after the Gate A, C and D reruns. Earlier editions are superseded rather than appended to, because a gate document that grows by accretion stops being readable at exactly the moment it matters. **Gate E is not a file. It is you reading this and saying so.** This is written for you to read once and decide. It is not a summary of good news. --- ## The verdict, in one place | Gate | State | What it rests on | |---|---|---| | A, functional | **PASS** | 55 packages ok, 0 fail. 217 integration tests, 0 fail, 1 skip. | | B, stress | **PASS** | Every stress item with a control that failed first. 30 minute soak, 2,028,801 samples. | | C, visual | **PASS, one named limit** | 88 captures, 0 findings, both surfaces. Pixel baselines approved and proven both ways. | | D, drift | **PASS** | Engine frozen, schema level at 85 across three databases, production binary unchanged. | | E, human | **Yours** | This document. | **Four findings held Phase 2 open. All four are closed.** One by execution, two by your decisions, and the third by your decision after a bounded run proved everything on our side of the boundary. **Under your recorded conditional pre approval,** fully green with zero open findings closes Phase 2 on your word. I believe that condition is met. The three things worth weighing before you agree are in the next section, not buried at the bottom. --- ## Read these three before you agree **One. Gate C has a coverage limit and I will not describe it as a clean pass without saying so.** The authenticated sweep took 48 captures containing only **18 distinct images**. Both fixture accounts hold exactly one tool, slateMATCH, so `/command`, `/screen`, `/recruit` and `/compliance` all render the same "tool not enabled" panel. That is correct behaviour, and it means most routes were photographed as a denial rather than as a screen, so the assertion about screens not rendering empty states is not exercised on them. The fix is fixture data: an org holding all tools for screen coverage, plus these restricted accounts for RBAC coverage. Both passes, not one. **Two. The production API has not changed and Phase 2 has shipped nothing to it.** The binary hash is byte identical to the pre build value. Every Phase 2 route answers 404 in production while the control routes answer 200. Closing Phase 2 says the work is proven, not that customers have it. Deploying is a separate decision nobody has asked you for yet. **Three. Two things need you, and neither blocks the close.** The five API keys pasted into chat need rotating at their providers. And the OpenAI account has no credit, which is why finding three closed by decision rather than by an external run. --- ## What I got wrong, first, because it is the most useful part I told you Phase 2 should be able to finish and implied the gate reruns were a formality. They were not. **Gate A failed on the first rerun with seven failing integration tests**, and running the gates properly cost a night and found ten defects. Two had been live in production for days. **The earlier Gate A pass was not reliable and I withdrew it as evidence.** Three of the seven failures were in a setup step that updates `organizations` through the app role, and that role holds SELECT only on that table in **both** production and staging, by design. Those tests could never have passed against a correctly granted database, so the previous PASS was taken either without them or with different credentials. It is gone from the bundle rather than left standing. **The pixel half of Gate C never existed.** You approved the contact sheets and the approval unblocked nothing, because the code it was meant to unblock had never been written. Two Gate C write ups recorded the gap as "no contact sheet has been approved", which reads as waiting on you while it was waiting on me. That is the worst version of this mistake: it moves an engineering task into your queue, where nobody is going to work on it. **And a smaller one worth naming.** My first engine freeze check tonight ran against a guessed path holding zero files at both ends and returned a clean zero. That is finding D8 reproduced by me, weeks after I wrote the rule that catches it. It was caught only because the rule says to assert the path exists first. --- ## The two production defects **The embedding provider could not authenticate at all.** `embeddings.newMegamind` accepted an API key and never passed it to the client it built. So every embedding in this platform depended on a fifteen line node reverse proxy, belonging to another project, staying alive to inject the credential. Had it stopped, embedding would have broken with no recovery path from inside this codebase. The failure shape is the lesson. The unauthenticated call returned 401, the error was swallowed upstream, and the test reported **similarity 0**. It read as "the embedder has no semantics" when the cause was "the request was refused". A transport failure wearing the costume of a bad model score is the most misleading result in this build. **The gateway refused every teaching signal ever sent.** It validates craft signals against a registered scoring contract allowlist and never registered one, so `/v1/teach` answered 422 to everything regardless of what it named. **That is why `teaching_signal_aggregates` and `curation_proposals` are both empty: not unused, unreachable.** The learning loop's transport had been closed since the allowlist was introduced. It now registers the engine's version at boot and logs what it accepts, because an allowlist that silently refuses everything looks identical to one nobody is using. --- ## Why the suite could not see any of this The integration suite gates itself on optional environment variables. Run with defaults it executed **195 tests and silently omitted 22**. Nothing set `MM_MEGAMIND_URL`, so every test needing the inference plane skipped itself. **A test gated on an optional variable does not fail. It disappears.** Four of the six Gate A defects were only reachable once those tests ran. Supplying every variable took the suite from 195 passed with 23 skips to **217 passed with 1 skip**, and that one skip needs per tenant databases which do not exist because the work is unmerged. The same shape appeared in Gate C: the whole suite authenticated only because the URL happened to point at that token injecting proxy. It was proving the proxy works. --- ## The four findings **One, the wage determination.** Closed by your decision. A scanned or undecodable text layer is a graceful terminal state: stored, hashed, versioned, `no_text_layer` shown with both causes explained, zero chunks so nobody can cite noise. OCR is candidate P2. Writing that explanation exposed the screen lying about it. The failure code map had six keys, three matched nothing the extractor emits, and four real codes had no explanation at all, one of them the exact status the xlsx attachment carries. Fixed, with a cross language test that fails if the two vocabularies drift again. **Two, no office reader.** Closed by your decision for Phase 2. The reader is pre approved as Phase 3's single improvement item, so that slot is spent before Phase 3 starts. **Three, the external normalize path.** Closed by your decision, and the directive supports it in a way I read too strictly for two days: 5.3 says public notice text **may** use the external backend, and it requires the verifier gate returned prose *exactly as it does for local models*, which makes the verifier backend blind by specification. Every 5.3 requirement is proven. The commercial endpoint is also not a sanctioned production provider anywhere in STACK_DECISIONS, which names Bedrock GovCloud, Azure OpenAI Gov, and self hosted vLLM, so exercising it would have proven a lane production would never use. What stays unproven and is accepted: prose authored by an external model passing the verifier. The bounded run was not wasted. It executed every mechanism on our side against the live endpoint for the first time, and it is what surfaced the missing audit row. **Four, the sweep was blind outside the repository.** Closed by execution. Fifteen enumerated scopes across two hosts, thirteen positive controls in both directions, tracked and untracked, inside and outside the repository. It found what it was built to find on its first working run: **two complete DSNs, passwords included, in a script a timer runs hourly as root.** `CREDENTIAL_CONSUMERS.md` had already called those two lines a trap and left them standing, because nothing could see them. The inventory knew. That gap between knowing and seeing is the whole finding. Repaired, and the same change took both credentials out of `argv`, measured at one exposure before and zero after. --- ## What the intelligence actually is, since you asked `internal/modules/ai` is 11,059 lines, the largest module in a 112,469 line codebase. Six routes, four augmentation classes, nine named graph planes with depth caps and cycle guards, 35 intents in one closed registry asserted at boot. Twelve learned models, 101 coefficients, four families fit on real labels. The AEDT guardrail holds in the type system: a model intent may emit only three output kinds, and that is also the CHECK constraint, so a candidate score is impossible to register, store, or emit. It is trained, gated, reachable, and human in the loop. What it lacks is **fuel in production**: no taught knowledge cards, a teaching loop whose transport was closed until tonight, 2457 extraction rows no code reads, and 2625 notice bodies plus 5363 attachments never fetched. You asked whether it can create its own tables. **I refused that one specifically.** A table created at runtime has no RLS policy, and migration 0085 exists tonight precisely because a policy failing to name a role denies everything; a table with no policy is the inverse failure and leaks across tenants with no fail safe. The design instead lets it grow **rows, never tables**, in a store general enough that new node kinds, edge kinds and relations are data. Allocated to Phase 3. --- ## What closing Phase 2 means 1. The document pipeline is built and proven on both real solicitation packages. 2. Every gate has run at HEAD with a control that had to fail first. 3. Zero findings are open. 4. The production API is untouched, so nothing here sits in front of a customer yet. 5. Phase 3's scope is recorded: the wrap rate model first, then the wage bridge, then the self extending store, with the office reader holding the improvement slot. **Your call.** If you agree, Phase 2 closes on the pre approval you already recorded, and the 23 item list carries forward with the money items ahead of the intelligence items, because composition makes an answer only as good as its worst fed generator and today the profitability half cannot be answered at all.