Repository navigation
fix(slm): derive the deploy gate over the role map, and require declaration for npu_worker (#14567) - #14675
Merged
Conversation
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
Applied Black, isort, and autoflake to match code-quality checks. Triggered by workflow auto-fix-formatting.yml.
3 tasks
This was referenced Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thinking Path
Owner decision on #14567: gate
npu_worker— declaration required.setup-ai-stack.ymltargetshosts: ai_stackandsetup-npu-worker.ymltargetshosts: npu_worker— sibling names_ROLE_TO_GROUPSgrants alongside the gatedaiml/npu, both reachable from/infrastructure/executewherelimit_hostsis 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_activereadsnode_roles_declared, required oncellm_nodesbecame 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 theslm-prefix role grants them alongsideslm_server.deploy-slm-agent.ymltargetsslm_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-agentis not a deploy target, soslm/slm_nodesstay broad. Pinned bytest_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 whysetup-npu-worker.ymlcan 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.pyasserted 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_nodesandai_stackbecome privileged, sorole_llm_activemust readnode_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.
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