# The Seven Release Gates & Aletheia

V9 (Metis — "A Curious Ape's Guide to Reality") generates lessons, and the one
thing a learning product cannot afford to generate is a confident falsehood. The
seven release gates are the governance-plane answer: a generated lesson is
**publishable only when seven independent eval gates all pass**, and a single
failing gate stops the lesson cold — it is not delivered, not cached, and not
shown. The gate verdicts are a real, strict contract (`V9GatesSchema`,
`libs/contracts/src/v9/lesson.ts:149`), the pass rule is a single function
(`isV9LessonPublishable`, `lesson.ts:246` — "true only when all seven gates
passed"), and the enforcement is wired into Stage 7 of the Prometheus pipeline,
where `forgeLesson` returns early with `blocked: true` the moment any gate fails
(`libs/v9/prometheus/src/pipeline.ts:232`). **Aletheia** is the subsystem that
owns three of those seven gates — grounding (G1), accuracy (G2), and safety (G6)
— and it is deliberately built as a _thin policy layer over rails that already
exist_, not a new grounding engine.

The reason it works this way is a platform finding the architecture doc names
directly (`V9_ARCHITECTURE.md` §5.1, finding **F6**): "grounding exists but is
not a mandatory pass on generated content." Oshun already has retrieval,
citation, a knowledge graph, and faithfulness evaluation in **Sophia**, and it
already computes real physics in the **Nyx/Kalika** kernels. What was missing
was not a grounding system but the _act of making those rails a mandatory pass_.
Aletheia is exactly that act and nothing more: textual grounding still belongs
to Sophia, numeric accuracy still belongs to Nyx/Kalika, and Aletheia owns only
the "must pass or block" semantics plus the regenerate-with-direction routing on
failure. This mirrors V8's **Minos** gate, which _enforced_ the fairness
validators rather than rebuilding them. This page is the deep companion to the
section hub at [../V9_ARCHITECTURE.md](../V9_ARCHITECTURE.md); the architecture
narrative and the gate table live in its §5.

## What ships, honestly

The gate **logic** is real, deterministic, CPU-only, and tested — it is not a
mock. Aletheia's three gates each run real code: G1 filters claims by Sophia pin
credibility and blocks the ungrounded (`grounding-gate.ts:43`); G2 _recomputes_
every STEM value from the real `@kalika/cosmology` Friedmann solver and
`@nyx/constants`, then matches it against the asserted number
(`accuracy-gate.ts:53`, `kernel-evaluators.ts:33`); G6 requires an
epistemic-status label on every claim and fails loud for high-stakes disciplines
(`safety-gate.ts:69`). The Aletheia spec asserts _domain correctness_, not
shape: the age of the universe must compute to ≈13.8 Gyr
(`aletheia.spec.ts:31`), the speed of light must equal `299792458` exactly
(`:38`), and a "6000-year-old universe" claim must be **blocked** (`:93`). The
other four gates are equally real: G4 is the Hephaestus computed-explorable DoD
(`explorable-runtime.ts:24`), G3/G5/G7 are evaluated in Prometheus (`gates.ts`),
and the whole thing composes through a full end-to-end `forgeLesson` pipeline
test that delivers, blocks, caches, and is deterministic across seeds
(`pipeline.spec.ts:108`–`176`).

What is a **seam, not a fabrication**: several of the richest checks are typed
_injection points_ that fail loud when unwired rather than faking a result. The
Sophia entailment check (`CitationVerifier`), the Sophia contradiction pass
(`ContradictionChecker`), the Metis curriculum-safety policy
(`CurriculumSafetyEvaluator`), and the Sekhmet age gate (`SekhmetAgeGate`) are
all interfaces (`grounding-gate.ts:27`, `accuracy-gate.ts:29`,
`safety-gate.ts:26`, `:41`). When a high-stakes discipline has **no** policy
wired, the safety gate _blocks_ rather than passing ungated
(`safety-gate.ts:115`) — fail-loud, not fail-open. A real
`DefaultCitationVerifier` exists in `libs/sophia/theory` but is **not** wired
into Aletheia by default; production wiring of these provider/model boundaries
is deferred. What is **spec-only / planned**: the G5 "LLM-as-judge panel" and
its correlation with the "Yemaya 76-validator suite" — only a deterministic
_structural_ quality default ships (`gates.ts:77`); and the G7 _cryptographic_
C2PA signing of every asset — `evaluateProvenance` checks that the provenance
hashes and ledger id are _present and well-formed_ (`gates.ts:105`), but
`c2paSigned` defaults to `false` on the explorable provenance
(`explorable.ts:95`), so actual signing is the inherited discipline the bundle
is shaped for, not a signature these libs produce.

## Two seven-gate framings — and which is canonical

There is a real naming divergence worth internalizing before reading any gate
code: **there are two G1–G7 mnemonics in V9, both real, both running on the same
shared platform release gate.** Confusing them will make the code look
contradictory when it is not.

The **canonical** numbering — the one this page, the architecture §5 table, the
contract `V9GatesSchema`, and the Prometheus/Aletheia/Hephaestus composition all
use — assigns the letters by _kind of check_:

| Gate | Meaning (canonical) | Owner / evaluator                                    | Fail action                      |
| ---- | ------------------- | ---------------------------------------------------- | -------------------------------- |
| G1   | Grounding           | Aletheia → Sophia pins (`grounding-gate.ts`)         | `reground`                       |
| G2   | Accuracy            | Aletheia → Nyx/Kalika recompute (`accuracy-gate.ts`) | `regenerate-with-…-ground-truth` |
| G3   | Pedagogy            | Prometheus `evaluatePedagogy` (`gates.ts:36`)        | re-scope / re-plan               |
| G4   | Completeness        | Hephaestus DoD (`explorable-runtime.ts:24`)          | fix or remove explorable         |
| G5   | Quality             | Prometheus `evaluateQuality` (`gates.ts:88`)         | regenerate-with-direction        |
| G6   | Safety              | Aletheia → Metis/Sekhmet (`safety-gate.ts`)          | `block-or-escalate`              |
| G7   | Provenance          | Prometheus `evaluateProvenance` (`gates.ts:105`)     | block until signed               |

The **second** framing belongs to the `@oshun/v9-lesson-gates` suite, which uses
a _different_ order entirely (`libs/v9/lesson-gates/src/index.ts`): **G1 truth,
G2 grounding, G3 teachability, G4 safety, G5 explorable, G6 adaptive, G7
retrieval** — verified by its own spec, which asserts the exact gate-id list
`['g1:truth', 'g2:grounding', 'g3:teachability', 'g4:safety', 'g5:explorable', 'g6:adaptive', 'g7:retrieval']`
(`lesson-gates.spec.ts:30`). Both are real, both register **seven** required
gates on the shared `@oshun/content-release-gates` `ReleaseGateService`, and
both express the same discipline. They differ in _altitude_: the canonical
composition (`composeGates`) assembles in-process contract verdicts from the
real evaluators, while `@oshun/v9-lesson-gates` is the suite registered on the
platform gate service, with its checks expressed as `gateFromEvalScore` /
`gateFromManifestCheck` / `createGroundingGate` over a flat lesson record. Note
one consequence of that altitude difference: the lesson-gates suite's G1 _reads_
a pre-stamped `truth: 'true' | 'false' | 'unverified'` field rather than
recomputing it (`index.ts:110`), and its G2 grounding treats "a non-empty
`sourcePin` string is present" as supported (`index.ts:89`). The _live_
Sophia/Nyx/Kalika checks live in the Aletheia path; the lesson-gates suite is
the platform-gate attestation that those verdicts were produced and that the
lesson cleared all seven. The "no eighth loop" rule (V9 must not fork its own
checker) is itself confirmed by `confirmSevenGateSuite`
(`libs/v9/governance/src/gate-suite.ts:27`), which asserts `gateCount === 7`,
`usesPlatformReleaseGate: true`, and `bespokeChecker: false`.

## The gate verdict contract

Every gate, in either framing, ultimately produces the same tiny contract shape
— `V9GateVerdict = { pass: boolean; evidence: string[] }` (`lesson.ts:141`) —
and the seven together are `V9Gates` (`lesson.ts:149`), a _strict_ object keyed
by the `V9GateId` enum `'G1' … 'G7'` (`lesson.ts:138`). Strictness matters: a
`V9LessonArtifact` cannot be constructed with a missing or extra gate.
Publishability is a pure function over those seven verdicts —
`isV9LessonPublishable` returns true only when `[G1…G7].every(v => v.pass)`
(`lesson.ts:246`), and the pipeline re-checks it defensively after compilation,
throwing if a "passing" lesson is somehow not publishable (`pipeline.ts:257`).

Internally, each Aletheia gate emits a richer `AletheiaGateVerdict`
(`libs/v9/aletheia/src/verdict.ts:18`) carrying the `gate` id, `pass`, an
`evidence` array, a `blockers` array, and an `action` — the `AletheiaFailAction`
(`verdict.ts:11`), one of
`'none' | 'reground' | 'regenerate-with-corrected-ground-truth' | 're-scope' | 'block-or-escalate'`.
The `evidence`/`blockers` split is deliberate: on pass, `evidence` is the
positive proof (which pins grounded which claim, what each kernel computed); on
fail, the verdict appends the blockers so the same array doubles as a failure
explanation. The contract-facing `V9GateVerdict` keeps only `{ pass, evidence }`
— `runAletheia` copies the blockers into `evidence` on failure so the artifact's
gate block records _why_ it failed without leaking the internal action enum
(`aletheia.ts:64`).

## Aletheia — the three gates it owns

`runAletheia` (`libs/v9/aletheia/src/aletheia.ts:47`) runs G1, G2, and G6
concurrently with `Promise.all`, then aggregates:
`pass = G1.pass && G2.pass && G6.pass` (`aletheia.ts:54`), and `actions` is the
de-duplicated set of fail actions across the failed gates (`aletheia.ts:55`) —
so a lesson that fails both grounding and accuracy surfaces
`['reground', 'regenerate-with-corrected-ground-truth']` for the
regenerate-with-direction router, with no duplicate noise.

### G1 — Grounding (every claim binds to a credible Sophia pin)

`evaluateGrounding` (`grounding-gate.ts:43`) walks each `AletheiaClaim` and
keeps only the pins whose `credibility` clears `minCredibility` (default `0.5`,
`grounding-gate.ts:47`). A claim with **zero** credible pins is a blocker —
`"ungrounded claim … (no pin ≥ 0.5 credibility)"` — and the gate's action is
`reground` (`grounding-gate.ts:85`). Two further blocks layer on top: a claim
the Metis evidence bundle marked `supportStatus: 'unsupported'` is rejected even
if a pin is present (`grounding-gate.ts:59`), and, when the optional
`CitationVerifier` entailment seam is wired, a claim that _no_ pin actually
entails is blocked with `"not entailed by any pin (Sophia citation check)"`
(`grounding-gate.ts:63`– `72`). That last check is the Sophia boundary: Aletheia
does not retrieve or rank — it asks an injected verifier whether each pin
supports the claim text. The `V9SophiaPin` contract (`primitives.ts:127`)
carries `pinId`, `sourceId`, an optional `locator` and `quote`, and the
`credibility` score in `[0,1]` that G1 thresholds on. Aletheia must **not**
reimplement RAG; G1 is the policy that makes Sophia's existing rail a hard pass.

### G2 — Accuracy (recompute the number; block what you cannot reproduce)

G2 is the one part of Aletheia with no home in Sophia — Sophia retrieves _text_;
it does not solve an ODE or evaluate an ephemeris. `evaluateAccuracy`
(`accuracy-gate.ts:53`) takes each `NumericClaim` (a `ref`, optional `params`,
and the `assertedValue` the generated text claims) and _recomputes_ it through
the kernel registry. The registry (`kernel-evaluators.ts:33`) is the binding
from a string ref to a **real in-repo computation** — no value is stored:

| Kernel ref                         | Real computation                                                     | Unit     |
| ---------------------------------- | -------------------------------------------------------------------- | -------- |
| `kalika:cosmology#ageTodayGyr`     | `ageTodayGyr(PLANCK_2018_COSMOLOGY)` (Friedmann integral)            | Gyr      |
| `kalika:cosmology#hubble0`         | `PLANCK_2018_COSMOLOGY.hubble0`                                      | km/s/Mpc |
| `kalika:cosmology#lookbackTimeGyr` | `lookbackTimeGyr(…, z)` (Simpson integration over expansion history) | Gyr      |
| `kalika:cosmology#hubbleParameter` | `hubbleParameter(…, z)` = `H0 · E(z)`                                | km/s/Mpc |
| `nyx:constants#speedOfLight`       | `SPEED_OF_LIGHT` = `299_792_458`                                     | m/s      |
| `nyx:constants#speedOfLightKmS`    | `SPEED_OF_LIGHT_KM` = `299_792.458`                                  | km/s     |

The cosmology values are not literals: `ageTodayGyr` (`friedmann.ts:138`)
Simpson-integrates `1 / (a · E(a))` over 4096 sub-intervals against the frozen
`PLANCK_2018_COSMOLOGY` parameters (`hubble0: 67.66`, `omegaMatter: 0.3111`,
`omegaLambda: 0.6889`, `friedmann.ts:39`), which is why the spec can assert the
result lands between 13.6 and 14.0 Gyr. For each claim the gate computes the
relative error `|asserted − computed| / max(|computed|, 1e-12)` and matches it
against a tolerance (per-claim `tolerance`, else default `1e-3`,
`accuracy-gate.ts:58`, `:80`). Two failure modes both **block** with action
`regenerate-with-corrected-ground-truth`: an _unknown_ kernel ref ("cannot
recompute … unknown kernel ref"), and a _tolerance miss_ ("value mismatch … text
asserts X, ref computes Y") — the architecture's one-line rule, "you cannot ship
a number you cannot reproduce." An optional `ContradictionChecker` seam runs a
Sophia-grounded contradiction pass over the claim text on top
(`accuracy-gate.ts:103`). The spec proves the teeth: asserting a `6000`-year-old
universe against `kalika:cosmology#ageTodayGyr` is blocked
(`aletheia.spec.ts:93`).

### G6 — Safety (labels, policy, age, and a human in the loop)

`evaluateSafety` (`safety-gate.ts:69`) enforces four things in order. First,
**every claim must carry an epistemic-status label** — one of `established`,
`contested`, `one-tradition`, `frontier` (`primitives.ts:114`) — so an
established fact and a frontier speculation are never presented identically; an
unlabeled claim blocks (`safety-gate.ts:78`). Second, the **Metis per-discipline
curriculum-safety policy** runs through the injected
`CurriculumSafetyEvaluator`; a `blocked`/`abstainRequired`/`correctionRequired`
verdict blocks, with `block-or-escalate` routing (`safety-gate.ts:88`–`114`).
Third, the **Sekhmet** age/sensitivity gate (`safety-gate.ts:122`). Fourth,
**high-stakes disciplines** — enumerated as `religion`, `psychology`,
`neuroscience` (`HIGH_STAKES_DISCIPLINES`, `safety-gate.ts:19`; note the code
uses `neuroscience` as the architecture's "health-adjacent" stand-in) —
additionally require a recorded human-review checkpoint, blocking with
`block-or-escalate` when `humanReviewed` is not set (`safety-gate.ts:137`). The
fail-loud invariant is the important one: a high-stakes discipline with **no**
curriculum policy wired does **not** auto-publish — it blocks
(`safety-gate.ts:95`, `:115`). Absence of a safety integration is treated as
unsafe, not as "clear."

## The other four gates (Prometheus + Hephaestus)

The remaining four canonical gates are assembled by `composeGates`
(`gates.ts:132`), which folds Aletheia's three contract verdicts together with
the explorable DoD and three Prometheus evaluations into a single `V9Gates`.

- **G3 Pedagogy** — `evaluatePedagogy` (`gates.ts:36`) blocks on a
  _prerequisite-coverage gap_ (a needed, not-yet-mastered prerequisite that is
  missing from the concept set, computed from `atlas.prerequisitesOf`), on
  **zero** anticipated misconceptions ("G3 requires misconception coverage"),
  and on a difficulty that falls outside the **flow band**. The flow signal
  comes from `@oshun/v9-mnemosyne-glue`: `tuneDifficultyToFlow`
  (`flow-channel.ts:70`) classifies the next item's success probability under
  the Mnemosyne IRT model into `'boredom' | 'flow' | 'anxiety'`, with the band
  default `0.6 < p < 0.85` (`flow-channel.ts:28`); only `'flow'` clears the
  gate.
- **G4 Completeness** — `evaluateExplorableDoD` (`explorable-runtime.ts:24`)
  enforces the V9 Definition of Done: a lesson must ship ≥1 `computed-kernel`
  explorable whose success state was _demonstrably reached_. Reachability is not
  asserted blind — the `V9ExplorableSuccessState.reachable` flag
  (`explorable.ts:68`) is set true only after the kernel output or headless
  verifier demonstrated the predicate, and `isV9ExplorableShippable`
  (`explorable.ts:128`) gates on exactly that. A generated-but-unverified
  explorable never ships.
- **G5 Quality** — `evaluateQuality` (`gates.ts:88`) scores the narrative
  against a `0.7` threshold. The shipped `defaultQualityJudge` (`gates.ts:77`)
  is a _deterministic structural_ proxy (rewarding ≥3 beats, ≥1 Socratic turn,
  ≥1 misconception, a forward-looking "next question"), with the LLM-as-judge
  panel left as the injectable `QualityJudge` boundary. The architecture's panel
  and Yemaya-validator correlation are the planned realization of this seam.
- **G7 Provenance** — `evaluateProvenance` (`gates.ts:105`) checks that the
  `skeletonHash`, `surfaceHash`, and `cacheKey` are well-formed 64-char hex
  digests and the `ledgerEntryId` is present. Seed-reproducibility is real and
  enforced by the deterministic pipeline (same `(inputs, seed)` ⇒ identical
  hashes, `pipeline.spec.ts:136`); cryptographic C2PA _signing_ of assets is the
  inherited discipline, not produced here.

## How a gate failure stops a lesson

Stage 7 of the Prometheus forge is where the gates bite. After grounding,
planning, writing, explorable-building, and scheduling, `forgeLesson` calls
`runAletheia` over the verified skeleton (`pipeline.ts:181`), evaluates
pedagogy, quality, and provenance, composes the seven verdicts, and computes
`blockedGateIds = ALL_GATE_IDS.filter(id => !gates[id].pass)`
(`pipeline.ts:232`). If that list is non-empty, the function returns immediately
with `blocked: true` and the failing ids — **before** Stage 8 — so _no artifact
is compiled, no C2PA bundle is minted, nothing is cached, and nothing is
delivered_ (`pipeline.ts:235`). Only a clean sweep reaches `compileLesson`. The
spec proves the block path end-to-end: with Sekhmet denying, the lesson is
blocked on G6 and never cached (`pipeline.spec.ts:155`), and a missing writer
boundary fails loud rather than fabricating narrative (`:176`).

```mermaid
flowchart TD
  A[Stage 1-6: verified skeleton + narrative + explorable] --> G{Stage 7: gates}
  G --> AL[runAletheia: G1 grounding, G2 accuracy, G6 safety]
  G --> H[Hephaestus DoD: G4 completeness]
  G --> P[Prometheus: G3 pedagogy, G5 quality, G7 provenance]
  AL --> C[composeGates -> V9Gates]
  H --> C
  P --> C
  C --> Q{all seven pass?}
  Q -- no --> B[return blocked:true + blockedGateIds<br/>no compile, no cache, no delivery]
  Q -- yes --> S[Stage 8: compile, C2PA bundle, ledger, profile-class cache]
  S --> D[V9LessonArtifact delivered]
```

## Reused substrate — what Aletheia must not reimplement

The gates are a composition, not a rebuild — which is the whole point of the
"thin policy layer" thesis. G1 leans on **Sophia** for retrieval, citation, the
knowledge graph, and faithfulness (`libs/sophia/*`, including
`libs/sophia/semantic-search` and the real `DefaultCitationVerifier` in
`libs/sophia/theory`). G2 leans on the **Kalika** cosmology kernels
(`libs/kalika/cosmology`, the Friedmann/Simpson solver) and the **Nyx** physical
constants (`libs/nyx/constants`). G3's flow band reuses the **Mnemosyne** IRT
model via `@oshun/v9-mnemosyne-glue`. And every gate, in both framings, runs on
the shared `@oshun/content-release-gates` `ReleaseGateService`
(`release-gates.ts:103`) — the same promotion gate every other Oshun product
uses, with its `gateFromEvalScore` / `gateFromManifestCheck` builders and the
`createGroundingGate` from `@oshun/content-quality-judge`
(`content-quality-judge/src/grounding-gate.ts:84`). Aletheia's contribution is
the _semantics_: the "every claim must have ≥1 credible pin" invariant, the
"recompute or block" rule, the "label every claim and gate the high-stakes"
rule, and the regenerate-with-direction routing. For the full reuse picture see
[./six-layer-reuse-stack.md](./six-layer-reuse-stack.md) and
[./subsystem-map-and-reuse-ledger.md](./subsystem-map-and-reuse-ledger.md).

## Configuration & edge cases

- **Thresholds are explicit, not magic.** G1 `minCredibility` defaults to `0.5`
  (`grounding-gate.ts:47`); G2 default tolerance is `1e-3` per claim
  (`accuracy-gate.ts:58`) — note the _contract_ `V9KernelResult.tolerance`
  defaults tighter at `1e-6` (`lesson.ts:51`), so a stored ground-truth value is
  bound more strictly than the text-vs-kernel match; G3's flow band is
  `(0.6, 0.85)` (`flow-channel.ts:28`); G5's quality threshold is `0.7`; the
  `@oshun/v9-lesson-gates` suite uses `minTeachability: 70` and `minSafety: 90`
  (`lesson-gates/src/index.ts:106`).
- **Unknown kernel ref ⇒ block, not skip.** G2 records a `computedValue: null`
  check and a blocker; it never silently passes a number it cannot reproduce
  (`accuracy-gate.ts:66`).
- **Missing seam ⇒ fail loud where it matters.** A high-stakes discipline with
  no curriculum policy blocks (`safety-gate.ts:115`); a non-high-stakes
  discipline with no policy simply proceeds with labels-only checks. The
  `humanReviewed` flag must be explicitly true to clear a high-stakes lesson.
- **Empty inputs.** G1 over an empty claim set passes vacuously (no ungrounded
  claim exists), but the contract guarantees a lesson has ≥1 grounded claim
  (`V9GroundTruthSchema`, `lesson.ts:58`) and ≥1 explorable (`lesson.ts:209`),
  so a real lesson never reaches the gates empty.
- **Determinism.** Gate evaluation reads only the skeleton, narrative, and
  injected seams — there is no `Math.random`, no wall clock inside the gates
  (the clock is the caller-supplied `nowUnixMs`/`signedAtIso`,
  `pipeline.ts:58`), which is what lets the pipeline assert identical hashes
  across two forges of the same seed.

## Related

- [./overview.md](./overview.md) — the V9 architecture overview, including the
  one-paragraph summary of the two gate framings this page expands.
- [./prometheus-lesson-pipeline.md](./prometheus-lesson-pipeline.md) — Stages
  0–8 of `forgeLesson`, where Stage 7 runs these gates.
- [./hephaestus-explorables.md](./hephaestus-explorables.md) — the
  computed-explorable runtime behind G4 completeness.
- [./lesson-artifact.md](./lesson-artifact.md) — the `V9LessonArtifact` whose
  `gates` block and `provenance` bundle these verdicts populate.
- [./atlas-knowledge-graph.md](./atlas-knowledge-graph.md) — the grounded
  concept graph G1 binds claims against and G3 reads prerequisites from.
- [./six-layer-reuse-stack.md](./six-layer-reuse-stack.md) and
  [./subsystem-map-and-reuse-ledger.md](./subsystem-map-and-reuse-ledger.md) —
  the reuse discipline that keeps Aletheia a policy layer, not a new engine.
- [./delivery-and-cross-cutting.md](./delivery-and-cross-cutting.md) —
  governance, entitlements, and the shared release-gate adoption
  (`confirmSevenGateSuite`).
- Hub: [../V9_ARCHITECTURE.md](../V9_ARCHITECTURE.md).
