Skip to content

fix(shared): a deployed install must resolve its own project root (#14624) - #14661

Merged
mrveiss merged 4 commits into
Dev_new_guifrom
issue-14624-resolve
Aug 21, 2026
Merged

mrveiss merged 4 commits into
Dev_new_guifrom
issue-14624-resolve

Conversation

@mrveiss

@mrveiss mrveiss commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Thinking Path

The SLM backend crash-looped on a deployed host — uvicorn exiting 1 during import, restart counter past 530, API unreachable. That included the code-sync and self-update endpoints, so the normal recovery path was inside the thing that was down.

ProjectRootUndeterminable: cannot determine the project root by walking up from
/opt/autobot/autobot_shared/paths.py

#14544 replacing a silent /opt/autobot guess with a raise is right. What made it fatal is that a deployed install satisfies none of the arms:

  • /opt/autobot/.env does not exist. The per-component files live one level down (autobot-backend/.env, autobot-ai-stack/.env, ...). The resolver's docstring assumes the opposite — "an install has a .env and no .git, so it matches on the .env arm" — and that premise does not hold for this layout.
  • is_checkout_root requires both .git and autobot_shared; an install has only the second. Correctly so: it is not a checkout.
  • Neither env override was set, because the host's systemd unit was dated 2026-06-18, two months before the template line that renders AUTOBOT_PROJECT_ROOT.

The deployment does normally export the override. But that makes startup contingent on every host's unit being current, with nothing checking it — and this host's was not. A resolution that only works where deployed state is fresh is not a resolution.

What Changed

is_install_root() recognises a deployed install: autobot_shared sitting beside at least one deployed component directory.

Deliberately not a relaxation of CHECKOUT_MARKERS. Their both-markers rule exists for stated reasons that still hold — autobot_shared alone matches a package parent, .git alone matches an unrelated repo if vendored — and loosening it would be a backdoor around exactly that. The install shape is distinct: a package's own parent does not carry component directories, and neither does anything above a checkout or worktree root.

Added to the same single-pass walk, so the #13149 reasoning is untouched: a worktree still matches at its own level and never climbs to the main tree's .env.

Verification

Not run from the checkout, by instruction — CI verifies correctness, the deployment verifies runtime.

The resolver executed against real directory trees mirroring each layout:

install resolves        -> True   (root .env: False, is_checkout_root: False — both pre-fix arms confirmed failing)
checkout resolves       -> True
worktree stays put      -> True   (#13149: did not escape to the main tree)
lone package parent     -> raises (good)
nothing identifiable    -> raises (good)

The last two matter as much as the first: #14544's guarantee is that nothing is guessed, and this must not become a silent fallback.

test_the_pre_fix_arms_really_did_all_fail pins why it raised, so a future change cannot quietly reintroduce the gap while the fix appears to still work.

Not in this PR

Why the host's systemd unit was two months stale — that gap is independent of this crash and likely affects other deployed units. Tracked on #14624.

Model Used

Claude Opus 5

Refs #14624


Supersedes #14640. That PR was opened as the base of a stack, and GitHub marks stack membership permanently: it refuses the sync merge endpoint, auto-merge, and base retargeting, and the membership survived both closing the child PR and deleting its branch. The only remaining route was the async merge API, which enforces an approving-review requirement that cannot be satisfied by the author. Reopened here as an ordinary PR with identical content — same branch, same head commit, same green CI, same code-reviewer pass.

@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No hardcoded values detected that have SSOT config equivalents!

@mrveiss
mrveiss merged commit 7bf3a6d into Dev_new_gui Aug 21, 2026
126 checks passed
@mrveiss
mrveiss deleted the issue-14624-resolve branch August 21, 2026 06:22
mrveiss added a commit that referenced this pull request Aug 21, 2026
…14624) (#14662)

Of the 13 unit templates that launch Python, only 2 set AUTOBOT_PROJECT_ROOT. The other eleven depend entirely on the resolver recognising the deployed install layout, which #14661 restored - so the #14544 raise was one stale unit away from taking out most of the fleet's Python services, not one.

Records the two groups and fails if the explicit set shrinks, if a new Python unit template belongs to neither, or if a template sets the override while still listed as relying on inference. The lists move one way only.

Not the conversion itself: each role names its install directory differently, so converting all eleven is a change worth verifying per role against a real deploy, and #14661 already removed the acute risk.

Refs #14624
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant