Per Permission Standards, which names this file. Part of the module spec.
P02b-5 account-site subject. GetAccountSiteQuery is non-public and
explicitly audit Off. It adds no permission key or grant, and
returns only the context's own actor/scope with the existing public site
projection. Its implemented HostAndClaim/host-scope guard precedes all readers;
membership alone cannot admit it. The module contract
owns the boundary. P02b-5 Step 4 exposes only its authenticated GET route;
Accepted ADR-0076 adds live
membership/lifecycle checks to its protected admission while preserving its
independent host ceiling and Off success classification. The
Phase 03 Status block owns execution
and qualification; acceptance is not activation.
ADR-0078 additionally admits the separately validated native-session origin under the same real-host ceiling. It does not admit HostOnly/ClaimAndMembership or turn AccountSite into an admin query; qualification lives in the phase Status block above.
P02b-1 Step 3 producer implemented — 2026-10-12. The completed-provisioning domain translator runs only during owner completion, adds no endpoint or permission, and inserts a pending outbox row under the provisioning announcement. Existing command reachability is unchanged. The integration-event catalogue owns the flow.
ADR-0046 P02b-2 complete and merged — 2026-10-13. All four steps completed both independent review rounds. The merge closeout owns CI/merge status. The API-owned dispatcher and terminal audit add no permission key or HTTP endpoint. P02b-3's targeted replay is internal; Phase 03 separately decides operator permission and routes. Neither grants a tenant administrator bypass-role access.
P02d-4 Step 2 implemented — 2026-10-03. Both review rounds and focused fix verification pass. Site bootstrap is a marked GET/HEAD request, audit Off and without a permission key or grant. It uses matching host scope and READ ONLY; normal reads add no audit row. Public configuration/settings ports remain internal and unrouted. Independent rejected- assertion auditing remains unchanged. The public contract owns allowlisting and lifecycle/locale checks.
Accepted ADR-0076 classifies that existing bootstrap through virtual Tenant
tenancy.public_site.read. This is Portal Public policy metadata, unavailable
as a stored Role grant; it adds no endpoint, Membership, template or visibility.
Credential-free public reads perform no identity/grant lookup. The
Permission standard owns the virtual class.
P02d-3 Step 1 implemented — 2026-10-02; both review rounds passed.
ITenantSettingsAccessor is internal and unrouted, uses trusted ambient
scope and adds no HTTP endpoint or permission key. Public admission belongs to
P02d-4. The module contract owns its scope.
P02d-2 Step 2 writers — 2026-10-02. The locale and branding commands are implemented unrouted tenant-wide operations, with no assignable permission or organization override. Their finite Seed admission is described below. Human-facing permissions bind the separate human handlers below. Their transport qualification belongs to Phase 03. No additional Hub-internal route is admitted here.
Bounded assignable contract. ADR-0079 selects exactly the three Tenant pairs below. The versioned manifest owns first adoption into Tenant Admin; declaration alone grants nothing. No Organization Tenancy pair or generic settings power is selected. The virtual Portal Public definition above remains nonassignable and separate.
Six write handlers and four verification queries have finite Seed admission.
TenancyOperationPolicySource binds each request to its declared Seed source under
the live contract.
The verification queries remain audit Off. These bindings add no HTTP or
Hub-internal route and no assignable permission key.
ProvisionTenantCommand runs with an unresolved tenant context so it can
announce the tenant it creates. Provisioning precedes Membership and attributes
the write to UserId.SystemActor; that value supplies no exemption from the
finite source/request gate.
CreateOrganizationCommand, MapHostToTenantCommand and the three P02d-2 writers
run resolved and derive their tenant from context, never request input. Finite
source admission and database isolation independently constrain these writes.
The Seeder remains their production caller.
Phase 02c owns the planned Hub-internal
routes: tenant creation invokes ProvisionTenantCommand, which also creates the
default organization, and host mapping invokes MapHostToTenantCommand. It adds
no direct CreateOrganizationCommand endpoint. That future surface accepts only
learnstack-hub realm tokens and needs its own admitted operation policy.
A future host-mapping route requires its own admission decision.
MapHostToTenantCommand controls whose data an anonymous request sees. The proposed
tenancy.hostmapping.admin key therefore describes an admin-scope act, outside
ordinary tenant-admin grants; HostMapping has no write action. The proposed
tenancy.tenant.admin remains a future provisioning example, not a P03-3 grant.
The older unregistered tenancy.organization.write example is replaced for this
packet by Tenant tenancy.organization.admin, covering lifecycle/default acts.
P03-3 creates no human host-mapping, domain, feature-flag or platform-operator
authority. Their named Phase 02c/P03-9 surfaces retain separate admission decisions.
| Resource | read | write | delete | admin | Default role grants |
|---|---|---|---|---|---|
Organization (organization) |
– | – | – | Tenant | Exact v2 Tenant Admin delta; only admitted Organization/default operations |
TenantLocale (locale) |
– | Tenant | – | – | Same delta; only admitted locale operations through Tenant root |
TenantSetting (setting) |
– | Tenant | – | – | Same delta; whole tenant-wide branding.theme plus ADR-0093's exact invitation policy |
Tenant has no delete: deprovisioning has no owning phase, and
Database Standards § GRANT matrix records that
the widening it needs is an ADR's to make, not a migration's.
Internal human requests carry separate Protected policies and audit bindings. Phase 03 owns packet state and transport qualification. All human writes require current Tenant capability, exact orgless context and fresh target/delegation/version checks under the canonical fences. The Tenant comes from resolved context; OrganizationId is a resource selector, not authority. Org Admin receives none of these three pairs. Its own-organization settings and Organization editor capabilities require a separate Phase 06 decision/consumer.
| Human request | Exact Tenant capability | Root |
|---|---|---|
ListOrganizationsQuery |
tenancy.organization.admin |
Detached bounded page; current Tenant default/version metadata |
GetOrganizationDetailQuery |
Same | Detached Organization and current default association |
ReadOrganizationReceiptQuery |
tenancy.organization.admin |
Exact original retained Organization; Scoped ordinary ReadWrite with fresh MUST disclosure audit, no original mutation rerun |
ReadDefaultOrganizationReceiptQuery |
Same | Original Tenant default-outcome resource, not the selected Organization; current disclosure capability and MUST read audit |
CreateManagedOrganizationCommand |
tenancy.organization.admin |
Organization |
RenameOrganizationCommand |
Same | Organization |
ArchiveOrganizationCommand |
Same | Organization |
SelectDefaultOrganizationCommand |
Same | Tenant; Active/nondeleted selected Organization must belong to it |
AddManagedTenantLocaleCommand |
tenancy.locale.write |
Tenant |
SetManagedDefaultTenantLocaleCommand |
Same | Tenant |
SetTenantLocaleEnabledCommand |
Same | Tenant |
RemoveTenantLocaleCommand |
Same | Tenant |
SetManagedTenantBrandingCommand |
tenancy.setting.write |
TenantSetting |
These requests share module business logic with the existing Seed acts without
dispatching them or obtaining Seed provenance. TenancyOperationPolicySource
classifies each human request separately; audit
owns the exact event/class bindings. Organization reads require the same Tenant
administration capability and MUST configuration-read audit; reads do not imply
an orgless mutation. Receipt reads permit terminal target facts only for their
original outcome, leaving ordinary list/detail filters unchanged. Default selection writes only Tenant's reference/version,
not the target Organization. Locale writes capture Tenant's contained navigation.
The new AdoptSeedAdministrationOriginCommand is instead a closed Seed-only act,
one Tenant per invocation. It cannot be sent by a human wrapper or obtained from
the v2 grant. Its fixed mapping projection and Tenant marker share the announced
unit of work and two MUST intents. No general host-mapping route or permission
is introduced. The module contract
and Standard 05
own exact witness/adoption/fence rules and write-free repeats.
Derives from: ADR-0093.
This Accepted extension adds the exact tenant-wide identity.invitation.ttl_days
setting operation to existing Tenant tenancy.setting.write; runtime/proof
remain P03-4 in the phase Status block. Existing holders gain this bounded
operation. No new pair, release, automatic grant or generic settings power is
introduced. A v1 tenant without the pair uses the 14-day default but cannot
edit; the explicit v2 adoption remains the only exceptional new-key grant path.
| Application consumer | Exact authority | Root / audit |
|---|---|---|
GetTenantInvitationPolicyQuery |
Own-current-tenant Membership coverage, orgless context | Only default/current bounded lifetime and absent/default or root version precondition; Off and physical ReadOnly |
SetTenantInvitationLifetimeCommand |
Tenant tenancy.setting.write, orgless context, fresh target/version checks |
One TenantSetting root, fixed key, integer 1–30 days; MUST update and protected keyed receipt |
ReadInvitationPolicyReceiptQuery |
Current own-Membership coverage in the same orgless tenant | Exact original retained TenantSetting ID/key; MUST read, no old write-permission requirement or other-setting disclosure |
First creation requires the explicit absent/default precondition and natural-key uniqueness; a race refuses, never becomes an unconditional upsert. Later writes require canonical strong If-Match. Policy changes do not extend prepared links; each initial send or explicit reissue freezes its current policy expiry. Read contracts supply no arbitrary setting directory or Organization setting variant. Identity consumes the bounded policy through Tenancy's application contract, never direct Tenancy SQL. Standard 19 owns grant adoption semantics and the API standard owns exact transport/replay consumers.