@substrat-run/contracts 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control-plane.d.ts +111 -2
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +111 -3
- package/dist/control-plane.js.map +1 -1
- package/dist/ids.d.ts +2 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +5 -0
- package/dist/ids.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.js +2 -2
- package/dist/manifest.js.map +1 -1
- package/dist/permission.d.ts.map +1 -1
- package/dist/permission.js +5 -0
- package/dist/permission.js.map +1 -1
- package/dist/registry.d.ts +133 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +95 -0
- package/dist/registry.js.map +1 -0
- package/dist/routing.d.ts +124 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +108 -0
- package/dist/routing.js.map +1 -0
- package/dist/tenancy.d.ts +62 -0
- package/dist/tenancy.d.ts.map +1 -1
- package/dist/tenancy.js +61 -1
- package/dist/tenancy.js.map +1 -1
- package/package.json +1 -1
package/dist/control-plane.d.ts
CHANGED
|
@@ -5,6 +5,18 @@ export declare const adminAction: z.ZodEnum<{
|
|
|
5
5
|
grant: "grant";
|
|
6
6
|
grantToOrg: "grantToOrg";
|
|
7
7
|
addMember: "addMember";
|
|
8
|
+
removeMember: "removeMember";
|
|
9
|
+
createOrg: "createOrg";
|
|
10
|
+
registerIdentityPool: "registerIdentityPool";
|
|
11
|
+
registerVertical: "registerVertical";
|
|
12
|
+
publishVersion: "publishVersion";
|
|
13
|
+
admitVersion: "admitVersion";
|
|
14
|
+
rejectVersion: "rejectVersion";
|
|
15
|
+
bindScopeVersion: "bindScopeVersion";
|
|
16
|
+
promoteVersion: "promoteVersion";
|
|
17
|
+
bindHostname: "bindHostname";
|
|
18
|
+
setHostnameStatus: "setHostnameStatus";
|
|
19
|
+
pruneAccessLog: "pruneAccessLog";
|
|
8
20
|
createTenant: "createTenant";
|
|
9
21
|
setTenantStatus: "setTenantStatus";
|
|
10
22
|
provisionScope: "provisionScope";
|
|
@@ -33,12 +45,96 @@ export declare const identityLink: z.ZodObject<{
|
|
|
33
45
|
scopeId: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
|
|
34
46
|
}, z.core.$strip>;
|
|
35
47
|
export type IdentityLink = z.infer<typeof identityLink>;
|
|
48
|
+
/**
|
|
49
|
+
* How an identity pool relates to tenants (K-23) — the fact that decides whether the
|
|
50
|
+
* same `externalId` seen in two tenants is one human or two.
|
|
51
|
+
*
|
|
52
|
+
* `central`: one pool serving many tenants. The same external subject IS the same
|
|
53
|
+
* person everywhere, which is what lets one login belong to several tenants (§4.3's
|
|
54
|
+
* staff case, and a branded multi-tenant consumer product like RallyPoint).
|
|
55
|
+
*
|
|
56
|
+
* `tenant-bound`: one pool serving exactly one tenant. Subject ids are unique only
|
|
57
|
+
* within it, so the same `externalId` in another tenant is a DIFFERENT person — the
|
|
58
|
+
* white-label case, where a consumer of two shops is correctly two accounts.
|
|
59
|
+
*
|
|
60
|
+
* Topology, not audience. The audiences in §4.3 are descriptive; this is enforceable.
|
|
61
|
+
*/
|
|
62
|
+
export declare const poolTopology: z.ZodEnum<{
|
|
63
|
+
central: "central";
|
|
64
|
+
"tenant-bound": "tenant-bound";
|
|
65
|
+
}>;
|
|
66
|
+
export type PoolTopology = z.infer<typeof poolTopology>;
|
|
67
|
+
/**
|
|
68
|
+
* A registered identity provider. `provider` names exactly one pool, so separate
|
|
69
|
+
* per-tenant deployments take distinct provider strings (`oidc:<issuer>`) — which the
|
|
70
|
+
* `identityLink` comment above already assumed.
|
|
71
|
+
*
|
|
72
|
+
* `tenantId` is non-null exactly when `topology` is `tenant-bound`: it is the one
|
|
73
|
+
* tenant that pool may serve, and linking into any other is refused.
|
|
74
|
+
*/
|
|
75
|
+
export declare const identityPool: z.ZodObject<{
|
|
76
|
+
provider: z.ZodString;
|
|
77
|
+
topology: z.ZodEnum<{
|
|
78
|
+
central: "central";
|
|
79
|
+
"tenant-bound": "tenant-bound";
|
|
80
|
+
}>;
|
|
81
|
+
tenantId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "TenantId", "out">>;
|
|
82
|
+
}, z.core.$strip>;
|
|
83
|
+
export type IdentityPool = z.infer<typeof identityPool>;
|
|
84
|
+
/**
|
|
85
|
+
* What the directory knows about an authenticated external identity, once the caller
|
|
86
|
+
* has said WHICH tenant's pool it came from.
|
|
87
|
+
*
|
|
88
|
+
* No `tenantId` here on purpose. The lookup takes the tenant as input (§4.3: with one
|
|
89
|
+
* auth pool per white-label tenant, an external subject id is unique only *within* its
|
|
90
|
+
* pool), so echoing it back would invite the very mental model this fixes — that the
|
|
91
|
+
* directory derives the tenant from the identity. You tell it which tenant; it tells
|
|
92
|
+
* you who.
|
|
93
|
+
*/
|
|
36
94
|
export declare const resolvedIdentity: z.ZodObject<{
|
|
37
95
|
principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
38
|
-
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
39
96
|
scopeId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
|
|
40
97
|
}, z.core.$strip>;
|
|
41
98
|
export type ResolvedIdentity = z.infer<typeof resolvedIdentity>;
|
|
99
|
+
/**
|
|
100
|
+
* One staff READ of the directory (K-24). Separate from `adminLogEntry` because a
|
|
101
|
+
* mutation is permanent evidence and a read is operational history — one table would
|
|
102
|
+
* force one retention policy on both.
|
|
103
|
+
*
|
|
104
|
+
* `resultCount` is what separates navigation from an incident: "called listScopes"
|
|
105
|
+
* against "enumerated 4,000 tenants".
|
|
106
|
+
*
|
|
107
|
+
* `drainedAt` marks a row shipped to Tier 2. Only drained rows may be pruned —
|
|
108
|
+
* expiring on age alone would destroy evidence while calling itself retention.
|
|
109
|
+
*/
|
|
110
|
+
export declare const accessLogEntry: z.ZodObject<{
|
|
111
|
+
id: z.ZodString;
|
|
112
|
+
actor: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
113
|
+
method: z.ZodString;
|
|
114
|
+
tenantId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "TenantId", "out">>;
|
|
115
|
+
scopeId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
|
|
116
|
+
params: z.ZodNullable<z.ZodString>;
|
|
117
|
+
resultCount: z.ZodNumber;
|
|
118
|
+
drainedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
119
|
+
at: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
120
|
+
}, z.core.$strip>;
|
|
121
|
+
export type AccessLogEntry = z.infer<typeof accessLogEntry>;
|
|
122
|
+
/**
|
|
123
|
+
* One principal's membership of one org, as the directory holds it (K-21).
|
|
124
|
+
*
|
|
125
|
+
* `revokedAt` non-null is a **tombstone**: the tuple is still here and still
|
|
126
|
+
* readable, and the permission walk skips it. Deletion is not an option — an
|
|
127
|
+
* operated compliance product has to show both that access was revoked and the
|
|
128
|
+
* trail proving it was once granted (D-32), and a deleted row shows neither.
|
|
129
|
+
*
|
|
130
|
+
* Listing defaults to live members only; revoked rows are the evidence view.
|
|
131
|
+
*/
|
|
132
|
+
export declare const orgMembership: z.ZodObject<{
|
|
133
|
+
principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
134
|
+
orgId: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
|
|
135
|
+
revokedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
136
|
+
}, z.core.$strip>;
|
|
137
|
+
export type OrgMembership = z.infer<typeof orgMembership>;
|
|
42
138
|
/**
|
|
43
139
|
* An append-only admin audit row (control-plane.md §4.4). Every field except
|
|
44
140
|
* `before`/`after` is stamped platform-side — never supplied by the caller —
|
|
@@ -58,6 +154,18 @@ export declare const adminLogEntry: z.ZodObject<{
|
|
|
58
154
|
grant: "grant";
|
|
59
155
|
grantToOrg: "grantToOrg";
|
|
60
156
|
addMember: "addMember";
|
|
157
|
+
removeMember: "removeMember";
|
|
158
|
+
createOrg: "createOrg";
|
|
159
|
+
registerIdentityPool: "registerIdentityPool";
|
|
160
|
+
registerVertical: "registerVertical";
|
|
161
|
+
publishVersion: "publishVersion";
|
|
162
|
+
admitVersion: "admitVersion";
|
|
163
|
+
rejectVersion: "rejectVersion";
|
|
164
|
+
bindScopeVersion: "bindScopeVersion";
|
|
165
|
+
promoteVersion: "promoteVersion";
|
|
166
|
+
bindHostname: "bindHostname";
|
|
167
|
+
setHostnameStatus: "setHostnameStatus";
|
|
168
|
+
pruneAccessLog: "pruneAccessLog";
|
|
61
169
|
createTenant: "createTenant";
|
|
62
170
|
setTenantStatus: "setTenantStatus";
|
|
63
171
|
provisionScope: "provisionScope";
|
|
@@ -69,11 +177,12 @@ export declare const adminLogEntry: z.ZodObject<{
|
|
|
69
177
|
revokeEntitlement: "revokeEntitlement";
|
|
70
178
|
linkIdentity: "linkIdentity";
|
|
71
179
|
}>;
|
|
72
|
-
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out"
|
|
180
|
+
tenantId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "TenantId", "out">>;
|
|
73
181
|
scopeId: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
|
|
74
182
|
vertical: z.ZodNullable<z.ZodString>;
|
|
75
183
|
before: z.ZodNullable<z.ZodUnknown>;
|
|
76
184
|
after: z.ZodNullable<z.ZodUnknown>;
|
|
185
|
+
causedBy: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "EventId", "out">>;
|
|
77
186
|
at: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
78
187
|
}, z.core.$strip>;
|
|
79
188
|
export type AdminLogEntry = z.infer<typeof adminLogEntry>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkBxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;;iBAMvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY;;;EAAsC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;;;iBAQrB,CAAC;AACL,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;iBAUzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;iBAIxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4BxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
package/dist/control-plane.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { instant, platformActorId, principalId, scopeId, tenantId } from './ids.js';
|
|
2
|
+
import { eventId, instant, orgId, platformActorId, principalId, scopeId, tenantId, } from './ids.js';
|
|
3
3
|
// The control plane — the shared layer across N per-vertical deployments (D-30,
|
|
4
4
|
// control-plane.md). This file carries the audit contract that every effecting
|
|
5
5
|
// mutation writes; the tenant registry, lifecycle, and entitlement store land in
|
|
@@ -12,6 +12,18 @@ export const adminAction = z.enum([
|
|
|
12
12
|
'grant',
|
|
13
13
|
'grantToOrg',
|
|
14
14
|
'addMember',
|
|
15
|
+
'removeMember', // K-21 — tombstones the membership tuple, never deletes it
|
|
16
|
+
'createOrg', // K-22 — orgs are a real record, not a free-form string
|
|
17
|
+
'registerIdentityPool',
|
|
18
|
+
'registerVertical', // #31 — the vertical + version registry
|
|
19
|
+
'publishVersion',
|
|
20
|
+
'admitVersion',
|
|
21
|
+
'rejectVersion',
|
|
22
|
+
'bindScopeVersion',
|
|
23
|
+
'promoteVersion',
|
|
24
|
+
'bindHostname', // K-26 — the hostname map
|
|
25
|
+
'setHostnameStatus', // #31 step 2 — where the two human checkpoints fire
|
|
26
|
+
'pruneAccessLog', // K-24 — deleting drained access rows is itself a mutation // K-23 — a provider declares its topology before it may link
|
|
15
27
|
'createTenant', // §4.1
|
|
16
28
|
'setTenantStatus', // §4.1 — before/after carry the transitioned status
|
|
17
29
|
'provisionScope', // §4.2 — the first scope-lifecycle transition (→ active)
|
|
@@ -38,11 +50,89 @@ export const identityLink = z.object({
|
|
|
38
50
|
tenantId,
|
|
39
51
|
scopeId: scopeId.optional(), // omitted = tenant-level home
|
|
40
52
|
});
|
|
53
|
+
/**
|
|
54
|
+
* How an identity pool relates to tenants (K-23) — the fact that decides whether the
|
|
55
|
+
* same `externalId` seen in two tenants is one human or two.
|
|
56
|
+
*
|
|
57
|
+
* `central`: one pool serving many tenants. The same external subject IS the same
|
|
58
|
+
* person everywhere, which is what lets one login belong to several tenants (§4.3's
|
|
59
|
+
* staff case, and a branded multi-tenant consumer product like RallyPoint).
|
|
60
|
+
*
|
|
61
|
+
* `tenant-bound`: one pool serving exactly one tenant. Subject ids are unique only
|
|
62
|
+
* within it, so the same `externalId` in another tenant is a DIFFERENT person — the
|
|
63
|
+
* white-label case, where a consumer of two shops is correctly two accounts.
|
|
64
|
+
*
|
|
65
|
+
* Topology, not audience. The audiences in §4.3 are descriptive; this is enforceable.
|
|
66
|
+
*/
|
|
67
|
+
export const poolTopology = z.enum(['central', 'tenant-bound']);
|
|
68
|
+
/**
|
|
69
|
+
* A registered identity provider. `provider` names exactly one pool, so separate
|
|
70
|
+
* per-tenant deployments take distinct provider strings (`oidc:<issuer>`) — which the
|
|
71
|
+
* `identityLink` comment above already assumed.
|
|
72
|
+
*
|
|
73
|
+
* `tenantId` is non-null exactly when `topology` is `tenant-bound`: it is the one
|
|
74
|
+
* tenant that pool may serve, and linking into any other is refused.
|
|
75
|
+
*/
|
|
76
|
+
export const identityPool = z
|
|
77
|
+
.object({
|
|
78
|
+
provider: z.string().min(1),
|
|
79
|
+
topology: poolTopology,
|
|
80
|
+
tenantId: tenantId.nullable(),
|
|
81
|
+
})
|
|
82
|
+
.refine((p) => (p.topology === 'tenant-bound') === (p.tenantId !== null), {
|
|
83
|
+
message: 'tenant-bound pools name their tenant; central pools must not',
|
|
84
|
+
});
|
|
85
|
+
/**
|
|
86
|
+
* What the directory knows about an authenticated external identity, once the caller
|
|
87
|
+
* has said WHICH tenant's pool it came from.
|
|
88
|
+
*
|
|
89
|
+
* No `tenantId` here on purpose. The lookup takes the tenant as input (§4.3: with one
|
|
90
|
+
* auth pool per white-label tenant, an external subject id is unique only *within* its
|
|
91
|
+
* pool), so echoing it back would invite the very mental model this fixes — that the
|
|
92
|
+
* directory derives the tenant from the identity. You tell it which tenant; it tells
|
|
93
|
+
* you who.
|
|
94
|
+
*/
|
|
41
95
|
export const resolvedIdentity = z.object({
|
|
42
96
|
principal: principalId,
|
|
43
|
-
tenantId,
|
|
44
97
|
scopeId: scopeId.nullable(),
|
|
45
98
|
});
|
|
99
|
+
/**
|
|
100
|
+
* One staff READ of the directory (K-24). Separate from `adminLogEntry` because a
|
|
101
|
+
* mutation is permanent evidence and a read is operational history — one table would
|
|
102
|
+
* force one retention policy on both.
|
|
103
|
+
*
|
|
104
|
+
* `resultCount` is what separates navigation from an incident: "called listScopes"
|
|
105
|
+
* against "enumerated 4,000 tenants".
|
|
106
|
+
*
|
|
107
|
+
* `drainedAt` marks a row shipped to Tier 2. Only drained rows may be pruned —
|
|
108
|
+
* expiring on age alone would destroy evidence while calling itself retention.
|
|
109
|
+
*/
|
|
110
|
+
export const accessLogEntry = z.object({
|
|
111
|
+
id: z.string().min(1),
|
|
112
|
+
actor: platformActorId,
|
|
113
|
+
method: z.string().min(1),
|
|
114
|
+
tenantId: tenantId.nullable(),
|
|
115
|
+
scopeId: scopeId.nullable(),
|
|
116
|
+
params: z.string().nullable(),
|
|
117
|
+
resultCount: z.number().int().nonnegative(),
|
|
118
|
+
drainedAt: instant.nullable(),
|
|
119
|
+
at: instant,
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* One principal's membership of one org, as the directory holds it (K-21).
|
|
123
|
+
*
|
|
124
|
+
* `revokedAt` non-null is a **tombstone**: the tuple is still here and still
|
|
125
|
+
* readable, and the permission walk skips it. Deletion is not an option — an
|
|
126
|
+
* operated compliance product has to show both that access was revoked and the
|
|
127
|
+
* trail proving it was once granted (D-32), and a deleted row shows neither.
|
|
128
|
+
*
|
|
129
|
+
* Listing defaults to live members only; revoked rows are the evidence view.
|
|
130
|
+
*/
|
|
131
|
+
export const orgMembership = z.object({
|
|
132
|
+
principal: principalId,
|
|
133
|
+
orgId,
|
|
134
|
+
revokedAt: instant.nullable(),
|
|
135
|
+
});
|
|
46
136
|
/**
|
|
47
137
|
* An append-only admin audit row (control-plane.md §4.4). Every field except
|
|
48
138
|
* `before`/`after` is stamped platform-side — never supplied by the caller —
|
|
@@ -57,11 +147,29 @@ export const adminLogEntry = z.object({
|
|
|
57
147
|
id: z.string().min(1), // ULID, stamped host-side; sortable = chronological
|
|
58
148
|
actor: platformActorId,
|
|
59
149
|
action: adminAction,
|
|
60
|
-
|
|
150
|
+
// Nullable for PLATFORM-level actions that target no tenant — registering a central
|
|
151
|
+
// identity pool is the first (K-23). Every tenant-scoped action still carries one;
|
|
152
|
+
// null means "the platform itself", not "unknown".
|
|
153
|
+
tenantId: tenantId.nullable(),
|
|
61
154
|
scopeId: scopeId.nullable(),
|
|
62
155
|
vertical: z.string().nullable(),
|
|
63
156
|
before: z.unknown().nullable(), // prior state where cheaply readable (e.g. a redefined role)
|
|
64
157
|
after: z.unknown().nullable(), // the applied payload
|
|
158
|
+
/**
|
|
159
|
+
* The domain event that caused this action, when one did (K-22 §4.2).
|
|
160
|
+
*
|
|
161
|
+
* The connector seam splits a change across two halves: a module emits inside its
|
|
162
|
+
* own transaction, and a privileged executor outside module code effects it. That
|
|
163
|
+
* splits the trail too — control-plane.md §3 named it as the main thing the pattern
|
|
164
|
+
* worsens. This is the join, and it is the EVENT ID rather than a new correlation
|
|
165
|
+
* field: the envelope already carries a kernel-stamped unique id that is the
|
|
166
|
+
* idempotency key downstream, so reusing it avoids widening a frozen contract
|
|
167
|
+
* (D-5/D-28) to say something it already says.
|
|
168
|
+
*
|
|
169
|
+
* Null for the ordinary case — a staff member acting directly caused nothing but
|
|
170
|
+
* themselves.
|
|
171
|
+
*/
|
|
172
|
+
causedBy: eventId.nullable(),
|
|
65
173
|
at: instant,
|
|
66
174
|
});
|
|
67
175
|
//# sourceMappingURL=control-plane.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"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"}
|
package/dist/ids.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export declare const scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
|
5
5
|
export type ScopeId = z.infer<typeof scopeId>;
|
|
6
6
|
export declare const principalId: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
7
7
|
export type PrincipalId = z.infer<typeof principalId>;
|
|
8
|
+
export declare const orgId: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
|
|
9
|
+
export type OrgId = z.infer<typeof orgId>;
|
|
8
10
|
export declare const platformActorId: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
9
11
|
export type PlatformActorId = z.infer<typeof platformActorId>;
|
|
10
12
|
export declare const eventId: z.core.$ZodBranded<z.ZodString, "EventId", "out">;
|
package/dist/ids.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,QAAQ,oDAA6C,CAAC;AACnE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,OAAO,mDAA4C,CAAC;AACjE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,WAAW,uDAAgD,CAAC;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,QAAQ,oDAA6C,CAAC;AACnE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,OAAO,mDAA4C,CAAC;AACjE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,WAAW,uDAAgD,CAAC;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAMtD,eAAO,MAAM,KAAK,iDAA0C,CAAC;AAC7D,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;AAK1C,eAAO,MAAM,eAAe,2DAAoD,CAAC;AACjF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,OAAO,mDAA4C,CAAC;AACjE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAE9C,eAAO,MAAM,aAAa,yDAAkD,CAAC;AAC7E,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAG1D,eAAO,MAAM,QAAQ,oDAGC,CAAC;AACvB,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAGhD,eAAO,MAAM,OAAO,mDAA2D,CAAC;AAChF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,OAAO,CAAC,CAAC;AAG9C,eAAO,MAAM,aAAa,yDAGC,CAAC;AAC5B,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,eAAO,MAAM,IAAI,aAAwD,CAAC"}
|
package/dist/ids.js
CHANGED
|
@@ -6,6 +6,11 @@ const ULID = /^[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
|
6
6
|
export const tenantId = z.string().regex(ULID).brand();
|
|
7
7
|
export const scopeId = z.string().regex(ULID).brand();
|
|
8
8
|
export const principalId = z.string().regex(ULID).brand();
|
|
9
|
+
// An organization inside a tenant — the subject of membership tuples and the target
|
|
10
|
+
// of `grantToOrg` (K-22). Branded like every other id: `orgId` was a free-form string
|
|
11
|
+
// until orgs became a real record, so `acme` and `Acme` silently addressed different
|
|
12
|
+
// orgs and a typo in a grant reached a phantom nothing would ever resolve to.
|
|
13
|
+
export const orgId = z.string().regex(ULID).brand();
|
|
9
14
|
// A platform-staff actor — the subject of every control-plane mutation (D-30, K-20).
|
|
10
15
|
// Branded DISTINCTLY from PrincipalId on purpose: a platform actor is not a principal
|
|
11
16
|
// in any tenant, and the compiler must refuse to confuse the two.
|
package/dist/ids.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,oFAAoF;AACpF,oFAAoF;AACpF,oEAAoE;AAEpE,MAAM,IAAI,GAAG,0BAA0B,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAc,CAAC;AAGnE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAa,CAAC;AAGjE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAiB,CAAC;AAGzE,qFAAqF;AACrF,sFAAsF;AACtF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAqB,CAAC;AAGjF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAa,CAAC;AAGjE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAmB,CAAC;AAG7E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,KAAK,CAAC,wDAAwD,CAAC;KAC/D,KAAK,EAAc,CAAC;AAGvB,gFAAgF;AAChF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAa,CAAC;AAGhF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,KAAK,CAAC,yBAAyB,CAAC;KAChC,KAAK,EAAmB,CAAC;AAG5B,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,oFAAoF;AACpF,oFAAoF;AACpF,oEAAoE;AAEpE,MAAM,IAAI,GAAG,0BAA0B,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAc,CAAC;AAGnE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAa,CAAC;AAGjE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAiB,CAAC;AAGzE,oFAAoF;AACpF,sFAAsF;AACtF,qFAAqF;AACrF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAW,CAAC;AAG7D,qFAAqF;AACrF,sFAAsF;AACtF,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAqB,CAAC;AAGjF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAa,CAAC;AAGjE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAmB,CAAC;AAG7E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC;KACtB,MAAM,EAAE;KACR,KAAK,CAAC,wDAAwD,CAAC;KAC/D,KAAK,EAAc,CAAC;AAGvB,gFAAgF;AAChF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAa,CAAC;AAGhF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,KAAK,CAAC,yBAAyB,CAAC;KAChC,KAAK,EAAmB,CAAC;AAG5B,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
|
package/dist/manifest.js
CHANGED
|
@@ -55,8 +55,8 @@ export const moduleManifest = z.object({
|
|
|
55
55
|
// Keyed on operations, never on engine transitions: the kernel sees
|
|
56
56
|
// operations, and must not learn engine internals (star topology). Policy
|
|
57
57
|
// that is CONDITIONAL on vertical data (e.g. "only montage orders need an
|
|
58
|
-
//
|
|
59
|
-
// demos/
|
|
58
|
+
// self-inspection") stays vertical-composed glue inside the operation — see
|
|
59
|
+
// demos/callout. Guards live here so that adding or DROPPING a compliance gate
|
|
60
60
|
// lands in the reviewable manifest diff.
|
|
61
61
|
//
|
|
62
62
|
// Optional: every pre-milestone-C manifest still parses unchanged (D-28,
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,0EAA0E;AAC1E,wEAAwE;AAExE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,KAAK,CAAC,sDAAsD,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,GAAG,EAAE,aAAa;IAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,qDAAqD;CACtF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,SAAS;IACf,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,gDAAgD;IAC3E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,8CAA8C;IAC5E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,wBAAwB;CAChF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,QAAQ,EAAE,mCAAmC;IACjD,OAAO,EAAE,aAAa;IACtB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,4CAA4C;IAC/E,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;QAC5B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,uDAAuD;KACzF,CAAC;IACF,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,8CAA8C;QAC7E,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,iDAAiD;KACrF,CAAC;IACF,iBAAiB,EAAE,CAAC,CAAC,KAAK,CACxB,CAAC,CAAC,MAAM,CAAC;QACP,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,cAAc,EAAE,aAAa,EAAE,mDAAmD;KACnF,CAAC,CACH;IACD,4EAA4E;IAC5E,8EAA8E;IAC9E,sDAAsD;IACtD,eAAe,EAAE,CAAC;SACf,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,cAAc;QAC7C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,aAAa;KAC7C,CAAC,CACH;SACA,QAAQ,EAAE;IACb,2EAA2E;IAC3E,4EAA4E;IAC5E,sEAAsE;IACtE,0EAA0E;IAC1E,sEAAsE;IACtE,0CAA0C;IAC1C,EAAE;IACF,oEAAoE;IACpE,0EAA0E;IAC1E,0EAA0E;IAC1E,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/permission.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,IAAI;;;iBAGf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,eAAO,MAAM,OAAO,aAAwD,CAAC;AAE7E,eAAO,MAAM,cAAc;;;;iBAUzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;;;;;iBAAsC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,cAAc;;;;;;;iBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAM5D,eAAO,MAAM,eAAe;;;;;;;;;;;;;iBAO1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,IAAI;;;iBAGf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC,eAAO,MAAM,OAAO,aAAwD,CAAC;AAE7E,eAAO,MAAM,cAAc;;;;iBAUzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;;;;;iBAAsC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,cAAc;;;;;;;iBAIzB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAM5D,eAAO,MAAM,eAAe;;;;;;;;;;;;;iBAO1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAgB9D,eAAO,MAAM,SAAS,qDAGC,CAAC;AACxB,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAGlD,eAAO,MAAM,YAAY,aAAqC,CAAC;AAE/D,eAAO,MAAM,aAAa;;;;iBAIxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAQ1D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;8BAUnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAS/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
package/dist/permission.js
CHANGED
|
@@ -54,6 +54,11 @@ export const capabilityGrant = z.object({
|
|
|
54
54
|
// ============================================================================
|
|
55
55
|
// 'principal:<ulid>' | 'org:<ulid>' | 'tenant:<ulid>' | 'scope:<ulid>' |
|
|
56
56
|
// '<entityType>:<entityId>' — namespace:id
|
|
57
|
+
//
|
|
58
|
+
// The regex is deliberately loose on the id half: entity ids are vertical-owned and
|
|
59
|
+
// need not be ULIDs. The kernel-owned namespaces above ARE all branded ULIDs at their
|
|
60
|
+
// own boundary — `org:` became one in K-22, which is when this comment stopped being
|
|
61
|
+
// aspirational.
|
|
57
62
|
export const objectRef = z
|
|
58
63
|
.string()
|
|
59
64
|
.regex(/^[a-z0-9_-]+:[^\s]+$/)
|
package/dist/permission.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The vertical + version registry (#31 step 1; D-33's milestone one).
|
|
4
|
+
*
|
|
5
|
+
* Today a scope carries a nullable `vertical` STRING — a label nothing validates and
|
|
6
|
+
* nothing can be pinned to. That is enough to say "this scope runs Callout" and not
|
|
7
|
+
* enough to say *which Callout*, which is what dev/staging/prod and preview
|
|
8
|
+
* deployments are: the same vertical at different versions.
|
|
9
|
+
*
|
|
10
|
+
* The registry makes a version a real record with digests, so promotion can compare
|
|
11
|
+
* two of them, and an admission status, so **push is not live**.
|
|
12
|
+
*/
|
|
13
|
+
/** Where a vertical came from. `builtin` is one we ship; the others are a customer's. */
|
|
14
|
+
export declare const verticalSource: z.ZodEnum<{
|
|
15
|
+
builtin: "builtin";
|
|
16
|
+
git: "git";
|
|
17
|
+
cli: "cli";
|
|
18
|
+
}>;
|
|
19
|
+
export type VerticalSource = z.infer<typeof verticalSource>;
|
|
20
|
+
export declare const vertical: z.ZodObject<{
|
|
21
|
+
slug: z.ZodString;
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
source: z.ZodEnum<{
|
|
24
|
+
builtin: "builtin";
|
|
25
|
+
git: "git";
|
|
26
|
+
cli: "cli";
|
|
27
|
+
}>;
|
|
28
|
+
createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export type Vertical = z.infer<typeof vertical>;
|
|
31
|
+
export declare const registerVerticalInput: z.ZodObject<{
|
|
32
|
+
slug: z.ZodString;
|
|
33
|
+
source: z.ZodEnum<{
|
|
34
|
+
builtin: "builtin";
|
|
35
|
+
git: "git";
|
|
36
|
+
cli: "cli";
|
|
37
|
+
}>;
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export type RegisterVerticalInput = z.infer<typeof registerVerticalInput>;
|
|
41
|
+
/**
|
|
42
|
+
* Whether a version may be bound to a scope.
|
|
43
|
+
*
|
|
44
|
+
* `pending` is what a push produces. The admission gates — boundary-lint, the
|
|
45
|
+
* migration diff and the permission diff — decide the rest, and binding a scope is a
|
|
46
|
+
* separate, reviewable step. That separation is the whole point: it is what stops a
|
|
47
|
+
* push being a deploy, and it puts the two human checkpoints where the blast radius
|
|
48
|
+
* is (promotion) rather than where the typing is (merge).
|
|
49
|
+
*/
|
|
50
|
+
export declare const admissionStatus: z.ZodEnum<{
|
|
51
|
+
pending: "pending";
|
|
52
|
+
admitted: "admitted";
|
|
53
|
+
rejected: "rejected";
|
|
54
|
+
}>;
|
|
55
|
+
export type AdmissionStatus = z.infer<typeof admissionStatus>;
|
|
56
|
+
/**
|
|
57
|
+
* One published version of a vertical.
|
|
58
|
+
*
|
|
59
|
+
* The three digests are what make promotion answerable. "Has the permission surface
|
|
60
|
+
* changed between the version in prod and the one I am promoting?" is a string
|
|
61
|
+
* comparison here, where today it is a person remembering to look — and per §4 of the
|
|
62
|
+
* plan, a checkpoint that can be skipped is not a checkpoint.
|
|
63
|
+
*/
|
|
64
|
+
export declare const verticalVersion: z.ZodObject<{
|
|
65
|
+
id: z.ZodString;
|
|
66
|
+
verticalSlug: z.ZodString;
|
|
67
|
+
version: z.ZodString;
|
|
68
|
+
manifestDigest: z.ZodString;
|
|
69
|
+
permissionDigest: z.ZodString;
|
|
70
|
+
migrationDigest: z.ZodString;
|
|
71
|
+
deploymentRef: z.ZodNullable<z.ZodString>;
|
|
72
|
+
admission: z.ZodEnum<{
|
|
73
|
+
pending: "pending";
|
|
74
|
+
admitted: "admitted";
|
|
75
|
+
rejected: "rejected";
|
|
76
|
+
}>;
|
|
77
|
+
admissionNote: z.ZodNullable<z.ZodString>;
|
|
78
|
+
createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
export type VerticalVersion = z.infer<typeof verticalVersion>;
|
|
81
|
+
export declare const publishVersionInput: z.ZodObject<{
|
|
82
|
+
id: z.ZodString;
|
|
83
|
+
verticalSlug: z.ZodString;
|
|
84
|
+
version: z.ZodString;
|
|
85
|
+
manifestDigest: z.ZodString;
|
|
86
|
+
permissionDigest: z.ZodString;
|
|
87
|
+
migrationDigest: z.ZodString;
|
|
88
|
+
deploymentRef: z.ZodNullable<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
export type PublishVersionInput = z.infer<typeof publishVersionInput>;
|
|
91
|
+
/**
|
|
92
|
+
* Where a version is promoted to (#31 step 2).
|
|
93
|
+
*
|
|
94
|
+
* A channel is a named pointer per vertical. Promotion moves it. Dev, staging and
|
|
95
|
+
* prod are therefore the same vertical at different versions, which is the sentence
|
|
96
|
+
* the registry existed to make sayable.
|
|
97
|
+
*/
|
|
98
|
+
export declare const channelName: z.ZodEnum<{
|
|
99
|
+
dev: "dev";
|
|
100
|
+
staging: "staging";
|
|
101
|
+
prod: "prod";
|
|
102
|
+
}>;
|
|
103
|
+
export type ChannelName = z.infer<typeof channelName>;
|
|
104
|
+
export declare const verticalChannel: z.ZodObject<{
|
|
105
|
+
verticalSlug: z.ZodString;
|
|
106
|
+
channel: z.ZodEnum<{
|
|
107
|
+
dev: "dev";
|
|
108
|
+
staging: "staging";
|
|
109
|
+
prod: "prod";
|
|
110
|
+
}>;
|
|
111
|
+
versionId: z.ZodString;
|
|
112
|
+
updatedAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
export type VerticalChannel = z.infer<typeof verticalChannel>;
|
|
115
|
+
/**
|
|
116
|
+
* What a promoter must acknowledge, per §4's two human checkpoints.
|
|
117
|
+
*
|
|
118
|
+
* Today the migration and permission diffs are a MERGE-time convention: CI renders
|
|
119
|
+
* them and a human is expected to read them, but nothing connects that reading to
|
|
120
|
+
* the moment the change reaches anyone. Promotion is that moment — the blast radius
|
|
121
|
+
* is here, not at the merge.
|
|
122
|
+
*
|
|
123
|
+
* So promotion refuses when a digest differs and the corresponding flag is unset,
|
|
124
|
+
* naming both digests in the error. The flag is one deliberate act rather than a
|
|
125
|
+
* gate that can be passed by not noticing, and the acknowledgement lands in the
|
|
126
|
+
* admin log — which turns "someone reviewed it" from a claim into evidence.
|
|
127
|
+
*/
|
|
128
|
+
export declare const promotionAcknowledgement: z.ZodObject<{
|
|
129
|
+
permissionChange: z.ZodOptional<z.ZodBoolean>;
|
|
130
|
+
migrationChange: z.ZodOptional<z.ZodBoolean>;
|
|
131
|
+
}, z.core.$strip>;
|
|
132
|
+
export type PromotionAcknowledgement = z.infer<typeof promotionAcknowledgement>;
|
|
133
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;GAUG;AAEH,yFAAyF;AACzF,eAAO,MAAM,cAAc;;;;EAAoC,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,eAAO,MAAM,QAAQ;;;;;;;;;iBAKnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEhD,eAAO,MAAM,qBAAqB;;;;;;;;iBAA0D,CAAC;AAC7F,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;EAA8C,CAAC;AAC3E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;iBAa1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB;;;;;;;;iBAQ9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,eAAO,MAAM,WAAW;;;;EAAqC,CAAC;AAC9D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,eAAO,MAAM,eAAe;;;;;;;;;iBAK1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB;;;iBAGnC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { instant, slug } from './ids.js';
|
|
3
|
+
/**
|
|
4
|
+
* The vertical + version registry (#31 step 1; D-33's milestone one).
|
|
5
|
+
*
|
|
6
|
+
* Today a scope carries a nullable `vertical` STRING — a label nothing validates and
|
|
7
|
+
* nothing can be pinned to. That is enough to say "this scope runs Callout" and not
|
|
8
|
+
* enough to say *which Callout*, which is what dev/staging/prod and preview
|
|
9
|
+
* deployments are: the same vertical at different versions.
|
|
10
|
+
*
|
|
11
|
+
* The registry makes a version a real record with digests, so promotion can compare
|
|
12
|
+
* two of them, and an admission status, so **push is not live**.
|
|
13
|
+
*/
|
|
14
|
+
/** Where a vertical came from. `builtin` is one we ship; the others are a customer's. */
|
|
15
|
+
export const verticalSource = z.enum(['builtin', 'git', 'cli']);
|
|
16
|
+
export const vertical = z.object({
|
|
17
|
+
slug, // stable, human-readable, and what a scope row denormalizes for display
|
|
18
|
+
name: z.string().min(1),
|
|
19
|
+
source: verticalSource,
|
|
20
|
+
createdAt: instant,
|
|
21
|
+
});
|
|
22
|
+
export const registerVerticalInput = vertical.pick({ slug: true, name: true, source: true });
|
|
23
|
+
/**
|
|
24
|
+
* Whether a version may be bound to a scope.
|
|
25
|
+
*
|
|
26
|
+
* `pending` is what a push produces. The admission gates — boundary-lint, the
|
|
27
|
+
* migration diff and the permission diff — decide the rest, and binding a scope is a
|
|
28
|
+
* separate, reviewable step. That separation is the whole point: it is what stops a
|
|
29
|
+
* push being a deploy, and it puts the two human checkpoints where the blast radius
|
|
30
|
+
* is (promotion) rather than where the typing is (merge).
|
|
31
|
+
*/
|
|
32
|
+
export const admissionStatus = z.enum(['pending', 'admitted', 'rejected']);
|
|
33
|
+
/**
|
|
34
|
+
* One published version of a vertical.
|
|
35
|
+
*
|
|
36
|
+
* The three digests are what make promotion answerable. "Has the permission surface
|
|
37
|
+
* changed between the version in prod and the one I am promoting?" is a string
|
|
38
|
+
* comparison here, where today it is a person remembering to look — and per §4 of the
|
|
39
|
+
* plan, a checkpoint that can be skipped is not a checkpoint.
|
|
40
|
+
*/
|
|
41
|
+
export const verticalVersion = z.object({
|
|
42
|
+
id: z.string().min(1), // ULID
|
|
43
|
+
verticalSlug: slug,
|
|
44
|
+
version: z.string().min(1), // the builder's label — semver, a git sha, whatever they push
|
|
45
|
+
manifestDigest: z.string().min(1),
|
|
46
|
+
permissionDigest: z.string().min(1),
|
|
47
|
+
migrationDigest: z.string().min(1),
|
|
48
|
+
/** How to reach the deployment that serves it. Null until something is deployed. */
|
|
49
|
+
deploymentRef: z.string().min(1).nullable(),
|
|
50
|
+
admission: admissionStatus,
|
|
51
|
+
/** Why it was rejected, when it was. Null otherwise. */
|
|
52
|
+
admissionNote: z.string().nullable(),
|
|
53
|
+
createdAt: instant,
|
|
54
|
+
});
|
|
55
|
+
export const publishVersionInput = verticalVersion.pick({
|
|
56
|
+
id: true,
|
|
57
|
+
verticalSlug: true,
|
|
58
|
+
version: true,
|
|
59
|
+
manifestDigest: true,
|
|
60
|
+
permissionDigest: true,
|
|
61
|
+
migrationDigest: true,
|
|
62
|
+
deploymentRef: true,
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Where a version is promoted to (#31 step 2).
|
|
66
|
+
*
|
|
67
|
+
* A channel is a named pointer per vertical. Promotion moves it. Dev, staging and
|
|
68
|
+
* prod are therefore the same vertical at different versions, which is the sentence
|
|
69
|
+
* the registry existed to make sayable.
|
|
70
|
+
*/
|
|
71
|
+
export const channelName = z.enum(['dev', 'staging', 'prod']);
|
|
72
|
+
export const verticalChannel = z.object({
|
|
73
|
+
verticalSlug: slug,
|
|
74
|
+
channel: channelName,
|
|
75
|
+
versionId: z.string().min(1),
|
|
76
|
+
updatedAt: instant,
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* What a promoter must acknowledge, per §4's two human checkpoints.
|
|
80
|
+
*
|
|
81
|
+
* Today the migration and permission diffs are a MERGE-time convention: CI renders
|
|
82
|
+
* them and a human is expected to read them, but nothing connects that reading to
|
|
83
|
+
* the moment the change reaches anyone. Promotion is that moment — the blast radius
|
|
84
|
+
* is here, not at the merge.
|
|
85
|
+
*
|
|
86
|
+
* So promotion refuses when a digest differs and the corresponding flag is unset,
|
|
87
|
+
* naming both digests in the error. The flag is one deliberate act rather than a
|
|
88
|
+
* gate that can be passed by not noticing, and the acknowledgement lands in the
|
|
89
|
+
* admin log — which turns "someone reviewed it" from a claim into evidence.
|
|
90
|
+
*/
|
|
91
|
+
export const promotionAcknowledgement = z.object({
|
|
92
|
+
permissionChange: z.boolean().optional(),
|
|
93
|
+
migrationChange: z.boolean().optional(),
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;GAUG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAGhE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,wEAAwE;IAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,cAAc;IACtB,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAG7F;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;AAG3E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO;IAC9B,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,8DAA8D;IAC1F,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,oFAAoF;IACpF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC3C,SAAS,EAAE,eAAe;IAC1B,wDAAwD;IACxD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,IAAI,CAAC;IACtD,EAAE,EAAE,IAAI;IACR,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,IAAI;CACpB,CAAC,CAAC;AAGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAG9D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,YAAY,EAAE,IAAI;IAClB,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC;AAGH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The hostname map (K-26; control-plane.md §4.7).
|
|
4
|
+
*
|
|
5
|
+
* §4.2 provisions a scope; nothing gave it a URL. This is the directory data a
|
|
6
|
+
* single environment-wide router resolves against — `hostname → (tenant, scope,
|
|
7
|
+
* vertical, surface, region)` — before dispatching to the vertical's worker.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Which app answers on this hostname.
|
|
11
|
+
*
|
|
12
|
+
* §5.5 originally specified one hostname per scope, which is already wrong: the
|
|
13
|
+
* shop fronts a storefront AND a back office from ONE scope, and RallyPoint a
|
|
14
|
+
* player app and a manager console. Same data, different audience and chrome — the
|
|
15
|
+
* split is deliberate and never a second source of truth.
|
|
16
|
+
*
|
|
17
|
+
* Vertical vocabulary, deliberately: the kernel never branches on it, exactly as it
|
|
18
|
+
* never branches on `scope.kind`. It is carried so the router knows where to send
|
|
19
|
+
* the request, and the vertical decides what that name means.
|
|
20
|
+
*/
|
|
21
|
+
export declare const surfaceName: z.ZodString;
|
|
22
|
+
/**
|
|
23
|
+
* Where the hostname's traffic may be processed.
|
|
24
|
+
*
|
|
25
|
+
* The DO jurisdiction (K-7) pins storage and execution and is fixed at provisioning.
|
|
26
|
+
* This is the OTHER half: Regional Services pins TLS termination and processing.
|
|
27
|
+
*
|
|
28
|
+
* **This column records the region; it does not cause it** (K-30). TLS terminates
|
|
29
|
+
* before any of our code runs, so nothing read from here can move it — the region is
|
|
30
|
+
* enforced by a wildcard Regional Hostnames config per jurisdiction
|
|
31
|
+
* (`*.eu.substrat.run`), and default hostnames carry the jurisdiction in the name.
|
|
32
|
+
* What this column is for is letting the router detect a CONTRADICTION between the
|
|
33
|
+
* edge configuration and the directory, and refuse the request.
|
|
34
|
+
*
|
|
35
|
+
* Which is also why it should be derived from the scope's jurisdiction rather than
|
|
36
|
+
* accepted as an independent input: two values that must agree, supplied separately,
|
|
37
|
+
* eventually disagree — and this is the one an EU claim rests on. `bindHostname` does
|
|
38
|
+
* not enforce that yet.
|
|
39
|
+
*
|
|
40
|
+
* Null means unconstrained. Widening beyond `eu` is additive; Cloudflare also offers
|
|
41
|
+
* `us` and `fedramp`, and `us` is needed as soon as a second jurisdiction ships.
|
|
42
|
+
*/
|
|
43
|
+
export declare const hostnameRegion: z.ZodNullable<z.ZodEnum<{
|
|
44
|
+
eu: "eu";
|
|
45
|
+
}>>;
|
|
46
|
+
export type HostnameRegion = z.infer<typeof hostnameRegion>;
|
|
47
|
+
/**
|
|
48
|
+
* Where a hostname is in its provisioning lifecycle (§4.2).
|
|
49
|
+
*
|
|
50
|
+
* Custom domains ride Cloudflare for SaaS, so a hostname is not a string somebody
|
|
51
|
+
* sets — it is DNS validation and certificate issuance, which take time and can
|
|
52
|
+
* fail. Treating it as a column would make "the domain does not work yet" and "the
|
|
53
|
+
* domain is broken" the same state.
|
|
54
|
+
*
|
|
55
|
+
* `pending` — recorded, nothing asked of Cloudflare yet
|
|
56
|
+
* `verifying` — DNS validation and cert issuance in flight
|
|
57
|
+
* `active` — serving
|
|
58
|
+
* `failed` — validation or issuance failed; `note` says why
|
|
59
|
+
*/
|
|
60
|
+
export declare const hostnameStatus: z.ZodEnum<{
|
|
61
|
+
pending: "pending";
|
|
62
|
+
verifying: "verifying";
|
|
63
|
+
active: "active";
|
|
64
|
+
failed: "failed";
|
|
65
|
+
}>;
|
|
66
|
+
export type HostnameStatus = z.infer<typeof hostnameStatus>;
|
|
67
|
+
/**
|
|
68
|
+
* A hostname, normalized to lower case.
|
|
69
|
+
*
|
|
70
|
+
* DNS is case-insensitive, so `ACME.example.com` and `acme.example.com` are the same
|
|
71
|
+
* name — and if the map stored them as two rows, the global-uniqueness check would
|
|
72
|
+
* let two different scopes each hold "the same" hostname, and a request would resolve
|
|
73
|
+
* to whichever casing it happened to arrive in. Normalizing in the schema means both
|
|
74
|
+
* adapters inherit it rather than each remembering to.
|
|
75
|
+
*
|
|
76
|
+
* 253 is the maximum length of a fully-qualified domain name.
|
|
77
|
+
*/
|
|
78
|
+
export declare const hostname: z.ZodString;
|
|
79
|
+
export declare const hostnameBinding: z.ZodObject<{
|
|
80
|
+
hostname: z.ZodString;
|
|
81
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
82
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
83
|
+
verticalSlug: z.ZodNullable<z.ZodString>;
|
|
84
|
+
surface: z.ZodString;
|
|
85
|
+
region: z.ZodNullable<z.ZodEnum<{
|
|
86
|
+
eu: "eu";
|
|
87
|
+
}>>;
|
|
88
|
+
status: z.ZodEnum<{
|
|
89
|
+
pending: "pending";
|
|
90
|
+
verifying: "verifying";
|
|
91
|
+
active: "active";
|
|
92
|
+
failed: "failed";
|
|
93
|
+
}>;
|
|
94
|
+
statusNote: z.ZodNullable<z.ZodString>;
|
|
95
|
+
canonical: z.ZodBoolean;
|
|
96
|
+
createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
97
|
+
}, z.core.$strip>;
|
|
98
|
+
export type HostnameBinding = z.infer<typeof hostnameBinding>;
|
|
99
|
+
export declare const bindHostnameInput: z.ZodObject<{
|
|
100
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
101
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
102
|
+
hostname: z.ZodString;
|
|
103
|
+
surface: z.ZodString;
|
|
104
|
+
region: z.ZodNullable<z.ZodEnum<{
|
|
105
|
+
eu: "eu";
|
|
106
|
+
}>>;
|
|
107
|
+
canonical: z.ZodBoolean;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
export type BindHostnameInput = z.infer<typeof bindHostnameInput>;
|
|
110
|
+
/**
|
|
111
|
+
* What the router needs to dispatch. Deliberately smaller than the full binding: a
|
|
112
|
+
* per-request hot path should read what it uses and nothing else.
|
|
113
|
+
*/
|
|
114
|
+
export declare const routeTarget: z.ZodObject<{
|
|
115
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
116
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
117
|
+
verticalSlug: z.ZodNullable<z.ZodString>;
|
|
118
|
+
surface: z.ZodString;
|
|
119
|
+
region: z.ZodNullable<z.ZodEnum<{
|
|
120
|
+
eu: "eu";
|
|
121
|
+
}>>;
|
|
122
|
+
}, z.core.$strip>;
|
|
123
|
+
export type RouteTarget = z.infer<typeof routeTarget>;
|
|
124
|
+
//# sourceMappingURL=routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,aAA4B,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc;;GAA4B,CAAC;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc;;;;;EAAuD,CAAC;AACnF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,aAA2C,CAAC;AAEjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;iBAiB1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,iBAAiB;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;;;iBAMtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
|
package/dist/routing.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { instant, scopeId, slug, tenantId } from './ids.js';
|
|
3
|
+
/**
|
|
4
|
+
* The hostname map (K-26; control-plane.md §4.7).
|
|
5
|
+
*
|
|
6
|
+
* §4.2 provisions a scope; nothing gave it a URL. This is the directory data a
|
|
7
|
+
* single environment-wide router resolves against — `hostname → (tenant, scope,
|
|
8
|
+
* vertical, surface, region)` — before dispatching to the vertical's worker.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Which app answers on this hostname.
|
|
12
|
+
*
|
|
13
|
+
* §5.5 originally specified one hostname per scope, which is already wrong: the
|
|
14
|
+
* shop fronts a storefront AND a back office from ONE scope, and RallyPoint a
|
|
15
|
+
* player app and a manager console. Same data, different audience and chrome — the
|
|
16
|
+
* split is deliberate and never a second source of truth.
|
|
17
|
+
*
|
|
18
|
+
* Vertical vocabulary, deliberately: the kernel never branches on it, exactly as it
|
|
19
|
+
* never branches on `scope.kind`. It is carried so the router knows where to send
|
|
20
|
+
* the request, and the vertical decides what that name means.
|
|
21
|
+
*/
|
|
22
|
+
export const surfaceName = z.string().min(1).max(32);
|
|
23
|
+
/**
|
|
24
|
+
* Where the hostname's traffic may be processed.
|
|
25
|
+
*
|
|
26
|
+
* The DO jurisdiction (K-7) pins storage and execution and is fixed at provisioning.
|
|
27
|
+
* This is the OTHER half: Regional Services pins TLS termination and processing.
|
|
28
|
+
*
|
|
29
|
+
* **This column records the region; it does not cause it** (K-30). TLS terminates
|
|
30
|
+
* before any of our code runs, so nothing read from here can move it — the region is
|
|
31
|
+
* enforced by a wildcard Regional Hostnames config per jurisdiction
|
|
32
|
+
* (`*.eu.substrat.run`), and default hostnames carry the jurisdiction in the name.
|
|
33
|
+
* What this column is for is letting the router detect a CONTRADICTION between the
|
|
34
|
+
* edge configuration and the directory, and refuse the request.
|
|
35
|
+
*
|
|
36
|
+
* Which is also why it should be derived from the scope's jurisdiction rather than
|
|
37
|
+
* accepted as an independent input: two values that must agree, supplied separately,
|
|
38
|
+
* eventually disagree — and this is the one an EU claim rests on. `bindHostname` does
|
|
39
|
+
* not enforce that yet.
|
|
40
|
+
*
|
|
41
|
+
* Null means unconstrained. Widening beyond `eu` is additive; Cloudflare also offers
|
|
42
|
+
* `us` and `fedramp`, and `us` is needed as soon as a second jurisdiction ships.
|
|
43
|
+
*/
|
|
44
|
+
export const hostnameRegion = z.enum(['eu']).nullable();
|
|
45
|
+
/**
|
|
46
|
+
* Where a hostname is in its provisioning lifecycle (§4.2).
|
|
47
|
+
*
|
|
48
|
+
* Custom domains ride Cloudflare for SaaS, so a hostname is not a string somebody
|
|
49
|
+
* sets — it is DNS validation and certificate issuance, which take time and can
|
|
50
|
+
* fail. Treating it as a column would make "the domain does not work yet" and "the
|
|
51
|
+
* domain is broken" the same state.
|
|
52
|
+
*
|
|
53
|
+
* `pending` — recorded, nothing asked of Cloudflare yet
|
|
54
|
+
* `verifying` — DNS validation and cert issuance in flight
|
|
55
|
+
* `active` — serving
|
|
56
|
+
* `failed` — validation or issuance failed; `note` says why
|
|
57
|
+
*/
|
|
58
|
+
export const hostnameStatus = z.enum(['pending', 'verifying', 'active', 'failed']);
|
|
59
|
+
/**
|
|
60
|
+
* A hostname, normalized to lower case.
|
|
61
|
+
*
|
|
62
|
+
* DNS is case-insensitive, so `ACME.example.com` and `acme.example.com` are the same
|
|
63
|
+
* name — and if the map stored them as two rows, the global-uniqueness check would
|
|
64
|
+
* let two different scopes each hold "the same" hostname, and a request would resolve
|
|
65
|
+
* to whichever casing it happened to arrive in. Normalizing in the schema means both
|
|
66
|
+
* adapters inherit it rather than each remembering to.
|
|
67
|
+
*
|
|
68
|
+
* 253 is the maximum length of a fully-qualified domain name.
|
|
69
|
+
*/
|
|
70
|
+
export const hostname = z.string().min(1).max(253).toLowerCase();
|
|
71
|
+
export const hostnameBinding = z.object({
|
|
72
|
+
hostname,
|
|
73
|
+
tenantId,
|
|
74
|
+
scopeId,
|
|
75
|
+
/** Denormalized from the scope, so the router resolves in one read. */
|
|
76
|
+
verticalSlug: slug.nullable(),
|
|
77
|
+
surface: surfaceName,
|
|
78
|
+
region: hostnameRegion,
|
|
79
|
+
status: hostnameStatus,
|
|
80
|
+
/** Why it failed, when it did. Null otherwise. */
|
|
81
|
+
statusNote: z.string().nullable(),
|
|
82
|
+
/**
|
|
83
|
+
* The one hostname a surface redirects to and issues certs for. Exactly one per
|
|
84
|
+
* (scope, surface) may hold it — the rest are aliases.
|
|
85
|
+
*/
|
|
86
|
+
canonical: z.boolean(),
|
|
87
|
+
createdAt: instant,
|
|
88
|
+
});
|
|
89
|
+
export const bindHostnameInput = hostnameBinding.pick({
|
|
90
|
+
hostname: true,
|
|
91
|
+
tenantId: true,
|
|
92
|
+
scopeId: true,
|
|
93
|
+
surface: true,
|
|
94
|
+
region: true,
|
|
95
|
+
canonical: true,
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* What the router needs to dispatch. Deliberately smaller than the full binding: a
|
|
99
|
+
* per-request hot path should read what it uses and nothing else.
|
|
100
|
+
*/
|
|
101
|
+
export const routeTarget = z.object({
|
|
102
|
+
tenantId,
|
|
103
|
+
scopeId,
|
|
104
|
+
verticalSlug: slug.nullable(),
|
|
105
|
+
surface: surfaceName,
|
|
106
|
+
region: hostnameRegion,
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE5D;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAGxD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGnF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,uEAAuE;IACvE,YAAY,EAAE,IAAI,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,cAAc;IACtB,kDAAkD;IAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;IACtB,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC,IAAI,CAAC;IACpD,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;CAChB,CAAC,CAAC;AAGH;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,QAAQ;IACR,OAAO;IACP,YAAY,EAAE,IAAI,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,cAAc;CACvB,CAAC,CAAC"}
|
package/dist/tenancy.d.ts
CHANGED
|
@@ -23,6 +23,35 @@ export declare const createTenantInput: z.ZodObject<{
|
|
|
23
23
|
name: z.ZodString;
|
|
24
24
|
}, z.core.$strip>;
|
|
25
25
|
export type CreateTenantInput = z.infer<typeof createTenantInput>;
|
|
26
|
+
/**
|
|
27
|
+
* An organization inside a tenant (K-22) — who membership tuples point at and what
|
|
28
|
+
* `grantToOrg` targets. Portal customers, staff groups, partner companies.
|
|
29
|
+
*
|
|
30
|
+
* `slug` and `name` are **attributes, not identity**: the id is a ULID, so renaming an
|
|
31
|
+
* org cannot silently orphan the tuples and grants that reference it. `tenantId` on the
|
|
32
|
+
* row is also kernel-design §4.3's required `orgId ↔ tenantId` join — *"an explicit,
|
|
33
|
+
* stable directory row, one per tenant, never reconstructed from names or slugs"* —
|
|
34
|
+
* which is why the identity adapter's org sync hangs off this record rather than a
|
|
35
|
+
* string convention.
|
|
36
|
+
*
|
|
37
|
+
* No lifecycle status yet, deliberately: nothing consumes one, and adding a nullable
|
|
38
|
+
* column later is additive. The branded id is the part that is brutal to retrofit.
|
|
39
|
+
*/
|
|
40
|
+
export declare const org: z.ZodObject<{
|
|
41
|
+
id: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
|
|
42
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
43
|
+
slug: z.ZodString;
|
|
44
|
+
name: z.ZodString;
|
|
45
|
+
createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export type Org = z.infer<typeof org>;
|
|
48
|
+
export declare const createOrgInput: z.ZodObject<{
|
|
49
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
50
|
+
id: z.core.$ZodBranded<z.ZodString, "OrgId", "out">;
|
|
51
|
+
slug: z.ZodString;
|
|
52
|
+
name: z.ZodString;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export type CreateOrgInput = z.infer<typeof createOrgInput>;
|
|
26
55
|
export declare const scopeStatus: z.ZodEnum<{
|
|
27
56
|
active: "active";
|
|
28
57
|
suspended: "suspended";
|
|
@@ -40,6 +69,32 @@ export declare const jurisdiction: z.ZodNullable<z.ZodEnum<{
|
|
|
40
69
|
eu: "eu";
|
|
41
70
|
}>>;
|
|
42
71
|
export type Jurisdiction = z.infer<typeof jurisdiction>;
|
|
72
|
+
/**
|
|
73
|
+
* A scope's last *failed* migration attempt (kernel-design §5.3), or null when the
|
|
74
|
+
* last attempt succeeded and when none has run.
|
|
75
|
+
*
|
|
76
|
+
* Migrations fail closed per scope: `applyPendingMigrations` rolls back and throws,
|
|
77
|
+
* so the scope serves nothing. Before this record existed the directory learned
|
|
78
|
+
* nothing from that — `schemaVersion` is projected only on the success path, so a
|
|
79
|
+
* half-migrated scope kept a stale value and rendered as healthy.
|
|
80
|
+
*
|
|
81
|
+
* Deliberately **not** a `scopeStatus` member: the scope already fails closed at the
|
|
82
|
+
* migration layer, so nothing about lifecycle gating changes, and the §3.3 machine
|
|
83
|
+
* (`provisioning → active → suspended ⇄ active → archiving → archived`) has no
|
|
84
|
+
* sensible transition for it. Structured rather than a flag because the
|
|
85
|
+
* reconciliation sweep (§5.3) retries with backoff and reports
|
|
86
|
+
* "487/500 migrated, 13 pending, 0 failed" — which needs the attempt count and the
|
|
87
|
+
* failing version, not a boolean.
|
|
88
|
+
*
|
|
89
|
+
* `attempts` counts *consecutive* failures and resets to 0 on a successful apply.
|
|
90
|
+
*/
|
|
91
|
+
export declare const migrationFailure: z.ZodNullable<z.ZodObject<{
|
|
92
|
+
version: z.ZodString;
|
|
93
|
+
error: z.ZodString;
|
|
94
|
+
attempts: z.ZodNumber;
|
|
95
|
+
lastAttemptAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
96
|
+
}, z.core.$strip>>;
|
|
97
|
+
export type MigrationFailure = z.infer<typeof migrationFailure>;
|
|
43
98
|
export declare const scope: z.ZodObject<{
|
|
44
99
|
id: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
45
100
|
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
@@ -62,7 +117,14 @@ export declare const scope: z.ZodObject<{
|
|
|
62
117
|
eu: "eu";
|
|
63
118
|
}>>;
|
|
64
119
|
vertical: z.ZodNullable<z.ZodString>;
|
|
120
|
+
verticalVersionId: z.ZodNullable<z.ZodString>;
|
|
65
121
|
schemaVersion: z.ZodString;
|
|
122
|
+
migrationFailure: z.ZodNullable<z.ZodObject<{
|
|
123
|
+
version: z.ZodString;
|
|
124
|
+
error: z.ZodString;
|
|
125
|
+
attempts: z.ZodNumber;
|
|
126
|
+
lastAttemptAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
127
|
+
}, z.core.$strip>>;
|
|
66
128
|
createdAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
67
129
|
}, z.core.$strip>;
|
|
68
130
|
export type Scope = z.infer<typeof scope>;
|
package/dist/tenancy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenancy.d.ts","sourceRoot":"","sources":["../src/tenancy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,YAAY;;;;EAA8C,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,MAAM;;;;;;;;;;iBAMjB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAI5C,eAAO,MAAM,iBAAiB;;;;iBAAoD,CAAC;AACnF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,WAAW;;;;;;EAMtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAGtD,eAAO,MAAM,YAAY;;;EAAqB,CAAC;AAC/C,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAGxD,eAAO,MAAM,YAAY;;GAA4B,CAAC;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"tenancy.d.ts","sourceRoot":"","sources":["../src/tenancy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,YAAY;;;;EAA8C,CAAC;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,MAAM;;;;;;;;;;iBAMjB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAI5C,eAAO,MAAM,iBAAiB;;;;iBAAoD,CAAC;AACnF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,GAAG;;;;;;iBAMd,CAAC;AACH,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;AAGtC,eAAO,MAAM,cAAc;;;;;iBAAiE,CAAC;AAC7F,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE5D,eAAO,MAAM,WAAW;;;;;;EAMtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAGtD,eAAO,MAAM,YAAY;;;EAAqB,CAAC;AAC/C,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAGxD,eAAO,MAAM,YAAY;;GAA4B,CAAC;AACtD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB;;;;;kBAOhB,CAAC;AACd,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgChB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC"}
|
package/dist/tenancy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { instant, scopeId, slug, tenantId } from './ids.js';
|
|
2
|
+
import { instant, orgId, scopeId, slug, tenantId } from './ids.js';
|
|
3
3
|
export const tenantStatus = z.enum(['active', 'suspended', 'deleting']);
|
|
4
4
|
export const tenant = z.object({
|
|
5
5
|
id: tenantId,
|
|
@@ -11,6 +11,29 @@ export const tenant = z.object({
|
|
|
11
11
|
// What the caller supplies to createTenant (control-plane.md §4.1); `status`
|
|
12
12
|
// (active) and `createdAt` are stamped host-side, never caller-supplied.
|
|
13
13
|
export const createTenantInput = tenant.pick({ id: true, slug: true, name: true });
|
|
14
|
+
/**
|
|
15
|
+
* An organization inside a tenant (K-22) — who membership tuples point at and what
|
|
16
|
+
* `grantToOrg` targets. Portal customers, staff groups, partner companies.
|
|
17
|
+
*
|
|
18
|
+
* `slug` and `name` are **attributes, not identity**: the id is a ULID, so renaming an
|
|
19
|
+
* org cannot silently orphan the tuples and grants that reference it. `tenantId` on the
|
|
20
|
+
* row is also kernel-design §4.3's required `orgId ↔ tenantId` join — *"an explicit,
|
|
21
|
+
* stable directory row, one per tenant, never reconstructed from names or slugs"* —
|
|
22
|
+
* which is why the identity adapter's org sync hangs off this record rather than a
|
|
23
|
+
* string convention.
|
|
24
|
+
*
|
|
25
|
+
* No lifecycle status yet, deliberately: nothing consumes one, and adding a nullable
|
|
26
|
+
* column later is additive. The branded id is the part that is brutal to retrofit.
|
|
27
|
+
*/
|
|
28
|
+
export const org = z.object({
|
|
29
|
+
id: orgId,
|
|
30
|
+
tenantId,
|
|
31
|
+
slug, // unique within the tenant
|
|
32
|
+
name: z.string().min(1),
|
|
33
|
+
createdAt: instant,
|
|
34
|
+
});
|
|
35
|
+
// `status`/`createdAt` are stamped host-side, never caller-supplied (as createTenantInput).
|
|
36
|
+
export const createOrgInput = org.pick({ id: true, tenantId: true, slug: true, name: true });
|
|
14
37
|
export const scopeStatus = z.enum([
|
|
15
38
|
'provisioning',
|
|
16
39
|
'active',
|
|
@@ -22,6 +45,33 @@ export const scopeStatus = z.enum([
|
|
|
22
45
|
export const storageShape = z.enum(['A', 'B']);
|
|
23
46
|
// Fixed at provisioning; a DO can never relocate (design K-7)
|
|
24
47
|
export const jurisdiction = z.enum(['eu']).nullable();
|
|
48
|
+
/**
|
|
49
|
+
* A scope's last *failed* migration attempt (kernel-design §5.3), or null when the
|
|
50
|
+
* last attempt succeeded and when none has run.
|
|
51
|
+
*
|
|
52
|
+
* Migrations fail closed per scope: `applyPendingMigrations` rolls back and throws,
|
|
53
|
+
* so the scope serves nothing. Before this record existed the directory learned
|
|
54
|
+
* nothing from that — `schemaVersion` is projected only on the success path, so a
|
|
55
|
+
* half-migrated scope kept a stale value and rendered as healthy.
|
|
56
|
+
*
|
|
57
|
+
* Deliberately **not** a `scopeStatus` member: the scope already fails closed at the
|
|
58
|
+
* migration layer, so nothing about lifecycle gating changes, and the §3.3 machine
|
|
59
|
+
* (`provisioning → active → suspended ⇄ active → archiving → archived`) has no
|
|
60
|
+
* sensible transition for it. Structured rather than a flag because the
|
|
61
|
+
* reconciliation sweep (§5.3) retries with backoff and reports
|
|
62
|
+
* "487/500 migrated, 13 pending, 0 failed" — which needs the attempt count and the
|
|
63
|
+
* failing version, not a boolean.
|
|
64
|
+
*
|
|
65
|
+
* `attempts` counts *consecutive* failures and resets to 0 on a successful apply.
|
|
66
|
+
*/
|
|
67
|
+
export const migrationFailure = z
|
|
68
|
+
.object({
|
|
69
|
+
version: z.string().min(1), // the `module@version` that threw
|
|
70
|
+
error: z.string(),
|
|
71
|
+
attempts: z.number().int().positive(), // ≥1: the record only exists after a failure
|
|
72
|
+
lastAttemptAt: instant,
|
|
73
|
+
})
|
|
74
|
+
.nullable();
|
|
25
75
|
export const scope = z.object({
|
|
26
76
|
id: scopeId, // globally unique; APIs still take (tenantId, scopeId) and cross-check (K-3)
|
|
27
77
|
tenantId,
|
|
@@ -38,11 +88,21 @@ export const scope = z.object({
|
|
|
38
88
|
// audit log's `vertical` target real for scope-lifecycle actions, and what
|
|
39
89
|
// console item 1 means by "which vertical each scope runs".
|
|
40
90
|
vertical: z.string().min(1).nullable(),
|
|
91
|
+
/**
|
|
92
|
+
* The registered version this scope runs (#31). Null for a scope provisioned
|
|
93
|
+
* before the registry, or bound to a vertical we ship but have not versioned.
|
|
94
|
+
*
|
|
95
|
+
* Kept ALONGSIDE `vertical` rather than replacing it: the slug is what the audit
|
|
96
|
+
* log's target and the console's filters read, and a denormalized label that
|
|
97
|
+
* survives a version being superseded is worth more than one join.
|
|
98
|
+
*/
|
|
99
|
+
verticalVersionId: z.string().min(1).nullable(),
|
|
41
100
|
// The scope's migration state: the count of applied (module, version) pairs,
|
|
42
101
|
// as a string. Written host-side after migrations apply — never caller-supplied.
|
|
43
102
|
// '0' means "provisioned, nothing applied yet". Comparing it against the host's
|
|
44
103
|
// registered migration total is what answers §5.4's "which scopes are behind".
|
|
45
104
|
schemaVersion: z.string(),
|
|
105
|
+
migrationFailure,
|
|
46
106
|
createdAt: instant,
|
|
47
107
|
});
|
|
48
108
|
//# sourceMappingURL=tenancy.js.map
|
package/dist/tenancy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenancy.js","sourceRoot":"","sources":["../src/tenancy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tenancy.js","sourceRoot":"","sources":["../src/tenancy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED