Verification

Every gate used to reason about the tree without ever starting it. Now the tree has to compile, the suite has to run, and the application has to boot and answer before anything is called finished.

Cheap and certain first, judgement last#

Every gate is deterministic until the final one. The table below is the same order with the failure conditions spelled out.

  1. 01EmptySomething was committed
  2. 02ScopeOnly declared paths touched
  3. 03ParseSource parses, wiring present
  4. 04BuildThe tree compiles
  5. 05TestsYour own suite passes
  6. 06TypesNo new diagnostics
  7. 07AcceptThe judgement call

The gate order#

The deterministic gates run first, in order. The judgement call comes last, and only sees diffs that already passed everything cheap and certain.

#GateFails when
1Empty buildNothing was actually committed
2ScopeA file outside the task’s declared scope was touched
3Static probesThe source does not parse, or wiring is missing
3bBuildThe tree does not compile
4TestsThe repository’s own suite fails
4bTypecheck and lintA new diagnostic appeared — pre-existing ones are ignored
5AcceptanceThe diff and its evidence do not satisfy the task

The smoke probe#

After the branches are merged, the smoke probe runs against the integrated tree — never per task, because a service is only whole once everything is assembled.

For each service that declares a start command it installs, builds, starts the process, polls the health route, requests each declared smoke route, and tears everything down.

Constraints the probe was built with#

Each of these was learned the hard way.

Never hangs
A per-service readiness budget and a whole-module watchdog force-kill every tracked process group. A stuck verification phase is worse than a wrong one.
Never leaks processes
New sessions plus process-group kills, because a preview server spawns children that outlive the shell that started them. A test asserts the group is actually dead.
Never touches your dashboard port
The port your local dashboard runs on is reserved and the allocator re-rolls. It binds loopback only, never all interfaces.
Never blocks shipping by itself
It reports, the repair loop reacts, and the gate decides. Same trust class as the integration test.
No new dependencies
The standard library only. A probe is not worth a package.
Flake discipline
A failure is re-run once from a fresh process, and only a reproducing failure counts.

A failed probe feeds the repair loop#

A smoke failure goes into the same self-heal loop the integration tests use: up to three fixer rounds, with scope widened to every path the plan touched, re-probing after each.

Its objective names the causes that actually produce this failure — a route never mounted, a handler raising, a missing environment default, a wrong host or port binding, a build output that was never produced.

Common questions

What if my repository has no test suite?

The gate records that the suite did not run, and that is not treated as a pass. Shipping requires a suite that ran and passed.

How does Tharas know how to start my services?

From a services declaration in the repository that says what exists and how to run each one. Where it is absent, the build command is resolved from the conventions of the stack.