@mdbase-dev/connect-protocol 0.1.0-beta.92 → 0.1.0-beta.94

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.
@@ -264,6 +264,10 @@ export declare const CONNECT_PROBLEM_CATALOG: {
264
264
  readonly category: "integrity";
265
265
  readonly recovery: "contact_support";
266
266
  };
267
+ readonly legacy_scope_reauthorization_required: {
268
+ readonly category: "authorization";
269
+ readonly recovery: "reauthorize";
270
+ };
267
271
  readonly managed_fcm_not_declared: {
268
272
  readonly category: "compatibility";
269
273
  readonly recovery: "fix_request";
@@ -595,6 +599,7 @@ export interface ConnectProblemDetailsByCode {
595
599
  "invalid_read_cursor": undefined;
596
600
  "invalid_request": undefined;
597
601
  "invalid_token_response": undefined;
602
+ "legacy_scope_reauthorization_required": undefined;
598
603
  "managed_fcm_not_declared": undefined;
599
604
  "manifest_load_failed": undefined;
600
605
  "manifest_required": undefined;
@@ -1058,6 +1063,12 @@ export interface ConnectProblemByCode {
1058
1063
  recovery: "contact_support";
1059
1064
  details?: never;
1060
1065
  };
1066
+ "legacy_scope_reauthorization_required": ConnectProblemBase & {
1067
+ code: "legacy_scope_reauthorization_required";
1068
+ category: "authorization";
1069
+ recovery: "reauthorize";
1070
+ details?: never;
1071
+ };
1061
1072
  "managed_fcm_not_declared": ConnectProblemBase & {
1062
1073
  code: "managed_fcm_not_declared";
1063
1074
  category: "compatibility";
@@ -67,6 +67,7 @@ export const CONNECT_PROBLEM_CATALOG = {
67
67
  "invalid_read_cursor": { category: "validation", recovery: "fix_request" },
68
68
  "invalid_request": { category: "validation", recovery: "fix_request" },
69
69
  "invalid_token_response": { category: "integrity", recovery: "contact_support" },
70
+ "legacy_scope_reauthorization_required": { category: "authorization", recovery: "reauthorize" },
70
71
  "managed_fcm_not_declared": { category: "compatibility", recovery: "fix_request" },
71
72
  "manifest_load_failed": { category: "availability", recovery: "retry" },
72
73
  "manifest_required": { category: "validation", recovery: "fix_request" },
package/dist/index.d.ts CHANGED
@@ -102,11 +102,15 @@ export interface ApplicationNotifications {
102
102
  * `id` is stable presentation metadata rather than proof of a publisher. Each
103
103
  * exact declaration is independently identified and authorized by Connect.
104
104
  */
105
+ export type CanonicalApplicationRequirements = Omit<ApplicationRequirements, "access" | "contracts"> & {
106
+ access: "full_collection";
107
+ contracts: [];
108
+ };
105
109
  interface MdbaseAppManifestBase {
106
110
  manifest_version: 1;
107
111
  id: string;
108
112
  name: string;
109
- requirements?: ApplicationRequirements;
113
+ requirements: CanonicalApplicationRequirements;
110
114
  provisions?: ApplicationProvisions;
111
115
  notifications?: ApplicationNotifications;
112
116
  }
@@ -164,7 +168,11 @@ export interface ApplicationRequirements {
164
168
  configuration?: ConfigurationRequirement[];
165
169
  /** Versioned semantic intent compiled by Connect into exact operations. */
166
170
  capabilities?: ApplicationCapabilityRequirements;
167
- /** Access boundary requested after compatibility and provisioning checks. */
171
+ /**
172
+ * Collection boundary request. New declarations must explicitly use
173
+ * `full_collection`; omitted and `contract` remain parseable only for legacy
174
+ * diagnosis and reauthorization.
175
+ */
168
176
  access?: "contract" | "full_collection";
169
177
  /** Restrict authorization to durable provider-backed collections. */
170
178
  collection_kind?: "hosted";
@@ -178,11 +186,12 @@ export interface ApplicationProvisions {
178
186
  }
179
187
  export interface GrantScope {
180
188
  /**
181
- * Exact contract definitions and sorted implementation sets approved by the
182
- * user. Digests make the scope fail closed if either the interface or any
183
- * provider changes after approval.
189
+ * Legacy semantic scope payload retained for wire/storage compatibility.
190
+ * Canonical application grants use an empty array; contracts remain available
191
+ * through collection resources and operation-level semantic selectors.
184
192
  */
185
193
  contracts: CollectionContractDescriptor[];
194
+ /** New authority must be `full_collection`; `contract` is legacy-only. */
186
195
  access: "contract" | "full_collection";
187
196
  }
188
197
  export interface RelayOperationRequest {
@@ -519,10 +528,11 @@ export interface RelayPolicySnapshot {
519
528
  protocol_version: 1;
520
529
  request_id: string;
521
530
  revision: string;
522
- connector_id: string;
523
- sequence: number;
524
- lease_issued_at_ms: number;
525
- lease_expires_at_ms: number;
531
+ /** Lease fields are absent on legacy N-1 grants-only snapshots. */
532
+ connector_id?: string;
533
+ sequence?: number;
534
+ lease_issued_at_ms?: number;
535
+ lease_expires_at_ms?: number;
526
536
  grants: GrantPolicy[];
527
537
  }
528
538
  export interface RelayHello {
package/dist/manifest.js CHANGED
@@ -54,7 +54,6 @@ export function parseAppManifest(value, options = {}) {
54
54
  return {
55
55
  ...manifest,
56
56
  requirements: {
57
- contracts: [],
58
57
  configuration: [],
59
58
  ...manifest.requirements
60
59
  },
@@ -355,27 +354,24 @@ function validateCapabilityRequirements(value) {
355
354
  const manifest = asObject(value);
356
355
  const requirements = asObject(manifest.requirements);
357
356
  const capabilities = asObject(requirements.capabilities);
357
+ const issues = [];
358
+ if (requirements.access !== "full_collection") {
359
+ issues.push(issue("/requirements/access", "collectionAccess", "must explicitly request full_collection; legacy or omitted access is not widened"));
360
+ }
358
361
  if (Object.keys(capabilities).length === 0)
359
- return [];
362
+ return issues;
360
363
  const required = Array.isArray(capabilities.required)
361
364
  ? capabilities.required.map(String)
362
365
  : [];
363
366
  const optional = Array.isArray(capabilities.optional)
364
367
  ? capabilities.optional.map(String)
365
368
  : [];
366
- const issues = [];
367
369
  const overlap = optional.find((capability) => required.includes(capability));
368
370
  if (overlap) {
369
371
  issues.push(issue("/requirements/capabilities/optional", "disjoint", `must not repeat required capability ${overlap}`));
370
372
  }
371
373
  const declared = new Set([...required, ...optional]);
372
374
  const provisions = asObject(manifest.provisions);
373
- if (Array.isArray(requirements.contracts)
374
- && requirements.contracts.length > 0
375
- && requirements.access !== "full_collection"
376
- && !required.includes("definitions.contracts.current")) {
377
- issues.push(issue("/requirements/capabilities/required", "contractCapability", "must require definitions.contracts.current for contract-scoped requirements"));
378
- }
379
375
  if (declared.has("definitions.type-pack.apply")) {
380
376
  if (requirements.access !== "full_collection") {
381
377
  issues.push(issue("/requirements/access", "typePackAccess", "must be full_collection for definitions.type-pack.apply"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdbase-dev/connect-protocol",
3
- "version": "0.1.0-beta.92",
3
+ "version": "0.1.0-beta.94",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -2955,6 +2955,46 @@
2955
2955
  }
2956
2956
  }
2957
2957
  },
2958
+ {
2959
+ "type": "object",
2960
+ "additionalProperties": false,
2961
+ "required": [
2962
+ "problem_version",
2963
+ "code",
2964
+ "category",
2965
+ "recovery",
2966
+ "message"
2967
+ ],
2968
+ "properties": {
2969
+ "problem_version": {
2970
+ "const": 1
2971
+ },
2972
+ "code": {
2973
+ "const": "legacy_scope_reauthorization_required"
2974
+ },
2975
+ "category": {
2976
+ "const": "authorization"
2977
+ },
2978
+ "recovery": {
2979
+ "const": "reauthorize"
2980
+ },
2981
+ "message": {
2982
+ "type": "string",
2983
+ "minLength": 1
2984
+ },
2985
+ "operation_outcome": {
2986
+ "enum": [
2987
+ "not_sent",
2988
+ "rejected",
2989
+ "unknown"
2990
+ ]
2991
+ },
2992
+ "trace_id": {
2993
+ "type": "string",
2994
+ "minLength": 1
2995
+ }
2996
+ }
2997
+ },
2958
2998
  {
2959
2999
  "type": "object",
2960
3000
  "additionalProperties": false,
@@ -250,6 +250,7 @@
250
250
  "invalid_read_cursor": { "category": "validation", "recovery": "fix_request" },
251
251
  "invalid_request": { "category": "validation", "recovery": "fix_request" },
252
252
  "invalid_token_response": { "category": "integrity", "recovery": "contact_support" },
253
+ "legacy_scope_reauthorization_required": { "category": "authorization", "recovery": "reauthorize" },
253
254
  "managed_fcm_not_declared": { "category": "compatibility", "recovery": "fix_request" },
254
255
  "manifest_load_failed": { "category": "availability", "recovery": "retry" },
255
256
  "manifest_required": { "category": "validation", "recovery": "fix_request" },
@@ -111,13 +111,13 @@
111
111
  "requirements": {
112
112
  "type": "object",
113
113
  "additionalProperties": false,
114
- "required": ["contracts"],
114
+ "required": ["access", "contracts"],
115
115
  "properties": {
116
116
  "capabilities": { "$ref": "#/$defs/capabilityRequirements" },
117
117
  "access": {
118
- "enum": ["contract", "full_collection"],
119
- "description": "Access boundary requested after compatibility and provisioning checks."
120
- },
118
+ "const": "full_collection",
119
+ "description": "Compatibility declaration for collection-level application authorization."
120
+ },
121
121
  "collection_kind": {
122
122
  "const": "hosted",
123
123
  "description": "Require a durable provider-backed collection with direct sync support."