Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/29318-tenancy-posture-activation-prose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@objectstack/spec': patch
---

docs(spec): the tenancy-posture docblocks say which side of the open/commercial split each activation sentence describes

Clause-②: no
Metadata-protocol: none

Comment-only. The header of `@objectstack/spec`'s tenancy-posture module and the `postureStampsOrganization` docblock said "open code does not mean free activation" without saying where, which read as if a multi-organization posture were licence-gated everywhere. It is not: on an open install `@objectstack/organizations` ships under Apache-2.0 with no licence check and entitles both walled postures by construction (ADR-0132 D1, D2, D4), so mounting it is enough. Only on a commercial host, where the package of the same name subclasses the open one and adds its licence gate (ADR-0132 D2, D3), does activation need an entitlement. The cloud ADR-0016 iron-rule paragraph no longer says the guarantee comes from not "giving the posture away": the guarantee is that a multi-organization shape never runs unwalled (ADR-0093 D5), on either side of the split. No schema, type, export or runtime behaviour changes.
40 changes: 26 additions & 14 deletions packages/spec/src/security/tenancy-posture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,32 @@
* group-wide visibility and cross-org workflow are inherent to the shape, and
* a hard per-org wall makes both an architecture problem.
*
* ## Open code, entitled activation
* ## Open code; activation is entitled only on a commercial host
*
* The wall's IMPLEMENTATION is open — the Layer 0 compiler, `accessible_org_ids`
* resolution and the D5 write stamping all ship in open packages — but ENABLING
* resolution and the D5 write stamping all ship in open packages — and ENABLING
* a multi-organization posture (`group` or `isolated`) requires the
* `@objectstack/organizations` runtime to be mounted (ADR-0105 D12, ADR-0093 D5).
* That runtime is open code too: it ships from this repository under Apache-2.0
* (ADR-0132 D1). What stays commercial is the entitlement — the licence gate the
* commercial package of the same name adds by subclassing the open one (ADR-0132
* D2, D3). The two are separate questions and must not be conflated: open code
* does not mean free activation.
*
* Cloud ADR-0016's 铁律 (强制免费、治理收费) is satisfied by the first half alone —
* it guarantees that a deployment RUNNING a multi-org shape is safe, which the
* platform delivers by REFUSING to run one unwalled (ADR-0093 D5), not by giving
* the posture away. You never silently get an unenforced organization boundary.
* (ADR-0132 D1). Implementation and entitlement are separate questions and must
* not be conflated, and which side of the split a deployment sits on answers
* the second one:
*
* - On an OPEN install, activation is gate-free. The open runtime carries no
* licence check of any kind (ADR-0132 D2) and entitles both walled postures
* by construction (ADR-0132 D4): mounting it is enough.
* - On a COMMERCIAL host, activation is entitled. The commercial package of the
* same name subclasses the open one and answers its licence gate in its own
* constructor, and the host's manifest resolves the name to that package
* (ADR-0132 D2, D3); it may also narrow which walled postures it entitles.
* There, and only there, open code does not mean free activation.
*
* Cloud ADR-0016's 铁律 (强制免费、治理收费) is satisfied by the wall itself, on
* both sides of the split — it guarantees that a deployment RUNNING a multi-org
* shape is safe, which the platform delivers by REFUSING to run one unwalled
* (ADR-0093 D5). Whether switching the posture on is free is the entitlement
* question above, not the iron rule's. You never silently get an unenforced
* organization boundary.
*/

import { z } from 'zod';
Expand Down Expand Up @@ -75,9 +85,11 @@ export function postureEnforcesWall(posture: TenancyPosture): boolean {
* runtime (open code, ADR-0132 D1) fills an absent value too, in its write
* middleware, but it is not the only stamper.
*
* What does need that runtime is ACTIVATING a walled posture (ADR-0105 D12):
* open code does not mean free activation. This predicate is the shared
* vocabulary for the stamping rule, whichever package does the stamping.
* What does need that runtime is ACTIVATING a walled posture (ADR-0105 D12).
* On an open install mounting it is enough (ADR-0132 D4); only on a commercial
* host is that activation licence-gated (ADR-0132 D2), and there open code does
* not mean free activation. This predicate is the shared vocabulary for the
* stamping rule, whichever package does the stamping.
*/
export function postureStampsOrganization(posture: TenancyPosture): boolean {
return postureEnforcesWall(posture);
Expand Down
Loading