@opengeni/contracts 4.1.0 → 5.0.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 (69) hide show
  1. package/dist/atlassian.d.ts +1 -0
  2. package/dist/atlassian.js +4 -4
  3. package/dist/bundled-skills.d.ts +5 -1
  4. package/dist/{chunk-HR6NB3CA.js → chunk-CM7E7PFV.js} +8341 -8206
  5. package/dist/chunk-CM7E7PFV.js.map +1 -0
  6. package/dist/{chunk-O5LEQHDM.js → chunk-ENJTPHKP.js} +2 -2
  7. package/dist/chunk-KUCZDFJ5.js +186 -0
  8. package/dist/chunk-KUCZDFJ5.js.map +1 -0
  9. package/dist/{chunk-5LYFSZ7O.js → chunk-YJEOWXOE.js} +8 -8
  10. package/dist/company-profile.d.ts +9 -6
  11. package/dist/connect.js +4 -4
  12. package/dist/connection-authority.d.ts +9 -317
  13. package/dist/connection-authority.js +7 -27
  14. package/dist/connector-tool-permissions.d.ts +73 -0
  15. package/dist/editable-artifact-codec-registry.js +2 -2
  16. package/dist/editable-artifact-live.js +2 -2
  17. package/dist/editable-artifact-serialized-commit.js +3 -3
  18. package/dist/editable-artifacts.js +13 -13
  19. package/dist/google-drive.d.ts +1 -0
  20. package/dist/google-drive.js +4 -4
  21. package/dist/host-mcp-bindings.d.ts +5 -0
  22. package/dist/host-mcp-bindings.js +34 -8
  23. package/dist/host-mcp-bindings.js.map +1 -1
  24. package/dist/index.d.ts +771 -3222
  25. package/dist/index.js +121 -75
  26. package/dist/knowledge-entries.d.ts +33 -0
  27. package/dist/knowledge-preparation.d.ts +207 -0
  28. package/dist/managed-sign-in-methods.d.ts +56 -0
  29. package/dist/managed-sign-in-methods.js +46 -0
  30. package/dist/managed-sign-in-methods.js.map +1 -0
  31. package/dist/mcp-oauth.d.ts +2 -2
  32. package/dist/organization-integration-policy.d.ts +27 -0
  33. package/dist/organization-usage.d.ts +102 -0
  34. package/dist/personal-github.d.ts +1 -0
  35. package/dist/personal-github.js +4 -4
  36. package/dist/remember.d.ts +6 -4
  37. package/dist/sandbox-provider-command.d.ts +91 -1
  38. package/dist/sandbox-recovery.d.ts +101 -0
  39. package/dist/session-goal-reports.d.ts +21 -0
  40. package/dist/session-message-search.d.ts +68 -0
  41. package/dist/skill-catalog-context.d.ts +7 -0
  42. package/dist/skills.d.ts +15 -0
  43. package/package.json +4 -4
  44. package/src/bundled-skills.ts +2 -0
  45. package/src/connection-authority.ts +25 -225
  46. package/src/connector-tool-permissions.ts +59 -0
  47. package/src/host-mcp-bindings.ts +37 -5
  48. package/src/index.ts +406 -755
  49. package/src/knowledge-entries.ts +4 -0
  50. package/src/knowledge-preparation.ts +50 -0
  51. package/src/managed-sign-in-methods.ts +37 -0
  52. package/src/mcp-oauth.ts +16 -18
  53. package/src/organization-integration-policy.ts +54 -0
  54. package/src/organization-usage.ts +45 -0
  55. package/src/sandbox-provider-command.ts +57 -1
  56. package/src/sandbox-recovery.ts +61 -0
  57. package/src/session-goal-reports.ts +45 -0
  58. package/src/session-message-search.ts +54 -0
  59. package/src/skill-catalog-context.ts +50 -0
  60. package/src/skills.ts +21 -6
  61. package/dist/chunk-HR6NB3CA.js.map +0 -1
  62. package/dist/chunk-J6QIYKO5.js +0 -348
  63. package/dist/chunk-J6QIYKO5.js.map +0 -1
  64. package/dist/host-mcp-resolvers.d.ts +0 -32
  65. package/dist/host-mcp-resolvers.js +0 -34
  66. package/dist/host-mcp-resolvers.js.map +0 -1
  67. package/src/host-mcp-resolvers.ts +0 -50
  68. /package/dist/{chunk-O5LEQHDM.js.map → chunk-ENJTPHKP.js.map} +0 -0
  69. /package/dist/{chunk-5LYFSZ7O.js.map → chunk-YJEOWXOE.js.map} +0 -0
package/src/index.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export * from "./artifact-catalog";
2
+ export * from "./session-message-search";
3
+ export * from "./session-goal-reports";
4
+ import { SessionGoalReportRequirements } from "./session-goal-reports";
5
+ export * from "./organization-integration-policy";
2
6
  import { SkillReviewReference, skillReviewHumanInput } from "./skills";
3
7
  import { AgentLearningOverrides } from "./agent-learning";
4
8
  export * from "./skills";
@@ -810,6 +814,7 @@ export const FIRST_PARTY_MCP_TOOL_NAMES = [
810
814
  "goal_pause",
811
815
  "goal_resume",
812
816
  "knowledge_search",
817
+ "knowledge_prepare_save",
813
818
  "knowledge_get",
814
819
  "knowledge_browse",
815
820
  "knowledge_save",
@@ -1247,7 +1252,7 @@ export const UserResourceAuthoritySummary = z.object({
1247
1252
  });
1248
1253
  export const ListUserResourceAuthoritiesQuery = z.object({
1249
1254
  scope: UserResourceAuthorityScope,
1250
- resourceKind: UserResourceKind,
1255
+ resourceKind: UserResourceKind.exclude(["connection"]),
1251
1256
  cursor: z.string().uuid().optional(),
1252
1257
  limit: z.coerce.number().int().min(1).max(100).default(50),
1253
1258
  });
@@ -1259,7 +1264,7 @@ export const ListUserResourceAuthoritiesResponse = z.object({
1259
1264
  export const IssueUserResourceGrantRequest = z
1260
1265
  .object({
1261
1266
  scope: UserResourceAuthorityScope,
1262
- resourceKind: UserResourceKind,
1267
+ resourceKind: UserResourceKind.exclude(["connection"]),
1263
1268
  mode: ManagedUserResourceGrantMode,
1264
1269
  context: SessionTenancyVisibility,
1265
1270
  sessionId: z.string().uuid().nullable().optional(),
@@ -2056,6 +2061,7 @@ export type WorkspaceSessionDefaults = z.infer<typeof WorkspaceSessionDefaults>;
2056
2061
  */
2057
2062
  export const WorkspaceSessionToolDefaults = z
2058
2063
  .object({
2064
+ inheritConnectedMcpServers: z.boolean().optional(),
2059
2065
  mcpServerIds: z
2060
2066
  .array(z.string().trim().min(1).max(128))
2061
2067
  .max(128)
@@ -2073,6 +2079,8 @@ export type WorkspaceSessionToolDefaults = z.infer<typeof WorkspaceSessionToolDe
2073
2079
  // Omitted keys preserve the stored selection; null removes only that override.
2074
2080
  export const WorkspaceSessionToolDefaultsPatch = z
2075
2081
  .object({
2082
+ inheritConnectedMcpServers:
2083
+ WorkspaceSessionToolDefaults.shape.inheritConnectedMcpServers.nullable(),
2076
2084
  mcpServerIds: WorkspaceSessionToolDefaults.shape.mcpServerIds.nullable(),
2077
2085
  firstPartyMcpTools: WorkspaceSessionToolDefaults.shape.firstPartyMcpTools.nullable(),
2078
2086
  })
@@ -3432,6 +3440,8 @@ export type ListSlackUserLinkAccessRequestsResponse = z.infer<
3432
3440
  typeof ListSlackUserLinkAccessRequestsResponse
3433
3441
  >;
3434
3442
 
3443
+ export * from "./organization-usage";
3444
+
3435
3445
  export const UsageEventType = z.enum([
3436
3446
  "agent_run.created",
3437
3447
  "agent_run.completed",
@@ -4171,6 +4181,8 @@ export const McpServerConnectionRef = z
4171
4181
  .object({
4172
4182
  /** Opaque host or standalone connection identifier. */
4173
4183
  connectionId: z.string().min(1).optional(),
4184
+ /** Explicit native catalog selector. Never overrides an exact connection pin. */
4185
+ accountSelection: z.literal("all_eligible").optional(),
4174
4186
  /** Host-owned credential authority; omission keeps OpenGeni's native connection authority. */
4175
4187
  authoritySource: z.literal("host").optional(),
4176
4188
  /** Durable fixed reference, or an explicit configuration-only selector.
@@ -4197,6 +4209,19 @@ export const McpServerConnectionRef = z
4197
4209
  })
4198
4210
  .strict()
4199
4211
  .superRefine((reference, context) => {
4212
+ if (
4213
+ reference.accountSelection &&
4214
+ (reference.connectionId !== undefined ||
4215
+ reference.authoritySource === "host" ||
4216
+ reference.selectedResources !== undefined)
4217
+ ) {
4218
+ context.addIssue({
4219
+ code: "custom",
4220
+ path: ["accountSelection"],
4221
+ message:
4222
+ "An all-eligible selector cannot contain an exact connection, host authority, or selected resources",
4223
+ });
4224
+ }
4200
4225
  const acceptedTurn = reference.hostBinding && "selection" in reference.hostBinding;
4201
4226
  if (
4202
4227
  acceptedTurn &&
@@ -4244,6 +4269,8 @@ export type McpServerConnectionRef = z.infer<typeof McpServerConnectionRef>;
4244
4269
  export const McpPersonalConnectionDelegation = z
4245
4270
  .object({
4246
4271
  serverId: z.string().min(1).max(256),
4272
+ /** Canonical policy/catalog identity when serverId is an account route. */
4273
+ canonicalServerId: z.string().min(1).max(256).optional(),
4247
4274
  connectionId: z.string().uuid(),
4248
4275
  /**
4249
4276
  * Immutable physical workspace that owns an activated common-user
@@ -4257,9 +4284,9 @@ export const McpPersonalConnectionDelegation = z
4257
4284
  kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]).optional(),
4258
4285
  connectionType: z.enum(["mcp", "social", "atlassian", "github_personal"]).optional(),
4259
4286
  /**
4260
- * Explicit common-authority grant selected by the owning human. Omission is
4261
- * retained only for legacy_user connections that cannot yet participate in
4262
- * the organization-user authority lifecycle.
4287
+ * Historical receipt data only. This schema also reads persisted work from
4288
+ * before the sender-owned cutover. Current admission rejects this field;
4289
+ * provider execution requires the canonical sender snapshot, never this grant.
4263
4290
  */
4264
4291
  userDelegation: UserResourceDelegation.optional(),
4265
4292
  /**
@@ -4325,8 +4352,7 @@ export const McpPersonalConnectionDelegation = z
4325
4352
  delegation.serverId !== "github:personal" ||
4326
4353
  delegation.providerDomain !== "github.com" ||
4327
4354
  delegation.kind !== "oauth2" ||
4328
- !delegation.originWorkspaceId ||
4329
- !delegation.userDelegation
4355
+ !delegation.originWorkspaceId
4330
4356
  ) {
4331
4357
  context.addIssue({
4332
4358
  code: "custom",
@@ -4370,7 +4396,7 @@ export type McpPersonalConnectionDelegation = z.infer<typeof McpPersonalConnecti
4370
4396
 
4371
4397
  /**
4372
4398
  * Exact personal MCP authority frozen on one causal turn or scheduled task.
4373
- * One server can have at most one grant; bounded validation keeps corrupt JSON
4399
+ * One server can have at most one account; bounded validation keeps corrupt JSON
4374
4400
  * from becoming executable credential authority at a DB read boundary.
4375
4401
  */
4376
4402
  export const McpPersonalConnectionDelegations = z
@@ -4398,33 +4424,108 @@ export const McpPersonalConnectionSummary = z
4398
4424
  .strict();
4399
4425
  export type McpPersonalConnectionSummary = z.infer<typeof McpPersonalConnectionSummary>;
4400
4426
 
4427
+ /** Internal, server-resolved account route frozen with accepted work. It is
4428
+ * not a public credential grant and must never be accepted from a caller. */
4429
+ export const McpConnectionAccountBinding = z
4430
+ .object({
4431
+ serverId: z.string().min(1).max(256),
4432
+ canonicalServerId: z.string().min(1).max(256),
4433
+ connectionId: z.string().uuid(),
4434
+ originWorkspaceId: z.string().uuid(),
4435
+ subjectScope: z.enum(["workspace", "subject"]),
4436
+ ownerSubjectId: z.string().min(1).max(512).nullable(),
4437
+ accountLabel: z.string().min(1).max(512),
4438
+ providerDomain: z.string().min(1).max(2048),
4439
+ kind: z.enum(["oauth2", "api_key", "app_install", "delegated"]),
4440
+ connectionRef: McpServerConnectionRef,
4441
+ connectionAuthorityGeneration: z.number().int().positive().optional(),
4442
+ })
4443
+ .strict()
4444
+ .superRefine((binding, context) => {
4445
+ if (
4446
+ binding.connectionRef.authoritySource === "host" ||
4447
+ binding.connectionRef.connectionId !== binding.connectionId ||
4448
+ binding.connectionRef.subjectScope !== binding.subjectScope ||
4449
+ binding.connectionRef.providerDomain !== binding.providerDomain ||
4450
+ binding.connectionRef.kind !== binding.kind
4451
+ ) {
4452
+ context.addIssue({
4453
+ code: "custom",
4454
+ path: ["connectionRef"],
4455
+ message: "Account reference must match its frozen identity",
4456
+ });
4457
+ }
4458
+ if ((binding.subjectScope === "subject") !== (binding.ownerSubjectId !== null)) {
4459
+ context.addIssue({
4460
+ code: "custom",
4461
+ path: ["ownerSubjectId"],
4462
+ message: "Only personal account bindings retain an owner",
4463
+ });
4464
+ }
4465
+ });
4466
+ export type McpConnectionAccountBinding = z.infer<typeof McpConnectionAccountBinding>;
4467
+
4468
+ export const McpConnectionAccountBindings = z
4469
+ .array(McpConnectionAccountBinding)
4470
+ .max(128)
4471
+ .superRefine((bindings, context) => {
4472
+ const routes = new Set<string>();
4473
+ const accounts = new Set<string>();
4474
+ bindings.forEach((binding, index) => {
4475
+ const account = JSON.stringify([binding.canonicalServerId, binding.connectionId]);
4476
+ if (routes.has(binding.serverId) || accounts.has(account)) {
4477
+ context.addIssue({
4478
+ code: "custom",
4479
+ path: [index],
4480
+ message: "Account bindings require unique routes and connector-account pairs",
4481
+ });
4482
+ }
4483
+ routes.add(binding.serverId);
4484
+ accounts.add(account);
4485
+ });
4486
+ });
4487
+
4401
4488
  /**
4402
- * Public, credential-free selection of one exact personal connection grant for
4403
- * one selected MCP/first-party server. The owner is always derived server-side.
4489
+ * Account choice only. The authenticated sender supplies authority; selecting
4490
+ * an account never delegates it to another participant or conversation.
4404
4491
  */
4405
- export const McpConnectionAuthoritySelection = z
4492
+ export const McpConnectionAccountSelection = z
4406
4493
  .object({
4407
4494
  serverId: z.string().min(1).max(256),
4408
4495
  connectionId: z.string().uuid(),
4409
- userDelegation: UserResourceDelegation,
4410
4496
  })
4411
4497
  .strict();
4412
- export type McpConnectionAuthoritySelection = z.infer<typeof McpConnectionAuthoritySelection>;
4498
+ export type McpConnectionAccountSelection = z.infer<typeof McpConnectionAccountSelection>;
4413
4499
 
4414
- export const McpConnectionAuthoritySelections = z
4415
- .array(McpConnectionAuthoritySelection)
4500
+ export const McpConnectionAccountSelections = z
4501
+ .array(McpConnectionAccountSelection)
4416
4502
  .max(128)
4417
4503
  .superRefine((selections, context) => {
4418
4504
  const seen = new Set<string>();
4505
+ const specialized = new Set<string>();
4419
4506
  for (const [index, selection] of selections.entries()) {
4420
- if (seen.has(selection.serverId)) {
4507
+ if (
4508
+ selection.serverId === "github:personal" ||
4509
+ selection.serverId === "google-drive-publishing"
4510
+ ) {
4511
+ if (specialized.has(selection.serverId)) {
4512
+ context.addIssue({
4513
+ code: "custom",
4514
+ message: "This specialized surface accepts only one connection account",
4515
+ path: [index, "serverId"],
4516
+ });
4517
+ }
4518
+ specialized.add(selection.serverId);
4519
+ }
4520
+ const key = JSON.stringify([selection.serverId, selection.connectionId]);
4521
+ if (seen.has(key)) {
4421
4522
  context.addIssue({
4422
4523
  code: "custom",
4423
- message: "connection authority selections must be unique by serverId",
4524
+ message: "connection account selections must be unique by serverId and connectionId",
4424
4525
  path: [index, "serverId"],
4425
4526
  });
4426
4527
  }
4427
- seen.add(selection.serverId);
4528
+ seen.add(key);
4428
4529
  }
4429
4530
  });
4430
4531
 
@@ -4433,7 +4534,7 @@ export type McpCredentialsRequest = {
4433
4534
  workspaceId: string;
4434
4535
  /** Immediate session whose model or Codemode call needs the credential. */
4435
4536
  sessionId: string;
4436
- /** Workspace-scoped lineage root for host authorization and binding lookup. */
4537
+ /** Workspace-scoped lineage root for accepted execution authority. */
4437
4538
  rootSessionId: string;
4438
4539
  turnId: string;
4439
4540
  /** Null only while a durable turn exists without a currently executing attempt. */
@@ -4449,8 +4550,8 @@ export type McpCredentialsRequest = {
4449
4550
  destinationUrl: string;
4450
4551
  /**
4451
4552
  * Credential transport requested by the caller. Omitted means the existing
4452
- * header-only MCP transport. The additive `http_api` target allows embedding
4453
- * hosts to return query/cookie API-key placements for local API integrations
4553
+ * header-only MCP transport. The `http_api` target permits query/cookie
4554
+ * API-key placements for local API integrations
4454
4555
  * without making those placements eligible for a remote MCP request.
4455
4556
  */
4456
4557
  credentialTarget?: "mcp" | "http_api";
@@ -4477,81 +4578,7 @@ export type ConnectionCredentialPlacement = {
4477
4578
  prefix?: string;
4478
4579
  };
4479
4580
 
4480
- /** Backend-only physical-use fence. Never serialized or accepted from a host response. */
4481
- export const hostMcpCredentialUseGuard: unique symbol = Symbol("hostMcpCredentialUseGuard");
4482
-
4483
- export type McpCredentialResolution =
4484
- | {
4485
- [hostMcpCredentialUseGuard]?: () => Promise<boolean>;
4486
- status: "ok";
4487
- /** Scope echoes are mandatory and verified before any header is used. */
4488
- accountId: string;
4489
- workspaceId: string;
4490
- sessionId: string;
4491
- headers: Record<string, string>;
4492
- /**
4493
- * Optional normalized HTTP credential placements. When present, header
4494
- * placements must exactly match `headers`. Query/cookie placements are
4495
- * accepted only for a request whose credentialTarget is `http_api`.
4496
- */
4497
- placements?: ConnectionCredentialPlacement[];
4498
- connectionId: string;
4499
- providerDomain: string;
4500
- provider?: string;
4501
- scopes?: string[];
4502
- resource?: string;
4503
- selectedResources?: McpConnectionResourceScope[];
4504
- expiresAt?: string | null;
4505
- }
4506
- | {
4507
- status: "auth_needed";
4508
- /** Scope echoes are mandatory even when the credential cannot be resolved. */
4509
- accountId: string;
4510
- workspaceId: string;
4511
- sessionId: string;
4512
- reason: McpCredentialAuthNeededReason;
4513
- providerDomain: string;
4514
- provider?: string;
4515
- connectionId?: string;
4516
- scopes?: string[];
4517
- resource?: string;
4518
- selectedResources?: McpConnectionResourceScope[];
4519
- authorizationUrl?: string;
4520
- };
4521
-
4522
- /** Non-turn authority captured by the authenticated API gateway, never by caller JSON. */
4523
- export type McpGatewayCredentialAuthority = {
4524
- kind: "external_user" | "organization_service";
4525
- subjectId: string;
4526
- permissions: AccessGrant["permissions"];
4527
- };
4528
-
4529
- export type McpGatewayCredentialsRequest = Pick<
4530
- McpCredentialsRequest,
4531
- | "accountId"
4532
- | "workspaceId"
4533
- | "destinationUrl"
4534
- | "credentialTarget"
4535
- | "serverId"
4536
- | "toolName"
4537
- | "connectionRef"
4538
- | "forceRefresh"
4539
- > & {
4540
- surface: "workspace_gateway";
4541
- requestId: string;
4542
- authority: McpGatewayCredentialAuthority;
4543
- };
4544
-
4545
- export type McpGatewayCredentialResolution =
4546
- | (Omit<Extract<McpCredentialResolution, { status: "ok" }>, "sessionId"> & { requestId: string })
4547
- | (Omit<Extract<McpCredentialResolution, { status: "auth_needed" }>, "sessionId"> & {
4548
- requestId: string;
4549
- });
4550
-
4551
4581
  export type ConnectionCredentialsPort = {
4552
- /** Restrict an optional remote adapter to explicit host refs. Omission keeps
4553
- * existing in-process host override and legacy-reference behavior. */
4554
- mcpAuthoritySource?: "host";
4555
4582
  // Every leg is optional: a host may drive only the credential classes it
4556
4583
  // owns. An unset leg falls through to today's standalone implementation for
4557
4584
  // that leg only.
@@ -4563,18 +4590,6 @@ export type ConnectionCredentialsPort = {
4563
4590
  * remains the sole owner of connection selection and credential policy.
4564
4591
  */
4565
4592
  runCredentials?(input: RunCredentialsRequest): Promise<RunCredentialsResolution>;
4566
- /**
4567
- * Resolve rotating MCP transport credentials at request time. Embedded hosts
4568
- * use this to keep their provider connection as the sole credential source;
4569
- * OpenGeni never requires a duplicate connection record. The same resolver is
4570
- * used by model-visible MCP tools and the exact-attempt Codemode projection.
4571
- */
4572
- mcpCredentials?(input: McpCredentialsRequest): Promise<McpCredentialResolution>;
4573
- /** Explicit opt-in for authenticated pre-session discovery and invocation.
4574
- * Does not call the turn-based mcpCredentials fallback or grant durable use. */
4575
- mcpGatewayCredentials?(
4576
- input: McpGatewayCredentialsRequest,
4577
- ): Promise<McpGatewayCredentialResolution>;
4578
4593
  };
4579
4594
 
4580
4595
  // ============ connection-credential provider — GitHub App API port (BYO-App, §7.6 / GitHub credential prototype remainder) ===
@@ -5715,10 +5730,14 @@ const registryId = /^[A-Za-z0-9_-]+$/;
5715
5730
  export const SessionMcpServerId = z.string().min(1).regex(registryId);
5716
5731
  export type SessionMcpServerId = z.infer<typeof SessionMcpServerId>;
5717
5732
 
5733
+ /** Session exclusions narrow live defaults without freezing future connections. */
5734
+ export const SessionExcludedMcpServerIds = z.array(SessionMcpServerId.max(200)).max(64);
5735
+
5718
5736
  // How a session's persisted tool selection was chosen.
5719
5737
  export const SessionToolPolicy = z.object({
5720
5738
  mode: z.enum(["workspace_default", "explicit", "inherited"]),
5721
5739
  inheritedFromSessionId: z.string().uuid().nullable(),
5740
+ excludedMcpServerIds: SessionExcludedMcpServerIds.optional(),
5722
5741
  });
5723
5742
  export type SessionToolPolicy = z.infer<typeof SessionToolPolicy>;
5724
5743
 
@@ -5831,8 +5850,7 @@ export const SessionMcpServerInput = z.object({
5831
5850
  // Write-only credential headers. Values are encrypted at rest and never
5832
5851
  // returned in session responses or events; response metadata exposes names.
5833
5852
  headers: z.record(z.string(), z.string()).optional(),
5834
- // Non-secret opaque pointer resolved at request time by the standalone
5835
- // connection broker or an embedding host's mcpCredentials port.
5853
+ // Non-secret pointer resolved by the native connection credential engine.
5836
5854
  connectionRef: McpServerConnectionRef.optional(),
5837
5855
  });
5838
5856
  export type SessionMcpServerInput = z.infer<typeof SessionMcpServerInput>;
@@ -5897,6 +5915,25 @@ export const SessionMcpServerMetadata = z
5897
5915
  .strict();
5898
5916
  export type SessionMcpServerMetadata = z.infer<typeof SessionMcpServerMetadata>;
5899
5917
 
5918
+ /** Session-local policies for inherited MCP capabilities, not server attachments. */
5919
+ export const SessionMcpApprovalPolicies = z
5920
+ .record(SessionMcpServerId, SessionMcpApprovalPolicy)
5921
+ .refine(
5922
+ (policies) => Object.keys(policies).length <= 64,
5923
+ "At most 64 MCP approval policies are allowed",
5924
+ );
5925
+ export const SessionMcpApprovalPolicyTarget = z.union([
5926
+ SessionMcpServerMetadata,
5927
+ z
5928
+ .object({
5929
+ id: SessionMcpServerId,
5930
+ requireApproval: SessionMcpApprovalPolicy,
5931
+ source: z.literal("workspace"),
5932
+ })
5933
+ .strict(),
5934
+ ]);
5935
+ export type SessionMcpApprovalPolicyTarget = z.infer<typeof SessionMcpApprovalPolicyTarget>;
5936
+
5900
5937
  export const UpdateSessionMcpApprovalPolicyRequest = z
5901
5938
  .object({
5902
5939
  requireApproval: SessionMcpApprovalPolicy,
@@ -5908,7 +5945,7 @@ export type UpdateSessionMcpApprovalPolicyRequest = z.infer<
5908
5945
 
5909
5946
  export const UpdateSessionMcpApprovalPolicyResponse = z
5910
5947
  .object({
5911
- server: SessionMcpServerMetadata,
5948
+ server: SessionMcpApprovalPolicyTarget,
5912
5949
  effectiveFrom: z.literal("next_attempt"),
5913
5950
  })
5914
5951
  .strict();
@@ -5936,7 +5973,7 @@ export function mergeToolRefs(existing: ToolRef[], additions: ToolRef[]): ToolRe
5936
5973
  }
5937
5974
  // Strict wins: if the same server appears both optional and strict, the
5938
5975
  // strict occurrence upgrades the merged ref so an unavailable server fails
5939
- // the turn. This preserves the fail-loud default when defaults, packs, and
5976
+
5940
5977
  // per-turn tool selections are combined.
5941
5978
  const optional = prior.optional === true && tool.optional === true ? true : undefined;
5942
5979
  const eager = prior.eager === true || tool.eager === true ? true : undefined;
@@ -6169,6 +6206,7 @@ export const SessionGoalSnapshot = z.discriminatedUnion("state", [
6169
6206
  text: SessionGoalTextWrite,
6170
6207
  successCriteria: SessionGoalSuccessCriteriaWrite.nullable(),
6171
6208
  rootConstraints: SessionGoalRootConstraintsWrite.default([]),
6209
+ reportRequirements: SessionGoalReportRequirements.optional(),
6172
6210
  mutationPolicy: SessionGoalMutationPolicy,
6173
6211
  capturedAt: z.string(),
6174
6212
  }),
@@ -6329,6 +6367,7 @@ export const SessionGoal = z.object({
6329
6367
  text: z.string(),
6330
6368
  successCriteria: z.string().nullable(),
6331
6369
  rootConstraints: z.array(z.string().min(1)).default([]),
6370
+ reportRequirements: SessionGoalReportRequirements.default([]),
6332
6371
  evidence: z.string().nullable(),
6333
6372
  rationale: z.string().nullable(),
6334
6373
  pausedReason: z.string().nullable(),
@@ -6352,6 +6391,7 @@ export const GoalSpec = z.object({
6352
6391
  text: SessionGoalTextWrite,
6353
6392
  successCriteria: SessionGoalSuccessCriteriaWrite.optional(),
6354
6393
  rootConstraints: SessionGoalRootConstraintsWrite.optional(),
6394
+ reportRequirements: SessionGoalReportRequirements.optional(),
6355
6395
  maxAutoContinuations: z.number().int().positive().optional(),
6356
6396
  mutationPolicy: SessionGoalMutationPolicy.optional(),
6357
6397
  });
@@ -6403,6 +6443,9 @@ export const UpdateSessionToolPolicyRequest = z.union([
6403
6443
  z
6404
6444
  .object({
6405
6445
  mode: z.literal("workspace_default"),
6446
+ // When supplied, edit only connector exclusions and preserve built-in tools.
6447
+ // Omission explicitly resets the complete policy to workspace defaults.
6448
+ excludedMcpServerIds: SessionExcludedMcpServerIds.optional(),
6406
6449
  expectedVersion: z.number().int().positive(),
6407
6450
  })
6408
6451
  .strict(),
@@ -7322,6 +7365,9 @@ export function renderSessionGoalContext(snapshot?: SessionGoalSnapshot): string
7322
7365
  const rootConstraints = snapshot.rootConstraints.length
7323
7366
  ? `\nRoot constraints (must remain satisfied):\n${snapshot.rootConstraints.map((constraint) => `- ${constraint}`).join("\n")}`
7324
7367
  : "";
7368
+ const reports = snapshot.reportRequirements?.length
7369
+ ? `\nRequired native document reports (persisted; completion requires current-head inspection receipts): ${JSON.stringify(snapshot.reportRequirements)}`
7370
+ : "";
7325
7371
  if (snapshot.state === "completed") {
7326
7372
  return `Previous session goal (frozen at logical-turn acceptance; objective revision ${snapshot.objectiveRevision}; status completed): ${snapshot.text}\nSuccess criteria: ${snapshot.successCriteria ?? "none specified"}.${rootConstraints} This goal is complete and remains as historical context. If the user provides a new long-running objective, create it with opengeni__goal_set; goal_update cannot revise a completed goal.`;
7327
7373
  }
@@ -7331,7 +7377,7 @@ export function renderSessionGoalContext(snapshot?: SessionGoalSnapshot): string
7331
7377
  : snapshot.mutationPolicy === "preserve_intent"
7332
7378
  ? "You may directly refine wording without changing intent; adaptations and replacements are proposals until a user applies them."
7333
7379
  : "You may autonomously refine, adapt, or replace the goal when explicit user direction or material new evidence justifies it.";
7334
- return `Standing session goal (frozen at logical-turn acceptance; objective revision ${snapshot.objectiveRevision}; status ${snapshot.state}): ${snapshot.text}\nSuccess criteria: ${snapshot.successCriteria ?? "none specified"}.${rootConstraints}\nMutation policy: ${snapshot.mutationPolicy}. ${policy} Treat later ordinary messages as additional context unless they explicitly redirect this objective. Root constraints are user/API authority and cannot be widened, removed, or rewritten by an agent. Semantic goal changes use opengeni__goal_update with the expected objective revision, change kind, and rationale.`;
7380
+ return `Standing session goal (frozen at logical-turn acceptance; objective revision ${snapshot.objectiveRevision}; status ${snapshot.state}): ${snapshot.text}\nSuccess criteria: ${snapshot.successCriteria ?? "none specified"}.${rootConstraints}${reports}\nMutation policy: ${snapshot.mutationPolicy}. ${policy} Treat later ordinary messages as additional context unless they explicitly redirect this objective. Root constraints are user/API authority and cannot be widened, removed, or rewritten by an agent. Semantic goal changes use opengeni__goal_update with the expected objective revision, change kind, and rationale.`;
7335
7381
  }
7336
7382
 
7337
7383
  /**
@@ -7561,25 +7607,33 @@ export type SaveComposerDraftRequest = z.infer<typeof SaveComposerDraftRequest>;
7561
7607
  * integrity fence for outcome-unknown idempotent replay; the matching durable
7562
7608
  * draft revision remains authoritative and is atomically rotated on acceptance.
7563
7609
  */
7564
- export const SubmitComposerDraftRequest = ComposerDraft.pick({
7565
- text: true,
7566
- annotations: true,
7567
- resources: true,
7568
- model: true,
7569
- reasoningEffort: true,
7570
- latencyMode: true,
7571
- })
7572
- .extend({
7573
- expectedDraftRevision: z.number().int().positive(),
7574
- clientEventId: SessionOperationKey,
7575
- delivery: z.enum(["send", "steer"]),
7576
- controlEtag: z.string().min(1).optional(),
7577
- modelContext: z.string().trim().min(1).max(32768).optional(),
7578
- mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
7579
- connectionAuthorities: McpConnectionAuthoritySelections.default([]),
7580
- personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
7610
+ export const SubmitComposerDraftRequest = z.preprocess(
7611
+ (input) =>
7612
+ input && typeof input === "object" && Object.hasOwn(input, "selectedHostMcpDelegations")
7613
+ ? null
7614
+ : input,
7615
+ ComposerDraft.pick({
7616
+ text: true,
7617
+ annotations: true,
7618
+ resources: true,
7619
+ model: true,
7620
+ reasoningEffort: true,
7621
+ latencyMode: true,
7581
7622
  })
7582
- .superRefine(requireEstablishedPersonalResourceEpoch);
7623
+ .extend({
7624
+ expectedDraftRevision: z.number().int().positive(),
7625
+ clientEventId: SessionOperationKey,
7626
+ delivery: z.enum(["send", "steer"]),
7627
+ controlEtag: z.string().min(1).optional(),
7628
+ modelContext: z.string().trim().min(1).max(32768).optional(),
7629
+ mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
7630
+ connectionAuthorities: z.never().optional(),
7631
+ connectionAccounts: McpConnectionAccountSelections.default([]),
7632
+
7633
+ personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
7634
+ })
7635
+ .superRefine(requireEstablishedPersonalResourceEpoch),
7636
+ );
7583
7637
  export type SubmitComposerDraftRequest = z.infer<typeof SubmitComposerDraftRequest>;
7584
7638
 
7585
7639
  /**
@@ -7589,6 +7643,7 @@ export type SubmitComposerDraftRequest = z.infer<typeof SubmitComposerDraftReque
7589
7643
  */
7590
7644
  export const NewSessionDraftOptions = withVariableSetIdAlias({
7591
7645
  agentLearning: AgentLearningOverrides.optional(),
7646
+ excludedMcpServerIds: SessionExcludedMcpServerIds.optional(),
7592
7647
  visibility: SessionVisibility.optional(),
7593
7648
  sandboxBackend: SandboxBackend.optional(),
7594
7649
  targetSandboxId: z.string().uuid().optional(),
@@ -7680,6 +7735,24 @@ export const SessionControlRequest = z.object({
7680
7735
  });
7681
7736
  export type SessionControlRequest = z.infer<typeof SessionControlRequest>;
7682
7737
 
7738
+ /** Retry an exact failed boundary without admitting another human message. */
7739
+ export const SessionRetryRequest = z
7740
+ .object({
7741
+ clientEventId: SessionOperationKey,
7742
+ failureEventId: z.string().uuid(),
7743
+ model: z.string().min(1).optional(),
7744
+ reasoningEffort: ReasoningEffort.optional(),
7745
+ latencyMode: LatencyMode.optional(),
7746
+ })
7747
+ .strict();
7748
+ export type SessionRetryRequest = z.infer<typeof SessionRetryRequest>;
7749
+ export const SessionRetryResponse = z.object({
7750
+ outcome: z.enum(["accepted", "replayed"]),
7751
+ turnId: z.string().uuid(),
7752
+ failureEventId: z.string().uuid(),
7753
+ });
7754
+ export type SessionRetryResponse = z.infer<typeof SessionRetryResponse>;
7755
+
7683
7756
  export const WorkspaceInferenceControlRequest = z.object({
7684
7757
  action: z.enum(["pause", "resume"]),
7685
7758
  reason: WorkspaceControlReason.optional(),
@@ -9286,6 +9359,11 @@ function refineScheduledTaskAgentConfig(
9286
9359
  /** Storage/projection shape. Deliberately unbounded so stored rows always parse. */
9287
9360
  export const ScheduledTaskAgentConfig = /* @__PURE__ */ z
9288
9361
  .object(scheduledTaskAgentConfigShape(false))
9362
+ .extend({
9363
+ /** Exact accepted choices when frozen; legacy omission retains historical selection. */
9364
+ connectionAccounts: McpConnectionAccountSelections.optional(),
9365
+ connectionAccountsFrozen: z.literal(true).optional(),
9366
+ })
9289
9367
  .superRefine(refineScheduledTaskAgentConfig);
9290
9368
  export type ScheduledTaskAgentConfig = z.infer<typeof ScheduledTaskAgentConfig>;
9291
9369
 
@@ -9365,6 +9443,8 @@ export const ScheduledTask = /* @__PURE__ */ z.object({
9365
9443
  accountId: z.string().uuid(),
9366
9444
  workspaceId: z.string().uuid(),
9367
9445
  name: z.string(),
9446
+ /** Immutable execution owner; null for workspace/service tasks. */
9447
+ ownerSubjectId: z.string().min(1).nullable(),
9368
9448
  status: ScheduledTaskStatus,
9369
9449
  schedule: ScheduledTaskScheduleSpec,
9370
9450
  temporalScheduleId: z.string(),
@@ -9377,7 +9457,6 @@ export const ScheduledTask = /* @__PURE__ */ z.object({
9377
9457
  subjectId: "unattributed-legacy",
9378
9458
  }),
9379
9459
  createdByContext: TurnInitiatorContext.default({}),
9380
- personalConnections: z.array(McpPersonalConnectionSummary).default([]),
9381
9460
  authorityRevision: z.number().int().positive().default(1),
9382
9461
  executionDigest: z.string().regex(/^[0-9a-f]{64}$/u),
9383
9462
  reusableSessionId: z.string().uuid().nullable(),
@@ -9403,7 +9482,9 @@ export type ScheduledTask = z.infer<typeof ScheduledTask>;
9403
9482
  export const ScheduledTaskRunAcceptedExecution = /* @__PURE__ */ z
9404
9483
  .object({
9405
9484
  version: z.literal(1),
9406
- task: ScheduledTask,
9485
+ // Historical accepted snapshots predate task ownership. Their execution
9486
+ // identity remains the separately frozen causal human, never this default.
9487
+ task: ScheduledTask.extend({ ownerSubjectId: z.string().min(1).nullable().default(null) }),
9407
9488
  resolvedModel: z.string().min(1),
9408
9489
  resolvedReasoningEffort: ReasoningEffort,
9409
9490
  resolvedLatencyMode: LatencyMode,
@@ -9524,6 +9605,7 @@ export const ScheduledTaskRunAcceptedExecution = /* @__PURE__ */ z
9524
9605
  .strict()
9525
9606
  .nullable(),
9526
9607
  personalConnectionDelegations: McpPersonalConnectionDelegations,
9608
+ mcpAccountBindings: McpConnectionAccountBindings.nullable().optional(),
9527
9609
  personalResourceAuthoritySubjectId: z.string().min(1).nullable(),
9528
9610
  /** One accepted human principal for every resource-bearing scheduled run. */
9529
9611
  causalHumanSubjectId: z.string().min(1).nullable().default(null),
@@ -9628,30 +9710,34 @@ export const ScheduledTaskRun = /* @__PURE__ */ z.object({
9628
9710
  });
9629
9711
  export type ScheduledTaskRun = z.infer<typeof ScheduledTaskRun>;
9630
9712
 
9631
- const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias({
9632
- agentLearning: z
9633
- .object({ scope: z.enum(["workspace", "personal"]), settings: AgentLearningOverrides })
9634
- .strict()
9635
- .optional(),
9636
- name: ScheduledTaskNameInput,
9637
- schedule: ScheduledTaskScheduleSpec,
9638
- action: z
9639
- .object({ kind: z.literal("agent_turn") })
9640
- .strict()
9641
- .default({ kind: "agent_turn" }),
9642
- runMode: ScheduledTaskRunMode.default("new_session_per_run"),
9643
- overlapPolicy: ScheduledTaskOverlapPolicy.default("allow_concurrent"),
9644
- targetSessionId: z.string().uuid().nullable().optional(),
9645
- connectionAuthorities: McpConnectionAuthoritySelections.default([]),
9646
- selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
9647
- agentConfig: ScheduledTaskAgentConfigInput,
9648
- status: ScheduledTaskStatus.default("active"),
9649
- variableSetId: z.string().uuid().nullable().optional(),
9650
- environmentId: z.string().uuid().nullable().optional(),
9651
- // The rig each run binds to (M3); its active version is resolved per fire.
9652
- rigId: z.string().uuid().nullable().optional(),
9653
- metadata: ScheduledTaskMetadataInput.default({}),
9654
- }).superRefine((value, context) => {
9713
+ const CreateAgentScheduledTaskRequest = /* @__PURE__ */ withVariableSetIdAlias(
9714
+ {
9715
+ agentLearning: z
9716
+ .object({ scope: z.enum(["workspace", "personal"]), settings: AgentLearningOverrides })
9717
+ .strict()
9718
+ .optional(),
9719
+ name: ScheduledTaskNameInput,
9720
+ schedule: ScheduledTaskScheduleSpec,
9721
+ action: z
9722
+ .object({ kind: z.literal("agent_turn") })
9723
+ .strict()
9724
+ .default({ kind: "agent_turn" }),
9725
+ runMode: ScheduledTaskRunMode.default("new_session_per_run"),
9726
+ overlapPolicy: ScheduledTaskOverlapPolicy.default("allow_concurrent"),
9727
+ targetSessionId: z.string().uuid().nullable().optional(),
9728
+ connectionAuthorities: z.never().optional(),
9729
+ connectionAccounts: McpConnectionAccountSelections.default([]),
9730
+
9731
+ agentConfig: ScheduledTaskAgentConfigInput,
9732
+ status: ScheduledTaskStatus.default("active"),
9733
+ variableSetId: z.string().uuid().nullable().optional(),
9734
+ environmentId: z.string().uuid().nullable().optional(),
9735
+ // The rig each run binds to (M3); its active version is resolved per fire.
9736
+ rigId: z.string().uuid().nullable().optional(),
9737
+ metadata: ScheduledTaskMetadataInput.default({}),
9738
+ },
9739
+ { rejectKeys: ["selectedHostMcpDelegations"] },
9740
+ ).superRefine((value, context) => {
9655
9741
  if (value.runMode === "existing_session" && !value.targetSessionId) {
9656
9742
  context.addIssue({
9657
9743
  code: "custom",
@@ -9701,7 +9787,7 @@ const CreateKnowledgeSourceSyncScheduledTaskRequest = /* @__PURE__ */ z
9701
9787
  variableSetId: null,
9702
9788
  environmentId: null,
9703
9789
  rigId: null,
9704
- connectionAuthorities: [],
9790
+ connectionAccounts: [],
9705
9791
  }));
9706
9792
 
9707
9793
  export const CreateScheduledTaskRequest = /* @__PURE__ */ z.union([
@@ -9711,34 +9797,38 @@ export const CreateScheduledTaskRequest = /* @__PURE__ */ z.union([
9711
9797
  export type CreateScheduledTaskRequest = z.infer<typeof CreateScheduledTaskRequest>;
9712
9798
 
9713
9799
  export const UpdateScheduledTaskRequest =
9714
- /* @__PURE__ */ withVariableSetIdAlias({
9715
- agentLearning: z
9716
- .object({
9717
- scope: z.enum(["workspace", "personal"]),
9718
- baselineScope: z.enum(["workspace", "personal"]).optional(),
9719
- operationId: z.uuid(),
9720
- expectedVersion: z.number().int().nonnegative(),
9721
- settings: AgentLearningOverrides,
9722
- })
9723
- .strict()
9724
- .optional(),
9725
- name: ScheduledTaskNameInput.optional(),
9726
- schedule: ScheduledTaskScheduleSpec.optional(),
9727
- runMode: ScheduledTaskRunMode.optional(),
9728
- overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
9729
- action: ScheduledTaskAction.optional(),
9730
- targetSessionId: z.string().uuid().nullable().optional(),
9731
- connectionAuthorities: McpConnectionAuthoritySelections.optional(),
9732
- selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
9733
- agentConfig: ScheduledTaskAgentConfigInput.optional(),
9734
- status: ScheduledTaskStatus.optional(),
9735
- variableSetId: z.string().uuid().nullable().optional(),
9736
- environmentId: z.string().uuid().nullable().optional(),
9737
- // The rig each run binds to (M3); null clears it. Its active version is
9738
- // resolved per fire, so an update takes effect on the next dispatch.
9739
- rigId: z.string().uuid().nullable().optional(),
9740
- metadata: z.record(z.string(), z.unknown()).optional(),
9741
- }).superRefine((value, context) => {
9800
+ /* @__PURE__ */ withVariableSetIdAlias(
9801
+ {
9802
+ agentLearning: z
9803
+ .object({
9804
+ scope: z.enum(["workspace", "personal"]),
9805
+ baselineScope: z.enum(["workspace", "personal"]).optional(),
9806
+ operationId: z.uuid(),
9807
+ expectedVersion: z.number().int().nonnegative(),
9808
+ settings: AgentLearningOverrides,
9809
+ })
9810
+ .strict()
9811
+ .optional(),
9812
+ name: ScheduledTaskNameInput.optional(),
9813
+ schedule: ScheduledTaskScheduleSpec.optional(),
9814
+ runMode: ScheduledTaskRunMode.optional(),
9815
+ overlapPolicy: ScheduledTaskOverlapPolicy.optional(),
9816
+ action: ScheduledTaskAction.optional(),
9817
+ targetSessionId: z.string().uuid().nullable().optional(),
9818
+ connectionAuthorities: z.never().optional(),
9819
+ connectionAccounts: McpConnectionAccountSelections.optional(),
9820
+
9821
+ agentConfig: ScheduledTaskAgentConfigInput.optional(),
9822
+ status: ScheduledTaskStatus.optional(),
9823
+ variableSetId: z.string().uuid().nullable().optional(),
9824
+ environmentId: z.string().uuid().nullable().optional(),
9825
+ // The rig each run binds to (M3); null clears it. Its active version is
9826
+ // resolved per fire, so an update takes effect on the next dispatch.
9827
+ rigId: z.string().uuid().nullable().optional(),
9828
+ metadata: z.record(z.string(), z.unknown()).optional(),
9829
+ },
9830
+ { rejectKeys: ["selectedHostMcpDelegations"] },
9831
+ ).superRefine((value, context) => {
9742
9832
  if (value.targetSessionId && value.runMode && value.runMode !== "existing_session") {
9743
9833
  context.addIssue({
9744
9834
  code: "custom",
@@ -9973,8 +10063,7 @@ export const AutomationSource = z.object({
9973
10063
  configuration: z.record(z.string(), z.unknown()),
9974
10064
  status: AutomationSourceStatus,
9975
10065
  version: z.number().int().positive(),
9976
- packInstallationId: z.string().uuid().nullable(),
9977
- packConnectorId: z.string().min(1).max(128).nullable(),
10066
+
9978
10067
  hasWebhookSecret: z.boolean(),
9979
10068
  webhookPath: z.string().min(1),
9980
10069
  createdBySubjectId: z.string(),
@@ -9993,19 +10082,8 @@ export const CreateAutomationTriggerRequest = /* @__PURE__ */ defineSkillContrac
9993
10082
  parameters: AutomationBoundedJson.default({}),
9994
10083
  sessionTemplate: AutomationSessionTemplate,
9995
10084
  status: AutomationTriggerStatus.default("active"),
9996
- packInstallationId: z.string().uuid().nullable().default(null),
9997
- packTemplateId: z.string().trim().min(1).max(128).nullable().default(null),
9998
10085
  })
9999
- .strict()
10000
- .superRefine((value, context) => {
10001
- if ((value.packInstallationId === null) !== (value.packTemplateId === null)) {
10002
- context.addIssue({
10003
- code: "custom",
10004
- path: ["packTemplateId"],
10005
- message: "packInstallationId and packTemplateId must be supplied together",
10006
- });
10007
- }
10008
- }),
10086
+ .strict(),
10009
10087
  );
10010
10088
  export type CreateAutomationTriggerRequest = z.infer<typeof CreateAutomationTriggerRequest>;
10011
10089
 
@@ -10041,8 +10119,7 @@ export const AutomationTrigger = /* @__PURE__ */ defineSkillContractSchema(() =>
10041
10119
  sessionTemplate: AutomationSessionTemplate,
10042
10120
  status: AutomationTriggerStatus,
10043
10121
  revision: z.number().int().positive(),
10044
- packInstallationId: z.string().uuid().nullable(),
10045
- packTemplateId: z.string().nullable(),
10122
+
10046
10123
  createdBySubjectId: z.string(),
10047
10124
  createdAt: z.string(),
10048
10125
  updatedAt: z.string(),
@@ -10089,66 +10166,6 @@ export const TriggerAutomationManuallyRequest = z
10089
10166
  .strict();
10090
10167
  export type TriggerAutomationManuallyRequest = z.infer<typeof TriggerAutomationManuallyRequest>;
10091
10168
 
10092
- export const CapabilityPackAutomationTemplate = /* @__PURE__ */ defineSkillContractSchema(() =>
10093
- z
10094
- .object({
10095
- id: z.string().min(1).max(128),
10096
- name: z.string().min(1).max(200),
10097
- description: z.string().min(1).max(4096),
10098
- adapterId: AutomationAdapterId,
10099
- eventTypes: z.array(z.string().min(1).max(256)).min(1).max(64),
10100
- sessionTemplate: AutomationSessionTemplate,
10101
- configuration: AutomationBoundedJson.default({}),
10102
- connectionRequirement: z.string().min(1).max(128).nullable().default(null),
10103
- })
10104
- .strict(),
10105
- );
10106
- export type CapabilityPackAutomationTemplate = z.infer<typeof CapabilityPackAutomationTemplate>;
10107
-
10108
- export const CapabilityPackConnectorAuthModel = z.enum([
10109
- "oauth2_authorization_code_pkce",
10110
- "oauth2_authorization_code",
10111
- "api_key",
10112
- "credential_ref",
10113
- ]);
10114
- export type CapabilityPackConnectorAuthModel = z.infer<typeof CapabilityPackConnectorAuthModel>;
10115
-
10116
- export const CapabilityPackConnector = z.object({
10117
- id: z.string().min(1),
10118
- name: z.string().min(1),
10119
- category: z.string().min(1),
10120
- authModel: CapabilityPackConnectorAuthModel,
10121
- providers: z.array(z.string().min(1)).default([]),
10122
- scopes: z.array(z.string().min(1)).default([]),
10123
- required: z.boolean().default(false),
10124
- metadata: z.record(z.string(), z.unknown()).default({}),
10125
- });
10126
- export type CapabilityPackConnector = z.infer<typeof CapabilityPackConnector>;
10127
-
10128
- export const CapabilityPackKnowledge = z.object({
10129
- type: z.literal("document_base"),
10130
- id: z.string().min(1),
10131
- name: z.string().min(1),
10132
- description: z.string().nullable().default(null),
10133
- required: z.boolean().default(false),
10134
- });
10135
- export type CapabilityPackKnowledge = z.infer<typeof CapabilityPackKnowledge>;
10136
-
10137
- export const CapabilityPackScheduledTaskTemplate = z.object({
10138
- id: z.string().min(1),
10139
- name: z.string().min(1),
10140
- description: z.string().min(1),
10141
- defaultSchedule: ScheduledTaskScheduleSpec,
10142
- defaultRunMode: ScheduledTaskRunMode.default("new_session_per_run"),
10143
- defaultOverlapPolicy: ScheduledTaskOverlapPolicy.default("skip"),
10144
- // Optional default agent prompt so registered pack manifests can ship fully
10145
- // instantiable templates; built-in packs may instead build prompts in code.
10146
- prompt: z.string().min(1).optional(),
10147
- });
10148
- export type CapabilityPackScheduledTaskTemplate = z.infer<
10149
- typeof CapabilityPackScheduledTaskTemplate
10150
- >;
10151
-
10152
10169
  // Construct canonical Skill validators synchronously, but let browser bundlers
10153
10170
  // discard their entire dependency graph (including YAML) for unrelated imports.
10154
10171
  // Each transitive schema initializer needs a pure factory boundary: annotating
@@ -10157,33 +10174,26 @@ function defineSkillContractSchema<Schema>(factory: () => Schema): Schema {
10157
10174
  return factory();
10158
10175
  }
10159
10176
 
10160
- // One file inside a pack skill directory. Paths are workspace-relative POSIX
10161
- // paths inside the skill directory (for example "SKILL.md" or
10162
- // "references/runbook.md"); content is UTF-8 text carried inline in the pack
10163
- // manifest, which is also how registered packs persist it (the manifest JSONB
10164
- // row in workspace_packs is the storage of record for pack skills).
10165
- export const CapabilityPackSkillFile = z.object({
10177
+ // One UTF-8 file inside a portable Skill folder. Paths are relative POSIX paths
10178
+ // such as "SKILL.md" or "references/runbook.md".
10179
+ export const SkillArtifactFile = z.object({
10166
10180
  path: z.string().min(1).max(512).refine(isSafeSkillRelativePath, {
10167
10181
  message: "skill file path must be a safe relative POSIX path without '..' segments",
10168
10182
  }),
10169
10183
  content: z.string().max(256 * 1024),
10170
10184
  });
10171
- export type CapabilityPackSkillFile = z.infer<typeof CapabilityPackSkillFile>;
10185
+ export type SkillArtifactFile = z.infer<typeof SkillArtifactFile>;
10172
10186
 
10173
- // A skill delivered by a capability pack. Files own metadata. Optional legacy
10174
- // name/description inputs are consistency assertions, never competing values.
10175
- export const CapabilityPackSkill = /* @__PURE__ */ defineSkillContractSchema(() =>
10187
+ // A portable Skill definition. Files own metadata; optional name/description
10188
+ // inputs are consistency assertions, never competing values.
10189
+ export const SkillArtifactDefinition = /* @__PURE__ */ defineSkillContractSchema(() =>
10176
10190
  z
10177
10191
  .object({
10178
10192
  name: z.string().min(1).max(64).optional(),
10179
10193
  description: z.string().min(1).max(1024).optional(),
10180
- // Workspace-managed Skills are available to every session in the
10181
- // workspace. Session-selected Skills remain installed and inspectable, but
10182
- // enter model context only when their immutable definition is attached to
10183
- // a session explicitly. This is the hard contamination boundary for Packs
10184
- // that guide implementation agents rather than customer-facing agents.
10194
+ // Installation policy stays separate from session-owned Skill content.
10185
10195
  activationMode: z.enum(["workspace_managed", "session_selected"]).optional(),
10186
- files: z.array(CapabilityPackSkillFile).min(1).max(128),
10196
+ files: z.array(SkillArtifactFile).min(1).max(128),
10187
10197
  })
10188
10198
  .transform((skill, ctx) => {
10189
10199
  const main = skill.files.find((file) => file.path === "SKILL.md");
@@ -10218,16 +10228,14 @@ export const CapabilityPackSkill = /* @__PURE__ */ defineSkillContractSchema(()
10218
10228
  return { ...skill, ...metadata };
10219
10229
  }),
10220
10230
  );
10221
- export type CapabilityPackSkill = z.infer<typeof CapabilityPackSkill>;
10222
- export type CapabilityPackSkillInput = z.input<typeof CapabilityPackSkill>;
10223
-
10224
- // Inline skill content fixed onto one session at creation. It intentionally
10225
- // uses the exact same validated directory shape as a pack skill, but has a
10226
- // different semantic owner and lifecycle. Session readers can inspect it; it
10227
- // is configuration, never a secret store. Pack activation policy is consumed
10228
- // at admission and cannot become part of the session-owned artifact.
10231
+ export type SkillArtifactDefinition = z.infer<typeof SkillArtifactDefinition>;
10232
+ export type SkillArtifactDefinitionInput = z.input<typeof SkillArtifactDefinition>;
10233
+
10234
+ // Inline Skill content fixed onto one session at creation. Session readers can
10235
+ // inspect it; it is configuration, never a secret store. Installation policy
10236
+ // cannot become part of the session-owned artifact.
10229
10237
  export const SessionSkill = /* @__PURE__ */ defineSkillContractSchema(() =>
10230
- CapabilityPackSkill.transform(({ activationMode: _activationMode, ...skill }) => skill),
10238
+ SkillArtifactDefinition.transform(({ activationMode: _activationMode, ...skill }) => skill),
10231
10239
  );
10232
10240
  export type SessionSkill = z.infer<typeof SessionSkill>;
10233
10241
  export type SessionSkillInput = z.input<typeof SessionSkill>;
@@ -10291,316 +10299,10 @@ function projectStoredTemplateSkillMetadata(value: unknown): unknown {
10291
10299
  };
10292
10300
  }
10293
10301
 
10294
- const CapabilityPackVariableSet = z
10295
- .object({
10296
- description: z.string().min(1).max(2048),
10297
- requiredVariables: z.array(VariableSetVariableName).max(256).default([]),
10298
- required: z.boolean().default(false),
10299
- })
10300
- .strict();
10301
-
10302
- const CapabilityPackComponentKey = z
10303
- .string()
10304
- .min(1)
10305
- .max(128)
10306
- .regex(/^[a-z0-9](?:[a-z0-9._/-]*[a-z0-9])?$/);
10307
-
10308
- const CapabilityPackInstanceKey = z
10309
- .string()
10310
- .min(1)
10311
- .max(128)
10312
- .regex(/^[a-z0-9](?:[a-z0-9._/-]*[a-z0-9])?$/);
10313
-
10314
- /**
10315
- * Immutable requirements adopted by a Pack installation. The manifest names
10316
- * portable identities; installation resolves them to exact workspace-local
10317
- * component rows and records Pack ownership in the shared component ledger.
10318
- */
10319
- export const CapabilityPackComponentReference = z.discriminatedUnion("kind", [
10320
- z
10321
- .object({
10322
- key: CapabilityPackComponentKey,
10323
- kind: z.literal("plugin"),
10324
- pluginKey: z.string().min(1).max(200),
10325
- version: z.string().min(1).max(128),
10326
- manifestDigest: z.string().regex(/^[0-9a-f]{64}$/),
10327
- required: z.boolean().default(true),
10328
- })
10329
- .strict(),
10330
- z
10331
- .object({
10332
- key: CapabilityPackComponentKey,
10333
- kind: z.literal("skill"),
10334
- capabilityId: z.string().min(1).max(512),
10335
- contentSha256: z.string().regex(/^[0-9a-f]{64}$/),
10336
- required: z.boolean().default(true),
10337
- })
10338
- .strict(),
10339
- z
10340
- .object({
10341
- key: CapabilityPackComponentKey,
10342
- kind: z.literal("integration"),
10343
- capabilityId: z.string().min(1).max(512),
10344
- instanceKey: CapabilityPackInstanceKey,
10345
- revisionId: z.string().min(1).max(512),
10346
- contentSha256: z.string().regex(/^[0-9a-f]{64}$/),
10347
- required: z.boolean().default(true),
10348
- })
10349
- .strict(),
10350
- z
10351
- .object({
10352
- key: CapabilityPackComponentKey,
10353
- kind: z.literal("facet"),
10354
- capabilityId: z.string().min(1).max(512),
10355
- instanceKey: CapabilityPackInstanceKey,
10356
- facetKey: z.string().min(1).max(200),
10357
- bindingKey: CapabilityPackInstanceKey,
10358
- configDigest: z.string().regex(/^[0-9a-f]{64}$/),
10359
- required: z.boolean().default(true),
10360
- })
10361
- .strict(),
10362
- ]);
10363
- export type CapabilityPackComponentReference = z.infer<typeof CapabilityPackComponentReference>;
10364
-
10365
- export const CapabilityPackRigRequirement = z
10366
- .object({
10367
- description: z.string().min(1).max(2048).optional(),
10368
- required: z.boolean().default(true),
10369
- rigId: z.string().uuid().optional(),
10370
- requireVerified: z.boolean().default(false),
10371
- })
10372
- .strict();
10373
- export type CapabilityPackRigRequirement = z.infer<typeof CapabilityPackRigRequirement>;
10374
-
10375
- export const CapabilityPack = /* @__PURE__ */ defineSkillContractSchema(() =>
10376
- z.preprocess(
10377
- (input) => {
10378
- if (!input || typeof input !== "object" || Array.isArray(input)) {
10379
- return input;
10380
- }
10381
- const record = input as Record<string, unknown>;
10382
- if (record.variableSet !== undefined) {
10383
- return record;
10384
- }
10385
- if (record.environment !== undefined) {
10386
- const { environment: _environment, ...rest } = record;
10387
- return { ...rest, variableSet: record.environment };
10388
- }
10389
- if (record.requiredVariables !== undefined) {
10390
- const { requiredVariables: _requiredVariables, ...rest } = record;
10391
- return {
10392
- ...rest,
10393
- variableSet: {
10394
- description: "Required variables",
10395
- requiredVariables: record.requiredVariables,
10396
- required:
10397
- Array.isArray(record.requiredVariables) && record.requiredVariables.length > 0,
10398
- },
10399
- };
10400
- }
10401
- return record;
10402
- },
10403
- z
10404
- .object({
10405
- id: z
10406
- .string()
10407
- .min(1)
10408
- .max(100)
10409
- .regex(/^[a-z0-9](?:[a-z0-9._/-]*[a-z0-9])?$/),
10410
- name: z.string().min(1).max(200),
10411
- description: z.string().min(1).max(4096),
10412
- role: z.string().min(1).max(128),
10413
- category: z.string().min(1).max(128),
10414
- version: z.string().min(1).max(128),
10415
- // Legacy manifest compatibility. V2 installation resolves this image to
10416
- // an explicit Rig requirement; the Pack no longer changes workspace
10417
- // runtime settings directly.
10418
- sandboxImage: z.string().trim().min(1).max(512).optional(),
10419
- // Optional provider-native immutable identities for the exact logical
10420
- // sandboxImage above. These avoid re-importing a private registry image on
10421
- // every provider while preserving sandboxImage as the cross-provider image
10422
- // provenance and lease-conflict identity.
10423
- sandboxProviderImages: z
10424
- .object({
10425
- modal: z
10426
- .object({
10427
- imageId: z
10428
- .string()
10429
- .trim()
10430
- .regex(/^im-[A-Za-z0-9]{22}$/),
10431
- })
10432
- .strict()
10433
- .optional(),
10434
- })
10435
- .strict()
10436
- .optional(),
10437
- // Legacy inline Skills are migrated into immutable Skill components by
10438
- // the V2 Pack installer. They are not loaded directly by V2 runtime.
10439
- skills: z
10440
- .array(CapabilityPackSkill)
10441
- .max(32)
10442
- .superRefine((skills, ctx) => {
10443
- const seen = new Set<string>();
10444
- skills.forEach((skill, index) => {
10445
- const key = skill.name.toLowerCase();
10446
- if (seen.has(key)) {
10447
- ctx.addIssue({
10448
- code: "custom",
10449
- message: `duplicate pack skill name: ${skill.name}`,
10450
- path: [index, "name"],
10451
- });
10452
- }
10453
- seen.add(key);
10454
- });
10455
- })
10456
- .default([]),
10457
- components: z.array(CapabilityPackComponentReference).max(128).default([]),
10458
- rig: CapabilityPackRigRequirement.optional(),
10459
- tools: z.array(ToolRef).default([]),
10460
- connectors: z.array(CapabilityPackConnector).default([]),
10461
- knowledge: z.array(CapabilityPackKnowledge).default([]),
10462
- scheduledTaskTemplates: z.array(CapabilityPackScheduledTaskTemplate).default([]),
10463
- automationTemplates: z.array(CapabilityPackAutomationTemplate).max(64).optional(),
10464
- variableSet: CapabilityPackVariableSet.optional(),
10465
- metadata: z.record(z.string(), z.unknown()).default({}),
10466
- })
10467
- .superRefine((pack, ctx) => {
10468
- const componentKeys = new Set<string>();
10469
- pack.components.forEach((component, index) => {
10470
- if (componentKeys.has(component.key)) {
10471
- ctx.addIssue({
10472
- code: "custom",
10473
- message: `duplicate Pack component key: ${component.key}`,
10474
- path: ["components", index, "key"],
10475
- });
10476
- }
10477
- componentKeys.add(component.key);
10478
- });
10479
- pack.skills.forEach((skill, index) => {
10480
- const key = `inline-skill/${skill.name.toLowerCase()}`;
10481
- if (componentKeys.has(key)) {
10482
- ctx.addIssue({
10483
- code: "custom",
10484
- message: `Pack component key conflicts with inline Skill ${skill.name}: ${key}`,
10485
- path: ["skills", index, "name"],
10486
- });
10487
- }
10488
- componentKeys.add(key);
10489
- });
10490
- const automationTemplateIds = new Set<string>();
10491
- pack.automationTemplates?.forEach((template, index) => {
10492
- if (automationTemplateIds.has(template.id)) {
10493
- ctx.addIssue({
10494
- code: "custom",
10495
- message: `duplicate Pack automation template id: ${template.id}`,
10496
- path: ["automationTemplates", index, "id"],
10497
- });
10498
- }
10499
- automationTemplateIds.add(template.id);
10500
- });
10501
- if (!pack.sandboxProviderImages?.modal) {
10502
- return;
10503
- }
10504
- if (!pack.sandboxImage) {
10505
- ctx.addIssue({
10506
- code: "custom",
10507
- message: "sandboxProviderImages.modal requires sandboxImage",
10508
- path: ["sandboxProviderImages", "modal"],
10509
- });
10510
- return;
10511
- }
10512
- if (!/@sha256:[0-9a-f]{64}$/i.test(pack.sandboxImage)) {
10513
- ctx.addIssue({
10514
- code: "custom",
10515
- message:
10516
- "sandboxProviderImages.modal requires sandboxImage to be pinned by an OCI sha256 digest",
10517
- path: ["sandboxImage"],
10518
- });
10519
- }
10520
- }),
10521
- ),
10522
- );
10523
- export type CapabilityPack = z.infer<typeof CapabilityPack>;
10524
-
10525
10302
  /** Execution view only; never replace the stored manifest or its digest with it. */
10526
- export const StoredCapabilityPack = /* @__PURE__ */ defineSkillContractSchema(() =>
10527
- z.preprocess((value) => {
10528
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
10529
- const pack = value as Record<string, unknown>;
10530
- return {
10531
- ...pack,
10532
- ...(pack.skills !== undefined ? { skills: projectStoredSkillMetadata(pack.skills) } : {}),
10533
- ...(Array.isArray(pack.automationTemplates)
10534
- ? {
10535
- automationTemplates: pack.automationTemplates.map((entry: unknown) => {
10536
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
10537
- const template = entry as Record<string, unknown>;
10538
- return {
10539
- ...template,
10540
- sessionTemplate: projectStoredTemplateSkillMetadata(template.sessionTemplate),
10541
- };
10542
- }),
10543
- }
10544
- : {}),
10545
- };
10546
- }, CapabilityPack),
10547
- );
10548
-
10549
- // Registering a pack stores the manifest itself; the request body is a full
10550
- // CapabilityPack manifest.
10551
- export const RegisterCapabilityPackRequest = /* @__PURE__ */ defineSkillContractSchema(
10552
- () => CapabilityPack,
10553
- );
10554
- export type RegisterCapabilityPackRequest = z.infer<typeof RegisterCapabilityPackRequest>;
10555
-
10556
- export const WorkspaceRegisteredPack = /* @__PURE__ */ defineSkillContractSchema(() =>
10557
- z.object({
10558
- accountId: z.string().uuid(),
10559
- workspaceId: z.string().uuid(),
10560
- pack: CapabilityPack,
10561
- createdAt: z.string(),
10562
- updatedAt: z.string(),
10563
- }),
10564
- );
10565
- export type WorkspaceRegisteredPack = z.infer<typeof WorkspaceRegisteredPack>;
10566
-
10567
- export const PackInstallationStatus = z.enum([
10568
- "installing",
10569
- "active",
10570
- "needs_attention",
10571
- "disabled",
10572
- ]);
10573
- export type PackInstallationStatus = z.infer<typeof PackInstallationStatus>;
10574
-
10575
- export const PackInstallation = z.object({
10576
- skillWrites: z.array(SkillWriteReceipt).optional(),
10577
- skillPublications: z.array(SkillPublicationReceipt).optional(),
10578
- skillReleases: z.array(SkillSourceReleaseReceipt).optional(),
10579
- id: z.string().uuid(),
10580
- accountId: z.string().uuid(),
10581
- workspaceId: z.string().uuid(),
10582
- packId: z.string().min(1),
10583
- status: PackInstallationStatus,
10584
- version: z.number().int().positive(),
10585
- // Exact accepted audit data, including historical fields and legacy Skills.
10586
- // Execution must explicitly parse StoredCapabilityPack; response validation
10587
- // must not project metadata, apply defaults, or change manifestDigest input.
10588
- manifestSnapshot: z.record(z.string(), z.unknown()).nullable(),
10589
- manifestDigest: z
10590
- .string()
10591
- .regex(/^[0-9a-f]{64}$/)
10592
- .nullable(),
10593
- selectedRigId: z.string().uuid().nullable(),
10594
- installedBySubjectId: z.string().min(1).max(1024).nullable(),
10595
- metadata: z.record(z.string(), z.unknown()),
10596
- enabledAt: z.string(),
10597
- updatedAt: z.string(),
10598
- });
10599
- export type PackInstallation = z.infer<typeof PackInstallation>;
10600
10303
 
10601
10304
  // ============ OpenGeni Review Bot — provider-neutral pull-request review automation ============
10602
10305
 
10603
- export const OPENGENI_PR_REVIEW_PACK_ID = "pr-review" as const;
10604
10306
  export const OPENGENI_PR_REVIEW_SESSION_ROLE = "pull_request_review" as const;
10605
10307
 
10606
10308
  export const PrReviewProvider = GitCredentialProvider;
@@ -10824,124 +10526,6 @@ export const PrReviewRepositoryBinding = /* @__PURE__ */ (() =>
10824
10526
  }))();
10825
10527
  export type PrReviewRepositoryBinding = z.infer<typeof PrReviewRepositoryBinding>;
10826
10528
 
10827
- export const EnablePackRequest = withVariableSetIdAlias({
10828
- variableSetId: z.string().uuid().optional(),
10829
- environmentId: z.string().uuid().optional(),
10830
- metadata: z.record(z.string(), z.unknown()).default({}),
10831
- });
10832
- export type EnablePackRequest = z.infer<typeof EnablePackRequest>;
10833
-
10834
- export const PackComponentResolutionStatus = z.enum(["ready", "missing", "mismatch"]);
10835
- export type PackComponentResolutionStatus = z.infer<typeof PackComponentResolutionStatus>;
10836
-
10837
- export const PackComponentResolution = z
10838
- .object({
10839
- key: CapabilityPackComponentKey,
10840
- kind: z.enum(["plugin", "skill", "integration", "facet", "inline_skill"]),
10841
- capabilityId: z.string().min(1).max(512),
10842
- required: z.boolean(),
10843
- status: PackComponentResolutionStatus,
10844
- expectedDigest: z.string().regex(/^[0-9a-f]{64}$/),
10845
- actualDigest: z
10846
- .string()
10847
- .regex(/^[0-9a-f]{64}$/)
10848
- .nullable(),
10849
- resolvedId: z.string().min(1).max(512).nullable(),
10850
- label: z.string().min(1).max(200),
10851
- })
10852
- .strict();
10853
- export type PackComponentResolution = z.infer<typeof PackComponentResolution>;
10854
-
10855
- export const PackRigResolution = z
10856
- .object({
10857
- required: z.boolean(),
10858
- status: z.enum(["not_required", "ready", "missing", "mismatch", "unverified"]),
10859
- requestedRigId: z.string().uuid().nullable(),
10860
- rigId: z.string().uuid().nullable(),
10861
- rigVersionId: z.string().uuid().nullable(),
10862
- name: z.string().min(1).max(200).nullable(),
10863
- image: z.string().min(1).max(512).nullable(),
10864
- })
10865
- .strict();
10866
- export type PackRigResolution = z.infer<typeof PackRigResolution>;
10867
-
10868
- export const PreviewPackInstallationRequest = z
10869
- .object({
10870
- rigId: z.string().uuid().optional(),
10871
- variableSetId: z.string().uuid().optional(),
10872
- })
10873
- .strict();
10874
- export type PreviewPackInstallationRequest = z.infer<typeof PreviewPackInstallationRequest>;
10875
-
10876
- export const PackInstallationPreview = z
10877
- .object({
10878
- packId: z.string().min(1),
10879
- packVersion: z.string().min(1),
10880
- manifestDigest: z.string().regex(/^[0-9a-f]{64}$/),
10881
- installationVersion: z.number().int().positive().nullable(),
10882
- action: z.enum(["install", "update", "repair"]),
10883
- ready: z.boolean(),
10884
- blockers: z.array(z.string().min(1).max(500)).max(256),
10885
- components: z.array(PackComponentResolution).max(160),
10886
- rig: PackRigResolution,
10887
- variableSetId: z.string().uuid().nullable(),
10888
- legacyInlineSkillCount: z.number().int().nonnegative().max(32),
10889
- legacySandboxImage: z.string().min(1).max(512).nullable(),
10890
- })
10891
- .strict();
10892
- export type PackInstallationPreview = z.infer<typeof PackInstallationPreview>;
10893
-
10894
- export const InstallPackRequest = z
10895
- .object({
10896
- expectedManifestDigest: z.string().regex(/^[0-9a-f]{64}$/),
10897
- expectedInstallationVersion: z.number().int().positive().optional(),
10898
- rigId: z.string().uuid().optional(),
10899
- variableSetId: z.string().uuid().optional(),
10900
- idempotencyKey: z.string().uuid(),
10901
- metadata: z.record(z.string(), z.unknown()).default({}),
10902
- })
10903
- .strict();
10904
- export type InstallPackRequest = z.infer<typeof InstallPackRequest>;
10905
-
10906
- export const PackUninstallPreview = z
10907
- .object({
10908
- packId: z.string().min(1),
10909
- installed: z.boolean(),
10910
- installationVersion: z.number().int().positive().nullable(),
10911
- components: z
10912
- .array(
10913
- z
10914
- .object({
10915
- key: CapabilityPackComponentKey,
10916
- kind: z.enum(["plugin", "skill", "integration", "facet", "inline_skill"]),
10917
- capabilityId: z.string().min(1).max(512),
10918
- retainedByOtherOwners: z.boolean(),
10919
- })
10920
- .strict(),
10921
- )
10922
- .max(160),
10923
- })
10924
- .strict();
10925
- export type PackUninstallPreview = z.infer<typeof PackUninstallPreview>;
10926
-
10927
- export const UninstallPackRequest = z
10928
- .object({
10929
- expectedInstallationVersion: z.number().int().positive(),
10930
- idempotencyKey: z.string().uuid(),
10931
- })
10932
- .strict();
10933
- export type UninstallPackRequest = z.infer<typeof UninstallPackRequest>;
10934
-
10935
- export const UninstallPackResult = z
10936
- .object({
10937
- skillReleases: z.array(SkillSourceReleaseReceipt).optional(),
10938
- packId: z.string().min(1),
10939
- status: z.enum(["not_installed", "uninstalled"]),
10940
- retainedComponents: z.array(z.string().min(1).max(512)).max(160),
10941
- })
10942
- .strict();
10943
- export type UninstallPackResult = z.infer<typeof UninstallPackResult>;
10944
-
10945
10529
  export const SocialProvider = z.enum([
10946
10530
  "x",
10947
10531
  "reddit",
@@ -11112,6 +10696,8 @@ export const ConnectionMetadata = z.object({
11112
10696
  id: z.string().uuid(),
11113
10697
  /** Opaque owner-only handle used to manage this personal connection's grants. */
11114
10698
  authorityId: z.string().uuid().optional(),
10699
+ /** Credential-free generation fence for exact accepted account routing. */
10700
+ connectionAuthorityGeneration: z.number().int().positive().optional(),
11115
10701
  accountId: z.string().uuid(),
11116
10702
  workspaceId: z.string().uuid(),
11117
10703
  subjectId: z.string().nullable(),
@@ -11221,6 +10807,8 @@ export const CreateConnectionRequest = z.object({
11221
10807
  expiresAt: z.string().datetime({ offset: true }).nullable().optional(),
11222
10808
  metadata: z.record(z.string(), z.unknown()).default({}),
11223
10809
  operationId: z.string().uuid().optional(),
10810
+ /** Retired: connection execution is authorized by the initiating user. */
10811
+ initialUseContexts: z.never().optional(),
11224
10812
  });
11225
10813
  export type CreateConnectionRequest = z.infer<typeof CreateConnectionRequest>;
11226
10814
 
@@ -11334,21 +10922,7 @@ export const IntegrationClientMetadata = z.object({
11334
10922
  });
11335
10923
  export type IntegrationClientMetadata = z.infer<typeof IntegrationClientMetadata>;
11336
10924
 
11337
- export const MarketingDailyAnalysisTaskRequest = z.object({
11338
- name: z.string().min(1).optional(),
11339
- connectionIds: z.array(z.string().uuid()).default([]),
11340
- documentBaseIds: z.array(z.string().uuid()).default([]),
11341
- timeZone: z.string().min(1).default("UTC"),
11342
- hour: z.number().int().min(0).max(23).default(9),
11343
- minute: z.number().int().min(0).max(59).default(0),
11344
- promptInstructions: z.string().min(1).optional(),
11345
- status: ScheduledTaskStatus.default("active"),
11346
- runMode: ScheduledTaskRunMode.default("new_session_per_run"),
11347
- overlapPolicy: ScheduledTaskOverlapPolicy.default("skip"),
11348
- });
11349
- export type MarketingDailyAnalysisTaskRequest = z.infer<typeof MarketingDailyAnalysisTaskRequest>;
11350
-
11351
- export const CapabilityKind = z.enum(["pack", "mcp", "api", "skill", "plugin"]);
10925
+ export const CapabilityKind = z.enum(["mcp", "api", "skill", "plugin"]);
11352
10926
  export type CapabilityKind = z.infer<typeof CapabilityKind>;
11353
10927
 
11354
10928
  export const CapabilitySource = z.enum([
@@ -11370,11 +10944,6 @@ export type CapabilityCatalogAuthKind = z.infer<typeof CapabilityCatalogAuthKind
11370
10944
  export const CapabilityCatalogTier = z.enum(["verified", "community"]);
11371
10945
  export type CapabilityCatalogTier = z.infer<typeof CapabilityCatalogTier>;
11372
10946
 
11373
- /**
11374
- * User-facing lifecycle truth for the Capabilities control center. This is a
11375
- * read-model projection only: each action is still executed by the owning
11376
- * Plugin, Integration, Connection, Skill, or Pack domain.
11377
- */
11378
10947
  export const CapabilityLifecycleStatus = z.enum([
11379
10948
  "available",
11380
10949
  "installed",
@@ -11481,6 +11050,7 @@ export const CapabilityCatalogItem = z.object({
11481
11050
  connectionRef: z
11482
11051
  .object({
11483
11052
  connectionId: z.string().min(1).optional(),
11053
+ accountSelection: z.literal("all_eligible").optional(),
11484
11054
  authoritySource: z.literal("host").optional(),
11485
11055
  providerDomain: z.string().min(1),
11486
11056
  kind: z.string().min(1),
@@ -11553,6 +11123,8 @@ export const CreateCapabilityCatalogItemRequest = z.object({
11553
11123
  export type CreateCapabilityCatalogItemRequest = z.infer<typeof CreateCapabilityCatalogItemRequest>;
11554
11124
 
11555
11125
  export const EnableCapabilityRequest = z.object({
11126
+ /** Automatic setup may create a missing installation, never rewrite an existing one. */
11127
+ onlyIfUninstalled: z.boolean().optional(),
11556
11128
  config: z.record(z.string(), z.unknown()).default({}),
11557
11129
  metadata: z.record(z.string(), z.unknown()).default({}),
11558
11130
  connectionRef: McpServerConnectionRef.optional(),
@@ -11582,7 +11154,7 @@ export type DiscoverMcpCapabilitiesResponse = z.infer<typeof DiscoverMcpCapabili
11582
11154
  export const SkillImportSource = z.enum(["github", "skills_sh"]);
11583
11155
  export type SkillImportSource = z.infer<typeof SkillImportSource>;
11584
11156
 
11585
- export const SkillInstallationSource = z.enum(["library", "github", "skills_sh", "pack"]);
11157
+ export const SkillInstallationSource = z.enum(["library", "github", "skills_sh"]);
11586
11158
  export type SkillInstallationSource = z.infer<typeof SkillInstallationSource>;
11587
11159
 
11588
11160
  export const PreviewSkillImportRequest = z.object({
@@ -11654,7 +11226,7 @@ export const InstalledSkill = z.object({
11654
11226
  export type InstalledSkill = z.infer<typeof InstalledSkill>;
11655
11227
 
11656
11228
  export const CapabilityComponentOwner = z.object({
11657
- kind: z.enum(["direct", "plugin", "pack", "migration"]),
11229
+ kind: z.enum(["direct", "plugin", "migration"]),
11658
11230
  id: z.string().min(1).max(512),
11659
11231
  removable: z.boolean(),
11660
11232
  });
@@ -12349,26 +11921,56 @@ export const ListInstalledPluginsResponse = z
12349
11921
  .strict();
12350
11922
  export type ListInstalledPluginsResponse = z.infer<typeof ListInstalledPluginsResponse>;
12351
11923
 
11924
+ export const PluginUninstallComponentImpact = z.object({
11925
+ capabilityId: z.string().min(1),
11926
+ kind: z.enum(["skill", "integration", "mcp"]),
11927
+ retainedByOtherOwners: z.boolean(),
11928
+ name: z.string().min(1),
11929
+ disposition: z.enum(["removed", "retained", "inactive"]),
11930
+ retentionReasons: z.array(
11931
+ z.enum(["other_owners", "customized", "re_scoped", "registry_unavailable"]),
11932
+ ),
11933
+ remainingOwners: z.array(
11934
+ z.object({
11935
+ kind: z.enum(["direct", "plugin", "migration"]),
11936
+ name: z.string().min(1),
11937
+ }),
11938
+ ),
11939
+ skillId: z.string().uuid().optional(),
11940
+ });
11941
+ export type PluginUninstallComponentImpact = z.infer<typeof PluginUninstallComponentImpact>;
11942
+
12352
11943
  export const PluginUninstallPreview = z
12353
11944
  .object({
12354
11945
  pluginKey: z.string().min(1),
12355
11946
  installed: z.boolean(),
12356
11947
  version: z.string().nullable(),
12357
11948
  installationVersion: z.number().int().positive().nullable(),
12358
- components: z.array(
12359
- z.object({
12360
- capabilityId: z.string().min(1),
12361
- kind: z.enum(["skill", "integration", "mcp"]),
12362
- retainedByOtherOwners: z.boolean(),
12363
- }),
12364
- ),
11949
+ previewToken: z
11950
+ .string()
11951
+ .regex(/^[0-9a-f]{64}$/)
11952
+ .optional(),
11953
+ components: z.array(PluginUninstallComponentImpact),
12365
11954
  })
12366
11955
  .strict();
12367
11956
  export type PluginUninstallPreview = z.infer<typeof PluginUninstallPreview>;
12368
11957
 
11958
+ export const PluginUninstallPreviewConflict = z
11959
+ .object({
11960
+ code: z.literal("plugin_uninstall_preview_changed"),
11961
+ message: z.string().min(1),
11962
+ preview: PluginUninstallPreview,
11963
+ })
11964
+ .strict();
11965
+ export type PluginUninstallPreviewConflict = z.infer<typeof PluginUninstallPreviewConflict>;
11966
+
12369
11967
  export const UninstallPluginRequest = z
12370
11968
  .object({
12371
11969
  expectedInstallationVersion: z.number().int().positive(),
11970
+ expectedPreviewToken: z
11971
+ .string()
11972
+ .regex(/^[0-9a-f]{64}$/)
11973
+ .optional(),
12372
11974
  idempotencyKey: z.string().uuid(),
12373
11975
  })
12374
11976
  .strict();
@@ -12501,6 +12103,23 @@ export type CancelSessionBackgroundCommandResult = z.infer<
12501
12103
  typeof CancelSessionBackgroundCommandResult
12502
12104
  >;
12503
12105
 
12106
+ export const SessionAdmissionBlock = z
12107
+ .object({
12108
+ reason: z.enum([
12109
+ "database_claim_rejected",
12110
+ "initiator_membership_required",
12111
+ "personal_resource_grant_required",
12112
+ ]),
12113
+ sqlState: z
12114
+ .string()
12115
+ .regex(/^[0-9A-Z]{5}$/)
12116
+ .nullable(),
12117
+ retryPolicy: z.literal("explicit_recheck"),
12118
+ blockedAt: z.string().datetime(),
12119
+ })
12120
+ .strict();
12121
+ export type SessionAdmissionBlock = z.infer<typeof SessionAdmissionBlock>;
12122
+
12504
12123
  export const Session = /* @__PURE__ */ defineSkillContractSchema(() =>
12505
12124
  z.object({
12506
12125
  bundledSkillIds: BundledSkillSelection.optional(),
@@ -12508,6 +12127,18 @@ export const Session = /* @__PURE__ */ defineSkillContractSchema(() =>
12508
12127
  workspaceId: z.string().uuid(),
12509
12128
  accountId: z.string().uuid(),
12510
12129
  status: SessionStatus,
12130
+ /** Accepted work is retained; Resume or a new Send/Steer rechecks admission. */
12131
+ admissionBlock: SessionAdmissionBlock.nullable().optional(),
12132
+ /** Detail-only dispatch evidence. A wake delivery attempt is not turn execution. */
12133
+ dispatchWait: z
12134
+ .object({
12135
+ state: z.enum(["pending", "acknowledged", "unavailable"]),
12136
+ attempts: z.number().int().nonnegative(),
12137
+ nextAttemptAt: z.string().nullable(),
12138
+ lastError: z.string().nullable(),
12139
+ })
12140
+ .nullable()
12141
+ .optional(),
12511
12142
  /** Detail-only failure evidence through lastSequence; independent of timeline paging. */
12512
12143
  failureDiagnostics: z
12513
12144
  .object({
@@ -12603,6 +12234,7 @@ export const Session = /* @__PURE__ */ defineSkillContractSchema(() =>
12603
12234
  // Per-session third-party MCP servers, metadata only. Credential values are
12604
12235
  // write-only and never appear here.
12605
12236
  mcpServers: z.array(SessionMcpServerMetadata).default([]),
12237
+ mcpApprovalPolicies: SessionMcpApprovalPolicies.optional(),
12606
12238
  // The manager session that spawned this one via session_create (set only
12607
12239
  // when the creating grant carried a worker-signed sessionId claim); null for
12608
12240
  // direct API creates and scheduled-task runs. When set, this session's
@@ -12743,6 +12375,10 @@ export const SessionListResponse = /* @__PURE__ */ defineSkillContractSchema(()
12743
12375
  z.object({
12744
12376
  pinned: z.array(Session),
12745
12377
  filtersApplied: z.literal(true).optional(),
12378
+ /** Effective server ordering; name uses ASCII-space trim, ASCII case fold,
12379
+ * UTF-8 byte order, then id ASC. Date keys and their id ties use DESC. */
12380
+ sortBy: z.enum(["updatedAt", "createdAt", "name", "archivedAt"]).optional(),
12381
+ archiveStatus: z.enum(["active", "archived", "all"]).optional(),
12746
12382
  originSiteId: z.string().uuid().optional(),
12747
12383
  /** True when older matching pins were omitted from this bounded page. */
12748
12384
  pinnedTruncated: z.boolean().optional(),
@@ -13237,6 +12873,10 @@ export type ToolAuthNeededReason = z.infer<typeof ToolAuthNeededReason>;
13237
12873
  export const ToolAuthNeededPayload = z
13238
12874
  .object({
13239
12875
  serverId: z.string().min(1),
12876
+ /** Exact configured connector for recovery; serverId remains the execution route. */
12877
+ canonicalServerId: z.string().min(1).optional(),
12878
+ /** Scope of the exact failed account, not the canonical catalog default. */
12879
+ connectionSubjectScope: z.enum(["workspace", "subject"]).optional(),
13240
12880
  toolName: z.string().min(1).nullable().optional(),
13241
12881
  providerDomain: z.string().min(1),
13242
12882
  provider: z.string().min(1).max(128).optional(),
@@ -15103,7 +14743,7 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15103
14743
  */
15104
14744
  requestedSessionId: z.string().uuid().optional(),
15105
14745
  /** Explicit external-owner grants for the direct initial turn only. */
15106
- selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
14746
+
15107
14747
  /** Top-level omission is workspace-visible. Agent-child omission inherits
15108
14748
  * the exact parent visibility; cross-visibility child creation is rejected.
15109
14749
  * Top-level private creation is an activated managed-cookie owning-human
@@ -15154,7 +14794,7 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15154
14794
  // trusted parent's selection; an explicit array, including [], wins.
15155
14795
  skills: SessionSkills.default([]),
15156
14796
  // Immutable workspace Skill identities to copy onto this session at
15157
- // creation. This is the explicit opt-in path for session-selected Pack
14797
+
15158
14798
  // Skills: installation alone never exposes them to model context. Child
15159
14799
  // omission still inherits the parent's already-materialized session Skills.
15160
14800
  installedSkillIds: z
@@ -15168,6 +14808,7 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15168
14808
  // omission still applies workspace-default capability MCP tools; explicit []
15169
14809
  // suppresses those defaults (the first-party OpenGeni server remains added).
15170
14810
  tools: z.array(ToolRef).default([]),
14811
+ excludedMcpServerIds: SessionExcludedMcpServerIds.optional(),
15171
14812
  metadata: z.record(z.string(), z.unknown()).default({}),
15172
14813
  model: z.string().min(1).optional(),
15173
14814
  reasoningEffort: ReasoningEffort.optional(),
@@ -15237,8 +14878,12 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15237
14878
  // permission. Credential headers are write-only: create responses and events
15238
14879
  // expose only SessionMcpServerMetadata.
15239
14880
  mcpServers: z.array(SessionMcpServerInput).max(SESSION_MCP_SERVERS_MAX).default([]),
15240
- /** Explicit personal-connection grants for the initial accepted turn. */
15241
- connectionAuthorities: McpConnectionAuthoritySelections.default([]),
14881
+ // Override approval policy without copying inherited capability definitions.
14882
+ // Unknown/disabled servers are rejected; curated approval floors still apply.
14883
+ mcpApprovalPolicies: SessionMcpApprovalPolicies.optional(),
14884
+ /** Optional account choices among the authenticated sender’s own connections. */
14885
+ connectionAuthorities: z.never().optional(),
14886
+ connectionAccounts: McpConnectionAccountSelections.default([]),
15242
14887
  /** Atomic owner issuance for the selected personal Variable Set/Rig closure. */
15243
14888
  personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
15244
14889
  // Shared-sandbox placement (addendum 05 §D.1). Three-way union; OMITTED ⇒
@@ -15271,7 +14916,7 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15271
14916
  ])
15272
14917
  .optional(),
15273
14918
  },
15274
- { rejectKeys: ["turnInstructions"] },
14919
+ { rejectKeys: ["turnInstructions", "selectedHostMcpDelegations"] },
15275
14920
  ).superRefine((value, context) => {
15276
14921
  if (value.startMode !== "realtime" && value.initialMessage === undefined) {
15277
14922
  context.addIssue({
@@ -15294,12 +14939,12 @@ export const CreateSessionRequest = /* @__PURE__ */ defineSkillContractSchema(()
15294
14939
  message: "modelContext requires an initialMessage; attach it to a realtime entry instead",
15295
14940
  });
15296
14941
  }
15297
- if (value.startMode === "realtime" && value.connectionAuthorities.length > 0) {
14942
+ if (value.startMode === "realtime" && value.connectionAccounts.length > 0) {
15298
14943
  context.addIssue({
15299
14944
  code: z.ZodIssueCode.custom,
15300
- path: ["connectionAuthorities"],
14945
+ path: ["connectionAccounts"],
15301
14946
  message:
15302
- "connectionAuthorities require an accepted initial turn and are not supported by realtime session staging",
14947
+ "connectionAccounts require an accepted initial turn and are not supported by realtime session staging",
15303
14948
  });
15304
14949
  }
15305
14950
  if (value.startMode === "realtime" && value.personalResourceAttachment !== undefined) {
@@ -15351,7 +14996,9 @@ export const HumanInputQuestion = z
15351
14996
  prompt: z.string().min(1).max(4096),
15352
14997
  label: z.string().min(1).max(128).nullable().optional(),
15353
14998
  helpText: z.string().max(2048).nullable().optional(),
15354
- skillReview: SkillReviewReference.optional(),
14999
+ // Strict model tool schemas encode an absent optional object as null.
15000
+ // A real review reference still requires every authority-bearing field.
15001
+ skillReview: SkillReviewReference.nullable().optional(),
15355
15002
  options: z.array(HumanInputOption).max(20).default([]),
15356
15003
  required: z.boolean().default(true),
15357
15004
  // Retained on the wire for older hosts. OpenGeni's stock runtime and
@@ -15564,9 +15211,9 @@ export const SessionUserMessagePayload = z
15564
15211
  // Header-value rotation only. URL/name/tool settings are immutable after
15565
15212
  // session create; persisted events expose metadata, never header values.
15566
15213
  mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
15567
- /** Explicit personal-connection grants for this exact logical turn. */
15568
- connectionAuthorities: McpConnectionAuthoritySelections.default([]),
15569
- selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
15214
+ /** Optional choices among the authenticated sender’s own accounts. */
15215
+ connectionAuthorities: z.never().optional(),
15216
+ connectionAccounts: McpConnectionAccountSelections.default([]),
15570
15217
  personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
15571
15218
  })
15572
15219
  .strict()
@@ -15614,9 +15261,9 @@ export const SteerSessionMessageRequest = z
15614
15261
  controlEtag: z.string().min(1).optional(),
15615
15262
  expectedDraftRevision: z.number().int().nonnegative().optional(),
15616
15263
  mcpCredentialUpdates: z.array(SessionMcpCredentialUpdateInput).optional(),
15617
- /** Explicit personal-connection grants for this exact steered turn. */
15618
- connectionAuthorities: McpConnectionAuthoritySelections.default([]),
15619
- selectedHostMcpDelegations: HostMcpCreateSelections.optional(),
15264
+ /** Optional choices among the authenticated sender’s own accounts. */
15265
+ connectionAuthorities: z.never().optional(),
15266
+ connectionAccounts: McpConnectionAccountSelections.default([]),
15620
15267
  personalResourceAttachment: PersonalResourceAttachmentIntent.optional(),
15621
15268
  })
15622
15269
  .strict()
@@ -17106,7 +16753,7 @@ export type WorkspaceModelCatalogResponse = z.infer<typeof WorkspaceModelCatalog
17106
16753
  * that rollout boundary. Mutating clients send this value in
17107
16754
  * `x-opengeni-api-contract`; the API rejects any other value before routing.
17108
16755
  */
17109
- export const OPENGENI_API_CONTRACT_REVISION = "2026-08-organization-recovery-custody-v1" as const;
16756
+ export const OPENGENI_API_CONTRACT_REVISION = "2026-09-plugins-and-skills-v1" as const;
17110
16757
  export const OPENGENI_API_CONTRACT_HEADER = "x-opengeni-api-contract" as const;
17111
16758
  /** Bounded request/response identifier shared by browser, ingress, and API diagnostics. */
17112
16759
  export const OPENGENI_CORRELATION_HEADER = "x-opengeni-correlation-id" as const;
@@ -17292,6 +16939,7 @@ export * from "./model-context-inspector";
17292
16939
  export * from "./workspace-learning-policy";
17293
16940
  export * from "./agent-learning";
17294
16941
  export * from "./knowledge-entries";
16942
+ export * from "./knowledge-preparation";
17295
16943
  export * from "./workspace-learning-administration";
17296
16944
  export * from "./workspace-state";
17297
16945
  export * from "./preference-registry";
@@ -17312,3 +16960,6 @@ export * from "./feedback";
17312
16960
  export type { PluginDiscoveryItem, PluginDiscoveryPage } from "./plugin-discovery";
17313
16961
  export { mcpEndpointIdentity } from "./mcp-endpoint";
17314
16962
  export { pluginMcpUnavailableReason } from "./mcp-endpoint";
16963
+ export * from "./connector-tool-permissions";
16964
+ export * from "./skill-catalog-context";
16965
+ export * from "./sandbox-recovery";