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
deploy(updater): ai-stack, npu-worker, frontend and browser have no role application path — role fixes stay inert on hosts #13460
update-all-nodes.yml — the playbook behind code-sync / self-update — now applies targeted task files for three roles: backend (env_only, unit_only), tts-worker (code_only) and postgresql (credentials_reconcile). Four managed components still have no application path at all, so a fix landing in their role templates is inert on every host, exactly as #12777 / #12886 / #12907 were.
Each of these roles owns systemd units and env files that the updater never renders:
roles/npu-worker/templates/npu-worker.py.j2 is the sharpest case: it is worker code rendered from a template, so it has the same shape as the TTS worker that served four-day-old code in #12886.
Why this is not "apply the roles in full"
Decided on #12959: delivery goes through code/config-only task files, never whole-role application. Applying roles/npu-worker in full would re-run OpenVINO/venv provisioning on every self-update — slow, network-dependent, and able to break a box that is already correctly installed. The established shape is roles/tts-worker/tasks/code_only.yml: the service files that carry code changes, split out of main.yml, with main.ymlincluding it so there is exactly one definition.
Work
roles/ai-stack/tasks/code_only.yml + include from main.yml + apply in PLAY 2 (when: 'ai_stack' in group_names)
roles/npu-worker/tasks/code_only.yml — must cover npu-worker.py.j2
roles/frontend/tasks/code_only.yml — unit + nginx config; the playbook already deploys frontend code inline
roles/browser/tasks/code_only.yml — playwright + vnc units
Each include uses apply: {become: true} — a bare become: on include_role makes ansible reject the whole playbook
Delete the xfail(strict=True) marker on test_every_managed_component_has_an_application_path once all four land (strict xfail turns the fix into a FAILURE until the marker goes)
Verification
python3 -m pytest autobot-slm-backend/tests/test_update_all_applies_roles_12959.py -q
# test_every_managed_component_has_an_application_path must XPASS -> delete the marker
Per component, on a host after a self-update: the rendered unit matches the role template.
$ forrin ai-stack npu-worker frontend browser;do git cat-file -e origin/Dev_new_gui:…/roles/$r/tasks/code_only.yml && echo "$r present"; doneai-stack presentnpu-worker presentfrontend presentbrowser present
$ git show origin/Dev_new_gui:…/playbooks/update-all-nodes.yml | grep -c 'tasks_from: code_only'5 # the four above + tts-worker
$ git show origin/Dev_new_gui:…/tests/test_update_all_applies_roles_12959.py | grep -c '@pytest.mark.xfail'0 # XPASSed, marker removed — exactly what it was for
Every checkbox:
ai-stack, npu-worker, frontend, browser each have code_only.yml, included by their own main.yml so there is one definition per component
All four applied in PLAY 2 with apply: {become: true} — a bare become on include_role makes ansible reject the whole playbook, breaking every self-update rather than one task
The xfail(strict=True) marker is gone, and all four moved into DELIVERED, so the passing regression guard now covers seven components instead of three
Two things that needed judgment rather than mechanical extraction:
ai-stack would have silently disabled ChromaDB auth.autobot-chromadb.service.j2 emits CHROMA_SERVER_AUTHN_* only when chromadb_auth_token is non-empty, and the role default is "". Extracting only the template tasks would have redeployed chroma on every update with authentication off — undoing #12513, with nothing failing and nothing logged. The #12513 token read is part of code_only.yml for that reason.
browser gained a genuine duplicate from my own change — the same env template rendered in main.yml and the new code_only.yml, to the same destination. That is exactly the inline-vs-role duplication #12959 exists to eliminate, reintroduced while fixing it. Removed; its only consumer is the playwright unit code_only.yml renders immediately after.
(npu-worker.env.j2 appears in both files and is not a duplicate — two different destinations, both intentional.)
Verification: 1095 SLM tests pass; both update-all-nodes.yml and deploy-full.yml pass --syntax-check. Guards invert-tested. No provisioning leaked onto the update path — venv/pip install/apt/npm ci/downloads appear in these files only inside comments explaining what must not run.
Follow-up #13504 removes a stale xfail reference the marker's removal left in a docstring.
Activity
test(deploy): assert the targeted-task-file delivery contract, not fu…
test(deploy): assert the targeted-task-file delivery contract, not fu…
fix(deploy): deliver the role-owned credential reconciliation through…
fix(deploy): give ai-stack, npu-worker, frontend and browser a delive…
github-actions commentedon Aug 4, 2026
PR #13501 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Aug 4, 2026
✅ Delivered — PR #13501, merged to
Dev_new_gui.Every checkbox:
ai-stack,npu-worker,frontend,browsereach havecode_only.yml, included by their ownmain.ymlso there is one definition per componentapply: {become: true}— a barebecomeoninclude_rolemakes ansible reject the whole playbook, breaking every self-update rather than one tasknpu-worker.py.j2covered — worker code rendered from a template, the sharpest case and the same shape as the TTS worker that served four-day-old code in bug(tts): synthesis 404s — deployed worker lacks /tts/synthesize/stream because autobot-tts-worker has NO resolve path AND NO drift visibility (silent skew on every backend update); /tts/clone-voice is a dead call that exists nowhere #12886xfail(strict=True)marker is gone, and all four moved intoDELIVERED, so the passing regression guard now covers seven components instead of threeTwo things that needed judgment rather than mechanical extraction:
ai-stackwould have silently disabled ChromaDB auth.autobot-chromadb.service.j2emitsCHROMA_SERVER_AUTHN_*only whenchromadb_auth_tokenis non-empty, and the role default is"". Extracting only the template tasks would have redeployed chroma on every update with authentication off — undoing #12513, with nothing failing and nothing logged. The #12513 token read is part ofcode_only.ymlfor that reason.browsergained a genuine duplicate from my own change — the same env template rendered inmain.ymland the newcode_only.yml, to the same destination. That is exactly the inline-vs-role duplication #12959 exists to eliminate, reintroduced while fixing it. Removed; its only consumer is the playwright unitcode_only.ymlrenders immediately after.(
npu-worker.env.j2appears in both files and is not a duplicate — two different destinations, both intentional.)Verification: 1095 SLM tests pass; both
update-all-nodes.ymlanddeploy-full.ymlpass--syntax-check. Guards invert-tested. No provisioning leaked onto the update path —venv/pip install/apt/npm ci/downloads appear in these files only inside comments explaining what must not run.Follow-up #13504 removes a stale
xfailreference the marker's removal left in a docstring.docs(test): drop a stale xfail reference the marker's removal left be…