Skip to content

docs(adr): ADR-056 app profiles, tenancy and entity scopes - #670

Open
seanspeaks wants to merge 2 commits into
nextfrom
adr/056-app-profiles
Open

seanspeaks wants to merge 2 commits into
nextfrom
adr/056-app-profiles

Conversation

@seanspeaks

@seanspeaks seanspeaks commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

ADR-056: app profiles, tenancy and entity scopes (Proposed, draft until accepted per ADR-043).

  • Profiles. Two adoption profiles:
    • Product: a multi-tenant SaaS product embedding integrations for its customers.
    • Operations: a company running its own automations. A personal or household deployment is a small operations deployment.
  • Repo shape. The adopter layout is backend/, an optional frontend/, and an optional ui-extensions/ (the home of ADR-022 artifacts). For 2.0.1, frigg init produces backend/ and takes --profile product|operations.
  • Browser-safe tenant auth.
    • adopterJwt is a 501 stub today, and friggToken login fails with primary: 'organization'.
    • Adopter JWT verification and the org-login fix are proposed as 2.0.1 candidates.
    • Until they land, the backend-for-frontend pattern is the documented approach.
  • Entity scopes individual | organization | global (2.1), matching the existing user types and ADR-024.
    • Entity.scope replaces the branch's isGlobal.
    • Organization entities are owned by the organization user.
    • A permission table defines who may create and use each scope.
    • A module can be bound at two scopes for APIs with two auth levels (Slack, Atlassian, GitHub).
  • Integration ownership rules for mixed-scope integrations, plus a new ORPHANED status when a member leaves an organization.
  • Visibility callback Definition.visible(context). Capability Context is recorded as rejected for now.
  • Default UIs (2.1): a product portal and an operations console, as templates the adopter owns. User-facing reports go in the v2 Management API, and admin reports stay on the admin routes.
  • Port, not rebase. The 2.1 implementation is ported fresh from claude/frigg-deployment-architecture-ed1CZ (file and commit table in §7). The global-entities guide banner now says "implemented on an unmerged branch; being ported to 2.x".

Related: ADR-024, ADR-032, ADR-053 (#668), ADR-054 (#669).

🤖 Generated with Claude Code

https://claude.ai/code/session_013b2UUFaQ5Lk6TFPqzRr1j7

📦 Published PR as canary version: 2.0.0--canary.670.2873d95.0

✨ Test out this PR locally via:

npm install @friggframework/admin-scripts@2.0.0--canary.670.2873d95.0
npm install @friggframework/core@2.0.0--canary.670.2873d95.0
npm install @friggframework/devtools@2.0.0--canary.670.2873d95.0
npm install @friggframework/eslint-config@2.0.0--canary.670.2873d95.0
npm install @friggframework/prettier-config@2.0.0--canary.670.2873d95.0
npm install @friggframework/schemas@2.0.0--canary.670.2873d95.0
npm install @friggframework/serverless-plugin@2.0.0--canary.670.2873d95.0
npm install @friggframework/test@2.0.0--canary.670.2873d95.0
npm install @friggframework/ui@2.0.0--canary.670.2873d95.0
# or 
yarn add @friggframework/admin-scripts@2.0.0--canary.670.2873d95.0
yarn add @friggframework/core@2.0.0--canary.670.2873d95.0
yarn add @friggframework/devtools@2.0.0--canary.670.2873d95.0
yarn add @friggframework/eslint-config@2.0.0--canary.670.2873d95.0
yarn add @friggframework/prettier-config@2.0.0--canary.670.2873d95.0
yarn add @friggframework/schemas@2.0.0--canary.670.2873d95.0
yarn add @friggframework/serverless-plugin@2.0.0--canary.670.2873d95.0
yarn add @friggframework/test@2.0.0--canary.670.2873d95.0
yarn add @friggframework/ui@2.0.0--canary.670.2873d95.0

Note

Low Risk
Documentation-only changes with no production code, schema, or auth behavior modified in this PR.

Overview
Adds proposed ADR-056 and wires it into the ADR index, roadmap data, and the Global Entities guide. This PR does not implement runtime behavior; it records planned architecture and phasing.

The ADR introduces product vs operations adoption profiles, documents the adopter repo layout (backend/, optional frontend/ and ui-extensions/), and scopes 2.0.1 to repo shape, frigg init --profile, and docs (with adopter JWT / org-primary login as candidates). 2.1 is specified as a fresh port from claude/frigg-deployment-architecture-ed1CZ: individual | organization | global entity scopes (replacing branch isGlobal), org roles, integration ownership and ORPHANED, Definition.visible(context), v2 API additions, and adopter-owned UI templates.

GLOBAL-ENTITIES-GUIDE.md gains a banner that implementation lives on the unmerged branch and will use scope: global per ADR-056. website/roadmap/data/adrs.json count goes to 32 with a new ADR-056 entry.

Reviewed by Cursor Bugbot for commit 2873d95. Bugbot is set up for automated code reviews on this repo. Configure here.

Names the two adoption profiles (product, operations), codifies the
adopter repo shape (backend/, frontend/, ui-extensions/ for ADR-022
artifacts) and frigg init --profile, proposes browser-safe tenant auth
(adopter JWT, org-primary login fix), user/org/app entity scopes with
multi-level-auth bindings, additive v2 API fields, and two adopter-owned
UI templates. Adds a design-only banner to the Global Entities guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@seanspeaks seanspeaks added release Create a release when this pr is merged prerelease This change is available in a prerelease. labels Oct 3, 2026
@netlify

netlify Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for friggframework-org ready!

Name Link
🔨 Latest commit 2873d95
🔍 Latest deploy log https://app.netlify.com/projects/friggframework-org/deploys/6ac168fd3a83170008acbf97
😎 Deploy Preview https://deploy-preview-670--friggframework-org.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

…back, port path

- Rename entity scopes to individual | organization | global, matching the
  User types and ADR-024. Migrate isGlobal to scope = 'GLOBAL' rather than
  keep both; org entities stay owned by the ORGANIZATION-type User, as on
  the branch, so Entity gets no organizationId column.
- Add integration ownership rules (mixed org + individual -> individual)
  and member offboarding: disable with a new ORPHANED status, deletion
  through ADR-032 cleanup.
- Add Definition.visible(context) applied in GetPossibleIntegrations, with
  host-supplied context and a visible option on defineIntegration; record
  Capability Context as rejected for now with a revisit trigger.
- State the 2.1 implementation is ported fresh from
  claude/frigg-deployment-architecture-ed1CZ (files and commit SHAs), not
  rebased; correct the ADR-024 status (implemented on that branch) and the
  Global Entities guide banner; cite the branch's one-vs-two deployments
  analysis in the tenancy context.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013b2UUFaQ5Lk6TFPqzRr1j7
@sonarqubecloud

sonarqubecloud Bot commented Oct 3, 2026

Copy link
Copy Markdown

@seanspeaks

Copy link
Copy Markdown
Contributor Author

ADR reconciliation needed after Stack A/B — drafted with Claude Code at Sean's request

Severity: must-reconcile (mostly merge order; the text items are on #677).

Merge order: #677 → this PR → #681–#685 can claim "implements ADR-056 §3.x" against merged text.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization has no extra usage available to pay for this review.

If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.

Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

Comment on lines +293 to +301
| Entities used | Integration owner |
|---|---|
| All `individual` | The individual |
| All `organization` | The organization (the ORGANIZATION-type `User`) |
| Mixed `organization` + `individual` | **The individual** |
| Mixed with `global` | The individual |

`global` entities do not decide ownership; the rule is applied to the remaining entities, so
`global` + `organization` only is organization-owned. Mixed integrations belong to the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ownership table and the prose under it contradict each other. The row Mixed with global | The individual implies that global + organization is individual-owned. The next paragraph says global entities do not decide ownership and that global + organization only is organization-owned. An implementer of CreateIntegration cannot tell which rule applies, and one reading orphans an org-shared integration when a member leaves.

Fix the table so it matches the rule, for example:

| Entities used (ignoring global) | Owner |
| All individual (or none)        | The individual |
| All organization                | The organization |
| Mixed organization + individual | The individual |

The rule also needs a case for an integration that uses only global entities.

Suggested change
| Entities used | Integration owner |
|---|---|
| All `individual` | The individual |
| All `organization` | The organization (the ORGANIZATION-type `User`) |
| Mixed `organization` + `individual` | **The individual** |
| Mixed with `global` | The individual |
`global` entities do not decide ownership; the rule is applied to the remaining entities, so
`global` + `organization` only is organization-owned. Mixed integrations belong to the
| Entities used (ignoring `global`) | Integration owner |
|---|---|
| All `individual` | The individual |
| All `organization` | The organization (the ORGANIZATION-type `User`) |
| Mixed `organization` + `individual` | **The individual** |
| Only `global` (no `individual` or `organization` entities) | The individual (the creator) |
`global` entities do not decide ownership; the rule is applied to the remaining entities, so
`global` + `organization` only is organization-owned. Mixed integrations belong to the

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@cursor

cursor Bot commented Oct 24, 2026

Copy link
Copy Markdown

Frigg 2.0.1 ADR review (COMMENT only — not an approval)

Verdict: would approve (as the base ADR-056 snapshot) — nothing blocking in this PR’s own text.

Checklist verified

Important (non-blocking for #670 alone; blocking for anyone implementing from #670 without #677)

Docs-only; no new test failures vs next.

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

Labels

prerelease This change is available in a prerelease. release Create a release when this pr is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant