# Engineering verification workflow

Read this document before non-trivial verification, performance work, or an
environment deployment. The root [AGENTS.md](../../AGENTS.md) owns the concise
working rules; this document owns the detailed verification procedure.
Apply it to the changed behavior and delivery scope. Documentation-only edits
need structural/link checks, not application suites. Existing relevant boundary
guards still run when their contract changes. Do not add tests that merely
mirror reversible, low-impact edits.

## Local-first verification and CI role

Local functional verification uses the target L2 delivery repository's
`docs/local-independent-deployment.md` and its three checked-in entrypoints:
`scripts/local_l0.py`, `scripts/local_app_install.py`, and `scripts/local_l1.py`.
Follow L0 `init` → App installation → L0 `activate` → L1 `deploy`; the L2
runbook owns prerequisites and flags. Local images/tags are accepted without
release-version/provenance comparisons. This is first-install and independent
process verification; it does not provide metadata upgrade, rollback or
partial-install recovery. Keep tenant deployment implementation in L2.

- Use local verification for the relevant application/API/browser and worker
  journeys before environment rollout. Record selected images, installation
  inputs, cases and results; local success alone does not prove a release.
- Test, Staging and other designated non-production environments may be used
  for production-simulation verification through their L2 runbooks/controllers:
  production topology, migrations/upgrades, failure/restart behavior and
  integrations. Select a topology and operation that actually prove the claim.
  Record exact image digests, metadata revision and acceptance evidence.
- CI owns clean-checkout/code gates and environment publication/promotion proof.
  Formal release acceptance still requires the target workflow's immutable
  candidate and provenance rules; local image overrides are not promotion proof.
- Reuse relevant fixtures, assertions and acceptance runners across local and
  environment verification. Report topology differences and unsupported local
  paths explicitly rather than claiming equivalent coverage.
- On an application failure, reproduce the failing path at the smallest
  environment that supports it, fix the owning layer and verify the failure
  class before redispatch. Do not use repeated deployment runs as the debugger.

### Batched test execution

A code edit is not a test boundary; a coherent evidence boundary is. Before
implementation, define the verification matrix for the relevant owners,
entrypoints, topology/concurrency cases, failure windows, and resource limits,
then accumulate the corresponding edits and run one meaningful batch.

- Run verification in tiers: static/compile checks, batched owner-level tests,
  complete producer-to-consumer walking slices, then full package/repository
  suites only after the candidate is frozen.
- Use targeted batches as the development debugger. Do not repeatedly run a
  long full suite to isolate one failure; isolate the failing test first.
- For long runs, set a bounded timeout, persist structured/full logs, preserve
  the real exit status, and report the last active test plus actionable failure
  diagnostics rather than routine passing output.
- Rerun a green batch only when later code can affect the invariant it proved.
  Do not rerun unaffected modules after comments, formatting, or unrelated
  changes; accumulate small follow-ups into one final relevant batch.
- A skipped integration test is not a pass. Supply its declared environment and
  confirm that the intended real path executed.
- When a full-suite failure appears outside the changed ownership boundary,
  prove that with the current-tree diff and an isolated rerun before deciding
  whether it blocks; do not dismiss it by assumption.

Before a non-trivial test batch, communicate the evidence contract concisely:

> Verification batch: `[invariants]`; scope: `[packages/entrypoints/topology]`;
> why now: implementation for this evidence boundary is complete; stop
> condition: `[first decisive failure or bounded timeout]`; full-suite policy:
> run only after this batch is green and the candidate is frozen.

---

## Performance Work Standard

For performance incidents, durable recording is the top priority. Do not rely on
memory or impressions: every profiling/optimization loop must append a short
record to the relevant performance learned doc before starting the next code
change. Record the run id, commits, environment, workload shape, profile result,
what changed, what failed, what was learned, and the next hypothesis.

Work in evidence loops:

1. Establish or refresh the model from current code, architecture, and data
   flow.
2. Add or collect profiles that can prove or disprove the model; prefer one
   decisive profile over many small guesses.
3. Analyze the numeric evidence and system design together to pick the
   highest-ROI bottleneck.
4. Implement the narrowest clean fix that preserves correctness and the
   L0/L1/L2 boundary: L0 owns generic mechanisms, L1 owns product grammar
   and shipped defaults, L2 owns admin-authored configuration; no tenant/provider
   special case belongs in L0.
5. Re-run the same workload, compare against the initial and previous baselines,
   and record both improvements and regressions.

Stop rather than force progress when the next optimization would break
correctness, metadata-driven design, or L0/L1 ownership; when the profile shows
no high-value bottleneck; or when a larger stress test would only amplify a
known smaller-scale failure. Larger load tests are validation, not a substitute
for diagnosis.

## Project commands

Select the relevant module's declared runner from its README, go.mod, or
package.json. These are available checks, not an unconditional per-task suite:

```sh
(cd backend && go test ./...)
(cd shared && go test ./...)
(cd frontend && npm run build)
git diff --check
```

Run full suites only after the relevant owner batch is green and the candidate
is frozen, when required by the changed scope or release gate. The frontend
build rewrites `frontend/public/version.json`; restore only changes produced by
this build unless the version update is intentional. Preserve pre-existing
user edits.
