tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

validation.md (68029B)


Testing

Use the Haskell host and route builds, linking, and tests through Nix. See build/run for guide selection and the language-feature inventory before .tri edits. For representation-sensitive work, see Compiler architecture.

Fast gates

The Haskell lexer/parser/compiler/source loader, recovery AST, and recovery workspace resolver have been removed. Executables, tests and benchmarks share the source-free runtime; the Nix boundary check rejects reintroduction of the retired frontend files. Host/test dependencies follow this source-free boundary. Runtime-presentation tests use independent constructor-display goldens; runtime demand tests exercise the same reducer used by production. Portable source tests provide the active language oracles: explicit expected values, locations, diagnostics, and negative controls. Representation tests cover retained portable artifacts. Historical Haskell frontend and self-hosting differential tests are retired.

nix flake check
python3 test/unit.py

The CLIs in test/stable_bundle.py and test/stable_costs.py are retired and fail before writes. Their preparation relied on implicit recovery compilation; keep those guards intact, including when old support/cache stamps are present. stable_bundle’s pure importable wire helpers remain supported. For current benchmarks, use the separately defined artifact-based Criterion workload below and collect fresh measurements.

Artifact-based Criterion benchmarks (opt-in)

nix build .#tricu-bench -o result-bench
nix build .#benchmarkWorkers -o result-benchmark-workers
nix build .#benchmarkSmoke --no-link
result-bench/bin/tricu-bench result-benchmark-workers/workers.arboricx \
  "$(cat result-benchmark-workers/sha256)" --verify-only
# Omit --verify-only for Criterion, or use --list / --help.

benchmarkWorkers builds bench/workers.tri and its explicit current-source library dependencies with the packaged stable compiler. It retains the staged sources, compiler metadata, CAS/receipts, bundle and whole-bundle SHA256. Preparation is bounded to 900 seconds compiling, 930 seconds externally, and an 8 GiB managed heap. Preparation builds benchmark applications; compiler generations and fixture publication follow their own workflows.

The Haskell runner consumes an explicit precompiled bundle and expected digest. Loading validates bundle structure, execution ABI and the exact export interface. A 120-second deadline covers loading and checking all 27 cases against independent complete expected values. Workers, inputs and expected values are fully constructed before timing; use external process/heap limits for actual timing runs. The digest authenticates selected bytes. Behavioral correctness depends on the independent expected-value checks.

The contract group measures precompiled application plus complete result equality; the registry group observes canonical Booleans in the same way. Parsing, compilation and publication are excluded. Historical contract benchmarks included recovery parsing/evaluation; compare timings only within the same workload definition. benchmarkSmoke checks expected results, wrong hashes, malformed bundles, incorrect interfaces, Criterion listing, and a one-iteration invocation of every case. Use repeated Criterion measurements for statistical performance analysis.

Interaction-tree inspection

nix flake check includes the Haskell Interaction inspection unit group and test/interaction_inspection.py in the host-policy check. The CLI fixtures build indexed bundles independently of the inspector, check outline/JSON identities and exit behavior, retain malformed/unknown/oversized input controls, and verify that inspection of effectful trees preserves files and leaves absent stores absent. The unit group covers all current host IO action tags, opaque continuations, exact export aliases, preview/depth/occurrence limits, and reachable exponentially shared values.

For the focused CLI check after building the Haskell host:

nix build .#
PYTHONDONTWRITEBYTECODE=1 python3 test/interaction_inspection.py result/bin/tricu

The compiled-source smoke example is in read-only interaction-tree inspection. It checks the native compiler-to-inspector path separately from independent wire fixtures; inspection reads the exported tree as data directly from its bundle.

Host loading and compiler supervision

The default Haskell tests directly exercise the production loader with flat and indexed objects: digest and ABI rejection, malformed and missing objects, manifest rejection, retained sharing, profiling-stage order, and selected exports with reads confined to their selected objects. Whole-interface loading retains manifest order.

Supervisor tests use constructed ABI workers. They check explicit selection, option validation, Result and publication validation, source-write denial, and a deadline that interrupts a sleeping worker. The default-frontend and portable-CLI probes additionally exercise real source compilation, REPL transactions, cache identities and compiler profiling:

nix build .#
python3 test/executable_arguments.py result/bin/tricu
python3 test/default_frontend.py result/bin/tricu
python3 test/portable_cli.py result/bin/tricu \
  --compiler-bundle bootstrap/build-stable.arboricx

These checks exercise the selected compiler and leave published fixtures unchanged.

IO permissions and run lifetime

The default IO ownership and path boundaries tests exercise new-file writes through escaping parent symlinks, ordinary allowed writes, and CAS rejection without forcing unpublished trees. Listening-socket rebinding checks run after normal completion, abort and timeout; blocked accept is also cancelled. FIFO writers establish that asynchronous OS work has started, stop draining until the run ends, then verify that the writer cannot finish its payload after run exit. These checks observe actual resource lifetime and effects alongside scheduler state.

See the host ABI for cancellation semantics and the limits of path-based permissions and timeout enforcement.

Current-source IO dependencies

nix build .#
PYTHONDONTWRITEBYTECODE=1 python3 test/io_dependencies.py result/bin/tricu

This opt-in probe compiles current io, base, and native_math sources with only those modules present in a temporary workspace. It checks IO constructor and conditional results and rejects an explicit import of the absent patterns module. Published compiler/support fixtures remain unchanged. The fast host policy tests separately check that the working compiler map is an exact closure and that IO depends only on base.

Batch development loop

Agree on a substantial related module group, its intended interface/behavior changes and a focused-test budget before starting. Compile candidates with the accepted stable toolchain and link affected consumers against that candidate. Reuse authenticated unchanged inputs to keep iteration focused on affected modules. Commit reviewable slices with explicit unpublished candidate status. Keep published fixtures unchanged until the batch's agreed acceptance checkpoint.

Start with a few complete-result/demand/effect probes and representative callers; expand coverage where the edit changes behavior or exposes a defect. Bound each compilation/run and the combined probe job. Record modest, justified adjustments to initial budget estimates. Unexpectedly costly or repeatedly exhausted jobs require diagnosis before another bounded attempt; exhausted jobs remain failed checks. Broader matrices and repeated performance studies need an explicit reason and budget; full-generation resource ceilings still apply.

Classify differential mismatches against intended requirements. Preserve meaningful requirements and intensional behavior; deliberately replace insecure/incoherent behavior or poor interfaces, updating callers and independent expected results with a stated rationale. Retain historical oracles and negative controls, and derive expectations independently of candidate output. Git provides source rollback; behavioral correctness requires tests.

Run the full compiler gate at the agreed batch checkpoint, using focused checks between drafts. A verified compiler checkpoint may explicitly defer publication: retain the audited fresh pair and generation-two native-import/recursion/program smoke coverage, leaving reference fixtures and working-source freshness pending. This permits subsequent candidate work with the verified compiler. Final compiler/support-cohort publication remains pending. See compiler rebuilding.

Three distinct checks

  1. Reference-artifact tests (nix flake check): current Haskell runtime, retained compiled compiler/support implementations, and their authenticated source snapshots. Edited .tri implementations require candidate tests.
  2. Candidate tests: explicitly compile the changed implementation with the retained stable compiler and run focused semantics/integrity/integration checks against the resulting artifact. Record candidate identity and preparation scope.
  3. Final batch acceptance: for compiler-affecting batches, the fresh stable generation/self-rebuild gate; genuinely rebuilt current fixtures, explicit working-source freshness and the fast suite. Support-only batches still need candidate/publication validation; compiler generations are required for compiler-affecting changes.

The Haskell gate loads fingerprinted, full compiler/support artifacts. Source bytes are stored by their existing arboricx.source.v1 digest under test/fixtures/reference-source/; the .v1 fixture metadata remains authoritative. The loader authenticates those bytes, including the headers used for import binding. Missing/corrupt snapshots fail. Library inputs come exclusively from authenticated snapshots. Unmapped test programs remain live test inputs. Bundle, receipt, namespace, kernel, and ABI checks remain.

test/ReferenceFixtures.hs owns authenticated artifact loading and direct published-interface selection. test/LibraryValueTests.hs invokes byte-list and HTTP exports with host-constructed inputs, without source wrappers or recovery compilation. test/ParserValueTests.hs does the same for binary and finite-stream parser protocols, including consumed/committed flags, rollback, zero-width repetition, and poisoned-field controls. HTTP framing/error expectations and no-socket-access controls remain independent of the compiled implementations. Mixed-cohort reuse verification in SupportFixture compares complete provider identities directly.

test/IODriverTests.hs uses explicit ABI trees for primitive/scheduler controls and portable-compiled programs for library sequencing, state, concurrency and socket integration. Its source scope contains only published io, prelude and socket interfaces. The shared ScriptedEffects interpreter checks exact effect order and complete replies without real filesystem/network access; live IO tests retain their permission and failure checks.

Unit runs reuse authenticated library artifacts with their recorded source identities. Compiler conformance wrappers use test/PortableTestCompiler.hs: the retained stable unit compiler receives explicit published fixture imports and a definition body. This test-only header adapter binds explicit fixture imports and returns only local definitions. Native module resolution has separate coverage. Preparation has a 30-second deadline and checks Result/list/name structure without forcing unused definition values. Invalid source and import shadowing fail without fallback. Useful library program tests use the same bounded portable compilation route with an explicit published prelude. div and mod zero-divisor expectations follow the checked numeric contract. All source tests use portable compilation with explicit imports.

# Verify reference-source/bundle fingerprints; check working-source freshness below.
python3 test/fixture_sources.py verify

# Required at final batch acceptance; exits nonzero and lists stale/missing
# source inputs or changed compiler-map membership/order.
python3 test/fixture_sources.py current

Working-source freshness and candidate behavior are separate checks. Pending freshness blocks final publication acceptance; an explicitly scoped verified compiler checkpoint may defer it. Failed reference integrity, candidate correctness, or generation verification blocks further feature work until repaired. Compiler edits require candidate tests and the generation acceptance gate.

To capture reference sources after a verified fixture publication (or to recover missing snapshots), select the source root that matches the fixture metadata:

python3 test/fixture_sources.py capture --source-root "$FIXTURE_SOURCE"

Capture authenticates all inputs before writing, only adds digest-named files, and refuses changed source or an existing corrupt snapshot. Existing fingerprints and compiled artifacts remain unchanged. Keep the snapshots with fixture publications and manage retirement of old digest-named files explicitly. Changed sources require genuine candidate compilation and fixture publication with fingerprints matching the actual inputs.

nix flake check also runs cheap artifact-only CLI checks and unit.py provenance/header, selector/reexport, RSS, prepared-session, native-scope, fixture-projection and reference/freshness separation controls. Its filtered source excludes archive/. It builds through Nix and tests retained compiler and library artifacts. Library-source compilation and compiler-generation checks are opt-in workflows.

Focused checks

Use new output directories and explicitly selected candidate artifacts. Record source, compiler, dependency, and export identities during preparation, and relink affected consumers before testing.

Artifact-only runners execute selected bundles and report their identities. Authenticate compilation provenance separately during preparation. The focused checks below supply candidate coverage; final batch acceptance follows the three-check workflow.

Digest and dependency analysis

The fast digest-hex checks compare the reference fixture worker with the immutable pre-optimization implementation in test/fixtures/hash-hex-reference.arboricx, including all byte values and malformed/noncanonical inputs. Preserve that reference unchanged. Select a genuinely compiled candidate object module for focused checks of edits:

python3 test/digest_hex.py result/bin/tricu \
  --subject "$CANDIDATE_OBJECT_BUNDLE" --directory /tmp/digest-hex-check

The directory must be fresh. This runner is artifact-only.

Focused name/dependency-analysis checks require explicitly selected, precompiled candidate modules:

python3 test/source_order.py result/bin/tricu \
  --order-bundle "$CANDIDATE_ORDER_BUNDLE" \
  --stable-bundle "$RELINKED_STABLE_BUNDLE" \
  --unit-bundle "$RELINKED_UNIT_BUNDLE" \
  --directory /tmp/source-order-check

The directory must be fresh. Prepare those full-export modules with the retained stable compiler, linking source_stable and source_unit against the changed source_order manifest (and unit against the relinked stable manifest). Record source hashes and dependency manifests during preparation. This artifact-only runner compares complete order/diagnostic/graph results and, with the optional unit bundle, complete stable compiled results for 38 cases. Reference sources and artifacts are authenticated independently; the report records every selected artifact identity.

HTTP syntax and framing

HTTP syntax checks are opt-in and artifact-only:

python3 test/http_headers.py "$TRICU" --subject "$HTTP_CANDIDATE" \
  --directory /tmp/http-syntax-check

The candidate must contain the full unqualified HTTP exports. The default corpus checks strict CRLF lines, complete header blocks, token names, value byte classes, SP/HTAB trimming, exact error progress, opaque body remainders, and shared request-line scanning. Deliberate semantic changes carry explicit reasons and independent complete expected trees; unaffected cases still compare against the immutable pre-rewrite reference. --legacy-behavior reproduces the earlier readability-only corpus against historical artifacts. Use the default corpus for the corrected parser. The byte domain is canonical naturals in 0..255. Historical out-of-domain cases have separate historical records; current expectations use the canonical byte domain. All byte classes and exact progress/remainder checks remain active. The frozen reference is independent of the candidate.

Content-Length/body-length selection has a separate artifact-only check:

python3 test/http_lengths.py "$TRICU" --subject "$HTTP_CANDIDATE" \
  --directory /tmp/http-length-check

It checks bounded decimal decoding through the 1 MiB body limit, all byte values, long digit/zero runs and malformed suffixes after overflow. Header selection rejects duplicate Content-Length (even identical), comma lists, and any unsupported Transfer-Encoding with 400; valid oversized lengths return 413. Names passed directly to contentLength must already be normalized by parseHeaders. Complete inert readBody error trees prove rejection before requesting body IO. Optional --reference selects an explicit previous HTTP bundle for small unchanged cases only: its old unbounded decoder cannot safely serve as the oracle for costly inputs. Every candidate case has an independent complete expected tree. The header regression above still applies.

