@stndrds/schema 1.0.0-alpha.185 → 1.0.0-alpha.187

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 (55) hide show
  1. package/dist/{filters-qNc-JmQI.d.ts → filters-DVBn5tov.d.ts} +81 -39
  2. package/dist/{filters-DVbxM2W4.d.mts → filters-HDG4kLoo.d.mts} +81 -39
  3. package/dist/{helpers-g5uHrKfE.d.mts → helpers-BjuFhbQQ.d.mts} +2 -2
  4. package/dist/{helpers-D-_4FAcR.d.ts → helpers-CSuoa3kj.d.ts} +2 -2
  5. package/dist/index.d.mts +185 -56
  6. package/dist/index.d.ts +185 -56
  7. package/dist/index.js +229 -105
  8. package/dist/index.mjs +215 -99
  9. package/dist/{types-CQTltaH_.d.ts → types-Bdlhgrf7.d.ts} +1 -1
  10. package/dist/{types-BTrwWar6.d.mts → types-C5DittlR.d.mts} +1 -1
  11. package/dist/validation/all.d.mts +3 -3
  12. package/dist/validation/all.d.ts +3 -3
  13. package/dist/validation/all.js +8 -8
  14. package/dist/validation/all.mjs +2 -2
  15. package/dist/validation/complex/currency.d.mts +2 -2
  16. package/dist/validation/complex/currency.d.ts +2 -2
  17. package/dist/validation/complex/file.d.mts +2 -2
  18. package/dist/validation/complex/file.d.ts +2 -2
  19. package/dist/validation/complex/location.d.mts +2 -2
  20. package/dist/validation/complex/location.d.ts +2 -2
  21. package/dist/validation/complex/phone.d.mts +2 -2
  22. package/dist/validation/complex/phone.d.ts +2 -2
  23. package/dist/validation/complex/relation.d.mts +2 -2
  24. package/dist/validation/complex/relation.d.ts +2 -2
  25. package/dist/validation/complex/richtext.d.mts +2 -2
  26. package/dist/validation/complex/richtext.d.ts +2 -2
  27. package/dist/validation/complex/select.d.mts +2 -2
  28. package/dist/validation/complex/select.d.ts +2 -2
  29. package/dist/validation/complex/user.d.mts +2 -2
  30. package/dist/validation/complex/user.d.ts +2 -2
  31. package/dist/validation/computed/formula.d.mts +2 -2
  32. package/dist/validation/computed/formula.d.ts +2 -2
  33. package/dist/validation/computed/rollup.d.mts +2 -2
  34. package/dist/validation/computed/rollup.d.ts +2 -2
  35. package/dist/validation/config/index.d.mts +1 -1
  36. package/dist/validation/config/index.d.ts +1 -1
  37. package/dist/validation/core/index.d.mts +3 -3
  38. package/dist/validation/core/index.d.ts +3 -3
  39. package/dist/validation/object/index.d.mts +3 -3
  40. package/dist/validation/object/index.d.ts +3 -3
  41. package/dist/validation/object/index.js +14 -14
  42. package/dist/validation/object/index.mjs +2 -2
  43. package/dist/validation/primitives/checkbox.d.mts +2 -2
  44. package/dist/validation/primitives/checkbox.d.ts +2 -2
  45. package/dist/validation/primitives/date.d.mts +2 -2
  46. package/dist/validation/primitives/date.d.ts +2 -2
  47. package/dist/validation/primitives/number.d.mts +2 -2
  48. package/dist/validation/primitives/number.d.ts +2 -2
  49. package/dist/validation/primitives/rating.d.mts +2 -2
  50. package/dist/validation/primitives/rating.d.ts +2 -2
  51. package/dist/validation/primitives/text.d.mts +2 -2
  52. package/dist/validation/primitives/text.d.ts +2 -2
  53. package/package.json +2 -2
  54. package/dist/{chunk-HG6EF4XD.js → chunk-64R5X3DF.js} +1 -1
  55. package/dist/{chunk-M7ZNKBOE.mjs → chunk-6JEQE4IP.mjs} +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,8 @@
3
3
  var chunkFRCDMQER_js = require('./chunk-FRCDMQER.js');
4
4
  require('./chunk-PGERPYDR.js');
5
5
  var chunkYQROI4IE_js = require('./chunk-YQROI4IE.js');
6
- var chunkHG6EF4XD_js = require('./chunk-HG6EF4XD.js');
6
+ var chunk64R5X3DF_js = require('./chunk-64R5X3DF.js');
7
+ require('./chunk-MAKSIK3P.js');
7
8
  require('./chunk-J5HRK3WD.js');
8
9
  require('./chunk-TKN73433.js');
9
10
  require('./chunk-D7WFIGXW.js');
@@ -13,7 +14,6 @@ require('./chunk-EZHMVZQ4.js');
13
14
  require('./chunk-VXOTYFEW.js');
14
15
  require('./chunk-OAQWRMTP.js');
15
16
  require('./chunk-ACQ3TUFK.js');
16
- require('./chunk-MAKSIK3P.js');
17
17
  require('./chunk-DC7YYE3U.js');
18
18
  require('./chunk-ROAZLZA2.js');
19
19
  require('./chunk-CCB4OY2O.js');
@@ -67,6 +67,9 @@ function isAttributeSortable(attr) {
67
67
  return !NON_SORTABLE_TYPES.has(attr.type);
68
68
  }
69
69
 
70
+ // src/types/document-layout.ts
71
+ var MAX_PRESET_DEPTH = 5;
72
+
70
73
  // src/types/documents.ts
71
74
  var DEFAULT_DOCUMENT_SLOT = { name: "file" };
72
75
 
@@ -94,6 +97,15 @@ var SchemaErrorCode = {
94
97
  ACCESS_DENIED: "SCHEMA_ACCESS_DENIED",
95
98
  // Sync
96
99
  SYNC_FAILED: "SCHEMA_SYNC_FAILED",
100
+ SYNC_CONFLICT: "SCHEMA_SYNC_CONFLICT",
101
+ SYNC_CASCADE: "SCHEMA_SYNC_CASCADE",
102
+ ORPHAN_SYSTEM_ATTRIBUTE: "SCHEMA_ORPHAN_SYSTEM_ATTRIBUTE",
103
+ // System Entity Immutability
104
+ SYSTEM_ENTITY_IMMUTABLE: "SCHEMA_SYSTEM_ENTITY_IMMUTABLE",
105
+ // L2 — migration system simplification (2026-05-17)
106
+ DESTRUCTIVE_NOT_ALLOWED: "SCHEMA_DESTRUCTIVE_NOT_ALLOWED",
107
+ MIGRATION_TIMEOUT: "SCHEMA_MIGRATION_TIMEOUT",
108
+ CHANGE_TYPE_NOT_SUPPORTED: "SCHEMA_CHANGE_TYPE_NOT_SUPPORTED",
97
109
  // Duplicates
98
110
  DUPLICATE_OBJECT: "SCHEMA_DUPLICATE_OBJECT",
99
111
  DUPLICATE_ATTRIBUTE: "SCHEMA_DUPLICATE_ATTRIBUTE",
@@ -207,6 +219,115 @@ var SyncError = class extends SchemaError {
207
219
  this.cause = cause;
208
220
  }
209
221
  };
