fix(policy): one checked discovery policy for policy_check.sh (follow symlinks, fail closed, stay in checkout) - #383
Merged
Conversation
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.
Summary
Closes #377.
tools/policy_check.shfound its input files with about 25 separatefindcalls. They used the default-Pmode, so they never descended into a symlinked directory, and most filtered with-type f, so they dropped a name-matching symlink before any read gate saw it. Some also discarded find errors. The linter could report green on files it never looked at.This PR gives the script one discovery policy, implemented once:
discover_paths, runsfind -L(DISCOVERY_FIND_BASE=(-L)) and returns find's exit status through a NUL sentinel record, so a failed or truncated discovery is never read as an empty result.discovery_gate_status, withfiles,dirsandrawgates, turns dangling links, non-regular files and unreadable files into findings instead of silent skips.realpath -mand rejected as a finding, never read, if it resolves outside the repository root. At most one containment finding is emitted per discovery call; any further escaping paths are counted.discover_checked_pathscombines the engine, the containment check and the gates. CHECK 1-15, SAFETY, COMPAT and WORKFLOW-FIXTURES all route through it. CHECK 15 uses therawgate so that its own read gate stays its type check. The old CHECK 15 private discovery helper is deleted. The only rawfindcalls left are the engine and two comment-marked-Pnegative controls.dirsgate, so a missing root is a failure rather than a[SKIP].Witnesses
DISCOVERYcanary runs over committed fixtures: a symlinked directory, a dangling symlink, and an escape symlink that points outside the repo. It asserts that-Ldescends where-Pdoes not, that the gate works in both directions, that the wrapper composes correctly, that the containment check and its cap work, that a nonexistent root propagates a non-zero status, and that the fixtures are still symlinks in this checkout.tests/policy/safety-discovery-policy.json, pins 18 load-bearing literals. Each was mutation-tested.tests/policy/safety-tracker-ref-guard.jsonhas a corrected description; its pinned literals are unchanged.Output unchanged on the real tree
policy_check.sh --strictfindings are identical tomain: Total 29, Allowlisted 29, New 0. Checks passed is 74 / 75 (was 72 / 73): the new DISCOVERY block and the new safety fixture each add one check. Safety fixtures: 43 / 43.Validation
bash tools/validate.sh --changed: escalated to the full suite becausetools/**changed. rc 0, all suites pass.bash tools/validate.sh --self-test: ALL PASS.Versioning
None. Only
tools/,tests/anddocs/adr/changed. There is noplugin/change and no bump trigger.Local review
Local Codex review found two issues. Both are fixed:
The final pass raised one high finding that was rejected as an already-recorded residual: containment stops the read but not the walk, so
find -Lstill traverses an external tree before its paths are rejected. This limit was accepted when containment was chosen, and it is recorded in ADR-0031 and in the engine header. The finding's recommendation, to drop global-L, would reverse the chosen policy.Known residuals (recorded, not fixed here)
core.symlinks=false, the committed symlink fixtures become text files and the canaries fail loudly, by design.findthat bypasses the wrapper.Follow-ups
validate.sh,validate_workflows.sh,validate_reports.sh,test_*.sh) have the same discovery gap and need the same containment.plugin/breakcore.symlinks=falseconsumer installs. This is a separate content rule.