The broader HTTP pipeline also has an opt-in artifact-only suite:

# Prepare test/httpEffects.tri explicitly with native_library_migration.py:
# --backend stable --library tests.httpEffects (plus normal selected dependencies).
python3 test/http_pipeline.py "$TRICU" --subject "$HTTP_CANDIDATE" \
  --reference "$PREVIOUS_HTTP" --driver "$HTTP_EFFECTS_DRIVER" \
  --directory /tmp/http-pipeline-check

Without --driver, this runs only pure validation/buffer/framing probes. With it, a test-only interpreter runs the actual selected HTTP functions, interprets Pure/Bind and supplies scripted primitive replies. Independent complete trees check results, every recv/router/send/close payload and ordering, and unused script entries. Interpreter controls exercise sequencing, missing/wrong/extra operations, fuel exhaustion, and abort; a wrong selected subject must fail. Optional --reference checks unchanged behavior and explicitly characterized old outputs for intentional corrections (EOF retry, receive-error shadowing, lost 431 status and the 413 reason phrase). For a reference that already includes those corrections, add --reference-current: every result and trace must then agree unchanged with the independent oracle AND the reference. Prepare the opt-in test driver separately from the support-fixture cohort.

The driver uses scripted effects. HTTP cleanup attempts close after an ordinary send Result and preserves the primary failure; terminal aborts and host exceptions are separate. Expectations include error precedence, EOF, bucketed reads, exact body lengths, binary suffixes, and the whole-buffer receive cap described in Parser.

For receiver changes, evaluate ordinary headers, fragmented reads, near-limit success/failure, and representative concurrent IO. Preserve limit-before-acceptance behavior, suffixes, errors, and complete receive/send/close traces. Measure time and memory together, including concurrent workloads when assessing throughput.

Exact package registry checks

nix flake check runs Haskell codec/publication tests (including concurrent identical publishers) and test/package_registry.py against a controlled loopback HTTP peer. This checks explicit trust, lock identity and mutation controls, redirects, metadata bounds, corrupt transport, module mismatches, offline reuse/binding, and local corruption using prebuilt wire fixtures.

For the full current-source vertical slice on the Haskell host:

nix build .#
python3 test/package_registry.py result/bin/tricu \
  --prepare-server /tmp/package-registry-candidate

The preparation directory must be new. Preparation compiles the current native server with the packaged stable compiler, retains source copies, source hashes, command and build log, and limits compilation to 900 seconds / 8 GiB heap. The runner then compiles a small two-export library, publishes it locally, serves it through the actual native HTTP routes, fetches into a fresh store, stops the server, generates a pinned workspace binding and compiles a consumer yielding 42. Invalid package route components must receive HTTP 400. Runtime children have a 2 GiB heap limit and bounded subprocess deadlines.

To reuse an already prepared server artifact:

python3 test/package_registry.py result/bin/tricu \
  --native-server /tmp/package-registry-candidate/server.arboricx

That module must export main root port, returning the IO-wrapped server action. These checks cover real loopback HTTP. HTTPS/certificate infrastructure, hostile-filesystem containment, and crash durability require separate validation.

Registry server pipelines (opt-in)

Prepare tests.httpEffects and tests.registryEffects explicitly through the stable native-library preparation route. The registry adapter reuses the same fuel-bounded Pure/Bind interpreter. Both modules are prepared as test-only artifacts, separately from the support fixture cohort. Select full unqualified registry and optional demo artifacts:

python3 test/registry_server.py "$TRICU" --subject "$SERVER_CANDIDATE" \
  --reference "$PREVIOUS_SERVER" --driver "$REGISTRY_EFFECTS_DRIVER" \
  --demo "$SERVER_DEMO" --previous-demo "$PREVIOUS_SERVER_DEMO" \
  --directory /tmp/registry-server-check

The runner executes selected artifacts through pure/scripted effects. Without a driver it checks pure hash/contract/path/prefix operations only. With it, independent complete trees check attempted action payloads/order, errors, unused replies, initialization, uploads/downloads, routes, the actual HTTP adapter and listener startup. Optional demo artifacts check initialization failure prevents listening, and successful initialization proceeds to listening. --baseline checks explicit historical expectations against an old subject including inert unsafe write requests. Candidate runs retain their independent current-behavior oracles. Reference comparisons characterize each intentional behavior change. Wrong-subject selection must fail. Reports record selected artifact identities; preparation provenance and publication are separate checks.

The server validates exact 64-character lowercase hexadecimal hashes before filesystem IO, including the digest reply used for upload. The old public unchecked hash-taking writer and shared <hash>.tmp staging are removed. Upload publication uses atomicWriteBytes, whose host-owned unique temporary file is in the destination directory. Publication replaces existing objects. Uploads accept arbitrary opaque bytes; consumers must validate bundle format before use. A post-publication sync error may leave the new file visible. Initialization now propagates errors and stops immediately. Bind/listen errors attempt close once and preserve the original error even if close fails.

The fast Haskell gate separately exercises bounded malformed-tree rejection (including unevaluated oversized suffixes), complete primitive traces, and small real-filesystem checks: initialization, binary round-trip, replacement, concurrent same-object uploads and absence of temporary residue. These use authenticated reference fixtures. Edited-source coverage, live-network behavior, scheduler fairness, crash injection, and terminal-abort/host-exception cleanup require separate checks.

Store root remains trusted configuration. Identifier validation checks spelling; host permissions control IO access, and symlink/race safety requires a trusted, stable store filesystem. Pure path helpers remain unguarded constructors. Hash predicates retain arbitrary-tree rejection; stripPrefix requires a proper list prefix and returns the exact suffix.

Support fixture publication

Support fixture v3 retains immutable original compiler/support snapshots and per-module provenance. Its 39-module reference cohort has stable-rebuilt native receipts, full manifests, and a separate compiled-root snapshot. Original snapshots preserve their recorded compiler identities. Rebuilt modules may change bodies and exports: their source fingerprints must match the actual compiled source/receipt, and their full export sets must match their new manifests. Tests still check receipt identities and published/rebuilt kernel equality. Support-provider manifests in receipts must match the selected cohort. Reusing an artifact requires matching provider interfaces as well as an unchanged consumer body.

Origin-retained modules require unchanged source fingerprints/output trees and identical complete interfaces of every imported or reexported provider. Comparison uses exact constructor/child interning across the bundles, independently of local node indices. Provider membership, every export name and every executable tree must match; this also preserves namespace and collision outcomes. Unrelated providers may change. Changes to unused or shadowed imports now require rebuilding: the former free-name-based reuse optimization is retired.

This proves identity relative to an authenticated, accepted original cohort. Source validation and new compilation receipts require compilation. The verifier recognizes the fixture's simple named-provider imports and reexports; unsupported directives, including build-only !source dependencies, fail closed and require rebuilding. The verifier compares recorded provider interfaces directly. Prefer rebuilding affected consumers to relaxing these checks. The current 39-module cohort is entirely rebuilt and already satisfies this policy. Future source changes still need candidate coverage and genuine publication at acceptance.

For a justified narrow repair, test/repair_support_dependencies.py materializes full original dependency manifests (and asserts their original identities), and test/native_library_migration.py builds the affected aliases with stable lowering. For a full support rebuild, explicitly select all current support modules and let their dependencies compile in the fresh candidate store. Use --backend stable --capabilities 8 --memory-mib 65536; candidate commands default to a 20-minute guard, and --batch-seconds 7200 permits a bounded full cohort. For compiler-affecting work, acceptance additionally requires the generation workflow below.

test/repair_support_fixture.py creates a new candidate directory, preserves published fixtures, and reproduces every candidate’s complete native manifest before accepting its kernels against the compilation receipt:

python3 test/repair_support_fixture.py "$TRICU" "$SUPPORT_CANDIDATES" \
  --output-directory "$SUPPORT_PUBLICATION" \
  --capabilities 8 --verification-memory-mib 65536

The publisher also accepts multiple preparation directories. To replace a prior candidate explicitly, supply its directory first, the new preparation later, and repeat --replace ALIAS for each duplicate alias. It checks the retained records against their own source bytes, compiler identities, and receipts. Repacking preserves those original compilation claims. Include genuinely rebuilt affected consumers in the selection: stale support dependency pins fail before metadata is published. Cohort membership/alias/path changes remain a separate operation. Rebuilt modules may deliberately change source and exports, with callers and expectations updated. The explicit --relocate-patterns operation adds only patterns at lib/patterns.tri, requires its genuine native rebuild, and refuses publication while it still belongs to the compiler fixture. V3 records this relocation without changing the immutable origin membership. Use that option when publishing the current 39-module support set; ordinary candidate replacement preserves cohort membership.

Current indexed native-manifest reproduction uses indexed import and exact manifest comparison. Reproducing retained flat manifests expands trees: its default audit RSS/heap limits are 8/4 GiB, with an explicitly selectable RSS cap up to 64 GiB and heap cap half that value. The large staged-conditional fixture needs more than the default heap. Indexed bundle packing/import validation retains 1 GiB RSS / 512 MiB heap limits. Each audit child has a 300-second deadline; the complete publication job is bounded to 20 minutes. verification.json records the actual checks. Failed candidates remain unpublished.

After successful candidate validation, install only support-library.arboricx, support-rebuilt.arboricx, support-library.v1, and support-receipts/, preserving the immutable origin files. Capture the matching reference sources, then run python3 test/fixture_sources.py current and nix flake check before accepting the fixture. Preserve actual compiler identities and original snapshots when repairing failures. Label backend-sensitive tree-shape goldens by their backend and check them independently. Extensional equivalence requires separate evidence.

SCP: archived experiment

SCP sources, commands, tests, demos, and the mixed workspace dispatcher are under archive/scp/ as historical material. Active builds and tests use the native module tooling. Historical commands in the SCP reference require a historical checkout.

The original fixture projection is recorded in test/fixtures/support-projection.json. Its immutable origin fingerprints remain checked inputs; rebuilt outputs are instead authenticated by native receipts and current cohort metadata. To reproduce that historical extraction, use test/project_support_fixture.py with explicit --original, --compiler, --source-root, --aliases, and new --output paths. Projection compares exact kernels and dependency closure without source compilation. Keep its historical ledger distinct from later compilation publications.

Compiler, transport, and publication

See compiler rebuilding for artifact prerequisites, backend selection, guarded generations, and independent closure audits. Runners default to stable; select it explicitly in recorded commands.

python3 test/source_equations.py result/bin/tricu \
  --generation "$GENERATION" --timeout 180
python3 test/portable_cli.py result/bin/tricu --indexed \
  --compiler-bundle "$GENERATION/build-stable.arboricx"
bash test/source_map_end_to_end.sh result/bin/tricu "$GENERATION" \
  .bootstrap-run/nested-map

Check each probe's --help for its other required prepared artifacts. Equation coverage has independent AST/diagnostic controls; module/map probes use native artifacts. verified_tree_loading.py covers verified transport and bounded loading/publication measurements, outside the default checks.

Header-only equivalence uses the explicit --native-header-equivalence option of refresh_compiler_fixture.py. It authenticates exact staged bytes and previous receipts and requires unchanged bodies and dependencies. It records header equivalence; new generations follow the generation runner workflow. For a support change, rebuild only the justified affected cohort and prove reuse for the rest. Record actual compiler pins and rebuild consumers whose dependency identities changed. Archive creation consumes existing accepted artifacts and their matching fixtures.

refresh_compiler_fixture.py and refresh_support_fixture.py publish artifacts after validation. refresh_compiler_fixture.py --output-directory DIR stages a compiler candidate without replacing the reference cohort, allowing pre- publication comparisons. Publish the compiler before the final support publisher run: support metadata binds the compiler fixture present during publication. They authenticate completed preparation receipts, current source fingerprints, full dependency manifests, and the packed fixture. Explicit --completed-only / --replace ALIAS select explicit, reviewable publication policies; failed preparation requires separate repair. Streaming publication retains tighter 600-second / 1 GiB RSS / 512 MiB managed-heap guards.

native_library_migration.py prepares explicit candidates, preserving definition bodies and dependency/import policy. Bare terminal-selector conversion and import-only reexports require explicit flags; arbitrary expressions and namespace widening fail. Candidate jobs / batches default to 20 minutes; an explicitly selected full cohort may use a two-hour batch ceiling. --memory-mib sets both the sampled direct-child RSS guard and host heap ceiling, up to 64 GiB. Full dependency manifests are mandatory; authored source and published fixtures remain unchanged.

Research and costs

Native math checks, formatter tooling, stable abstraction/bundles, and staging experiments remain opt-in; use their retained compiler and support artifacts. Compile current compiler libraries through the selected portable toolchain.

python3 test/staging_experiment.py result/bin/tricu \
  --prepared "$STAGING_PREPARATION" --prepared "$UPDATED_FIXTURE_PREPARATION" \
  --compiler-bundle "$GENERATION/build-stable.arboricx" \
  --directory .bootstrap-run/staging-runtime --skip-measurements
python3 test/staged_conditional.py result/bin/tricu \
  --prepared "$STAGING_PREPARATION" --prepared "$UPDATED_FIXTURE_PREPARATION" \
  --compiler-bundle "$GENERATION/build-stable.arboricx" \
  --directory .bootstrap-run/staging-source --source-only \
  --case yes --case closed-unselected --case ordinary \
  --case list-advance --case slice-unicode

Both research harnesses cap whole runs and children at 1200 seconds. Prepared fixture selections reuse authenticated trees; generated case data is compiled in batches. Explicit scalar fixture data supplies Unicode codepoints directly; native source-file loading remains restricted to ASCII. Run formatter integration separately.

Report preparation, loading, compilation, publication, allocation, RSS, logical size and DAG size separately. Direct-child RSS covers only the child process; measure descendants separately. Guard stops and missing measurements are failures. Research-profile contracts are in Compiler architecture.

Local-control candidates (opt-in)

Select genuinely rebuilt source_unit and source_program candidate bundles, plus a stable-prepared tests.localControlEffects driver and fresh output directories. The driver depends on the existing tests.httpEffects interpreter; prepare it through the native library preparation tool with that dependency selected explicitly. Keep test drivers in a separate test-only preparation.

python3 test/local_control.py "$TRICU" --unit "$UNIT" --program "$PROGRAM" \
  --directory "$SYNTAX_CHECK"
python3 test/local_control_consumers.py "$TRICU" --unit "$UNIT" \
  --driver "$LOCAL_CONTROL_DRIVER" --directory "$CONSUMER_CHECK"

The first check compares complete located AST replies, complete diagnostic records, independent values, and a wrong-compiler negative control. Compiler private diagnostic remainders are retained as implementation-level evidence; language-level oracles cover the public diagnostics. The second compiles and serializes small HTTP/registry replacement functions before invoking them, compares both candidate and authenticated retained kernels to independent complete values/effect traces, and records expanded wire-tree sizes and guarded whole-process costs. Authenticate driver source, receipts, and dependencies during preparation. The default Nix check runs cheap harness controls; run these compilations explicitly.

Arboricx reader rewrites (opt-in)

python3 test/arboricx_readers.py "$TRICU" \
  --subject "$CANDIDATE_MODULES" --reference "$RETAINED_MODULES" \
  --directory "$FRESH_PROBE_DIRECTORY"

Both directories contain full arboricx_common, arboricx_nodes and arboricx_manifest bundles. Independent complete-result oracles cover field reads, every truncation of representative records, opaque suffixes, counted records, node payload/index validation, and error precedence. Differential shape probes cover selected malformed trees. A wrong-export control must fail the independent oracle. Prepare candidates separately with the portable stable compiler, rebuild dependent Arboricx consumers, authenticate receipts and prove tested/published kernel identity before refreshing fixtures.

binary.bindParser threads the successful value and remaining input to its continuation and supports do directly. The full readManifest entrypoint historically returns unit in both its extension slot and successful remainder, even with trailing input. This is explicitly characterized separately from the remainder-preserving field readers. The current suffix-preserving behavior is covered by bundle_batch.py below.

Socket convenience cleanup (opt-in)

python3 test/socket_conveniences.py "$TRICU" \
  --subject "$CANDIDATE_SOCKET" --reference "$RETAINED_SOCKET" \
  --driver "$REGISTRY_EFFECT_DRIVER" --directory "$FRESH_PROBE_DIRECTORY"

Checks complete primitive payloads/order and exact Result remainders. The retained reference predates cleanup: successful acquisition followed by failed bind, listen or connect intentionally adds one close; the original error survives close failure. Acquisition failure returns directly; success transfers ownership. Terminal aborts and host exceptions follow host lifetime handling, separately from ordinary Result cleanup. The scripted test records socket actions as data. The Haskell gate separately exercises a real ephemeral listener and successful loopback connection, plus exact scripted cleanup paths.

Parser control rewrites (opt-in)

python3 test/parser_control.py "$TRICU" \
  --subject "$CANDIDATE_PARSER" --reference "$RETAINED_PARSER" \
  --driver "$PARSER_CONTROL_DRIVER" --directory "$FRESH_PROBE_DIRECTORY"

Compile test/parserControl.tri explicitly through the stable portable toolchain. Its higher-order wrappers receive the selected compiled parser export after wrapper construction. Independent full replies cover repetition, zero-width success, failure progress, bind/lexer flag propagation, and non-Leaf truthiness. Divergent ignored fields and unselected handlers must remain unforced. A same-arity wrong-export control uses parserOptional in place of parserMany. Record/authenticate driver source, receipts, compiler/options, dependencies and complete manifest separately. Parser edits are compiler-affecting: acceptance also requires the fresh stable generation/self-rebuild and publication steps in compiler rebuilding.

Foundational list workload comparisons (opt-in)

Use an authenticated pre-adoption fixture directory, including bundle metadata and source snapshots, for historical manual-worker comparisons:

python3 test/base_workloads.py result/bin/tricu \
  --compiler "$STABLE_BUNDLE" --directory "$FRESH_OUTPUT" \
  --reference-fixtures "$REFERENCE_FIXTURES" \
  --sizes 64 1024 8192 --repetitions 7
python3 test/base_readable.py result/bin/tricu \
  --compiler "$STABLE_BUNDLE" --reference-source "$REFERENCE_BASE_SOURCE" \
  --directory "$OTHER_FRESH_OUTPUT"

The first compares published/manual fixed points, direct recursion, patterns, and captured local recursion over protocol/log-like workloads. It authenticates manual/published kernel equality and checks independent complete results, edge cases, ignored-field demand, and a wrong-subject control. Its whole-job budget is 30 minutes with 8 GiB child RSS/heap guards.

The second compiles complete reference/current base modules and linked drivers, then checks independent edge/demand/effect cases and a smaller workload screen. Its whole-job budget is five minutes, compilation 60 seconds, and ordinary calls 20 seconds. Effects are interpreted interaction trees with scripted replies.

Use fresh processes, interleaved variants, discarded warmups, and recorded raw samples. arboricx run --repeat can reuse an evaluated application; use a fresh process for each independent invocation. Loading-to-WHNF, invocation-through-rendered-output, and explicit full-result forcing measure different work; the latter two include deferred evaluation and their respective observer costs. See the profile phase definitions; ordinary --profile leaves discarded result fields lazy. Report preparation separately. Sampled RSS can miss short-lived peaks, and small timing differences require broader evidence before generalizing. Partial matrices remain incomplete. These probes leave accepted compiler and support fixtures unchanged.

Pattern lowering comparison (opt-in)

python3 test/pattern_lowering.py result/bin/tricu \
  --reference-unit "$RETAINED_SOURCE_UNIT_BUNDLE" \
  --directory /tmp/tricu-pattern-candidate

The probe authenticates the shipped compiler and complete unchanged reference modules. It stages the source lowerer and rebuilds its affected compiler consumers through source_unit; receipts, source bytes, exported objects, and exact dependency pins are audited before execution. Only unchanged dependency boundaries use full retained-module facades. Accepted artifacts remain unchanged.

The Haskell control driver is compiled through Nix. Checks reuse the 75-case independent equation corpus, exercise constructor/equality workloads on finite and poisoned inputs, and verify split-column ordering, nested failure, unreached pins and whole-child captures. Two exact code-generation targets compare ordinary equations with independently authored direct dispatchers; the retained compiler must fail those optimization targets. Non-pattern controls must retain their original trees. Optimized-backend function trees must also remain identical; stable function construction must tolerate unselected closed divergence while application to the divergent branch must not return. The existing 46-case local-control suite also runs on the candidate.

Select an authenticated retained source_unit bundle with unqualified exports for --reference-unit; its digest is recorded separately from the shipped compiler used to construct the candidate. --prepare-worker additionally rebuilds all affected consumers through source_map and emits a pruned stable transition worker.arboricx for subsequent generation acceptance. --resume permits diagnostic checkpoint reuse only.

Fresh-process cost probes interleave reference/candidate executions, discard a warmup, and retain three samples per role. Identical explicit recursion and full output oracles isolate dispatch costs. Separate small compiler probes force the complete returned definition trees. Both use explicit full-result profiling: reduction plus DAG traversal, excluding load and rendering. Allocation is GC-sampled; peak residency and reduction counts require separate measurements. Reports retain raw profiles, source/compiler/artifact identities, receipts, controls, and medians.

Limits: 20 minutes overall, 600 seconds for native compilation with an 8 GiB heap, 180 seconds / 4 GiB for the Haskell controls, and 20-second / 512 MiB workload calls (30 seconds / 1 GiB for construction probes). --resume authenticates native checkpoints and preserves the previous report for diagnostic reuse. --skip-costs retains semantic/integrity controls without timing runs. Compiler acceptance additionally requires a fresh generation/self-rebuild pair.

Sharing characterization (opt-in)

python3 test/sharing_probes.py result/bin/tricu \
  --directory /tmp/tricu-sharing-probe

Use a fresh directory. The probe compiles tiny import-free programs with the shipped stable compiler and runs only the Haskell host. It compares a bound shared computation with two separately written calls, checks their complete small outputs against an independent oracle, and compares a shared DAG with itself using an ordinary TC structural comparator. Input DAGs contain depth+1 physical nodes and 2^(depth+1)-1 logical occurrences. It also checks that ordinary profiling ignores a divergent Result remainder while explicit full-result forcing hits a resource bound.

Runs use fresh processes, three samples by default, a 512 MiB child heap cap, 20-second commands (three seconds for the expected noncompletion), and a 180-second whole-job budget. report.json retains commands, source/artifact hashes, manifest pins, raw profiles, and medians. The measured interval is force-begin through force-end: reduction plus sharing-aware traversal, excluding loading and rendering. Allocation counters are GC-sampled; reduction counts and peak residency require separate measurements. Results characterize these particular examples. Universal binding sharing, eager compatibility, and general compiler speedups require broader evidence. Published compiler/support artifacts remain unchanged.

Collections, contracts, and ordinary cleanup candidates (opt-in)

The three library batch runners below require REFERENCE_FIXTURES: authenticated pre-rewrite fixtures, including their reference-source snapshots, selected from frozen 1f24085:test/fixtures (or the identical foundations publication). Historical correction/API-delta controls require those pre-rewrite fixtures. Sources under test still come from the current checkout; the reference flag selects only historical controls and cost/API comparisons.

python3 test/collections_batch.py "$TRICU" \
  --reference-fixtures "$REFERENCE_FIXTURES" \
  --compiler "$GENERATION/build-stable.arboricx" --directory "$PROBE_DIRECTORY"

The directory must be fresh. --resume explicitly reuses diagnostic compilation checkpoints; native receipt keys invalidate changed inputs. The whole-job limit is twenty minutes, with thirty seconds per ordinary call. The descriptive cost screen uses two sizes and three post-warmup samples.

Preparation stages the affected foundations, contracts, IO, HTTP/socket, drivers, and demo consumers. It authenticates every source, stable producer/options receipt, full manifest, dependency receipt, and export pin. Independent complete Results cover transformed collection/proxy values, malformed inputs, short-circuit demand, effect ordering, and ordinary cleanup. Historical correction controls and a same-arity wrong-subject control remain required. Published fixtures stay untouched.

Numeric and decimal candidates (opt-in)

python3 test/numeric_batch.py "$TRICU" \
  --reference-fixtures "$REFERENCE_FIXTURES" \
  --compiler "$GENERATION/build-stable.arboricx" --directory "$PROBE_DIRECTORY"

Stages base, bytes, conversions, prelude, native math, and a driver with the selected stable producer. Authenticates source/options/dependency/export receipts and the driver's full native manifest. The source map must match headers and retain full compiler-root reachability. --resume is diagnostic cache reuse.

Independent complete outputs cover saturation, ordering, carry/borrow, random bit patterns, zero divisors, powers, decimal boundaries, classifiers, malformed encodings, and demand. Operand-swapped and historical zero-divisor negative controls must fail the current oracle. The small interleaved cost screen is descriptive. Run affected collection/HTTP consumers separately. Budgets: fifteen minutes overall, thirty seconds per ordinary invocation, and 8 GiB sampled child RSS.

Binary and bundle candidates (opt-in)

python3 test/bundle_batch.py "$TRICU" \
  --reference-fixtures "$REFERENCE_FIXTURES" \
  --compiler "$GENERATION/build-stable.arboricx" --directory "$PROBE_DIRECTORY"

Stages current binary/bundle dependencies and its driver with authenticated source/options/producer receipts, complete manifests, export pins, and reimported driver identity. --resume explicitly reuses diagnostic checkpoints. Budgets: fifteen minutes overall, thirty seconds per ordinary invocation, and 8 GiB sampled child RSS.

Independent complete Results cover truncations/remainders, UTF-8, manifest versions, suffixes, section ranges, export contracts, roots, node payloads/edges/duplicates, typed codecs, and early rejection. Existing executable fixtures are reconstructed as complete trees. Historical correction and wrong-reader controls prevent an old implementation from satisfying a new oracle accidentally.

The bounded cost screen uses two fork-spine sizes, one warmup, and alternating samples. Report stronger validation's allocation and timing costs honestly. Use this runner for current suffix-preservation checks; arboricx_readers.py compares a historical cohort.

Compiler candidate checks

Independent compiler models, cases, and probe templates live in test/tooling_batch_models.py and test/source_*_models.py; test/unit.py checks the models and corpus invariants. Use compiled candidate artifacts to test edited implementations, alongside the reference and acceptance checks described above.

Current formatter preparation is documented in tri-tools and uses test/prepare_formatter.py, without historical reference inputs. python3 test/shipped_compiler.py checks the shipped accepted builder against its recorded sources and published executable tree, without generating a compiler.

Module/object candidate (opt-in)

test/source_modules.py "$TRICU" --compiler "$STABLE_COMPILER" --seed "$LOWERING_CANDIDATE_DIRECTORY" --directory "$NEW_DIRECTORY" exercises current codecs, native headers, demand, and scripted complete IO traces. The seed is optional, explicit, and reauthenticated. The shared compiler_candidate.py links immutable CAS objects only, copies mutable checkpoints and reaudits all staged current sources/receipts/exports after the build. Existing directories require --resume. Limits remain 1500s overall, 900s per compilation and 65536 MiB sampled child/heap. The seed remains unchanged.

Build/publication candidates (opt-in)

test/source_building.py "$TRICU" --compiler "$STABLE_COMPILER" --seed "$MODULE_CANDIDATE_DIRECTORY" --directory "$NEW_DIRECTORY" checks complete bundle bytes against a Python postorder-interning model, integer field boundaries, lock rows, source maps, receipts, and empty/memo/cycle demand. It emits an audited source_map-selected.arboricx exposing both explicit backends. Use it as the --worker-bundle for test/bootstrap_generation_cli.py with a verified previous generation, selected standard adapter and --backend stable; this separately checks live publication, invalidation, interruption, corruption, and failure of unavailable compiler selections.

test/source_export_cache.py uses the same options, with the build candidate as seed, and checks complete scripted cache-hit/miss/storage/error/selection traces. Both use the shared candidate limits and provenance rules above and report diagnostic reuse explicitly.

Stable construction/publication shards (opt-in)

Use both bounded groups for the complete 28-case stable abstraction corpus:

for GROUP in core sequences; do
  python3 test/stable_abstraction.py "$TRICU" --generation "$GENERATION" \
    --case-group "$GROUP" --directory "$PROBE_DIRECTORY/$GROUP" \
    --memory-mib 65536 --wall-seconds 1500
done

The core group covers 20 construction/application/diagnostic/demand cases; the sequence group covers eight slice/repetition cases. Whole-job and sampled child RSS guards remain active. A single unsharded run can exceed the whole-job budget because each distinct program is separately published; shard the corpus while keeping the limit fixed. complete.json binds selected/completed names and compiler/harness hashes. Unicode sequence fixtures contain explicit scalar cells and test codepoint operations. UTF-8 native-source transport has separate coverage below. Bounded expected divergence records noncompletion within the selected budget; proving nontermination requires separate analysis.

Native source UTF-8 boundary (opt-in focused probe)

python3 test/native_source_utf8.py "$TRICU" --generation "$PREVIOUS" \
  --compiler "$MATCHING_RETAINED_COMPILER" --directory "$PROBE_DIRECTORY"

This transition probe requires a matching retained flat-native compiler and support closure. Use a Nix-built Haskell host and a new output directory. It compiles current read/stage and map consumers with that retained compiler and authenticated support exports. The published frontend is checked separately by test/default_frontend.py, including Unicode source, raw-byte receipts, stdin, and malformed/BOM rejection. It checks exact input/overlay octets, source-domain fingerprints, ASCII parity, multibyte strings/comments, scalar coordinates, and malformed UTF-8/BOM rejection. Host unit tests separately cover binary IO parity, permissions and invalid encoder scalars. Existing scalar-list fixtures cover scalar operations; file decoding requires the byte-level cases above. Limits are 8192 MiB, 900 seconds for compilation, 180 seconds per smoke and 1500 seconds for the whole job. Generation acceptance and fixture publication follow their separate workflows.

Published-library consumer (opt-in)

Builds three curated libraries through the shipped stable compiler, publishes exact releases in a new local registry directory, fetches them into an empty consumer CAS over a controlled GET peer using one project declaration/lock, closes that server, and binds/checks/compiles demos/package-inspector/main.tri offline. The consumer receives library inputs exclusively through fetched packages. The native registry route itself is covered by the separate package-registry checks above.

nix build .#
nix build .#inspectorOracle --out-link result-inspector-oracle
WORK=$(mktemp -d)
nix shell --inputs-from . nixpkgs#python3 -c python3 test/library_inspector.py \
  result/bin/tricu --oracle result-inspector-oracle/bin/inspector-oracle \
  --directory "$WORK/inspection"

inspectorOracle is a test-only Haskell executable using Wire.decodeBundle and verifyBundle to inspect export records as data independently of the compiled inspector. Complete reports must match, including whole-file hash, record count, export order, root indices, kind/ABI and percent escaping. Fixtures cover invalid headers, truncation, malformed manifests, invalid unselected roots/ABIs, duplicate exports/nodes, forward edges, terminal-control/UTF-8 names, and 41 stored nodes representing more than a trillion logical occurrences. An IO export that aborts if executed is inspected successfully. The published libraries and inspector itself are inputs too. Missing files and denied reads must fail nonzero.

On the validation host, the full 18-input publication/consumer check took about five minutes: offline consumer compilation was about 1.5 seconds, while inspecting the roughly 221 KiB inspection library or consumer bundle took about a minute each. These timings describe that validation host and workload; measure other environments independently. The in-memory portable parser is significantly more expensive than the native Haskell report oracle.

It then publishes a local test-only foundation revision with one additional export, changes only the foundation selection, and explicitly updates that one binding. The other two lock rows must stay byte-identical. Stale checks and binding before fetch fail. After fetching, the registry is stopped again and the unchanged consumer is rebound, checked and recompiled offline; its output must still match the independent oracle. The update diff and resulting inspector identity are recorded; the test release stays confined to the local registry. With the registry still closed, project explain must report verified local evidence and project diff must identify the added revision export and structurally identical common foundation exports. Both human-readable reports are retained in the JSON.

The preparation retains artifacts, the initial/current project locks and generated bindings/ownership state, separate producer and consumer stores, compiler/source hashes, command logs and outcomes in report.json as local validation evidence. Signing and distributing provenance requires a separate workflow. Current bounds: 8 GiB GHC heap per tricu child, 900-second compile deadline, 180-second inspection deadline and 2400-second overall command budget. Heap bounds cover managed heap; total process RSS requires separate controls. It remains opt-in; default checks exercise cheap CLI --no-result controls and site-staging immutability without recompilation.

test/project_dependencies.py runs in the default host-policy check with small wire fixtures and a controlled GET peer. It covers frozen/no-network resolution, scoped updates/additions/removals, late-resolution failure preserving the whole lock, registry equivocation (including renames), origin mismatch, missing/corrupt CAS objects, authored/edited/symlink binding collisions, journal recovery, removal of owned bindings only, input/output collisions and offline retries. Inputs are prebuilt wire fixtures and networking is confined to the controlled peer; each CLI child has a 1 GiB GHC heap limit and a 30-second deadline. Haskell tests separately check the metadata codecs, canonicalization, name bounds and duplicate/conflicting selections.

test/project_inspection.py is another default host-policy check. Independently assembled wire/CAS fixtures prove ordered structural equality despite changed physical numbering/object hashes, unequal trees, 81-node exponential DAGs, unreachable records, interface/ABI/kind changes, terminal-safe metadata, and missing/corrupt/malformed evidence even under unchanged pins. Files and mtimes are snapshotted around every report; absent stores must remain absent. Each CLI child has a 512 MiB GHC heap guard and a 30-second deadline. Small Haskell comparisons also agree with independently evaluated constructor equality; large-DAG expected answers preserve sharing. A focused byte-budget test confirms that repeated object references share inspection results and additional objects become unavailable when the retained-byte allowance is exhausted.

The default command preserves checked-in site files. To additionally stage accepted library releases for the existing static-site/dependency-pack pipeline, add --stage-site ext/demo-site to a fresh run. Staging authenticates the bundle bytes, preserves existing versions, refuses conflicts, writes bundles before index entries, and leaves public deployment to a separately authorized operation. --version LABEL selects a new exact release label for the library set; changing executable bytes under an existing name/version is rejected. Use an exclusively owned local site workspace and serialize staging operations to preserve index consistency.

Retained provenance (opt-in)

First retain a successful published-library inspector run as described above. Then capture/rebuild the actual three library modules and inspector:

nix build .#
WORK=$(mktemp -d)
nix shell --inputs-from . nixpkgs#python3 -c python3 test/provenance.py \
  result/bin/tricu --accepted "$INSPECTOR_ACCEPTANCE_DIRECTORY" \
  --directory "$WORK/provenance"

The harness copies producer workspaces/stores to a disposable location, captures four self-contained input packs, deletes that producer copy, and rebuilds in fresh directories from the packs only. It runs outside the checkout, with the packaged compiler data path deliberately unavailable and the registry offline. Each native module and compiler-returned receipt must reproduce exactly. The initial validation host took about 3.5 minutes total: roughly 31/35/139 seconds for foundation/file IO/inspection libraries and 2 seconds for the inspector. These timings describe that validation host and workload; measure other environments independently.

An additional genuine build adds an ignored source comment: source, receipt and pack identities must change while the executable stays identical. That history must also reproduce after its disposable producer is deleted.

A separate negative fixture changes the inspector's source and native receipt to claim the old output, authenticates every changed object, and includes a matching poisoned producer cache. Byte/receipt verification must succeed as claims only; a fresh rebuild must ignore that cache, produce different code, and report a mismatch. This guards the distinction between integrity and actual reproduction. Artifacts, pack pins, commands, timings and outcomes are retained in report.json. Children use an 8 GiB GHC heap ceiling, 900-second compiler deadline and bounded subprocess deadlines within a 2400-second overall budget. Total RSS requires separate controls.

The default test/provenance.py run (wired into nix flake check) uses independent wire/CAS/native-receipt fixtures. These cover no-execution verification with a non-compiler tree, stale source refusal, explicit receipt selection without a cache, immutable capture destinations, incorrect pins, missing/corrupt sources, options, receipts and executables, malformed inventories, path traversal, symlinked CAS directories, an unauthorized compiler, and verification after all producer files have been removed. Verification snapshots require unchanged files and mtimes. Each child has a 512 MiB GHC heap ceiling and a 30-second deadline.

CLI workspace source locations

nix flake check includes declaration parsing, ancestor discovery, nearest-file boundaries, collision/missing-file rejection, and temporary snapshot cleanup. For real packaged-compiler coverage on the Haskell host:

nix build .#
python3 test/workspace_compile.py result/bin/tricu
nix build .#arboricxServerTest --no-link

The focused harness compiles a nested application with transitive reexports from an unrelated working directory, compares its bundle byte-for-byte with a flat workspace build, captures and independently replays the mapped inputs beneath a conflicting parent declaration, verifies cache invalidation after a source edit, and retains negative cycle, missing-import, and source-collision controls. The deployment check compiles the actual repository application via tricu.workspace and exercises its server behavior.

Constructor-only K pruning (opt-in source check)

This check rebuilds source_stable and source_unit from the working source with the packaged compiler, authenticating unchanged fixture dependencies. It checks the rebuilt source implementation using independent expectations:

nix develop -c python3 test/stable_constructor_k.py result/bin/tricu \
  --directory "$WORK/constructor-k"

Use a fresh output directory. GHC and its dependencies are selected through Nix. The harness adds probe-only exports in its disposable workspace; cached residual helpers remain private in production. The independent Haskell oracle uses full free-variable sets; the implementation uses a minimum-index summary. Checks cover successive annotated abstractions, sparse indices, constructor and unsafe-call classification, complete application results against a no-shortcut baseline, opaque arguments, closed-divergence construction, and diagnostic/remainder preservation. It also runs the local control corpus against the rebuilt unit compiler and audits native dependency pins and receipts. Children have explicit heap and time bounds.

These finite controls establish behavior for the tested cases. General termination and demand equivalence require separate proof. Compiler publication additionally requires the full reproduction, cross-host checks, and retention workflow in compiler rebuilding.

Digest-byte validation (opt-in source check)

Rebuild the current source_object module against source-authenticated fixture dependencies and check its private byte guard and public digest predicate:

nix develop -c python3 test/digest_byte.py result/bin/tricu \
  --directory "$WORK/digest-byte"

Use a fresh directory. The harness adds private probe exports only in its disposable workspace, audits native manifests and receipts, and builds the independent Haskell observer through Nix. Canonical bytes are checked against a bounded structural model; malformed trees retain the separately modeled legacy predecessor/comparison behavior. Cases cover all byte values, out-of-range naturals, malformed bits/tails, the eight-bit boundary, complete 64-byte digests, wrong lengths, and ignored/demanded poison payloads. Each observed result is compared completely, not by a prefix or hash alone.

These finite controls are not compiler acceptance or a general demand-equivalence proof. Publication still requires the reproduction, cross-host, site-refresh and retention workflow in compiler rebuilding.

ASCII classifiers (opt-in source check)

native_math's digit, letter, and lowerHex operate on canonical naturals, not arbitrary trees. The focused check compiles current source using the packaged stable compiler, audits its native receipt, and compares complete Boolean trees against independent Integer predicates:

nix develop -c python3 test/ascii_classifiers.py result/bin/tricu \
  --directory "$WORK/ascii-classifiers"

Use a fresh directory. Coverage includes every byte and BMP code point, Unicode boundaries, naturals up to 1025 bits with ASCII low bits, deterministic larger samples, and a wrong-subject rejection control. Malformed/partial-tree results and demand are outside this numeric fast path's contract. The digest consumer's canonical guard and arbitrary-tree fallback require the separate digest-byte checks above. Changes also require compiler source/diagnostic, HTTP header and UTF-8 boundary checks; classifier tests alone are not consumer or generation acceptance. Performance measurements must use matched complete workloads, not only individual predicates.

Compiler name-index controls (opt-in)

python3 test/name_index.py result/bin/tricu --directory "$FRESH_CHECK"
# Also select a rebuilt source_unit bundle, with unqualified export names:
python3 test/name_index.py result/bin/tricu --directory "$FRESH_UNIT_CHECK" \
  --unit "$UNIT_BUNDLE" --reference "$REFERENCE_COMPILER_LIBRARY"

The first rebuilds source_index and its current prelude dependencies through an authenticated packaged compiler. It checks complete results against host first-match lookup, persistent overrides, misses, opaque values, partial-key/tail demand controls, and a deliberately wrong worker. The optional module check uses 75 independent source outcomes (shared with source_equations.py), compares complete reference/candidate results, and checks environment precedence and demand. Selected unit/reference artifacts are fingerprinted, not source-freshness certified by this option; select audited rebuilt artifacts. Finite poison tests are not a general termination-equivalence proof. This check neither accepts a generation nor publishes fixtures.