Skip to content

Build and Release Acceptance Gates

Status

This document defines the production release gate for the typed mixed-DAG consumer migration. The executable entry point is:

./scripts/release_acceptance_gate.sh

That command is the only supported way to issue a passing release seal at:

dist/release_acceptance.json

The gate has no --fast, --skip-build, or --skip-tests release mode. A partial validation may be useful during development, but it is not a release acceptance result.

Gate sequence

Stage Required evidence
runtime_preflight The site and MCP virtual environments exist; their required imports work; Pagefind is installed; the frozen release-scope file exists.
mcp_compatibility_tests The MCP typed-graph suite passes, including unchanged legacy prime schemas and failure isolation when the mixed artifact is unavailable.
repository_tests The full scripts/test_*.py regression suite passes under the combined MCP/site runtime.
production_site_build scripts/build_eoa_site.sh runs without --fast, with search forced on. This rebuilds the canonical DAG, compatibility projection, catalog exports, generated docs, MkDocs site, Pagefind index, downloads, and learnability exports.
typed_graph_validation The freshly rebuilt graph validates against both JSON Schemas and the frozen source/topology assertions.
mcp_runtime_smoke Lookup, semantic retrieval, domain filtering, hierarchy traversal, aliasing, and coverage smokes pass against the rebuilt artifacts.
final_release_validation Cross-artifact and deployed-site checks pass and the machine-readable release seal is written.

The final validator receives the exact completed-stage set from the shell orchestrator. Running validate_release_acceptance.py directly cannot produce a passing seal because it cannot prove that the preceding build and test stages ran.

Hard release failures

The final gate rejects a release when any of the following is true:

  • the mixed manifest is missing, is not schema v2, or was built without the frozen release scope;
  • the graph has a directed cycle, isolate, multiple weak components, or a forbidden prime → domain-specific directed relation;
  • any graph artifact differs from the size or SHA-256 recorded in mixed_dag.manifest.json;
  • dag.jsonl or dag.json differs from its explicit prime_dag.* compatibility source;
  • prime, domain-specific, or archetype semantic coverage is incomplete, or the auxiliary catalog graph omits a prime;
  • the MCP tool surface changes unexpectedly, a legacy prime schema/response drifts, or MCP loads a topology seal different from the canonical manifest;
  • the production site lacks Pagefind, retains an uppercase template token, or omits the route for any canonical typed node;
  • a registered public download is missing, differs between source/generated docs/deployed site, or fails its published digest; or
  • the downloads manifest fails to distinguish the canonical typed graph from the incomplete prime-only compatibility projection.

Advisory findings

An advisory is recorded but does not reject the release when it represents curated metadata rather than a mechanical consumer failure. At present this applies to primes without a structural/framed grade. Those nodes remain searchable and routable; their search annotation is unlabeled.

The search smoke suite also retains date-frozen diagnostic expectations as non-fatal DRIFT notices. Coverage, schemas, and runtime behavior remain hard gates. Recalibrating the frozen retrieval diagnostic is a separate evaluation decision and must not be smuggled into a release-build change.

Seal lifecycle

At startup the orchestrator overwrites any prior seal with:

{"status": "in_progress"}

If a stage exits nonzero, the error trap writes a failed record naming the stage and exit code. Only after every stage succeeds can the final validator write:

{"status": "passed"}

The passing record contains:

  • every acceptance check and its evidence;
  • graph counts and canonical hashes;
  • MCP tool count, coverage, and prime-vs-mixed calibration counts;
  • deployed HTML, Pagefind, typed-route, and download counts;
  • Git HEAD and dirty-worktree evidence; and
  • SHA-256 hashes of the load-bearing source, schema, MCP, and build files.

Git dirtiness is recorded rather than rejected. This repository's publication workflow can deliberately build from an uncommitted curator workspace; the content-addressed source and artifact hashes identify the accepted state without pretending the current HEAD alone describes it.

Runtime selection

The checked-in defaults are:

site_src/.venv/bin/python
mcp_server/.venv/bin/python

They can be overridden without changing the gate:

EOA_SITE_PYTHON=/path/to/python \
EOA_MCP_PYTHON=/path/to/python \
./scripts/release_acceptance_gate.sh

The production build is run with the site environment first on PATH and EOA_BUILD_SEARCH=true. The repository suite runs with the MCP interpreter plus the site environment's package directory, providing JSON Schema/MCP dependencies and MkDocs/frontmatter dependencies in one test process.

Failure recovery

Read failed_stage in dist/release_acceptance.json, repair that stage, and rerun the whole gate. Do not manually change a failed record to passed; the next gate run will invalidate it, and the required stage receipt will still be absent.