@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.
@@ -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;AAUxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;EAgBtB,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,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,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"}
@@ -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
- tenantId,
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,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpF,gFAAgF;AAChF,+EAA+E;AAC/E,iFAAiF;AACjF,4CAA4C;AAE5C,2EAA2E;AAC3E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC;IAChC,YAAY;IACZ,YAAY;IACZ,OAAO;IACP,YAAY;IACZ,WAAW;IACX,cAAc,EAAE,OAAO;IACvB,iBAAiB,EAAE,oDAAoD;IACvE,gBAAgB,EAAE,yDAAyD;IAC3E,cAAc,EAAE,OAAO;IACvB,gBAAgB,EAAE,OAAO;IACzB,cAAc,EAAE,OAAO;IACvB,gBAAgB,EAAE,uDAAuD;IACzE,kBAAkB,EAAE,6CAA6C;IACjE,mBAAmB,EAAE,OAAO;IAC5B,cAAc,EAAE,kDAAkD;CACnE,CAAC,CAAC;AAGH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,sCAAsC;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,sDAAsD;IACrF,SAAS,EAAE,WAAW;IACtB,QAAQ;IACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,8BAA8B;CAC5D,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,WAAW;IACtB,QAAQ;IACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAGH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,oDAAoD;IAC3E,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,WAAW;IACnB,QAAQ;IACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE;IAC3B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,6DAA6D;IAC7F,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,sBAAsB;IACrD,EAAE,EAAE,OAAO;CACZ,CAAC,CAAC"}
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;AAKtD,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"}
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
@@ -18,6 +18,8 @@
18
18
  */
19
19
  export { z } from 'zod';
20
20
  export * from './ids.js';
21
+ export * from './registry.js';
22
+ export * from './routing.js';
21
23
  export * from './tenancy.js';
22
24
  export * from './control-plane.js';
23
25
  export * from './permission.js';
@@ -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
@@ -18,6 +18,8 @@
18
18
  */
19
19
  export { z } from 'zod';
20
20
  export * from './ids.js';
21
+ export * from './registry.js';
22
+ export * from './routing.js';
21
23
  export * from './tenancy.js';
22
24
  export * from './control-plane.js';
23
25
  export * from './permission.js';
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
- // egenkontroll") stays vertical-composed glue inside the operation — see
59
- // demos/fsm. Guards live here so that adding or DROPPING a compliance gate
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,
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -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;AAW9D,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"}
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"}
@@ -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]+$/)
@@ -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"}
@@ -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"}
@@ -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>;
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;iBAsBhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC"}
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
@@ -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;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAGxE,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,EAAE,EAAE,QAAQ;IACZ,IAAI;IACJ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC;AAGH,6EAA6E;AAC7E,yEAAyE;AACzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAGnF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC;IAChC,cAAc;IACd,QAAQ;IACR,WAAW;IACX,WAAW;IACX,UAAU;CACX,CAAC,CAAC;AAGH,uFAAuF;AACvF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAG/C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAGtD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,EAAE,EAAE,OAAO,EAAE,6EAA6E;IAC1F,QAAQ;IACR,aAAa,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,4DAA4D;IAC/F,IAAI,EAAE,uBAAuB;IAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,qEAAqE;IAC9F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,WAAW;IACnB,YAAY;IACZ,YAAY;IACZ,+EAA+E;IAC/E,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtC,6EAA6E;IAC7E,iFAAiF;IACjF,gFAAgF;IAChF,+EAA+E;IAC/E,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB,SAAS,EAAE,OAAO;CACnB,CAAC,CAAC"}
1
+ {"version":3,"file":"tenancy.js","sourceRoot":"","sources":["../src/tenancy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/contracts",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Substrat kernel contract schemas — Zod is the source of truth (master plan D-22); OAS/JSON Schema are emitted artifacts",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {