@xemahq/kernel-contracts 0.16.2 → 0.18.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.
Files changed (32) hide show
  1. package/dist/agent-workspace/awp-spec.json +1 -1
  2. package/dist/contribution/lib/contribution-kind.d.ts +1 -0
  3. package/dist/contribution/lib/contribution-kind.d.ts.map +1 -1
  4. package/dist/contribution/lib/contribution-kind.js +1 -0
  5. package/dist/contribution/lib/contribution-kind.js.map +1 -1
  6. package/dist/lifecycle-events/index.d.ts +2 -0
  7. package/dist/lifecycle-events/index.d.ts.map +1 -0
  8. package/dist/lifecycle-events/index.js +18 -0
  9. package/dist/lifecycle-events/index.js.map +1 -0
  10. package/dist/lifecycle-events/lib/lifecycle-events.d.ts +25 -0
  11. package/dist/lifecycle-events/lib/lifecycle-events.d.ts.map +1 -0
  12. package/dist/lifecycle-events/lib/lifecycle-events.js +32 -0
  13. package/dist/lifecycle-events/lib/lifecycle-events.js.map +1 -0
  14. package/dist/resource/index.d.ts +2 -0
  15. package/dist/resource/index.d.ts.map +1 -1
  16. package/dist/resource/index.js +2 -0
  17. package/dist/resource/index.js.map +1 -1
  18. package/dist/resource/lib/resource-ownership-contribution.d.ts +29 -0
  19. package/dist/resource/lib/resource-ownership-contribution.d.ts.map +1 -0
  20. package/dist/resource/lib/resource-ownership-contribution.js +35 -0
  21. package/dist/resource/lib/resource-ownership-contribution.js.map +1 -0
  22. package/dist/resource/lib/resource-ref.d.ts +9 -0
  23. package/dist/resource/lib/resource-ref.d.ts.map +1 -0
  24. package/dist/resource/lib/resource-ref.js +33 -0
  25. package/dist/resource/lib/resource-ref.js.map +1 -0
  26. package/package.json +1 -1
  27. package/src/contribution/lib/contribution-kind.ts +15 -0
  28. package/src/lifecycle-events/index.ts +1 -0
  29. package/src/lifecycle-events/lib/lifecycle-events.ts +103 -0
  30. package/src/resource/index.ts +12 -5
  31. package/src/resource/lib/resource-ownership-contribution.ts +127 -0
  32. package/src/resource/lib/resource-ref.ts +75 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://xema.dev/schemas/awp-spec.v1.json",
3
- "emittedAt": "2026-06-26T20:48:27.706Z",
3
+ "emittedAt": "2026-06-27T11:25:54.369Z",
4
4
  "spec": {
5
5
  "id": "awp/v1",
6
6
  "version": "1.2.0",
@@ -38,6 +38,7 @@ export declare enum ContributionKind {
38
38
  DeliverableSpecKind = "deliverable-spec-kind",
39
39
  RuntimeMountKind = "runtime-mount-kind",
40
40
  Capability = "capability",
41
+ ResourceOwnership = "resource-ownership",
41
42
  StageMachine = "stage-machine"
42
43
  }
43
44
  export declare const ContributionKindSchema: z.ZodEnum<typeof ContributionKind>;
@@ -1 +1 @@
1
- {"version":3,"file":"contribution-kind.d.ts","sourceRoot":"","sources":["../../../src/contribution/lib/contribution-kind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,oBAAY,gBAAgB;IAE1B,gBAAgB,sBAAsB;IACtC,WAAW,iBAAiB;IAC5B,OAAO,aAAa;IACpB,gBAAgB,sBAAsB;IACtC,aAAa,mBAAmB;IAChC,YAAY,kBAAkB;IAC9B,UAAU,gBAAgB;IAC1B,YAAY,kBAAkB;IAC9B,mBAAmB,yBAAyB;IAC5C,UAAU,gBAAgB;IAC1B,WAAW,iBAAiB;IAC5B,wBAAwB,+BAA+B;IACvD,UAAU,gBAAgB;IAI1B,YAAY,kBAAkB;IAE9B,WAAW,iBAAiB;IAQ5B,YAAY,kBAAkB;IAM9B,WAAW,iBAAiB;IAW5B,cAAc,oBAAoB;IAElC,kBAAkB,yBAAyB;IAE3C,IAAI,SAAS;IAEb,UAAU,gBAAgB;IAE1B,oBAAoB,0BAA0B;IAE9C,oBAAoB,2BAA2B;IAE/C,yBAAyB,gCAAgC;IAGzD,mBAAmB,yBAAyB;IAI5C,cAAc,oBAAoB;IAElC,eAAe,qBAAqB;IAEpC,iBAAiB,uBAAuB;IAExC,yBAAyB,gCAAgC;IAEzD,WAAW,iBAAiB;IAI5B,UAAU,gBAAgB;IAE1B,YAAY,kBAAkB;IAE9B,cAAc,oBAAoB;IAElC,WAAW,iBAAiB;IAI5B,eAAe,sBAAsB;IAErC,mBAAmB,0BAA0B;IAE7C,gBAAgB,uBAAuB;IAiBvC,UAAU,eAAe;IAczB,YAAY,kBAAkB;CAC/B;AAMD,eAAO,MAAM,sBAAsB,oCAAiC,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,GAAG,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"contribution-kind.d.ts","sourceRoot":"","sources":["../../../src/contribution/lib/contribution-kind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,oBAAY,gBAAgB;IAE1B,gBAAgB,sBAAsB;IACtC,WAAW,iBAAiB;IAC5B,OAAO,aAAa;IACpB,gBAAgB,sBAAsB;IACtC,aAAa,mBAAmB;IAChC,YAAY,kBAAkB;IAC9B,UAAU,gBAAgB;IAC1B,YAAY,kBAAkB;IAC9B,mBAAmB,yBAAyB;IAC5C,UAAU,gBAAgB;IAC1B,WAAW,iBAAiB;IAC5B,wBAAwB,+BAA+B;IACvD,UAAU,gBAAgB;IAI1B,YAAY,kBAAkB;IAE9B,WAAW,iBAAiB;IAQ5B,YAAY,kBAAkB;IAM9B,WAAW,iBAAiB;IAW5B,cAAc,oBAAoB;IAElC,kBAAkB,yBAAyB;IAE3C,IAAI,SAAS;IAEb,UAAU,gBAAgB;IAE1B,oBAAoB,0BAA0B;IAE9C,oBAAoB,2BAA2B;IAE/C,yBAAyB,gCAAgC;IAGzD,mBAAmB,yBAAyB;IAI5C,cAAc,oBAAoB;IAElC,eAAe,qBAAqB;IAEpC,iBAAiB,uBAAuB;IAExC,yBAAyB,gCAAgC;IAEzD,WAAW,iBAAiB;IAI5B,UAAU,gBAAgB;IAE1B,YAAY,kBAAkB;IAE9B,cAAc,oBAAoB;IAElC,WAAW,iBAAiB;IAI5B,eAAe,sBAAsB;IAErC,mBAAmB,0BAA0B;IAE7C,gBAAgB,uBAAuB;IAiBvC,UAAU,eAAe;IAezB,iBAAiB,uBAAuB;IAcxC,YAAY,kBAAkB;CAC/B;AAMD,eAAO,MAAM,sBAAsB,oCAAiC,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,GAAG,gBAAgB,EAAE,CAAC"}
@@ -42,6 +42,7 @@ var ContributionKind;
42
42
  ContributionKind["DeliverableSpecKind"] = "deliverable-spec-kind";
43
43
  ContributionKind["RuntimeMountKind"] = "runtime-mount-kind";
44
44
  ContributionKind["Capability"] = "capability";
45
+ ContributionKind["ResourceOwnership"] = "resource-ownership";
45
46
  ContributionKind["StageMachine"] = "stage-machine";
46
47
  })(ContributionKind || (exports.ContributionKind = ContributionKind = {}));
47
48
  exports.ContributionKindSchema = zod_1.z.nativeEnum(ContributionKind);
@@ -1 +1 @@
1
- {"version":3,"file":"contribution-kind.js","sourceRoot":"","sources":["../../../src/contribution/lib/contribution-kind.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAexB,IAAY,gBA0HX;AA1HD,WAAY,gBAAgB;IAE1B,0DAAsC,CAAA;IACtC,gDAA4B,CAAA;IAC5B,wCAAoB,CAAA;IACpB,0DAAsC,CAAA;IACtC,oDAAgC,CAAA;IAChC,kDAA8B,CAAA;IAC9B,8CAA0B,CAAA;IAC1B,kDAA8B,CAAA;IAC9B,gEAA4C,CAAA;IAC5C,8CAA0B,CAAA;IAC1B,gDAA4B,CAAA;IAC5B,2EAAuD,CAAA;IACvD,8CAA0B,CAAA;IAI1B,kDAA8B,CAAA;IAE9B,gDAA4B,CAAA;IAQ5B,kDAA8B,CAAA;IAM9B,gDAA4B,CAAA;IAW5B,sDAAkC,CAAA;IAElC,+DAA2C,CAAA;IAE3C,iCAAa,CAAA;IAEb,8CAA0B,CAAA;IAE1B,kEAA8C,CAAA;IAE9C,mEAA+C,CAAA;IAE/C,6EAAyD,CAAA;IAGzD,gEAA4C,CAAA;IAI5C,sDAAkC,CAAA;IAElC,wDAAoC,CAAA;IAEpC,4DAAwC,CAAA;IAExC,6EAAyD,CAAA;IAEzD,gDAA4B,CAAA;IAI5B,8CAA0B,CAAA;IAE1B,kDAA8B,CAAA;IAE9B,sDAAkC,CAAA;IAElC,gDAA4B,CAAA;IAI5B,yDAAqC,CAAA;IAErC,iEAA6C,CAAA;IAE7C,2DAAuC,CAAA;IAiBvC,6CAAyB,CAAA;IAczB,kDAA8B,CAAA;AAChC,CAAC,EA1HW,gBAAgB,gCAAhB,gBAAgB,QA0H3B;AAMY,QAAA,sBAAsB,GAAG,OAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"contribution-kind.js","sourceRoot":"","sources":["../../../src/contribution/lib/contribution-kind.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAexB,IAAY,gBAyIX;AAzID,WAAY,gBAAgB;IAE1B,0DAAsC,CAAA;IACtC,gDAA4B,CAAA;IAC5B,wCAAoB,CAAA;IACpB,0DAAsC,CAAA;IACtC,oDAAgC,CAAA;IAChC,kDAA8B,CAAA;IAC9B,8CAA0B,CAAA;IAC1B,kDAA8B,CAAA;IAC9B,gEAA4C,CAAA;IAC5C,8CAA0B,CAAA;IAC1B,gDAA4B,CAAA;IAC5B,2EAAuD,CAAA;IACvD,8CAA0B,CAAA;IAI1B,kDAA8B,CAAA;IAE9B,gDAA4B,CAAA;IAQ5B,kDAA8B,CAAA;IAM9B,gDAA4B,CAAA;IAW5B,sDAAkC,CAAA;IAElC,+DAA2C,CAAA;IAE3C,iCAAa,CAAA;IAEb,8CAA0B,CAAA;IAE1B,kEAA8C,CAAA;IAE9C,mEAA+C,CAAA;IAE/C,6EAAyD,CAAA;IAGzD,gEAA4C,CAAA;IAI5C,sDAAkC,CAAA;IAElC,wDAAoC,CAAA;IAEpC,4DAAwC,CAAA;IAExC,6EAAyD,CAAA;IAEzD,gDAA4B,CAAA;IAI5B,8CAA0B,CAAA;IAE1B,kDAA8B,CAAA;IAE9B,sDAAkC,CAAA;IAElC,gDAA4B,CAAA;IAI5B,yDAAqC,CAAA;IAErC,iEAA6C,CAAA;IAE7C,2DAAuC,CAAA;IAiBvC,6CAAyB,CAAA;IAezB,4DAAwC,CAAA;IAcxC,kDAA8B,CAAA;AAChC,CAAC,EAzIW,gBAAgB,gCAAhB,gBAAgB,QAyI3B;AAMY,QAAA,sBAAsB,GAAG,OAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './lib/lifecycle-events';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lifecycle-events/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./lib/lifecycle-events"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lifecycle-events/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC"}
@@ -0,0 +1,25 @@
1
+ import { z } from 'zod';
2
+ export declare enum LifecycleEventType {
3
+ OrganizationDeleted = "organization.organization.deleted",
4
+ ProjectDeleted = "project.project.deleted",
5
+ UserDeleted = "user.user.deleted"
6
+ }
7
+ export declare const IDENTITY_LIFECYCLE_EVENT_SOURCE: "/services/identity-api";
8
+ export declare const PROJECT_LIFECYCLE_EVENT_SOURCE: "/services/project-registry-api";
9
+ export declare const LIFECYCLE_EVENT_SCHEMA_VERSION: "1.0.0";
10
+ export declare const OrganizationDeletedEventSchema: z.ZodObject<{
11
+ id: z.ZodString;
12
+ }, z.core.$strict>;
13
+ export declare const ProjectDeletedEventSchema: z.ZodObject<{
14
+ id: z.ZodString;
15
+ orgId: z.ZodString;
16
+ projectId: z.ZodString;
17
+ }, z.core.$strict>;
18
+ export declare const UserDeletedEventSchema: z.ZodObject<{
19
+ id: z.ZodString;
20
+ orgId: z.ZodOptional<z.ZodString>;
21
+ }, z.core.$strict>;
22
+ export type OrganizationDeletedEventPayload = z.infer<typeof OrganizationDeletedEventSchema>;
23
+ export type ProjectDeletedEventPayload = z.infer<typeof ProjectDeletedEventSchema>;
24
+ export type UserDeletedEventPayload = z.infer<typeof UserDeletedEventSchema>;
25
+ //# sourceMappingURL=lifecycle-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-events.d.ts","sourceRoot":"","sources":["../../../src/lifecycle-events/lib/lifecycle-events.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,oBAAY,kBAAkB;IAE5B,mBAAmB,sCAAsC;IAEzD,cAAc,4BAA4B;IAS1C,WAAW,sBAAsB;CAClC;AAGD,eAAO,MAAM,+BAA+B,EAAG,wBAAiC,CAAC;AAGjF,eAAO,MAAM,8BAA8B,EACzC,gCAAyC,CAAC;AAG5C,eAAO,MAAM,8BAA8B,EAAG,OAAgB,CAAC;AAO/D,eAAO,MAAM,8BAA8B;;kBAIhC,CAAC;AAOZ,eAAO,MAAM,yBAAyB;;;;kBAM3B,CAAC;AAOZ,eAAO,MAAM,sBAAsB;;;kBAKxB,CAAC;AAEZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CACnD,OAAO,8BAA8B,CACtC,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAC9C,OAAO,yBAAyB,CACjC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserDeletedEventSchema = exports.ProjectDeletedEventSchema = exports.OrganizationDeletedEventSchema = exports.LIFECYCLE_EVENT_SCHEMA_VERSION = exports.PROJECT_LIFECYCLE_EVENT_SOURCE = exports.IDENTITY_LIFECYCLE_EVENT_SOURCE = exports.LifecycleEventType = void 0;
4
+ const zod_1 = require("zod");
5
+ var LifecycleEventType;
6
+ (function (LifecycleEventType) {
7
+ LifecycleEventType["OrganizationDeleted"] = "organization.organization.deleted";
8
+ LifecycleEventType["ProjectDeleted"] = "project.project.deleted";
9
+ LifecycleEventType["UserDeleted"] = "user.user.deleted";
10
+ })(LifecycleEventType || (exports.LifecycleEventType = LifecycleEventType = {}));
11
+ exports.IDENTITY_LIFECYCLE_EVENT_SOURCE = '/services/identity-api';
12
+ exports.PROJECT_LIFECYCLE_EVENT_SOURCE = '/services/project-registry-api';
13
+ exports.LIFECYCLE_EVENT_SCHEMA_VERSION = '1.0.0';
14
+ exports.OrganizationDeletedEventSchema = zod_1.z
15
+ .object({
16
+ id: zod_1.z.string(),
17
+ })
18
+ .strict();
19
+ exports.ProjectDeletedEventSchema = zod_1.z
20
+ .object({
21
+ id: zod_1.z.string(),
22
+ orgId: zod_1.z.string(),
23
+ projectId: zod_1.z.string(),
24
+ })
25
+ .strict();
26
+ exports.UserDeletedEventSchema = zod_1.z
27
+ .object({
28
+ id: zod_1.z.string(),
29
+ orgId: zod_1.z.string().optional(),
30
+ })
31
+ .strict();
32
+ //# sourceMappingURL=lifecycle-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-events.js","sourceRoot":"","sources":["../../../src/lifecycle-events/lib/lifecycle-events.ts"],"names":[],"mappings":";;;AA2BA,6BAAwB;AAOxB,IAAY,kBAcX;AAdD,WAAY,kBAAkB;IAE5B,+EAAyD,CAAA;IAEzD,gEAA0C,CAAA;IAS1C,uDAAiC,CAAA;AACnC,CAAC,EAdW,kBAAkB,kCAAlB,kBAAkB,QAc7B;AAGY,QAAA,+BAA+B,GAAG,wBAAiC,CAAC;AAGpE,QAAA,8BAA8B,GACzC,gCAAyC,CAAC;AAG/B,QAAA,8BAA8B,GAAG,OAAgB,CAAC;AAOlD,QAAA,8BAA8B,GAAG,OAAC;KAC5C,MAAM,CAAC;IACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;CACf,CAAC;KACD,MAAM,EAAE,CAAC;AAOC,QAAA,yBAAyB,GAAG,OAAC;KACvC,MAAM,CAAC;IACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;IACjB,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;CACtB,CAAC;KACD,MAAM,EAAE,CAAC;AAOC,QAAA,sBAAsB,GAAG,OAAC;KACpC,MAAM,CAAC;IACN,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE;IACd,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC"}
@@ -4,4 +4,6 @@ export * from './lib/resource-declaration';
4
4
  export * from './lib/xema-manifest';
5
5
  export * from './lib/stack';
6
6
  export * from './lib/plan';
7
+ export * from './lib/resource-ownership-contribution';
8
+ export * from './lib/resource-ref';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resource/index.ts"],"names":[],"mappings":"AAgBA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resource/index.ts"],"names":[],"mappings":"AAqBA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,uCAAuC,CAAC;AACtD,cAAc,oBAAoB,CAAC"}
@@ -20,4 +20,6 @@ __exportStar(require("./lib/resource-declaration"), exports);
20
20
  __exportStar(require("./lib/xema-manifest"), exports);
21
21
  __exportStar(require("./lib/stack"), exports);
22
22
  __exportStar(require("./lib/plan"), exports);
23
+ __exportStar(require("./lib/resource-ownership-contribution"), exports);
24
+ __exportStar(require("./lib/resource-ref"), exports);
23
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resource/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAgBA,sDAAoC;AACpC,4DAA0C;AAC1C,6DAA2C;AAC3C,sDAAoC;AACpC,8CAA4B;AAC5B,6CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resource/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAqBA,sDAAoC;AACpC,4DAA0C;AAC1C,6DAA2C;AAC3C,sDAAoC;AACpC,8CAA4B;AAC5B,6CAA2B;AAC3B,wEAAsD;AACtD,qDAAmC"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { SubjectKind } from '../../subject';
3
+ export declare enum ResourceVisibilityPattern {
4
+ OwnerOnly = "owner-only",
5
+ OrgShared = "org-shared",
6
+ ProjectShared = "project-shared",
7
+ SpaceShared = "space-shared",
8
+ ExplicitShare = "explicit-share"
9
+ }
10
+ export declare const ResourceVisibilityPatternSchema: z.ZodEnum<typeof ResourceVisibilityPattern>;
11
+ export interface OwnerRef {
12
+ readonly kind: SubjectKind;
13
+ readonly ref: string;
14
+ }
15
+ export declare const OwnerRefSchema: z.ZodType<OwnerRef>;
16
+ export interface ExplicitShareRef {
17
+ readonly kind: SubjectKind;
18
+ readonly ref: string;
19
+ }
20
+ export declare const ExplicitShareRefSchema: z.ZodType<ExplicitShareRef>;
21
+ export interface ResourceOwnershipContributionManifest {
22
+ readonly resourceType: string;
23
+ readonly resourceId: string;
24
+ readonly visibility: ResourceVisibilityPattern;
25
+ readonly owners: readonly OwnerRef[];
26
+ readonly explicitShares?: readonly ExplicitShareRef[];
27
+ }
28
+ export declare const ResourceOwnershipContributionManifestSchema: z.ZodType<ResourceOwnershipContributionManifest>;
29
+ //# sourceMappingURL=resource-ownership-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-ownership-contribution.d.ts","sourceRoot":"","sources":["../../../src/resource/lib/resource-ownership-contribution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAqB,MAAM,eAAe,CAAC;AA0B/D,oBAAY,yBAAyB;IAEnC,SAAS,eAAe;IAExB,SAAS,eAAe;IAExB,aAAa,mBAAmB;IAEhC,WAAW,iBAAiB;IAE5B,aAAa,mBAAmB;CACjC;AAED,eAAO,MAAM,+BAA+B,6CAE3C,CAAC;AAQF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAGtB,CAAC;AAS1B,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,sBAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAG9B,CAAC;AAgBlC,MAAM,WAAW,qCAAqC;IAEpD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC;IAE/C,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IAMrC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACvD;AASD,eAAO,MAAM,2CAA2C,EAAE,CAAC,CAAC,OAAO,CAAC,qCAAqC,CAUjD,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResourceOwnershipContributionManifestSchema = exports.ExplicitShareRefSchema = exports.OwnerRefSchema = exports.ResourceVisibilityPatternSchema = exports.ResourceVisibilityPattern = void 0;
4
+ const zod_1 = require("zod");
5
+ const subject_1 = require("../../subject");
6
+ const RESOURCE_IDENTIFIER_MAX = 200;
7
+ const RESOURCE_PRINCIPALS_MAX = 100;
8
+ var ResourceVisibilityPattern;
9
+ (function (ResourceVisibilityPattern) {
10
+ ResourceVisibilityPattern["OwnerOnly"] = "owner-only";
11
+ ResourceVisibilityPattern["OrgShared"] = "org-shared";
12
+ ResourceVisibilityPattern["ProjectShared"] = "project-shared";
13
+ ResourceVisibilityPattern["SpaceShared"] = "space-shared";
14
+ ResourceVisibilityPattern["ExplicitShare"] = "explicit-share";
15
+ })(ResourceVisibilityPattern || (exports.ResourceVisibilityPattern = ResourceVisibilityPattern = {}));
16
+ exports.ResourceVisibilityPatternSchema = zod_1.z.nativeEnum(ResourceVisibilityPattern);
17
+ exports.OwnerRefSchema = zod_1.z.object({
18
+ kind: subject_1.SubjectKindSchema,
19
+ ref: zod_1.z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
20
+ });
21
+ exports.ExplicitShareRefSchema = zod_1.z.object({
22
+ kind: subject_1.SubjectKindSchema,
23
+ ref: zod_1.z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
24
+ });
25
+ exports.ResourceOwnershipContributionManifestSchema = zod_1.z.object({
26
+ resourceType: zod_1.z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
27
+ resourceId: zod_1.z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
28
+ visibility: exports.ResourceVisibilityPatternSchema,
29
+ owners: zod_1.z.array(exports.OwnerRefSchema).min(1).max(RESOURCE_PRINCIPALS_MAX),
30
+ explicitShares: zod_1.z
31
+ .array(exports.ExplicitShareRefSchema)
32
+ .max(RESOURCE_PRINCIPALS_MAX)
33
+ .optional(),
34
+ });
35
+ //# sourceMappingURL=resource-ownership-contribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-ownership-contribution.js","sourceRoot":"","sources":["../../../src/resource/lib/resource-ownership-contribution.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,2CAA+D;AAO/D,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAQpC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAWpC,IAAY,yBAWX;AAXD,WAAY,yBAAyB;IAEnC,qDAAwB,CAAA;IAExB,qDAAwB,CAAA;IAExB,6DAAgC,CAAA;IAEhC,yDAA4B,CAAA;IAE5B,6DAAgC,CAAA;AAClC,CAAC,EAXW,yBAAyB,yCAAzB,yBAAyB,QAWpC;AAEY,QAAA,+BAA+B,GAAG,OAAC,CAAC,UAAU,CACzD,yBAAyB,CAC1B,CAAC;AAaW,QAAA,cAAc,GAAwB,OAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,EAAE,2BAAiB;IACvB,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;CACpD,CAAwB,CAAC;AAcb,QAAA,sBAAsB,GAAgC,OAAC,CAAC,MAAM,CAAC;IAC1E,IAAI,EAAE,2BAAiB;IACvB,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;CACpD,CAAgC,CAAC;AAwCrB,QAAA,2CAA2C,GACtD,OAAC,CAAC,MAAM,CAAC;IACP,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAC5D,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAC1D,UAAU,EAAE,uCAA+B;IAC3C,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,sBAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC;IACnE,cAAc,EAAE,OAAC;SACd,KAAK,CAAC,8BAAsB,CAAC;SAC7B,GAAG,CAAC,uBAAuB,CAAC;SAC5B,QAAQ,EAAE;CACd,CAAqD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const RESOURCE_REF_PREFIX: "resource";
2
+ export declare const RESOURCE_REF_DELIMITER: ":";
3
+ export interface ResourceRefParts {
4
+ readonly type: string;
5
+ readonly id: string;
6
+ }
7
+ export declare function composeResourceRef(type: string, id: string): string;
8
+ export declare function parseResourceRef(ref: string): ResourceRefParts;
9
+ //# sourceMappingURL=resource-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-ref.d.ts","sourceRoot":"","sources":["../../../src/resource/lib/resource-ref.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,mBAAmB,EAAG,UAAmB,CAAC;AAGvD,eAAO,MAAM,sBAAsB,EAAG,GAAY,CAAC;AAKnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAiBnE;AAQD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAkB9D"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RESOURCE_REF_DELIMITER = exports.RESOURCE_REF_PREFIX = void 0;
4
+ exports.composeResourceRef = composeResourceRef;
5
+ exports.parseResourceRef = parseResourceRef;
6
+ exports.RESOURCE_REF_PREFIX = 'resource';
7
+ exports.RESOURCE_REF_DELIMITER = ':';
8
+ function composeResourceRef(type, id) {
9
+ if (type.length === 0 || id.length === 0) {
10
+ throw new Error(`Invalid resource ref segments: "type" and "id" must both be non-empty (got type="${type}", id="${id}").`);
11
+ }
12
+ if (type.includes(exports.RESOURCE_REF_DELIMITER)) {
13
+ throw new Error(`Invalid resource type "${type}": must not contain the "${exports.RESOURCE_REF_DELIMITER}" delimiter.`);
14
+ }
15
+ if (id.includes(exports.RESOURCE_REF_DELIMITER)) {
16
+ throw new Error(`Invalid resource id "${id}": must not contain the "${exports.RESOURCE_REF_DELIMITER}" delimiter.`);
17
+ }
18
+ return `${exports.RESOURCE_REF_PREFIX}${exports.RESOURCE_REF_DELIMITER}${type}${exports.RESOURCE_REF_DELIMITER}${id}`;
19
+ }
20
+ function parseResourceRef(ref) {
21
+ const [prefix, type, id, ...rest] = ref.split(exports.RESOURCE_REF_DELIMITER);
22
+ if (rest.length > 0 || prefix === undefined || type === undefined || id === undefined) {
23
+ throw new Error(`Invalid resource ref "${ref}": expected exactly "${exports.RESOURCE_REF_PREFIX}:<type>:<id>".`);
24
+ }
25
+ if (prefix !== exports.RESOURCE_REF_PREFIX) {
26
+ throw new Error(`Invalid resource ref "${ref}": must start with the "${exports.RESOURCE_REF_PREFIX}" prefix.`);
27
+ }
28
+ if (type.length === 0 || id.length === 0) {
29
+ throw new Error(`Invalid resource ref "${ref}": "type" and "id" segments must both be non-empty.`);
30
+ }
31
+ return { type, id };
32
+ }
33
+ //# sourceMappingURL=resource-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-ref.js","sourceRoot":"","sources":["../../../src/resource/lib/resource-ref.ts"],"names":[],"mappings":";;;AA+BA,gDAiBC;AAQD,4CAkBC;AA7DY,QAAA,mBAAmB,GAAG,UAAmB,CAAC;AAG1C,QAAA,sBAAsB,GAAG,GAAY,CAAC;AAenD,SAAgB,kBAAkB,CAAC,IAAY,EAAE,EAAU;IACzD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,oFAAoF,IAAI,UAAU,EAAE,KAAK,CAC1G,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,8BAAsB,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,4BAA4B,8BAAsB,cAAc,CAC/F,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,QAAQ,CAAC,8BAAsB,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,wBAAwB,EAAE,4BAA4B,8BAAsB,cAAc,CAC3F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,2BAAmB,GAAG,8BAAsB,GAAG,IAAI,GAAG,8BAAsB,GAAG,EAAE,EAAE,CAAC;AAChG,CAAC;AAQD,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,8BAAsB,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACtF,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,wBAAwB,2BAAmB,gBAAgB,CACxF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,2BAAmB,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,2BAA2B,2BAAmB,WAAW,CACtF,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,qDAAqD,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACtB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/kernel-contracts",
3
- "version": "0.16.2",
3
+ "version": "0.18.0",
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/",
@@ -122,6 +122,21 @@ export enum ContributionKind {
122
122
  */
123
123
  Capability = 'capability',
124
124
 
125
+ // -- Phase 5: resource-ownership self-registration -----------------------
126
+ /**
127
+ * A resource-instance ownership/visibility declaration contributed by a
128
+ * biome — `resourceType` + `resourceId` + a `ResourceVisibilityPattern` +
129
+ * the owning subjects (and optional explicit shares). The kernel owns this
130
+ * enum member AND the manifest schema
131
+ * (`ResourceOwnershipContributionManifestSchema`, exported from
132
+ * `@xemahq/kernel-contracts/resource`), mirroring the `Capability` kind: a
133
+ * single value-identical wire shape both the contribution-file parser and
134
+ * the owning domain service validate fail-fast. Provenance is stamped by the
135
+ * parser from the discovering biome's manifest — authors do not declare it
136
+ * inline.
137
+ */
138
+ ResourceOwnership = 'resource-ownership',
139
+
125
140
  // -- Domain stage machines (MailOps asset lifecycle) ---------------------
126
141
  /**
127
142
  * A deterministic asset stage machine contributed by a domain biome to a
@@ -0,0 +1 @@
1
+ export * from './lib/lifecycle-events';
@@ -0,0 +1,103 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // ── Canonical platform lifecycle-deletion event contracts ──
3
+ //
4
+ // `organization.organization.deleted`, `project.project.deleted`, and
5
+ // `identity.user.deleted` are the three CANONICAL cascade-cleanup signals every
6
+ // stateful biome subscribes to. Before this contract existed, each of the
7
+ // ~14 consumers hand-re-declared the same `type` string, `source`, and payload
8
+ // `data` shape in its own `consumed-events.registry.ts` — drift waiting to
9
+ // happen on a producer-side change.
10
+ //
11
+ // These contracts live in the KERNEL (Layer 0) so a subscriber depends on the
12
+ // kernel package, never on the producer service. The producers
13
+ // (`project-registry-api` for project, `identity-api` for org + user) import
14
+ // the SAME enum + schema to emit; subscribers import them to match — one source
15
+ // of truth, zero service-to-service code coupling. This mirrors the
16
+ // search-source / mail-source registries (`@xemahq/kernel-contracts/*`) that
17
+ // let a consumer act on any producer's events without importing its client.
18
+ //
19
+ // NOTE: This subpath holds the type strings + payload schemas ONLY. The
20
+ // descriptor wrapper (`defineEvent(...)`) lives in the Layer-1 runtime package
21
+ // `@xemahq/events`, which Layer 0 must not depend on. A consumer keeps its
22
+ // `defineEvent({ type: ..., data: ... })` call but sources the `type` from
23
+ // `LifecycleEventType` and the `data` from these schemas instead of re-typing
24
+ // them. Do not change a `type` string without a coordinated migration — every
25
+ // other service matches on it.
26
+ // ═══════════════════════════════════════════════════════════════════════════
27
+
28
+ import { z } from 'zod';
29
+
30
+ /**
31
+ * Closed set of canonical platform lifecycle-deletion event `type`s. These are
32
+ * the wire identifiers consumers subscribe to for cascade cleanup — never a
33
+ * free-form string at a call site.
34
+ */
35
+ export enum LifecycleEventType {
36
+ /** An organization was deleted — cascade-delete all of the org's data. */
37
+ OrganizationDeleted = 'organization.organization.deleted',
38
+ /** A project was deleted — cascade-delete all project-scoped data. */
39
+ ProjectDeleted = 'project.project.deleted',
40
+ /**
41
+ * A user was deleted — cascade-delete that user's user-scoped data.
42
+ *
43
+ * The wire string is `user.user.deleted` — the value identity-api (the
44
+ * producer) actually emits (`WebhookEvents.USER_DELETED`). The lone
45
+ * consumer that today declares `identity.user.deleted` (memory-api) never
46
+ * fires on a real delete; adopting this descriptor fixes that mismatch.
47
+ */
48
+ UserDeleted = 'user.user.deleted',
49
+ }
50
+
51
+ /** Producer URI of the org + user deletion events (identity is the source). */
52
+ export const IDENTITY_LIFECYCLE_EVENT_SOURCE = '/services/identity-api' as const;
53
+
54
+ /** Producer URI of the project deletion event. */
55
+ export const PROJECT_LIFECYCLE_EVENT_SOURCE =
56
+ '/services/project-registry-api' as const;
57
+
58
+ /** Schema version stamped on every canonical lifecycle-deletion event. */
59
+ export const LIFECYCLE_EVENT_SCHEMA_VERSION = '1.0.0' as const;
60
+
61
+ /**
62
+ * `organization.organization.deleted` payload. Identity emits only the org id;
63
+ * the org id also rides the envelope's `ehorgid` extension, so consumers that
64
+ * scope by extension never even read the body.
65
+ */
66
+ export const OrganizationDeletedEventSchema = z
67
+ .object({
68
+ id: z.string(),
69
+ })
70
+ .strict();
71
+
72
+ /**
73
+ * `project.project.deleted` payload. Canonical cascade signal — carries the
74
+ * full project triple so a consumer can scope deletes by `orgId` and/or
75
+ * `projectId` without a lookup.
76
+ */
77
+ export const ProjectDeletedEventSchema = z
78
+ .object({
79
+ id: z.string(),
80
+ orgId: z.string(),
81
+ projectId: z.string(),
82
+ })
83
+ .strict();
84
+
85
+ /**
86
+ * `identity.user.deleted` payload. `orgId` is optional because a user is a
87
+ * cross-org subject; an org-scoped consumer reads `ehorgid` from the envelope
88
+ * to bound the cascade to its own org.
89
+ */
90
+ export const UserDeletedEventSchema = z
91
+ .object({
92
+ id: z.string(),
93
+ orgId: z.string().optional(),
94
+ })
95
+ .strict();
96
+
97
+ export type OrganizationDeletedEventPayload = z.infer<
98
+ typeof OrganizationDeletedEventSchema
99
+ >;
100
+ export type ProjectDeletedEventPayload = z.infer<
101
+ typeof ProjectDeletedEventSchema
102
+ >;
103
+ export type UserDeletedEventPayload = z.infer<typeof UserDeletedEventSchema>;
@@ -7,11 +7,16 @@
7
7
  // the `XemaManifest` (`xema.yaml`) document, plus the server-side `Stack` state
8
8
  // and the `ResourcePlan` diff vocabulary.
9
9
  //
10
- // A DAG LEAF on purpose: per-kind `spec` bodies are validated by the owning
11
- // domain service (which holds the authoritative DTO), so this surface drags no
12
- // cross-subpath dependency into the kernel. The Terraform provider, the first-
13
- // party `xema.yaml` apply, and the frontend all converge on these contracts.
14
- // Zero runtime deps beyond `zod`.
10
+ // Per-kind `spec` bodies are validated by the owning domain service (which
11
+ // holds the authoritative DTO), so the IaC surface drags no cross-subpath
12
+ // dependency into the kernel. The Terraform provider, the first-party
13
+ // `xema.yaml` apply, and the frontend all converge on these contracts.
14
+ //
15
+ // This subpath also carries the resource-OWNERSHIP contribution contract (the
16
+ // `ContributionKind.ResourceOwnership` manifest + visibility enum) and the
17
+ // `resource:<type>:<id>` ref grammar. The ownership manifest reuses the kernel
18
+ // `SubjectKind` taxonomy, so this surface declares exactly ONE cross-subpath
19
+ // edge (`resource -> subject`). Zero runtime deps beyond `zod`.
15
20
  // ═══════════════════════════════════════════════════════════════════════════
16
21
 
17
22
  export * from './lib/resource-kind';
@@ -20,3 +25,5 @@ export * from './lib/resource-declaration';
20
25
  export * from './lib/xema-manifest';
21
26
  export * from './lib/stack';
22
27
  export * from './lib/plan';
28
+ export * from './lib/resource-ownership-contribution';
29
+ export * from './lib/resource-ref';
@@ -0,0 +1,127 @@
1
+ import { z } from 'zod';
2
+
3
+ import { SubjectKind, SubjectKindSchema } from '../../subject';
4
+
5
+ /**
6
+ * Maximum length of the `resourceType` / `resourceId` identifier strings on a
7
+ * resource-ownership manifest. Bounded so describe/list responses stay small
8
+ * and persisted rows have a predictable upper size.
9
+ */
10
+ const RESOURCE_IDENTIFIER_MAX = 200;
11
+
12
+ /**
13
+ * Hard cap on the number of owners / explicit shares carried by a single
14
+ * resource-ownership manifest. Keeps a contribution envelope bounded; a
15
+ * resource that genuinely needs more sharees is a design smell (use an
16
+ * org/project-shared visibility instead of enumerating principals).
17
+ */
18
+ const RESOURCE_PRINCIPALS_MAX = 100;
19
+
20
+ /**
21
+ * `ResourceVisibilityPattern` — the closed set of ownership/visibility shapes a
22
+ * biome may declare for a resource instance it contributes (plan §6 Phase 5).
23
+ *
24
+ * Precedence is NOT encoded here — this enum only names HOW a resource is
25
+ * shared; the PDP in `authorization-api` derives the effective verdict from the
26
+ * declared pattern plus the invocation's subject/scope. A closed set so the
27
+ * OpenAPI/zod schema stays a stable enum (never a free-form string).
28
+ */
29
+ export enum ResourceVisibilityPattern {
30
+ /** Visible only to the declared owner subject(s). */
31
+ OwnerOnly = 'owner-only',
32
+ /** Visible to every member of the owning organization. */
33
+ OrgShared = 'org-shared',
34
+ /** Visible to every member of the owning project. */
35
+ ProjectShared = 'project-shared',
36
+ /** Visible to every member of the owning space. */
37
+ SpaceShared = 'space-shared',
38
+ /** Visible only to the subjects enumerated in `explicitShares`. */
39
+ ExplicitShare = 'explicit-share',
40
+ }
41
+
42
+ export const ResourceVisibilityPatternSchema = z.nativeEnum(
43
+ ResourceVisibilityPattern,
44
+ );
45
+
46
+ /**
47
+ * `OwnerRef` — a pointer to a subject that owns (or is explicitly shared) a
48
+ * resource. Reuses the kernel `SubjectKind` taxonomy so a resource may be owned
49
+ * by a user, an agent, a service account, a group, etc. `ref` is the bare
50
+ * per-kind identifier (mirrors `SubjectRef.id`), NOT a `kind:id` composite.
51
+ */
52
+ export interface OwnerRef {
53
+ readonly kind: SubjectKind;
54
+ readonly ref: string;
55
+ }
56
+
57
+ export const OwnerRefSchema: z.ZodType<OwnerRef> = z.object({
58
+ kind: SubjectKindSchema,
59
+ ref: z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
60
+ }) as z.ZodType<OwnerRef>;
61
+
62
+ /**
63
+ * `ExplicitShareRef` — one entry in a manifest's `explicitShares` list. Only
64
+ * meaningful when `visibility` is `ResourceVisibilityPattern.ExplicitShare`;
65
+ * it names a subject the resource is shared with (the same shape as
66
+ * `OwnerRef`, kept as its own type so a future per-share grant level can be
67
+ * added without churning every owner site).
68
+ */
69
+ export interface ExplicitShareRef {
70
+ readonly kind: SubjectKind;
71
+ readonly ref: string;
72
+ }
73
+
74
+ export const ExplicitShareRefSchema: z.ZodType<ExplicitShareRef> = z.object({
75
+ kind: SubjectKindSchema,
76
+ ref: z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
77
+ }) as z.ZodType<ExplicitShareRef>;
78
+
79
+ /**
80
+ * Manifest shape carried by every `ContributionKind.ResourceOwnership`
81
+ * envelope (plan §6 Phase 5). One contribution = one resource instance's
82
+ * ownership/visibility declaration.
83
+ *
84
+ * Mirrors `CapabilityContributionManifest` precisely: a value-identical subset
85
+ * of the wire body the owning domain service accepts, validated fail-fast at
86
+ * biome-discovery time. Provenance (`biome.id`, `biome.version`) is NOT a field
87
+ * here — the `CapabilityParser`-equivalent stamps it from the discovering
88
+ * biome's `xema-biome.json`. Authors do not declare provenance inline.
89
+ *
90
+ * Validation is fail-fast: a contribution that violates any constraint is
91
+ * rejected at boot. No silent coercion.
92
+ */
93
+ export interface ResourceOwnershipContributionManifest {
94
+ /** The resource type slug (e.g. `document`, `dataset`). ≤ 200 chars. */
95
+ readonly resourceType: string;
96
+ /** The resource instance id within `resourceType`. ≤ 200 chars. */
97
+ readonly resourceId: string;
98
+ /** How the resource is shared — see `ResourceVisibilityPattern`. */
99
+ readonly visibility: ResourceVisibilityPattern;
100
+ /** The owning subject(s). At least one; hard-capped at 100. */
101
+ readonly owners: readonly OwnerRef[];
102
+ /**
103
+ * Subjects the resource is explicitly shared with. Only meaningful when
104
+ * `visibility` is `ResourceVisibilityPattern.ExplicitShare`. Hard-capped at
105
+ * 100. Omitted (not `[]`) when no explicit shares apply.
106
+ */
107
+ readonly explicitShares?: readonly ExplicitShareRef[];
108
+ }
109
+
110
+ /**
111
+ * Zod validator for `ResourceOwnershipContributionManifest`. The
112
+ * biome-discovery parser AND the owning domain service's wire DTO BOTH route
113
+ * every candidate envelope through this schema, so a malformed contribution
114
+ * fails at the boundary instead of at the wire (mirrors
115
+ * `CapabilityContributionManifestSchema`).
116
+ */
117
+ export const ResourceOwnershipContributionManifestSchema: z.ZodType<ResourceOwnershipContributionManifest> =
118
+ z.object({
119
+ resourceType: z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
120
+ resourceId: z.string().min(1).max(RESOURCE_IDENTIFIER_MAX),
121
+ visibility: ResourceVisibilityPatternSchema,
122
+ owners: z.array(OwnerRefSchema).min(1).max(RESOURCE_PRINCIPALS_MAX),
123
+ explicitShares: z
124
+ .array(ExplicitShareRefSchema)
125
+ .max(RESOURCE_PRINCIPALS_MAX)
126
+ .optional(),
127
+ }) as z.ZodType<ResourceOwnershipContributionManifest>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Resource-instance ref grammar — the canonical composite string for a single
3
+ * resource instance: `resource:<type>:<id>`.
4
+ *
5
+ * Mirrors the subject-ref grammar (`subjectRefToString` / `parseSubjectRef`)
6
+ * but is FIXED-arity: exactly three colon-delimited segments. Because the id
7
+ * sits in the final segment AND we forbid the delimiter inside both `type` and
8
+ * `id`, the encoding is unambiguous and losslessly round-trips — no
9
+ * split-on-first-colon ambiguity. Fail-fast on any malformed input; never
10
+ * silently coerce.
11
+ */
12
+
13
+ /** The fixed prefix every resource ref carries. */
14
+ export const RESOURCE_REF_PREFIX = 'resource' as const;
15
+
16
+ /** The segment delimiter. Forbidden inside `type` and `id`. */
17
+ export const RESOURCE_REF_DELIMITER = ':' as const;
18
+
19
+ /**
20
+ * Parsed form of a resource ref.
21
+ */
22
+ export interface ResourceRefParts {
23
+ readonly type: string;
24
+ readonly id: string;
25
+ }
26
+
27
+ /**
28
+ * Compose `resource:<type>:<id>` from a type + id. Fail-fast if either segment
29
+ * is empty or contains the `:` delimiter (which would make the ref ambiguous /
30
+ * un-round-trippable). Never coerce — an invalid segment throws.
31
+ */
32
+ export function composeResourceRef(type: string, id: string): string {
33
+ if (type.length === 0 || id.length === 0) {
34
+ throw new Error(
35
+ `Invalid resource ref segments: "type" and "id" must both be non-empty (got type="${type}", id="${id}").`,
36
+ );
37
+ }
38
+ if (type.includes(RESOURCE_REF_DELIMITER)) {
39
+ throw new Error(
40
+ `Invalid resource type "${type}": must not contain the "${RESOURCE_REF_DELIMITER}" delimiter.`,
41
+ );
42
+ }
43
+ if (id.includes(RESOURCE_REF_DELIMITER)) {
44
+ throw new Error(
45
+ `Invalid resource id "${id}": must not contain the "${RESOURCE_REF_DELIMITER}" delimiter.`,
46
+ );
47
+ }
48
+ return `${RESOURCE_REF_PREFIX}${RESOURCE_REF_DELIMITER}${type}${RESOURCE_REF_DELIMITER}${id}`;
49
+ }
50
+
51
+ /**
52
+ * Parse `resource:<type>:<id>` back into its parts. Fail-fast on a wrong
53
+ * prefix, wrong arity, or an empty segment. The inverse of
54
+ * `composeResourceRef` — any string that `composeResourceRef` produced parses
55
+ * back to the identical `{ type, id }`.
56
+ */
57
+ export function parseResourceRef(ref: string): ResourceRefParts {
58
+ const [prefix, type, id, ...rest] = ref.split(RESOURCE_REF_DELIMITER);
59
+ if (rest.length > 0 || prefix === undefined || type === undefined || id === undefined) {
60
+ throw new Error(
61
+ `Invalid resource ref "${ref}": expected exactly "${RESOURCE_REF_PREFIX}:<type>:<id>".`,
62
+ );
63
+ }
64
+ if (prefix !== RESOURCE_REF_PREFIX) {
65
+ throw new Error(
66
+ `Invalid resource ref "${ref}": must start with the "${RESOURCE_REF_PREFIX}" prefix.`,
67
+ );
68
+ }
69
+ if (type.length === 0 || id.length === 0) {
70
+ throw new Error(
71
+ `Invalid resource ref "${ref}": "type" and "id" segments must both be non-empty.`,
72
+ );
73
+ }
74
+ return { type, id };
75
+ }