N2API's local verification commands isolate temporary files and disposable
Docker resources so repeated development runs cannot silently consume the host
disk. Use the root Makefile instead of creating ad hoc caches under /tmp.
Each test run creates a unique directory with mktemp -d under
${N2API_TMP_ROOT:-${TMPDIR:-/tmp}}. An EXIT/INT/TERM trap removes only
that directory. Concurrent runs have distinct run IDs and active markers and
hold a shared lifecycle lock. Maintenance requires the exclusive lock, so one
run or maintenance command cannot remove another active run.
The lifecycle exports these locations:
GOCACHE,GOTMPDIR,GOPATH,TMPDIR, andXDG_CACHE_HOMEare unique to the current run and are deleted at exit.GOMODCACHEuses.cache/dev/go-modand is deleted after a run if it exceedsN2API_GO_MOD_CACHE_MAX_MIB(default2048) and no other managed run is active.BUN_INSTALL_CACHE_DIRuses.cache/dev/bun, capped byN2API_BUN_CACHE_MAX_MIB(default1024).PLAYWRIGHT_BROWSERS_PATHuses.cache/dev/playwright-browsers, capped byN2API_PLAYWRIGHT_CACHE_MAX_MIB(default2048). Playwright output, traces, screenshots, and reports stay inside the current run directory.- SvelteKit's bounded
.svelte-kitworkspace remains underfrontend/so generated server modules can resolve frontend dependencies. The adapter-staticbuildoutput is redirected into the current run directory. Deep cleanup removes the repository-local.svelte-kitworkspace.
Failed Playwright evidence is deleted by default. Set
N2API_KEEP_FAILED_ARTIFACTS=1 to retain it under
.cache/dev/artifacts/<run-id>. Regular cleanup keeps at most five sets for
seven days by default; override N2API_ARTIFACT_KEEP_COUNT or
N2API_ARTIFACT_TTL_DAYS when needed.
Docker E2E and restore resources use a unique Compose project plus both
io.knowsky.n2api.resource=test and io.knowsky.n2api.run-id=<run-id> labels.
The creating process runs compose down --volumes --remove-orphans --rmi local
from its trap. This removes that run's containers, network, test database
volume, and locally built test images without removing pulled or production
images.
Run the normal unit checks:
make testPostgreSQL store tests that create schemas or truncate fixtures require both
N2API_STORE_TEST_DATABASE_URL and
N2API_STORE_TEST_ALLOW_DESTRUCTIVE=1. The connected database name must contain
a separate test, e2e, or restore segment. The suite checks
current_database() before migrations or cleanup and refuses the development
database n2api even when a database URL is supplied accidentally. Create a
dedicated disposable database such as n2api_store_test; never point store
tests at the deploy Compose database.
Run isolated Docker verification:
make test-go-quality
make test-critical-race
make test-control-connections
make test-e2e
make test-contracts
make test-request-log-profile
make test-management-list-profile
make test-production-deploytest-go-quality installs Staticcheck 2026.1 from the fixed Go module version
v0.7.0 into the run directory, then runs Staticcheck and go vet across the
backend. test-critical-race and test-control-connections start isolated
PostgreSQL projects and cover critical packages, real process lifecycle, locks,
LISTEN reconnect, authentication, and budget concurrency. The Request Log and
management-list profiles use separate labelled PostgreSQL projects without
publishing the database port; the former loads one million synthetic rows.
Managed cleanup removes every test database volume.
The development Compose stack starts postgres-backup after PostgreSQL is
healthy. It creates a custom-format dump immediately and every six hours by
default, validates each archive with pg_restore --list, then atomically moves
it into the ignored backups/ directory. The directory is 0750 and archives
are 0640, owned by root and the configured host operator group. Set
N2API_BACKUP_GID in .env to the numeric result of id -g for the operator
who copies or restores backups; it defaults to 1000. Existing matching dumps
are normalized when the sidecar starts. Files older than seven days are
removed. Override the bounded interval and retention with
N2API_BACKUP_INTERVAL_SECONDS and N2API_BACKUP_RETENTION_DAYS in .env.
Create and validate an additional backup immediately:
make backup-devInspect the sidecar with docker compose -f deploy/compose.yaml logs postgres-backup. A healthy sidecar proves that its latest local archive passed
the archive-list check, is recent, and still exists as a non-empty readable
file; it does not prove a full restore. Continue running the
isolated restore drill documented in the operator manual, and copy important
backups to encrypted off-host storage. Local dumps are lost with the VPS disk.
Install the pinned Playwright Chromium build into the controlled browser cache, then run Playwright commands through the wrapper:
make playwright-install
make test-playwright PLAYWRIGHT_ARGS='test /tmp/n2api-browser-tests/example.spec.ts'The project does not add Playwright as a frontend dependency. Temporary browser tests and configuration should remain outside the repository.
make disk-check is read-only. It warns when the checked filesystem is at or
above N2API_DISK_WARN_PERCENT (default 80). Managed verification commands
run the strict check automatically and refuse to start when free space is below
N2API_DISK_MIN_FREE_GIB (default 10). The report separates the protected
deploy Compose volume, labelled test resources, and unknown/shared Docker
usage.
Run safe, idempotent maintenance with:
make clean-dev-artifactsThis removes expired marked run directories, expired retained evidence,
over-limit controlled caches, and inactive Docker resources carrying the exact
N2API test label. It never selects the production deploy Compose project,
deploy_n2api-postgres, unlabelled resources, global Bun cache, or global
Playwright browser cache.
Deep cleanup is explicit:
make clean-dev-artifacts-deepIt additionally removes legacy N2API Go caches at exact known paths and the
repository's controlled caches. It still does not remove production resources,
global user caches, tmp/imagegen, backups, bind mounts, or unknown data.
Do not use docker system prune, docker image prune, or
docker volume prune as routine N2API cleanup. They operate beyond this
project's ownership boundary. Builder-wide cleanup used by the documented
no-cache development stack refresh is a separate explicit operation and must
not run concurrently with another build.