@xemahq/kernel-contracts 0.2.0 → 0.2.2

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.
Files changed (147) hide show
  1. package/dist/agent-workspace/awp-spec.json +1 -1
  2. package/dist/biome/index.d.ts +5 -0
  3. package/dist/biome/index.d.ts.map +1 -1
  4. package/dist/biome/index.js +5 -0
  5. package/dist/biome/index.js.map +1 -1
  6. package/dist/biome/lib/biome-audience.d.ts +8 -0
  7. package/dist/biome/lib/biome-audience.d.ts.map +1 -0
  8. package/dist/biome/lib/biome-audience.js +12 -0
  9. package/dist/biome/lib/biome-audience.js.map +1 -0
  10. package/dist/biome/lib/biome-availability-grant.d.ts +10 -0
  11. package/dist/biome/lib/biome-availability-grant.d.ts.map +1 -0
  12. package/dist/biome/lib/biome-availability-grant.js +12 -0
  13. package/dist/biome/lib/biome-availability-grant.js.map +1 -0
  14. package/dist/biome/lib/biome-origin.d.ts +8 -0
  15. package/dist/biome/lib/biome-origin.d.ts.map +1 -0
  16. package/dist/biome/lib/biome-origin.js +12 -0
  17. package/dist/biome/lib/biome-origin.js.map +1 -0
  18. package/dist/biome/lib/biome-target.d.ts +7 -0
  19. package/dist/biome/lib/biome-target.d.ts.map +1 -0
  20. package/dist/biome/lib/biome-target.js +11 -0
  21. package/dist/biome/lib/biome-target.js.map +1 -0
  22. package/dist/biome/lib/biome-tier.d.ts +10 -0
  23. package/dist/biome/lib/biome-tier.d.ts.map +1 -0
  24. package/dist/biome/lib/biome-tier.js +19 -0
  25. package/dist/biome/lib/biome-tier.js.map +1 -0
  26. package/dist/contribution/lib/contribution-kind.d.ts +2 -1
  27. package/dist/contribution/lib/contribution-kind.d.ts.map +1 -1
  28. package/dist/contribution/lib/contribution-kind.js +1 -0
  29. package/dist/contribution/lib/contribution-kind.js.map +1 -1
  30. package/dist/distribution/index.d.ts +5 -0
  31. package/dist/distribution/index.d.ts.map +1 -0
  32. package/dist/distribution/index.js +21 -0
  33. package/dist/distribution/index.js.map +1 -0
  34. package/dist/distribution/lib/distribution-lock.d.ts +24 -0
  35. package/dist/distribution/lib/distribution-lock.d.ts.map +1 -0
  36. package/dist/distribution/lib/distribution-lock.js +34 -0
  37. package/dist/distribution/lib/distribution-lock.js.map +1 -0
  38. package/dist/distribution/lib/distribution-selector.d.ts +12 -0
  39. package/dist/distribution/lib/distribution-selector.d.ts.map +1 -0
  40. package/dist/distribution/lib/distribution-selector.js +13 -0
  41. package/dist/distribution/lib/distribution-selector.js.map +1 -0
  42. package/dist/distribution/lib/distribution.d.ts +21 -0
  43. package/dist/distribution/lib/distribution.d.ts.map +1 -0
  44. package/dist/distribution/lib/distribution.js +30 -0
  45. package/dist/distribution/lib/distribution.js.map +1 -0
  46. package/dist/distribution/lib/image-lock.d.ts +20 -0
  47. package/dist/distribution/lib/image-lock.d.ts.map +1 -0
  48. package/dist/distribution/lib/image-lock.js +30 -0
  49. package/dist/distribution/lib/image-lock.js.map +1 -0
  50. package/dist/inquiry/lib/enums.d.ts +4 -0
  51. package/dist/inquiry/lib/enums.d.ts.map +1 -1
  52. package/dist/inquiry/lib/enums.js +6 -1
  53. package/dist/inquiry/lib/enums.js.map +1 -1
  54. package/dist/inquiry/lib/inquiry.d.ts +5 -9
  55. package/dist/inquiry/lib/inquiry.d.ts.map +1 -1
  56. package/dist/inquiry/lib/inquiry.js +4 -2
  57. package/dist/inquiry/lib/inquiry.js.map +1 -1
  58. package/dist/invocation/index.d.ts +10 -0
  59. package/dist/invocation/index.d.ts.map +1 -0
  60. package/dist/invocation/index.js +26 -0
  61. package/dist/invocation/index.js.map +1 -0
  62. package/dist/invocation/lib/execution-requirements.d.ts +24 -0
  63. package/dist/invocation/lib/execution-requirements.d.ts.map +1 -0
  64. package/dist/invocation/lib/execution-requirements.js +25 -0
  65. package/dist/invocation/lib/execution-requirements.js.map +1 -0
  66. package/dist/invocation/lib/invocation-decision.d.ts +8 -0
  67. package/dist/invocation/lib/invocation-decision.d.ts.map +1 -0
  68. package/dist/invocation/lib/invocation-decision.js +10 -0
  69. package/dist/invocation/lib/invocation-decision.js.map +1 -0
  70. package/dist/invocation/lib/invocation-mode.d.ts +8 -0
  71. package/dist/invocation/lib/invocation-mode.d.ts.map +1 -0
  72. package/dist/invocation/lib/invocation-mode.js +12 -0
  73. package/dist/invocation/lib/invocation-mode.js.map +1 -0
  74. package/dist/invocation/lib/invocation-priority.d.ts +8 -0
  75. package/dist/invocation/lib/invocation-priority.d.ts.map +1 -0
  76. package/dist/invocation/lib/invocation-priority.js +12 -0
  77. package/dist/invocation/lib/invocation-priority.js.map +1 -0
  78. package/dist/invocation/lib/invocation-record.d.ts +27 -0
  79. package/dist/invocation/lib/invocation-record.d.ts.map +1 -0
  80. package/dist/invocation/lib/invocation-record.js +29 -0
  81. package/dist/invocation/lib/invocation-record.js.map +1 -0
  82. package/dist/invocation/lib/invocation-status.d.ts +13 -0
  83. package/dist/invocation/lib/invocation-status.d.ts.map +1 -0
  84. package/dist/invocation/lib/invocation-status.js +17 -0
  85. package/dist/invocation/lib/invocation-status.js.map +1 -0
  86. package/dist/invocation/lib/invoke-request.d.ts +13 -0
  87. package/dist/invocation/lib/invoke-request.d.ts.map +1 -0
  88. package/dist/invocation/lib/invoke-request.js +15 -0
  89. package/dist/invocation/lib/invoke-request.js.map +1 -0
  90. package/dist/invocation/lib/invoke-response.d.ts +17 -0
  91. package/dist/invocation/lib/invoke-response.d.ts.map +1 -0
  92. package/dist/invocation/lib/invoke-response.js +19 -0
  93. package/dist/invocation/lib/invoke-response.js.map +1 -0
  94. package/dist/invocation/lib/isolation-level.d.ts +7 -0
  95. package/dist/invocation/lib/isolation-level.d.ts.map +1 -0
  96. package/dist/invocation/lib/isolation-level.js +11 -0
  97. package/dist/invocation/lib/isolation-level.js.map +1 -0
  98. package/dist/mail-source/index.d.ts +2 -0
  99. package/dist/mail-source/index.d.ts.map +1 -0
  100. package/dist/mail-source/index.js +18 -0
  101. package/dist/mail-source/index.js.map +1 -0
  102. package/dist/mail-source/lib/mail-event.d.ts +58 -0
  103. package/dist/mail-source/lib/mail-event.d.ts.map +1 -0
  104. package/dist/mail-source/lib/mail-event.js +41 -0
  105. package/dist/mail-source/lib/mail-event.js.map +1 -0
  106. package/dist/policy/index.d.ts +1 -0
  107. package/dist/policy/index.d.ts.map +1 -1
  108. package/dist/policy/index.js +1 -0
  109. package/dist/policy/index.js.map +1 -1
  110. package/dist/policy/lib/egress-allowlist.d.ts +18 -0
  111. package/dist/policy/lib/egress-allowlist.d.ts.map +1 -0
  112. package/dist/policy/lib/egress-allowlist.js +130 -0
  113. package/dist/policy/lib/egress-allowlist.js.map +1 -0
  114. package/dist/policy/lib/obligations.d.ts +12 -1
  115. package/dist/policy/lib/obligations.d.ts.map +1 -1
  116. package/dist/policy/lib/obligations.js +14 -1
  117. package/dist/policy/lib/obligations.js.map +1 -1
  118. package/package.json +1 -1
  119. package/src/biome/index.ts +5 -0
  120. package/src/biome/lib/biome-audience.ts +27 -0
  121. package/src/biome/lib/biome-availability-grant.ts +42 -0
  122. package/src/biome/lib/biome-origin.ts +26 -0
  123. package/src/biome/lib/biome-target.ts +16 -0
  124. package/src/biome/lib/biome-tier.ts +44 -0
  125. package/src/contribution/lib/contribution-kind.ts +14 -0
  126. package/src/distribution/index.ts +4 -0
  127. package/src/distribution/lib/distribution-lock.ts +88 -0
  128. package/src/distribution/lib/distribution-selector.ts +35 -0
  129. package/src/distribution/lib/distribution.ts +82 -0
  130. package/src/distribution/lib/image-lock.ts +77 -0
  131. package/src/inquiry/lib/enums.ts +13 -0
  132. package/src/inquiry/lib/inquiry.ts +22 -4
  133. package/src/invocation/index.ts +9 -0
  134. package/src/invocation/lib/execution-requirements.ts +61 -0
  135. package/src/invocation/lib/invocation-decision.ts +21 -0
  136. package/src/invocation/lib/invocation-mode.ts +26 -0
  137. package/src/invocation/lib/invocation-priority.ts +16 -0
  138. package/src/invocation/lib/invocation-record.ts +59 -0
  139. package/src/invocation/lib/invocation-status.ts +32 -0
  140. package/src/invocation/lib/invoke-request.ts +34 -0
  141. package/src/invocation/lib/invoke-response.ts +39 -0
  142. package/src/invocation/lib/isolation-level.ts +20 -0
  143. package/src/mail-source/index.ts +1 -0
  144. package/src/mail-source/lib/mail-event.ts +106 -0
  145. package/src/policy/index.ts +1 -0
  146. package/src/policy/lib/egress-allowlist.ts +239 -0
  147. package/src/policy/lib/obligations.ts +61 -0
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAIL_EVENT_DATA_TYPE = exports.MAIL_EVENT_SOURCE = exports.MAIL_EVENT_SCHEMA_VERSION = exports.MailThreadUpdatedSchema = exports.MailMessageClassifiedSchema = exports.MailMessageReceivedSchema = exports.MailEventBaseSchema = exports.MailEventType = void 0;
4
+ const zod_1 = require("zod");
5
+ var MailEventType;
6
+ (function (MailEventType) {
7
+ MailEventType["MessageReceived"] = "mail.message.received";
8
+ MailEventType["MessageClassified"] = "mail.message.classified";
9
+ MailEventType["ThreadUpdated"] = "mail.thread.updated";
10
+ })(MailEventType || (exports.MailEventType = MailEventType = {}));
11
+ exports.MailEventBaseSchema = zod_1.z.object({
12
+ orgId: zod_1.z.string().min(1),
13
+ projectId: zod_1.z.string().min(1).optional(),
14
+ mailboxRef: zod_1.z.string().min(1),
15
+ messageId: zod_1.z.string().min(1),
16
+ threadRef: zod_1.z.string().min(1).optional(),
17
+ from: zod_1.z.string().min(1),
18
+ subject: zod_1.z.string().optional(),
19
+ receivedAt: zod_1.z.string().min(1),
20
+ labels: zod_1.z.array(zod_1.z.string()).optional(),
21
+ });
22
+ exports.MailMessageReceivedSchema = exports.MailEventBaseSchema.extend({
23
+ classification: zod_1.z.string().min(1).optional(),
24
+ });
25
+ exports.MailMessageClassifiedSchema = exports.MailEventBaseSchema.extend({
26
+ classification: zod_1.z.string().min(1),
27
+ });
28
+ exports.MailThreadUpdatedSchema = zod_1.z.object({
29
+ orgId: zod_1.z.string().min(1),
30
+ projectId: zod_1.z.string().min(1).optional(),
31
+ mailboxRef: zod_1.z.string().min(1),
32
+ threadRef: zod_1.z.string().min(1),
33
+ subject: zod_1.z.string().optional(),
34
+ participants: zod_1.z.array(zod_1.z.string()),
35
+ messageCount: zod_1.z.number().int().nonnegative(),
36
+ lastReceivedAt: zod_1.z.string().min(1),
37
+ });
38
+ exports.MAIL_EVENT_SCHEMA_VERSION = '1.0.0';
39
+ exports.MAIL_EVENT_SOURCE = '/xema/services/mailops-api';
40
+ exports.MAIL_EVENT_DATA_TYPE = 'mailops';
41
+ //# sourceMappingURL=mail-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail-event.js","sourceRoot":"","sources":["../../../src/mail-source/lib/mail-event.ts"],"names":[],"mappings":";;;AAsBA,6BAAwB;AAMxB,IAAY,aAOX;AAPD,WAAY,aAAa;IAEvB,0DAAyC,CAAA;IAEzC,8DAA6C,CAAA;IAE7C,sDAAqC,CAAA;AACvC,CAAC,EAPW,aAAa,6BAAb,aAAa,QAOxB;AAMY,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAEvC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAE9B,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7B,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAGU,QAAA,yBAAyB,GAAG,2BAAmB,CAAC,MAAM,CAAC;IAKlE,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAMU,QAAA,2BAA2B,GAAG,2BAAmB,CAAC,MAAM,CAAC;IACpE,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAClC,CAAC,CAAC;AAGU,QAAA,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACvC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAE9B,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAEjC,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAE5C,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAClC,CAAC,CAAC;AAWU,QAAA,yBAAyB,GAAG,OAAgB,CAAC;AAG7C,QAAA,iBAAiB,GAAG,4BAAqC,CAAC;AAG1D,QAAA,oBAAoB,GAAG,SAAkB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export * from './lib/obligations';
2
+ export * from './lib/egress-allowlist';
2
3
  export * from './lib/route-hints';
