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
bug(deploy): three more path defects around the backend PYTHONPATH and module symlinks #15560
Three findings from the B3/B4 work in PR #15559. All pre-existing, none fixed
there — that PR was scoped to the autobot_shared symlink and the backend_install_dir meaning, and widening it would have made a deploy-path
change harder to review.
autobot-slm-backend/ansible/roles/ai-stack/tasks/main.yml — the
"Create src/ symlinks to backend modules" task builds each src: as an absolute
path under the backend install directory.
Same defect family as B4, but wider: B4 was one well-known link, this is an
arbitrary set of backend modules. A link whose target does not depend on where
the link lives cannot survive the tree moving, which is the property #13539's
release scheme depends on.
Targets resolve relative to the link's own directory
A test resolves them with realpath under a relocated root, in the style of repo_tests/autobot_shared_symlink_relative_13539_test.py — asserting on the resolved destination, not on the absence of a string
2. fix-backend-environment.yml hand-writes a PYTHONPATH it just rendered
The playbook renders autobot-backend.service.j2 and then, a few lines later,
writes a PYTHONPATH again via lineinfile/shell. Two sources for one value,
which can drift — and the template is the canonical one.
This sits directly on the defect B3 exposed: the same playbook was producing PYTHONPATH=…:/opt/autobot_shared, a directory that does not exist. #15559 fixed
the rendered value; the hand-written duplicate is still a second, independent
writer of the same setting.
Establish whether the hand-written path is needed at all, or is a leftover from before the template covered it
If it is needed, it derives from the same variables as the template rather than restating them
A test asserts the two agree, or that only one writer exists
3. setup-user-backend.yml defines a variable nothing consumes
backend_shared_dir is defined and never referenced in that file or the role it
invokes. Dead configuration reads as meaningful to whoever edits next.
Confirm it is genuinely unconsumed across every playbook and role that could inherit it
Remove it, or wire it in if the omission is the actual bug
Evidence
Found while fixing #13539's B3/B4 blockers (PR #15559). The B4 sweep also turned
up three symlink sites the design document had not listed, so the population here
should be assumed larger than these three until swept.
Closed on code evidence, verified against merged Dev_new_gui (PR #15602, e1d8b51d).
Defect
Evidence from base
1 — ai-stack symlink src spelled out
Now ../../{{ backend_install_dir | basename }}/{{ item }}; the basename comes from the variable, so the two sibling install dirs cannot drift apart. Proved with real symlinks under tmp_path + os.path.realpath, with the historical absolute form as the contrast case
2 — two lineinfile writers fighting the template
Both removed. grep -c lineinfile returns 2 on the file, and both hits are inside comments recording why they went — no live task. The play now slurps the rendered unit, derives backend_unit_pythonpath (4 uses), and fails if the unit carries none
3 — backend_shared_dir names a variable no role reads
setup-user-backend.yml now uses backend_shared_standalone_dir (2 uses), which is the name roles/backend and roles/autobot_shared actually declare
Regression guard
repo_tests/ansible_backend_path_defects_15560_test.py present in base
Defect 2 is the one worth recording properly. The two lineinfile tasks rewrote EnvironmentFile= and Environment="PYTHONPATH=..." a few lines after the template had already written both — one setting with two writers that disagreed. That is how this play came to produce a PYTHONPATH entry pointing at a directory that does not exist (#13539/B3). #15559 corrected the rendered value; the hand-written duplicate was a separate, independent writer and survived that fix untouched.
Removing them is not deletion of working code: the template is confirmed the sole writer of both settings, its single-line output matches the regex the play reads back with, and every downstream consumer — the import test and the summary — was moved onto the derived value in the same change. Verified before removal rather than after.
Defect 3 was wired in rather than dropped: the play's backend_deployed_root now actually reaches the standalone autobot_shared copy, which the misnamed variable meant it never did.
The guard generalises the third defect instead of pinning it — every variable setup-user-backend.yml defines must be referenced somewhere in the tree, so the next variable named for a reader that does not exist fails at authoring time.
Activity
fix(deploy): derive the extracted path defaults from base_dir and fol…
chore(ci): take the stranded baseline entries with the paths the extr…
test(guard): drop the pin whose command moved and fail on a dangling …
fix(ansible): stage the SLM frontend publish and repair three backend…
mrveiss commentedon Sep 4, 2026
Closed on code evidence, verified against merged
Dev_new_gui(PR #15602,e1d8b51d).srcspelled out../../{{ backend_install_dir | basename }}/{{ item }}; the basename comes from the variable, so the two sibling install dirs cannot drift apart. Proved with real symlinks undertmp_path+os.path.realpath, with the historical absolute form as the contrast caselineinfilewriters fighting the templategrep -c lineinfilereturns 2 on the file, and both hits are inside comments recording why they went — no live task. The play now slurps the rendered unit, derivesbackend_unit_pythonpath(4 uses), and fails if the unit carries nonebackend_shared_dirnames a variable no role readssetup-user-backend.ymlnow usesbackend_shared_standalone_dir(2 uses), which is the nameroles/backendandroles/autobot_sharedactually declarerepo_tests/ansible_backend_path_defects_15560_test.pypresent in baseDefect 2 is the one worth recording properly. The two
lineinfiletasks rewroteEnvironmentFile=andEnvironment="PYTHONPATH=..."a few lines after the template had already written both — one setting with two writers that disagreed. That is how this play came to produce aPYTHONPATHentry pointing at a directory that does not exist (#13539/B3). #15559 corrected the rendered value; the hand-written duplicate was a separate, independent writer and survived that fix untouched.Removing them is not deletion of working code: the template is confirmed the sole writer of both settings, its single-line output matches the regex the play reads back with, and every downstream consumer — the import test and the summary — was moved onto the derived value in the same change. Verified before removal rather than after.
Defect 3 was wired in rather than dropped: the play's
backend_deployed_rootnow actually reaches the standaloneautobot_sharedcopy, which the misnamed variable meant it never did.The guard generalises the third defect instead of pinning it — every variable
setup-user-backend.ymldefines must be referenced somewhere in the tree, so the next variable named for a reader that does not exist fails at authoring time.fix(ansible): the ai-stack manifest default must not be a Jinja templ…