@objectstack/lint 17.0.0-rc.3 → 17.0.0-rc.5

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.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Manifest } from '@objectstack/sdui-parser';
2
+ import { Options } from 'ajv';
2
3
  import { AccessMatrix } from '@objectstack/spec/security';
3
4
  export { A as AUTHORING_COMMANDS, a as AUTHORING_RULES, b as AUTHORING_SURFACES, c as AuthoringCommand, d as AuthoringFinding, e as AuthoringRule, f as AuthoringRuleContext, g as AuthoringRuleInputTier, h as AuthoringRuleRun, i as AuthoringRuleTier, j as AuthoringSeverity, k as AuthoringSurface, E as EXPRESSION_INVALID, R as RuntimeGateResult, l as RuntimeStackContext, m as authoringRulesFor, r as runAuthoringRules, n as runRuntimeAuthoringRules, o as runtimeAuthoringRulesFor, p as runtimeGatedTypes, s as splitBySeverity, q as stackKeyForType } from './runtime-Cs64ShwN.cjs';
4
5
 
@@ -79,6 +80,8 @@ declare const CHART_FIELD_UNKNOWN = "chart-field-unknown";
79
80
  declare const CHART_CONFIG_MISSING = "chart-config-missing";
80
81
  declare const TABLE_COUNT_ONLY = "table-count-only";
81
82
  declare const MEASURE_AGGREGATE_INCOHERENT = "measure-aggregate-incoherent";
83
+ declare const WIDGET_LEGACY_ANALYTICS_SHAPE = "widget-legacy-analytics-shape";
84
+ declare const WIDGET_LEGACY_ANALYTICS_UNRENDERABLE = "widget-legacy-analytics-unrenderable";
82
85
  declare const DASHBOARD_FILTER_FIELD_UNKNOWN = "dashboard-filter-field-unknown";
83
86
  type WidgetBindingSeverity = 'error' | 'warning';
84
87
  interface WidgetBindingFinding {
@@ -95,7 +98,7 @@ interface WidgetBindingFinding {
95
98
  /** How to fix (or deliberately suppress) it. */
96
99
  hint: string;
97
100
  }
98
- type AnyRec$C = Record<string, unknown>;
101
+ type AnyRec$E = Record<string, unknown>;
99
102
  /**
100
103
  * Validate every dashboard widget's dataset binding. Returns the list of
101
104
  * findings (empty = clean). Caller decides how to surface them: `error`
@@ -103,7 +106,7 @@ type AnyRec$C = Record<string, unknown>;
103
106
  * should fail validate/build; `warning` findings are advisory and must
104
107
  * never fail the build on their own.
105
108
  */
106
- declare function validateWidgetBindings(stack: AnyRec$C): WidgetBindingFinding[];
109
+ declare function validateWidgetBindings(stack: AnyRec$E): WidgetBindingFinding[];
107
110
 
108
111
  interface ExprIssue {
109
112
  where: string;
@@ -116,12 +119,12 @@ interface ExprIssue {
116
119
  */
117
120
  severity?: 'error' | 'warning';
118
121
  }
119
- type AnyRec$B = Record<string, unknown>;
122
+ type AnyRec$D = Record<string, unknown>;
120
123
  /**
121
124
  * Validate every predicate in the stack. Returns the list of issues (empty =
122
125
  * clean). Caller decides how to surface / whether to fail the build.
123
126
  */
124
- declare function validateStackExpressions(stack: AnyRec$B): ExprIssue[];
127
+ declare function validateStackExpressions(stack: AnyRec$D): ExprIssue[];
125
128
 
126
129
  /**
127
130
  * The corrective sentence, lifted **verbatim** from `unevaluableRuleError` in
@@ -153,10 +156,41 @@ interface NullGuardFinding {
153
156
  /**
154
157
  * Find every ordering/arithmetic operand that resolves to a nullable declared
155
158
  * field and is not dominated by a real null guard. Returns `[]` for anything
156
- * that does not parse (syntax is reported by `validateExpression`, not here)
157
- * this pass never invents a second syntax verdict.
159
+ * that does not parse this pass never invents a second syntax verdict.
160
+ *
161
+ * "Does not parse" is deliberately **not** this module's own opinion (#4812).
162
+ * The AST comes from `@objectstack/formula`'s `parseCelToAst`, the same front
163
+ * end `celEngine.compile`/`evaluate` use, so the set of sources this gate can
164
+ * reason about is exactly the set the platform accepts — rewrite (#3306) and
165
+ * `DEFAULT_LIMITS` included. This module used to build its own bare
166
+ * `new Environment({ unlistedVariablesAreDyn: true, enableOptionalTypes: true })`,
167
+ * which carried **no limits**: it parsed, and then adjudicated, predicates that
168
+ * `compile()` rejects outright at `Exceeded maxAstNodes (256)` / `maxDepth (32)`
169
+ * / `maxListElements (64)`. Two parse entries, two answers to "what can be
170
+ * parsed" — and this gate held the more permissive one.
171
+ *
172
+ * A source the canonical front end will not parse is therefore left entirely to
173
+ * the gate that owns that verdict: `validateExpression` runs at the very same
174
+ * call sites (`validate-expressions.ts` calls `check()` alongside
175
+ * `checkNullGuards()`) and reports the syntax fault or the bounds fault as a
176
+ * blocking error, with a message written for self-correction. Nothing is lost
177
+ * by staying silent here — and once the author fixes the fault the null-guard
178
+ * verdict comes back on the next run.
158
179
  */
159
180
  declare function findUnguardedNullableOperands(source: string, opts: NullGuardOptions): NullGuardFinding[];
181
+ /**
182
+ * What the surface actually DOES once the predicate aborts (#4811).
183
+ *
184
+ * Both outcomes are bugs, but they are *opposite* bugs, and an author needs to
185
+ * be told which one they have: "your write will be refused" and "your rule will
186
+ * never fire" send you to different places. Never guess one — read the
187
+ * surface's runtime and name what it really implements.
188
+ */
189
+ type NullGuardOutcome =
190
+ /** Validation rules + hook conditions: the fault propagates, the write is refused (#4761). */
191
+ 'fail-closed'
192
+ /** Field `requiredWhen`: `rule-validator.ts` logs and skips, so nothing is enforced (#4811). */
193
+ | 'fail-open';
160
194
  /**
161
195
  * The publish-time message for one finding. Names the rule, the operand and the
162
196
  * `!= null` fix (the three things the author needs), then closes with the
@@ -164,8 +198,11 @@ declare function findUnguardedNullableOperands(source: string, opts: NullGuardOp
164
198
  *
165
199
  * @param subject How the site names itself, e.g. `validation rule 'end_after_start'`.
166
200
  * @param objectName The object whose field list decided nullability.
201
+ * @param finding The unguarded operand to report.
202
+ * @param outcome What this surface's runtime does with the abort. Defaults to
203
+ * `fail-closed` — what both #4763 surfaces do.
167
204
  */
168
- declare function nullGuardMessage(subject: string, objectName: string | undefined, finding: NullGuardFinding): string;
205
+ declare function nullGuardMessage(subject: string, objectName: string | undefined, finding: NullGuardFinding, outcome?: NullGuardOutcome): string;
169
206
 
170
207
  type ListViewModeSeverity = 'error' | 'warning';
171
208
  interface ListViewModeFinding {
@@ -179,7 +216,7 @@ interface ListViewModeFinding {
179
216
  hint: string;
180
217
  }
181
218
  declare const LIST_VIEW_FILTERS_IN_VIEWS_MODE = "list-view-filters-in-views-mode";
182
- type AnyRec$A = Record<string, unknown>;
219
+ type AnyRec$C = Record<string, unknown>;
183
220
  /**
184
221
  * Flag ADR-0047 "views" mode violations on an object's built-in named views or a
185
222
  * `defineView` default `list` / named `listViews`: `quickFilters`, or a `tabs`
@@ -189,7 +226,7 @@ type AnyRec$A = Record<string, unknown>;
189
226
  *
190
227
  * Feed the PRE-parse stack (normalizeStackInput output) — see file header.
191
228
  */
192
- declare function validateListViewMode(stack: AnyRec$A): ListViewModeFinding[];
229
+ declare function validateListViewMode(stack: AnyRec$C): ListViewModeFinding[];
193
230
 
194
231
  type FunctionalCompletenessSeverity = 'error' | 'warning';
195
232
  interface FunctionalCompletenessFinding {
@@ -222,12 +259,44 @@ interface FlowTriggerReadinessFinding {
222
259
  }
223
260
  declare const FLOW_TRIGGER_UNKNOWN_OBJECT = "flow-trigger-unknown-object";
224
261
  declare const FLOW_DRAFT_STATUS_AMBIGUOUS = "flow-draft-status-ambiguous";
225
- type AnyRec$z = Record<string, unknown>;
262
+ declare const FLOW_TRIGGER_UNKNOWN_EVENT = "flow-trigger-unknown-event";
263
+ /**
264
+ * #5496 — `config.timeRelative` is present but `TimeRelativeTriggerSchema`
265
+ * rejects it, so the sweep is never installed.
266
+ *
267
+ * Named for the DESCRIPTOR rather than for the rule that reads it, because this
268
+ * is the first of a family: every flow-node `config` slot whose contract a
269
+ * schema (or the engine) can already decide, yet which nothing checks at
270
+ * authoring time. `flow-<descriptor>-<verdict>` is the shape the next one takes.
271
+ */
272
+ declare const FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID = "flow-time-relative-descriptor-invalid";
273
+ /**
274
+ * #5647 — `config.timeRelative` is present but is not an object, so the engine
275
+ * never routes the flow to the time-relative trigger at all.
276
+ *
277
+ * The second id in the `flow-<descriptor>-<verdict>` family, and a DIFFERENT
278
+ * verdict from `…-INVALID` rather than a widening of it. The two partition the
279
+ * non-null values of one key along the engine's own routing predicate, so
280
+ * exactly one of them can ever fire on a given descriptor:
281
+ *
282
+ * - `typeof === 'object'` (including arrays and `Date`) — the engine ROUTES
283
+ * it, `TimeRelativeTriggerSchema` gets a verdict, and a bad shape is
284
+ * `…-INVALID`. That path has a bind-time warn; the rule moves it earlier.
285
+ * - anything else (`'daily'`, `7`, `true`, a function) — the engine routes it
286
+ * NOWHERE, so no schema and no trigger ever sees it. That is this id, and
287
+ * there is no runtime channel at all for it to be moved earlier from.
288
+ */
289
+ declare const FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE = "flow-time-relative-descriptor-unroutable";
290
+ type AnyRec$B = Record<string, unknown>;
226
291
  /**
227
292
  * Validate auto-launched flow trigger wiring against the stack definition.
228
- * Pure and dependency-free; safe on pre- or post-parse stacks.
293
+ *
294
+ * Pure — no I/O, no runtime, no mutation of `stack` — and safe on pre- or
295
+ * post-parse stacks. Its one dependency is the `@objectstack/spec` schema that
296
+ * owns the `timeRelative` descriptor's contract, which is the point: the rule
297
+ * ASKS that schema rather than restating it.
229
298
  */
230
- declare function validateFlowTriggerReadiness(stack: AnyRec$z): FlowTriggerReadinessFinding[];
299
+ declare function validateFlowTriggerReadiness(stack: AnyRec$B): FlowTriggerReadinessFinding[];
231
300
 
232
301
  type FlowTemplatePathSeverity = 'error' | 'warning';
233
302
  interface FlowTemplatePathFinding {
@@ -242,12 +311,12 @@ interface FlowTemplatePathFinding {
242
311
  }
243
312
  declare const FLOW_TEMPLATE_UNKNOWN_FIELD = "flow-template-unknown-field";
244
313
  declare const FLOW_TEMPLATE_LOOKUP_TRAVERSAL = "flow-template-lookup-traversal";
245
- type AnyRec$y = Record<string, unknown>;
314
+ type AnyRec$A = Record<string, unknown>;
246
315
  /**
247
316
  * Validate `{record.<path>}` template references across every record-change
248
317
  * flow. Pure and dependency-free; safe on pre- or post-parse stacks.
249
318
  */
250
- declare function validateFlowTemplatePaths(stack: AnyRec$y): FlowTemplatePathFinding[];
319
+ declare function validateFlowTemplatePaths(stack: AnyRec$A): FlowTemplatePathFinding[];
251
320
 
252
321
  type ReadonlyFlowWriteSeverity = 'error' | 'warning';
253
322
  interface ReadonlyFlowWriteFinding {
@@ -262,12 +331,12 @@ interface ReadonlyFlowWriteFinding {
262
331
  }
263
332
  declare const FLOW_UPDATE_READONLY_FIELD = "flow-update-readonly-field";
264
333
  declare const FLOW_UPDATE_READONLY_WHEN_FIELD = "flow-update-readonly-when-field";
265
- type AnyRec$x = Record<string, unknown>;
334
+ type AnyRec$z = Record<string, unknown>;
266
335
  /**
267
336
  * Validate flow `update_record` writes against target-object readonly
268
337
  * declarations. Pure and dependency-free; safe on pre- or post-parse stacks.
269
338
  */
270
- declare function validateReadonlyFlowWrites(stack: AnyRec$x): ReadonlyFlowWriteFinding[];
339
+ declare function validateReadonlyFlowWrites(stack: AnyRec$z): ReadonlyFlowWriteFinding[];
271
340
 
272
341
  type ViewContainerSeverity = 'error' | 'warning';
273
342
  interface ViewContainerFinding {
@@ -304,14 +373,14 @@ declare const STYLE_CLASSNAME_TAILWIND = "style-classname-tailwind";
304
373
  declare const STYLE_RESPONSIVE_NO_BASE = "style-responsive-no-base";
305
374
  declare const STYLE_UNKNOWN_CSS_PROPERTY = "style-unknown-css-property";
306
375
  declare const STYLE_UNKNOWN_TOKEN = "style-unknown-token";
307
- type AnyRec$w = Record<string, unknown>;
376
+ type AnyRec$y = Record<string, unknown>;
308
377
  /**
309
378
  * Validate every page's component tree for SDUI styling correctness (ADR-0065).
310
379
  * Returns findings (empty = clean). `error` findings describe styles that are
311
380
  * silently dropped and should fail validate/build; `warning` findings are
312
381
  * advisory (typos, drift, footguns).
313
382
  */
314
- declare function validateResponsiveStyles(stack: AnyRec$w): StyleFinding[];
383
+ declare function validateResponsiveStyles(stack: AnyRec$y): StyleFinding[];
315
384
 
316
385
  type JsxPageSeverity = 'error' | 'warning';
317
386
  interface JsxPageFinding {
@@ -324,8 +393,8 @@ interface JsxPageFinding {
324
393
  message: string;
325
394
  hint: string;
326
395
  }
327
- type AnyRec$v = Record<string, unknown>;
328
- declare function validateJsxPages(stack: AnyRec$v, opts?: {
396
+ type AnyRec$x = Record<string, unknown>;
397
+ declare function validateJsxPages(stack: AnyRec$x, opts?: {
329
398
  manifest?: Manifest;
330
399
  }): JsxPageFinding[];
331
400
 
@@ -338,8 +407,8 @@ interface ReactPageFinding {
338
407
  message: string;
339
408
  hint: string;
340
409
  }
341
- type AnyRec$u = Record<string, unknown>;
342
- declare function validateReactPages(stack: AnyRec$u): ReactPageFinding[];
410
+ type AnyRec$w = Record<string, unknown>;
411
+ declare function validateReactPages(stack: AnyRec$w): ReactPageFinding[];
343
412
 
344
413
  type ReactPropSeverity = 'error' | 'warning';
345
414
  interface ReactPropFinding {
@@ -350,12 +419,13 @@ interface ReactPropFinding {
350
419
  message: string;
351
420
  hint: string;
352
421
  }
353
- type AnyRec$t = Record<string, unknown>;
422
+ type AnyRec$v = Record<string, unknown>;
354
423
  declare const REACT_CHART_FIELD_UNKNOWN = "react-chart-field-unknown";
355
424
  declare const REACT_CHART_AGGREGATE_INVALID = "react-chart-aggregate-invalid";
356
425
  declare const REACT_CHART_AXIS_UNKNOWN = "react-chart-axis-unknown";
426
+ declare const REACT_CHART_DRILLDOWN_INVALID = "react-chart-drilldown-invalid";
357
427
  declare const REACT_BLOCK_NEEDS_RECORD_CONTEXT = "react-block-needs-record-context";
358
- declare function validateReactPageProps(stack: AnyRec$t): ReactPropFinding[];
428
+ declare function validateReactPageProps(stack: AnyRec$v): ReactPropFinding[];
359
429
 
360
430
  type SourceStyleSeverity = 'error' | 'warning';
361
431
  interface SourceStyleFinding {
@@ -367,8 +437,8 @@ interface SourceStyleFinding {
367
437
  hint: string;
368
438
  }
369
439
  declare const PAGE_SOURCE_CLASSNAME = "page-source-className-tailwind";
370
- type AnyRec$s = Record<string, unknown>;
371
- declare function validatePageSourceStyling(stack: AnyRec$s): SourceStyleFinding[];
440
+ type AnyRec$u = Record<string, unknown>;
441
+ declare function validatePageSourceStyling(stack: AnyRec$u): SourceStyleFinding[];
372
442
 
373
443
  /**
374
444
  * Build-time record-title diagnostics (ADR-0079).
@@ -412,34 +482,18 @@ interface RecordTitleFinding {
412
482
  /** How to fix it. */
413
483
  hint: string;
414
484
  }
415
- type AnyRec$r = Record<string, unknown>;
485
+ type AnyRec$t = Record<string, unknown>;
416
486
  /**
417
487
  * Validate every object's record-title declaration. Returns the list of
418
488
  * findings (empty = clean). Both rules are advisory (`warning`): the caller
419
489
  * must never fail the build on them alone — auto-provision + the `Record #<id>`
420
490
  * floor guarantee a resolvable title at runtime.
421
491
  */
422
- declare function validateRecordTitle(stack: AnyRec$r): RecordTitleFinding[];
492
+ declare function validateRecordTitle(stack: AnyRec$t): RecordTitleFinding[];
423
493
 
424
- /**
425
- * Build-time semantic-role diagnostics (ADR-0085).
426
- *
427
- * The object-level semantic roles (`stageField`, `highlightFields` /
428
- * deprecated `compactLayout`, `fieldGroups` + `Field.group`) are pointers
429
- * into the object's own field map. A dangling pointer is Zod-valid but
430
- * silently inert at render time — the exact "parsed, unmarked, silently
431
- * inert" shape ADR-0078 prohibits — so the completeness lint flags it here,
432
- * uniformly for `os build`/`os validate`, MCP authoring and hand authors.
433
- *
434
- * All three rules are warnings, not errors: every consumer degrades
435
- * gracefully (an unknown `Field.group` renders in the ungrouped bucket, an
436
- * unknown highlight name is skipped, an unknown `stageField` falls back to
437
- * heuristics), so nothing is fully broken — but the author almost certainly
438
- * typo'd a name and should be told at author time, not discover it by
439
- * staring at an unchanged page.
440
- */
441
494
  declare const FIELD_GROUP_UNDECLARED = "field-group-undeclared";
442
495
  declare const FIELD_GROUP_EMPTY = "field-group-empty";
496
+ declare const FIELD_GROUP_SHADOWED = "field-group-shadowed";
443
497
  declare const SEMANTIC_ROLE_FIELD_UNKNOWN = "semantic-role-field-unknown";
444
498
  type SemanticRoleSeverity = 'error' | 'warning';
445
499
  interface SemanticRoleFinding {
@@ -456,13 +510,13 @@ interface SemanticRoleFinding {
456
510
  /** How to fix it. */
457
511
  hint: string;
458
512
  }
459
- type AnyRec$q = Record<string, unknown>;
513
+ type AnyRec$s = Record<string, unknown>;
460
514
  /**
461
515
  * Validate every object's semantic-role pointers. Returns the list of
462
516
  * findings (empty = clean). Advisory only — the caller must never fail the
463
517
  * build on these alone.
464
518
  */
465
- declare function validateSemanticRoles(stack: AnyRec$q): SemanticRoleFinding[];
519
+ declare function validateSemanticRoles(stack: AnyRec$s): SemanticRoleFinding[];
466
520
 
467
521
  /**
468
522
  * Build-time form-layout diagnostics (#2578).
@@ -505,12 +559,12 @@ interface FormLayoutFinding {
505
559
  /** How to fix it. */
506
560
  hint: string;
507
561
  }
508
- type AnyRec$p = Record<string, unknown>;
562
+ type AnyRec$r = Record<string, unknown>;
509
563
  /**
510
564
  * Validate authored form-view layout. Returns findings (empty = clean).
511
565
  * Advisory only — the caller must never fail the build on these alone.
512
566
  */
513
- declare function validateFormLayout(stack: AnyRec$p): FormLayoutFinding[];
567
+ declare function validateFormLayout(stack: AnyRec$r): FormLayoutFinding[];
514
568
 
515
569
  /**
516
570
  * Build-time conditional-visibility diagnostics (ADR-0089 D3b).
@@ -572,7 +626,7 @@ interface VisibilityFinding {
572
626
  /** How to fix it. */
573
627
  hint: string;
574
628
  }
575
- type AnyRec$o = Record<string, unknown>;
629
+ type AnyRec$q = Record<string, unknown>;
576
630
  /**
577
631
  * Validate conditional-visibility keys across authored views and pages.
578
632
  *
@@ -587,7 +641,7 @@ type AnyRec$o = Record<string, unknown>;
587
641
  * `*.view.ts` / `*.page.ts` surfaces (so a `data.`-rooted predicate is flagged). The
588
642
  * alias-deprecated check is layer-agnostic.
589
643
  */
590
- declare function validateVisibilityPredicates(stack: AnyRec$o, opts?: VisibilityOptions): VisibilityFinding[];
644
+ declare function validateVisibilityPredicates(stack: AnyRec$q, opts?: VisibilityOptions): VisibilityFinding[];
591
645
 
592
646
  declare const CAPABILITY_REFERENCE_UNKNOWN = "capability-reference-unknown";
593
647
  type CapabilityRefSeverity = 'error' | 'warning';
@@ -605,16 +659,17 @@ interface CapabilityRefFinding {
605
659
  /** How to fix it. */
606
660
  hint: string;
607
661
  }
608
- type AnyRec$n = Record<string, unknown>;
662
+ type AnyRec$p = Record<string, unknown>;
609
663
  /**
610
664
  * Validate every capability reference in a stack. Returns findings (empty =
611
665
  * clean). Advisory only — callers must not fail the build on these alone.
612
666
  */
613
- declare function validateCapabilityReferences(stack: AnyRec$n): CapabilityRefFinding[];
667
+ declare function validateCapabilityReferences(stack: AnyRec$p): CapabilityRefFinding[];
614
668
 
615
669
  declare const APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER = "approval-approver-not-membership-tier";
616
670
  declare const APPROVAL_APPROVER_TYPE_DEPRECATED = "approval-approver-type-deprecated";
617
671
  declare const APPROVAL_APPROVER_TYPE_UNKNOWN = "approval-approver-type-unknown";
672
+ declare const APPROVAL_APPROVER_TYPE_UNSUPPORTED = "approval-approver-type-unsupported";
618
673
  declare const APPROVAL_ESCALATION_REASSIGN_NO_TARGET = "approval-escalation-reassign-no-target";
619
674
  declare const APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY = "approval-approvers-may-resolve-empty";
620
675
  declare const APPROVAL_EXPRESSION_INVALID = "approval-expression-invalid";
@@ -635,12 +690,12 @@ interface ApprovalApproverFinding {
635
690
  /** How to fix it. */
636
691
  hint: string;
637
692
  }
638
- type AnyRec$m = Record<string, unknown>;
693
+ type AnyRec$o = Record<string, unknown>;
639
694
  /**
640
695
  * Validate the approvers of every Approval node in the stack's flows.
641
696
  * Returns findings (empty = clean).
642
697
  */
643
- declare function validateApprovalApprovers(stack: AnyRec$m): ApprovalApproverFinding[];
698
+ declare function validateApprovalApprovers(stack: AnyRec$o): ApprovalApproverFinding[];
644
699
 
645
700
  type SeedReplaySafetySeverity = 'error' | 'warning';
646
701
  interface SeedReplaySafetyFinding {
@@ -654,7 +709,7 @@ interface SeedReplaySafetyFinding {
654
709
  hint: string;
655
710
  }
656
711
  declare const SEED_INSERT_MODE_DUPLICATES_ON_REPLAY = "seed-insert-mode-duplicates-on-replay";
657
- type AnyRec$l = Record<string, unknown>;
712
+ type AnyRec$n = Record<string, unknown>;
658
713
  /**
659
714
  * Flag every seed dataset declared with `mode: 'insert'` — the one non-idempotent
660
715
  * mode, which duplicates its rows on every replay boot (framework#3434). Returns
@@ -664,7 +719,7 @@ type AnyRec$l = Record<string, unknown>;
664
719
  * Reads `stack.data` (the `SeedSchema[]` fixtures). Safe on any shape — a stack
665
720
  * with no `data` array yields no findings.
666
721
  */
667
- declare function validateSeedReplaySafety(stack: AnyRec$l): SeedReplaySafetyFinding[];
722
+ declare function validateSeedReplaySafety(stack: AnyRec$n): SeedReplaySafetyFinding[];
668
723
 
669
724
  type SeedStateMachineSeverity = 'warning';
670
725
  interface SeedStateMachineFinding {
@@ -678,7 +733,7 @@ interface SeedStateMachineFinding {
678
733
  hint: string;
679
734
  }
680
735
  declare const SEED_VALUE_OUTSIDE_STATE_MACHINE = "seed-value-outside-state-machine";
681
- type AnyRec$k = Record<string, unknown>;
736
+ type AnyRec$m = Record<string, unknown>;
682
737
  /**
683
738
  * Flag every seed record whose `state_machine`-governed field carries a value
684
739
  * the machine does not declare (framework#3433 follow-up). Returns the findings
@@ -691,7 +746,7 @@ type AnyRec$k = Record<string, unknown>;
691
746
  * unresolved `cel` Expression envelope, a number) is skipped: it cannot be
692
747
  * statically compared to the declared-state set.
693
748
  */
694
- declare function validateSeedStateMachine(stack: AnyRec$k): SeedStateMachineFinding[];
749
+ declare function validateSeedStateMachine(stack: AnyRec$m): SeedStateMachineFinding[];
695
750
 
696
751
  declare const SECURITY_OWD_UNSET = "security-owd-unset";
697
752
  declare const SECURITY_OWD_ALIAS = "security-owd-alias";
@@ -702,6 +757,7 @@ declare const SECURITY_ROLE_WORD = "security-role-word";
702
757
  declare const SECURITY_BOOK_AUDIENCE_UNKNOWN_SET = "security-book-audience-unknown-set";
703
758
  declare const SECURITY_PRIVATE_NO_READSCOPE = "security-private-no-readscope";
704
759
  declare const SECURITY_MASTER_DETAIL_UNGRANTED = "security-master-detail-ungranted";
760
+ declare const SECURITY_FLS_UNQUALIFIED_KEY = "security-fls-unqualified-key";
705
761
  declare const SECURITY_GRANT_EXPIRED_AT_AUTHORING = "security-grant-expired-at-authoring";
706
762
  declare const SECURITY_DELEGATION_MISSING_REASON = "security-delegation-missing-reason";
707
763
  type SecuritySeverity = 'error' | 'warning' | 'info';
@@ -718,7 +774,7 @@ interface SecurityFinding {
718
774
  /** How to fix it. */
719
775
  hint: string;
720
776
  }
721
- type AnyRec$j = Record<string, unknown>;
777
+ type AnyRec$l = Record<string, unknown>;
722
778
  /**
723
779
  * Validate the security posture of a stack. Returns findings (empty = clean).
724
780
  * `error` findings gate the build in `os compile`; `info` is advisory.
@@ -726,7 +782,7 @@ type AnyRec$j = Record<string, unknown>;
726
782
  * `opts.nowMs` injects the clock for the ADR-0091 authoring-time expiry rule
727
783
  * (tests); production callers omit it.
728
784
  */
729
- declare function validateSecurityPosture(stack: AnyRec$j, opts?: {
785
+ declare function validateSecurityPosture(stack: AnyRec$l, opts?: {
730
786
  nowMs?: number;
731
787
  }): SecurityFinding[];
732
788
 
@@ -759,13 +815,62 @@ declare function validateSecurityPosture(stack: AnyRec$j, opts?: {
759
815
  * business-unit sharing rule on a PLATFORM-GLOBAL object (`tenancy.enabled:
760
816
  * false`) has no organization column to scope against, so the grant spans every
761
817
  * organization in the database — a cross-org BU grant by construction, and the
762
- * "cross-org BU mega-tree" the ADR rejected, arrived at by accident.
818
+ * "cross-org BU mega-tree" the ADR rejected, arrived at by accident. It covers
819
+ * BOTH business-unit recipients, `business_unit` and `unit_and_subordinates`
820
+ * — see {@link BU_TREE_RECIPIENT_TYPES} for the word list and its deliberate
821
+ * complement.
763
822
  *
764
823
  * Both are `error`, per ADR-0049 discipline: each mirrors a real enforcement
765
824
  * property (the Layer 0 wall's independence; the org-predicated BU resolver),
766
825
  * so the lint moves the failure from silent-wrong-answer to author-time fix-it.
767
826
  *
768
827
  * Pure `(stack) => Finding[]`; accepts the NORMALIZED stack input.
828
+ *
829
+ * ## Scope — the keys this rule reads, and the ones it deliberately does not
830
+ *
831
+ * Every key below is one `@objectstack/spec` DECLARES. That is a contract, not
832
+ * a style preference: the rule is registered `input: 'parsed'`, so what it sees
833
+ * is what `ObjectStackSchema` returned. An undeclared key never survives to be
834
+ * read — the stack root strips it, and the `.strict()` sub-schemas reject the
835
+ * whole stack outright — so a branch keyed on one is inert for every stack an
836
+ * author can actually ship (#4984, #5009).
837
+ *
838
+ * | Read | Declared by |
839
+ * |---------------------------------------|------------------------------------|
840
+ * | `permissions[]` | `ObjectStackSchema` |
841
+ * | `permissions[].rowLevelSecurity[]` | `PermissionSetSchema` |
842
+ * | `…[].using` / `…[].check` | `RowLevelSecurityPolicySchema` |
843
+ * | `sharingRules[]` | `ObjectStackSchema` |
844
+ * | `sharingRules[].condition` / `.sharedWith` / `.object` | `SharingRuleSchema` |
845
+ * | `objects[].tenancy` / `.systemFields` | `ObjectSchema` |
846
+ *
847
+ * NOT read, and each for a reason that is a schema fact:
848
+ *
849
+ * - `permissionSets` / `sharing` — not declared on the stack root. The root
850
+ * STRIPS them, so after parse they are `undefined` no matter what the author
851
+ * wrote. The declared spellings are `permissions` and `sharingRules`.
852
+ * - `sharingRules[].objectName` — `SharingRuleSchema` is `.strict()` and knows
853
+ * it only as a rejected name; `object` is required, so the canonical read can
854
+ * never be missing on a rule that parsed.
855
+ * - `objects[].rowLevelSecurity` / `objects[].rls` — **object-level RLS is not
856
+ * an authoring surface at all.** `ObjectSchema` declares neither key (nor
857
+ * does `authorable-surface.json` list one: the sole entry is
858
+ * `security/PermissionSet:rowLevelSecurity`), and `ObjectSchema` is
859
+ * `.strict()`, so a stack carrying one does not parse — it is refused with
860
+ * "Unrecognized key(s) on this object". Until #5009 this file walked that
861
+ * non-existent surface for ~20 lines, complete with an `objects[N].
862
+ * rowLevelSecurity[M].using` diagnostic path. Nothing could reach it, and the
863
+ * cost was never the missed finding: the next author to read this rule (human
864
+ * or AI) came away believing object-level RLS was a real authorization
865
+ * surface and wrote more code against it (#5008 nearly did). RLS policies
866
+ * live on a permission set; that is the branch above.
867
+ *
868
+ * Alias tolerance belongs at the schema's refusal, not in a consumer (Prime
869
+ * Directive #12) — where it also converts a loud, named rejection into a
870
+ * silently-inert gate. `validate-org-axis-red-lines.test.ts` pins all of this
871
+ * structurally: every key read here is checked against the declaring schema's
872
+ * own `.shape`, and every `findings.push` site must be reachable by a fixture
873
+ * that passed `safeParse`.
769
874
  */
770
875
  declare const ORG_AXIS_PERMISSION_INHERITANCE = "org-axis-permission-inheritance";
771
876
  declare const ORG_AXIS_CROSS_ORG_BU_GRANT = "org-axis-cross-org-bu-grant";
@@ -788,18 +893,71 @@ interface OrgAxisFinding {
788
893
  */
789
894
  declare function validateOrgAxisRedLines(stack: unknown): OrgAxisFinding[];
790
895
 
896
+ /** A `condition` outside the pushdown subset — the rule is never seeded. */
897
+ declare const SHARING_RULE_UNLOWERABLE_CONDITION = "sharing-rule-unlowerable-condition";
898
+ /** A `condition` reading `current_user.*` — unresolvable when grants are materialized. */
899
+ declare const SHARING_RULE_RUNTIME_VARIABLE_CONDITION = "sharing-rule-runtime-variable-condition";
900
+ type SharingRuleEnforceabilitySeverity = 'error' | 'warning';
901
+ interface SharingRuleEnforceabilityFinding {
902
+ severity: SharingRuleEnforceabilitySeverity;
903
+ /** Diagnostic rule id (`sharing-rule-*`). */
904
+ rule: string;
905
+ /** Human-readable location, e.g. `sharing rule "high_value_opps" on object "opportunity"`. */
906
+ where: string;
907
+ /** Config path, e.g. `sharingRules[2].condition`. */
908
+ path: string;
909
+ /** What is wrong. */
910
+ message: string;
911
+ /** How to fix it. */
912
+ hint: string;
913
+ }
791
914
  /**
792
- * [ADR-0049 references] Reference-integrity for dashboard header & widget
793
- * action targets (issue #3367).
915
+ * Gate stack-declared sharing rules on the ONE thing their runtime consumer
916
+ * does with `condition`: lower it to a `criteria_json` filter.
917
+ *
918
+ * Pure `(stack) => Finding[]`; tolerates the normalized and the parsed tier.
919
+ */
920
+ declare function validateSharingRuleEnforceability(stack: unknown): SharingRuleEnforceabilityFinding[];
921
+
922
+ /** A predicate outside the pushdown subset — the policy enforces nothing. */
923
+ declare const RLS_PREDICATE_UNENFORCEABLE = "rls-predicate-unenforceable";
924
+ /** A predicate that does not parse as CEL even after the legacy SQL bridge. */
925
+ declare const RLS_PREDICATE_UNPARSEABLE = "rls-predicate-unparseable";
926
+ type RlsPredicateSeverity = 'error' | 'warning';
927
+ interface RlsPredicateFinding {
928
+ severity: RlsPredicateSeverity;
929
+ /** Diagnostic rule id (`rls-predicate-*`). */
930
+ rule: string;
931
+ /** Human-readable location, e.g. `permission set "sales" policy "own_leads"`. */
932
+ where: string;
933
+ /** Config path, e.g. `permissions[2].rowLevelSecurity[0].using`. */
934
+ path: string;
935
+ /** What is wrong. */
936
+ message: string;
937
+ /** How to fix it. */
938
+ hint: string;
939
+ }
940
+ /**
941
+ * Gate every stack-declared RLS predicate on the ONE thing the runtime does
942
+ * with it: lower it to a FilterCondition (ADR-0056 D4).
943
+ *
944
+ * Pure `(stack) => Finding[]`; tolerates the normalized and the parsed tier
945
+ * (`using` / `check` are plain `z.string()`, identical in both).
946
+ */
947
+ declare function validateRlsPredicateEnforceability(stack: unknown): RlsPredicateFinding[];
948
+
949
+ /**
950
+ * [ADR-0049 — references] Reference-integrity for dashboard header action
951
+ * targets (issue #3367).
794
952
  *
795
953
  * ADR-0049 established the "enforce-or-remove" gate for spec *properties*: a
796
954
  * declared property the runtime does not honour is a false promise and must be
797
955
  * enforced, marked experimental, or removed. This rule applies the SAME honesty
798
- * principle to *references*. A dashboard header action (or a widget's header
799
- * action button) names a target — a `script`/`modal` action, or a `url` route —
800
- * that must actually resolve. A dangling target ships a button that renders and,
801
- * on click, silently does nothing: a false affordance, exactly the failure
802
- * ADR-0049 exists to prevent, just for a reference rather than a property.
956
+ * principle to *references*. A dashboard header action names a target — a
957
+ * `script`/`modal` action, or a `url` route — that must actually resolve. A
958
+ * dangling target ships a button that renders and, on click, silently does
959
+ * nothing: a false affordance, exactly the failure ADR-0049 exists to prevent,
960
+ * just for a reference rather than a property.
803
961
  *
804
962
  * Nothing in the protocol schema can express this: `actionUrl` is a free string,
805
963
  * so `{ actionType: 'script', actionUrl: 'export_dashboard_pdf' }` parses and
@@ -807,7 +965,24 @@ declare function validateOrgAxisRedLines(stack: unknown): OrgAxisFinding[];
807
965
  *
808
966
  * Surfaces checked:
809
967
  * - dashboard `header.actions[]` — each `{ actionType, actionUrl }`
810
- * - dashboard `widgets[].actionUrl` (+ `actionType`) — the per-widget button
968
+ *
969
+ * ## The widget branch, and why it is gone (#5010)
970
+ *
971
+ * This rule used to check `widgets[].actionUrl` too, describing it as "the
972
+ * per-widget button" and claiming in this docblock that it "mirrors the objectui
973
+ * runtime dispatch". It did not: no renderer in either repo has ever drawn a
974
+ * per-widget action button — all 14 `actionUrl` reads in `DashboardRenderer` are
975
+ * scoped to `header.actions[]`. So the strictest arm of this rule (a dangling
976
+ * `script`/`modal` target is an ERROR, i.e. a failed build) was enforcing
977
+ * referential integrity for a button that could not render. An author could be
978
+ * blocked from shipping because a control that does not exist pointed at an
979
+ * action that also did not.
980
+ *
981
+ * That inversion — a rule written to delete false affordances, itself sustaining
982
+ * one — is why the widget keys were retired rather than the check merely
983
+ * relaxed: `widgets[].actionUrl` / `actionType` / `actionIcon` are now tombstoned
984
+ * in `@objectstack/spec` 17.0.0, so authoring one is a `tsc` error and a parse
985
+ * error carrying the prescription. There is no widget target left to resolve.
811
986
  *
812
987
  * Resolution mirrors the objectui runtime dispatch (`DashboardRenderer` +
813
988
  * `DashboardView`) so the lint flags exactly what would fail to resolve at
@@ -860,13 +1035,13 @@ interface DashboardActionRefFinding {
860
1035
  /** How to fix it. */
861
1036
  hint: string;
862
1037
  }
863
- type AnyRec$i = Record<string, unknown>;
1038
+ type AnyRec$k = Record<string, unknown>;
864
1039
  /**
865
- * Validate every dashboard header / widget action reference in a stack. Returns
1040
+ * Validate every dashboard header action reference in a stack. Returns
866
1041
  * findings (empty = clean). `script`/`modal` dead targets are errors; `url`
867
1042
  * unresolved routes are warnings.
868
1043
  */
869
- declare function validateDashboardActionRefs(stack: AnyRec$i): DashboardActionRefFinding[];
1044
+ declare function validateDashboardActionRefs(stack: AnyRec$k): DashboardActionRefFinding[];
870
1045
 
871
1046
  /**
872
1047
  * Build-time filter-placeholder diagnostics (issue #3574).
@@ -964,12 +1139,12 @@ interface ObjectRefFinding {
964
1139
  /** How to fix it. */
965
1140
  hint: string;
966
1141
  }
967
- type AnyRec$h = Record<string, unknown>;
1142
+ type AnyRec$j = Record<string, unknown>;
968
1143
  /**
969
1144
  * Validate every object-name reference on the surfaces listed in the module
970
1145
  * header. Returns findings (empty = clean).
971
1146
  */
972
- declare function validateObjectReferences(stack: AnyRec$h): ObjectRefFinding[];
1147
+ declare function validateObjectReferences(stack: AnyRec$j): ObjectRefFinding[];
973
1148
 
974
1149
  type ReferenceIntegritySeverity = 'error' | 'warning';
975
1150
  /**
@@ -1193,7 +1368,7 @@ interface SearchableFieldFinding {
1193
1368
  * runtime would refuse are flagged (#4830).
1194
1369
  */
1195
1370
  type SearchableFieldRole = 'canonical' | 'narrowing';
1196
- type AnyRec$g = Record<string, unknown>;
1371
+ type AnyRec$i = Record<string, unknown>;
1197
1372
  /**
1198
1373
  * Validate every `searchableFields` declaration in the stack — the object's own
1199
1374
  * (the canonical set, ADR-0061) and the list views that narrow it. Returns
@@ -1204,7 +1379,7 @@ type AnyRec$g = Record<string, unknown>;
1204
1379
  * `validate-react-page-props` — the gate that already parses that source —
1205
1380
  * runs the same `checkSearchableFieldList` core on it (#4329).
1206
1381
  */
1207
- declare function validateSearchableFields(stack: AnyRec$g): SearchableFieldFinding[];
1382
+ declare function validateSearchableFields(stack: AnyRec$i): SearchableFieldFinding[];
1208
1383
 
1209
1384
  declare const ACTION_NAME_UNDEFINED = "action-name-undefined";
1210
1385
  type ActionNameRefSeverity = 'error' | 'warning';
@@ -1222,12 +1397,12 @@ interface ActionNameRefFinding {
1222
1397
  /** How to fix it. */
1223
1398
  hint: string;
1224
1399
  }
1225
- type AnyRec$f = Record<string, unknown>;
1400
+ type AnyRec$h = Record<string, unknown>;
1226
1401
  /**
1227
1402
  * Validate every name-bound action reference in a stack. Returns findings
1228
1403
  * (empty = clean).
1229
1404
  */
1230
- declare function validateActionNameRefs(stack: AnyRec$f): ActionNameRefFinding[];
1405
+ declare function validateActionNameRefs(stack: AnyRec$h): ActionNameRefFinding[];
1231
1406
 
1232
1407
  /**
1233
1408
  * [ADR-0078 Phase 3 — Tier-A `action-locations`] An action nobody placed.
@@ -1294,12 +1469,12 @@ interface ActionLocationsFinding {
1294
1469
  /** How to fix it. */
1295
1470
  hint: string;
1296
1471
  }
1297
- type AnyRec$e = Record<string, unknown>;
1472
+ type AnyRec$g = Record<string, unknown>;
1298
1473
  /**
1299
1474
  * Flag every action that declares no placement and that no view places by
1300
1475
  * name. Returns findings (empty = clean).
1301
1476
  */
1302
- declare function validateActionLocations(stack: AnyRec$e): ActionLocationsFinding[];
1477
+ declare function validateActionLocations(stack: AnyRec$g): ActionLocationsFinding[];
1303
1478
 
1304
1479
  /**
1305
1480
  * Shared page-component traversal for the lint rules that inspect
@@ -1325,7 +1500,29 @@ declare function validateActionLocations(stack: AnyRec$e): ActionLocationsFindin
1325
1500
  * author never wrote, so those pages are skipped here and covered by
1326
1501
  * `validate-jsx-pages` / `validate-react-page-props` instead.
1327
1502
  */
1328
- type AnyRec$d = Record<string, unknown>;
1503
+ type AnyRec$f = Record<string, unknown>;
1504
+ /** A visited component plus everything needed to locate and bind it. */
1505
+ interface WalkedComponent {
1506
+ /** The component record itself. */
1507
+ component: AnyRec$f;
1508
+ /** Config path, e.g. `pages[0].regions[1].components[2]`. */
1509
+ path: string;
1510
+ /**
1511
+ * The object this component binds against, by precedence:
1512
+ * `dataSource.object` → `properties.object` → the page's `object`.
1513
+ * `undefined` when nothing in the chain names one.
1514
+ */
1515
+ objectName?: string;
1516
+ }
1517
+ /** Is this page authored as `source` (so its `regions` must not be linted)? */
1518
+ declare function isSourceAuthoredPage(page: AnyRec$f): boolean;
1519
+ /**
1520
+ * Walk every component on a page, depth-first, yielding each with its config
1521
+ * path and resolved object binding. Source-authored pages yield nothing.
1522
+ *
1523
+ * `pagePath` is the caller's path prefix for the page (e.g. `pages[3]`).
1524
+ */
1525
+ declare function walkPageComponents(page: AnyRec$f, pagePath: string): WalkedComponent[];
1329
1526
 
1330
1527
  /**
1331
1528
  * [ADR-0078 — completeness] Field-reference integrity for page components
@@ -1399,7 +1596,33 @@ interface PageFieldFinding {
1399
1596
  hint: string;
1400
1597
  }
1401
1598
 
1402
- declare function validatePageFieldBindings(stack: AnyRec$d): PageFieldFinding[];
1599
+ declare function validatePageFieldBindings(stack: AnyRec$f): PageFieldFinding[];
1600
+
1601
+ /** A key authored in `properties` that the type's props schema does not declare. */
1602
+ declare const COMPONENT_PROPS_UNKNOWN_KEY = "component-props-unknown-key";
1603
+ /** A value in `properties` that the type's props schema rejects. */
1604
+ declare const COMPONENT_PROPS_INVALID = "component-props-invalid";
1605
+ /**
1606
+ * Advisory on every finding this rule emits — see the module header. The type
1607
+ * is a single literal rather than a union so the tier claim in
1608
+ * `authoring-rules.ts` is provable from this file's source, which is exactly
1609
+ * what `authoring-rule-wiring.test.ts` reads it for.
1610
+ */
1611
+ type ComponentPropsSeverity = 'warning';
1612
+ interface ComponentPropsFinding {
1613
+ severity: ComponentPropsSeverity;
1614
+ /** Diagnostic rule id. */
1615
+ rule: string;
1616
+ /** Human-readable location, e.g. `page "task_detail" · record:highlights`. */
1617
+ where: string;
1618
+ /** Config path, e.g. `pages[0].regions[1].components[0].properties.titel`. */
1619
+ path: string;
1620
+ /** What is wrong. */
1621
+ message: string;
1622
+ /** How to fix it. */
1623
+ hint: string;
1624
+ }
1625
+ declare function validateComponentProps(stack: AnyRec$f): ComponentPropsFinding[];
1403
1626
 
1404
1627
  /**
1405
1628
  * [ADR-0021 — semantic layer] Chart-binding integrity for the surfaces the
@@ -1456,7 +1679,102 @@ interface ChartBindingFinding {
1456
1679
  hint: string;
1457
1680
  }
1458
1681
 
1459
- declare function validateChartBindings(stack: AnyRec$d): ChartBindingFinding[];
1682
+ declare function validateChartBindings(stack: AnyRec$f): ChartBindingFinding[];
1683
+
1684
+ type RuleCompilabilitySeverity = 'error';
1685
+ interface RuleCompilabilityFinding {
1686
+ severity: RuleCompilabilitySeverity;
1687
+ /** Stable diagnostic rule id (`--json` consumers and allowlists key on it). */
1688
+ rule: string;
1689
+ /** Human-readable location, e.g. `object 'account' · validation 'tax_id_format'`. */
1690
+ where: string;
1691
+ /** Config path, e.g. `objects.account.validations.tax_id_format.regex`. */
1692
+ path: string;
1693
+ message: string;
1694
+ hint: string;
1695
+ }
1696
+ /** A `format` rule whose `regex` `new RegExp(...)` refuses to compile. */
1697
+ declare const VALIDATION_RULE_REGEX_UNCOMPILABLE = "validation-rule-regex-uncompilable";
1698
+ /** A `json_schema` rule whose `schema` ajv refuses to compile. */
1699
+ declare const VALIDATION_RULE_SCHEMA_UNCOMPILABLE = "validation-rule-json-schema-uncompilable";
1700
+ /**
1701
+ * The ajv options the runtime's shared instance is constructed with
1702
+ * (`rule-validator.ts`). Exported so the parity test can assert BOTH halves —
1703
+ * that this object is what the gate compiles with, and that the runtime source
1704
+ * still says the same thing.
1705
+ */
1706
+ declare const RUNTIME_AJV_OPTIONS: Options;
1707
+ type AnyRec$e = Record<string, unknown>;
1708
+ /** One authored validation rule, located for a finding. */
1709
+ interface WalkedValidationRule {
1710
+ /** The rule record itself — a top-level entry, or a `conditional` branch. */
1711
+ rule: AnyRec$e;
1712
+ /** The declaring object's `name`, or `(unnamed object)`. */
1713
+ objectName: string;
1714
+ /** The nesting-aware rule name as prose: `'outer' → 'inner'`. */
1715
+ label: string;
1716
+ /** Human-readable location: `object 'account' · validation 'outer' → 'inner'`. */
1717
+ where: string;
1718
+ /** Config path of the rule: `objects.account.validations.outer.then.inner`. */
1719
+ basePath: string;
1720
+ }
1721
+ /**
1722
+ * Reject every object validation rule whose static artifact — a `format` rule's
1723
+ * `regex`, a `json_schema` rule's `schema` — the runtime's own compiler cannot
1724
+ * compile. Pure `(stack) => Finding[]`; never throws.
1725
+ */
1726
+ declare function validateRuleCompilability(stack: unknown): RuleCompilabilityFinding[];
1727
+
1728
+ type RuleSchemaFormatSeverity = 'error';
1729
+ interface RuleSchemaFormatFinding {
1730
+ severity: RuleSchemaFormatSeverity;
1731
+ /** Stable diagnostic rule id (`--json` consumers and allowlists key on it). */
1732
+ rule: string;
1733
+ /** Human-readable location, e.g. `object 'account' · validation 'support_shape'`. */
1734
+ where: string;
1735
+ /**
1736
+ * Config path of the offending keyword — the rule's `schema` key followed by
1737
+ * the RFC 6901 JSON Pointer into it, e.g.
1738
+ * `objects.account.validations.support_shape.schema#/properties/email/format`.
1739
+ */
1740
+ path: string;
1741
+ message: string;
1742
+ hint: string;
1743
+ }
1744
+ /** A `json_schema` rule naming a `format` the runtime's ajv has not registered. */
1745
+ declare const VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT = "validation-rule-json-schema-unknown-format";
1746
+ /**
1747
+ * Depth cap on the schema walk. Not a cycle guard for parsed metadata — that is
1748
+ * a tree — but the same cheap promise `flow-walk.ts`'s `MAX_REGION_DEPTH` and
1749
+ * `validate-rule-compilability.ts`'s `MAX_RULE_NESTING_DEPTH` make: `os lint`
1750
+ * never parses, so it hands this walker whatever object the author's module
1751
+ * actually built, and `const s = { type: 'object' }; s.properties = { self: s };`
1752
+ * is a two-line accident. Well past any reviewable schema.
1753
+ */
1754
+ declare const MAX_SCHEMA_WALK_DEPTH = 32;
1755
+ /**
1756
+ * The registered name closest to `name`, or `null` when nothing is close enough
1757
+ * to be worth suggesting.
1758
+ *
1759
+ * The budget scales with the typo's own length — three edits on a twelve-letter
1760
+ * name is a plausible slip, three edits on a four-letter one is a different word
1761
+ * — so a genuinely invented name (`shoe_size`) gets no suggestion instead of a
1762
+ * confident wrong one. Comparison is case-insensitive on the authored side so
1763
+ * `Email` is diagnosed as the case typo it is; ajv's own lookup is
1764
+ * case-SENSITIVE, which is exactly why `Email` is unregistered in the first
1765
+ * place. Ties break alphabetically, so the suggestion is stable.
1766
+ */
1767
+ declare function nearestRegisteredFormat(name: string, registered: readonly string[]): string | null;
1768
+ /**
1769
+ * Reject every `json_schema` validation rule that names a `format` the runtime's
1770
+ * ajv has not registered — the keyword ajv logs once and drops, leaving the rule
1771
+ * declared and inert. Pure `(stack) => Finding[]`.
1772
+ *
1773
+ * Lazier than the compile gate on purpose: the registered set is only asked for
1774
+ * once a schema actually NAMES a format, so a stack whose `json_schema` rules
1775
+ * use none never loads ajv at all (`lazy-deps.test.ts` pins this).
1776
+ */
1777
+ declare function validateRuleSchemaFormats(stack: unknown): RuleSchemaFormatFinding[];
1460
1778
 
1461
1779
  declare const NAV_OBJECT_UNGRANTED = "nav-object-ungranted";
1462
1780
  type NavAccessSeverity = 'error' | 'warning';
@@ -1474,12 +1792,12 @@ interface NavAccessFinding {
1474
1792
  /** How to fix it. */
1475
1793
  hint: string;
1476
1794
  }
1477
- type AnyRec$c = Record<string, unknown>;
1795
+ type AnyRec$d = Record<string, unknown>;
1478
1796
  /**
1479
1797
  * Validate that every object a stack's navigation exposes is readable by at
1480
1798
  * least one permission set the stack declares. Returns findings (empty = clean).
1481
1799
  */
1482
- declare function validateNavAccess(stack: AnyRec$c): NavAccessFinding[];
1800
+ declare function validateNavAccess(stack: AnyRec$d): NavAccessFinding[];
1483
1801
 
1484
1802
  declare const TRANSLATION_TARGET_UNKNOWN = "translation-target-unknown";
1485
1803
  declare const TRANSLATION_OPTION_KEY_UNKNOWN = "translation-option-key-unknown";
@@ -1498,12 +1816,35 @@ interface TranslationRefFinding {
1498
1816
  /** How to fix it. */
1499
1817
  hint: string;
1500
1818
  }
1501
- type AnyRec$b = Record<string, unknown>;
1819
+ type AnyRec$c = Record<string, unknown>;
1502
1820
  /**
1503
1821
  * Validate every reference a translation bundle makes against the metadata it
1504
1822
  * claims to translate. Returns findings (empty = clean).
1505
1823
  */
1506
- declare function validateTranslationReferences(stack: AnyRec$b): TranslationRefFinding[];
1824
+ declare function validateTranslationReferences(stack: AnyRec$c): TranslationRefFinding[];
1825
+
1826
+ declare const TRANSLATION_SECTION_NAME_MISSING = "translation-section-name-missing";
1827
+ type TranslatableSectionSeverity = 'warning';
1828
+ interface TranslatableSectionFinding {
1829
+ /** Always `warning` — one heading stays in the source locale; nothing breaks. */
1830
+ severity: TranslatableSectionSeverity;
1831
+ /** Diagnostic rule id. */
1832
+ rule: string;
1833
+ /** Human-readable location, e.g. `object "crm_case" · view "case_views" · formViews.create`. */
1834
+ where: string;
1835
+ /** Config path, e.g. `views[0].formViews.create.sections[1]`. */
1836
+ path: string;
1837
+ /** What is wrong. */
1838
+ message: string;
1839
+ /** How to fix it. */
1840
+ hint: string;
1841
+ }
1842
+ type AnyRec$b = Record<string, unknown>;
1843
+ /**
1844
+ * Report every form/detail section that declares a heading but no `name`, on an
1845
+ * object the stack actually translates. Returns findings (empty = clean).
1846
+ */
1847
+ declare function validateTranslatableSections(stack: AnyRec$b): TranslatableSectionFinding[];
1507
1848
 
1508
1849
  /**
1509
1850
  * [ADR-0064 §3] Skill ↔ agent surface affinity (issue #3820).
@@ -1842,45 +2183,6 @@ declare function buildAccessMatrix(stack: AnyRec$4): AccessMatrix;
1842
2183
  */
1843
2184
  declare function diffAccessMatrix(before: AccessMatrix, after: AccessMatrix): string[];
1844
2185
 
1845
- /**
1846
- * Build-time lint for flow authoring ANTI-PATTERNS — metadata that is valid
1847
- * (passes schema + expression checks) but is semantically a footgun at runtime.
1848
- * Most are emitted as WARNINGS: they guide the author (very often an AI
1849
- * generating templates) toward the robust pattern without failing the build on
1850
- * a technically-legal construct.
1851
- *
1852
- * A finding carrying `severity: 'error'` FAILS the build. The bar is: **no
1853
- * reading of the author's metadata does what it says, deterministically, on
1854
- * every run.** Warning about such a shape is just a slower way of finding out.
1855
- * That covers two kinds, and only these:
1856
- *
1857
- * - **The runtime refuses.** {@link FLOW_RUNAS_UNSCOPED} — a user-less trigger
1858
- * with `runAs:'user'` has no identity to scope to, so the data operation is
1859
- * refused outright (#3760).
1860
- * - **The declaration is inert and the route silently differs from what is
1861
- * written.** {@link FLOW_BRANCH_LABEL_UNMATCHED} — a decision computes a
1862
- * branch no out-edge carries, so the branch is discarded and every out-edge
1863
- * is considered instead. {@link FLOW_DEFAULT_EDGE_WITH_CONDITION} — an edge
1864
- * that is both the default and conditional; the condition wins and the
1865
- * marker routes nothing. Neither *fails*; both are wrong every time, and
1866
- * silently, which is worse (#4414).
1867
- *
1868
- * The bar is deliberately about *provability*, not severity of consequence. A
1869
- * shape with a legitimate reading stays a warning even when it is usually a
1870
- * mistake — {@link FLOW_DECISION_UNCONDITIONAL_BRANCH} is normally a guard that
1871
- * does not guard, but a decision with one guarded and one unconditional out-edge
1872
- * is a legal "maybe notify, always continue" fan-out, and
1873
- * {@link FLOW_MULTIPLE_DEFAULT_EDGES} can genuinely mean "when nothing matched,
1874
- * do both". Failing a customer's build on a shape we cannot prove wrong is a
1875
- * worse trade than letting the warning be ignored.
1876
- *
1877
- * #1874 — time-relative rules via record-change date-EQUALITY. A start-node
1878
- * trigger condition like `end_date == daysFromNow(60)` on a `record-*` trigger
1879
- * only fires if the record happens to be written on that exact day; the robust
1880
- * shape is a daily SCHEDULE trigger + a range query. We flag the equality form
1881
- * specifically (range operators `>=`/`<=` are not flagged — they're the building
1882
- * block of the correct pattern), keeping false positives near zero.
1883
- */
1884
2186
  interface FlowLintFinding {
1885
2187
  where: string;
1886
2188
  message: string;
@@ -1908,6 +2210,12 @@ declare const FLOW_BARE_DOLLAR_REF = "flow-bare-dollar-reference";
1908
2210
  declare const FLOW_APPROVAL_REVISE_DEAD_END = "flow-approval-revise-dead-end";
1909
2211
  declare const FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE = "flow-approval-revise-unmarked-backedge";
1910
2212
  declare const FLOW_APPROVAL_REVISE_DISABLED = "flow-approval-revise-disabled";
2213
+ /**
2214
+ * #3823 — the `revise` edge targets a node that is not the service-owned revise
2215
+ * window. `error`: `ApprovalService.sendBack` refuses this metadata outright
2216
+ * (see {@link scanApprovalReviseLoops}).
2217
+ */
2218
+ declare const FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED = "flow-approval-revise-target-not-service-owned";
1911
2219
  /**
1912
2220
  * #3760 — renamed from `flow-schedule-runas-unscoped`. The old id named the
1913
2221
  * *schedule*, which was never the boundary: the rule is about a trigger that
@@ -1923,8 +2231,22 @@ declare const FLOW_MULTIPLE_DEFAULT_EDGES = "flow-multiple-default-edges";
1923
2231
  /** #4414 — `config.condition` on a node whose executor never reads it. */
1924
2232
  declare const FLOW_INERT_NODE_CONDITION = "flow-inert-node-condition";
1925
2233
  /**
1926
- * Lint every flow's start node for known authoring anti-patterns. Returns a
1927
- * (possibly empty) list of advisory findings never throws, never fails a build.
2234
+ * #5482 a `delete_record` / `update_record` node that declares `multi: true`
2235
+ * and bounds it with NOTHING: the whole-object write, by declaration.
2236
+ *
2237
+ * Named descriptor-first per the family note on
2238
+ * `flow-time-relative-descriptor-invalid` in `validate-flow-trigger-readiness.ts`
2239
+ * (`flow-<descriptor>-<verdict>`, #5496): the descriptor is the
2240
+ * `multi` bulk declaration on a write node, the verdict is that no predicate
2241
+ * bounds it. See {@link scanUnboundedBulkWrites} for why this is a warning and
2242
+ * how it divides labour with the #3810 run-time guard.
2243
+ */
2244
+ declare const FLOW_MULTI_WRITE_UNFILTERED = "flow-multi-write-unfiltered";
2245
+ /**
2246
+ * Lint every flow for known authoring anti-patterns — its own graph AND every
2247
+ * nested ADR-0031 region (#5383). Returns a (possibly empty) list of findings;
2248
+ * never throws. A finding marked `severity: 'error'` fails the build, and since
2249
+ * #5383 it can be raised by a node inside a `loop` body too.
1928
2250
  */
1929
2251
  declare function lintFlowPatterns(stack: AnyRec$3): FlowLintFinding[];
1930
2252
 
@@ -2003,36 +2325,86 @@ interface LintIssue {
2003
2325
  fix?: string;
2004
2326
  }
2005
2327
  declare const UNIQUE_DOUBLE_DECLARATION = "unique/double-declaration";
2006
- /**
2007
- * R10 the same column carries BOTH a field-level `unique: true` and an
2008
- * object-level single-column unique index (#3991).
2009
- *
2010
- * The two spellings are deliberately different (see `IndexSchema`): field-level
2011
- * `unique: true` is tenant-scoped since #3696 — it materializes as
2012
- * `(organization_id, col)`, unique *within* the tenant while a declared index
2013
- * is materialized over exactly the columns listed, i.e. platform-wide. Both are
2014
- * legitimate on their own; together on one column they are never right:
2015
- *
2016
- * - On a tenant-scoped object they CONTRADICT. The stricter one wins
2017
- * physically, so the global index enforces uniqueness and the tenant
2018
- * composite becomes a constraint nothing can ever trip. One of the two
2019
- * intents the author wrote is silently discarded.
2020
- * - On a tenancy-less object they are exactly REDUNDANT — both describe the
2021
- * same single-column unique index, under the same generated name.
2022
- *
2023
- * Tenancy is deliberately NOT inferred here: `organization_id` is injected by
2024
- * the kernel at registration rather than authored, so an authoring-time guess
2025
- * would be wrong half the time. The combination is worth flagging either way,
2026
- * and the message names both readings so the author picks the one they meant.
2027
- *
2028
- * A field declared `unique: 'global'` is exempt: it already says
2029
- * platform-wide, so the declared index restates the same intent rather than
2030
- * contradicting it (still redundant, but not a silent loss of meaning).
2328
+ declare const UNIQUE_UNSCOPED_DECLARED_INDEX = "unique/unscoped-declared-index";
2329
+ declare const UNIQUE_LEGACY_ORGANIZATION_COMPOSITE = "unique/legacy-organization-composite";
2330
+ /**
2331
+ * R11 (ADR-0120 D5a) — a declared index carries bare `unique: true`: the one
2332
+ * spelling whose scope is unstated.
2333
+ *
2334
+ * Positional intent is the #4986 trap: an author writes
2335
+ * `indexes: [{ fields: ['name'], unique: true }]` on an organization-scoped
2336
+ * object, intends "unique per organization", and silently gets
2337
+ * installation-wide. This rule fires on the SPELLING alone — deliberately no
2338
+ * tenancy or posture inference (`organization_id` is kernel-injected at
2339
+ * registration, not authored, so an authoring-time guess would be wrong half
2340
+ * the time; that dead end is documented on #4698). Both replacement words are
2341
+ * checkable at authoring time, which is what makes this the first gate in the
2342
+ * #4986 saga that can actually run here.
2343
+ *
2344
+ * 17.x: warning. Protocol 18 rejects the spelling at validate/publish (#5082).
2345
+ * Advisory never fails a build in 17.x.
2346
+ *
2347
+ * Wiring: own AUTHORING_RULES entry (validate/build), and `lintDataModel`
2348
+ * calls it for `os lint` each command reports each finding exactly once.
2349
+ */
2350
+ declare function lintUnscopedDeclaredIndexes(objects: any[]): LintIssue[];
2351
+ /**
2352
+ * R10 (ADR-0120 D5b) the same single column carries BOTH a field-level
2353
+ * `unique` and a declared single-column unique index (#3991), judged in the
2354
+ * scope vocabulary. Each side states (or positionally implies) a boundary —
2355
+ * field: `true`/`'organization'` = per-organization, `'global'` =
2356
+ * installation-wide; declared index: `'global'` (or bare `true`, its
2357
+ * deprecated spelling) = installation-wide, `'organization'` =
2358
+ * per-organization — giving four quadrants:
2359
+ *
2360
+ * - Different scopes (field per-organization × index `'global'`, or field
2361
+ * `'global'` × index `'organization'`): CONTRADICTION. The installation-wide
2362
+ * index is physically stricter and wins; the per-organization constraint
2363
+ * can never be tripped. One declared intent is silently dead.
2364
+ * - Same scope (both per-organization, or both installation-wide):
2365
+ * REDUNDANCY — the same index declared twice.
2366
+ *
2367
+ * Tenancy is deliberately NOT inferred here — the quadrants are judged from
2368
+ * the two spellings alone, which is exactly what the vocabulary buys
2369
+ * (pre-ADR-0120, the contradiction quadrant could only be described
2370
+ * conditionally on unknowable tenancy).
2371
+ *
2372
+ * A composite declared index (`['organization_id', 'email']`) stays exempt:
2373
+ * it is the legacy hand-written organization spelling and agrees with the
2374
+ * field-level default (its `'organization'` respelling nudge is ADR-0120 D5c,
2375
+ * a separate wave).
2031
2376
  *
2032
2377
  * Advisory. The resulting stack is well-defined — the cost is an intent that
2033
2378
  * never takes effect, not a broken artifact — so this never fails a build.
2034
2379
  */
2035
2380
  declare function lintUniqueDeclarations(objects: any[]): LintIssue[];
2381
+ /**
2382
+ * R12 (ADR-0120 D5c) — a declared unique index whose column list CONTAINS the
2383
+ * organization column: the hand-written per-organization composite (S6),
2384
+ * predating the vocabulary that can now say so.
2385
+ *
2386
+ * Why this is worth a nudge rather than left alone. The legacy spelling
2387
+ * `{ fields: ['organization_id', 'name'], unique: true }` says "per
2388
+ * organization" to a reader and materializes as a plain composite — and SQL
2389
+ * UNIQUE is NULL-distinct, so on every row where the organization column is
2390
+ * NULL it enforces **nothing** (#5030, measured). On a single-organization
2391
+ * deployment that is *every* row. The `'organization'` respelling is what closes
2392
+ * that hole: the driver makes the LISTED organization column NULL-safe in place
2393
+ * (`COALESCE(organization_id, '__global__')`), so the NULL rows become one
2394
+ * platform bucket that is unique among themselves.
2395
+ *
2396
+ * **Advisory, and deliberately no auto-fix.** ADR-0120 D5c is explicit that the
2397
+ * legacy spelling stays valid and unmigrated forever if untouched — zero forced
2398
+ * drift. Opting in is a real physical tightening that goes through the D4
2399
+ * ceremony (a `recreate_index` gated by the duplicate pre-flight probe), because
2400
+ * the rows the void constraint admitted may still be there. Fixing this on the
2401
+ * author's behalf would schedule that migration without asking.
2402
+ *
2403
+ * Not fired for `unique: 'organization'` — that IS the respelling — nor for a
2404
+ * unique declared on the organization column ALONE, which is not a composite and
2405
+ * has no per-organization reading to recover.
2406
+ */
2407
+ declare function lintLegacyOrganizationComposites(objects: any[]): LintIssue[];
2036
2408
  /**
2037
2409
  * Lint the relationship / data-modeling conventions across the full object set.
2038
2410
  * Pure and deterministic — safe to call from both the `lint` command and the
@@ -2040,4 +2412,4 @@ declare function lintUniqueDeclarations(objects: any[]): LintIssue[];
2040
2412
  */
2041
2413
  declare function lintDataModel(objects: any[]): LintIssue[];
2042
2414
 
2043
- export { ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_NAME_UNDEFINED, ACTION_NO_PLACEMENT, ACTION_RECORD_WRITE_DISCARDED, ACTION_RECORD_WRITE_PATTERNS, ACTION_RECORD_WRITE_PATTERN_IDS, AGENT_AUTHORING_WITHDRAWN, AI_SKILL_SURFACE_MISMATCH, AI_SKILL_TOOL_UNRESOLVED, APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY, APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED, APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER, APPROVAL_APPROVER_TYPE_DEPRECATED, APPROVAL_APPROVER_TYPE_UNKNOWN, APPROVAL_DECISION_OUTPUTS_RESERVED, APPROVAL_ESCALATION_REASSIGN_NO_TARGET, APPROVAL_EXPRESSION_INVALID, APPROVAL_EXPRESSION_NO_EMPTY_POLICY, AUTONUMBER_LITERAL_TOKEN, AUTONUMBER_OPTIONAL_FIELD, AUTONUMBER_SELF_REFERENCE, AUTONUMBER_UNKNOWN_FIELD, type ActionBodyWriteExclusion, type ActionBodyWriteFinding, type ActionBodyWriteSeverity, type ActionLocationsFinding, type ActionLocationsSeverity, type ActionNameRefFinding, type ActionNameRefSeverity, type AiAgentAuthoringFinding, type AiAgentAuthoringSeverity, type AiSurfaceAffinityFinding, type AiSurfaceAffinitySeverity, type AiToolRefFinding, type AiToolRefSeverity, type ApprovalApproverFinding, type ApprovalApproverSeverity, type AutonumberLintFinding, type BodyWritePatternExclusion, CAPABILITY_REFERENCE_UNKNOWN, CHART_AXIS_NOT_SELECTED, CHART_CONFIG_MISSING, CHART_DATASET_UNKNOWN, CHART_DIMENSION_UNKNOWN, CHART_FIELD_UNKNOWN, CHART_MEASURE_UNKNOWN, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_UNKNOWN, type DashboardActionRefFinding, type DashboardActionRefSeverity, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, FIELD_GROUP_EMPTY, FIELD_GROUP_UNDECLARED, FILTER_TOKEN_UNKNOWN, FLOW_APPROVAL_REVISE_DEAD_END, FLOW_APPROVAL_REVISE_DISABLED, FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE, FLOW_BARE_DOLLAR_REF, FLOW_BRANCH_LABEL_UNMATCHED, FLOW_DATE_EQUALITY_FILTER, FLOW_DECISION_UNCONDITIONAL_BRANCH, FLOW_DEFAULT_EDGE_WITH_CONDITION, FLOW_DOUBLE_BRACE_INTERP, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_ERROR_LABEL_NOT_FAULT, FLOW_INERT_NODE_CONDITION, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TIME_RELATIVE_ANTIPATTERN, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FilterTokenFinding, type FilterTokenSeverity, type FlowLintFinding, type FlowNodeWriteFinding, type FlowNodeWriteSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FlowWriteNodeDeferral, type FormLayoutFinding, type FormLayoutSeverity, type FunctionalCompletenessFinding, type FunctionalCompletenessSeverity, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, type LintIssue, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, MEASURE_AGGREGATE_INCOHERENT, NAV_OBJECT_UNGRANTED, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_SOURCE_CLASSNAME, type PageFieldFinding, type PageFieldSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_FIELD_UNKNOWN, REFERENCE_INTEGRITY_RULES, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_DELEGATION_MISSING_REASON, SECURITY_EXTERNAL_WIDER, SECURITY_GRANT_EXPIRED_AT_AUTHORING, SECURITY_MASTER_DETAIL_UNGRANTED, SECURITY_OWD_ALIAS, SECURITY_OWD_UNSET, SECURITY_PRIVATE_NO_READSCOPE, SECURITY_ROLE_WORD, SECURITY_WILDCARD_VAMA, SEED_INSERT_MODE_DUPLICATES_ON_REPLAY, SEED_VALUE_OUTSIDE_STATE_MACHINE, SEMANTIC_ROLE_FIELD_UNKNOWN, STYLE_CLASSNAME_TAILWIND, STYLE_NODE_MISSING_ID, STYLE_RESPONSIVE_NO_BASE, STYLE_UNKNOWN_CSS_PROPERTY, STYLE_UNKNOWN_TOKEN, type SearchableFieldFinding, type SearchableFieldRole, type SearchableFieldSeverity, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SourceStyleFinding, type SourceStyleSeverity, type StyleFinding, type StyleSeverity, TABLE_COUNT_ONLY, TITLE_FORMAT_RETIRED, TITLE_UNRESOLVABLE, TRANSLATION_OPTION_KEY_UNKNOWN, TRANSLATION_TARGET_UNKNOWN, type TranslationRefFinding, type TranslationRefSeverity, UNIQUE_DOUBLE_DECLARATION, VIEW_CONTAINER_SHAPE, VIEW_KEY_COLLISION, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_MEASURE_UNKNOWN, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, findUnguardedNullableOperands, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLivenessProperties, lintUniqueDeclarations, lintViewRefs, nullGuardMessage, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateDashboardActionRefs, validateFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewMode, validateNavAccess, validateNavTargetRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateReadonlyFlowWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateSearchableFields, validateSecurityPosture, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateStackExpressions, validateTranslationReferences, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings };
2415
+ export { ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_NAME_UNDEFINED, ACTION_NO_PLACEMENT, ACTION_RECORD_WRITE_DISCARDED, ACTION_RECORD_WRITE_PATTERNS, ACTION_RECORD_WRITE_PATTERN_IDS, AGENT_AUTHORING_WITHDRAWN, AI_SKILL_SURFACE_MISMATCH, AI_SKILL_TOOL_UNRESOLVED, APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY, APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED, APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER, APPROVAL_APPROVER_TYPE_DEPRECATED, APPROVAL_APPROVER_TYPE_UNKNOWN, APPROVAL_APPROVER_TYPE_UNSUPPORTED, APPROVAL_DECISION_OUTPUTS_RESERVED, APPROVAL_ESCALATION_REASSIGN_NO_TARGET, APPROVAL_EXPRESSION_INVALID, APPROVAL_EXPRESSION_NO_EMPTY_POLICY, AUTONUMBER_LITERAL_TOKEN, AUTONUMBER_OPTIONAL_FIELD, AUTONUMBER_SELF_REFERENCE, AUTONUMBER_UNKNOWN_FIELD, type ActionBodyWriteExclusion, type ActionBodyWriteFinding, type ActionBodyWriteSeverity, type ActionLocationsFinding, type ActionLocationsSeverity, type ActionNameRefFinding, type ActionNameRefSeverity, type AiAgentAuthoringFinding, type AiAgentAuthoringSeverity, type AiSurfaceAffinityFinding, type AiSurfaceAffinitySeverity, type AiToolRefFinding, type AiToolRefSeverity, type ApprovalApproverFinding, type ApprovalApproverSeverity, type AutonumberLintFinding, type BodyWritePatternExclusion, CAPABILITY_REFERENCE_UNKNOWN, CHART_AXIS_NOT_SELECTED, CHART_CONFIG_MISSING, CHART_DATASET_UNKNOWN, CHART_DIMENSION_UNKNOWN, CHART_FIELD_UNKNOWN, CHART_MEASURE_UNKNOWN, COMPONENT_PROPS_INVALID, COMPONENT_PROPS_UNKNOWN_KEY, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, type ComponentPropsFinding, type ComponentPropsSeverity, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_UNKNOWN, type DashboardActionRefFinding, type DashboardActionRefSeverity, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, FIELD_GROUP_EMPTY, FIELD_GROUP_SHADOWED, FIELD_GROUP_UNDECLARED, FILTER_TOKEN_UNKNOWN, FLOW_APPROVAL_REVISE_DEAD_END, FLOW_APPROVAL_REVISE_DISABLED, FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED, FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE, FLOW_BARE_DOLLAR_REF, FLOW_BRANCH_LABEL_UNMATCHED, FLOW_DATE_EQUALITY_FILTER, FLOW_DECISION_UNCONDITIONAL_BRANCH, FLOW_DEFAULT_EDGE_WITH_CONDITION, FLOW_DOUBLE_BRACE_INTERP, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_ERROR_LABEL_NOT_FAULT, FLOW_INERT_NODE_CONDITION, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_MULTI_WRITE_UNFILTERED, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TIME_RELATIVE_ANTIPATTERN, FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID, FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE, FLOW_TRIGGER_UNKNOWN_EVENT, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FilterTokenFinding, type FilterTokenSeverity, type FlowLintFinding, type FlowNodeWriteFinding, type FlowNodeWriteSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FlowWriteNodeDeferral, type FormLayoutFinding, type FormLayoutSeverity, type FunctionalCompletenessFinding, type FunctionalCompletenessSeverity, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, type LintIssue, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, MAX_SCHEMA_WALK_DEPTH, MEASURE_AGGREGATE_INCOHERENT, NAV_OBJECT_UNGRANTED, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_SOURCE_CLASSNAME, type PageFieldFinding, type PageFieldSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_DRILLDOWN_INVALID, REACT_CHART_FIELD_UNKNOWN, REFERENCE_INTEGRITY_RULES, RLS_PREDICATE_UNENFORCEABLE, RLS_PREDICATE_UNPARSEABLE, RUNTIME_AJV_OPTIONS, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, type RlsPredicateFinding, type RlsPredicateSeverity, type RuleCompilabilityFinding, type RuleCompilabilitySeverity, type RuleSchemaFormatFinding, type RuleSchemaFormatSeverity, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_DELEGATION_MISSING_REASON, SECURITY_EXTERNAL_WIDER, SECURITY_FLS_UNQUALIFIED_KEY, SECURITY_GRANT_EXPIRED_AT_AUTHORING, SECURITY_MASTER_DETAIL_UNGRANTED, SECURITY_OWD_ALIAS, SECURITY_OWD_UNSET, SECURITY_PRIVATE_NO_READSCOPE, SECURITY_ROLE_WORD, SECURITY_WILDCARD_VAMA, SEED_INSERT_MODE_DUPLICATES_ON_REPLAY, SEED_VALUE_OUTSIDE_STATE_MACHINE, SEMANTIC_ROLE_FIELD_UNKNOWN, SHARING_RULE_RUNTIME_VARIABLE_CONDITION, SHARING_RULE_UNLOWERABLE_CONDITION, STYLE_CLASSNAME_TAILWIND, STYLE_NODE_MISSING_ID, STYLE_RESPONSIVE_NO_BASE, STYLE_UNKNOWN_CSS_PROPERTY, STYLE_UNKNOWN_TOKEN, type SearchableFieldFinding, type SearchableFieldRole, type SearchableFieldSeverity, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SharingRuleEnforceabilityFinding, type SharingRuleEnforceabilitySeverity, type SourceStyleFinding, type SourceStyleSeverity, type StyleFinding, type StyleSeverity, TABLE_COUNT_ONLY, TITLE_FORMAT_RETIRED, TITLE_UNRESOLVABLE, TRANSLATION_OPTION_KEY_UNKNOWN, TRANSLATION_SECTION_NAME_MISSING, TRANSLATION_TARGET_UNKNOWN, type TranslatableSectionFinding, type TranslatableSectionSeverity, type TranslationRefFinding, type TranslationRefSeverity, UNIQUE_DOUBLE_DECLARATION, UNIQUE_LEGACY_ORGANIZATION_COMPOSITE, UNIQUE_UNSCOPED_DECLARED_INDEX, VALIDATION_RULE_REGEX_UNCOMPILABLE, VALIDATION_RULE_SCHEMA_UNCOMPILABLE, VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT, VIEW_CONTAINER_SHAPE, VIEW_KEY_COLLISION, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_LEGACY_ANALYTICS_SHAPE, WIDGET_LEGACY_ANALYTICS_UNRENDERABLE, WIDGET_MEASURE_UNKNOWN, type WalkedComponent, type WalkedValidationRule, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, findUnguardedNullableOperands, isSourceAuthoredPage, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLegacyOrganizationComposites, lintLivenessProperties, lintUniqueDeclarations, lintUnscopedDeclaredIndexes, lintViewRefs, nearestRegisteredFormat, nullGuardMessage, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateComponentProps, validateDashboardActionRefs, validateFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewMode, validateNavAccess, validateNavTargetRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateReadonlyFlowWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateRlsPredicateEnforceability, validateRuleCompilability, validateRuleSchemaFormats, validateSearchableFields, validateSecurityPosture, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateSharingRuleEnforceability, validateStackExpressions, validateTranslatableSections, validateTranslationReferences, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings, walkPageComponents };