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
materialize_assembly_root writes the shape files through a root-kept symlink to anywhere on disk, and crashes with a traceback on a link loop, after both legs are pushed #183
What is wrong.materialize_assembly_root writes the shape's files into the assembly by plain path, so it follows any symlink the plan keeps in the root.
Writes outside the work directory. A source that keeps .github -> /some/absolute/dir, or a relative link out of the tree, makes the adoption write validate.yml outside the work directory. One review run wrote it into a directory the operator never named.
Crashes after both legs are pushed. A symlink self-loop, or a checkout without symlinks (core.symlinks=false), crashes the materializer with a raw Python traceback.
On main the adoption then says adoption verified. On the #167 branch (PR #182) the verification at least fails, because the split lacks the pinned file. Neither refuses before the legs exist.
Found by the re-verification of the #167 fix (head b635473). Pre-existing on main.
What would fix it.check finds, and execute refuses before any leg exists, a root-kept symlink that a shape path runs through and that resolves outside the source tree or into a mounted leg (the latter is #172's case). The materializer resolves each written path inside the assembly and refuses, never writes, outside it. A loop is a refusal, not a traceback.
CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-09T13:56:49Z, for #183
Logged in lanes/log/openRepoShape-1.md at 6b81983b79d65934bac3053a12c80268f8f0ce34.
The three reads (lane-collision-protocol Rule 1):
1. existing `CLAIMED —` comments on opensoft/openRepoShape#183:
none
2. `gh pr list --repo opensoft/openRepoShape --state all --search "#183"`, kept where the row or its body names `#183`:
none
3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `183` as a whole token:
none
(lane openreposhape-5 (openRepoShape-5), 2026-10-12T02:27Z) COMPOSITION NOTE for the #183 branch, fix/adopt-root-kept-symlinks, read at 6c44591.
What #313 adds. Lane 5's PR #313 (fix/adopt-check-shape-paths, #262/#263) adds check findings and execute refusals for a kept root path where the shape writes a directory or its shape/ collision copy.
Text conflicts.6c44591 has three conflicts with #313, all in adopt-project.py. It has two of them against main alone. #313 follows 6c44591's backticks for the paths its messages name.
Evidence. The re-verification section of reviewP-report.md, under handoffs/openRepoShape/attachments/lane-openRepoShape-5/ in opensoft/brett-wip.
Found by lane 5's review of fix/adopt-check-link-and-manifest (69c54c9, the fix for #303 and #305), its N1. It is a composition of that branch with lane 1's fix/adopt-root-kept-symlinks (6c44591), not a bug in either alone.
What it is. Lane 5's branch adds plan-empty-symlink: check reports every 120000 entry whose blob is empty, wherever it sits in the tree, and execute refuses it before any leg exists. Lane 1's branch already reports the same link, through _Walk.empty and plan-root-symlink, when it is kept in the root at or above a shape path. On the merged tree such a link is reported twice, and execute's refusal wears the first finding's code, plan-empty-symlink. The two remediations agree (fix it in the source), so the duplicate and the code are what is wrong.
The failing test. On origin/main ab623dd with both branches merged (the review resolved the conflict blocks in adopt-project.py mechanically, keeping both sides; that is not either lane's resolution):
Only execute's refusal code differs: the test's check assertion still passes, because symlink_findings keeps only the plan-root-symlink line. Three other tests in that file fail on the same tree and do not come from lane 5's branch. origin/main ab623dd with 6c44591 alone fails test_check_reports_the_link_and_execute_refuses_it_before_any_leg[a-link-at-the-copy-itself] and test_the_materializer_refuses_before_it_writes[the-copy-onto-a-file] and [the-copy-into-a-directory] (3 failed, 93 passed), because #313's plan-root-blocks-shape-copy and materialize-copy-blocked now answer first. Lane 5's branch adds exactly one failure, the one above.
Who drops the duplicate depends on which lands second. Keep one finding per empty link, and let it be plan-empty-symlink: it reads every empty link in the tree whatever the plan does with it, where plan-root-symlink sees only the ones at or above a shape path.
If lane 5's branch lands first, lane 1's branch drops its empty-target half: _Walk.empty (set at the if not target: hop) and the empty-target sentence in _root_symlink_finding. The test above then expects plan-empty-symlink, or goes.
If lane 1's branch lands first, lane 5's branch drops the duplicate when it merges, and changes that test the same way. Nothing for lane 1 to do beyond expecting it.
The two branches also conflict textually, in 3 blocks of adopt-project.py (the module docstring's check paragraph, _entry_findings' docstring and its return line): the same 3 that c7c02fa, the base of lane 5's branch, has with lane 1's. Against origin/main 0f67f7b, lane 1's branch has 5 blocks on its own.
One more overlap, for whoever resolves it: a dangling link kept at project.yaml is reported by plan-root-blocks-manifest (lane 5) and by plan-root-symlink (lane 1), and an empty one by plan-empty-symlink as well, so three findings for one link.
Activity
brettheap commentedon Oct 9, 2026
CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-09T13:56:49Z, for #183
Logged in
lanes/log/openRepoShape-1.mdat6b81983b79d65934bac3053a12c80268f8f0ce34.The three reads (lane-collision-protocol Rule 1):
adopt-project.py: `check` decides a symlink kept AT a shape path by w…
adopt-project.py: the walker's comment gives its example link without…
Merge origin/main 60588d5 into fix/adopt-root-kept-symlinks: #214, #217…
adopt-project.py: the symlink probe reads what `git config` writes as…
shape_materialize.py: the materializer's refusals name each path betw…
adopt-project.py: `check` asks, of a disk that ignores case, whether …
brettheap commentedon Oct 12, 2026
(lane openreposhape-5 (openRepoShape-5), 2026-10-12T02:27Z) COMPOSITION NOTE for the #183 branch,
fix/adopt-root-kept-symlinks, read at 6c44591.What #313 adds. Lane 5's PR #313 (
fix/adopt-check-shape-paths, #262/#263) addscheckfindings andexecuterefusals for a kept root path where the shape writes a directory or itsshape/collision copy.The double report.
checkfinds, andexecuterefuses before any leg exists, a kept root path where the shape writes a directory or itsshape/copy, whether the disk keeps case or not; the materializer never writes over a copy (#262, #263) #313 finds a symlink AT the copy today; nothing on main finds one.plan-root-symlinkfinds it too, so it would be reported twice.checkfinds, andexecuterefuses before any leg exists, a kept root path where the shape writes a directory or itsshape/copy, whether the disk keeps case or not; the materializer never writes over a copy (#262, #263) #313 and materialize_assembly_root writes the shape files through a root-kept symlink to anywhere on disk, and crashes with a traceback on a link loop, after both legs are pushed #183 lands second should make adopt-project.py:checkfinds, andexecuterefuses before any leg exists, a kept root path where the shape writes a directory or itsshape/copy, whether the disk keeps case or not; the materializer never writes over a copy (#262, #263) #313's_shape_blocksskipSYMLINK_MODE. That is one line.checkfinds, andexecuterefuses before any leg exists, a kept root path where the shape writes a directory or itsshape/copy, whether the disk keeps case or not; the materializer never writes over a copy (#262, #263) #313 at all. adopt-project.py:checkfinds, andexecuterefuses before any leg exists, a kept root path where the shape writes a directory or itsshape/copy, whether the disk keeps case or not; the materializer never writes over a copy (#262, #263) #313 leaves that to materialize_assembly_root writes the shape files through a root-kept symlink to anywhere on disk, and crashes with a traceback on a link loop, after both legs are pushed #183, and its review's fuzz found no miss outside that case.Text conflicts. 6c44591 has three conflicts with #313, all in
adopt-project.py. It has two of them against main alone. #313 follows 6c44591's backticks for the paths its messages name.Evidence. The re-verification section of
reviewP-report.md, underhandoffs/openRepoShape/attachments/lane-openRepoShape-5/inopensoft/brett-wip.adopt-project.py: `check` finds, and `execute` refuses before any leg…
update-shape.py: a path the root holds a symlink or a Windows junctio…
brettheap commentedon Oct 12, 2026
(lane openRepoShape-5, 2026-10-12T15:16Z)
Found by lane 5's review of
fix/adopt-check-link-and-manifest(69c54c9, the fix for #303 and #305), its N1. It is a composition of that branch with lane 1'sfix/adopt-root-kept-symlinks(6c44591), not a bug in either alone.What it is. Lane 5's branch adds
plan-empty-symlink:checkreports every120000entry whose blob is empty, wherever it sits in the tree, andexecuterefuses it before any leg exists. Lane 1's branch already reports the same link, through_Walk.emptyandplan-root-symlink, when it is kept in the root at or above a shape path. On the merged tree such a link is reported twice, andexecute's refusal wears the first finding's code,plan-empty-symlink. The two remediations agree (fix it in the source), so the duplicate and the code are what is wrong.The failing test. On origin/main ab623dd with both branches merged (the review resolved the conflict blocks in
adopt-project.pymechanically, keeping both sides; that is not either lane's resolution):Only
execute's refusal code differs: the test'scheckassertion still passes, becausesymlink_findingskeeps only theplan-root-symlinkline. Three other tests in that file fail on the same tree and do not come from lane 5's branch. origin/main ab623dd with 6c44591 alone failstest_check_reports_the_link_and_execute_refuses_it_before_any_leg[a-link-at-the-copy-itself]andtest_the_materializer_refuses_before_it_writes[the-copy-onto-a-file]and[the-copy-into-a-directory](3 failed, 93 passed), because #313'splan-root-blocks-shape-copyandmaterialize-copy-blockednow answer first. Lane 5's branch adds exactly one failure, the one above.Who drops the duplicate depends on which lands second. Keep one finding per empty link, and let it be
plan-empty-symlink: it reads every empty link in the tree whatever the plan does with it, whereplan-root-symlinksees only the ones at or above a shape path._Walk.empty(set at theif not target:hop) and the empty-target sentence in_root_symlink_finding. The test above then expectsplan-empty-symlink, or goes.The two branches also conflict textually, in 3 blocks of
adopt-project.py(the module docstring'scheckparagraph,_entry_findings' docstring and its return line): the same 3 that c7c02fa, the base of lane 5's branch, has with lane 1's. Against origin/main 0f67f7b, lane 1's branch has 5 blocks on its own.One more overlap, for whoever resolves it: a dangling link kept at
project.yamlis reported byplan-root-blocks-manifest(lane 5) and byplan-root-symlink(lane 1), and an empty one byplan-empty-symlinkas well, so three findings for one link.adopt-project.py: a symlink kept AT the copy under `shape/` of a path…
shape_materialize.py: where a symlink leads the shape's copy is #262'…
adopt-project.py: `check` says a symlink that leads the shape's copy …
adopt-project.py and shape_materialize.py: a path that follows more t…
10 remaining items
adopt-project.py: `check` finds, and `execute` refuses before any leg…
Merge origin/main 965420b into fix/adopt-root-kept-symlinks: `_entry_…
tests/test_adopt_root_symlinks.py: an empty-target link above `script…
Merge origin/main af01068 into fix/adopt-root-kept-symlinks: `_entry_…
adopt-project.py: `check` follows each declared pin's file, `contract…
tests/test_adopt_root_symlinks.py: `declare()` reads the plan as text…
Merge main b0826e0 (#504's squash for #183 and #178) into fix/adopt-g…
Merge main b0826e0 into fix/adopt-plan-quote-yaml-keywords (#181)
tests.yml and adopt-project.py: the Windows job installs git-filter-r…
docs/release-notes/v1.0.0.md: brought up to main 8beb3d9, so section …
docs/release-notes/v1.0.0.md: brought up to main 3121945, so section …
adopt-project.py: `check`'s throwaway repositories are made in the wo…
adopt-project.py (#910, review round 1): a row pins `asked()`'s `adop…
adopt-project.py: `check`'s throwaway repositories are made in the wo…