mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 01:50:44 +08:00
Fix role binding filter when mapping is empty
should_apply_workspace_role_filter no longer requires at least one bound skill. With binding enabled and an empty map, the catalog shows only public workspace skills per role (matches prewarm and runtime). Update Admin copy and add regression test. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
091a5626e7
commit
4dbb834c95
3 changed files with 30 additions and 8 deletions
|
|
@ -7990,7 +7990,7 @@ async function renderSkills() {
|
|||
class: "muted",
|
||||
style: "margin:8px 0;line-height:1.5;",
|
||||
text:
|
||||
"When enabled, installed workspace skills only appear in the model skills catalog for the selected role. You can optionally inherit manager-bound skills to other roles.",
|
||||
"When enabled, the model skills catalog is filtered per role: each role sees only skills bound to that role (and optionally manager-bound skills), plus skills under skills/_workspace/public/. If nothing is bound yet, non-public skills are hidden until you assign them.",
|
||||
}),
|
||||
skillBindingStatus,
|
||||
skillBindingPersistHint,
|
||||
|
|
|
|||
|
|
@ -128,17 +128,15 @@ def _all_installed_skill_names(store: Any) -> set[str]:
|
|||
|
||||
|
||||
def should_apply_workspace_role_filter(*, store: Any, skill_binding_role: str | None) -> bool:
|
||||
"""When role binding is enabled, always filter the workspace skill catalog by role.
|
||||
|
||||
Empty binding maps still apply: each role then only sees ``public`` workspace skills
|
||||
(see :func:`allowed_workspace_skill_names_for_role`), not the full install tree.
|
||||
"""
|
||||
if not str(skill_binding_role or "").strip():
|
||||
return False
|
||||
if not skill_role_binding_enabled(store=store):
|
||||
return False
|
||||
raw = load_skill_role_binding_dict(store)
|
||||
normalized = normalize_skill_role_binding(
|
||||
mapping_raw=raw,
|
||||
valid_skill_names=_all_installed_skill_names(store),
|
||||
)
|
||||
if not mapping_has_any_skill_names(normalized):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,30 @@ def test_collect_includes_own_private_lane_without_role_mapping(tmp_path: Path,
|
|||
assert "lane-bound-skill" in names
|
||||
|
||||
|
||||
def test_collect_when_binding_enabled_empty_mapping_shows_only_public(tmp_path: Path, monkeypatch) -> None:
|
||||
db = tmp_path / "ops.sqlite"
|
||||
store = SqliteStore(str(db))
|
||||
skills_root = tmp_path / "skills_empty_bind"
|
||||
skills_root.mkdir(parents=True, exist_ok=True)
|
||||
_write_skill(skills_root, "skill-root-only")
|
||||
_write_skill(skills_root / "_workspace" / "public", "skill-public")
|
||||
|
||||
monkeypatch.setenv("AIA_SKILLS_ROOT", str(skills_root))
|
||||
store.set_setting(SKILL_ROLE_BINDING_ENABLED_SETTING, "1")
|
||||
store.set_setting(SKILL_ROLE_BINDING_KEY, "{}")
|
||||
|
||||
reg = default_registry(store=store)
|
||||
entries = collect_skill_catalog_entries(
|
||||
store=store,
|
||||
registry=reg,
|
||||
base_url="",
|
||||
skill_binding_role="generalist",
|
||||
)
|
||||
names = {e[0] for e in entries}
|
||||
assert "skill-public" in names
|
||||
assert "skill-root-only" not in names
|
||||
|
||||
|
||||
def test_collect_unfiltered_when_binding_disabled(tmp_path: Path, monkeypatch) -> None:
|
||||
db = tmp_path / "ops.sqlite"
|
||||
store = SqliteStore(str(db))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue