Three new lint tests close gaps in the INFINITO_* SPOT contract:
* tests/lint/filesystem/env/test_default_env_keys_handled.py
Every default.env key must be wired through a handler.
* tests/lint/filesystem/env/test_used_keys_declared.py
Every INFINITO_* in .sh/.py must live in env/{default,ci}.env or
a handler; per-line `# nocheck:` suppresses runtime-only refs.
* tests/lint/filesystem/python/test_no_infinito_get_defaults.py
Forbid ANY default in `.get("INFINITO_*", ...)` -- including the
empty-string fallback (which silently masks an unset key). The
nocheck check walks every physical line the call spans so an
autoformat-split call still honours the marker.
Cache namespace flattens to a single prefix:
INFINITO_PACKAGE_CACHE_* -> INFINITO_CACHE_PACKAGE_*
INFINITO_REGISTRY_CACHE_* -> INFINITO_CACHE_REGISTRY_*
The five previously driver-injected paths (APT_LIST, NPMRC,
PIP_CONF, REGISTRY_PROXY_CONF, FRONTEND_CA_FILE) move into
env/default.env and passthrough.STATIC_KEYS; the
`cache_env_overrides()` helper and its two call sites are gone
along with the test-fixture override for FRONTEND_CA_DIR.
SPOT-strict rewrites:
- 19 sites: `something.get("INFINITO_X", "")` -> subscript
`something["INFINITO_X"]` (loud KeyError when env loader did
not run; all keys live in env/default.env).
- 2 handler-internal bootstrap reads suppressed with
`# nocheck: handler-bootstrap-read`.
- 30 runtime-only / driver-injected / test-fixture references
annotated with `# nocheck: <reason>` per-line.
- Unit tests that previously removed SPOT-guaranteed keys via
`{k: v ... if k \!= KEY}` or `clear=True` switch to setting
the key to "" explicitly, matching the new contract.
Side fixes:
- INFINITO_DNS_DOMAIN + INFINITO_DNS_HOSTS_FILE move from
shell-side defaults in common.sh to env/default.env and
passthrough.STATIC_KEYS.
- dns_systemd_is_operational() drops the dead
INFINITO_DNS_FORCE_HOSTS_FALLBACK override branch (the
variable was never set anywhere).
- INFINITO_WORKER_FETCH switches from `os.environ.get(KEY, "1")`
to `os.environ[KEY]`.
- scripts/tests/code/wrapper.sh exec args move into a bash
array so `# nocheck:` on INFINITO_TEST_TYPE can live on its
own element line (SC2215 fix).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The package-cache active probe in
scripts/tests/environment/utils/cache.sh had `releases/40/...`
hardcoded as the upstream path for the `yum-fedora` Nexus proxy.
Fedora 40 went EOL in May 2025 and dl.fedoraproject.org stopped
serving its repodata, so the probe failed every Test Environment
(fedora:latest) CI job with:
[probe] package-cache: GET /repository/yum-fedora/releases/40/Everything/x86_64/os/repodata/repomd.xml
curl: (22) The requested URL returned error: 404
[FAIL] package-cache: proxy 'yum-fedora' did not serve
'releases/40/Everything/x86_64/os/repodata/repomd.xml'
Resolve the version dynamically from the runtime image's
`/etc/os-release` instead. The new `_resolve_fedora_release` helper
runs `docker run --rm --entrypoint /bin/cat <image> /etc/os-release`
and lifts `VERSION_ID` via awk, so `fedora:latest` is tracked
automatically and future EOL transitions no longer require a code
change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
probe_did_inner_build() in scripts/tests/environment/utils/cache.sh
hardcoded the compose network as `infinito-nexus_default`. Compose
derives the network name from the project name, which defaults to the
host CWD basename — `infinito-nexus` locally, `infinito-nexus-core` in
the CI fork, something else again in Act runners and worktrees. CI
therefore failed the test-environment matrix on every distro with
`network infinito-nexus_default not found` even though the cache
stack itself was healthy.
Look up the network the running `infinito-package-cache-frontend`
container is actually attached to via `docker inspect` and use that.
Fail loudly if discovery returns empty rather than silently skipping
the probe.
Verified via `make act-workflow ACT_WORKFLOW=.github/workflows/test-environment.yml ACT_JOB=test-environment ACT_MATRIX='dev_runtime_image:debian:bookworm'` — Job succeeded, probe step reports `[OK] DiD inner-build flowed through cache frontend`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the previous OR-based assertion in scripts/tests/environment
(which trivially passed because the Nexus log always grows from
health probes) with a richer set of helpers split across two files
under utils/ for SRP/SPOT.
scripts/tests/environment/utils/cache.sh (new):
* expected_system_proxy_for_runtime maps DEV_RUNTIME_IMAGE to the
Nexus proxy that handles its system package manager (apt-debian,
apt-ubuntu, yum-fedora, yum-rocky; empty for Manjaro/Arch where
pacman is not cached).
* nexus_repo_requests counts only /repository/<name>/... entries in
the Nexus request log, optionally scoped to one proxy. Filters out
health probes, admin REST calls, and Web-UI traffic.
* registry_cache_flows counts every cache-flow status (HIT, MISS,
REVALIDATED, UPDATING, STALE) so cold deploys also count.
* assert_caches_used fails with a per-cache breakdown when any of
three independent conditions is violated: total Nexus repo
traffic = 0, the runtime's expected system proxy has 0 cached
requests, or the deploy itself produced 0 registry-cache flows.
* probe_caches actively fetches a known upstream resource through
each cache (apt-debian/dists/bookworm/Release for the package
cache, /ca.crt for the registry cache).
* probe_did_inner_build drives a throwaway docker build whose
apt-get update runs against deb.debian.org. The build container
is placed on the compose network and pinned via --add-host to the
frontend IP, exactly like the runtime override that
roles/sys-svc-compose/files/compose.py injects for app builds.
After the build the test snapshots
``docker logs infinito-package-cache-frontend`` and asserts the
frontend recorded new requests, proving DiD apt traffic flows
through nginx -> Nexus apt-debian and not directly to upstream.
DOCKER_BUILDKIT=0 because BuildKit refuses --network=<compose-net>.
scripts/tests/environment/utils/common.sh (renamed from lib.sh):
keeps the bootstrap, constants, inventory inspect, and
assert_http_status; cache helpers moved out so the file is
single-concern.
scripts/tests/environment/07_deploy_minimal.sh sources both files;
order is snapshot, deploy, probe_caches, probe_did_inner_build,
snapshot, assert_caches_used. Active probes contribute traffic that
the AND assertion verifies, so the assertion is robust on deploys
that do not naturally trigger inner-build apt traffic.
.github/workflows/test-environment.yml: propagate DEV_RUNTIME_IMAGE
into the inner ``docker run`` so per-distro probe target and proxy
expectation resolve correctly inside the orchestrator.
.gitignore + .dockerignore: also ignore .claude/settings.local.json,
which compose mounts as /dev/null and which the classic docker
builder would otherwise try (and fail) to read into the build
context.
Verified end-to-end with five iterations of
``make act-workflow ACT_WORKFLOW=.github/workflows/test-environment.yml
ACT_JOB=test-environment ACT_MATRIX='dev_runtime_image:debian:bookworm'``.
The final iteration reports +81 apt-debian, +235 registry-cache
flows, +13 frontend log lines from the DiD probe, and "[OK] both
cache stacks observed activity" plus "[OK] DiD inner-build flowed
through cache frontend".