@objectstack/lint 16.1.0 → 17.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -94,7 +94,7 @@ interface WidgetBindingFinding {
94
94
  /** How to fix (or deliberately suppress) it. */
95
95
  hint: string;
96
96
  }
97
- type AnyRec$h = Record<string, unknown>;
97
+ type AnyRec$t = Record<string, unknown>;
98
98
  /**
99
99
  * Validate every dashboard widget's dataset binding. Returns the list of
100
100
  * findings (empty = clean). Caller decides how to surface them: `error`
@@ -102,7 +102,7 @@ type AnyRec$h = Record<string, unknown>;
102
102
  * should fail validate/build; `warning` findings are advisory and must
103
103
  * never fail the build on their own.
104
104
  */
105
- declare function validateWidgetBindings(stack: AnyRec$h): WidgetBindingFinding[];
105
+ declare function validateWidgetBindings(stack: AnyRec$t): WidgetBindingFinding[];
106
106
 
107
107
  interface ExprIssue {
108
108
  where: string;
@@ -115,12 +115,12 @@ interface ExprIssue {
115
115
  */
116
116
  severity?: 'error' | 'warning';
117
117
  }
118
- type AnyRec$g = Record<string, unknown>;
118
+ type AnyRec$s = Record<string, unknown>;
119
119
  /**
120
120
  * Validate every predicate in the stack. Returns the list of issues (empty =
121
121
  * clean). Caller decides how to surface / whether to fail the build.
122
122
  */
123
- declare function validateStackExpressions(stack: AnyRec$g): ExprIssue[];
123
+ declare function validateStackExpressions(stack: AnyRec$s): ExprIssue[];
124
124
 
125
125
  type ListViewModeSeverity = 'error' | 'warning';
126
126
  interface ListViewModeFinding {
@@ -134,7 +134,7 @@ interface ListViewModeFinding {
134
134
  hint: string;
135
135
  }
136
136
  declare const LIST_VIEW_FILTERS_IN_VIEWS_MODE = "list-view-filters-in-views-mode";
137
- type AnyRec$f = Record<string, unknown>;
137
+ type AnyRec$r = Record<string, unknown>;
138
138
  /**
139
139
  * Flag ADR-0047 "views" mode violations on an object's built-in named views or a
140
140
  * `defineView` default `list` / named `listViews`: `quickFilters`, or a `tabs`
@@ -144,7 +144,7 @@ type AnyRec$f = Record<string, unknown>;
144
144
  *
145
145
  * Feed the PRE-parse stack (normalizeStackInput output) — see file header.
146
146
  */
147
- declare function validateListViewMode(stack: AnyRec$f): ListViewModeFinding[];
147
+ declare function validateListViewMode(stack: AnyRec$r): ListViewModeFinding[];
148
148
 
149
149
  type FlowTriggerReadinessSeverity = 'error' | 'warning';
150
150
  interface FlowTriggerReadinessFinding {
@@ -159,12 +159,52 @@ interface FlowTriggerReadinessFinding {
159
159
  }
160
160
  declare const FLOW_TRIGGER_UNKNOWN_OBJECT = "flow-trigger-unknown-object";
161
161
  declare const FLOW_DRAFT_STATUS_AMBIGUOUS = "flow-draft-status-ambiguous";
162
- type AnyRec$e = Record<string, unknown>;
162
+ type AnyRec$q = Record<string, unknown>;
163
163
  /**
164
164
  * Validate auto-launched flow trigger wiring against the stack definition.
165
165
  * Pure and dependency-free; safe on pre- or post-parse stacks.
166
166
  */
167
- declare function validateFlowTriggerReadiness(stack: AnyRec$e): FlowTriggerReadinessFinding[];
167
+ declare function validateFlowTriggerReadiness(stack: AnyRec$q): FlowTriggerReadinessFinding[];
168
+
169
+ type FlowTemplatePathSeverity = 'error' | 'warning';
170
+ interface FlowTemplatePathFinding {
171
+ severity: FlowTemplatePathSeverity;
172
+ rule: string;
173
+ /** Human-readable location, e.g. `flow "notify_lead" node "notify"`. */
174
+ where: string;
175
+ /** Config path, e.g. `flows[0].nodes[2]`. */
176
+ path: string;
177
+ message: string;
178
+ hint: string;
179
+ }
180
+ declare const FLOW_TEMPLATE_UNKNOWN_FIELD = "flow-template-unknown-field";
181
+ declare const FLOW_TEMPLATE_LOOKUP_TRAVERSAL = "flow-template-lookup-traversal";
182
+ type AnyRec$p = Record<string, unknown>;
183
+ /**
184
+ * Validate `{record.<path>}` template references across every record-change
185
+ * flow. Pure and dependency-free; safe on pre- or post-parse stacks.
186
+ */
187
+ declare function validateFlowTemplatePaths(stack: AnyRec$p): FlowTemplatePathFinding[];
188
+
189
+ type ReadonlyFlowWriteSeverity = 'error' | 'warning';
190
+ interface ReadonlyFlowWriteFinding {
191
+ severity: ReadonlyFlowWriteSeverity;
192
+ rule: string;
193
+ /** Human-readable location, e.g. `flow "approve_deal" › node "Mark approved"`. */
194
+ where: string;
195
+ /** Config path, e.g. `flows[0].nodes[3].config.fields.approval_status`. */
196
+ path: string;
197
+ message: string;
198
+ hint: string;
199
+ }
200
+ declare const FLOW_UPDATE_READONLY_FIELD = "flow-update-readonly-field";
201
+ declare const FLOW_UPDATE_READONLY_WHEN_FIELD = "flow-update-readonly-when-field";
202
+ type AnyRec$o = Record<string, unknown>;
203
+ /**
204
+ * Validate flow `update_record` writes against target-object readonly
205
+ * declarations. Pure and dependency-free; safe on pre- or post-parse stacks.
206
+ */
207
+ declare function validateReadonlyFlowWrites(stack: AnyRec$o): ReadonlyFlowWriteFinding[];
168
208
 
169
209
  type ViewContainerSeverity = 'error' | 'warning';
170
210
  interface ViewContainerFinding {
@@ -201,14 +241,14 @@ declare const STYLE_CLASSNAME_TAILWIND = "style-classname-tailwind";
201
241
  declare const STYLE_RESPONSIVE_NO_BASE = "style-responsive-no-base";
202
242
  declare const STYLE_UNKNOWN_CSS_PROPERTY = "style-unknown-css-property";
203
243
  declare const STYLE_UNKNOWN_TOKEN = "style-unknown-token";
204
- type AnyRec$d = Record<string, unknown>;
244
+ type AnyRec$n = Record<string, unknown>;
205
245
  /**
206
246
  * Validate every page's component tree for SDUI styling correctness (ADR-0065).
207
247
  * Returns findings (empty = clean). `error` findings describe styles that are
208
248
  * silently dropped and should fail validate/build; `warning` findings are
209
249
  * advisory (typos, drift, footguns).
210
250
  */
211
- declare function validateResponsiveStyles(stack: AnyRec$d): StyleFinding[];
251
+ declare function validateResponsiveStyles(stack: AnyRec$n): StyleFinding[];
212
252
 
213
253
  type JsxPageSeverity = 'error' | 'warning';
214
254
  interface JsxPageFinding {
@@ -221,8 +261,8 @@ interface JsxPageFinding {
221
261
  message: string;
222
262
  hint: string;
223
263
  }
224
- type AnyRec$c = Record<string, unknown>;
225
- declare function validateJsxPages(stack: AnyRec$c, opts?: {
264
+ type AnyRec$m = Record<string, unknown>;
265
+ declare function validateJsxPages(stack: AnyRec$m, opts?: {
226
266
  manifest?: Manifest;
227
267
  }): JsxPageFinding[];
228
268
 
@@ -235,8 +275,8 @@ interface ReactPageFinding {
235
275
  message: string;
236
276
  hint: string;
237
277
  }
238
- type AnyRec$b = Record<string, unknown>;
239
- declare function validateReactPages(stack: AnyRec$b): ReactPageFinding[];
278
+ type AnyRec$l = Record<string, unknown>;
279
+ declare function validateReactPages(stack: AnyRec$l): ReactPageFinding[];
240
280
 
241
281
  type ReactPropSeverity = 'error' | 'warning';
242
282
  interface ReactPropFinding {
@@ -247,8 +287,11 @@ interface ReactPropFinding {
247
287
  message: string;
248
288
  hint: string;
249
289
  }
250
- type AnyRec$a = Record<string, unknown>;
251
- declare function validateReactPageProps(stack: AnyRec$a): ReactPropFinding[];
290
+ type AnyRec$k = Record<string, unknown>;
291
+ declare const REACT_CHART_FIELD_UNKNOWN = "react-chart-field-unknown";
292
+ declare const REACT_CHART_AGGREGATE_INVALID = "react-chart-aggregate-invalid";
293
+ declare const REACT_CHART_AXIS_UNKNOWN = "react-chart-axis-unknown";
294
+ declare function validateReactPageProps(stack: AnyRec$k): ReactPropFinding[];
252
295
 
253
296
  type SourceStyleSeverity = 'error' | 'warning';
254
297
  interface SourceStyleFinding {
@@ -260,8 +303,8 @@ interface SourceStyleFinding {
260
303
  hint: string;
261
304
  }
262
305
  declare const PAGE_SOURCE_CLASSNAME = "page-source-className-tailwind";
263
- type AnyRec$9 = Record<string, unknown>;
264
- declare function validatePageSourceStyling(stack: AnyRec$9): SourceStyleFinding[];
306
+ type AnyRec$j = Record<string, unknown>;
307
+ declare function validatePageSourceStyling(stack: AnyRec$j): SourceStyleFinding[];
265
308
 
266
309
  /**
267
310
  * Build-time record-title diagnostics (ADR-0079).
@@ -305,14 +348,14 @@ interface RecordTitleFinding {
305
348
  /** How to fix it. */
306
349
  hint: string;
307
350
  }
308
- type AnyRec$8 = Record<string, unknown>;
351
+ type AnyRec$i = Record<string, unknown>;
309
352
  /**
310
353
  * Validate every object's record-title declaration. Returns the list of
311
354
  * findings (empty = clean). Both rules are advisory (`warning`): the caller
312
355
  * must never fail the build on them alone — auto-provision + the `Record #<id>`
313
356
  * floor guarantee a resolvable title at runtime.
314
357
  */
315
- declare function validateRecordTitle(stack: AnyRec$8): RecordTitleFinding[];
358
+ declare function validateRecordTitle(stack: AnyRec$i): RecordTitleFinding[];
316
359
 
317
360
  /**
318
361
  * Build-time semantic-role diagnostics (ADR-0085).
@@ -349,13 +392,13 @@ interface SemanticRoleFinding {
349
392
  /** How to fix it. */
350
393
  hint: string;
351
394
  }
352
- type AnyRec$7 = Record<string, unknown>;
395
+ type AnyRec$h = Record<string, unknown>;
353
396
  /**
354
397
  * Validate every object's semantic-role pointers. Returns the list of
355
398
  * findings (empty = clean). Advisory only — the caller must never fail the
356
399
  * build on these alone.
357
400
  */
358
- declare function validateSemanticRoles(stack: AnyRec$7): SemanticRoleFinding[];
401
+ declare function validateSemanticRoles(stack: AnyRec$h): SemanticRoleFinding[];
359
402
 
360
403
  /**
361
404
  * Build-time form-layout diagnostics (#2578).
@@ -398,12 +441,12 @@ interface FormLayoutFinding {
398
441
  /** How to fix it. */
399
442
  hint: string;
400
443
  }
401
- type AnyRec$6 = Record<string, unknown>;
444
+ type AnyRec$g = Record<string, unknown>;
402
445
  /**
403
446
  * Validate authored form-view layout. Returns findings (empty = clean).
404
447
  * Advisory only — the caller must never fail the build on these alone.
405
448
  */
406
- declare function validateFormLayout(stack: AnyRec$6): FormLayoutFinding[];
449
+ declare function validateFormLayout(stack: AnyRec$g): FormLayoutFinding[];
407
450
 
408
451
  /**
409
452
  * Build-time conditional-visibility diagnostics (ADR-0089 D3b).
@@ -465,7 +508,7 @@ interface VisibilityFinding {
465
508
  /** How to fix it. */
466
509
  hint: string;
467
510
  }
468
- type AnyRec$5 = Record<string, unknown>;
511
+ type AnyRec$f = Record<string, unknown>;
469
512
  /**
470
513
  * Validate conditional-visibility keys across authored views and pages.
471
514
  *
@@ -480,7 +523,7 @@ type AnyRec$5 = Record<string, unknown>;
480
523
  * `*.view.ts` / `*.page.ts` surfaces (so a `data.`-rooted predicate is flagged). The
481
524
  * alias-deprecated check is layer-agnostic.
482
525
  */
483
- declare function validateVisibilityPredicates(stack: AnyRec$5, opts?: VisibilityOptions): VisibilityFinding[];
526
+ declare function validateVisibilityPredicates(stack: AnyRec$f, opts?: VisibilityOptions): VisibilityFinding[];
484
527
 
485
528
  declare const CAPABILITY_REFERENCE_UNKNOWN = "capability-reference-unknown";
486
529
  type CapabilityRefSeverity = 'error' | 'warning';
@@ -498,17 +541,22 @@ interface CapabilityRefFinding {
498
541
  /** How to fix it. */
499
542
  hint: string;
500
543
  }
501
- type AnyRec$4 = Record<string, unknown>;
544
+ type AnyRec$e = Record<string, unknown>;
502
545
  /**
503
546
  * Validate every capability reference in a stack. Returns findings (empty =
504
547
  * clean). Advisory only — callers must not fail the build on these alone.
505
548
  */
506
- declare function validateCapabilityReferences(stack: AnyRec$4): CapabilityRefFinding[];
549
+ declare function validateCapabilityReferences(stack: AnyRec$e): CapabilityRefFinding[];
507
550
 
508
551
  declare const APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER = "approval-approver-not-membership-tier";
509
552
  declare const APPROVAL_APPROVER_TYPE_DEPRECATED = "approval-approver-type-deprecated";
510
553
  declare const APPROVAL_APPROVER_TYPE_UNKNOWN = "approval-approver-type-unknown";
511
554
  declare const APPROVAL_ESCALATION_REASSIGN_NO_TARGET = "approval-escalation-reassign-no-target";
555
+ declare const APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY = "approval-approvers-may-resolve-empty";
556
+ declare const APPROVAL_EXPRESSION_INVALID = "approval-expression-invalid";
557
+ declare const APPROVAL_EXPRESSION_NO_EMPTY_POLICY = "approval-expression-no-empty-policy";
558
+ declare const APPROVAL_DECISION_OUTPUTS_RESERVED = "approval-decision-outputs-reserved";
559
+ declare const APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED = "approval-approver-cross-org-unsupported";
512
560
  type ApprovalApproverSeverity = 'error' | 'warning' | 'info';
513
561
  interface ApprovalApproverFinding {
514
562
  severity: ApprovalApproverSeverity;
@@ -523,12 +571,63 @@ interface ApprovalApproverFinding {
523
571
  /** How to fix it. */
524
572
  hint: string;
525
573
  }
526
- type AnyRec$3 = Record<string, unknown>;
574
+ type AnyRec$d = Record<string, unknown>;
527
575
  /**
528
576
  * Validate the approvers of every Approval node in the stack's flows.
529
577
  * Returns findings (empty = clean).
530
578
  */
531
- declare function validateApprovalApprovers(stack: AnyRec$3): ApprovalApproverFinding[];
579
+ declare function validateApprovalApprovers(stack: AnyRec$d): ApprovalApproverFinding[];
580
+
581
+ type SeedReplaySafetySeverity = 'error' | 'warning';
582
+ interface SeedReplaySafetyFinding {
583
+ severity: SeedReplaySafetySeverity;
584
+ rule: string;
585
+ /** Human-readable location, e.g. `seed "showcase_project_membership"`. */
586
+ where: string;
587
+ /** Config path, e.g. `data[12].mode`. */
588
+ path: string;
589
+ message: string;
590
+ hint: string;
591
+ }
592
+ declare const SEED_INSERT_MODE_DUPLICATES_ON_REPLAY = "seed-insert-mode-duplicates-on-replay";
593
+ type AnyRec$c = Record<string, unknown>;
594
+ /**
595
+ * Flag every seed dataset declared with `mode: 'insert'` — the one non-idempotent
596
+ * mode, which duplicates its rows on every replay boot (framework#3434). Returns
597
+ * the findings (empty = clean). The caller decides how to surface them / whether
598
+ * to fail the build; the CLI folds them in as advisory warnings.
599
+ *
600
+ * Reads `stack.data` (the `SeedSchema[]` fixtures). Safe on any shape — a stack
601
+ * with no `data` array yields no findings.
602
+ */
603
+ declare function validateSeedReplaySafety(stack: AnyRec$c): SeedReplaySafetyFinding[];
604
+
605
+ type SeedStateMachineSeverity = 'warning';
606
+ interface SeedStateMachineFinding {
607
+ severity: SeedStateMachineSeverity;
608
+ rule: string;
609
+ /** Human-readable location, e.g. `seed "showcase_project" ("Legacy Sunset")`. */
610
+ where: string;
611
+ /** Config path, e.g. `data[4].records[3].status`. */
612
+ path: string;
613
+ message: string;
614
+ hint: string;
615
+ }
616
+ declare const SEED_VALUE_OUTSIDE_STATE_MACHINE = "seed-value-outside-state-machine";
617
+ type AnyRec$b = Record<string, unknown>;
618
+ /**
619
+ * Flag every seed record whose `state_machine`-governed field carries a value
620
+ * the machine does not declare (framework#3433 follow-up). Returns the findings
621
+ * (empty = clean). The caller decides how to surface them; the CLI folds them in
622
+ * as advisory warnings.
623
+ *
624
+ * Reads `stack.objects` (for the state-machine rules) and `stack.data` (the
625
+ * `SeedSchema[]` fixtures). Safe on any shape — a stack with no objects or no
626
+ * `data` array yields no findings. A value that is not a plain string (an
627
+ * unresolved `cel` Expression envelope, a number) is skipped: it cannot be
628
+ * statically compared to the declared-state set.
629
+ */
630
+ declare function validateSeedStateMachine(stack: AnyRec$b): SeedStateMachineFinding[];
532
631
 
533
632
  declare const SECURITY_OWD_UNSET = "security-owd-unset";
534
633
  declare const SECURITY_OWD_ALIAS = "security-owd-alias";
@@ -555,7 +654,7 @@ interface SecurityFinding {
555
654
  /** How to fix it. */
556
655
  hint: string;
557
656
  }
558
- type AnyRec$2 = Record<string, unknown>;
657
+ type AnyRec$a = Record<string, unknown>;
559
658
  /**
560
659
  * Validate the security posture of a stack. Returns findings (empty = clean).
561
660
  * `error` findings gate the build in `os compile`; `info` is advisory.
@@ -563,10 +662,68 @@ type AnyRec$2 = Record<string, unknown>;
563
662
  * `opts.nowMs` injects the clock for the ADR-0091 authoring-time expiry rule
564
663
  * (tests); production callers omit it.
565
664
  */
566
- declare function validateSecurityPosture(stack: AnyRec$2, opts?: {
665
+ declare function validateSecurityPosture(stack: AnyRec$a, opts?: {
567
666
  nowMs?: number;
568
667
  }): SecurityFinding[];
569
668
 
669
+ /**
670
+ * [ADR-0105 D6] The two organization-axis red lines, enforced at authoring time.
671
+ *
672
+ * ADR-0105 gives organizations a reporting/grouping dimension
673
+ * (`sys_organization.parent_organization_id`, sibling ordering). That dimension
674
+ * is load-bearing for consolidated reporting — and dangerous, because it LOOKS
675
+ * like a permission hierarchy. Two lines keep it from becoming one:
676
+ *
677
+ * | Rule | Red line |
678
+ * |-----------------------------------------|-----------------------------------|
679
+ * | org-axis-permission-inheritance (error) | D6 ①: no inheritance along the org tree |
680
+ * | org-axis-cross-org-bu-grant (error) | D6 ②: business-unit trees stay org-internal |
681
+ *
682
+ * **① No permission inheritance along the org axis.** Cross-organization
683
+ * visibility comes from membership union (`accessible_org_ids`, ADR-0105 D2) —
684
+ * the engine's own Layer 0 wall — never from walking a parent reference. An RLS
685
+ * policy or sharing rule that reads `parent_organization_id` builds a SECOND
686
+ * permission hierarchy beside the business-unit tree: exactly the dual-hierarchy
687
+ * mistake ADR-0057 D5 retired and ADR-0090 D3 finalized for positions. It also
688
+ * silently outranks the wall it sits behind, since a Layer-1 policy cannot widen
689
+ * Layer 0 (W1) — so the author gets a rule that appears to grant access and
690
+ * does not. Fail at authoring, not in a support ticket.
691
+ *
692
+ * **② Business-unit trees remain org-internal.** `sys_business_unit` is
693
+ * org-scoped and every BU mechanism (`unit_and_subordinates` sharing,
694
+ * `adminScope` delegation, depth scopes) resolves within ONE organization. A
695
+ * business-unit sharing rule on a PLATFORM-GLOBAL object (`tenancy.enabled:
696
+ * false`) has no organization column to scope against, so the grant spans every
697
+ * organization in the database — a cross-org BU grant by construction, and the
698
+ * "cross-org BU mega-tree" the ADR rejected, arrived at by accident.
699
+ *
700
+ * Both are `error`, per ADR-0049 discipline: each mirrors a real enforcement
701
+ * property (the Layer 0 wall's independence; the org-predicated BU resolver),
702
+ * so the lint moves the failure from silent-wrong-answer to author-time fix-it.
703
+ *
704
+ * Pure `(stack) => Finding[]`; accepts the NORMALIZED stack input.
705
+ */
706
+ declare const ORG_AXIS_PERMISSION_INHERITANCE = "org-axis-permission-inheritance";
707
+ declare const ORG_AXIS_CROSS_ORG_BU_GRANT = "org-axis-cross-org-bu-grant";
708
+ type OrgAxisSeverity = 'error' | 'warning';
709
+ interface OrgAxisFinding {
710
+ severity: OrgAxisSeverity;
711
+ /** Diagnostic rule id (`org-axis-*`). */
712
+ rule: string;
713
+ /** Human-readable location, e.g. `permission set "plant_reader"`. */
714
+ where: string;
715
+ /** Config path, e.g. `permissions[2].rowLevelSecurity[0].using`. */
716
+ path: string;
717
+ /** What is wrong. */
718
+ message: string;
719
+ /** How to fix it. */
720
+ hint: string;
721
+ }
722
+ /**
723
+ * Lint an ObjectStack config for the ADR-0105 D6 organization-axis red lines.
724
+ */
725
+ declare function validateOrgAxisRedLines(stack: unknown): OrgAxisFinding[];
726
+
570
727
  /**
571
728
  * [ADR-0049 — references] Reference-integrity for dashboard header & widget
572
729
  * action targets (issue #3367).
@@ -639,13 +796,487 @@ interface DashboardActionRefFinding {
639
796
  /** How to fix it. */
640
797
  hint: string;
641
798
  }
642
- type AnyRec$1 = Record<string, unknown>;
799
+ type AnyRec$9 = Record<string, unknown>;
643
800
  /**
644
801
  * Validate every dashboard header / widget action reference in a stack. Returns
645
802
  * findings (empty = clean). `script`/`modal` dead targets are errors; `url`
646
803
  * unresolved routes are warnings.
647
804
  */
648
- declare function validateDashboardActionRefs(stack: AnyRec$1): DashboardActionRefFinding[];
805
+ declare function validateDashboardActionRefs(stack: AnyRec$9): DashboardActionRefFinding[];
806
+
807
+ /**
808
+ * Build-time filter-placeholder diagnostics (issue #3574).
809
+ *
810
+ * Filter values travel as JSON, so a user-scoped or time-scoped slice cannot
811
+ * call code inline — it writes a placeholder that the client resolves just
812
+ * before querying:
813
+ *
814
+ * { owner_id: '{current_user_id}', created_at: { $gte: '{week_start}' } }
815
+ *
816
+ * Exactly two vocabularies resolve inside a filter value: context tokens
817
+ * (`{current_user_id}`, `{current_org_id}` — see `context-tokens.zod.ts`) and
818
+ * date macros (`{today}`, `{30_days_ago}` — see `date-macros.zod.ts`).
819
+ * Anything else is passed to the data engine **verbatim**, matches no row, and
820
+ * the surface renders an empty result.
821
+ *
822
+ * ## Why this is an error, not a warning
823
+ *
824
+ * The runtime failure mode is silent and indistinguishable from success. A
825
+ * metric widget filtered on an unresolved `{current_user}` renders `0`, which
826
+ * looks exactly like a metric that is legitimately zero — no console error, no
827
+ * server log, nothing for a human reviewer to notice. Issue #3574 found a
828
+ * dashboard that had been broken this way since the day it was written.
829
+ *
830
+ * That failure mode is worse for AI authors than for humans. An AI reads a
831
+ * successful query returning `0` as a correct answer and builds on it — it has
832
+ * no instinct that the number looks wrong. Its correction loop is
833
+ * "author → validate → fix", so a diagnostic only reaches it if the diagnostic
834
+ * can fail the build. A runtime warning in a server log is invisible to it.
835
+ * Hence: authoring-time error.
836
+ *
837
+ * The near-miss spellings this catches are not hypothetical. Each is a correct
838
+ * spelling *somewhere else* in the platform, which is precisely why authors
839
+ * reach for them:
840
+ *
841
+ * - `{current_user}` — `current_user.id` is the RLS expression root
842
+ * - `{user_id}` — `{user_id}` is valid `titleFormat` field interpolation
843
+ * - `{current_organization_id}` — `organization_id` is the real column name
844
+ *
845
+ * `CONTEXT_TOKEN_SUGGESTIONS` maps each to what the author meant, so the
846
+ * diagnostic names the fix instead of only reporting the symptom.
847
+ *
848
+ * ## Scope — filter subtrees only
849
+ *
850
+ * The walk descends into `filter` / `filters` / `runtimeFilter` subtrees and
851
+ * classifies string values inside them. It deliberately does NOT check
852
+ * navigation `recordId` / `params`, which resolve an additional vocabulary —
853
+ * `AppContextSelector` ids such as `{active_package}` — that is meaningless in
854
+ * a filter because filters are not evaluated with the sidebar's selector
855
+ * state. Restricting the walk keeps that legitimate usage out of the rule and
856
+ * holds false positives at zero.
857
+ *
858
+ * Only whole-string placeholders are considered (`'{token}'` / `'${token}'`,
859
+ * anchored). A value that merely contains braces is left alone.
860
+ */
861
+ declare const FILTER_TOKEN_UNKNOWN = "filter-token-unknown";
862
+ type FilterTokenSeverity = 'error' | 'warning';
863
+ interface FilterTokenFinding {
864
+ /** Always `error` today — an unresolved placeholder silently matches nothing. */
865
+ severity: FilterTokenSeverity;
866
+ /** Diagnostic rule id. */
867
+ rule: string;
868
+ /** Human-readable location, e.g. `dashboard "sales" · widget "my_deals"`. */
869
+ where: string;
870
+ /** Config path, e.g. `dashboards[0].widgets[2].filter.owner_id`. */
871
+ path: string;
872
+ /** What is wrong. */
873
+ message: string;
874
+ /** How to fix it. */
875
+ hint: string;
876
+ }
877
+ /**
878
+ * Validate filter placeholders across a schema-parsed stack.
879
+ *
880
+ * Pure `(stack) => Finding[]`; no I/O. Covers dashboards (widget + global
881
+ * filters), objects (list views), top-level view containers, reports,
882
+ * datasets, and pages.
883
+ */
884
+ declare function validateFilterTokens(stack: Record<string, unknown> | undefined | null): FilterTokenFinding[];
885
+
886
+ declare const OBJECT_REFERENCE_UNKNOWN = "object-reference-unknown";
887
+ declare const OBJECT_REFERENCE_UNREGISTERED_PLATFORM = "object-reference-unregistered-platform";
888
+ type ObjectRefSeverity = 'error' | 'warning';
889
+ interface ObjectRefFinding {
890
+ /** `error` for an unresolvable own-stack name; `warning` for an unknown platform name. */
891
+ severity: ObjectRefSeverity;
892
+ /** Diagnostic rule id. */
893
+ rule: string;
894
+ /** Human-readable location, e.g. `action "mass_update" · param "owner"`. */
895
+ where: string;
896
+ /** Config path, e.g. `actions[2].params[0].reference`. */
897
+ path: string;
898
+ /** What is wrong. */
899
+ message: string;
900
+ /** How to fix it. */
901
+ hint: string;
902
+ }
903
+ type AnyRec$8 = Record<string, unknown>;
904
+ /**
905
+ * Validate every object-name reference on the surfaces listed in the module
906
+ * header. Returns findings (empty = clean).
907
+ */
908
+ declare function validateObjectReferences(stack: AnyRec$8): ObjectRefFinding[];
909
+
910
+ declare const ACTION_NAME_UNDEFINED = "action-name-undefined";
911
+ type ActionNameRefSeverity = 'error' | 'warning';
912
+ interface ActionNameRefFinding {
913
+ /** Always `error` — a name-bound action that resolves nowhere is a dead button. */
914
+ severity: ActionNameRefSeverity;
915
+ /** Diagnostic rule id. */
916
+ rule: string;
917
+ /** Human-readable location, e.g. `view "crm_lead" · list "all" · bulkActions`. */
918
+ where: string;
919
+ /** Config path, e.g. `views[0].list.bulkActions[1]`. */
920
+ path: string;
921
+ /** What is wrong. */
922
+ message: string;
923
+ /** How to fix it. */
924
+ hint: string;
925
+ }
926
+ type AnyRec$7 = Record<string, unknown>;
927
+ /**
928
+ * Validate every name-bound action reference in a stack. Returns findings
929
+ * (empty = clean).
930
+ */
931
+ declare function validateActionNameRefs(stack: AnyRec$7): ActionNameRefFinding[];
932
+
933
+ /**
934
+ * Shared page-component traversal for the lint rules that inspect
935
+ * `PageComponent.properties` (issue #3583).
936
+ *
937
+ * Getting this walk right is subtle enough that duplicating it has already
938
+ * produced one dead rule, so it lives here once:
939
+ *
940
+ * - Components hang off `page.regions[].components[]` and `page.slots.<slot>`
941
+ * — there is NO top-level `page.components`. A walker that reads
942
+ * `page.components` silently visits nothing on a schema-parsed stack.
943
+ * - `slots.<slot>` is `PageComponent | PageComponent[]` — a single component
944
+ * is legal and must be normalized.
945
+ * - `PageComponentSchema` is `.strict()`, so a component carries no `children`
946
+ * key of its own. Sub-trees live INSIDE the untyped `properties` bag:
947
+ * `page:tabs` → `properties.items[].children`, `page:accordion` →
948
+ * `properties.items[].children`, `page:card` → `properties.body` /
949
+ * `properties.footer`. All are `z.array(z.unknown())`, so the recursion is
950
+ * untyped and has to be done by hand.
951
+ * - `kind: 'html' | 'react' | 'jsx'` pages are authored as `source`, which is
952
+ * authoritative; their `regions` hold at most a DERIVED cache that the
953
+ * source wins over. Linting that cache reports findings about metadata the
954
+ * author never wrote, so those pages are skipped here and covered by
955
+ * `validate-jsx-pages` / `validate-react-page-props` instead.
956
+ */
957
+ type AnyRec$6 = Record<string, unknown>;
958
+
959
+ /**
960
+ * [ADR-0078 — completeness] Field-reference integrity for page components
961
+ * (issue #3583, assessment R3).
962
+ *
963
+ * `PageComponent.properties` is `z.record(z.string(), z.unknown())` — an
964
+ * untyped bag. The typed prop schemas exist (`ComponentPropsMap` in
965
+ * `@objectstack/spec/ui`) but nothing validates `properties` against them, so
966
+ * every field name a component references ships exactly as typed. The HotCRM
967
+ * audit found KPI cards and page headers bound to fields the object does not
968
+ * have; each renders blank or falls back, and nothing reports the miss.
969
+ *
970
+ * Field-existence lint already exists for forms (`FORM_FIELD_UNKNOWN`),
971
+ * semantic roles, and flow templates. This is the same check for pages, at the
972
+ * same advisory severity: every consumer degrades gracefully (a missing field
973
+ * is skipped, not crashed on), so a warning is the honest level.
974
+ *
975
+ * ── Which object a component binds ──────────────────────────────────────
976
+ *
977
+ * `dataSource.object` → `properties.object` → the page's `object`. A per-element
978
+ * `dataSource` exists precisely so one page can bind several objects, and the
979
+ * `element:*` family declares its own `object`; both must win over the page's.
980
+ *
981
+ * ── Why a hand-written descriptor table ─────────────────────────────────
982
+ *
983
+ * `ComponentPropsMap` cannot drive this rule: a Zod schema does not say which
984
+ * of its `z.string()` props is a FIELD NAME (`RecordPathProps.statusField` and
985
+ * `AIChatWindowProps.agentId` are both plain strings), and the type universe is
986
+ * open anyway — `PageComponent.type` is `z.union([PageComponentType,
987
+ * z.string()])`, so unregistered types like `record:line_items` parse and are
988
+ * authored in the wild. The table below names the field-bearing props
989
+ * explicitly; an unknown component type is SKIPPED silently, never flagged.
990
+ *
991
+ * The table also covers shapes the props schemas do not yet describe but real
992
+ * pages authored anyway (they pass only because `properties` is unvalidated):
993
+ * `record:details` `sections[].fields[]` and `hideFields[]`, and the record
994
+ * picker's `labelField`. Linting the schema's shape alone would find nothing on
995
+ * the actual corpus.
996
+ */
997
+ declare const PAGE_FIELD_UNKNOWN = "page-field-unknown";
998
+ type PageFieldSeverity = 'error' | 'warning';
999
+ interface PageFieldFinding {
1000
+ /** Always `warning` — page renderers skip an unknown field rather than fail. */
1001
+ severity: PageFieldSeverity;
1002
+ /** Diagnostic rule id. */
1003
+ rule: string;
1004
+ /** Human-readable location, e.g. `page "task_detail" · record:highlights`. */
1005
+ where: string;
1006
+ /** Config path, e.g. `pages[0].regions[1].components[0].properties.fields[2]`. */
1007
+ path: string;
1008
+ /** What is wrong. */
1009
+ message: string;
1010
+ /** How to fix it. */
1011
+ hint: string;
1012
+ }
1013
+
1014
+ declare function validatePageFieldBindings(stack: AnyRec$6): PageFieldFinding[];
1015
+
1016
+ /**
1017
+ * [ADR-0021 — semantic layer] Chart-binding integrity for the surfaces the
1018
+ * dashboard rule does not reach (issue #3583, assessment R4).
1019
+ *
1020
+ * `validate-widget-bindings` already resolves a dashboard widget's
1021
+ * `chartConfig` axes against its dataset's declared dimensions and measures
1022
+ * (`chart-field-unknown`). It is scoped to `stack.dashboards`, so three other
1023
+ * chart surfaces ship unchecked — and the HotCRM audit found exactly the bug
1024
+ * that scoping allows: an axis naming a RAW FIELD instead of a dataset measure.
1025
+ * Post-ADR-0021 the result rows are keyed by measure NAME (`sum_amount`), not
1026
+ * the base column (`amount`), so the axis renders and the series is empty.
1027
+ *
1028
+ * Surfaces covered here:
1029
+ *
1030
+ * 1. **Report charts** — `report.chart` and `report.blocks[].chart`.
1031
+ * `ReportChartSchema` narrows `xAxis`/`yAxis` from ChartConfig's
1032
+ * object/array shapes to bare STRINGS, which is why simply pointing the
1033
+ * dashboard rule at reports would find nothing: its `Array.isArray(yAxis)`
1034
+ * guard skips a string silently. `series[].name` keeps the array shape.
1035
+ * 2. **List-view charts** — `ListChartConfigSchema` (`dataset` +
1036
+ * `dimensions` + `values`), reachable through `views[].list`,
1037
+ * `views[].listViews.<key>`, and `objects[].listViews.<key>`.
1038
+ * 3. **Dataset-bound page chart components** — a `PageComponent` whose
1039
+ * `properties` carry a `dataset` (the `object-chart` component). Same
1040
+ * binding shape as a list chart, but it arrives through the untyped
1041
+ * `properties` bag.
1042
+ *
1043
+ * Not covered HERE, and deliberately so: the react `<ObjectChart>` block. It is
1044
+ * OBJECT-bound (`objectName` + an inline `aggregate`), so its result rows are
1045
+ * keyed by the RAW FIELD NAMES rather than by a measure name — the opposite
1046
+ * convention, which would make `chart-measure-unknown`'s message a lie. It also
1047
+ * arrives as JSX rather than config, so it needs the TypeScript compiler this
1048
+ * rule has no business loading. It is checked by `validate-react-page-props`
1049
+ * instead, against the naming convention `chartAggregateResultKeys`
1050
+ * (`@objectstack/spec/ui`) now pins down (#3701).
1051
+ */
1052
+ declare const CHART_DIMENSION_UNKNOWN = "chart-dimension-unknown";
1053
+ declare const CHART_MEASURE_UNKNOWN = "chart-measure-unknown";
1054
+ declare const CHART_DATASET_UNKNOWN = "chart-dataset-unknown";
1055
+ declare const CHART_AXIS_NOT_SELECTED = "chart-axis-not-selected";
1056
+ type ChartBindingSeverity = 'error' | 'warning';
1057
+ interface ChartBindingFinding {
1058
+ severity: ChartBindingSeverity;
1059
+ /** Diagnostic rule id. */
1060
+ rule: string;
1061
+ /** Human-readable location, e.g. `report "hours_by_status" · chart`. */
1062
+ where: string;
1063
+ /** Config path, e.g. `reports[2].chart.yAxis`. */
1064
+ path: string;
1065
+ /** What is wrong. */
1066
+ message: string;
1067
+ /** How to fix it. */
1068
+ hint: string;
1069
+ }
1070
+
1071
+ declare function validateChartBindings(stack: AnyRec$6): ChartBindingFinding[];
1072
+
1073
+ declare const NAV_OBJECT_UNGRANTED = "nav-object-ungranted";
1074
+ type NavAccessSeverity = 'error' | 'warning';
1075
+ interface NavAccessFinding {
1076
+ /** Always `warning` — a grant may come from a package this stack cannot see. */
1077
+ severity: NavAccessSeverity;
1078
+ /** Diagnostic rule id. */
1079
+ rule: string;
1080
+ /** Human-readable location, e.g. `app "crm" · nav "nav_forecast"`. */
1081
+ where: string;
1082
+ /** Config path, e.g. `apps[0].navigation[3].objectName`. */
1083
+ path: string;
1084
+ /** What is wrong. */
1085
+ message: string;
1086
+ /** How to fix it. */
1087
+ hint: string;
1088
+ }
1089
+ type AnyRec$5 = Record<string, unknown>;
1090
+ /**
1091
+ * Validate that every object a stack's navigation exposes is readable by at
1092
+ * least one permission set the stack declares. Returns findings (empty = clean).
1093
+ */
1094
+ declare function validateNavAccess(stack: AnyRec$5): NavAccessFinding[];
1095
+
1096
+ declare const TRANSLATION_TARGET_UNKNOWN = "translation-target-unknown";
1097
+ declare const TRANSLATION_OPTION_KEY_UNKNOWN = "translation-option-key-unknown";
1098
+ type TranslationRefSeverity = 'warning';
1099
+ interface TranslationRefFinding {
1100
+ /** Always `warning` — an orphan translation key is inert, not broken. */
1101
+ severity: TranslationRefSeverity;
1102
+ /** Diagnostic rule id. */
1103
+ rule: string;
1104
+ /** Human-readable location, e.g. `locale "zh-CN" · object "crm_lead"`. */
1105
+ where: string;
1106
+ /** Config path, e.g. `translations[0]["zh-CN"].objects.crm_lead.fields.campaign`. */
1107
+ path: string;
1108
+ /** What is wrong. */
1109
+ message: string;
1110
+ /** How to fix it. */
1111
+ hint: string;
1112
+ }
1113
+ type AnyRec$4 = Record<string, unknown>;
1114
+ /**
1115
+ * Validate every reference a translation bundle makes against the metadata it
1116
+ * claims to translate. Returns findings (empty = clean).
1117
+ */
1118
+ declare function validateTranslationReferences(stack: AnyRec$4): TranslationRefFinding[];
1119
+
1120
+ /**
1121
+ * [ADR-0064 §3] Skill ↔ agent surface affinity (issue #3820).
1122
+ *
1123
+ * An agent binds a product surface (`'ask'` | `'build'`, ADR-0063 §1) and a
1124
+ * skill declares which surface it belongs to (`'ask'` | `'build'` | `'both'`,
1125
+ * ADR-0063 §3). A skill may only attach to an agent whose surface it matches —
1126
+ * `'both'` attaches to either. The runtime treats a violation as a FAST LOAD
1127
+ * ERROR: `resolveActiveSkills()` throws on the first incompatible binding, so
1128
+ * an agent shipping one mismatched skill reference fails at **chat time** with
1129
+ * a 500 — after parse, after validate, after deploy.
1130
+ *
1131
+ * Both sides of the check are declared in the same stack, so the contradiction
1132
+ * is statically provable and this rule carries severity **error** with zero
1133
+ * false positives by construction. Both sides default to `'ask'` when the
1134
+ * `surface` field is absent (mirroring the runtime's defaults), so the rule is
1135
+ * safe on the raw/normalized config the `lint` path carries as well as the
1136
+ * schema-parsed stack.
1137
+ *
1138
+ * Scope note: this rule deliberately does NOT check that `agent.skills[]`
1139
+ * names resolve at all. Kernel skills (`schema_reader`, the `ask`/`build`
1140
+ * bundles) are runtime-registered and statically invisible, and whether
1141
+ * app-stack tool/skill namespaces get a platform-name registry is an open
1142
+ * decision (#3820 D0/D2) — resolving names against `stack.skills` alone would
1143
+ * flag every kernel-skill reference. An unresolved name is therefore skipped
1144
+ * here; only a reference that resolves in-stack AND contradicts the affinity
1145
+ * contract is reported.
1146
+ */
1147
+ declare const AI_SKILL_SURFACE_MISMATCH = "ai-skill-surface-mismatch";
1148
+ type AiSurfaceAffinitySeverity = 'error' | 'warning';
1149
+ interface AiSurfaceAffinityFinding {
1150
+ /** Always `error` — the runtime throws on this binding at chat time. */
1151
+ severity: AiSurfaceAffinitySeverity;
1152
+ /** Diagnostic rule id. */
1153
+ rule: string;
1154
+ /** Human-readable location, e.g. `agent "sales_copilot" · skills`. */
1155
+ where: string;
1156
+ /** Config path, e.g. `agents[0].skills[2]`. */
1157
+ path: string;
1158
+ /** What is wrong. */
1159
+ message: string;
1160
+ /** How to fix it. */
1161
+ hint: string;
1162
+ }
1163
+ type AnyRec$3 = Record<string, unknown>;
1164
+ /**
1165
+ * Validate every in-stack agent→skill binding against the ADR-0064 §3 surface
1166
+ * affinity contract. Returns findings (empty = clean).
1167
+ */
1168
+ declare function validateAiSurfaceAffinity(stack: AnyRec$3): AiSurfaceAffinityFinding[];
1169
+
1170
+ declare const AI_SKILL_TOOL_UNRESOLVED = "ai-skill-tool-unresolved";
1171
+ type AiToolRefSeverity = 'error' | 'warning';
1172
+ interface AiToolRefFinding {
1173
+ /** Always `warning` — see the header for why this rule starts advisory. */
1174
+ severity: AiToolRefSeverity;
1175
+ /** Diagnostic rule id. */
1176
+ rule: string;
1177
+ /** Human-readable location, e.g. `skill "revenue_forecasting" · tools`. */
1178
+ where: string;
1179
+ /** Config path, e.g. `skills[3].tools[1]`. */
1180
+ path: string;
1181
+ /** What is wrong. */
1182
+ message: string;
1183
+ /** How to fix it. */
1184
+ hint: string;
1185
+ }
1186
+ type AnyRec$2 = Record<string, unknown>;
1187
+ /**
1188
+ * Validate every `skill.tools[]` reference in a stack. Returns findings
1189
+ * (empty = clean).
1190
+ */
1191
+ declare function validateAiToolReferences(stack: AnyRec$2): AiToolRefFinding[];
1192
+
1193
+ /**
1194
+ * [ADR-0063 §2] `stack.agents` is a platform-internal slot (issue #3820).
1195
+ *
1196
+ * ADR-0063 §2 withdrew tenant/app-package custom agents: the kernel ships
1197
+ * exactly two agents (`ask`, `build`), the surface the user is in binds one,
1198
+ * and third parties extend the platform by authoring **skills**, never
1199
+ * `*.agent.ts`. The `agent` metadata type carries the decision
1200
+ * (`allowRuntimeCreate: false, allowOrgOverride: false`), and the runtime
1201
+ * enforces it on both paths — `listAgents()` filters non-platform records out
1202
+ * of the catalog, and `loadAgent()` refuses them outright (cloud#904), so a
1203
+ * stack-authored agent 404s on chat and cannot be pinned via
1204
+ * `app.defaultAgent`.
1205
+ *
1206
+ * What was missing is the AUTHORING-time signal. `defineStack` still accepts
1207
+ * an `agents` array, so an app package could declare agents that parse,
1208
+ * validate, and build into the artifact — and then do nothing at runtime.
1209
+ * HotCRM shipped two of them for months. That is the ADR-0078 shape this rule
1210
+ * closes: loud at the producer, tolerant at the consumer (Prime Directive
1211
+ * #12).
1212
+ *
1213
+ * Severity is **warning**, not error, for one reason: the platform's own
1214
+ * packages legitimately author agent records, and this rule cannot tell a
1215
+ * platform package from an app package by reading the stack alone. A warning
1216
+ * that names the runtime consequence is honest for both readers; the runtime
1217
+ * is what actually gates. Deliberately NOT a Zod refine — an existing stack
1218
+ * must keep parsing (ADR-0078 non-goal #1).
1219
+ */
1220
+ declare const AGENT_AUTHORING_WITHDRAWN = "agent-authoring-withdrawn";
1221
+ type AiAgentAuthoringSeverity = 'error' | 'warning';
1222
+ interface AiAgentAuthoringFinding {
1223
+ /** Always `warning` — the runtime is the gate; this is the authoring-time signal. */
1224
+ severity: AiAgentAuthoringSeverity;
1225
+ /** Diagnostic rule id. */
1226
+ rule: string;
1227
+ /** Human-readable location, e.g. `agent "sales_copilot"`. */
1228
+ where: string;
1229
+ /** Config path, e.g. `agents[0]`. */
1230
+ path: string;
1231
+ /** What is wrong. */
1232
+ message: string;
1233
+ /** How to fix it. */
1234
+ hint: string;
1235
+ }
1236
+ type AnyRec$1 = Record<string, unknown>;
1237
+ /**
1238
+ * Flag every agent declared in a stack. Returns findings (empty = clean,
1239
+ * which is what every app package should be).
1240
+ */
1241
+ declare function validateAiAgentAuthoring(stack: AnyRec$1): AiAgentAuthoringFinding[];
1242
+
1243
+ type ReferenceIntegritySeverity = 'error' | 'warning';
1244
+ /**
1245
+ * The shape every rule in the suite already returns. Declared here so callers
1246
+ * can hold one type instead of a six-way union.
1247
+ */
1248
+ interface ReferenceIntegrityFinding {
1249
+ /** `error` = the reference is dead; `warning` = it may resolve elsewhere, or the miss is inert. */
1250
+ severity: ReferenceIntegritySeverity;
1251
+ /** Diagnostic rule id (stable; used by allowlists and docs). */
1252
+ rule: string;
1253
+ /** Human-readable location. */
1254
+ where: string;
1255
+ /** Config path. */
1256
+ path: string;
1257
+ /** What is wrong. */
1258
+ message: string;
1259
+ /** How to fix it. */
1260
+ hint: string;
1261
+ }
1262
+ /** One member of the suite. `name` is the exported function's name — the id a wiring test can assert on. */
1263
+ interface ReferenceIntegrityRule {
1264
+ name: string;
1265
+ run: (stack: Record<string, unknown>) => ReferenceIntegrityFinding[];
1266
+ }
1267
+ /**
1268
+ * Every reference-integrity rule, in the order their findings are reported.
1269
+ *
1270
+ * ADDING A RULE: append it here and it runs on `validate`, `lint` and
1271
+ * `compile` at once. Do not re-wire the commands.
1272
+ */
1273
+ declare const REFERENCE_INTEGRITY_RULES: readonly ReferenceIntegrityRule[];
1274
+ /**
1275
+ * Run every reference-integrity rule over a stack. Returns the concatenated
1276
+ * findings (empty = clean). Pure: no I/O, safe on both the schema-parsed stack
1277
+ * and the raw/normalized config the `lint` path carries.
1278
+ */
1279
+ declare function validateReferenceIntegrity(stack: Record<string, unknown>): ReferenceIntegrityFinding[];
649
1280
 
650
1281
  /**
651
1282
  * [ADR-0090 D6] Access-matrix snapshot — authoring-time companion to the
@@ -671,4 +1302,4 @@ declare function buildAccessMatrix(stack: AnyRec): AccessMatrix;
671
1302
  */
672
1303
  declare function diffAccessMatrix(before: AccessMatrix, after: AccessMatrix): string[];
673
1304
 
674
- export { APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER, APPROVAL_APPROVER_TYPE_DEPRECATED, APPROVAL_APPROVER_TYPE_UNKNOWN, APPROVAL_ESCALATION_REASSIGN_NO_TARGET, type ApprovalApproverFinding, type ApprovalApproverSeverity, CAPABILITY_REFERENCE_UNKNOWN, CHART_CONFIG_MISSING, CHART_FIELD_UNKNOWN, type CapabilityRefFinding, type CapabilityRefSeverity, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_UNKNOWN, type DashboardActionRefFinding, type DashboardActionRefSeverity, type ExprIssue, FIELD_GROUP_EMPTY, FIELD_GROUP_UNDECLARED, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_TRIGGER_UNKNOWN_OBJECT, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FormLayoutFinding, type FormLayoutSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, type ListViewModeFinding, type ListViewModeSeverity, MEASURE_AGGREGATE_INCOHERENT, PAGE_SOURCE_CLASSNAME, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type RecordTitleFinding, type RecordTitleSeverity, 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, SEMANTIC_ROLE_FIELD_UNKNOWN, STYLE_CLASSNAME_TAILWIND, STYLE_NODE_MISSING_ID, STYLE_RESPONSIVE_NO_BASE, STYLE_UNKNOWN_CSS_PROPERTY, STYLE_UNKNOWN_TOKEN, type SecurityFinding, type SecuritySeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type SourceStyleFinding, type SourceStyleSeverity, type StyleFinding, type StyleSeverity, TABLE_COUNT_ONLY, TITLE_FORMAT_RETIRED, TITLE_UNRESOLVABLE, VIEW_CONTAINER_SHAPE, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_MEASURE_UNKNOWN, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, validateApprovalApprovers, validateCapabilityReferences, validateDashboardActionRefs, validateFlowTriggerReadiness, validateFormLayout, validateJsxPages, validateListViewMode, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateRecordTitle, validateResponsiveStyles, validateSecurityPosture, validateSemanticRoles, validateStackExpressions, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings };
1305
+ export { ACTION_NAME_UNDEFINED, 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, type ActionNameRefFinding, type ActionNameRefSeverity, type AiAgentAuthoringFinding, type AiAgentAuthoringSeverity, type AiSurfaceAffinityFinding, type AiSurfaceAffinitySeverity, type AiToolRefFinding, type AiToolRefSeverity, type ApprovalApproverFinding, type ApprovalApproverSeverity, 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, FIELD_GROUP_EMPTY, FIELD_GROUP_UNDECLARED, FILTER_TOKEN_UNKNOWN, FLOW_DRAFT_STATUS_AMBIGUOUS, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, type FilterTokenFinding, type FilterTokenSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FormLayoutFinding, type FormLayoutSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FILTERS_IN_VIEWS_MODE, type ListViewModeFinding, type ListViewModeSeverity, MEASURE_AGGREGATE_INCOHERENT, NAV_OBJECT_UNGRANTED, type NavAccessFinding, type NavAccessSeverity, 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_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, 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 SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, 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, VIEW_CONTAINER_SHAPE, VISIBILITY_ALIAS_DEPRECATED, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_MEASURE_UNKNOWN, type WidgetBindingFinding, type WidgetBindingSeverity, buildAccessMatrix, diffAccessMatrix, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateDashboardActionRefs, validateFilterTokens, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateJsxPages, validateListViewMode, validateNavAccess, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validateReactPageProps, validateReactPages, validateReadonlyFlowWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateSecurityPosture, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateStackExpressions, validateTranslationReferences, validateViewContainers, validateVisibilityPredicates, validateWidgetBindings };