fix(checks): build-check validated the env file under --project-root then read values from cwd (BACKLOG #1062) - #242
Merged
Conversation
…then read from cwd (BACKLOG #1062) `messagefoundry check --project-root R` anchored --config and --service-config under R and HARD-FAILED when R/<env_dir>/<env>.toml was absent -- then dropped R. run_checks took no root, so _check_build re-derived the value anchor from Path.cwd(). The gate verified the file under the root the operator named and read the VALUES from wherever the shell happened to be. `serve` never had this. It writes the root into cli["environments"]["base_dir"] before load_settings. The comment directly above the defect even claimed parity -- "Resolve env() against the active environment the same way serve does" -- and serve's way IS that assignment, which was the missing step. THE FIX IS SERVE'S MECHANISM, not a new one. run_checks gains `project_root`, threaded to _check_build and applied as a [environments].base_dir CLI override, so load_settings' CLI > env > file precedence puts it above a file-set base_dir exactly as serve does. The existing resolve_values_base_dir call is unchanged and becomes correct because base_dir is now populated; left unset it still falls back to the process directory, so the documented `check --config config` invocation is byte-identical. Scope confirmed by reading, not assumed: four call sites in checks.py load settings this way, and only _check_build resolves environment VALUES. The other three are unaffected. TESTS ASSERT THE DIVERGENCE, which is the only shape that can fail: the process directory holds its OWN value file with a different host. A test run from inside the root passes with the bug present, because both anchors agree there -- the same masking that hid the rule 3d defect on Windows. AND THE PRE-FIX BEHAVIOUR WAS REPRODUCED, not inferred. Reverting both files and running the same invocation from a directory carrying its own environments/ prod.toml showed the values read from the PROCESS directory while the root was the one validated. Stated because the test's own pre-fix failure is only a TypeError -- the parameter did not exist -- which proves the API is new and NOT that the old behaviour was wrong. The reproduction is what proves the defect. Consequence, in the conditional per section 0: build-check is a required blocking check for the ADR 0092 posture-keyed insecure-hop refusal, whose hosts and schemes are env()-supplied, so a deploying site could have had that refusal decided against a different environment's values than the one it named. Nothing is deployed, so this is what a deploying site would have hit. Verified: ruff format + check clean, mypy strict clean across 262 files, 122 tests green across the anchoring, checks, gate-parity, offline-resolution and environments suites. Banner closed in the same commit; headings unchanged at 142 on both sides, since a banner edit adds none.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes BACKLOG #1062. 4 files, +118 -2. Closes the item's banner in the same commit.
THE DEFECT.
messagefoundry checkvalidated that<root>/<env_dir>/<env>.tomlEXISTSunder the supplied
--project-root, then dropped the root --_check_buildre-derived thevalue anchor from
Path.cwd(). So it verified the file under the supplied root and read theVALUES from wherever the shell happened to be standing.
THE FIX IS SERVE'S OWN MECHANISM, not a new one.
run_checksgainsproject_root, threadedto
_check_buildand applied as an[environments].base_dirCLI override, soload_settings' CLI > env > file precedence puts it above a file-setbase_direxactly asservealready does (cli["environments"]["base_dir"] = args.project_root). The existingresolve_values_base_dircall is UNCHANGED and becomes correct becausebase_diris nowpopulated. Left unset it still falls back to the process directory, so
check --config configis byte-identical.SCOPE CONFIRMED BY READING, not assumed from the item: four call sites in checks.py load
settings that way, and only
_check_buildresolves environment VALUES. The other three areunaffected.
⭐ THE WEAKNESS IN THE TEST EVIDENCE, STATED RATHER THAN LEFT TO BE FOUND. The tests' pre-fix
failure is only a TypeError --
run_checks() got an unexpected keyword argument 'project_root'-- which proves the API is NEW, not that the old behaviour was WRONG. That isa weaker red than it looks. The defect was therefore reproduced BEHAVIOURALLY instead: both
files reverted, the same invocation run from a directory carrying its own
environments/prod.toml, and measured --The reproduction proves the defect; the tests guard the fix.
THE TESTS ASSERT THE DIVERGENCE, which is the only shape that can fail: the process
directory holds its own value file with a DIFFERENT host. A test run from inside the root
passes WITH the bug present, because both anchors agree there -- the same masking that hid
the rule 3d defect on Windows, and the reason #1000's asymmetry rule requires a control that
can distinguish. A second test asserts the no-root fallback still anchors on cwd, so this is
a correction and not a widening.
VERIFIED: ruff format + check clean; mypy strict clean across 262 files; 122 tests green
across the anchoring, checks, gate-parity, offline-resolution and environments suites. Based
on 132dc68 (current main), merge-tree clean. Headings 142 on both sides -- a banner edit
adds none.