Skip to content

fix(slm): derive the deploy gate over the role map, and require declaration for npu_worker (#14567) - #14675

Merged
mrveiss merged 6 commits into
Dev_new_guifrom
issue-14567-gate
Aug 21, 2026
Merged

mrveiss merged 6 commits into
Dev_new_guifrom
issue-14567-gate

Conversation

@mrveiss

@mrveiss mrveiss commented Aug 21, 2026 •

Copy link
Copy Markdown
Owner

Thinking Path

Owner decision on #14567: gate npu_worker — declaration required.

setup-ai-stack.yml targets hosts: ai_stack and setup-npu-worker.yml targets hosts: npu_worker — sibling names _ROLE_TO_GROUPS grants alongside the gated aiml/npu, both reachable from /infrastructure/execute where limit_hosts is optional. So a node that never declared ai-stack or npu-worker could still receive full provisioning.

#14513 and #14552 each fixed this by enumerating names, and each was too short. This derives the set instead, by closing over the role map: if a role can place a node in a gated group, every group that role grants is equally a deploy target.

What Changed

  • _DEPLOY_GATED_SEED — the group names deploy plays actually mention.
  • _close_over_role_groups() — derives the full gated set from _ROLE_TO_GROUPS, minus any group a non-deploy role also grants.
  • role_llm_active reads node_roles_declared, required once llm_nodes became privileged.
  • test_wizard_inventory_parity_14286.py — the rule it encoded is updated to the decided one, split into the declared and detected-only cases.
  • inventory_deploy_gate_test.py — five rules pinning the closure, the sibling coverage, and the agent-membership refinement.

The refinement that keeps this from being worse than the bug

A naive closure gates slm/slm_nodes, because the slm- prefix role grants them alongside slm_server. deploy-slm-agent.yml targets slm_nodes. That version would withhold the agent-repair playbook from agent nodes — the remedy the agent's own 401 message names (#14350 / #14351) unreachable for exactly the nodes needing it.

So a group stays ungated when a non-deploy role also grants it. slm-agent is not a deploy target, so slm/slm_nodes stay broad. Pinned by test_agent_membership_stays_ungated.

The decided behaviour change

ROLE_ANSIBLE_GROUPS["tts-worker"] = "npu_worker" is semantic, not legacy: TTS runs on NPU hardware, which is why setup-npu-worker.yml can reach it. The owner's call is that a detected-only tts-worker should no longer be an NPU deploy target, while a declared one still is.

test_wizard_inventory_parity_14286.py asserted the opposite, so it is updated rather than worked around — split into the two cases it now covers, with the decision recorded in the docstring. That test previously blocked this change; it now states the rule.

Also required by the gate

llm_nodes and ai_stack become privileged, so role_llm_active must read node_roles_declared (#14560) — otherwise the group half is gated while the node_roles half is not, and a detected-but-undeclared node still activates the role. It was the only fact of the seven gating a privileged group that still read the raw union.

Verification

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

gated: ai, ai_stack, aiml, backend, browser, browser_worker, frontend,
       llm_nodes, main, npu, npu_worker, npu_workers, slm_server

declared npu-worker  keeps npu_worker : True
detected-only tts    gets npu_worker  : False   <- the decided change
declared ai-stack    keeps ai_stack   : True
declared tts-worker  keeps ai_stack   : True
agent node keeps slm_nodes            : True
detected-only redis keeps redis       : True
privileged facts still reading raw node_roles: none

Both tests that blocked the earlier attempt were re-run in logic form: the #14560 privileged-facts rule now passes, and the #9965 parity test is updated to the decided rule rather than bypassed.

Model Used

Claude Opus 5

Closes #14567

@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No hardcoded values detected that have SSOT config equivalents!

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