Implementation Plan: FGA-Projected Team Shares
Spec: spec.md
Contract: contracts/module-api.md
Status: Draft — do not implement until PR 2 is opened
Phase 0 — Prerequisite (separate track)
Ensure agent-skills FGA-only team shares are on main:
- Mongo strip +
$unsetonagent_skills - PUT
previousTeamRefsfrom FGA - Hydrate on GET
- Migration
agent_skill_openfga_reconcile_v1documented in admin UI
This spec does not block on that merge but PR 2 should rebase on it.
Phase 1 — Generic module (PR 2)
- Add
ui/src/lib/rbac/fga-projected-team-shares.tsper contract P1–P5. - Move
resolveTeamSlugstoui/src/lib/rbac/team-slug-resolve.ts(or keep internal to module if YAGNI). - Move
extractTeamSlugsFromTuplesfromagent-skill-openfga-reconcile.ts; re-exportteamSlugsFromSkillTuplesas deprecated alias or thin wrapper for migration planner. - Refactor
skill-team-grants.tsto facade (FR-008). - Refactor
agent-skill-visibility.tshydrate (FR-009). - Replace local strip helpers in
configs/route.tswith P4 helpers. - Unit tests:
fga-projected-team-shares.test.ts+ run existing skill suites. - Docs: short subsection under RBAC docs linking Model A vs B.
Exit: All tests in spec SC-002; no new Mongo shared_with_teams on skills.
Phase 2 — Dynamic agents (PR 3)
- Add
AGENT_DESCRIPTORto module. - PUT
/api/dynamic-agents:previousSharedTeamSlugsfromreadSharedTeamSlugsFromOpenFgabeforereconcileAgentRelationships(or merge visibility/global into agent builder — do not duplicate globaluser:*in generic module). - Decision Q1: remove Mongo persistence of
shared_with_teams+ hydrate on GET, or dual-write during transition. - Regression test: stale FGA tuple revoked when Mongo list empty.
- Optional admin migration
dynamic_agent_openfga_team_shares_v1if production has drift.
Exit: SC-004; agent route-rbac tests updated.
Phase 3 — Registry & coverage (PR 4, optional)
export const FGA_PROJECTED_RESOURCE_DESCRIPTORS = [SKILL_DESCRIPTOR, ...].- Tie to
fga-enforcement-manifest/ projected-field lint (FR-004 in coverage spec). - Document in
2026-06-04-fga-coverage-guaranteemanifest.
Verification commands (PR 2)
cd ui
npm test -- --testPathPatterns="fga-projected-team-shares|skill-team-grants|agent-skill-openfga|route-rbac|agent-skill-visibility|import-zip/route"
npm run lint
Rollback
- Facade preserves old import paths; revert PR 2 by restoring
skill-team-grantsimplementation without removing skills FGA-only behavior from routes.
Estimated size
| PR | ~LOC | Risk |
|---|---|---|
| PR 2 | 400–600 | Low (refactor + tests) |
| PR 3 | 300–500 | Medium (agent global + tools edges) |
| PR 4 | 100–200 | Low |