Skip to content

Umbrella: scoped + shareable custom skills and custom agents (company-wide by default) #11277

Description

@mrveiss

Design owner: mrveiss. Spec: docs/superpowers/specs/2026-07-08-scoped-shareable-skills-agents-design.md (added by this umbrella).

Gives custom (user-created / imported / hub) skills and custom agents a scope + grant model mirroring secrets, so a skill/agent is created once and shared company-wide by default, narrowable to group/user — preventing duplication. Definitions persist to Postgres (survive /opt/autobot git-pull), governance/trust gating retained. Absorbs #11141 (cross-source conflict/dedup).

Decisions (brainstormed)

  • Scopes mirror SecretScope: USER / SESSION / SHARED / GROUP / ORGANIZATION. Default = ORGANIZATION (company-wide), narrowable down. ORG is the ceiling; truly-global = builtin/code via promoter.py.
  • Authorization only — scope + generic resource_grants table; definitions stored plaintext in Postgres (no secrets DEK envelope).
  • One global registry + visible_to(principal) filter at list/route/execute; execute-time is the hard gate. Single canonical instance = natural dedup.
  • Agents reuse existing agent_org_nodes.company_id (Company OS) for the ORG default; use resource_grants only when limited below company-wide.
  • Governance: external ⇒ sandboxed; company-wide scope change gated under SEMI_AUTO.

Tasks

  • T0: Boot-reload fix — re-register custom/hub/imported skill definitions at startup so they survive backend restart (SkillManager.initialize()). Standalone bug fix; prerequisite seam for T2.
  • T1: Shared scope/authz core — ScopeLevel enum, resource_grants table + migration, visible_to(principal) resolver + resolution cache, authz service + unit tests. No behavior change.
  • T2: Skills adopt scoping
    • 2.1 skill_definitions table + migration; custom-skill persistence Redis-only → Postgres (Redis = cache/config)
    • 2.2 Registry loads custom defs from DB at boot; generator/importer/hub write DB rows (builds on T0)
    • 2.3 Visibility filter at list/route/execute + execute-time hard gate
    • 2.4 Create/import reuse-or-fork guard + cross-source conflict resolver (Closes Skill registry: detect cross-source name conflicts instead of silently skipping #11141)
    • 2.5 API (create/scope/grant) + SkillsView scope badge & "Limit access" (i18n ×11)
    • 2.6 Governance trigger on company-wide scope change
  • T3: Custom agents adopt scoping
    • 3.1 Agents use resource_grants (resource_type=agent) for limiting; ORG default stays agent_org_nodes.company_id
    • 3.2 Company OS agent views: "Limit access" affordance + visibility filter on agent listings
    • 3.3 Agent capability-KB indexing respects limited scope
  • T4: Docs & closure — update skills/agents docs; verify ACs; file discovery issues.

Each T is one PR-sized deliverable (T2 splits into ~6 sub-PRs).


Discovered during T0+T1 (closure audit, PR #11287)

  • T0 shipped hub-only. _load_custom_definitions() re-registers hub skills only. Externally-imported skills (external_importer → /var/lib/autobot/skill_cache) and generated skills are still not re-registered at boot. Fold into T2.2 (registry loads custom defs from DB at boot) — DB-backed reload will cover all sources uniformly.
  • Canonical debt → Canonical debt: 3 overlapping visibility-scope enums + parallel principal/visibility/grant implementations #11290. ScopeLevel/Principal/is_visible/resource_grants overlap with SecretScope, knowledge VisibilityLevel + OwnershipManager.check_access, and PrincipalFacts. Consolidation is a scoped, owner-gated follow-up (Canonical debt: 3 overlapping visibility-scope enums + parallel principal/visibility/grant implementations #11290), not part of this umbrella.
  • Minor infra: empty autobot-backend/autobot_shared/ dir (namespace-package trap — new shared code must go in repo-root autobot_shared/); repo has no shared async-DB test fixture (each DB test builds its own in-memory sqlite fixture).
  • T2 carry-forwards: every grant/revoke/scope-change write MUST call resource_visibility.invalidate() (cache has no TTL); add a can_access denial test + assert permission mutation in the grant idempotency test.

Activity

  1. mrveiss commented on Jul 8, 2026

    @mrveiss
    OwnerAuthor

    T0 + T1 implemented → PR #11287 (spec+plan already merged in #11281).

    • T0: Boot-reload fix — register_declarative() + SkillManager._load_custom_definitions() at boot. Custom/hub skills no longer vanish on restart.
    • T1: Shared scope/authz core — ScopeLevel enum, resource_grants table + migration 20260708_068, is_visible() rule, ResourceGrantStore, can_access() resolver + cache.

    Built via subagent-driven TDD (per-task spec+quality reviews + final opus whole-branch review = READY TO MERGE). 21 tests pass. Default-deny authz verified (null-company cross-tenant guard). Awaiting CI + review.

    Carry-forward to T2 (tracked):

    • Every grant/revoke/scope-change write path MUST call resource_visibility.invalidate() (decision cache has no TTL).
    • Add a can_access denial test + assert permission-mutation in the grant idempotency test.

    Remaining: T2 (skills adopt scoping), T3 (agents), T4 (docs/closure).

  2. mrveiss commented on Jul 11, 2026

    @mrveiss
    OwnerAuthor

    Worktree-audit status (2026-07-11): T0+T1 landed via #11287 (boot-reload fix + scope/granularity). The stale local issue-11277 worktree (its merged content) has been pruned. T2–T4 remain open under this umbrella — no change to scope.

  3. added this to the v0.10.0 milestone on Sep 12, 2026
  4. mrveiss commented on Sep 18, 2026

    @mrveiss
    OwnerAuthor

    Follow-ups from #16927. #11277's "single access entry point" (can_access() over resource_grants) is read by no production access check, and after #16927 nothing writes to it either. That is filed as #16981 (wire it or retire it). Related: #16982, where Secret.is_accessible_by also has no production caller.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions