You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
templates/assembly-root/scripts/validate-pins.py: a .github/workflows/ directory that this user cannot list or search ends the run in a PermissionError traceback, exit 1, where a workflow file it cannot open is a workflow-unreadable refusal, exit 2 #434
Found while finishing PR #359's branch (the fix for #359, a workflow FILE that is not UTF-8 or that this user cannot open). Not claimed.
What is wrong._workflow_refs (templates/assembly-root/scripts/validate-pins.py:170-196) still lets a PermissionError escape when the .github/workflows/ DIRECTORY, not a file in it, cannot be opened: workflows.is_dir() (:184), workflows.iterdir() (:186) and the is_file() stat on each child (:187) are unguarded. main() handles Refusal only, so the run ends in a traceback, exit 1, which is the code this validator uses for a finding. #359 refuses a FILE this user cannot open (workflow-unreadable); #383 and PR #403 do both the file and the directory for bump-leg.py.
Probed on the #359 branch's template (no git, no network, no gh), by calling _workflow_refs on a root holding one UTF-8 legs.yml:
mode
result
.github/workflows/ 000 (cannot be listed)
PermissionError escapes
.github/workflows/ r-- (listable, not searchable: is_file() stats each child)
PermissionError escapes
.github/ r-- (workflows/ cannot be statted)
PermissionError escapes
.github/workflows/ 755 (control)
returns
The probe is impl359-validate-pins-workflow-utf8/tools/probe-unlistable-directory.py in the lane's attachments, with its log. The is_file() calls on the pin and the manifest (:210, :366, :497, :677) have the same shape and were not probed.
What it should do. Refuse by name, exit 2, in the words #359's workflow-unreadable uses (.github/workflows: cannot be listed (Permission denied)), with a remediation that says to restore read and search access, then run the same command again. It is a pinned template copy, so the change moves scripts/validate-pins.py's digest for every project already cut, as #359's does.
How to test. Beside tests/test_validate_pins_unreadable_workflow.py, a scaffolded root and a chmod on the directory, restored in a finally; skip on Windows and when os.geteuid() == 0 (tests/test_family_add_refusals.py:677). Each row above exits 2 with the refusal id and the path, and no Traceback.
CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-15T23:03:44Z, for #434
Logged in lanes/log/openRepoShape-4.md at ac2f51a79fc09f97443d587984735a2bee064c89.
The three reads (lane-collision-protocol Rule 1):
1. existing `CLAIMED —` comments on opensoft/openRepoShape#434:
none
2. `gh pr list --repo opensoft/openRepoShape --state all --search "#434"`, kept where the row or its body names `#434`:
none
3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `434` as a whole token:
none
Activity
brettheap commentedon Oct 15, 2026
CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-15T23:03:44Z, for #434
Logged in
lanes/log/openRepoShape-4.mdatac2f51a79fc09f97443d587984735a2bee064c89.The three reads (lane-collision-protocol Rule 1):
tests/test_validate_pins_unreadable_workflows_dir.py: the 3.14 stand-…
docs/release-notes/v1.1.0.md: refreshed at main 4cf5fb0 (49 pull requ…
tests: validate-pins.py's workflow scan skips a directory, a dangling…
shape-doctor.py: the `legs`, `manifest kinds` and `shape currency` ro…