3
4
  export * from './lib/policy';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./lib/obligations"), exports);
18
+ __exportStar(require("./lib/egress-allowlist"), exports);
18
19
  __exportStar(require("./lib/route-hints"), exports);
19
20
  __exportStar(require("./lib/policy"), exports);
20
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,oDAAkC;AAClC,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,yDAAuC;AACvC,oDAAkC;AAClC,+CAA6B"}
@@ -0,0 +1,18 @@
1
+ import { type EgressAllowlistObligation } from './obligations';
2
+ export type EgressDecision = {
3
+ readonly allowed: true;
4
+ } | {
5
+ readonly allowed: false;
6
+ readonly reason: EgressDenyReason;
7
+ };
8
+ export declare enum EgressDenyReason {
9
+ InvalidTarget = "invalid-target",
10
+ Blocklisted = "blocklisted",
11
+ NotAllowlisted = "not-allowlisted"
12
+ }
13
+ export declare class MalformedEgressObligationError extends Error {
14
+ constructor(detail: string);
15
+ }
16
+ export declare function evaluateEgress(targetUrl: string, obligation: EgressAllowlistObligation): EgressDecision;
17
+ export declare function isEgressAllowed(targetUrl: string, obligation: EgressAllowlistObligation): boolean;
18
+ //# sourceMappingURL=egress-allowlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"egress-allowlist.d.ts","sourceRoot":"","sources":["../../../src/policy/lib/egress-allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAmBvB,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAGnE,oBAAY,gBAAgB;IAE1B,aAAa,mBAAmB;IAEhC,WAAW,gBAAgB;IAE3B,cAAc,oBAAoB;CACnC;AAOD,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,MAAM,EAAE,MAAM;CAI3B;AAcD,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,yBAAyB,GACpC,cAAc,CA6BhB;AAOD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAET"}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MalformedEgressObligationError = exports.EgressDenyReason = void 0;
4
+ exports.evaluateEgress = evaluateEgress;
5
+ exports.isEgressAllowed = isEgressAllowed;
6
+ const obligations_1 = require("./obligations");
7
+ var EgressDenyReason;
8
+ (function (EgressDenyReason) {
9
+ EgressDenyReason["InvalidTarget"] = "invalid-target";
10
+ EgressDenyReason["Blocklisted"] = "blocklisted";
11
+ EgressDenyReason["NotAllowlisted"] = "not-allowlisted";
12
+ })(EgressDenyReason || (exports.EgressDenyReason = EgressDenyReason = {}));
13
+ class MalformedEgressObligationError extends Error {
14
+ constructor(detail) {
15
+ super(`Malformed egress-allowlist obligation: ${detail}`);
16
+ this.name = 'MalformedEgressObligationError';
17
+ }
18
+ }
19
+ exports.MalformedEgressObligationError = MalformedEgressObligationError;
20
+ function evaluateEgress(targetUrl, obligation) {
21
+ const parsed = obligations_1.EgressAllowlistObligationSchema.safeParse(obligation);
22
+ if (!parsed.success) {
23
+ throw new MalformedEgressObligationError(parsed.error.issues[0]?.message ?? 'invalid payload');
24
+ }
25
+ const { allow, deny } = parsed.data;
26
+ const target = parseTarget(targetUrl);
27
+ if (target === null) {
28
+ return { allowed: false, reason: EgressDenyReason.InvalidTarget };
29
+ }
30
+ if (deny !== undefined) {
31
+ for (const pattern of deny) {
32
+ if (matchPattern(pattern, target)) {
33
+ return { allowed: false, reason: EgressDenyReason.Blocklisted };
34
+ }
35
+ }
36
+ }
37
+ for (const pattern of allow) {
38
+ if (matchPattern(pattern, target)) {
39
+ return { allowed: true };
40
+ }
41
+ }
42
+ return { allowed: false, reason: EgressDenyReason.NotAllowlisted };
43
+ }
44
+ function isEgressAllowed(targetUrl, obligation) {
45
+ return evaluateEgress(targetUrl, obligation).allowed;
46
+ }
47
+ function parseTarget(rawUrl) {
48
+ let u;
49
+ try {
50
+ u = new URL(rawUrl);
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ if (u.protocol !== 'http:' && u.protocol !== 'https:') {
56
+ return null;
57
+ }
58
+ const host = u.hostname.toLowerCase().replace(/\.$/, '');
59
+ if (host.length === 0) {
60
+ return null;
61
+ }
62
+ return { host, scheme: u.protocol, path: normalisePath(u.pathname) };
63
+ }
64
+ function normalisePath(pathname) {
65
+ const collapsed = pathname.replace(/\/{2,}/g, '/');
66
+ if (collapsed.length > 1 && collapsed.endsWith('/')) {
67
+ return collapsed.slice(0, -1);
68
+ }
69
+ return collapsed.length === 0 ? '/' : collapsed;
70
+ }
71
+ function matchPattern(pattern, target) {
72
+ const schemeSep = pattern.indexOf('://');
73
+ if (schemeSep === -1) {
74
+ if (pattern.includes('/')) {
75
+ return false;
76
+ }
77
+ return matchHost(pattern.toLowerCase(), target.host);
78
+ }
79
+ const scheme = pattern.slice(0, schemeSep + 1).toLowerCase();
80
+ if (scheme !== target.scheme) {
81
+ return false;
82
+ }
83
+ const rest = pattern.slice(schemeSep + 3);
84
+ const slash = rest.indexOf('/');
85
+ const hostPart = (slash === -1 ? rest : rest.slice(0, slash)).toLowerCase();
86
+ const pathPart = slash === -1 ? '' : rest.slice(slash);
87
+ if (!matchHost(hostPart, target.host)) {
88
+ return false;
89
+ }
90
+ return matchPath(pathPart, target.path);
91
+ }
92
+ function matchHost(pattern, host) {
93
+ if (pattern.length === 0) {
94
+ return false;
95
+ }
96
+ const pLabels = pattern.split('.');
97
+ const hLabels = host.split('.');
98
+ if (pLabels.length !== hLabels.length) {
99
+ return false;
100
+ }
101
+ for (let i = 0; i < pLabels.length; i++) {
102
+ const pl = pLabels[i];
103
+ const hl = hLabels[i];
104
+ if (pl === '*') {
105
+ if (hl === undefined || hl.length === 0) {
106
+ return false;
107
+ }
108
+ continue;
109
+ }
110
+ if (pl !== hl) {
111
+ return false;
112
+ }
113
+ }
114
+ return true;
115
+ }
116
+ function matchPath(patternPath, targetPath) {
117
+ if (patternPath === '' || patternPath === '/') {
118
+ return true;
119
+ }
120
+ const wildcard = patternPath.endsWith('/*');
121
+ const base = normalisePath(wildcard ? patternPath.slice(0, -2) : patternPath);
122
+ if (!wildcard) {
123
+ return targetPath === base;
124
+ }
125
+ if (targetPath === base) {
126
+ return true;
127
+ }
128
+ return targetPath.startsWith(base === '/' ? '/' : `${base}/`);
129
+ }
130
+ //# sourceMappingURL=egress-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"egress-allowlist.js","sourceRoot":"","sources":["../../../src/policy/lib/egress-allowlist.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,8 @@ export declare enum PolicyObligationKind {
7
7
  MaxDurationSeconds = "max-duration-seconds",
8
8
  MaxCostUsd = "max-cost-usd",
9
9
  RestrictOutputClassification = "restrict-output-classification",
10
- DataResidency = "data-residency"
10
+ DataResidency = "data-residency",
11
+ EgressAllowlist = "egress-allowlist"
11
12
  }
12
13
  export declare const PolicyObligationKindSchema: z.ZodEnum<typeof PolicyObligationKind>;
13
14
  export declare enum RunnerKind {
@@ -64,6 +65,12 @@ export declare const DataResidencyObligationSchema: z.ZodObject<{
64
65
  residency: z.ZodEnum<typeof DataResidency>;
65
66
  }, z.core.$strip>;
66
67
  export type DataResidencyObligation = z.infer<typeof DataResidencyObligationSchema>;
68
+ export declare const EgressAllowlistObligationSchema: z.ZodObject<{
69
+ kind: z.ZodLiteral<PolicyObligationKind.EgressAllowlist>;
70
+ allow: z.ZodArray<z.ZodString>;
71
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
72
+ }, z.core.$strip>;
73
+ export type EgressAllowlistObligation = z.infer<typeof EgressAllowlistObligationSchema>;
67
74
  export declare const PolicyObligationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
68
75
  kind: z.ZodLiteral<PolicyObligationKind.Audit>;
69
76
  }, z.core.$strip>, z.ZodObject<{
@@ -86,6 +93,10 @@ export declare const PolicyObligationSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
86
93
  }, z.core.$strip>, z.ZodObject<{
87
94
  kind: z.ZodLiteral<PolicyObligationKind.DataResidency>;
88
95
  residency: z.ZodEnum<typeof DataResidency>;
96
+ }, z.core.$strip>, z.ZodObject<{
97
+ kind: z.ZodLiteral<PolicyObligationKind.EgressAllowlist>;
98
+ allow: z.ZodArray<z.ZodString>;
99
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
89
100
  }, z.core.$strip>], "kind">;
90
101
  export type PolicyObligation = z.infer<typeof PolicyObligationSchema>;
91
102
  //# sourceMappingURL=obligations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"obligations.d.ts","sourceRoot":"","sources":["../../../src/policy/lib/obligations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,oBAAY,oBAAoB;IAC9B,KAAK,UAAU;IACf,aAAa,mBAAmB;IAChC,iBAAiB,wBAAwB;IACzC,oBAAoB,2BAA2B;IAC/C,kBAAkB,yBAAyB;IAC3C,UAAU,iBAAiB;IAC3B,4BAA4B,mCAAmC;IAC/D,aAAa,mBAAmB;CACjC;AAED,eAAO,MAAM,0BAA0B,wCAAqC,CAAC;AAa7E,oBAAY,UAAU;IACpB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,YAAY,kBAAkB;IAC9B,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,EAAE,OAAO;IAQT,WAAW,iBAAiB;CAC7B;AAED,eAAO,MAAM,gBAAgB,8BAA2B,CAAC;AAWzD,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,eAAe,qBAAqB;CACrC;AAED,eAAO,MAAM,mBAAmB,iCAA8B,CAAC;AAU/D,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,iCAAiC;;;iBAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAC/C,OAAO,iCAAiC,CACzC,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;iBAI/C,CAAC;AACH,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAClD,OAAO,oCAAoC,CAC5C,CAAC;AAEF,eAAO,MAAM,kCAAkC;;;iBAG7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAChD,OAAO,kCAAkC,CAC1C,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,4CAA4C;;;iBAGvD,CAAC;AACH,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAC1D,OAAO,4CAA4C,CACpD,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AASF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;2BASjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
1
+ {"version":3,"file":"obligations.d.ts","sourceRoot":"","sources":["../../../src/policy/lib/obligations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,oBAAY,oBAAoB;IAC9B,KAAK,UAAU;IACf,aAAa,mBAAmB;IAChC,iBAAiB,wBAAwB;IACzC,oBAAoB,2BAA2B;IAC/C,kBAAkB,yBAAyB;IAC3C,UAAU,iBAAiB;IAC3B,4BAA4B,mCAAmC;IAC/D,aAAa,mBAAmB;IAShC,eAAe,qBAAqB;CACrC;AAED,eAAO,MAAM,0BAA0B,wCAAqC,CAAC;AAa7E,oBAAY,UAAU;IACpB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,YAAY,kBAAkB;IAC9B,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,EAAE,OAAO;IAQT,WAAW,iBAAiB;CAC7B;AAED,eAAO,MAAM,gBAAgB,8BAA2B,CAAC;AAWzD,oBAAY,aAAa;IACvB,EAAE,OAAO;IACT,EAAE,OAAO;IACT,eAAe,qBAAqB;CACrC;AAED,eAAO,MAAM,mBAAmB,iCAA8B,CAAC;AAU/D,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,iCAAiC;;;iBAG5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAC/C,OAAO,iCAAiC,CACzC,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;iBAI/C,CAAC;AACH,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,KAAK,CAClD,OAAO,oCAAoC,CAC5C,CAAC;AAEF,eAAO,MAAM,kCAAkC;;;iBAG7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAChD,OAAO,kCAAkC,CAC1C,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;iBAGrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,4CAA4C;;;iBAGvD,CAAC;AACH,MAAM,MAAM,sCAAsC,GAAG,CAAC,CAAC,KAAK,CAC1D,OAAO,4CAA4C,CACpD,CAAC;AAEF,eAAO,MAAM,6BAA6B;;;iBAGxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AAoCF,eAAO,MAAM,+BAA+B;;;;iBAY1C,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,+BAA+B,CACvC,CAAC;AASF,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;2BAUjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PolicyObligationSchema = exports.DataResidencyObligationSchema = exports.RestrictOutputClassificationObligationSchema = exports.MaxCostUsdObligationSchema = exports.MaxDurationSecondsObligationSchema = exports.RequireHumanApprovalObligationSchema = exports.RequireRunnerKindObligationSchema = exports.RedactSecretsObligationSchema = exports.AuditObligationSchema = exports.DataResidencySchema = exports.DataResidency = exports.RunnerKindSchema = exports.RunnerKind = exports.PolicyObligationKindSchema = exports.PolicyObligationKind = void 0;
3
+ exports.PolicyObligationSchema = exports.EgressAllowlistObligationSchema = exports.DataResidencyObligationSchema = exports.RestrictOutputClassificationObligationSchema = exports.MaxCostUsdObligationSchema = exports.MaxDurationSecondsObligationSchema = exports.RequireHumanApprovalObligationSchema = exports.RequireRunnerKindObligationSchema = exports.RedactSecretsObligationSchema = exports.AuditObligationSchema = exports.DataResidencySchema = exports.DataResidency = exports.RunnerKindSchema = exports.RunnerKind = exports.PolicyObligationKindSchema = exports.PolicyObligationKind = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const space_1 = require("../../space");
6
6
  var PolicyObligationKind;
@@ -13,6 +13,7 @@ var PolicyObligationKind;
13
13
  PolicyObligationKind["MaxCostUsd"] = "max-cost-usd";
14
14
  PolicyObligationKind["RestrictOutputClassification"] = "restrict-output-classification";
15
15
  PolicyObligationKind["DataResidency"] = "data-residency";
16
+ PolicyObligationKind["EgressAllowlist"] = "egress-allowlist";
16
17
  })(PolicyObligationKind || (exports.PolicyObligationKind = PolicyObligationKind = {}));
17
18
  exports.PolicyObligationKindSchema = zod_1.z.nativeEnum(PolicyObligationKind);
18
19
  var RunnerKind;
@@ -63,6 +64,17 @@ exports.DataResidencyObligationSchema = zod_1.z.object({
63
64
  kind: zod_1.z.literal(PolicyObligationKind.DataResidency),
64
65
  residency: exports.DataResidencySchema,
65
66
  });
67
+ const EGRESS_PATTERN = zod_1.z
68
+ .string()
69
+ .min(1)
70
+ .refine((p) => !/[\s@#?]/.test(p), {
71
+ message: 'egress pattern must not contain whitespace, "@", "#" or "?" (those belong to the target URL, not the rule)',
72
+ });
73
+ exports.EgressAllowlistObligationSchema = zod_1.z.object({
74
+ kind: zod_1.z.literal(PolicyObligationKind.EgressAllowlist),
75
+ allow: zod_1.z.array(EGRESS_PATTERN).min(1),
76
+ deny: zod_1.z.array(EGRESS_PATTERN).optional(),
77
+ });
66
78
  exports.PolicyObligationSchema = zod_1.z.discriminatedUnion('kind', [
67
79
  exports.AuditObligationSchema,
68
80
  exports.RedactSecretsObligationSchema,
@@ -72,5 +84,6 @@ exports.PolicyObligationSchema = zod_1.z.discriminatedUnion('kind', [
72
84
  exports.MaxCostUsdObligationSchema,
73
85
  exports.RestrictOutputClassificationObligationSchema,
74
86
  exports.DataResidencyObligationSchema,
87
+ exports.EgressAllowlistObligationSchema,
75
88
  ]);
76
89
  //# sourceMappingURL=obligations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"obligations.js","sourceRoot":"","sources":["../../../src/policy/lib/obligations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"obligations.js","sourceRoot":"","sources":["../../../src/policy/lib/obligations.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/kernel-contracts",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Consolidated Xema OS kernel wire contracts — pure types + zod schemas for the 32 kernel protocol surfaces. One package, one npm scope, wildcard per-surface subpath exports. No framework/runtime deps.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",
@@ -1,7 +1,12 @@
1
1
  export * from './lib/biome-capability-refs';
2
2
  export * from './lib/biome-lifecycle';
3
3
  export * from './lib/biome-scope';
4
+ export * from './lib/biome-tier';
5
+ export * from './lib/biome-target';
6
+ export * from './lib/biome-audience';
7
+ export * from './lib/biome-origin';
4
8
  export * from './lib/biome-trust-tier';
9
+ export * from './lib/biome-availability-grant';
5
10
  export * from './lib/biome-api';
6
11
  export * from './lib/biome-lifecycle-hooks';
7
12
  export * from './lib/biome-engines';
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `BiomeAudience` — WHO a biome is for. Orthogonal to dependency tier
5
+ * (`BiomeTier`), origin (`BiomeOrigin`), and install scope (`BiomeScope`).
6
+ *
7
+ * - `Org` (default) — a normal biome, available to organizations (subject to
8
+ * org enablement + availability grants) and eligible to appear in the store.
9
+ * - `Operator` — for Xema PLATFORM OPERATORS only (us). Effects, enforced
10
+ * across the planes:
11
+ * 1. Packaging — distribution SELECTORS skip operator biomes; they ship
12
+ * only when explicitly named in `include[]` (the "force it in" rule for
13
+ * the internal distribution).
14
+ * 2. Discovery — never store-listed; hidden from org-facing biome UIs.
15
+ * 3. Access — gated to the `platform_admin` realm role.
16
+ *
17
+ * Closed set; new values are a kernel change.
18
+ */
19
+ export enum BiomeAudience {
20
+ Org = 'org',
21
+ Operator = 'operator',
22
+ }
23
+
24
+ export const BiomeAudienceSchema = z.nativeEnum(BiomeAudience);
25
+
26
+ /** The default audience applied when a manifest omits the field. */
27
+ export const DEFAULT_BIOME_AUDIENCE = BiomeAudience.Org;
@@ -0,0 +1,42 @@
1
+ import { z } from 'zod';
2
+ import { SubjectRefSchema, type SubjectRef } from '../../subject';
3
+
4
+ /**
5
+ * Canonical authorization action for "may this subject see/use this biome".
6
+ * Registered as a gatable action in `authorization-api`; the biome-host web
7
+ * registry filters the per-org biome list by evaluating this action for the
8
+ * caller. NOT the same as installing or enabling a biome (those are org-admin
9
+ * actions) — this is the third, finer level: availability to a subject within
10
+ * an org that has already enabled the biome.
11
+ */
12
+ export const BIOME_ACCESS_ACTION = 'biome.access';
13
+
14
+ /**
15
+ * `BiomeAvailabilityGrant` — makes an org-enabled biome available to a specific
16
+ * subject (a `user` or a `group`/team) within an org.
17
+ *
18
+ * Semantics (fail-OPEN by absence, NOT by error):
19
+ * - If an org has ZERO grant rows for a biome, the biome is available
20
+ * ORG-WIDE (the default; preserves today's org-wide enablement behaviour).
21
+ * - If an org has ONE OR MORE grant rows for a biome, the biome is available
22
+ * ONLY to the union of the granted subjects (and to org/platform admins).
23
+ *
24
+ * `subject.kind` is meaningful only for `User` and `Group` (team). Org-wide
25
+ * availability is expressed by the ABSENCE of rows, never by an `org` subject
26
+ * row — so there is exactly one way to say "everyone".
27
+ *
28
+ * Backed by `authorization-api` (the PDP) as grants over the `biome.access`
29
+ * action; the biome-id is the resource. Portals are the UI that writes these
30
+ * rows — availability is the generic permission, Portals are the curation lens.
31
+ */
32
+ export interface BiomeAvailabilityGrant {
33
+ orgId: string;
34
+ biomeId: string;
35
+ subject: SubjectRef;
36
+ }
37
+
38
+ export const BiomeAvailabilityGrantSchema = z.object({
39
+ orgId: z.string().min(1),
40
+ biomeId: z.string().min(1),
41
+ subject: SubjectRefSchema,
42
+ }) as z.ZodType<BiomeAvailabilityGrant>;
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `BiomeOrigin` — the packaging-time PROVENANCE posture carried on a biome
5
+ * manifest (`xema.trustTier` in `xema-biome.json`). This is the value
6
+ * available at BUILD/resolve time and the one a distribution `trustPolicy`
7
+ * gates on (e.g. a locked appliance allows only `first-party`).
8
+ *
9
+ * Distinct from the richer 6-value publication/install provenance
10
+ * (`BiomeTrustTier`), which is assigned later at store-publish / install time
11
+ * and is not knowable from source. Keep the two separate — the distribution
12
+ * trust gate operates on origin, not on install-time provenance.
13
+ *
14
+ * Closed set; new values are a kernel change. (Seam: the biome-sdk manifest's
15
+ * own 2-value `BiomeTrustTierSchema` should migrate to import this enum so the
16
+ * posture has a single source of truth.)
17
+ */
18
+ export enum BiomeOrigin {
19
+ FirstParty = 'first-party',
20
+ ThirdParty = 'third-party',
21
+ }
22
+
23
+ export const BiomeOriginSchema = z.nativeEnum(BiomeOrigin);
24
+
25
+ /** The default origin applied when a manifest omits the field. */
26
+ export const DEFAULT_BIOME_ORIGIN = BiomeOrigin.ThirdParty;
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `BiomeTarget` — the runtime surface a biome ships for. A `server` biome runs
5
+ * as a backend workload (NestJS service / worker); a `web` biome is a federated
6
+ * frontend module mounted in the host shell. Mirrors the biome-sdk manifest
7
+ * `xema.target` discriminant; lives here as the canonical contract so the
8
+ * distribution lockfile can type the resolved surface without depending on the
9
+ * (Layer 1) biome-sdk.
10
+ */
11
+ export enum BiomeTarget {
12
+ Server = 'server',
13
+ Web = 'web',
14
+ }
15
+
16
+ export const BiomeTargetSchema = z.nativeEnum(BiomeTarget);
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `BiomeTier` — the canonical DEPENDENCY/BOOT tier of a biome.
5
+ *
6
+ * This is the axis that governs which biomes a biome may depend on and the
7
+ * boot order (kernel boots first, then system, then base, then platform). It
8
+ * is DISTINCT from two other biome dimensions that share overlapping string
9
+ * values but mean different things:
10
+ *
11
+ * - `BiomeScope` (`biome-scope.ts`) — the INSTALLATION scope
12
+ * (`system|org|project|sandbox`): where an installation lives.
13
+ * - `BiomeTrustTier` (`biome-trust-tier.ts`) — PROVENANCE/origin
14
+ * (`first-party|verified-store|community-store|…`).
15
+ *
16
+ * Closed set, ordered low→high. `third-party` is intentionally NOT a tier
17
+ * value — origin/trust is carried by `BiomeTrustTier`, not by the dependency
18
+ * tier (the two axes were previously conflated in the biome-sdk
19
+ * `BiomeScopeSchema`). New tiers are a kernel change.
20
+ *
21
+ * String values match the on-wire `xema.scope` field of `xema-biome.json`
22
+ * (the manifest field name remains `scope` for now; the distribution tooling
23
+ * maps `xema.scope` → `BiomeTier`).
24
+ */
25
+ export enum BiomeTier {
26
+ Kernel = 'kernel',
27
+ System = 'system',
28
+ Base = 'base',
29
+ Platform = 'platform',
30
+ }
31
+
32
+ export const BiomeTierSchema = z.nativeEnum(BiomeTier);
33
+
34
+ /**
35
+ * Tier precedence, low→high. A biome of tier `T` may depend only on biomes
36
+ * whose tier index is `<=` its own. Index 0 (`Kernel`) is the always-shipped
37
+ * floor of every distribution.
38
+ */
39
+ export const BIOME_TIER_ORDER: readonly BiomeTier[] = [
40
+ BiomeTier.Kernel,
41
+ BiomeTier.System,
42
+ BiomeTier.Base,
43
+ BiomeTier.Platform,
44
+ ];
@@ -121,6 +121,20 @@ export enum ContributionKind {
121
121
  * upsert by `ref`, so they cannot drift.
122
122
  */
123
123
  Capability = 'capability',
124
+
125
+ // -- Domain stage machines (MailOps asset lifecycle) ---------------------
126
+ /**
127
+ * A deterministic asset stage machine contributed by a domain biome to a
128
+ * stage-machine host (today: `mailops-api`). The descriptor is pure data —
129
+ * an asset type plus an ordered list of stages, each non-initial stage
130
+ * declaring the evidence kinds that must be present to reach it. The host
131
+ * compiles the descriptor into runtime predicates over the asset's evidence
132
+ * timeline (`computeStage`). The kernel owns only this enum member; the
133
+ * descriptor's manifest schema is owned by the ingesting host (mirroring
134
+ * `ArtifactType`, whose schema lives in `artifact-store-api`) because the
135
+ * stage machine is a host-domain concept, not a kernel one.
136
+ */
137
+ StageMachine = 'stage-machine',
124
138
  }
125
139
 
126
140
  /**
@@ -0,0 +1,4 @@
1
+ export * from './lib/distribution-selector';
2
+ export * from './lib/distribution';
3
+ export * from './lib/distribution-lock';
4
+ export * from './lib/image-lock';
@@ -0,0 +1,88 @@
1
+ import { z } from 'zod';
2
+ import {
3
+ BiomeTierSchema,
4
+ BiomeTargetSchema,
5
+ BiomeOriginSchema,
6
+ type BiomeTier,
7
+ type BiomeTarget,
8
+ type BiomeOrigin,
9
+ } from '../../biome';
10
+
11
+ /**
12
+ * A single biome as resolved into a distribution lockfile. Version-pinned and
13
+ * (once images are built) content-addressed. `imageDigest` is populated by the
14
+ * image-manifest step (`images.lock.json`) and may be absent in the pure biome
15
+ * lockfile before images are built.
16
+ */
17
+ export interface LockedBiome {
18
+ id: string;
19
+ version: string;
20
+ tier: BiomeTier;
21
+ target: BiomeTarget;
22
+ /** Provenance posture from the manifest (gated by the distribution trustPolicy). */
23
+ origin: BiomeOrigin;
24
+ /** Whether the org may disable this biome once shipped (cannot-disable). */
25
+ mandatory: boolean;
26
+ /** Source repo + path the biome was resolved from (provenance for the build). */
27
+ repo: string;
28
+ path: string;
29
+ /** Set by the image-manifest resolver; `image@sha256:<digest>`. */
30
+ imageDigest?: string;
31
+ }
32
+
33
+ export const LockedBiomeSchema = z.object({
34
+ id: z.string().min(1),
35
+ version: z.string().min(1),
36
+ tier: BiomeTierSchema,
37
+ target: BiomeTargetSchema,
38
+ origin: BiomeOriginSchema,
39
+ mandatory: z.boolean(),
40
+ repo: z.string().min(1),
41
+ path: z.string().min(1),
42
+ imageDigest: z.string().min(1).optional(),
43
+ }) as z.ZodType<LockedBiome>;
44
+
45
+ /**
46
+ * `DistributionLock` — the deterministic, resolved output of a `Distribution`.
47
+ * THE single artifact every consumer reads (deploy generator, test-suite
48
+ * mapping, biome-host boot filter, appliance build). No consumer re-applies the
49
+ * distribution rules — the lockfile is the hard boundary.
50
+ *
51
+ * `resolvedAt` / `inputHash` are stamped by the resolver tooling, not the
52
+ * kernel (kernel contracts hold no clock); both optional so the type is usable
53
+ * mid-resolution.
54
+ */
55
+ export interface DistributionLock {
56
+ schemaVersion: 1;
57
+ distributionId: string;
58
+ biomes: readonly LockedBiome[];
59
+ /** ISO-8601 timestamp the resolver stamped (tooling-supplied). */
60
+ resolvedAt?: string;
61
+ /** Hash of the resolver inputs (manifest + index) for drift detection. */
62
+ inputHash?: string;
63
+ }
64
+
65
+ export const DistributionLockSchema = z.object({
66
+ schemaVersion: z.literal(1),
67
+ distributionId: z.string().min(1),
68
+ biomes: z.array(LockedBiomeSchema).readonly(),
69
+ resolvedAt: z.string().min(1).optional(),
70
+ inputHash: z.string().min(1).optional(),
71
+ }) as z.ZodType<DistributionLock>;
72
+
73
+ /**
74
+ * Parse + validate a raw `distribution.lock.json`. Fail-fast on any shape error
75
+ * — the lockfile is the hard boundary every consumer reads, so a malformed lock
76
+ * must never be silently tolerated.
77
+ */
78
+ export function parseDistributionLock(raw: unknown): DistributionLock {
79
+ const result = DistributionLockSchema.safeParse(raw);
80
+ if (!result.success) {
81
+ throw new Error(
82
+ `Invalid distribution.lock.json: ${result.error.issues
83
+ .map((i) => `[${i.path.join('.')}] ${i.message}`)
84
+ .join('; ')}`,
85
+ );
86
+ }
87
+ return result.data;
88
+ }