222
+ var SystemEntityImmutableError = class extends SchemaError {
223
+ constructor(entityType, entityName) {
224
+ super(
225
+ `Cannot mutate system ${entityType} "${entityName}". System entities are declared in code and immutable at runtime.`,
226
+ SchemaErrorCode.SYSTEM_ENTITY_IMMUTABLE,
227
+ { entityType, entityName }
228
+ );
229
+ this.name = "SystemEntityImmutableError";
230
+ this.entityType = entityType;
231
+ this.entityName = entityName;
232
+ }
233
+ };
234
+ var SyncConflictError = class extends SchemaError {
235
+ constructor(params) {
236
+ const target = params.attributeName ? `"${params.objectName}.${params.attributeName}"` : `"${params.objectName}"`;
237
+ super(
238
+ `Cannot promote runtime entity ${target}: ${params.reason}. Resolve via: (1) relax the code constraint, (2) migrate runtime values manually, or (3) rename the code declaration.`,
239
+ SchemaErrorCode.SYNC_CONFLICT,
240
+ {
241
+ objectName: params.objectName,
242
+ attributeName: params.attributeName,
243
+ reason: params.reason
244
+ }
245
+ );
246
+ this.name = "SyncConflictError";
247
+ this.objectName = params.objectName;
248
+ this.attributeName = params.attributeName;
249
+ this.reason = params.reason;
250
+ }
251
+ };
252
+ var SyncCascadeError = class extends SchemaError {
253
+ constructor(objectName, conflictingAttributes) {
254
+ super(
255
+ `Cannot demote object "${objectName}": attributes ${conflictingAttributes.join(", ")} are still declared in code. Remove them from code first, or restore the object.`,
256
+ SchemaErrorCode.SYNC_CASCADE,
257
+ { objectName, conflictingAttributes }
258
+ );
259
+ this.name = "SyncCascadeError";
260
+ this.objectName = objectName;
261
+ this.conflictingAttributes = conflictingAttributes;
262
+ }
263
+ };
264
+ var OrphanSystemAttributeError = class extends SchemaError {
265
+ constructor(objectName, attributeName) {
266
+ super(
267
+ `Attribute "${objectName}.${attributeName}" is system:true but its object parent is system:false. This is an invariant violation.`,
268
+ SchemaErrorCode.ORPHAN_SYSTEM_ATTRIBUTE,
269
+ { objectName, attributeName }
270
+ );
271
+ this.name = "OrphanSystemAttributeError";
272
+ this.objectName = objectName;
273
+ this.attributeName = attributeName;
274
+ }
275
+ };
276
+ var DestructiveSyncNotAllowedError = class extends SchemaError {
277
+ constructor(operations) {
278
+ const summary = operations.map((op) => {
279
+ if (op.type === "remove_attribute") {
280
+ return `- remove_attribute "${op.objectName ?? "?"}.${op.name}"`;
281
+ }
282
+ if (op.type === "remove_object") {
283
+ return "- remove_object";
284
+ }
285
+ return `- ${op.type}`;
286
+ }).join("\n");
287
+ super(
288
+ `Destructive schema operations detected (data will be lost):
289
+ ${summary}
290
+
291
+ To allow Standards to apply these automatically, set the environment variable:
292
+ STANDARDS_ALLOW_DESTRUCTIVE_SYNC=1
293
+
294
+ Otherwise, revert your code changes or back up the data first.`,
295
+ SchemaErrorCode.DESTRUCTIVE_NOT_ALLOWED,
296
+ { operations }
297
+ );
298
+ this.name = "DestructiveSyncNotAllowedError";
299
+ this.operations = operations;
300
+ }
301
+ };
302
+ var MigrationTimeoutError = class extends SchemaError {
303
+ constructor(objectName, migrated, total, maxDurationMs) {
304
+ super(
305
+ `Migration for "${objectName}" exceeded the maximum duration (${maxDurationMs}ms). Migrated ${migrated}/${total} records before timeout. Increase STANDARDS_MIGRATION_MAX_DURATION_MS or split the migration into smaller batches.`,
306
+ SchemaErrorCode.MIGRATION_TIMEOUT,
307
+ { objectName, migrated, total, maxDurationMs }
308
+ );
309
+ this.name = "MigrationTimeoutError";
310
+ this.objectName = objectName;
311
+ this.migrated = migrated;
312
+ this.total = total;
313
+ this.maxDurationMs = maxDurationMs;
314
+ }
315
+ };
316
+ var ChangeTypeNotSupportedError = class extends SchemaError {
317
+ constructor(objectName, attributeName) {
318
+ super(
319
+ `Cannot change type of attribute "${objectName}.${attributeName}" via runtime API. Declare a migration in your schema code:
320
+ object("${objectName}").migration(N, (m) =>
321
+ m.changeType("${attributeName}", from, to, { transform: (v) => ... })
322
+ )`,
323
+ SchemaErrorCode.CHANGE_TYPE_NOT_SUPPORTED,
324
+ { objectName, attributeName }
325
+ );
326
+ this.name = "ChangeTypeNotSupportedError";
327
+ this.objectName = objectName;
328
+ this.attributeName = attributeName;
329
+ }
330
+ };
210
331
  var DuplicateError = class extends SchemaError {
211
332
  constructor(resourceType, resourceName) {
212
333
  const code = resourceType === "object" ? SchemaErrorCode.DUPLICATE_OBJECT : SchemaErrorCode.DUPLICATE_ATTRIBUTE;
@@ -430,21 +551,15 @@ var OPERATORS_BY_TYPE = {
430
551
  select: ["is", "is_not", "any_of", "none_of", "is_empty", "is_not_empty"],
431
552
  multiselect: ["contains", "not_contains", "is_empty", "is_not_empty"],
432
553
  location: ["contains", "is_empty", "is_not_empty"],
433
- // Reference attribute types (file, user, relation, document) all route
434
- // through the edge filter resolver, which normalizes is/is_not/any_of/
435
- // none_of/contains/not_contains via `getOperatorPolarity` +
436
- // `normalizeForEdgeRpc`. Keep the operator lists symmetric so the schema
437
- // validation matches what the runtime actually supports.
438
- file: [
439
- "is",
440
- "is_not",
441
- "any_of",
442
- "none_of",
443
- "contains",
444
- "not_contains",
445
- "is_empty",
446
- "is_not_empty"
447
- ],
554
+ // Reference attribute types (user, relation) all route through the edge
555
+ // filter resolver, which normalizes is/is_not/any_of/none_of/contains/
556
+ // not_contains via `getOperatorPolarity` + `normalizeForEdgeRpc`. Keep the
557
+ // operator lists symmetric so the schema validation matches what the runtime
558
+ // actually supports.
559
+ // File and document attributes only expose presence operators — qualified
560
+ // filters (via `.qualifyWith()` on document) keep their own operator set
561
+ // based on the property type.
562
+ file: ["is_empty", "is_not_empty"],
448
563
  user: [
449
564
  "is",
450
565
  "is_not",
@@ -481,17 +596,7 @@ var OPERATORS_BY_TYPE = {
481
596
  "is_empty",
482
597
  "is_not_empty"
483
598
  ],
484
- // Document: same edge-backed operator set as relation / user / file.
485
- document: [
486
- "is",
487
- "is_not",
488
- "any_of",
489
- "none_of",
490
- "contains",
491
- "not_contains",
492
- "is_empty",
493
- "is_not_empty"
494
- ]
599
+ document: ["is_empty", "is_not_empty"]
495
600
  };
496
601
  var NO_VALUE_OPERATORS = [
497
602
  "is_empty",
@@ -585,8 +690,8 @@ var RESERVED_ATTRIBUTE_NAMES = [
585
690
  "values",
586
691
  "metadata",
587
692
  "deletedAt",
588
- "schemaVersion",
589
- "archivedValues"
693
+ "deletedBy",
694
+ "schemaVersion"
590
695
  ];
591
696
 
592
697
  // src/types/permissions.ts
@@ -688,7 +793,6 @@ var SYSTEM_ATTRIBUTES = {
688
793
  system: true,
689
794
  hidden: true,
690
795
  // Hidden from regular form views
691
- multiple: true,
692
796
  icon: "paperclip",
693
797
  description: "Free-form document attachments"
694
798
  }
@@ -1157,7 +1261,9 @@ var SYSTEM_RESOURCES = {
1157
1261
  /** Audit log access */
1158
1262
  AUDIT: "audit",
1159
1263
  /** Programmatic access keys */
1160
- API_KEYS: "api-keys"
1264
+ API_KEYS: "api-keys",
1265
+ /** Agent session visibility — required for an agent actor to read its own sessions */
1266
+ SESSION: "session"
1161
1267
  };
1162
1268
  var ALL_SYSTEM_RESOURCES = [
1163
1269
  SYSTEM_RESOURCES.PEOPLE,
@@ -1169,7 +1275,8 @@ var ALL_SYSTEM_RESOURCES = [
1169
1275
  SYSTEM_RESOURCES.FORMS,
1170
1276
  SYSTEM_RESOURCES.DOCUMENTS,
1171
1277
  SYSTEM_RESOURCES.AUDIT,
1172
- SYSTEM_RESOURCES.API_KEYS
1278
+ SYSTEM_RESOURCES.API_KEYS,
1279
+ SYSTEM_RESOURCES.SESSION
1173
1280
  ];
1174
1281
  var SYSTEM_RESOURCE_LABELS = {
1175
1282
  people: "People",
@@ -1181,7 +1288,8 @@ var SYSTEM_RESOURCE_LABELS = {
1181
1288
  forms: "Forms",
1182
1289
  documents: "Documents",
1183
1290
  audit: "Audit",
1184
- "api-keys": "API keys"
1291
+ "api-keys": "API keys",
1292
+ session: "Agent sessions"
1185
1293
  };
1186
1294
  var DEFAULT_ROLES = {
1187
1295
  /** Full platform access - can manage everything */
@@ -1217,7 +1325,10 @@ var DEFAULT_ROLE_PERMISSIONS = {
1217
1325
  agent_default: {
1218
1326
  system: [
1219
1327
  { target: "documents", actions: ["read", "create", "update"] },
1220
- { target: "files", actions: ["read", "create", "update"] }
1328
+ { target: "files", actions: ["read", "create", "update"] },
1329
+ // Required so the agent actor can read its own sessions when the worker
1330
+ // resumes a queued job under the agent's identity (runAsAgentActor).
1331
+ { target: "session", actions: ["observe"] }
1221
1332
  ],
1222
1333
  object: [{ target: "*", actions: ["read", "create", "update", "delete"] }]
1223
1334
  }
@@ -1360,7 +1471,7 @@ var BaseAttributeBuilder = class {
1360
1471
  * @see https://standardschema.dev/
1361
1472
  */
1362
1473
  get "~standard"() {
1363
- const zodSchema = chunkHG6EF4XD_js.createAttributeValidator(this.build());
1474
+ const zodSchema = chunk64R5X3DF_js.createAttributeValidator(this.build());
1364
1475
  return createStandardSchemaProps(zodSchema);
1365
1476
  }
1366
1477
  constructor(type, name, label) {
@@ -1370,7 +1481,10 @@ var BaseAttributeBuilder = class {
1370
1481
  name,
1371
1482
  label,
1372
1483
  type,
1373
- required: false
1484
+ required: false,
1485
+ // Default: system entities are declared in code and immutable at runtime.
1486
+ // Use .runtime() to opt out (advanced use only — tests, seeds, fixtures).
1487
+ system: true
1374
1488
  };
1375
1489
  }
1376
1490
  setRequired(value) {
@@ -1411,8 +1525,22 @@ var BaseAttributeBuilder = class {
1411
1525
  asPhantomState() {
1412
1526
  return this;
1413
1527
  }
1414
- system() {
1415
- this.attr.system = true;
1528
+ /**
1529
+ * Marks this attribute as runtime-only (system: false).
1530
+ *
1531
+ * ⚠️ ADVANCED USE ONLY. In production schemas, attributes declared in code are
1532
+ * automatically system:true (immutable at runtime). Use .runtime() ONLY for:
1533
+ * - Test fixtures (`*.test.ts`, `tests/`)
1534
+ * - Seed data (`seeds/`)
1535
+ * - Dev fixtures (`fixtures/`)
1536
+ *
1537
+ * Calling .runtime() in production code creates an attribute that:
1538
+ * - Can be modified or deleted by end users via the admin UI
1539
+ * - Is not part of your code contract
1540
+ * - Will be picked up by `standards diff` as runtime drift
1541
+ */
1542
+ runtime() {
1543
+ this.attr.system = false;
1416
1544
  return this;
1417
1545
  }
1418
1546
  disabled() {
@@ -1998,7 +2126,7 @@ var SingleRelationAttributeBuilder = class extends BaseRelationAttributeBuilder
1998
2126
  isRequired: this.attr.required
1999
2127
  }
2000
2128
  );
2001
- if (this.attr.system) multiBuilder.system();
2129
+ if (this.attr.system === false) multiBuilder.runtime();
2002
2130
  if (this.attr.hidden) multiBuilder.hidden();
2003
2131
  if (this.attr.disabled) multiBuilder.disabled();
2004
2132
  if (this.attr.placeholder) multiBuilder.placeholder(this.attr.placeholder);
@@ -2207,15 +2335,7 @@ var DocumentAttributeBuilder = class extends BaseAttributeBuilder {
2207
2335
  super("document", name, label);
2208
2336
  }
2209
2337
  /**
2210
- * Allow multiple documents.
2211
- * Value becomes string[] instead of string (or Array<{ id; props }> when qualified).
2212
- */
2213
- multiple() {
2214
- this.attr.multiple = true;
2215
- return this;
2216
- }
2217
- /**
2218
- * Maximum number of documents (only applies when multiple: true).
2338
+ * Maximum number of documents.
2219
2339
  */
2220
2340
  maxDocuments(count) {
2221
2341
  this.attr.maxDocuments = count;
@@ -2274,7 +2394,6 @@ var DocumentAttributeBuilder = class extends BaseAttributeBuilder {
2274
2394
  *
2275
2395
  * @example
2276
2396
  * document({ name: "contracts", label: "Contracts" })
2277
- * .multiple()
2278
2397
  * .qualifyWith(
2279
2398
  * select({ name: "kind", label: "Kind" }).options([...]),
2280
2399
  * number({ name: "amount", label: "Amount" }).min(0),
@@ -2614,30 +2733,6 @@ function resolveBuiltInTransform(targetType) {
2614
2733
  };
2615
2734
  return map[targetType];
2616
2735
  }
2617
- function reverseOperation(op) {
2618
- switch (op.type) {
2619
- case "rename_attribute":
2620
- return { type: "rename_attribute", from: op.to, to: op.from };
2621
- case "add_attribute":
2622
- return { type: "remove_attribute", name: op.attribute.name, backup_config: op.attribute };
2623
- case "remove_attribute":
2624
- return { type: "add_attribute", attribute: op.backup_config };
2625
- case "change_type":
2626
- return {
2627
- type: "change_type",
2628
- name: op.name,
2629
- from: op.to,
2630
- to: op.from,
2631
- transform: op.transform ? resolveBuiltInTransform(op.from) : void 0
2632
- };
2633
- case "update_config":
2634
- return { type: "update_config", name: op.name, from: op.to, to: op.from };
2635
- case "rename_object":
2636
- return { type: "rename_object", from: op.to, to: op.from };
2637
- case "remove_object":
2638
- return { type: "remove_object", backup: op.backup };
2639
- }
2640
- }
2641
2736
  var MigrationBuilder = class {
2642
2737
  constructor(version) {
2643
2738
  this.operations = [];
@@ -2723,14 +2818,12 @@ var MigrationBuilder = class {
2723
2818
  // BUILD
2724
2819
  // --------------------------------------------------------------------------
2725
2820
  /**
2726
- * Produce the final MigrationDefinition with auto-generated reverse operations.
2821
+ * Produce the final MigrationDefinition.
2727
2822
  */
2728
2823
  build() {
2729
- const reverse_operations = [...this.operations].reverse().map((op) => reverseOperation(op));
2730
2824
  return {
2731
2825
  version: this.version,
2732
- operations: [...this.operations],
2733
- reverse_operations
2826
+ operations: [...this.operations]
2734
2827
  };
2735
2828
  }
2736
2829
  };
@@ -2744,7 +2837,7 @@ var ObjectBuilder = class {
2744
2837
  name: config.name,
2745
2838
  label: config.label,
2746
2839
  attributes: [],
2747
- system: false
2840
+ system: true
2748
2841
  };
2749
2842
  }
2750
2843
  /**
@@ -2756,7 +2849,7 @@ var ObjectBuilder = class {
2756
2849
  * @see https://standardschema.dev/
2757
2850
  */
2758
2851
  get "~standard"() {
2759
- const zodSchema = chunkHG6EF4XD_js.createObjectValidator(this.build());
2852
+ const zodSchema = chunk64R5X3DF_js.createObjectValidator(this.build());
2760
2853
  return createStandardSchemaProps(zodSchema);
2761
2854
  }
2762
2855
  /**
@@ -2782,11 +2875,21 @@ var ObjectBuilder = class {
2782
2875
  return this;
2783
2876
  }
2784
2877
  /**
2785
- * Mark as system/native object (defined in code, protected)
2786
- * System objects cannot be deleted/modified by clients
2878
+ * Marks this object as runtime-only (system: false).
2879
+ *
2880
+ * ⚠️ ADVANCED USE ONLY. In production schemas, objects declared in code are
2881
+ * automatically system:true (immutable at runtime). Use .runtime() ONLY for:
2882
+ * - Test fixtures (`*.test.ts`, `tests/`)
2883
+ * - Seed data (`seeds/`)
2884
+ * - Dev fixtures (`fixtures/`)
2885
+ *
2886
+ * Calling .runtime() in production code creates an object that:
2887
+ * - Can be modified or deleted by end users via the admin UI
2888
+ * - Is not part of your code contract
2889
+ * - Will be picked up by `standards diff` as runtime drift
2787
2890
  */
2788
- system() {
2789
- this.obj.system = true;
2891
+ runtime() {
2892
+ this.obj.system = false;
2790
2893
  return this;
2791
2894
  }
2792
2895
  /**
@@ -2857,6 +2960,19 @@ var ObjectBuilder = class {
2857
2960
  this._labelExpression = template;
2858
2961
  return this;
2859
2962
  }
2963
+ /**
2964
+ * Attach a document layout convention to this object. Defines named variant
2965
+ * sub-folders and installable preset structures inside a record's drive.
2966
+ */
2967
+ documentLayout(layout) {
2968
+ if (layout.presets) {
2969
+ for (const preset of layout.presets) {
2970
+ validatePresetDepth(preset.structure, 1);
2971
+ }
2972
+ }
2973
+ this.obj.documentLayout = layout;
2974
+ return this;
2975
+ }
2860
2976
  /**
2861
2977
  * Declare a schema migration for this object.
2862
2978
  *
@@ -2957,6 +3073,16 @@ The labelExpression defines how records are displayed in lists and relations.
2957
3073
  function object(config) {
2958
3074
  return new ObjectBuilder(config);
2959
3075
  }
3076
+ function validatePresetDepth(nodes, depth) {
3077
+ if (depth > MAX_PRESET_DEPTH) {
3078
+ throw new Error(`Preset structure exceeds max depth of ${MAX_PRESET_DEPTH}`);
3079
+ }
3080
+ for (const node of nodes) {
3081
+ if (node.children && node.children.length > 0) {
3082
+ validatePresetDepth(node.children, depth + 1);
3083
+ }
3084
+ }
3085
+ }
2960
3086
  var GroupBuilder = class {
2961
3087
  constructor(id, label) {
2962
3088
  this.data = { fields: [] };
@@ -4525,8 +4651,8 @@ var NativeObjectRegistryClass = class {
4525
4651
  * @example
4526
4652
  * ```typescript
4527
4653
  * // No .build() needed - registry auto-builds!
4654
+ * // Objects are system:true by default (immutable at runtime).
4528
4655
  * const PRODUCT = object({ id: "obj-product", name: "products", label: "Product" })
4529
- * .system()
4530
4656
  * .attribute(text({ id: "attr-name", name: "name", label: "Name" }));
4531
4657
  *
4532
4658
  * registry.register(PRODUCT); // ← Auto-builds here
@@ -4554,7 +4680,7 @@ var NativeObjectRegistryClass = class {
4554
4680
  if (!object2.system) {
4555
4681
  throw new Error(
4556
4682
  `[NativeObjectRegistry] Cannot register object "${object2.name}" (id: ${object2.id}): missing system flag.
4557
- Native objects must have system=true. Did you forget to call .system() in your builder?`
4683
+ Native objects must have system=true. Did you call .runtime() on the builder? Remove that call \u2014 objects are system:true by default.`
4558
4684
  );
4559
4685
  }
4560
4686
  if (this.objects.has(object2.name)) {
@@ -5431,7 +5557,6 @@ var OPERATOR_SPECS = {
5431
5557
  "user",
5432
5558
  "multiselect",
5433
5559
  "relation",
5434
- "document",
5435
5560
  "formula"
5436
5561
  ],
5437
5562
  evaluateInMemory: (v, rv) => {
@@ -5440,16 +5565,7 @@ var OPERATOR_SPECS = {
5440
5565
  }
5441
5566
  },
5442
5567
  not_contains: {
5443
- appliesTo: [
5444
- "text",
5445
- "textarea",
5446
- "phone",
5447
- "user",
5448
- "multiselect",
5449
- "relation",
5450
- "document",
5451
- "formula"
5452
- ],
5568
+ appliesTo: ["text", "textarea", "phone", "user", "multiselect", "relation", "formula"],
5453
5569
  evaluateInMemory: (v, rv) => {
5454
5570
  if (Array.isArray(v)) return !v.map(toStr).includes(toStr(rv));
5455
5571
  return !toStr(v).toLowerCase().includes(toStr(rv).toLowerCase());
@@ -5611,7 +5727,7 @@ var OPERATOR_SPECS = {
5611
5727
  },
5612
5728
  // ---- select multi-value ----
5613
5729
  any_of: {
5614
- appliesTo: ["status", "select", "relation", "document"],
5730
+ appliesTo: ["status", "select", "relation"],
5615
5731
  evaluateInMemory: (v, rv) => {
5616
5732
  const ruleArr = toArr(rv).map(toStr);
5617
5733
  const valArr = toArr(v).map(toStr);
@@ -5619,7 +5735,7 @@ var OPERATOR_SPECS = {
5619
5735
  }
5620
5736
  },
5621
5737
  none_of: {
5622
- appliesTo: ["status", "select", "relation", "document"],
5738
+ appliesTo: ["status", "select", "relation"],
5623
5739
  evaluateInMemory: (v, rv) => {
5624
5740
  const ruleArr = toArr(rv).map(toStr);
5625
5741
  const valArr = toArr(v).map(toStr);
@@ -5783,27 +5899,27 @@ Object.defineProperty(exports, "parseAttributeConfig", {
5783
5899
  });
5784
5900
  Object.defineProperty(exports, "computeRecordStatus", {
5785
5901
  enumerable: true,
5786
- get: function () { return chunkHG6EF4XD_js.computeRecordStatus; }
5902
+ get: function () { return chunk64R5X3DF_js.computeRecordStatus; }
5787
5903
  });
5788
5904
  Object.defineProperty(exports, "createFormAttributeValidator", {
5789
5905
  enumerable: true,
5790
- get: function () { return chunkHG6EF4XD_js.createFormAttributeValidator; }
5906
+ get: function () { return chunk64R5X3DF_js.createFormAttributeValidator; }
5791
5907
  });
5792
5908
  Object.defineProperty(exports, "validateDraft", {
5793
5909
  enumerable: true,
5794
- get: function () { return chunkHG6EF4XD_js.validateDraft; }
5910
+ get: function () { return chunk64R5X3DF_js.validateDraft; }
5795
5911
  });
5796
5912
  Object.defineProperty(exports, "validateDraftOrThrow", {
5797
5913
  enumerable: true,
5798
- get: function () { return chunkHG6EF4XD_js.validateDraftOrThrow; }
5914
+ get: function () { return chunk64R5X3DF_js.validateDraftOrThrow; }
5799
5915
  });
5800
5916
  Object.defineProperty(exports, "validateObject", {
5801
5917
  enumerable: true,
5802
- get: function () { return chunkHG6EF4XD_js.validateObject; }
5918
+ get: function () { return chunk64R5X3DF_js.validateObject; }
5803
5919
  });
5804
5920
  Object.defineProperty(exports, "validateObjectOrThrow", {
5805
5921
  enumerable: true,
5806
- get: function () { return chunkHG6EF4XD_js.validateObjectOrThrow; }
5922
+ get: function () { return chunk64R5X3DF_js.validateObjectOrThrow; }
5807
5923
  });
5808
5924
  Object.defineProperty(exports, "DEFAULT_VALIDATION_MESSAGES", {
5809
5925
  enumerable: true,
@@ -5821,6 +5937,7 @@ exports.ActivityTabConfig = ActivityTabConfig;
5821
5937
  exports.AttributeInUseError = AttributeInUseError;
5822
5938
  exports.AttributeNotFoundError = AttributeNotFoundError;
5823
5939
  exports.BEHAVIOR_PROPERTIES = BEHAVIOR_PROPERTIES;
5940
+ exports.ChangeTypeNotSupportedError = ChangeTypeNotSupportedError;
5824
5941
  exports.ConcurrentModificationError = ConcurrentModificationError;
5825
5942
  exports.CustomTabConfig = CustomTabConfig;
5826
5943
  exports.DB_COLUMN_FIELDS = DB_COLUMN_FIELDS;
@@ -5830,6 +5947,7 @@ exports.DEFAULT_ROLE_DESCRIPTIONS = DEFAULT_ROLE_DESCRIPTIONS;
5830
5947
  exports.DEFAULT_ROLE_LABELS = DEFAULT_ROLE_LABELS;
5831
5948
  exports.DEFAULT_ROLE_PERMISSIONS = DEFAULT_ROLE_PERMISSIONS;
5832
5949
  exports.DOCUMENT_SYSTEM_ATTRIBUTES = DOCUMENT_SYSTEM_ATTRIBUTES;
5950
+ exports.DestructiveSyncNotAllowedError = DestructiveSyncNotAllowedError;
5833
5951
  exports.DetailViewBuilder = DetailViewBuilder;
5834
5952
  exports.DocumentSlotValidationError = DocumentSlotValidationError;
5835
5953
  exports.DocumentsTabConfig = DocumentsTabConfig;
@@ -5848,8 +5966,10 @@ exports.IDENTITY_PROPERTIES = IDENTITY_PROPERTIES;
5848
5966
  exports.InvalidPathError = InvalidPathError;
5849
5967
  exports.ListViewBuilder = ListViewBuilder;
5850
5968
  exports.ListViewTabConfigBuilder = ListViewTabConfigBuilder;
5969
+ exports.MAX_PRESET_DEPTH = MAX_PRESET_DEPTH;
5851
5970
  exports.MaxDepthExceededError = MaxDepthExceededError;
5852
5971
  exports.MemoryNotFoundError = MemoryNotFoundError;
5972
+ exports.MigrationTimeoutError = MigrationTimeoutError;
5853
5973
  exports.NO_VALUE_OPERATORS = NO_VALUE_OPERATORS;
5854
5974
  exports.NoopGeocodingAdapter = NoopGeocodingAdapter;
5855
5975
  exports.NotFoundError = NotFoundError;
@@ -5859,6 +5979,7 @@ exports.OPERATOR_SPECS = OPERATOR_SPECS;
5859
5979
  exports.ObjectBuilder = ObjectBuilder;
5860
5980
  exports.ObjectNotFoundError = ObjectNotFoundError;
5861
5981
  exports.ObjectReferencedError = ObjectReferencedError;
5982
+ exports.OrphanSystemAttributeError = OrphanSystemAttributeError;
5862
5983
  exports.PRESENTATION_PROPERTIES = PRESENTATION_PROPERTIES;
5863
5984
  exports.ProtectedResourceError = ProtectedResourceError;
5864
5985
  exports.ProtectedRoleError = ProtectedRoleError;
@@ -5880,7 +6001,10 @@ exports.SYSTEM_RESOURCE_LABELS = SYSTEM_RESOURCE_LABELS;
5880
6001
  exports.SchemaError = SchemaError;
5881
6002
  exports.SchemaErrorCode = SchemaErrorCode;
5882
6003
  exports.StorageError = StorageError;
6004
+ exports.SyncCascadeError = SyncCascadeError;
6005
+ exports.SyncConflictError = SyncConflictError;
5883
6006
  exports.SyncError = SyncError;
6007
+ exports.SystemEntityImmutableError = SystemEntityImmutableError;
5884
6008
  exports.TabBuilder = TabBuilder;
5885
6009
  exports.TableTabConfig = TableTabConfig;
5886
6010
  exports.USER_STATUSES = USER_STATUSES;