@objectstack/lint 17.3.0 → 17.4.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/CHANGELOG.md +779 -1
- package/dist/index.cjs +2279 -1368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +778 -439
- package/dist/index.d.ts +778 -439
- package/dist/index.js +2212 -1311
- package/dist/index.js.map +1 -1
- package/dist/{runtime-B8F5-Cbg.d.cts → runtime-S3OZQDZV.d.cts} +13 -2
- package/dist/{runtime-B8F5-Cbg.d.ts → runtime-S3OZQDZV.d.ts} +13 -2
- package/dist/runtime.cjs +2388 -1538
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +2345 -1489
- package/dist/runtime.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Manifest } from '@objectstack/sdui-parser';
|
|
|
3
3
|
import { SearchFieldMeta } from '@objectstack/spec/data';
|
|
4
4
|
import { Options } from 'ajv';
|
|
5
5
|
import { AccessMatrixParsed } from '@objectstack/spec/security';
|
|
6
|
-
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 RuntimePackageScope, m as RuntimeStackContext, n as authoringRulesFor, o as buildRuntimeWriteSnapshots, p as narrowObjectsToPackageClosure, r as runAuthoringRules, q as runRuntimeAuthoringRules, s as runtimeAuthoringRulesFor, t as runtimeGatedTypes, u as splitBySeverity, v as stackKeyForType } from './runtime-
|
|
6
|
+
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 RuntimePackageScope, m as RuntimeStackContext, n as authoringRulesFor, o as buildRuntimeWriteSnapshots, p as narrowObjectsToPackageClosure, r as runAuthoringRules, q as runRuntimeAuthoringRules, s as runtimeAuthoringRulesFor, t as runtimeGatedTypes, u as splitBySeverity, v as stackKeyForType } from './runtime-S3OZQDZV.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Build-time dashboard widget binding diagnostics (issues #1719, #1721).
|
|
@@ -23,13 +23,6 @@ export { A as AUTHORING_COMMANDS, a as AUTHORING_RULES, b as AUTHORING_SURFACES,
|
|
|
23
23
|
* name on the bound dataset.
|
|
24
24
|
* - `widget-measure-unknown` — a `values[]` entry is not a measure name on
|
|
25
25
|
* the bound dataset.
|
|
26
|
-
* - `chart-field-unknown` — a `chartConfig` binding names a field the query
|
|
27
|
-
* result will not contain: `xAxis.field` must be one of the widget's
|
|
28
|
-
* dimensions (or a dataset dimension), and each `yAxis[].field` /
|
|
29
|
-
* `series[].name` must be one of the widget's selected measures
|
|
30
|
-
* (`values`). Post-cutover (ADR-0021) the result rows are keyed by
|
|
31
|
-
* measure NAME (e.g. `sum_amount`), not the base column (`amount`) — a
|
|
32
|
-
* stale base-column reference renders the axis but an empty series.
|
|
33
26
|
* - `widget-legacy-analytics-unrenderable` (#1878/#1894) — a widget uses the
|
|
34
27
|
* removed pre-ADR-0021 inline-analytics shape (`categoryField`/`rowField`/…)
|
|
35
28
|
* as its ONLY data wiring: no `dataset`, no `object`, no inline `data`. The
|
|
@@ -63,8 +56,45 @@ export { A as AUTHORING_COMMANDS, a as AUTHORING_RULES, b as AUTHORING_SURFACES,
|
|
|
63
56
|
*
|
|
64
57
|
* Advisory rules — severity `warning`, build stays green:
|
|
65
58
|
*
|
|
66
|
-
* - `chart-
|
|
67
|
-
*
|
|
59
|
+
* - `chart-field-unknown` (#1721; tier ruled on #15463) — a `chartConfig`
|
|
60
|
+
* BINDING key names something the widget's selection does not carry:
|
|
61
|
+
* `xAxis.field` is not one of the widget's dimensions (or a dataset
|
|
62
|
+
* dimension), or a `yAxis[].field` / `series[].name` is not one of its
|
|
63
|
+
* selected measures (`values`). Post-cutover (ADR-0021) the result rows are
|
|
64
|
+
* keyed by measure NAME (e.g. `sum_amount`), not the base column (`amount`),
|
|
65
|
+
* so a stale base-column reference is the usual way to write one. The pinned
|
|
66
|
+
* renderer REFUSES all three keys as bindings — see "The three refused
|
|
67
|
+
* binding keys" below — so the authored key changes nothing that renders: it
|
|
68
|
+
* is a silent no-op, exactly `widget-legacy-analytics-shape`'s class. Kept as
|
|
69
|
+
* a finding because the author wrote a binding and believes it is in force.
|
|
70
|
+
* - `chart-config-missing` — a `combo` widget has no `chartConfig`, so no
|
|
71
|
+
* series carries a mark and the combination chart draws as one uniform
|
|
72
|
+
* family. Narrowed to `combo` because `chartConfig` carries NO binding:
|
|
73
|
+
* `DatasetWidget` derives the axis and one series per measure from the
|
|
74
|
+
* widget's own `dimensions` / `values`, and actively REFUSES an authored
|
|
75
|
+
* `ChartAxis.field` / `ChartSeries.name`. See "What the renderer actually
|
|
76
|
+
* derives" below for the pinned contract this now mirrors.
|
|
77
|
+
* - `chart-measures-missing` — a chart-family widget selects NO measures
|
|
78
|
+
* (`values` empty or absent). The pinned renderer short-circuits to an
|
|
79
|
+
* authoring placeholder — *"Pick measures (values) for this dataset
|
|
80
|
+
* widget."* — before any query runs, so no chart is drawn at all. Warning
|
|
81
|
+
* rather than error because an empty selection is a legitimate
|
|
82
|
+
* work-in-progress state a build must tolerate; erroring would gate the
|
|
83
|
+
* `sys_metadata` publish path on a half-authored widget.
|
|
84
|
+
* - `widget-measures-missing` (#15508) — a NON-chart dataset widget — a
|
|
85
|
+
* single-value family (`metric`/`kpi`/`gauge`/`solid-gauge`/`bullet`) or a
|
|
86
|
+
* tabular one (`table`/`pivot`) — selects NO measures. The placeholder above
|
|
87
|
+
* is returned for these families too: the pinned `values.length === 0` return
|
|
88
|
+
* stands above every family branch, so the KPI number or the table is not
|
|
89
|
+
* drawn either. Same warning tier and suppression as the chart-family
|
|
90
|
+
* spelling; a separate id because "chart" does not name this condition and
|
|
91
|
+
* because the family keeps one id per class.
|
|
92
|
+
* - `chart-dimensions-missing` — a chart-family widget selects at least one
|
|
93
|
+
* measure but NO dimensions. The pinned renderer's
|
|
94
|
+
* `isMetric = METRIC_TYPES.has(widgetType) || dimensions.length === 0`
|
|
95
|
+
* routes it to the single-value branch, so it renders a KPI number and the
|
|
96
|
+
* family the author declared is silently ignored. Warning because the
|
|
97
|
+
* number is real and correct — it is the chart that is gone.
|
|
68
98
|
* - `table-count-only` (#1719) — a `table`/`pivot` widget whose selected
|
|
69
99
|
* measures are ALL `aggregate: 'count'` and which declares no
|
|
70
100
|
* `dimensions` asks the analytics service for a single summary row. That
|
|
@@ -177,6 +207,176 @@ export { A as AUTHORING_COMMANDS, a as AUTHORING_RULES, b as AUTHORING_SURFACES,
|
|
|
177
207
|
* through the flat `SYSTEM_FIELDS` union, which is what lets a reference to
|
|
178
208
|
* `owner_id` on an `ownership: 'none'` object stay a real finding.
|
|
179
209
|
*
|
|
210
|
+
* ### What the renderer actually derives (#14436)
|
|
211
|
+
*
|
|
212
|
+
* `chart-config-missing` used to fire on EVERY chart family that was not a
|
|
213
|
+
* single-value or tabular type, on the stated grounds that without
|
|
214
|
+
* `chartConfig` "the renderer cannot determine which measure to plot, so the
|
|
215
|
+
* series renders empty". That consequence was false, and it fired on this
|
|
216
|
+
* platform's OWN shipped metadata: the `system_overview` dashboard draws a pie
|
|
217
|
+
* and a bar, each with one dimension and one measure and no `chartConfig`, and
|
|
218
|
+
* both render correctly. A warning-tier rule that mis-fires on first-party
|
|
219
|
+
* metadata is the ADR-0072 D1 cost the whole family exists to avoid — it
|
|
220
|
+
* teaches every reader, human and agent, that this family is noise.
|
|
221
|
+
*
|
|
222
|
+
* The renderer's contract, read at the `@object-ui` revision this repo PINS
|
|
223
|
+
* (`.objectui-sha`), not at objectui's `origin/main` — the Console ships the
|
|
224
|
+
* pin, so the exemption is written against the behaviour the pin has:
|
|
225
|
+
*
|
|
226
|
+
* - `DatasetWidget` calls `buildChartSeries(rows, dimensions, values, …)`,
|
|
227
|
+
* which returns `{ data, xAxisKey, series }` — the x-axis key is
|
|
228
|
+
* `dimensions[0]` and there is exactly one series per entry of `values`.
|
|
229
|
+
* `chartConfig` is not an argument to it.
|
|
230
|
+
* - The authored `chartConfig` reaches the chart only through
|
|
231
|
+
* `mergeAuthoredPresentation` (per-series/axis PRESENTATION merged ONTO
|
|
232
|
+
* those derived bindings) and `chartConfigPresentation` (chrome: titles,
|
|
233
|
+
* height, colours, data labels, annotations, legend).
|
|
234
|
+
* - The BINDING half of an authored `chartConfig` is refused outright. The
|
|
235
|
+
* renderer pins this by name in
|
|
236
|
+
* `packages/plugin-dashboard/src/__tests__/DatasetWidget.chartConfig.test.tsx`:
|
|
237
|
+
* *"ignores an authored axis `field` and keeps the derived axis binding"*,
|
|
238
|
+
* *"ignores an authored series and keeps one derived series per measure"*,
|
|
239
|
+
* *"ignores `chartConfig.type` — the widget type owns the chart family"*,
|
|
240
|
+
* and *"emits none of the presentation keys when no chartConfig is
|
|
241
|
+
* declared"*.
|
|
242
|
+
*
|
|
243
|
+
* So for every chart family except one, a missing `chartConfig` costs the
|
|
244
|
+
* widget nothing at all, and ADDING one could not have repaired a widget whose
|
|
245
|
+
* selection is empty either — `chart-field-unknown` above reports a
|
|
246
|
+
* `yAxis[].field` that names anything the widget did not select, so
|
|
247
|
+
* `chartConfig` can never supply a measure the `values` array is missing.
|
|
248
|
+
*
|
|
249
|
+
* **The one surviving arm is `combo`**, and it is a real loss rather than an
|
|
250
|
+
* inferred one. A combination chart's whole identity is a per-series MARK, and
|
|
251
|
+
* that mark is authored as `chartConfig.series[].type` — presentation, so it
|
|
252
|
+
* does merge forward. `mergeAuthoredSeries` states the default it falls back
|
|
253
|
+
* to: *"a derived series with no authored entry keeps the family default"*,
|
|
254
|
+
* and `DatasetWidget.comboPresentation.test.tsx` records what that cost when
|
|
255
|
+
* the merge was missing — *"Without it the line measure drew as the second
|
|
256
|
+
* bar."* A `combo` with no `chartConfig` therefore draws every measure with
|
|
257
|
+
* one mark: the author asked for a combination and got a plain one. Warning
|
|
258
|
+
* rather than error, because the numbers are right and the chart renders — it
|
|
259
|
+
* is the shape that is wrong.
|
|
260
|
+
*
|
|
261
|
+
* ⚠️ Two genuinely un-renderable shapes are NOT this id's, because neither is
|
|
262
|
+
* caused by nor repairable with `chartConfig` and folding them in would leave
|
|
263
|
+
* this id misnaming its own condition: a chart-family widget selecting NO
|
|
264
|
+
* measures, and one selecting NO dimensions. They have their own ids —
|
|
265
|
+
* `chart-measures-missing` and `chart-dimensions-missing` — described next.
|
|
266
|
+
*
|
|
267
|
+
* ### The two empty-selection shapes (#15462)
|
|
268
|
+
*
|
|
269
|
+
* Read at the same PINNED `@object-ui` revision (`.objectui-sha`), in
|
|
270
|
+
* `packages/plugin-dashboard/src/DatasetWidget.tsx`:
|
|
271
|
+
*
|
|
272
|
+
* - `:683` — `if (values.length === 0)` returns the authoring placeholder
|
|
273
|
+
* `tt('dashboard.pickMeasures', 'Pick measures (values) for this dataset
|
|
274
|
+
* widget.')`. It stands ABOVE every family branch, so a widget selecting no
|
|
275
|
+
* measure never reaches a chart, a table or a KPI number: nothing is drawn.
|
|
276
|
+
* - `:423` — `const isMetric = METRIC_TYPES.has(widgetType) ||
|
|
277
|
+
* dimensions.length === 0;`, with `METRIC_TYPES` (`:343`) = `metric`, `kpi`,
|
|
278
|
+
* `gauge`, `solid-gauge`, `bullet`; `:424` is the tabular test
|
|
279
|
+
* (`table`/`pivot`); and the render branches (`:702`, `:798`, `:854`) route
|
|
280
|
+
* `isMetric ? KPI : isTable ? table : chart`. A dimensionless `bar` is
|
|
281
|
+
* therefore drawn as a single KPI number — the failure direction the family's
|
|
282
|
+
* own docblock names, except worse: the number is REAL, so the missing chart
|
|
283
|
+
* reads as a design choice rather than as a defect.
|
|
284
|
+
*
|
|
285
|
+
* So "chart family" here is not a hand list — it is what that routing leaves
|
|
286
|
+
* over: a declared `ChartTypeSchema` option that is neither a `METRIC_TYPES`
|
|
287
|
+
* member nor tabular ({@link CHART_FAMILY_WIDGET_TYPES}). The taxonomy supplies
|
|
288
|
+
* the universe and the renderer decides the exceptions, which is the same
|
|
289
|
+
* division #14436 settled for `MARK_MIXING_CHART_TYPES`: this file's copies of
|
|
290
|
+
* the renderer's two sets are held to `ChartTypeSchema` by the rule's tests, so
|
|
291
|
+
* a member that stops being a declared chart type reds instead of going quiet.
|
|
292
|
+
*
|
|
293
|
+
* The two ids never both fire on one widget, and the reason is the pin's own
|
|
294
|
+
* order: with no measures the placeholder returns at `:683` and the `isMetric`
|
|
295
|
+
* branch is never reached, so `chart-dimensions-missing`'s consequence (a KPI
|
|
296
|
+
* number in place of the chart) is not what that widget does. A widget missing
|
|
297
|
+
* both reports `chart-measures-missing` alone, whose hint names the missing
|
|
298
|
+
* dimension too.
|
|
299
|
+
*
|
|
300
|
+
* Both are warnings, per the tier decision on #15462: an empty selection is a
|
|
301
|
+
* state an author passes THROUGH, and the family's errors are reserved for
|
|
302
|
+
* bindings the analytics service cannot satisfy.
|
|
303
|
+
*
|
|
304
|
+
* **The measures shape is every family's, not the chart family's (#15508).**
|
|
305
|
+
* Re-read at the pinned `.objectui-sha` (`a472b0716`, where the four cited
|
|
306
|
+
* lines still read as quoted above), `:683` is ABOVE `:423`/`:424` and tests
|
|
307
|
+
* nothing but `values.length === 0`. So a `metric`, `kpi`, `gauge`,
|
|
308
|
+
* `solid-gauge`, `bullet`, `table` or `pivot` widget that selects no measures
|
|
309
|
+
* renders that same placeholder: the KPI number or the table the author
|
|
310
|
+
* declared is not drawn either, and a missing tile on a board reads as
|
|
311
|
+
* "nothing to report" rather than as a defect. Nothing else reported it —
|
|
312
|
+
* `table-count-only` requires `values.length > 0` before it looks, and rules
|
|
313
|
+
* (b)/(c) iterate the arrays, so an empty one is silent by construction.
|
|
314
|
+
*
|
|
315
|
+
* The population therefore widens to every DECLARED widget type
|
|
316
|
+
* ({@link NON_CHART_DATASET_WIDGET_TYPES} is the taxonomy minus the chart
|
|
317
|
+
* family), carried by TWO ids rather than one:
|
|
318
|
+
* {@link CHART_MEASURES_MISSING} keeps the chart family, and
|
|
319
|
+
* {@link WIDGET_MEASURES_MISSING} takes the rest. Two, because "chart" stops
|
|
320
|
+
* naming the condition once the population is every family — a `metric` tile
|
|
321
|
+
* is not a chart — while the old id is depended on from OUTSIDE this file (the
|
|
322
|
+
* `packages/lint` barrel re-exports it, which
|
|
323
|
+
* `rule-id-barrel-exports.test.ts` makes a public-surface contract, and a
|
|
324
|
+
* board may already carry `suppressWarnings: ['chart-measures-missing']`).
|
|
325
|
+
* Renaming would have retired a reachable id and falsified those references;
|
|
326
|
+
* splitting keeps every one of them true and lets each message state the
|
|
327
|
+
* consequence its family actually has (no chart drawn / no KPI number drawn /
|
|
328
|
+
* no table rendered), which one id could only do by branching anyway.
|
|
329
|
+
*
|
|
330
|
+
* The DIMENSIONS shape stays chart-family only, and deliberately: a
|
|
331
|
+
* dimensionless `metric` or `table` is what those families are FOR (the
|
|
332
|
+
* shipped `system_overview` KPI tiles are exactly that shape), and a
|
|
333
|
+
* dimensionless `table` already has its own id in `table-count-only`.
|
|
334
|
+
*
|
|
335
|
+
* ### The three refused binding keys (#15463)
|
|
336
|
+
*
|
|
337
|
+
* `chart-field-unknown` shipped at `error` with a message that named a QUERY
|
|
338
|
+
* failure — *"the query result will not contain it"*. Read at the same PINNED
|
|
339
|
+
* `@object-ui` revision (`.objectui-sha`), that consequence never happens,
|
|
340
|
+
* because the renderer never reads these keys as bindings at all. The rule id
|
|
341
|
+
* covers exactly three positions, and all three are refused:
|
|
342
|
+
*
|
|
343
|
+
* - `chartConfig.xAxis.field` — `axisPresentation`
|
|
344
|
+
* (`@object-ui/core` `src/utils/chart-presentation.ts`) builds the axis's
|
|
345
|
+
* presentation MINUS its `field`, and that dropping is structural, not a
|
|
346
|
+
* guard: the x-axis key is `buildChartSeries`' `xAxisKey`, i.e. the widget's
|
|
347
|
+
* `dimensions[0]`. An authored `field` re-points nothing.
|
|
348
|
+
* - `chartConfig.yAxis[].field` — the same `axisPresentation` call, per entry.
|
|
349
|
+
* The entry keeps its SLOT (the count is what turns on a secondary axis) and
|
|
350
|
+
* its scale/chrome; only the binding is dropped.
|
|
351
|
+
* - `chartConfig.series[].name` — `mergeAuthoredSeries` pairs an authored
|
|
352
|
+
* entry with the derived binding whose `dataKey` it EQUALS, one series per
|
|
353
|
+
* entry of `values`. A name matching no derived series is *"**ignored** —
|
|
354
|
+
* membership belongs to the dataset, so an author cannot add, remove or
|
|
355
|
+
* re-point a series from the chart config"*. So the presentation the author
|
|
356
|
+
* hung on that entry — the mark, the colour, the stack, the axis side —
|
|
357
|
+
* lands on nothing.
|
|
358
|
+
*
|
|
359
|
+
* The renderer pins all three by name in
|
|
360
|
+
* `packages/plugin-dashboard/src/__tests__/DatasetWidget.chartConfig.test.tsx`
|
|
361
|
+
* (*"ignores an authored axis `field` and keeps the derived axis binding"*,
|
|
362
|
+
* *"ignores an authored series and keeps one derived series per measure"*).
|
|
363
|
+
*
|
|
364
|
+
* So the failure is not a broken page, it is an ignored key — which is the
|
|
365
|
+
* class `widget-legacy-analytics-shape` above reports at WARNING tier in this
|
|
366
|
+
* same file (*"the dashboard renderer ignores them … a silent no-op"*). All
|
|
367
|
+
* three positions therefore drop from `error` to `warning`, suppressible per
|
|
368
|
+
* widget, and each message states what actually happens instead of a query that
|
|
369
|
+
* never runs. The finding is KEPT rather than deleted: unlike #14436's
|
|
370
|
+
* over-reach the metadata really is wrong — the author wrote a binding and
|
|
371
|
+
* believes it is in force.
|
|
372
|
+
*
|
|
373
|
+
* The tier drop is a behaviour change on the `sys_metadata` publish door: the
|
|
374
|
+
* 2026-08-15 ruling put all SIX of this rule's error ids on that door as one
|
|
375
|
+
* "this board cannot render" class, and this id leaves that set, so a publish
|
|
376
|
+
* carrying only a refused `chartConfig` binding key now SUCCEEDS with the
|
|
377
|
+
* finding on the advisory channel. The remaining five are unchanged; the
|
|
378
|
+
* accept-set is re-pinned in `runtime-gate.test.ts`.
|
|
379
|
+
*
|
|
180
380
|
* Warnings can be deliberately suppressed per widget via
|
|
181
381
|
* `suppressWarnings: ['<rule-id>']`; errors cannot — they describe a
|
|
182
382
|
* binding the analytics service cannot satisfy.
|
|
@@ -186,6 +386,27 @@ declare const WIDGET_DIMENSION_UNKNOWN = "widget-dimension-unknown";
|
|
|
186
386
|
declare const WIDGET_MEASURE_UNKNOWN = "widget-measure-unknown";
|
|
187
387
|
declare const CHART_FIELD_UNKNOWN = "chart-field-unknown";
|
|
188
388
|
declare const CHART_CONFIG_MISSING = "chart-config-missing";
|
|
389
|
+
/**
|
|
390
|
+
* [#15462] A chart-family widget selects no measures, so the pinned renderer
|
|
391
|
+
* draws the "Pick measures (values)" placeholder instead of a chart.
|
|
392
|
+
*/
|
|
393
|
+
declare const CHART_MEASURES_MISSING = "chart-measures-missing";
|
|
394
|
+
/**
|
|
395
|
+
* [#15462] A chart-family widget selects no dimensions, so the pinned
|
|
396
|
+
* renderer's `isMetric` branch draws a KPI number instead of the declared
|
|
397
|
+
* chart family.
|
|
398
|
+
*/
|
|
399
|
+
declare const CHART_DIMENSIONS_MISSING = "chart-dimensions-missing";
|
|
400
|
+
/**
|
|
401
|
+
* [#15508] A NON-chart dataset widget — a `METRIC_WIDGET_TYPES` or a
|
|
402
|
+
* `TABULAR_WIDGET_TYPES` one — selects no measures, so the pinned renderer
|
|
403
|
+
* draws the same "Pick measures (values)" placeholder in place of the KPI
|
|
404
|
+
* number or the table. The chart-family spelling of the same shape keeps its
|
|
405
|
+
* own id ({@link CHART_MEASURES_MISSING}); see "The two empty-selection
|
|
406
|
+
* shapes" in the module docblock for why the population is split across two
|
|
407
|
+
* ids rather than carried by one.
|
|
408
|
+
*/
|
|
409
|
+
declare const WIDGET_MEASURES_MISSING = "widget-measures-missing";
|
|
189
410
|
declare const TABLE_COUNT_ONLY = "table-count-only";
|
|
190
411
|
declare const MEASURE_AGGREGATE_INCOHERENT = "measure-aggregate-incoherent";
|
|
191
412
|
declare const WIDGET_LEGACY_ANALYTICS_SHAPE = "widget-legacy-analytics-shape";
|
|
@@ -218,7 +439,7 @@ interface WidgetBindingFinding {
|
|
|
218
439
|
/** How to fix (or deliberately suppress) it. */
|
|
219
440
|
hint: string;
|
|
220
441
|
}
|
|
221
|
-
type AnyRec$
|
|
442
|
+
type AnyRec$N = Record<string, unknown>;
|
|
222
443
|
/**
|
|
223
444
|
* Validate every dashboard widget's dataset binding. Returns the list of
|
|
224
445
|
* findings (empty = clean). Caller decides how to surface them: `error`
|
|
@@ -226,7 +447,7 @@ type AnyRec$L = Record<string, unknown>;
|
|
|
226
447
|
* should fail validate/build; `warning` findings are advisory and must
|
|
227
448
|
* never fail the build on their own.
|
|
228
449
|
*/
|
|
229
|
-
declare function validateWidgetBindings(stack: AnyRec$
|
|
450
|
+
declare function validateWidgetBindings(stack: AnyRec$N): WidgetBindingFinding[];
|
|
230
451
|
|
|
231
452
|
interface ExprIssue {
|
|
232
453
|
where: string;
|
|
@@ -239,7 +460,7 @@ interface ExprIssue {
|
|
|
239
460
|
*/
|
|
240
461
|
severity?: 'error' | 'warning';
|
|
241
462
|
}
|
|
242
|
-
type AnyRec$
|
|
463
|
+
type AnyRec$M = Record<string, unknown>;
|
|
243
464
|
/**
|
|
244
465
|
* A FIELD-level conditional rule (`visibleWhen` / `readonlyWhen` /
|
|
245
466
|
* `requiredWhen`) that reaches for a namespace root the field level does not
|
|
@@ -525,7 +746,7 @@ declare function fieldRuleRootIssue(slot: string, source: string): {
|
|
|
525
746
|
* Validate every predicate in the stack. Returns the list of issues (empty =
|
|
526
747
|
* clean). Caller decides how to surface / whether to fail the build.
|
|
527
748
|
*/
|
|
528
|
-
declare function validateStackExpressions(stack: AnyRec$
|
|
749
|
+
declare function validateStackExpressions(stack: AnyRec$M): ExprIssue[];
|
|
529
750
|
|
|
530
751
|
/**
|
|
531
752
|
* The corrective sentence, lifted **verbatim** from `unevaluableRuleError` in
|
|
@@ -718,7 +939,7 @@ interface ListViewModeFinding {
|
|
|
718
939
|
hint: string;
|
|
719
940
|
}
|
|
720
941
|
declare const LIST_VIEW_FILTERS_IN_VIEWS_MODE = "list-view-filters-in-views-mode";
|
|
721
|
-
type AnyRec$
|
|
942
|
+
type AnyRec$L = Record<string, unknown>;
|
|
722
943
|
/**
|
|
723
944
|
* Flag ADR-0047 "views" mode violations on an object's built-in named views or a
|
|
724
945
|
* `defineView` default `list` / named `listViews`: `quickFilters`, or a `tabs`
|
|
@@ -728,7 +949,7 @@ type AnyRec$J = Record<string, unknown>;
|
|
|
728
949
|
*
|
|
729
950
|
* Feed the PRE-parse stack (normalizeStackInput output) — see file header.
|
|
730
951
|
*/
|
|
731
|
-
declare function validateListViewMode(stack: AnyRec$
|
|
952
|
+
declare function validateListViewMode(stack: AnyRec$L): ListViewModeFinding[];
|
|
732
953
|
|
|
733
954
|
type FunctionalCompletenessSeverity = 'error' | 'warning';
|
|
734
955
|
interface FunctionalCompletenessFinding {
|
|
@@ -843,7 +1064,7 @@ declare const FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE = "flow-time-relative-des
|
|
|
843
1064
|
* call sites that each skip it.
|
|
844
1065
|
*/
|
|
845
1066
|
declare const FLOW_TRIGGER_UNROUTABLE = "flow-trigger-unroutable";
|
|
846
|
-
type AnyRec$
|
|
1067
|
+
type AnyRec$K = Record<string, unknown>;
|
|
847
1068
|
/**
|
|
848
1069
|
* Validate auto-launched flow trigger wiring against the stack definition.
|
|
849
1070
|
*
|
|
@@ -852,7 +1073,7 @@ type AnyRec$I = Record<string, unknown>;
|
|
|
852
1073
|
* owns the `timeRelative` descriptor's contract, which is the point: the rule
|
|
853
1074
|
* ASKS that schema rather than restating it.
|
|
854
1075
|
*/
|
|
855
|
-
declare function validateFlowTriggerReadiness(stack: AnyRec$
|
|
1076
|
+
declare function validateFlowTriggerReadiness(stack: AnyRec$K): FlowTriggerReadinessFinding[];
|
|
856
1077
|
|
|
857
1078
|
type FlowTemplatePathSeverity = 'error' | 'warning';
|
|
858
1079
|
interface FlowTemplatePathFinding {
|
|
@@ -868,12 +1089,12 @@ interface FlowTemplatePathFinding {
|
|
|
868
1089
|
declare const FLOW_TEMPLATE_UNKNOWN_FIELD = "flow-template-unknown-field";
|
|
869
1090
|
declare const FLOW_TEMPLATE_LOOKUP_TRAVERSAL = "flow-template-lookup-traversal";
|
|
870
1091
|
declare const FLOW_TEMPLATE_FIELD_UNPROVISIONED = "flow-template-field-unprovisioned";
|
|
871
|
-
type AnyRec$
|
|
1092
|
+
type AnyRec$J = Record<string, unknown>;
|
|
872
1093
|
/**
|
|
873
1094
|
* Validate `{record.<path>}` template references across every record-change
|
|
874
1095
|
* flow. Pure and dependency-free; safe on pre- or post-parse stacks.
|
|
875
1096
|
*/
|
|
876
|
-
declare function validateFlowTemplatePaths(stack: AnyRec$
|
|
1097
|
+
declare function validateFlowTemplatePaths(stack: AnyRec$J): FlowTemplatePathFinding[];
|
|
877
1098
|
|
|
878
1099
|
type ReadonlyFlowWriteSeverity = 'error' | 'warning';
|
|
879
1100
|
interface ReadonlyFlowWriteFinding {
|
|
@@ -888,12 +1109,13 @@ interface ReadonlyFlowWriteFinding {
|
|
|
888
1109
|
}
|
|
889
1110
|
declare const FLOW_UPDATE_READONLY_FIELD = "flow-update-readonly-field";
|
|
890
1111
|
declare const FLOW_UPDATE_READONLY_WHEN_FIELD = "flow-update-readonly-when-field";
|
|
891
|
-
type AnyRec$
|
|
1112
|
+
type AnyRec$I = Record<string, unknown>;
|
|
892
1113
|
/**
|
|
893
|
-
* Validate flow `update_record` writes against target-object
|
|
894
|
-
* declarations. Pure and dependency-free; safe on pre- or post-parse
|
|
1114
|
+
* Validate flow `update_record` / `create_record` writes against target-object
|
|
1115
|
+
* readonly declarations. Pure and dependency-free; safe on pre- or post-parse
|
|
1116
|
+
* stacks.
|
|
895
1117
|
*/
|
|
896
|
-
declare function validateReadonlyFlowWrites(stack: AnyRec$
|
|
1118
|
+
declare function validateReadonlyFlowWrites(stack: AnyRec$I): ReadonlyFlowWriteFinding[];
|
|
897
1119
|
|
|
898
1120
|
/** What a caller needs to tell an author WHICH source went unread, and where. */
|
|
899
1121
|
interface SourceParseFailure {
|
|
@@ -1021,7 +1243,7 @@ interface BodyWritePatternExclusion {
|
|
|
1021
1243
|
declare const HOOK_BODY_WRITE_PATTERN_IDS: readonly string[];
|
|
1022
1244
|
/** Ledger shapes this rule leaves alone, each with its reason. */
|
|
1023
1245
|
declare const HOOK_BODY_WRITE_EXCLUSIONS: readonly BodyWritePatternExclusion[];
|
|
1024
|
-
type AnyRec$
|
|
1246
|
+
type AnyRec$H = Record<string, unknown>;
|
|
1025
1247
|
/** One statically-extracted field write found in an L2 body. */
|
|
1026
1248
|
interface ExtractedHookBodyWrite {
|
|
1027
1249
|
/** Which {@link HOOK_BODY_WRITE_PATTERNS} entry matched. */
|
|
@@ -1090,8 +1312,45 @@ declare function extractHookBodyWriteSet(source: string): ExtractedHookBodyWrite
|
|
|
1090
1312
|
/**
|
|
1091
1313
|
* Validate L2 hook-body writes against target-object field declarations.
|
|
1092
1314
|
* Pure `(stack) => Finding[]` (ADR-0019); safe on pre- or post-parse stacks.
|
|
1093
|
-
|
|
1094
|
-
|
|
1315
|
+
*
|
|
1316
|
+
* ## Which intakes reach a hook authored as an inline `handler` (#16095)
|
|
1317
|
+
*
|
|
1318
|
+
* This rule opens on `body.language === 'js'`. A hook written as
|
|
1319
|
+
* `handler: async (ctx) => { … }` carries no `body`, so whether it is judged
|
|
1320
|
+
* is a property of the DOOR — what each caller hands this function — not of
|
|
1321
|
+
* the rule. Measured (`packages/cli/test/lint-hook-rules-reach-handler-hooks*`):
|
|
1322
|
+
*
|
|
1323
|
+
* Every leg below was measured with the body-authored control beside it, so a
|
|
1324
|
+
* silent leg is a reading about that door and never about this rule. The doors
|
|
1325
|
+
* are the call sites of `runAuthoringRules`, enumerated — not the three `os *`
|
|
1326
|
+
* commands, which are fewer than the doors:
|
|
1327
|
+
*
|
|
1328
|
+
* `os build` union `compile.ts` lowers every inline handler to a
|
|
1329
|
+
* metadata body BEFORE its parse (`lowerCallables`)
|
|
1330
|
+
* and judges the parsed result — REACHED, always was.
|
|
1331
|
+
* `os build` per-package same lowered `result.data`, re-entered one package
|
|
1332
|
+
* manifest at a time — REACHED, always was.
|
|
1333
|
+
* `os lint` hands the registry's `parsed` tier that same
|
|
1334
|
+
* lowered view — REACHED since #16095.
|
|
1335
|
+
* scaffold validate `runScaffoldAuthoringRules` (`os init` / `dev` over
|
|
1336
|
+
* a rendered template) lowers before it parses too —
|
|
1337
|
+
* REACHED, always was, and pinned since #16095.
|
|
1338
|
+
* `os validate` lowers before it parses since #16544 — the same
|
|
1339
|
+
* `lowerCallables` call, between its pre-parse
|
|
1340
|
+
* unknown-key lints and its parse — REACHED since
|
|
1341
|
+
* #16544. Measured NOT reached under #16095, when it
|
|
1342
|
+
* parsed the normalized stack without lowering while
|
|
1343
|
+
* the body-authored control fired; closing it was
|
|
1344
|
+
* its own accept/reject decision, taken on #16544.
|
|
1345
|
+
* direct call judges exactly the stack it is given — NOT reached
|
|
1346
|
+
* unless the caller lowers first; measured both ways.
|
|
1347
|
+
*
|
|
1348
|
+
* A handler the extractor refuses (forbidden token, free identifier,
|
|
1349
|
+
* unparseable) is left with no `body` on every door, so this rule stays silent
|
|
1350
|
+
* on it; the refusal itself is reported by `os lint`'s `hook-body/*` rules and
|
|
1351
|
+
* by `os build`'s warn-and-bundle line, never guessed at here.
|
|
1352
|
+
*/
|
|
1353
|
+
declare function validateHookBodyWrites(stack: AnyRec$H): HookBodyWriteFinding[];
|
|
1095
1354
|
|
|
1096
1355
|
type ReadonlyHookWriteSeverity = 'error' | 'warning';
|
|
1097
1356
|
interface ReadonlyHookWriteFinding {
|
|
@@ -1117,13 +1376,50 @@ declare const HOOK_API_UPDATE_READONLY_WHEN_FIELD = "hook-api-update-readonly-wh
|
|
|
1117
1376
|
declare const READONLY_HOOK_WRITE_PATTERN_IDS: readonly string[];
|
|
1118
1377
|
/** Ledger shapes this rule leaves alone, each with its reason. */
|
|
1119
1378
|
declare const READONLY_HOOK_WRITE_EXCLUSIONS: readonly BodyWritePatternExclusion[];
|
|
1120
|
-
type AnyRec$
|
|
1379
|
+
type AnyRec$G = Record<string, unknown>;
|
|
1121
1380
|
/**
|
|
1122
1381
|
* Validate L2 hook-body `ctx.api` writes against target-object readonly
|
|
1123
1382
|
* declarations. Pure `(stack) => Finding[]` (ADR-0019); safe on pre- or
|
|
1124
1383
|
* post-parse stacks.
|
|
1125
|
-
|
|
1126
|
-
|
|
1384
|
+
*
|
|
1385
|
+
* ## Which intakes reach a hook authored as an inline `handler` (#16095)
|
|
1386
|
+
*
|
|
1387
|
+
* This rule opens on `body.language === 'js'`. A hook written as
|
|
1388
|
+
* `handler: async (ctx) => { … }` carries no `body`, so whether it is judged
|
|
1389
|
+
* is a property of the DOOR — what each caller hands this function — not of
|
|
1390
|
+
* the rule. Measured (`packages/cli/test/lint-hook-rules-reach-handler-hooks*`):
|
|
1391
|
+
*
|
|
1392
|
+
* Every leg below was measured with the body-authored control beside it, so a
|
|
1393
|
+
* silent leg is a reading about that door and never about this rule. The doors
|
|
1394
|
+
* are the call sites of `runAuthoringRules`, enumerated — not the three `os *`
|
|
1395
|
+
* commands, which are fewer than the doors:
|
|
1396
|
+
*
|
|
1397
|
+
* `os build` union `compile.ts` lowers every inline handler to a
|
|
1398
|
+
* metadata body BEFORE its parse (`lowerCallables`)
|
|
1399
|
+
* and judges the parsed result — REACHED, always was.
|
|
1400
|
+
* `os build` per-package same lowered `result.data`, re-entered one package
|
|
1401
|
+
* manifest at a time — REACHED, always was.
|
|
1402
|
+
* `os lint` hands the registry's `parsed` tier that same
|
|
1403
|
+
* lowered view — REACHED since #16095.
|
|
1404
|
+
* scaffold validate `runScaffoldAuthoringRules` (`os init` / `dev` over
|
|
1405
|
+
* a rendered template) lowers before it parses too —
|
|
1406
|
+
* REACHED, always was, and pinned since #16095.
|
|
1407
|
+
* `os validate` lowers before it parses since #16544 — the same
|
|
1408
|
+
* `lowerCallables` call, between its pre-parse
|
|
1409
|
+
* unknown-key lints and its parse — REACHED since
|
|
1410
|
+
* #16544. Measured NOT reached under #16095, when it
|
|
1411
|
+
* parsed the normalized stack without lowering while
|
|
1412
|
+
* the body-authored control fired; closing it was
|
|
1413
|
+
* its own accept/reject decision, taken on #16544.
|
|
1414
|
+
* direct call judges exactly the stack it is given — NOT reached
|
|
1415
|
+
* unless the caller lowers first; measured both ways.
|
|
1416
|
+
*
|
|
1417
|
+
* A handler the extractor refuses (forbidden token, free identifier,
|
|
1418
|
+
* unparseable) is left with no `body` on every door, so this rule stays silent
|
|
1419
|
+
* on it; the refusal itself is reported by `os lint`'s `hook-body/*` rules and
|
|
1420
|
+
* by `os build`'s warn-and-bundle line, never guessed at here.
|
|
1421
|
+
*/
|
|
1422
|
+
declare function validateReadonlyHookWrites(stack: AnyRec$G): ReadonlyHookWriteFinding[];
|
|
1127
1423
|
|
|
1128
1424
|
type ReadonlyActionWriteSeverity = 'warning';
|
|
1129
1425
|
interface ReadonlyActionWriteFinding {
|
|
@@ -1150,13 +1446,13 @@ declare const ACTION_API_UPDATE_READONLY_WHEN_FIELD = "action-api-update-readonl
|
|
|
1150
1446
|
declare const READONLY_ACTION_WRITE_PATTERN_IDS: readonly string[];
|
|
1151
1447
|
/** Ledger shapes this rule leaves alone, each with its reason. */
|
|
1152
1448
|
declare const READONLY_ACTION_WRITE_EXCLUSIONS: readonly BodyWritePatternExclusion[];
|
|
1153
|
-
type AnyRec$
|
|
1449
|
+
type AnyRec$F = Record<string, unknown>;
|
|
1154
1450
|
/**
|
|
1155
1451
|
* Validate L2 action-body `ctx.api` writes against target-object `readonlyWhen`
|
|
1156
1452
|
* declarations. Pure `(stack) => Finding[]` (ADR-0019); safe on pre- or
|
|
1157
1453
|
* post-parse stacks.
|
|
1158
1454
|
*/
|
|
1159
|
-
declare function validateReadonlyActionWrites(stack: AnyRec$
|
|
1455
|
+
declare function validateReadonlyActionWrites(stack: AnyRec$F): ReadonlyActionWriteFinding[];
|
|
1160
1456
|
|
|
1161
1457
|
type ViewContainerSeverity = 'error' | 'warning';
|
|
1162
1458
|
interface ViewContainerFinding {
|
|
@@ -1193,14 +1489,14 @@ declare const STYLE_CLASSNAME_TAILWIND = "style-classname-tailwind";
|
|
|
1193
1489
|
declare const STYLE_RESPONSIVE_NO_BASE = "style-responsive-no-base";
|
|
1194
1490
|
declare const STYLE_UNKNOWN_CSS_PROPERTY = "style-unknown-css-property";
|
|
1195
1491
|
declare const STYLE_UNKNOWN_TOKEN = "style-unknown-token";
|
|
1196
|
-
type AnyRec$
|
|
1492
|
+
type AnyRec$E = Record<string, unknown>;
|
|
1197
1493
|
/**
|
|
1198
1494
|
* Validate every page's component tree for SDUI styling correctness (ADR-0065).
|
|
1199
1495
|
* Returns findings (empty = clean). `error` findings describe styles that are
|
|
1200
1496
|
* silently dropped and should fail validate/build; `warning` findings are
|
|
1201
1497
|
* advisory (typos, drift, footguns).
|
|
1202
1498
|
*/
|
|
1203
|
-
declare function validateResponsiveStyles(stack: AnyRec$
|
|
1499
|
+
declare function validateResponsiveStyles(stack: AnyRec$E): StyleFinding[];
|
|
1204
1500
|
|
|
1205
1501
|
type JsxPageSeverity = 'error' | 'warning';
|
|
1206
1502
|
interface JsxPageFinding {
|
|
@@ -1213,8 +1509,8 @@ interface JsxPageFinding {
|
|
|
1213
1509
|
message: string;
|
|
1214
1510
|
hint: string;
|
|
1215
1511
|
}
|
|
1216
|
-
type AnyRec$
|
|
1217
|
-
declare function validateJsxPages(stack: AnyRec$
|
|
1512
|
+
type AnyRec$D = Record<string, unknown>;
|
|
1513
|
+
declare function validateJsxPages(stack: AnyRec$D, opts?: {
|
|
1218
1514
|
manifest?: Manifest;
|
|
1219
1515
|
}): JsxPageFinding[];
|
|
1220
1516
|
|
|
@@ -1227,8 +1523,8 @@ interface ReactPageFinding {
|
|
|
1227
1523
|
message: string;
|
|
1228
1524
|
hint: string;
|
|
1229
1525
|
}
|
|
1230
|
-
type AnyRec$
|
|
1231
|
-
declare function validateReactPages(stack: AnyRec$
|
|
1526
|
+
type AnyRec$C = Record<string, unknown>;
|
|
1527
|
+
declare function validateReactPages(stack: AnyRec$C): ReactPageFinding[];
|
|
1232
1528
|
|
|
1233
1529
|
type ReactPropSeverity = 'error' | 'warning';
|
|
1234
1530
|
interface ReactPropFinding {
|
|
@@ -1239,7 +1535,7 @@ interface ReactPropFinding {
|
|
|
1239
1535
|
message: string;
|
|
1240
1536
|
hint: string;
|
|
1241
1537
|
}
|
|
1242
|
-
type AnyRec$
|
|
1538
|
+
type AnyRec$B = Record<string, unknown>;
|
|
1243
1539
|
/**
|
|
1244
1540
|
* The source could not be parsed, so the prop checks below read a partially
|
|
1245
1541
|
* recovered tree (#10653).
|
|
@@ -1265,13 +1561,21 @@ declare const REACT_PAGE_SOURCE_UNPARSEABLE = "react-page-source-unparseable";
|
|
|
1265
1561
|
* "alias + loud deprecation", same shape as `approval-approver-type-deprecated`.
|
|
1266
1562
|
*/
|
|
1267
1563
|
declare const REACT_PROP_DEPRECATED = "react-prop-deprecated";
|
|
1564
|
+
/**
|
|
1565
|
+
* [#14791] A prop written in a react-tier spelling the contract has RETIRED
|
|
1566
|
+
* (maintainer ruling 2026-09-07: `<ListView objectName>` / `viewType` go with
|
|
1567
|
+
* no deprecation window). Error, never warning: the contract no longer
|
|
1568
|
+
* publishes the spelling, and the finding carries the prescription — the
|
|
1569
|
+
* react-tier twin of a metadata schema's `retiredKey()` tombstone.
|
|
1570
|
+
*/
|
|
1571
|
+
declare const REACT_PROP_RETIRED = "react-prop-retired";
|
|
1268
1572
|
declare const REACT_CHART_FIELD_UNKNOWN = "react-chart-field-unknown";
|
|
1269
1573
|
declare const REACT_CHART_FIELD_UNPROVISIONED = "react-chart-field-unprovisioned";
|
|
1270
1574
|
declare const REACT_CHART_AGGREGATE_INVALID = "react-chart-aggregate-invalid";
|
|
1271
1575
|
declare const REACT_CHART_AXIS_UNKNOWN = "react-chart-axis-unknown";
|
|
1272
1576
|
declare const REACT_CHART_DRILLDOWN_INVALID = "react-chart-drilldown-invalid";
|
|
1273
1577
|
declare const REACT_BLOCK_NEEDS_RECORD_CONTEXT = "react-block-needs-record-context";
|
|
1274
|
-
declare function validateReactPageProps(stack: AnyRec$
|
|
1578
|
+
declare function validateReactPageProps(stack: AnyRec$B): ReactPropFinding[];
|
|
1275
1579
|
|
|
1276
1580
|
type SourceStyleSeverity = 'error' | 'warning';
|
|
1277
1581
|
interface SourceStyleFinding {
|
|
@@ -1283,8 +1587,8 @@ interface SourceStyleFinding {
|
|
|
1283
1587
|
hint: string;
|
|
1284
1588
|
}
|
|
1285
1589
|
declare const PAGE_SOURCE_CLASSNAME = "page-source-className-tailwind";
|
|
1286
|
-
type AnyRec$
|
|
1287
|
-
declare function validatePageSourceStyling(stack: AnyRec$
|
|
1590
|
+
type AnyRec$A = Record<string, unknown>;
|
|
1591
|
+
declare function validatePageSourceStyling(stack: AnyRec$A): SourceStyleFinding[];
|
|
1288
1592
|
|
|
1289
1593
|
/**
|
|
1290
1594
|
* Build-time record-title diagnostics (ADR-0079).
|
|
@@ -1328,14 +1632,14 @@ interface RecordTitleFinding {
|
|
|
1328
1632
|
/** How to fix it. */
|
|
1329
1633
|
hint: string;
|
|
1330
1634
|
}
|
|
1331
|
-
type AnyRec$
|
|
1635
|
+
type AnyRec$z = Record<string, unknown>;
|
|
1332
1636
|
/**
|
|
1333
1637
|
* Validate every object's record-title declaration. Returns the list of
|
|
1334
1638
|
* findings (empty = clean). Both rules are advisory (`warning`): the caller
|
|
1335
1639
|
* must never fail the build on them alone — auto-provision + the `Record #<id>`
|
|
1336
1640
|
* floor guarantee a resolvable title at runtime.
|
|
1337
1641
|
*/
|
|
1338
|
-
declare function validateRecordTitle(stack: AnyRec$
|
|
1642
|
+
declare function validateRecordTitle(stack: AnyRec$z): RecordTitleFinding[];
|
|
1339
1643
|
|
|
1340
1644
|
declare const FIELD_GROUP_UNDECLARED = "field-group-undeclared";
|
|
1341
1645
|
declare const FIELD_GROUP_EMPTY = "field-group-empty";
|
|
@@ -1357,13 +1661,13 @@ interface SemanticRoleFinding {
|
|
|
1357
1661
|
/** How to fix it. */
|
|
1358
1662
|
hint: string;
|
|
1359
1663
|
}
|
|
1360
|
-
type AnyRec$
|
|
1664
|
+
type AnyRec$y = Record<string, unknown>;
|
|
1361
1665
|
/**
|
|
1362
1666
|
* Validate every object's semantic-role pointers. Returns the list of
|
|
1363
1667
|
* findings (empty = clean). Advisory only — the caller must never fail the
|
|
1364
1668
|
* build on these alone.
|
|
1365
1669
|
*/
|
|
1366
|
-
declare function validateSemanticRoles(stack: AnyRec$
|
|
1670
|
+
declare function validateSemanticRoles(stack: AnyRec$y): SemanticRoleFinding[];
|
|
1367
1671
|
|
|
1368
1672
|
declare const FORM_FIELD_UNKNOWN = "form-field-unknown";
|
|
1369
1673
|
declare const FORM_COLSPAN_ABSOLUTE = "absolute-colspan-discouraged";
|
|
@@ -1389,12 +1693,12 @@ interface FormLayoutFinding {
|
|
|
1389
1693
|
/** How to fix it. */
|
|
1390
1694
|
hint: string;
|
|
1391
1695
|
}
|
|
1392
|
-
type AnyRec$
|
|
1696
|
+
type AnyRec$x = Record<string, unknown>;
|
|
1393
1697
|
/**
|
|
1394
1698
|
* Validate authored form-view layout. Returns findings (empty = clean).
|
|
1395
1699
|
* Advisory only — the caller must never fail the build on these alone.
|
|
1396
1700
|
*/
|
|
1397
|
-
declare function validateFormLayout(stack: AnyRec$
|
|
1701
|
+
declare function validateFormLayout(stack: AnyRec$x): FormLayoutFinding[];
|
|
1398
1702
|
|
|
1399
1703
|
declare const VISIBILITY_ROOT_MISLAYERED = "visibility-root-mislayered";
|
|
1400
1704
|
declare const VISIBILITY_BARE_IDENTIFIER = "visibility-bare-identifier";
|
|
@@ -1459,7 +1763,7 @@ interface VisibilityFinding {
|
|
|
1459
1763
|
/** How to fix it. */
|
|
1460
1764
|
hint: string;
|
|
1461
1765
|
}
|
|
1462
|
-
type AnyRec$
|
|
1766
|
+
type AnyRec$w = Record<string, unknown>;
|
|
1463
1767
|
/**
|
|
1464
1768
|
* Validate conditional-visibility predicates across authored views and pages.
|
|
1465
1769
|
*
|
|
@@ -1488,7 +1792,7 @@ type AnyRec$u = Record<string, unknown>;
|
|
|
1488
1792
|
* check (#13594) is layer-agnostic in both halves: it prescribes a NAME, and the
|
|
1489
1793
|
* environment registers the same names on every layer.
|
|
1490
1794
|
*/
|
|
1491
|
-
declare function validateVisibilityPredicates(stack: AnyRec$
|
|
1795
|
+
declare function validateVisibilityPredicates(stack: AnyRec$w, opts?: VisibilityOptions): VisibilityFinding[];
|
|
1492
1796
|
|
|
1493
1797
|
declare const PREDICATE_PATH_UNRESOLVED = "predicate-path-unresolved";
|
|
1494
1798
|
declare const PREDICATE_PATH_UNROOTED = "predicate-path-unrooted";
|
|
@@ -1531,7 +1835,7 @@ interface PredicatePathOptions {
|
|
|
1531
1835
|
*/
|
|
1532
1836
|
resolveSchema?: (schemaId: string) => unknown;
|
|
1533
1837
|
}
|
|
1534
|
-
type AnyRec$
|
|
1838
|
+
type AnyRec$v = Record<string, unknown>;
|
|
1535
1839
|
/**
|
|
1536
1840
|
* Refuse a metadata-form predicate that names a path the target schema does not
|
|
1537
1841
|
* declare (#7010).
|
|
@@ -1560,7 +1864,7 @@ type AnyRec$t = Record<string, unknown>;
|
|
|
1560
1864
|
*
|
|
1561
1865
|
* Returns findings (empty = clean).
|
|
1562
1866
|
*/
|
|
1563
|
-
declare function validatePredicatePathRefs(stack: AnyRec$
|
|
1867
|
+
declare function validatePredicatePathRefs(stack: AnyRec$v, opts?: PredicatePathOptions): PredicatePathFinding[];
|
|
1564
1868
|
|
|
1565
1869
|
declare const CAPABILITY_REFERENCE_UNKNOWN = "capability-reference-unknown";
|
|
1566
1870
|
type CapabilityRefSeverity = 'error' | 'warning';
|
|
@@ -1578,12 +1882,12 @@ interface CapabilityRefFinding {
|
|
|
1578
1882
|
/** How to fix it. */
|
|
1579
1883
|
hint: string;
|
|
1580
1884
|
}
|
|
1581
|
-
type AnyRec$
|
|
1885
|
+
type AnyRec$u = Record<string, unknown>;
|
|
1582
1886
|
/**
|
|
1583
1887
|
* Validate every capability reference in a stack. Returns findings (empty =
|
|
1584
1888
|
* clean). Advisory only — callers must not fail the build on these alone.
|
|
1585
1889
|
*/
|
|
1586
|
-
declare function validateCapabilityReferences(stack: AnyRec$
|
|
1890
|
+
declare function validateCapabilityReferences(stack: AnyRec$u): CapabilityRefFinding[];
|
|
1587
1891
|
|
|
1588
1892
|
declare const APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER = "approval-approver-not-membership-tier";
|
|
1589
1893
|
declare const APPROVAL_APPROVER_TYPE_DEPRECATED = "approval-approver-type-deprecated";
|
|
@@ -1609,12 +1913,12 @@ interface ApprovalApproverFinding {
|
|
|
1609
1913
|
/** How to fix it. */
|
|
1610
1914
|
hint: string;
|
|
1611
1915
|
}
|
|
1612
|
-
type AnyRec$
|
|
1916
|
+
type AnyRec$t = Record<string, unknown>;
|
|
1613
1917
|
/**
|
|
1614
1918
|
* Validate the approvers of every Approval node in the stack's flows.
|
|
1615
1919
|
* Returns findings (empty = clean).
|
|
1616
1920
|
*/
|
|
1617
|
-
declare function validateApprovalApprovers(stack: AnyRec$
|
|
1921
|
+
declare function validateApprovalApprovers(stack: AnyRec$t): ApprovalApproverFinding[];
|
|
1618
1922
|
|
|
1619
1923
|
type SeedReplaySafetySeverity = 'error' | 'warning';
|
|
1620
1924
|
interface SeedReplaySafetyFinding {
|
|
@@ -1628,7 +1932,7 @@ interface SeedReplaySafetyFinding {
|
|
|
1628
1932
|
hint: string;
|
|
1629
1933
|
}
|
|
1630
1934
|
declare const SEED_INSERT_MODE_DUPLICATES_ON_REPLAY = "seed-insert-mode-duplicates-on-replay";
|
|
1631
|
-
type AnyRec$
|
|
1935
|
+
type AnyRec$s = Record<string, unknown>;
|
|
1632
1936
|
/**
|
|
1633
1937
|
* Flag every seed dataset declared with `mode: 'insert'` — the one non-idempotent
|
|
1634
1938
|
* mode, which duplicates its rows on every replay boot (framework#3434). Returns
|
|
@@ -1638,7 +1942,7 @@ type AnyRec$q = Record<string, unknown>;
|
|
|
1638
1942
|
* Reads `stack.data` (the `SeedSchema[]` fixtures). Safe on any shape — a stack
|
|
1639
1943
|
* with no `data` array yields no findings.
|
|
1640
1944
|
*/
|
|
1641
|
-
declare function validateSeedReplaySafety(stack: AnyRec$
|
|
1945
|
+
declare function validateSeedReplaySafety(stack: AnyRec$s): SeedReplaySafetyFinding[];
|
|
1642
1946
|
|
|
1643
1947
|
type SeedStateMachineSeverity = 'warning';
|
|
1644
1948
|
interface SeedStateMachineFinding {
|
|
@@ -1652,7 +1956,7 @@ interface SeedStateMachineFinding {
|
|
|
1652
1956
|
hint: string;
|
|
1653
1957
|
}
|
|
1654
1958
|
declare const SEED_VALUE_OUTSIDE_STATE_MACHINE = "seed-value-outside-state-machine";
|
|
1655
|
-
type AnyRec$
|
|
1959
|
+
type AnyRec$r = Record<string, unknown>;
|
|
1656
1960
|
/**
|
|
1657
1961
|
* Flag every seed record whose `state_machine`-governed field carries a value
|
|
1658
1962
|
* the machine does not declare (framework#3433 follow-up). Returns the findings
|
|
@@ -1665,7 +1969,7 @@ type AnyRec$p = Record<string, unknown>;
|
|
|
1665
1969
|
* unresolved `cel` Expression envelope, a number) is skipped: it cannot be
|
|
1666
1970
|
* statically compared to the declared-state set.
|
|
1667
1971
|
*/
|
|
1668
|
-
declare function validateSeedStateMachine(stack: AnyRec$
|
|
1972
|
+
declare function validateSeedStateMachine(stack: AnyRec$r): SeedStateMachineFinding[];
|
|
1669
1973
|
|
|
1670
1974
|
declare const SECURITY_OWD_UNSET = "security-owd-unset";
|
|
1671
1975
|
declare const SECURITY_OWD_ALIAS = "security-owd-alias";
|
|
@@ -1677,6 +1981,7 @@ declare const SECURITY_BOOK_AUDIENCE_UNKNOWN_SET = "security-book-audience-unkno
|
|
|
1677
1981
|
declare const SECURITY_PRIVATE_NO_READSCOPE = "security-private-no-readscope";
|
|
1678
1982
|
declare const SECURITY_MASTER_DETAIL_UNGRANTED = "security-master-detail-ungranted";
|
|
1679
1983
|
declare const SECURITY_FLS_UNQUALIFIED_KEY = "security-fls-unqualified-key";
|
|
1984
|
+
declare const SECURITY_FLS_UNKNOWN_FIELD = "security-fls-unknown-field";
|
|
1680
1985
|
declare const SECURITY_GRANT_EXPIRED_AT_AUTHORING = "security-grant-expired-at-authoring";
|
|
1681
1986
|
declare const SECURITY_DELEGATION_MISSING_REASON = "security-delegation-missing-reason";
|
|
1682
1987
|
declare const SECURITY_CBP_NO_RELATION = "security-controlled-by-parent-no-relation";
|
|
@@ -1695,7 +2000,7 @@ interface SecurityFinding {
|
|
|
1695
2000
|
/** How to fix it. */
|
|
1696
2001
|
hint: string;
|
|
1697
2002
|
}
|
|
1698
|
-
type AnyRec$
|
|
2003
|
+
type AnyRec$q = Record<string, unknown>;
|
|
1699
2004
|
/**
|
|
1700
2005
|
* Validate the security posture of a stack. Returns findings (empty = clean).
|
|
1701
2006
|
* `error` findings gate the build in `os compile`; `info` is advisory.
|
|
@@ -1703,7 +2008,7 @@ type AnyRec$o = Record<string, unknown>;
|
|
|
1703
2008
|
* `opts.nowMs` injects the clock for the ADR-0091 authoring-time expiry rule
|
|
1704
2009
|
* (tests); production callers omit it.
|
|
1705
2010
|
*/
|
|
1706
|
-
declare function validateSecurityPosture(stack: AnyRec$
|
|
2011
|
+
declare function validateSecurityPosture(stack: AnyRec$q, opts?: {
|
|
1707
2012
|
nowMs?: number;
|
|
1708
2013
|
}): SecurityFinding[];
|
|
1709
2014
|
/**
|
|
@@ -1734,94 +2039,8 @@ declare function validateSecurityPosture(stack: AnyRec$o, opts?: {
|
|
|
1734
2039
|
* carries `positions`/`apps` and both types are gated — at which point it
|
|
1735
2040
|
* crosses whole, in one edit, as its own entry.
|
|
1736
2041
|
*/
|
|
1737
|
-
declare function validateSecurityRoleWord(stack: AnyRec$
|
|
2042
|
+
declare function validateSecurityRoleWord(stack: AnyRec$q): SecurityFinding[];
|
|
1738
2043
|
|
|
1739
|
-
/**
|
|
1740
|
-
* [ADR-0105 D6] The two organization-axis red lines, enforced at authoring time.
|
|
1741
|
-
*
|
|
1742
|
-
* ADR-0105 gives organizations a reporting/grouping dimension
|
|
1743
|
-
* (`sys_organization.parent_organization_id`, sibling ordering). That dimension
|
|
1744
|
-
* is load-bearing for consolidated reporting — and dangerous, because it LOOKS
|
|
1745
|
-
* like a permission hierarchy. Two lines keep it from becoming one:
|
|
1746
|
-
*
|
|
1747
|
-
* | Rule | Red line |
|
|
1748
|
-
* |-----------------------------------------|-----------------------------------|
|
|
1749
|
-
* | org-axis-permission-inheritance (error) | D6 ①: no inheritance along the org tree |
|
|
1750
|
-
* | org-axis-cross-org-bu-grant (error) | D6 ②: business-unit trees stay org-internal |
|
|
1751
|
-
*
|
|
1752
|
-
* **① No permission inheritance along the org axis.** Cross-organization
|
|
1753
|
-
* visibility comes from membership union (`accessible_org_ids`, ADR-0105 D2) —
|
|
1754
|
-
* the engine's own Layer 0 wall — never from walking a parent reference. An RLS
|
|
1755
|
-
* policy or sharing rule that reads `parent_organization_id` builds a SECOND
|
|
1756
|
-
* permission hierarchy beside the business-unit tree: exactly the dual-hierarchy
|
|
1757
|
-
* mistake ADR-0057 D5 retired and ADR-0090 D3 finalized for positions. It also
|
|
1758
|
-
* silently outranks the wall it sits behind, since a Layer-1 policy cannot widen
|
|
1759
|
-
* Layer 0 (W1) — so the author gets a rule that appears to grant access and
|
|
1760
|
-
* does not. Fail at authoring, not in a support ticket.
|
|
1761
|
-
*
|
|
1762
|
-
* **② Business-unit trees remain org-internal.** `sys_business_unit` is
|
|
1763
|
-
* org-scoped and every BU mechanism (`unit_and_subordinates` sharing,
|
|
1764
|
-
* `adminScope` delegation, depth scopes) resolves within ONE organization. A
|
|
1765
|
-
* business-unit sharing rule on a PLATFORM-GLOBAL object (`tenancy.enabled:
|
|
1766
|
-
* false`) has no organization column to scope against, so the grant spans every
|
|
1767
|
-
* organization in the database — a cross-org BU grant by construction, and the
|
|
1768
|
-
* "cross-org BU mega-tree" the ADR rejected, arrived at by accident. It covers
|
|
1769
|
-
* BOTH business-unit recipients, `business_unit` and `unit_and_subordinates`
|
|
1770
|
-
* — see {@link BU_TREE_RECIPIENT_TYPES} for the word list and its deliberate
|
|
1771
|
-
* complement.
|
|
1772
|
-
*
|
|
1773
|
-
* Both are `error`, per ADR-0049 discipline: each mirrors a real enforcement
|
|
1774
|
-
* property (the Layer 0 wall's independence; the org-predicated BU resolver),
|
|
1775
|
-
* so the lint moves the failure from silent-wrong-answer to author-time fix-it.
|
|
1776
|
-
*
|
|
1777
|
-
* Pure `(stack) => Finding[]`; accepts the NORMALIZED stack input.
|
|
1778
|
-
*
|
|
1779
|
-
* ## Scope — the keys this rule reads, and the ones it deliberately does not
|
|
1780
|
-
*
|
|
1781
|
-
* Every key below is one `@objectstack/spec` DECLARES. That is a contract, not
|
|
1782
|
-
* a style preference: the rule is registered `input: 'parsed'`, so what it sees
|
|
1783
|
-
* is what `ObjectStackSchema` returned. An undeclared key never survives to be
|
|
1784
|
-
* read — the stack root strips it, and the `.strict()` sub-schemas reject the
|
|
1785
|
-
* whole stack outright — so a branch keyed on one is inert for every stack an
|
|
1786
|
-
* author can actually ship (#4984, #5009).
|
|
1787
|
-
*
|
|
1788
|
-
* | Read | Declared by |
|
|
1789
|
-
* |---------------------------------------|------------------------------------|
|
|
1790
|
-
* | `permissions[]` | `ObjectStackSchema` |
|
|
1791
|
-
* | `permissions[].rowLevelSecurity[]` | `PermissionSetSchema` |
|
|
1792
|
-
* | `…[].using` / `…[].check` | `RowLevelSecurityPolicySchema` |
|
|
1793
|
-
* | `sharingRules[]` | `ObjectStackSchema` |
|
|
1794
|
-
* | `sharingRules[].condition` / `.sharedWith` / `.object` | `SharingRuleSchema` |
|
|
1795
|
-
* | `objects[].tenancy` / `.systemFields` | `ObjectSchema` |
|
|
1796
|
-
*
|
|
1797
|
-
* NOT read, and each for a reason that is a schema fact:
|
|
1798
|
-
*
|
|
1799
|
-
* - `permissionSets` / `sharing` — not declared on the stack root. The root
|
|
1800
|
-
* STRIPS them, so after parse they are `undefined` no matter what the author
|
|
1801
|
-
* wrote. The declared spellings are `permissions` and `sharingRules`.
|
|
1802
|
-
* - `sharingRules[].objectName` — `SharingRuleSchema` is `.strict()` and knows
|
|
1803
|
-
* it only as a rejected name; `object` is required, so the canonical read can
|
|
1804
|
-
* never be missing on a rule that parsed.
|
|
1805
|
-
* - `objects[].rowLevelSecurity` / `objects[].rls` — **object-level RLS is not
|
|
1806
|
-
* an authoring surface at all.** `ObjectSchema` declares neither key (nor
|
|
1807
|
-
* does `authorable-surface.json` list one: the sole entry is
|
|
1808
|
-
* `security/PermissionSet:rowLevelSecurity`), and `ObjectSchema` is
|
|
1809
|
-
* `.strict()`, so a stack carrying one does not parse — it is refused with
|
|
1810
|
-
* "Unrecognized key(s) on this object". Until #5009 this file walked that
|
|
1811
|
-
* non-existent surface for ~20 lines, complete with an `objects[N].
|
|
1812
|
-
* rowLevelSecurity[M].using` diagnostic path. Nothing could reach it, and the
|
|
1813
|
-
* cost was never the missed finding: the next author to read this rule (human
|
|
1814
|
-
* or AI) came away believing object-level RLS was a real authorization
|
|
1815
|
-
* surface and wrote more code against it (#5008 nearly did). RLS policies
|
|
1816
|
-
* live on a permission set; that is the branch above.
|
|
1817
|
-
*
|
|
1818
|
-
* Alias tolerance belongs at the schema's refusal, not in a consumer (Prime
|
|
1819
|
-
* Directive #12) — where it also converts a loud, named rejection into a
|
|
1820
|
-
* silently-inert gate. `validate-org-axis-red-lines.test.ts` pins all of this
|
|
1821
|
-
* structurally: every key read here is checked against the declaring schema's
|
|
1822
|
-
* own `.shape`, and every `findings.push` site must be reachable by a fixture
|
|
1823
|
-
* that passed `safeParse`.
|
|
1824
|
-
*/
|
|
1825
2044
|
declare const ORG_AXIS_PERMISSION_INHERITANCE = "org-axis-permission-inheritance";
|
|
1826
2045
|
declare const ORG_AXIS_CROSS_ORG_BU_GRANT = "org-axis-cross-org-bu-grant";
|
|
1827
2046
|
type OrgAxisSeverity = 'error' | 'warning';
|
|
@@ -1903,86 +2122,6 @@ interface RlsPredicateFinding {
|
|
|
1903
2122
|
*/
|
|
1904
2123
|
declare function validateRlsPredicateEnforceability(stack: unknown): RlsPredicateFinding[];
|
|
1905
2124
|
|
|
1906
|
-
/**
|
|
1907
|
-
* [ADR-0049 — references] Reference-integrity for dashboard header action
|
|
1908
|
-
* targets (issue #3367).
|
|
1909
|
-
*
|
|
1910
|
-
* ADR-0049 established the "enforce-or-remove" gate for spec *properties*: a
|
|
1911
|
-
* declared property the runtime does not honour is a false promise and must be
|
|
1912
|
-
* enforced, marked experimental, or removed. This rule applies the SAME honesty
|
|
1913
|
-
* principle to *references*. A dashboard header action names a target — a
|
|
1914
|
-
* `script`/`modal` action, or a `url` route — that must actually resolve. A
|
|
1915
|
-
* dangling target ships a button that renders and, on click, silently does
|
|
1916
|
-
* nothing: a false affordance, exactly the failure ADR-0049 exists to prevent,
|
|
1917
|
-
* just for a reference rather than a property.
|
|
1918
|
-
*
|
|
1919
|
-
* Nothing in the protocol schema can express this: `actionUrl` is a free string,
|
|
1920
|
-
* so `{ actionType: 'script', actionUrl: 'export_dashboard_pdf' }` parses and
|
|
1921
|
-
* ships even when no such action is defined anywhere in the stack.
|
|
1922
|
-
*
|
|
1923
|
-
* Surfaces checked:
|
|
1924
|
-
* - dashboard `header.actions[]` — each `{ actionType, actionUrl }`
|
|
1925
|
-
*
|
|
1926
|
-
* ## The widget branch, and why it is gone (#5010)
|
|
1927
|
-
*
|
|
1928
|
-
* This rule used to check `widgets[].actionUrl` too, describing it as "the
|
|
1929
|
-
* per-widget button" and claiming in this docblock that it "mirrors the objectui
|
|
1930
|
-
* runtime dispatch". It did not: no renderer in either repo has ever drawn a
|
|
1931
|
-
* per-widget action button — all 14 `actionUrl` reads in `DashboardRenderer` are
|
|
1932
|
-
* scoped to `header.actions[]`. So the strictest arm of this rule (a dangling
|
|
1933
|
-
* `script`/`modal` target is an ERROR, i.e. a failed build) was enforcing
|
|
1934
|
-
* referential integrity for a button that could not render. An author could be
|
|
1935
|
-
* blocked from shipping because a control that does not exist pointed at an
|
|
1936
|
-
* action that also did not.
|
|
1937
|
-
*
|
|
1938
|
-
* That inversion — a rule written to delete false affordances, itself sustaining
|
|
1939
|
-
* one — is why the widget keys were retired rather than the check merely
|
|
1940
|
-
* relaxed: `widgets[].actionUrl` / `actionType` / `actionIcon` are now tombstoned
|
|
1941
|
-
* in `@objectstack/spec` 17.0.0, so authoring one is a `tsc` error and a parse
|
|
1942
|
-
* error carrying the prescription. There is no widget target left to resolve.
|
|
1943
|
-
*
|
|
1944
|
-
* Resolution mirrors the objectui runtime dispatch (`DashboardRenderer`
|
|
1945
|
-
* hands the target to the SHARED `useActionModal` since objectui#4782) so the
|
|
1946
|
-
* lint flags exactly what would fail to resolve at runtime:
|
|
1947
|
-
*
|
|
1948
|
-
* actionType 'script' → `actionUrl` must name a DEFINED action (`stack.actions`
|
|
1949
|
-
* or any `object.actions`, by `name`). A script target that names no
|
|
1950
|
-
* defined action fails open at runtime ("action not found"). → ERROR.
|
|
1951
|
-
*
|
|
1952
|
-
* actionType 'modal' → `actionUrl` names a declared PAGE (`stack.pages`), and
|
|
1953
|
-
* only a page — maintainer ruling objectstack#6739-A (2026-08-09). This
|
|
1954
|
-
* rule used to accept a defined action name, a bare object name, and the
|
|
1955
|
-
* `<verb>_<object>` convention (create_/new_/add_/edit_/update_ + object),
|
|
1956
|
-
* on the claim that it mirrored `DashboardView`'s own modal handler. That
|
|
1957
|
-
* handler — the convention's last live copy — was deleted by objectui#4782
|
|
1958
|
-
* (after objectui#4764 retired the object fallback in `useActionModal`):
|
|
1959
|
-
* the runtime resolves a string modal target against page metadata and
|
|
1960
|
-
* REFUSES everything else, so each retired limb here blessed a button that
|
|
1961
|
-
* dispatches to a named refusal at runtime. The ruling explicitly declined
|
|
1962
|
-
* the middle shape (keep the prefix, reject bare object names): a target
|
|
1963
|
-
* names the page `create_opportunity`, or it names nothing. Opening an
|
|
1964
|
-
* object's form is `actionType: 'form'`. Otherwise → ERROR.
|
|
1965
|
-
*
|
|
1966
|
-
* actionType 'url' → a relative in-app path. WARN when a recognizable
|
|
1967
|
-
* `<collection>/<name>` segment (objects/reports/dashboards/pages/views)
|
|
1968
|
-
* names an entity that does not exist in this stack. External URLs
|
|
1969
|
-
* (`http(s)://`, `//`), interpolated targets (`${…}`), and opaque routes
|
|
1970
|
-
* (no recognized collection segment) are skipped — they cannot be resolved
|
|
1971
|
-
* statically and may be host/app/plugin routes. → WARNING.
|
|
1972
|
-
*
|
|
1973
|
-
* actionType 'flow' | 'api' — not checked: flow targets resolve against the
|
|
1974
|
-
* automation engine / other packages, and api targets are opaque endpoints.
|
|
1975
|
-
* Out of scope for #3367.
|
|
1976
|
-
*
|
|
1977
|
-
* Severity split follows the issue's acceptance criteria: an undefined
|
|
1978
|
-
* `script`/`modal` target FAILS validation (a genuine dead reference that fails
|
|
1979
|
-
* open at runtime as a dead button); an unresolved `url` route is advisory
|
|
1980
|
-
* (route resolution is app-context-dependent, and a path may be served by
|
|
1981
|
-
* another installed package or a host/console route). External, interpolated,
|
|
1982
|
-
* convention, and opaque targets are exempted to keep false positives near zero
|
|
1983
|
-
* — the same conservative posture as the sibling `lint-view-refs` and
|
|
1984
|
-
* `validate-capability-references` rules.
|
|
1985
|
-
*/
|
|
1986
2125
|
declare const DASHBOARD_ACTION_TARGET_UNDEFINED = "dashboard-action-target-undefined";
|
|
1987
2126
|
declare const DASHBOARD_ACTION_ROUTE_UNRESOLVED = "dashboard-action-route-unresolved";
|
|
1988
2127
|
type DashboardActionRefSeverity = 'error' | 'warning';
|
|
@@ -2000,13 +2139,13 @@ interface DashboardActionRefFinding {
|
|
|
2000
2139
|
/** How to fix it. */
|
|
2001
2140
|
hint: string;
|
|
2002
2141
|
}
|
|
2003
|
-
type AnyRec$
|
|
2142
|
+
type AnyRec$p = Record<string, unknown>;
|
|
2004
2143
|
/**
|
|
2005
2144
|
* Validate every dashboard header action reference in a stack. Returns
|
|
2006
2145
|
* findings (empty = clean). `script`/`modal` dead targets are errors; `url`
|
|
2007
2146
|
* unresolved routes are warnings.
|
|
2008
2147
|
*/
|
|
2009
|
-
declare function validateDashboardActionRefs(stack: AnyRec$
|
|
2148
|
+
declare function validateDashboardActionRefs(stack: AnyRec$p): DashboardActionRefFinding[];
|
|
2010
2149
|
|
|
2011
2150
|
/**
|
|
2012
2151
|
* Build-time filter-placeholder diagnostics (issue #3574).
|
|
@@ -2090,9 +2229,82 @@ interface FilterTokenFinding {
|
|
|
2090
2229
|
*/
|
|
2091
2230
|
declare function validateFilterTokens(stack: Record<string, unknown> | undefined | null): FilterTokenFinding[];
|
|
2092
2231
|
|
|
2232
|
+
/** Diagnostic rule id. */
|
|
2233
|
+
declare const FLOW_FILTER_TOKEN_UNKNOWN = "flow-filter-token-unknown";
|
|
2234
|
+
interface FlowFilterTokenFinding {
|
|
2235
|
+
/** Always `error` — the node throws a guard refusal instead of running. */
|
|
2236
|
+
severity: 'error';
|
|
2237
|
+
rule: string;
|
|
2238
|
+
/** Human-readable location, e.g. `flow "opportunity_stagnation"`. */
|
|
2239
|
+
where: string;
|
|
2240
|
+
/** Config path, e.g. `flows[2].nodes[1].config.filter.close_date.$lt`. */
|
|
2241
|
+
path: string;
|
|
2242
|
+
message: string;
|
|
2243
|
+
hint: string;
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* Validate flow-node filter placeholders across a schema-parsed stack.
|
|
2247
|
+
*
|
|
2248
|
+
* Pure `(stack) => Finding[]`; no I/O.
|
|
2249
|
+
*/
|
|
2250
|
+
declare function validateFlowFilterTokens(stack: Record<string, unknown> | undefined | null): FlowFilterTokenFinding[];
|
|
2251
|
+
|
|
2252
|
+
/** The two names legal only as a whole token (`{TODAY() + 7}`), never in a call. */
|
|
2253
|
+
declare const FLOW_TEMPLATE_DATE_FUNCTIONS: readonly string[];
|
|
2254
|
+
/**
|
|
2255
|
+
* The value-expression function table — the CEL stdlib's numeric six, by the
|
|
2256
|
+
* #11060 ruling. Mirrors `EXPRESSION_FUNCTION_ARITY`'s key set.
|
|
2257
|
+
*/
|
|
2258
|
+
declare const FLOW_TEMPLATE_VALUE_FUNCTIONS: readonly string[];
|
|
2259
|
+
/** What the flow template dialect does with one whole-string `{…}` token. */
|
|
2260
|
+
type FlowTemplateTokenVerdict =
|
|
2261
|
+
/** `{NOW()}` / `{TODAY() - 45}` — the evaluator resolves it. Legitimate. */
|
|
2262
|
+
{
|
|
2263
|
+
kind: 'date-function';
|
|
2264
|
+
name: string;
|
|
2265
|
+
}
|
|
2266
|
+
/** `{$User.Id}` — the evaluator resolves it from the run context. */
|
|
2267
|
+
| {
|
|
2268
|
+
kind: 'user-context';
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* `{recordId}` / `{record.id}` — a `VariableMap` lookup, and the position
|
|
2272
|
+
* from which an unresolved name is handed to the filter dialect. OPEN: not
|
|
2273
|
+
* decidable from authored metadata, so never a finding.
|
|
2274
|
+
*/
|
|
2275
|
+
| {
|
|
2276
|
+
kind: 'variable-path';
|
|
2277
|
+
head: string;
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* A call to a name in NEITHER table. `resolveToken` throws
|
|
2281
|
+
* `FlowExpressionFunctionError` here (a guard refusal — a `fault` edge must
|
|
2282
|
+
* not swallow it), so the node cannot run. THIS is the finding.
|
|
2283
|
+
*/
|
|
2284
|
+
| {
|
|
2285
|
+
kind: 'unknown-function';
|
|
2286
|
+
name: string;
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Anything else — junk shapes (`{30 days ago}`) and arithmetic over names
|
|
2290
|
+
* this module cannot resolve. `resolveToken` answers `undefined` and the
|
|
2291
|
+
* CRUD collapse guard (#3810) reports it at run time. Open, not judged.
|
|
2292
|
+
*/
|
|
2293
|
+
| {
|
|
2294
|
+
kind: 'unresolvable-shape';
|
|
2295
|
+
};
|
|
2296
|
+
/**
|
|
2297
|
+
* Classify the INSIDE of one whole-string `{…}` filter token — `inner` is the
|
|
2298
|
+
* text between the braces, exactly as authored.
|
|
2299
|
+
*
|
|
2300
|
+
* Mirrors `resolveToken`'s dispatch order (see the module header). Holds no
|
|
2301
|
+
* severity and knows nothing about where the token was found.
|
|
2302
|
+
*/
|
|
2303
|
+
declare function classifyFlowTemplateToken(inner: string): FlowTemplateTokenVerdict;
|
|
2304
|
+
|
|
2093
2305
|
/**
|
|
2094
|
-
* Build-time refusal of a bare dashboard date-range PRESET name
|
|
2095
|
-
* comparand
|
|
2306
|
+
* Build-time refusal of a bare dashboard date-range PRESET name authored as a
|
|
2307
|
+
* filter comparand — two arms, one wording.
|
|
2096
2308
|
*
|
|
2097
2309
|
* `last_7_days` / `last_30_days` / `last_90_days` and their ten calendar
|
|
2098
2310
|
* siblings are REAL declared names (`DATE_RANGE_PRESETS`,
|
|
@@ -2118,10 +2330,10 @@ declare function validateFilterTokens(stack: Record<string, unknown> | undefined
|
|
|
2118
2330
|
* (`['created_at', '>=', …]`) — and reports with the located `where` / `path`
|
|
2119
2331
|
* the CLI commands render.
|
|
2120
2332
|
*
|
|
2121
|
-
* ##
|
|
2333
|
+
* ## Arm 1 — ordering positions, FIELD-AGNOSTIC (#8793)
|
|
2122
2334
|
*
|
|
2123
|
-
*
|
|
2124
|
-
*
|
|
2335
|
+
* The judgement rides on POSITION alone, exactly as the schema door's #8793
|
|
2336
|
+
* note lays out at length:
|
|
2125
2337
|
*
|
|
2126
2338
|
* - **Judged:** `$gt` / `$gte` / `$lt` / `$lte` comparands and `$between`
|
|
2127
2339
|
* endpoints (Mongo shape); `>` / `>=` / `<` / `<=` / `between` triples and
|
|
@@ -2129,17 +2341,105 @@ declare function validateFilterTokens(stack: Record<string, unknown> | undefined
|
|
|
2129
2341
|
* `greater_than` / `less_than` / `greater_than_or_equal` /
|
|
2130
2342
|
* `less_than_or_equal` / `before` / `after` / `between` view filter rules
|
|
2131
2343
|
* and every alias `normalizeFilterOperator` folds onto them. An ORDERED
|
|
2132
|
-
* comparison against a declared preset name has no legitimate reading
|
|
2133
|
-
*
|
|
2134
|
-
* `$in`, `$nin`, …). A select/picklist column legitimately stores values
|
|
2135
|
-
* that collide with preset names (`GlobalFilterSchema`'s own pins protect
|
|
2136
|
-
* `type: 'select', defaultValue: 'this_quarter'`), and on a declared
|
|
2137
|
-
* temporal field the engine door still refuses these at query time with the
|
|
2138
|
-
* field's type in hand.
|
|
2344
|
+
* comparison against a declared preset name has no legitimate reading on
|
|
2345
|
+
* ANY column, so no field type is needed to refuse it.
|
|
2139
2346
|
* - **Only the 13 declared names.** A near-miss (`last_60_days`) is not this
|
|
2140
2347
|
* rule's business — on a temporal field the engine's field-typed door
|
|
2141
2348
|
* catches it; judging undeclared strings here would be a guessed superset.
|
|
2142
2349
|
*
|
|
2350
|
+
* ## Arm 2 — equality and membership positions, FIELD-TYPED (#16106)
|
|
2351
|
+
*
|
|
2352
|
+
* Equality (`{ period: 'this_quarter' }`, `$eq`, `$ne`) and membership (`$in`
|
|
2353
|
+
* / `$nin`) CANNOT be judged blind: a select/picklist column legitimately
|
|
2354
|
+
* stores values that collide with preset names (`GlobalFilterSchema`'s own
|
|
2355
|
+
* pins protect `type: 'select', defaultValue: 'this_quarter'`), and equality
|
|
2356
|
+
* against such a stored value is a working filter. That is why the schema
|
|
2357
|
+
* door — field-agnostic by construction — keeps its ordering-only boundary,
|
|
2358
|
+
* and why this arm exists HERE, where the stack's object metadata is in hand:
|
|
2359
|
+
* maintainer-ruled 2026-09-06 (#16106, comment 5557019138, adopting
|
|
2360
|
+
* recommendation 1′): *at a layer that holds the object metadata, a declared
|
|
2361
|
+
* `date` / `datetime` field refuses one of the 13 declared preset names in
|
|
2362
|
+
* EVERY comparand position — bare (implicit equality), `$eq` / `$ne`, `$in` /
|
|
2363
|
+
* `$nin` and their view-rule and triple spellings, alongside the ordering
|
|
2364
|
+
* positions already judged.* Same message, same prescription (the #5240
|
|
2365
|
+
* convention): the window the preset already means is exactly what an author
|
|
2366
|
+
* writing `close_date == 'last_30_days'` intended.
|
|
2367
|
+
*
|
|
2368
|
+
* Measured first (ruling item 3), as real queries on a declared `date` field
|
|
2369
|
+
* (`close_date`) and a declared `datetime` sibling, on two real drivers —
|
|
2370
|
+
* `@objectstack/driver-memory` and `@objectstack/driver-sqlite-wasm` — 30 rows
|
|
2371
|
+
* seeded / 20 inside a 30-day window; both drivers answered identically:
|
|
2372
|
+
*
|
|
2373
|
+
* ```
|
|
2374
|
+
* close_date: 'last_30_days' REFUSED INVALID_FILTER / 400 (bare)
|
|
2375
|
+
* close_date: { $eq: 'last_30_days' } REFUSED INVALID_FILTER / 400
|
|
2376
|
+
* close_date: { $in: ['last_30_days'] } REFUSED INVALID_FILTER / 400
|
|
2377
|
+
* close_date: { $ne / $nin … } REFUSED INVALID_FILTER / 400
|
|
2378
|
+
* close_date: { $gte: '{30_days_ago}' } 200 count=20 <- positive control
|
|
2379
|
+
* close_date: '2026-09-03' 200 count=1 <- equality works on a date
|
|
2380
|
+
* stage: 'this_quarter' (select column) 200 count=10 <- the picklist case, alive
|
|
2381
|
+
* ```
|
|
2382
|
+
*
|
|
2383
|
+
* So at QUERY time the engine door already refuses every residue position on a
|
|
2384
|
+
* declared temporal field — the residue was purely an AUTHORING-time gap:
|
|
2385
|
+
* `objectstack lint` passed and `defineStack` accepted a filter the runtime
|
|
2386
|
+
* then refused with a 400 on first render. This arm closes that gap where the
|
|
2387
|
+
* AI author's correction loop can see it.
|
|
2388
|
+
*
|
|
2389
|
+
* ### Which object a filter is judged against
|
|
2390
|
+
*
|
|
2391
|
+
* `walkAuthoredFilters` finds the subtrees; this arm re-walks each subtree's
|
|
2392
|
+
* config path back through its ancestors and binds the filter to the NEAREST
|
|
2393
|
+
* ancestor that declares an object, in the spellings the carriers actually
|
|
2394
|
+
* use (each one the same read a sibling rule already makes at that position):
|
|
2395
|
+
*
|
|
2396
|
+
* - a literal `object` / `objectName` — a dataset, a summary field's child
|
|
2397
|
+
* object, a global filter's `optionsFrom`, a page data source, a
|
|
2398
|
+
* `record:related_list`'s `properties`, a time-relative trigger;
|
|
2399
|
+
* - a `dataset` name, resolved to that dataset's `object` — dashboard widgets
|
|
2400
|
+
* (`validate-widget-bindings`, #14148), reports and report blocks;
|
|
2401
|
+
* - `data: { provider: 'object', object }` — standalone views and list views
|
|
2402
|
+
* (`validate-list-view-field-refs`, #14107); any OTHER provider names no
|
|
2403
|
+
* object, so the position is unjudged;
|
|
2404
|
+
* - `config.objectName` / `config.object` — flow CRUD nodes
|
|
2405
|
+
* (`validate-flow-node-writes`), a templated `{…}` value skipped;
|
|
2406
|
+
* - `dataSource.object`, then `properties.object` / `properties.objectName`
|
|
2407
|
+
* — page components (`validate-page-field-bindings`);
|
|
2408
|
+
* - `publicPicker.object`, else the enclosing form field's `reference`
|
|
2409
|
+
* resolved on the view's object, else NOTHING — a form field's public-lookup
|
|
2410
|
+
* picker (`FormFieldPublicPickerSchema`) queries the REFERENCED object, so
|
|
2411
|
+
* its `filter` must never fall through to the parent form object (#16106
|
|
2412
|
+
* review finding B1: that fall-through was a false refusal wherever the two
|
|
2413
|
+
* objects share a field name with differing types);
|
|
2414
|
+
* - and, under `objects`, the object itself — its list views, tabs and
|
|
2415
|
+
* `relatedListFilter` (the filter runs over the CHILD rows, i.e. the object
|
|
2416
|
+
* that owns the field).
|
|
2417
|
+
*
|
|
2418
|
+
* The field key (a bare name, or a dotted relationship path) is then resolved
|
|
2419
|
+
* through `resolveFieldPath` (`object-graph.ts`), and the comparand is judged
|
|
2420
|
+
* only when the LEAF resolves to an author-declared field of type `date` or
|
|
2421
|
+
* `datetime` — the two types the ruling names.
|
|
2422
|
+
*
|
|
2423
|
+
* ### What this arm deliberately does NOT judge
|
|
2424
|
+
*
|
|
2425
|
+
* Every one of these is a MISSED CATCH (the engine door still refuses it at
|
|
2426
|
+
* query time, field type in hand), never a false build error:
|
|
2427
|
+
*
|
|
2428
|
+
* - a position no ancestor binds (an app-level filter, a dashboard-level
|
|
2429
|
+
* filter outside a widget), a dataset or object the stack does not declare,
|
|
2430
|
+
* an object with no readable field map, a view on a non-`object` provider;
|
|
2431
|
+
* - a leaf that resolves only as a registry-INJECTED column (`created_at`,
|
|
2432
|
+
* `updated_at`, …): the object graph carries no type for those — their type
|
|
2433
|
+
* is registry-owned and invisible here (`FieldPathVerdict`'s own contract);
|
|
2434
|
+
* - a `time` field: the ruling names `date` / `datetime`, and a wall-clock
|
|
2435
|
+
* column has no preset-shaped authoring slip worth a rule of its own;
|
|
2436
|
+
* - a field the object does not declare at all (a typo) — that is the
|
|
2437
|
+
* `*-filter-field-unknown` rules' finding, not a second one here.
|
|
2438
|
+
*
|
|
2439
|
+
* The implicit-equality position is reported under the operator it LOWERS to,
|
|
2440
|
+
* `$eq`, at the path of the field itself (`…filter.close_date`, no operator
|
|
2441
|
+
* segment), so the located path still says exactly what was authored.
|
|
2442
|
+
*
|
|
2143
2443
|
* Both vocabularies' `{placeholder}` spellings never collide with a preset
|
|
2144
2444
|
* name (a preset carries no braces), so this rule and `validate-filter-tokens`
|
|
2145
2445
|
* cannot double-report one value.
|
|
@@ -2163,9 +2463,10 @@ interface PresetComparandFinding {
|
|
|
2163
2463
|
/**
|
|
2164
2464
|
* Validate every authored filter across a stack for bare preset comparands.
|
|
2165
2465
|
*
|
|
2166
|
-
* Pure `(stack) => Finding[]`; no I/O.
|
|
2167
|
-
*
|
|
2168
|
-
* the runtime publish gate's per-write
|
|
2466
|
+
* Pure `(stack) => Finding[]`; no I/O. Arm 1 judges the filter literal alone;
|
|
2467
|
+
* arm 2 additionally reads the stack's own `objects` (and `datasets`, to bind
|
|
2468
|
+
* a widget or report) — both collections the runtime publish gate's per-write
|
|
2469
|
+
* snapshot carries — and stays silent wherever they are absent.
|
|
2169
2470
|
*/
|
|
2170
2471
|
declare function validatePresetComparands(stack: Record<string, unknown> | undefined | null): PresetComparandFinding[];
|
|
2171
2472
|
|
|
@@ -2215,12 +2516,12 @@ interface ObjectRefFinding {
|
|
|
2215
2516
|
/** How to fix it. */
|
|
2216
2517
|
hint: string;
|
|
2217
2518
|
}
|
|
2218
|
-
type AnyRec$
|
|
2519
|
+
type AnyRec$o = Record<string, unknown>;
|
|
2219
2520
|
/**
|
|
2220
2521
|
* Validate every object-name reference on the surfaces listed in the module
|
|
2221
2522
|
* header. Returns findings (empty = clean).
|
|
2222
2523
|
*/
|
|
2223
|
-
declare function validateObjectReferences(stack: AnyRec$
|
|
2524
|
+
declare function validateObjectReferences(stack: AnyRec$o): ObjectRefFinding[];
|
|
2224
2525
|
|
|
2225
2526
|
type ReferenceIntegritySeverity = 'error' | 'warning';
|
|
2226
2527
|
/**
|
|
@@ -2617,7 +2918,7 @@ interface SearchableFieldFinding {
|
|
|
2617
2918
|
* runtime would refuse are flagged (#4830).
|
|
2618
2919
|
*/
|
|
2619
2920
|
type SearchableFieldRole = 'canonical' | 'narrowing';
|
|
2620
|
-
type AnyRec$
|
|
2921
|
+
type AnyRec$n = Record<string, unknown>;
|
|
2621
2922
|
/**
|
|
2622
2923
|
* The slice of an object the search checks resolve against: the authored
|
|
2623
2924
|
* field map (existence + the `type`/`hidden` meta search resolution reads),
|
|
@@ -2648,7 +2949,7 @@ interface ObjectSearchTarget {
|
|
|
2648
2949
|
* `validate-react-page-props` — the gate that already parses that source —
|
|
2649
2950
|
* runs the same `checkSearchableFieldList` core on it (#4329).
|
|
2650
2951
|
*/
|
|
2651
|
-
declare function validateSearchableFields(stack: AnyRec$
|
|
2952
|
+
declare function validateSearchableFields(stack: AnyRec$n): SearchableFieldFinding[];
|
|
2652
2953
|
|
|
2653
2954
|
declare const SORT_FIELD_UNKNOWN = "sort-field-unknown";
|
|
2654
2955
|
declare const SORT_FIELD_UNSORTABLE = "sort-field-unsortable";
|
|
@@ -2674,7 +2975,7 @@ interface SortableFieldFinding {
|
|
|
2674
2975
|
/** How to fix it. */
|
|
2675
2976
|
hint: string;
|
|
2676
2977
|
}
|
|
2677
|
-
type AnyRec$
|
|
2978
|
+
type AnyRec$m = Record<string, unknown>;
|
|
2678
2979
|
/**
|
|
2679
2980
|
* Check ONE authored `sort` declaration against the object it is bound to —
|
|
2680
2981
|
* the shared core behind every list-view surface that declares an ordering.
|
|
@@ -2697,7 +2998,7 @@ declare function checkSortDeclaration(declared: unknown, objectName: string | un
|
|
|
2697
2998
|
* over the bound object's own columns. See the module note for the four
|
|
2698
2999
|
* sort-carrying surfaces that were checked and deliberately left out.
|
|
2699
3000
|
*/
|
|
2700
|
-
declare function validateSortableFields(stack: AnyRec$
|
|
3001
|
+
declare function validateSortableFields(stack: AnyRec$m): SortableFieldFinding[];
|
|
2701
3002
|
|
|
2702
3003
|
/** A list-view field reference that resolves to no field on the bound object. */
|
|
2703
3004
|
declare const LIST_VIEW_FIELD_UNKNOWN = "list-view-field-unknown";
|
|
@@ -2722,14 +3023,40 @@ interface ListViewFieldRefFinding {
|
|
|
2722
3023
|
/** How to fix it. */
|
|
2723
3024
|
hint: string;
|
|
2724
3025
|
}
|
|
2725
|
-
type AnyRec$
|
|
3026
|
+
type AnyRec$l = Record<string, unknown>;
|
|
2726
3027
|
/**
|
|
2727
3028
|
* Validate every list view's field references against the object graph.
|
|
2728
3029
|
* Returns findings (empty = clean). Pure `(stack) => Finding[]`; no I/O, and
|
|
2729
3030
|
* safe on both the schema-parsed stack and the raw config the `lint` path
|
|
2730
3031
|
* carries.
|
|
2731
3032
|
*/
|
|
2732
|
-
declare function validateListViewFieldRefs(stack: AnyRec$
|
|
3033
|
+
declare function validateListViewFieldRefs(stack: AnyRec$l): ListViewFieldRefFinding[];
|
|
3034
|
+
|
|
3035
|
+
/** An object-level field-name list entry that resolves to no field on the object. */
|
|
3036
|
+
declare const OBJECT_FIELD_REF_UNKNOWN = "object-field-ref-unknown";
|
|
3037
|
+
type ObjectFieldRefSeverity = 'error' | 'warning';
|
|
3038
|
+
interface ObjectFieldRefFinding {
|
|
3039
|
+
/** Always `error` — see the severity note on this module. */
|
|
3040
|
+
severity: ObjectFieldRefSeverity;
|
|
3041
|
+
/** Diagnostic rule id. */
|
|
3042
|
+
rule: string;
|
|
3043
|
+
/** Human-readable location, e.g. `object "proj_task" › highlightFields`. */
|
|
3044
|
+
where: string;
|
|
3045
|
+
/** Config path, e.g. `objects[0].highlightFields[1]`. */
|
|
3046
|
+
path: string;
|
|
3047
|
+
/** What is wrong. */
|
|
3048
|
+
message: string;
|
|
3049
|
+
/** How to fix it. */
|
|
3050
|
+
hint: string;
|
|
3051
|
+
}
|
|
3052
|
+
type AnyRec$k = Record<string, unknown>;
|
|
3053
|
+
/**
|
|
3054
|
+
* Validate every object's own field-name lists against the object graph.
|
|
3055
|
+
* Returns findings (empty = clean). Pure `(stack) => Finding[]`; no I/O, and
|
|
3056
|
+
* safe on both the schema-parsed stack and the raw config the `lint` path
|
|
3057
|
+
* carries.
|
|
3058
|
+
*/
|
|
3059
|
+
declare function validateObjectFieldRefs(stack: AnyRec$k): ObjectFieldRefFinding[];
|
|
2733
3060
|
|
|
2734
3061
|
declare const ACTION_NAME_UNDEFINED = "action-name-undefined";
|
|
2735
3062
|
type ActionNameRefSeverity = 'error' | 'warning';
|
|
@@ -2747,62 +3074,13 @@ interface ActionNameRefFinding {
|
|
|
2747
3074
|
/** How to fix it. */
|
|
2748
3075
|
hint: string;
|
|
2749
3076
|
}
|
|
2750
|
-
type AnyRec$
|
|
3077
|
+
type AnyRec$j = Record<string, unknown>;
|
|
2751
3078
|
/**
|
|
2752
3079
|
* Validate every name-bound action reference in a stack. Returns findings
|
|
2753
3080
|
* (empty = clean).
|
|
2754
3081
|
*/
|
|
2755
|
-
declare function validateActionNameRefs(stack: AnyRec$
|
|
3082
|
+
declare function validateActionNameRefs(stack: AnyRec$j): ActionNameRefFinding[];
|
|
2756
3083
|
|
|
2757
|
-
/**
|
|
2758
|
-
* [ADR-0078 Phase 3 — Tier-A `action-locations`] An action nobody placed.
|
|
2759
|
-
*
|
|
2760
|
-
* `locations` is an action's placement declaration. An action that omits it —
|
|
2761
|
-
* and that no view names in `bulkActions` / `bulkActionDefs` / `rowActions` —
|
|
2762
|
-
* has no surface at all: it parses, it publishes, Setup lists it, and no user
|
|
2763
|
-
* can ever click it. ADR-0078 names this shape in its opening paragraph ("a
|
|
2764
|
-
* `summary` with no `summaryOperations`; **an `action` with no `locations`**;
|
|
2765
|
-
* … Each parses, 'renders', reports success — and does nothing") and Phase 3
|
|
2766
|
-
* asks for exactly this rule, one verified shape at a time.
|
|
2767
|
-
*
|
|
2768
|
-
* The renderer half is now unambiguous: objectui#3142 collapsed four
|
|
2769
|
-
* disagreeing renderers onto one predicate — an action renders at a location
|
|
2770
|
-
* only if it DECLARES that location. Before that, `action:bar` and the record
|
|
2771
|
-
* header showed an undeclared action *everywhere*, which is what made this
|
|
2772
|
-
* shape look alive; it is measurably inert as of objectui 17.1.
|
|
2773
|
-
*
|
|
2774
|
-
* ## What is NOT flagged, and why
|
|
2775
|
-
*
|
|
2776
|
-
* **`locations: []` — a deliberate headless action.** `content/docs/ui/
|
|
2777
|
-
* actions.mdx` ("Headless actions: declare it, then hide it") documents the
|
|
2778
|
-
* empty array as a first-class shape: the action stays callable over REST /
|
|
2779
|
-
* MCP / AI and keeps its capability gate, param contract and audit trail,
|
|
2780
|
-
* while claiming no UI surface. ADR-0110 D3 refuses an *undeclared* handler,
|
|
2781
|
-
* so a headless declaration is the only legal way to expose such an action —
|
|
2782
|
-
* flagging it would fight that ADR. The distinction this rule draws is
|
|
2783
|
-
* therefore between an author who said "nowhere, deliberately" (`[]`) and one
|
|
2784
|
-
* who never said anything at all (key absent).
|
|
2785
|
-
*
|
|
2786
|
-
* **Actions a view places by NAME.** Naming an action in a list view's
|
|
2787
|
-
* `bulkActions` or `bulkActionDefs` IS its placement — the selection bar is
|
|
2788
|
-
* driven by the view, never by `locations` (that is what the retired
|
|
2789
|
-
* `action.bulkEnabled` tombstone prescribes, and what objectui#3139's
|
|
2790
|
-
* aggregate bulk mode relies on: an action that only makes sense over a
|
|
2791
|
-
* selection has no single-record location by construction). `rowActions` is
|
|
2792
|
-
* exempted on the same zero-false-positive posture (ADR-0072 D1): it is the
|
|
2793
|
-
* same field pair on the same container, and an author who named an action
|
|
2794
|
-
* there has stated an intent — a name that resolves to nothing is already
|
|
2795
|
-
* `action-name-undefined`'s job, not this rule's.
|
|
2796
|
-
*
|
|
2797
|
-
* Scope note: this rule asks only "did anyone place this action?". It
|
|
2798
|
-
* deliberately does NOT check that a declared location is one a renderer
|
|
2799
|
-
* actually serves, nor that a view's named action belongs to that view's
|
|
2800
|
-
* object — distinct classes with their own rules. Cross-package placement (a
|
|
2801
|
-
* view in another installed package naming this action) is the one legitimate
|
|
2802
|
-
* miss, which is why this is a **warning**: like every other "declared but
|
|
2803
|
-
* does nothing" finding in this package (`validateSemanticRoles`,
|
|
2804
|
-
* `lintLivenessProperties`), it is high-signal and never fatal.
|
|
2805
|
-
*/
|
|
2806
3084
|
declare const ACTION_NO_PLACEMENT = "action-no-placement";
|
|
2807
3085
|
type ActionLocationsSeverity = 'error' | 'warning';
|
|
2808
3086
|
interface ActionLocationsFinding {
|
|
@@ -2819,12 +3097,12 @@ interface ActionLocationsFinding {
|
|
|
2819
3097
|
/** How to fix it. */
|
|
2820
3098
|
hint: string;
|
|
2821
3099
|
}
|
|
2822
|
-
type AnyRec$
|
|
3100
|
+
type AnyRec$i = Record<string, unknown>;
|
|
2823
3101
|
/**
|
|
2824
3102
|
* Flag every action that declares no placement and that no view places by
|
|
2825
3103
|
* name. Returns findings (empty = clean).
|
|
2826
3104
|
*/
|
|
2827
|
-
declare function validateActionLocations(stack: AnyRec$
|
|
3105
|
+
declare function validateActionLocations(stack: AnyRec$i): ActionLocationsFinding[];
|
|
2828
3106
|
|
|
2829
3107
|
/**
|
|
2830
3108
|
* Shared page-component traversal for the lint rules that inspect
|
|
@@ -2850,11 +3128,11 @@ declare function validateActionLocations(stack: AnyRec$h): ActionLocationsFindin
|
|
|
2850
3128
|
* author never wrote, so those pages are skipped here and covered by
|
|
2851
3129
|
* `validate-jsx-pages` / `validate-react-page-props` instead.
|
|
2852
3130
|
*/
|
|
2853
|
-
type AnyRec$
|
|
3131
|
+
type AnyRec$h = Record<string, unknown>;
|
|
2854
3132
|
/** A visited component plus everything needed to locate and bind it. */
|
|
2855
3133
|
interface WalkedComponent {
|
|
2856
3134
|
/** The component record itself. */
|
|
2857
|
-
component: AnyRec$
|
|
3135
|
+
component: AnyRec$h;
|
|
2858
3136
|
/** Config path, e.g. `pages[0].regions[1].components[2]`. */
|
|
2859
3137
|
path: string;
|
|
2860
3138
|
/**
|
|
@@ -2865,7 +3143,7 @@ interface WalkedComponent {
|
|
|
2865
3143
|
objectName?: string;
|
|
2866
3144
|
}
|
|
2867
3145
|
/** Is this page authored as `source` (so its `regions` must not be linted)? */
|
|
2868
|
-
declare function isSourceAuthoredPage(page: AnyRec$
|
|
3146
|
+
declare function isSourceAuthoredPage(page: AnyRec$h): boolean;
|
|
2869
3147
|
/**
|
|
2870
3148
|
* Walk every component on a page, depth-first, yielding each with its config
|
|
2871
3149
|
* path and resolved object binding. Source-authored pages yield nothing.
|
|
@@ -2902,7 +3180,7 @@ declare function isSourceAuthoredPage(page: AnyRec$g): boolean;
|
|
|
2902
3180
|
* descent is bounded by the document's own finite nesting, so the cap would only
|
|
2903
3181
|
* ever fire on acyclic input, which is precisely the input it must not truncate.
|
|
2904
3182
|
*/
|
|
2905
|
-
declare function walkPageComponents(page: AnyRec$
|
|
3183
|
+
declare function walkPageComponents(page: AnyRec$h, pagePath: string): WalkedComponent[];
|
|
2906
3184
|
|
|
2907
3185
|
/**
|
|
2908
3186
|
* object name → its DECLARED field-group keys.
|
|
@@ -2912,7 +3190,7 @@ declare function walkPageComponents(page: AnyRec$g, pagePath: string): WalkedCom
|
|
|
2912
3190
|
* data-dependent) finding from a reference to a group that was never declared.
|
|
2913
3191
|
* This index answers only the second question — the one with a closed oracle.
|
|
2914
3192
|
*
|
|
2915
|
-
* `fieldGroups` is an ARRAY on `ObjectSchema`, and `
|
|
3193
|
+
* `fieldGroups` is an ARRAY on `ObjectSchema`, and `recordsOf` additionally
|
|
2916
3194
|
* resolves the name-keyed map shape that raw (non-`defineStack`) metadata can
|
|
2917
3195
|
* carry, the same tolerance every other index in this package extends.
|
|
2918
3196
|
*/
|
|
@@ -3046,7 +3324,7 @@ interface PageFieldFinding {
|
|
|
3046
3324
|
hint: string;
|
|
3047
3325
|
}
|
|
3048
3326
|
|
|
3049
|
-
declare function validatePageFieldBindings(stack: AnyRec$
|
|
3327
|
+
declare function validatePageFieldBindings(stack: AnyRec$h): PageFieldFinding[];
|
|
3050
3328
|
|
|
3051
3329
|
declare const PAGE_VISUALIZATION_WITHOUT_BINDING = "page/visualization-without-binding";
|
|
3052
3330
|
type PageVisualizationSeverity = 'error' | 'warning';
|
|
@@ -3097,8 +3375,8 @@ interface VisualizationPredicate {
|
|
|
3097
3375
|
* that pin is the drift this table's whole purpose is to make loud.
|
|
3098
3376
|
*/
|
|
3099
3377
|
declare const OBJECTUI_DERIVATION_PREDICATES: readonly VisualizationPredicate[];
|
|
3100
|
-
type AnyRec$
|
|
3101
|
-
declare function validatePageVisualizationBindings(stack: AnyRec$
|
|
3378
|
+
type AnyRec$g = Record<string, unknown>;
|
|
3379
|
+
declare function validatePageVisualizationBindings(stack: AnyRec$g): PageVisualizationFinding[];
|
|
3102
3380
|
|
|
3103
3381
|
/** A key authored in `properties` that the type's props schema does not declare. */
|
|
3104
3382
|
declare const COMPONENT_PROPS_UNKNOWN_KEY = "component-props-unknown-key";
|
|
@@ -3124,7 +3402,7 @@ interface ComponentPropsFinding {
|
|
|
3124
3402
|
/** How to fix it. */
|
|
3125
3403
|
hint: string;
|
|
3126
3404
|
}
|
|
3127
|
-
declare function validateComponentProps(stack: AnyRec$
|
|
3405
|
+
declare function validateComponentProps(stack: AnyRec$h): ComponentPropsFinding[];
|
|
3128
3406
|
|
|
3129
3407
|
/** A component `type` inside a spec-reserved namespace that the vocabulary does not declare. */
|
|
3130
3408
|
declare const COMPONENT_TYPE_UNKNOWN = "component-type-unknown";
|
|
@@ -3141,7 +3419,7 @@ interface ComponentTypeFinding {
|
|
|
3141
3419
|
/** How to fix it. */
|
|
3142
3420
|
hint: string;
|
|
3143
3421
|
}
|
|
3144
|
-
declare function validateComponentTypes(stack: AnyRec$
|
|
3422
|
+
declare function validateComponentTypes(stack: AnyRec$h): ComponentTypeFinding[];
|
|
3145
3423
|
|
|
3146
3424
|
/**
|
|
3147
3425
|
* [ADR-0021 — semantic layer] Chart-binding integrity for the surfaces the
|
|
@@ -3178,6 +3456,132 @@ declare function validateComponentTypes(stack: AnyRec$g): ComponentTypeFinding[]
|
|
|
3178
3456
|
* rule has no business loading. It is checked by `validate-react-page-props`
|
|
3179
3457
|
* instead, against the naming convention `chartAggregateResultKeys`
|
|
3180
3458
|
* (`@objectstack/spec/ui`) now pins down (#3701).
|
|
3459
|
+
*
|
|
3460
|
+
* ## Which positions are BINDINGS, and which are presentation (#15575)
|
|
3461
|
+
*
|
|
3462
|
+
* `chart-measure-unknown`'s message names a QUERY consequence — *"this series
|
|
3463
|
+
* comes back empty"* — and that is only true where the position feeds the
|
|
3464
|
+
* dataset query. Read at the pinned `@object-ui` revision (`.objectui-sha`),
|
|
3465
|
+
* the three surfaces do not agree, so the tier and the consequence are per
|
|
3466
|
+
* POSITION rather than per rule:
|
|
3467
|
+
*
|
|
3468
|
+
* - **Report charts.** The chart runs its OWN query out of the two axis
|
|
3469
|
+
* strings — `useDatasetRows(dataset, [xAxis], [yAxis], …)` in
|
|
3470
|
+
* `plugin-report/src/DatasetReportRenderer.tsx`, and in that file's own
|
|
3471
|
+
* words *"the embedded chart queries only `chart.xAxis` × `chart.yAxis`"*.
|
|
3472
|
+
* So `chart.yAxis` IS the binding and keeps `error`. `chart.series[]` is
|
|
3473
|
+
* not: it is *"The author's per-chart override for ONE measure's display
|
|
3474
|
+
* name — the entry of `chart.series[]` whose `name` IS that measure"*,
|
|
3475
|
+
* lowered through `mergeAuthoredSeries`, for which *"an authored entry
|
|
3476
|
+
* naming a measure that is NOT in the dataset selection is **ignored** —
|
|
3477
|
+
* membership belongs to the dataset"* (`@object-ui/core`
|
|
3478
|
+
* `src/utils/chart-presentation.ts`).
|
|
3479
|
+
* - **List-view charts.** `ListChartConfigSchema` is a STRICT object of
|
|
3480
|
+
* `chartType` / `dataset` / `dimensions` / `values`: it declares no
|
|
3481
|
+
* `series` and no `yAxis`, so this rule has no presentation position on
|
|
3482
|
+
* that surface at all. Its one measure position is `values[]`, which
|
|
3483
|
+
* `app-shell/src/views/ObjectView.tsx` hands to the chart component as the
|
|
3484
|
+
* dataset measures (and synthesises the series list FROM). Query binding,
|
|
3485
|
+
* `error`, unchanged.
|
|
3486
|
+
* - **Dataset-bound page chart components.** `plugin-charts/src/ObjectChart.tsx`
|
|
3487
|
+
* queries `{ dimensions: schema.dimensions, measures: schema.values }` and
|
|
3488
|
+
* then REPLACES the authored series wholesale —
|
|
3489
|
+
* `{ ...schema, data, xAxisKey, series: datasetChart.series }`, one derived
|
|
3490
|
+
* entry per selected measure. An authored `properties.series[].name` reaches
|
|
3491
|
+
* the renderer not at all, and an authored `properties.yAxis[].field` is
|
|
3492
|
+
* inert for the same reason (`normalizeChartSchema` synthesises series from
|
|
3493
|
+
* `yAxis[].field` only when there are none, which on this surface means an
|
|
3494
|
+
* empty `values` — a chart with no measures to plot either way). Both are
|
|
3495
|
+
* presentation; `dimensions` / `values` are the binding.
|
|
3496
|
+
*
|
|
3497
|
+
* So the presentation positions drop to `warning` and state what actually
|
|
3498
|
+
* happens, which is the resolution the maintainer ruling on
|
|
3499
|
+
* `chart-field-unknown` reached for the same question one rule over (see "The
|
|
3500
|
+
* three refused binding keys" in `validate-widget-bindings.ts`). Two things
|
|
3501
|
+
* follow that differ from that sibling, and are worth stating rather than
|
|
3502
|
+
* leaving to be re-derived:
|
|
3503
|
+
*
|
|
3504
|
+
* - **There is no per-position suppression here.** `suppressWarnings` is
|
|
3505
|
+
* declared on the dashboard WIDGET only (`spec/src/ui/dashboard.zod.ts`),
|
|
3506
|
+
* and none of these three surfaces carries the key. A `warning` is advisory
|
|
3507
|
+
* (the consumers split on `severity === 'error'`) but cannot be silenced
|
|
3508
|
+
* individually; declaring the key on these surfaces would be a schema
|
|
3509
|
+
* change, which this rule has no standing to make.
|
|
3510
|
+
* - **The page surface's axis refs and series refs are separate limbs.** They
|
|
3511
|
+
* used to be concatenated into one `series` array before the measure walk,
|
|
3512
|
+
* so every `yAxis[].field` took the SERIES message. Reading both shapes on
|
|
3513
|
+
* that surface is deliberate (the props bag mixes them); giving them one
|
|
3514
|
+
* message was not — the pin refuses the two for different reasons, so they
|
|
3515
|
+
* now carry different sentences.
|
|
3516
|
+
*
|
|
3517
|
+
* `chart-axis-not-selected` (declared measure, outside the selection) rides the
|
|
3518
|
+
* same walk and took the same one-size sentence — *"the query does not return
|
|
3519
|
+
* it, so the series plots nothing"*. That is the truth at a query position and
|
|
3520
|
+
* not at a presentation one, where no series is derived for the name in the
|
|
3521
|
+
* first place, so its consequence is per position too.
|
|
3522
|
+
*
|
|
3523
|
+
* ## Which SET `chart-axis-not-selected` resolves against (#15734)
|
|
3524
|
+
*
|
|
3525
|
+
* The consequence is per POSITION; the selection it is measured against is per
|
|
3526
|
+
* SURFACE — and on the report surface that selection is not `report.values`.
|
|
3527
|
+
* At the same pinned revision `DatasetReportRenderer.tsx` runs
|
|
3528
|
+
* `useDatasetRows(dataset, plan.kind === 'series' && xAxis ? [xAxis] : [],
|
|
3529
|
+
* wantsQuery && yAxis ? [yAxis] : [], …)` and derives the plotted series with
|
|
3530
|
+
* `buildChartSeries(…, [xAxis], [yAxis], …)` — *"the selection is exactly one
|
|
3531
|
+
* dimension × one measure, so this takes the helper's single-dimension branch
|
|
3532
|
+
* and returns ONE series"*. `report.values` is the selection of the TABLE
|
|
3533
|
+
* beneath the chart; the chart's own is the axis pair. Two things follow:
|
|
3534
|
+
*
|
|
3535
|
+
* - **Nothing to report at the report `chart.yAxis`.** That position IS the
|
|
3536
|
+
* chart's query, so it cannot fail to select itself. The warning that fired
|
|
3537
|
+
* for a declared measure outside `report.values` stated a query consequence
|
|
3538
|
+
* its own pin refutes: the chart asks for exactly that measure and plots
|
|
3539
|
+
* it. `chart-measure-unknown` at that position is untouched — an UNDECLARED
|
|
3540
|
+
* measure still returns no column, and still gates.
|
|
3541
|
+
* - **`chart.series[].name` resolves against the singleton `{ chart.yAxis }`.**
|
|
3542
|
+
* The override is paired with a DERIVED series and the chart derives one,
|
|
3543
|
+
* so that singleton — not `report.values` — is the set an entry can land
|
|
3544
|
+
* on. An entry naming `chart.yAxis` lands however the table is selected;
|
|
3545
|
+
* one naming any other declared measure lands on nothing.
|
|
3546
|
+
*
|
|
3547
|
+
* The list-view and page-component surfaces keep `values`: there it IS the
|
|
3548
|
+
* measure set the query asks for, so the existing resolution is correct.
|
|
3549
|
+
*
|
|
3550
|
+
* ## What a REPORT binds, chart or no chart (#16105)
|
|
3551
|
+
*
|
|
3552
|
+
* A report is dataset-bound in its own right — `ReportSchema` requires
|
|
3553
|
+
* `dataset` + `values` on every non-`joined` report and declares `rows` (the
|
|
3554
|
+
* down axis) and `columns` (the across axis a `matrix` pivots on, ADR-0021 D2)
|
|
3555
|
+
* as dimension names "from the dataset". The chart is optional decoration on
|
|
3556
|
+
* top of that binding, not the binding itself.
|
|
3557
|
+
*
|
|
3558
|
+
* The walk did not read it that way. Every report position reached the resolver
|
|
3559
|
+
* through one closure that opened `if (!isRec(chart)) return`, and that closure
|
|
3560
|
+
* was the only site `report.dataset` was ever passed to, so:
|
|
3561
|
+
*
|
|
3562
|
+
* - a report authored WITHOUT a chart was not checked at all — an unresolvable
|
|
3563
|
+
* `dataset`, an unknown `rows`/`columns` dimension and an unknown `values`
|
|
3564
|
+
* measure all published clean; and
|
|
3565
|
+
* - `rows`/`columns` were passed to the resolver on NO report, charted or not.
|
|
3566
|
+
* On one and the same charted report, `values` was resolved and the
|
|
3567
|
+
* dimension selection beside it was not.
|
|
3568
|
+
*
|
|
3569
|
+
* So the dataset is resolved once per report and once per block — before the
|
|
3570
|
+
* chart question is asked — and fed to two groups of positions: the report's
|
|
3571
|
+
* own selection (`rows`/`columns` → `chart-dimension-unknown`, `values` →
|
|
3572
|
+
* `chart-measure-unknown`) and, when a chart is present, its axis refs
|
|
3573
|
+
* exactly as before. Not a second "chartless reports too" pass after the early
|
|
3574
|
+
* return: one path, entered unconditionally, with the chart as the branch it
|
|
3575
|
+
* always was. Which is also why an unresolvable dataset on a charted report is
|
|
3576
|
+
* still ONE finding — `resolveDataset` runs once per surface, not once per
|
|
3577
|
+
* group.
|
|
3578
|
+
*
|
|
3579
|
+
* `rows`/`columns` take `chart-dimension-unknown` rather than an id of their
|
|
3580
|
+
* own: the position is a dataset DIMENSION reference resolved against the
|
|
3581
|
+
* dataset's declared dimensions, which is what that rule already means on the
|
|
3582
|
+
* list-view and page surfaces, and the spec's own words for the two report
|
|
3583
|
+
* keys are "down axis" and "across" — so the rule's existing sentence about an
|
|
3584
|
+
* axis rendering with no categories is true where it now fires.
|
|
3181
3585
|
*/
|
|
3182
3586
|
declare const CHART_DIMENSION_UNKNOWN = "chart-dimension-unknown";
|
|
3183
3587
|
declare const CHART_MEASURE_UNKNOWN = "chart-measure-unknown";
|
|
@@ -3198,7 +3602,7 @@ interface ChartBindingFinding {
|
|
|
3198
3602
|
hint: string;
|
|
3199
3603
|
}
|
|
3200
3604
|
|
|
3201
|
-
declare function validateChartBindings(stack: AnyRec$
|
|
3605
|
+
declare function validateChartBindings(stack: AnyRec$h): ChartBindingFinding[];
|
|
3202
3606
|
|
|
3203
3607
|
/** An `include[]` entry that does not name a joinable relationship path. */
|
|
3204
3608
|
declare const DATASET_INCLUDE_UNKNOWN = "dataset-include-unknown";
|
|
@@ -3223,14 +3627,14 @@ interface DatasetRefFinding {
|
|
|
3223
3627
|
/** How to fix it. */
|
|
3224
3628
|
hint: string;
|
|
3225
3629
|
}
|
|
3226
|
-
type AnyRec$
|
|
3630
|
+
type AnyRec$f = Record<string, unknown>;
|
|
3227
3631
|
/**
|
|
3228
3632
|
* Validate every ADR-0021 dataset's references against the object graph.
|
|
3229
3633
|
* Returns findings (empty = clean). Pure `(stack) => Finding[]`; no I/O, and
|
|
3230
3634
|
* safe on both the schema-parsed stack and the raw config the `lint` path
|
|
3231
3635
|
* carries.
|
|
3232
3636
|
*/
|
|
3233
|
-
declare function validateDatasetReferences(stack: AnyRec$
|
|
3637
|
+
declare function validateDatasetReferences(stack: AnyRec$f): DatasetRefFinding[];
|
|
3234
3638
|
|
|
3235
3639
|
/**
|
|
3236
3640
|
* Field types that address ANOTHER object, so a `.<hop>` through one is a join
|
|
@@ -3481,11 +3885,11 @@ declare const VALIDATION_RULE_SCHEMA_UNCOMPILABLE = "validation-rule-json-schema
|
|
|
3481
3885
|
* still says the same thing.
|
|
3482
3886
|
*/
|
|
3483
3887
|
declare const RUNTIME_AJV_OPTIONS: Options;
|
|
3484
|
-
type AnyRec$
|
|
3888
|
+
type AnyRec$e = Record<string, unknown>;
|
|
3485
3889
|
/** One authored validation rule, located for a finding. */
|
|
3486
3890
|
interface WalkedValidationRule {
|
|
3487
3891
|
/** The rule record itself — a top-level entry, or a `conditional` branch. */
|
|
3488
|
-
rule: AnyRec$
|
|
3892
|
+
rule: AnyRec$e;
|
|
3489
3893
|
/** The declaring object's `name`, or `(unnamed object)`. */
|
|
3490
3894
|
objectName: string;
|
|
3491
3895
|
/** The nesting-aware rule name as prose: `'outer' → 'inner'`. */
|
|
@@ -3569,12 +3973,61 @@ interface NavAccessFinding {
|
|
|
3569
3973
|
/** How to fix it. */
|
|
3570
3974
|
hint: string;
|
|
3571
3975
|
}
|
|
3572
|
-
type AnyRec$
|
|
3976
|
+
type AnyRec$d = Record<string, unknown>;
|
|
3573
3977
|
/**
|
|
3574
3978
|
* Validate that every object a stack's navigation exposes is readable by at
|
|
3575
3979
|
* least one permission set the stack declares. Returns findings (empty = clean).
|
|
3576
3980
|
*/
|
|
3577
|
-
declare function validateNavAccess(stack: AnyRec$
|
|
3981
|
+
declare function validateNavAccess(stack: AnyRec$d): NavAccessFinding[];
|
|
3982
|
+
|
|
3983
|
+
declare const FIELD_NO_CONSUMERS = "field-no-consumers";
|
|
3984
|
+
type FieldConsumerSeverity = 'warning';
|
|
3985
|
+
/** Why the field is reported: carriers only, or nothing at all. */
|
|
3986
|
+
type FieldConsumerVerdict = 'inert' | 'carrier-only';
|
|
3987
|
+
interface FieldConsumerFinding {
|
|
3988
|
+
/** Always `warning` — a consumer may live outside the stack (see module note). */
|
|
3989
|
+
severity: FieldConsumerSeverity;
|
|
3990
|
+
/** Diagnostic rule id. */
|
|
3991
|
+
rule: string;
|
|
3992
|
+
/** Human-readable location, e.g. `object "crm_product" · field "tax_rate"`. */
|
|
3993
|
+
where: string;
|
|
3994
|
+
/** Config path of the DECLARATION, e.g. `objects[3].fields.tax_rate` (map shape) or `objects[3].fields[2]` (array shape). */
|
|
3995
|
+
path: string;
|
|
3996
|
+
/** What is wrong. */
|
|
3997
|
+
message: string;
|
|
3998
|
+
/** How to fix it. */
|
|
3999
|
+
hint: string;
|
|
4000
|
+
/** The declaring object. */
|
|
4001
|
+
object: string;
|
|
4002
|
+
/** The field name. */
|
|
4003
|
+
field: string;
|
|
4004
|
+
/** `carrier-only` when carrier sites exist, `inert` when no site of any kind names the field. */
|
|
4005
|
+
verdict: FieldConsumerVerdict;
|
|
4006
|
+
/** Config paths of the carrier sites a removal must clean (empty for `inert`). */
|
|
4007
|
+
carriers: string[];
|
|
4008
|
+
/** The stack roots this verdict was measured over — consumer roots then carrier roots. */
|
|
4009
|
+
rootsScanned: readonly string[];
|
|
4010
|
+
}
|
|
4011
|
+
type AnyRec$c = Record<string, unknown>;
|
|
4012
|
+
/**
|
|
4013
|
+
* Roots whose contents can CONSUME a field, walked with an object context.
|
|
4014
|
+
* `objects` is here for what an object carries besides its field map —
|
|
4015
|
+
* formulas, roll-ups, validations, built-in list views, hooks, actions,
|
|
4016
|
+
* indexes, `highlightFields`, `searchableFields`. Order is report order.
|
|
4017
|
+
*/
|
|
4018
|
+
declare const CONSUMER_ROOTS: readonly string[];
|
|
4019
|
+
/**
|
|
4020
|
+
* Roots whose contents carry a field without reading it. A locale row is a
|
|
4021
|
+
* label for a field, not a consumer of one; a seed VALUE nothing reads is the
|
|
4022
|
+
* shape being hunted; an import column and a field-level permission grant are
|
|
4023
|
+
* customer-facing surfaces a removal must clean, not evidence of a reader.
|
|
4024
|
+
*/
|
|
4025
|
+
declare const CARRIER_ROOTS: readonly string[];
|
|
4026
|
+
/**
|
|
4027
|
+
* Report every declared field that nothing in the stack reads or displays.
|
|
4028
|
+
* Returns findings (empty = clean). Pure; safe on pre- or post-parse stacks.
|
|
4029
|
+
*/
|
|
4030
|
+
declare function validateFieldConsumers(stack: AnyRec$c): FieldConsumerFinding[];
|
|
3578
4031
|
|
|
3579
4032
|
declare const TRANSLATION_TARGET_UNKNOWN = "translation-target-unknown";
|
|
3580
4033
|
declare const TRANSLATION_OPTION_KEY_UNKNOWN = "translation-option-key-unknown";
|
|
@@ -3623,33 +4076,6 @@ type AnyRec$a = Record<string, unknown>;
|
|
|
3623
4076
|
*/
|
|
3624
4077
|
declare function validateTranslatableSections(stack: AnyRec$a): TranslatableSectionFinding[];
|
|
3625
4078
|
|
|
3626
|
-
/**
|
|
3627
|
-
* [ADR-0064 §3] Skill ↔ agent surface affinity (issue #3820).
|
|
3628
|
-
*
|
|
3629
|
-
* An agent binds a product surface (`'ask'` | `'build'`, ADR-0063 §1) and a
|
|
3630
|
-
* skill declares which surface it belongs to (`'ask'` | `'build'` | `'both'`,
|
|
3631
|
-
* ADR-0063 §3). A skill may only attach to an agent whose surface it matches —
|
|
3632
|
-
* `'both'` attaches to either. The runtime treats a violation as a FAST LOAD
|
|
3633
|
-
* ERROR: `resolveActiveSkills()` throws on the first incompatible binding, so
|
|
3634
|
-
* an agent shipping one mismatched skill reference fails at **chat time** with
|
|
3635
|
-
* a 500 — after parse, after validate, after deploy.
|
|
3636
|
-
*
|
|
3637
|
-
* Both sides of the check are declared in the same stack, so the contradiction
|
|
3638
|
-
* is statically provable and this rule carries severity **error** with zero
|
|
3639
|
-
* false positives by construction. Both sides default to `'ask'` when the
|
|
3640
|
-
* `surface` field is absent (mirroring the runtime's defaults), so the rule is
|
|
3641
|
-
* safe on the raw/normalized config the `lint` path carries as well as the
|
|
3642
|
-
* schema-parsed stack.
|
|
3643
|
-
*
|
|
3644
|
-
* Scope note: this rule deliberately does NOT check that `agent.skills[]`
|
|
3645
|
-
* names resolve at all. Kernel skills (`schema_reader`, the `ask`/`build`
|
|
3646
|
-
* bundles) are runtime-registered and statically invisible, and whether
|
|
3647
|
-
* app-stack tool/skill namespaces get a platform-name registry is an open
|
|
3648
|
-
* decision (#3820 D0/D2) — resolving names against `stack.skills` alone would
|
|
3649
|
-
* flag every kernel-skill reference. An unresolved name is therefore skipped
|
|
3650
|
-
* here; only a reference that resolves in-stack AND contradicts the affinity
|
|
3651
|
-
* contract is reported.
|
|
3652
|
-
*/
|
|
3653
4079
|
declare const AI_SKILL_SURFACE_MISMATCH = "ai-skill-surface-mismatch";
|
|
3654
4080
|
type AiSurfaceAffinitySeverity = 'error' | 'warning';
|
|
3655
4081
|
interface AiSurfaceAffinityFinding {
|
|
@@ -3696,78 +4122,6 @@ type AnyRec$8 = Record<string, unknown>;
|
|
|
3696
4122
|
*/
|
|
3697
4123
|
declare function validateAiToolReferences(stack: AnyRec$8): AiToolRefFinding[];
|
|
3698
4124
|
|
|
3699
|
-
/**
|
|
3700
|
-
* [ADR-0063 §2] `stack.agents` is a platform-internal slot (issue #3820).
|
|
3701
|
-
*
|
|
3702
|
-
* ADR-0063 §2 withdrew tenant/app-package custom agents: the kernel ships
|
|
3703
|
-
* exactly two agents (`ask`, `build`), the surface the user is in binds one,
|
|
3704
|
-
* and third parties extend the platform by authoring **skills**, never
|
|
3705
|
-
* `*.agent.ts`. The `agent` metadata type carries the decision
|
|
3706
|
-
* (`allowRuntimeCreate: false, allowOrgOverride: false`), and the runtime
|
|
3707
|
-
* enforces it on both paths — `listAgents()` filters non-platform records out
|
|
3708
|
-
* of the catalog, and `loadAgent()` refuses them outright (cloud#904), so a
|
|
3709
|
-
* stack-authored agent 404s on chat and cannot be pinned via
|
|
3710
|
-
* `app.defaultAgent`.
|
|
3711
|
-
*
|
|
3712
|
-
* What was missing is the AUTHORING-time signal. `defineStack` still accepts
|
|
3713
|
-
* an `agents` array, so an app package could declare agents that parse,
|
|
3714
|
-
* validate, and build into the artifact — and then do nothing at runtime.
|
|
3715
|
-
* HotCRM shipped two of them for months. That is the ADR-0078 shape this rule
|
|
3716
|
-
* closes: loud at the producer, tolerant at the consumer (Prime Directive
|
|
3717
|
-
* #12).
|
|
3718
|
-
*
|
|
3719
|
-
* Severity is **warning**, not error, for one reason: the platform's own
|
|
3720
|
-
* packages legitimately author agent records, and this rule cannot tell a
|
|
3721
|
-
* platform package from an app package by reading the stack alone. A warning
|
|
3722
|
-
* that names the runtime consequence is honest for both readers; the runtime
|
|
3723
|
-
* is what actually gates. Deliberately NOT a Zod refine — an existing stack
|
|
3724
|
-
* must keep parsing (ADR-0078 non-goal #1).
|
|
3725
|
-
*
|
|
3726
|
-
* ## The value half (issue #6041)
|
|
3727
|
-
*
|
|
3728
|
-
* The rule above catches a stack that *declares* a withdrawn agent record.
|
|
3729
|
-
* It never looked at `app.defaultAgent` — a plain
|
|
3730
|
-
* `SnakeCaseIdentifierSchema` string, so any snake_case value parses, builds,
|
|
3731
|
-
* and passes `os:check` even when it names nothing the runtime will ever
|
|
3732
|
-
* resolve. #5985 measured the blind spot directly: replaying the bad example
|
|
3733
|
-
* `defaultAgent: 'sales_copilot'` left `check:skill-examples` at 208 green,
|
|
3734
|
-
* EXIT=0. `app.defaultAgent` silently falls back to the platform default at
|
|
3735
|
-
* runtime (ADR-0063 §1) instead of crashing, which is why this limb is
|
|
3736
|
-
* **warning**, not error, same as the rule above — the maintainer ruling on
|
|
3737
|
-
* #6041 (2026-08-07, reaffirmed 2026-08-09) is option A: add the value check
|
|
3738
|
-
* at warning tier, reusing `PLATFORM_AGENT_NAMES` rather than narrowing the
|
|
3739
|
-
* schema to an enum (a breaking authoring change ADR-0063 already walked
|
|
3740
|
-
* back once).
|
|
3741
|
-
*
|
|
3742
|
-
* ## Why the value limb no longer reads the same roster (issue #14461)
|
|
3743
|
-
*
|
|
3744
|
-
* `PLATFORM_AGENT_NAMES` holds FOUR names, and reusing it for the value limb
|
|
3745
|
-
* meant this gate accepted `defaultAgent: 'metadata_assistant'` — the exact
|
|
3746
|
-
* spelling `skills/objectstack-ai` tells authors is "not vocabulary". The
|
|
3747
|
-
* platform then taught it from its own only live example: `studio.app.ts`
|
|
3748
|
-
* pinned the alias. So an AI author copying the one working example in the
|
|
3749
|
-
* repo wrote the forbidden spelling and this rule waved it through — the
|
|
3750
|
-
* silent-tolerance shape ADR-0078 exists to close, committed by the gate
|
|
3751
|
-
* itself.
|
|
3752
|
-
*
|
|
3753
|
-
* The maintainer ruling on #14461 (2026-09-03) re-pins Studio to `build` and
|
|
3754
|
-
* SPLITS the two limbs' rosters, keeping both of #6041's operative decisions
|
|
3755
|
-
* intact (warning tier, no Zod enum):
|
|
3756
|
-
*
|
|
3757
|
-
* - the DECLARATION limb still reads all four names. Its question is "does
|
|
3758
|
-
* this record shadow a platform record?", and declaring `metadata_assistant`
|
|
3759
|
-
* shadows `build` through the alias exactly as declaring `build` does. That
|
|
3760
|
-
* judgement is unchanged.
|
|
3761
|
-
* - the VALUE limb reads `CANONICAL_AGENT_NAMES` only, and a legacy alias
|
|
3762
|
-
* gets its own rule id and wording ({@link DEFAULT_AGENT_LEGACY_ALIAS}).
|
|
3763
|
-
* Its question is "is this the right thing to WRITE?", and the answer for
|
|
3764
|
-
* an alias is no even though it resolves.
|
|
3765
|
-
*
|
|
3766
|
-
* The alias limb stays `warning`, not `error`, and for a sharper reason than
|
|
3767
|
-
* the roster limb: an aliased pin is not broken. It resolves, the app gets the
|
|
3768
|
-
* agent it meant, and nothing a user can see is wrong — which is precisely why
|
|
3769
|
-
* the signal has to be an authoring-time nudge rather than a build break.
|
|
3770
|
-
*/
|
|
3771
4125
|
declare const AGENT_AUTHORING_WITHDRAWN = "agent-authoring-withdrawn";
|
|
3772
4126
|
/** `app.defaultAgent` names something outside the platform agent roster. */
|
|
3773
4127
|
declare const DEFAULT_AGENT_OUTSIDE_ROSTER = "default-agent-outside-roster";
|
|
@@ -4135,21 +4489,6 @@ declare const VIEW_REF_FORM_TARGET_KIND = "view-ref-form-target-kind";
|
|
|
4135
4489
|
declare const VIEW_REF_NAV_VIEW_MISSING = "view-ref-nav-view-missing";
|
|
4136
4490
|
declare function lintViewRefs(stack: AnyRec): ViewRefFinding[];
|
|
4137
4491
|
|
|
4138
|
-
/**
|
|
4139
|
-
* Data-model best-practice lint rules.
|
|
4140
|
-
*
|
|
4141
|
-
* These rules encode the relationship / master-detail / roll-up conventions the
|
|
4142
|
-
* platform ships (see the objectstack-data and objectstack-ui skills, ADR-0035).
|
|
4143
|
-
* They run over the normalized object set and flag anti-patterns that an
|
|
4144
|
-
* author — human OR an AI generator — commonly produces. They are intentionally
|
|
4145
|
-
* heuristic: structural problems are `error`, likely-wrong choices are
|
|
4146
|
-
* `warning`, and "you probably want this" nudges are `suggestion`. None of them
|
|
4147
|
-
* block on a judgement call.
|
|
4148
|
-
*
|
|
4149
|
-
* The same rules double as the automated rubric for the metadata-generation
|
|
4150
|
-
* eval (see `score.ts`): a generated stack scores well exactly when it is
|
|
4151
|
-
* schema-valid AND lint-clean here.
|
|
4152
|
-
*/
|
|
4153
4492
|
type Severity = 'error' | 'warning' | 'suggestion';
|
|
4154
4493
|
interface LintIssue {
|
|
4155
4494
|
severity: Severity;
|
|
@@ -4354,4 +4693,4 @@ declare function auditPageExpressionEnvelopes(page: unknown, pageLabel: string):
|
|
|
4354
4693
|
/** Render findings as the actionable red an author reads in CI. */
|
|
4355
4694
|
declare function renderBareExpressionFindings(findings: readonly BareExpressionFinding[]): string;
|
|
4356
4695
|
|
|
4357
|
-
export { ACTION_API_UPDATE_READONLY_WHEN_FIELD, ACTION_BODY_SOURCE_UNPARSEABLE, ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_BODY_WRITE_UNPROVISIONED_ANCHOR, 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 BareExpressionFinding, 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, COMPONENT_TYPE_UNKNOWN, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, type CheckedParse, type CheckedParseOptions, type ComponentPropsFinding, type ComponentPropsSeverity, type ComponentTypeFinding, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_NOT_INCLUDED, DASHBOARD_FILTER_FIELD_UNKNOWN, DASHBOARD_FILTER_FIELD_UNPROVISIONED, DATASET_FIELD_NOT_INCLUDED, DATASET_FIELD_UNKNOWN, DATASET_FILTER_FIELD_UNKNOWN, DATASET_INCLUDE_UNKNOWN, DEFAULT_AGENT_LEGACY_ALIAS, DEFAULT_AGENT_OUTSIDE_ROSTER, type DashboardActionRefFinding, type DashboardActionRefSeverity, type DatasetRefFinding, type DatasetRefSeverity, type EmptyCombinatorFinding, type EmptyCombinatorSeverity, type EnvelopeAuditDoor, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, FIELD_GROUP_EMPTY, FIELD_GROUP_SHADOWED, FIELD_GROUP_UNDECLARED, FIELD_RULE_BOUND_ROOTS, FILTER_EMPTY_COMBINATOR, FILTER_EMPTY_NODE, FILTER_PRESET_COMPARAND, 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_LOOP_BODY_UNCONTAINED, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_MULTI_WRITE_UNFILTERED, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_NODE_WRITE_UNPROVISIONED_ANCHOR, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_FIELD_UNPROVISIONED, 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_TRIGGER_UNROUTABLE, FLOW_TRY_CATCH_WITHOUT_CATCH, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, FORM_SECTION_GROUP_UNKNOWN, type FieldPathAccount, type FieldPathVerdict, type FilterFieldKey, 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, type GraphField, type GraphObject, HOOK_API_UPDATE_READONLY_FIELD, HOOK_API_UPDATE_READONLY_WHEN_FIELD, HOOK_BODY_SOURCE_UNPARSEABLE, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, HOOK_BODY_WRITE_UNPROVISIONED_ANCHOR, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FIELD_DOTTED, LIST_VIEW_FIELD_UNKNOWN, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, LIVENESS_LIVE_ELSEWHERE_PROPERTY, LIVENESS_PLANNED_PROPERTY, type LintIssue, type ListViewFieldRefFinding, type ListViewFieldRefSeverity, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, type LocatedLintIssue, MANAGED_API_METHOD_UNAFFORDABLE, MAX_SCHEMA_WALK_DEPTH, MEASURE_AGGREGATE_INCOHERENT, type ManagedApiMethodFinding, NAV_OBJECT_UNGRANTED, NAV_OBJECT_UNSERVABLE, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavObjectServabilityFinding, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECTUI_DERIVATION_PREDICATES, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, OPEN_VOCABULARY_PROBES, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectGraph, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_FIELD_UNPROVISIONED, PAGE_SECTION_GROUP_UNKNOWN, PAGE_SOURCE_CLASSNAME, PAGE_VISUALIZATION_WITHOUT_BINDING, PARSE_FAILURE_HINT, PREDICATE_PATH_UNRESOLVED, PREDICATE_PATH_UNROOTED, PREDICATE_RHS_PATH_SHAPED, PRE_SEAL_PHASES, type PageEnvelopeAudit, type PageFieldFinding, type PageFieldSeverity, type PageVisualizationFinding, type PageVisualizationSeverity, type PredicatePathFinding, type PredicatePathOptions, type PredicatePathSeverity, type PresetComparandFinding, type PresetComparandSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_DRILLDOWN_INVALID, REACT_CHART_FIELD_UNKNOWN, REACT_CHART_FIELD_UNPROVISIONED, REACT_PAGE_SOURCE_UNPARSEABLE, REACT_PROP_DEPRECATED, READONLY_ACTION_WRITE_EXCLUSIONS, READONLY_ACTION_WRITE_PATTERN_IDS, READONLY_HOOK_WRITE_EXCLUSIONS, READONLY_HOOK_WRITE_PATTERN_IDS, REFERENCE_INTEGRITY_RULES, RELATIONSHIP_FIELD_TYPES, RLS_PREDICATE_OVER_BUDGET, RLS_PREDICATE_UNENFORCEABLE, RLS_PREDICATE_UNPARSEABLE, RUNTIME_AJV_OPTIONS, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyActionWriteFinding, type ReadonlyActionWriteSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type ReadonlyHookWriteFinding, type ReadonlyHookWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, type RlsPredicateFinding, type RlsPredicateSeverity, type RuleCompilabilityFinding, type RuleCompilabilitySeverity, type RuleSchemaFormatFinding, type RuleSchemaFormatSeverity, SEAL_MARKERS, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNPROVISIONED, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_CBP_AMBIGUOUS_RELATION, SECURITY_CBP_NO_RELATION, 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, SEMANTIC_ROLE_FIELD_UNPROVISIONED, SHARING_RULE_OBJECT_CONTROLLED_BY_PARENT, SHARING_RULE_OBJECT_NOT_SHAREABLE, SHARING_RULE_RUNTIME_VARIABLE_CONDITION, SHARING_RULE_UNLOWERABLE_CONDITION, SORT_FIELD_UNKNOWN, SORT_FIELD_UNPROVISIONED, SORT_FIELD_UNSORTABLE, STARTUP_OPEN_VOCABULARY_VERDICT, STARTUP_SOURCE_UNPARSEABLE, STARTUP_VERDICT_ASSERTIVE_WORDING, STARTUP_VERDICT_HINT, 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 SectionGroupFinding, type SectionGroupRef, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SharingRuleEnforceabilityFinding, type SharingRuleEnforceabilitySeverity, type SortableFieldFinding, type SortableFieldSeverity, type SourceParseFailure, type SourceStyleFinding, type SourceStyleSeverity, type StartupRegistryVerdictFinding, type StartupRegistryVerdictOptions, type StartupRegistryVerdictSeverity, 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_PAGE_UNRESOLVED, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VIEW_REF_NAV_VIEW_MISSING, VISIBILITY_BARE_IDENTIFIER, VISIBILITY_PREDICATE_OVER_BUDGET, VISIBILITY_PREDICATE_SYNTAX, VISIBILITY_PREDICATE_UNKNOWN_FUNCTION, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewPageRefFinding, type ViewPageRefSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, type VisualizationPredicate, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_FILTER_FIELD_NOT_INCLUDED, WIDGET_FILTER_FIELD_UNKNOWN, WIDGET_LEGACY_ANALYTICS_SHAPE, WIDGET_LEGACY_ANALYTICS_UNRENDERABLE, WIDGET_MEASURE_UNKNOWN, WIDGET_SORTBY_UNSELECTED, type WalkedComponent, type WalkedValidationRule, type WidgetBindingFinding, type WidgetBindingSeverity, auditPageExpressionEnvelopes, authorWarnedProperties, buildAccessMatrix, checkSectionGroupRefs, checkSortDeclaration, describeFieldPathVerdict, describeParseFailure, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, fieldRuleRootIssue, findStartupRegistryVerdicts, findUnguardedNullableOperands, indexObjectFieldGroups, indexObjectGraph, isSourceAuthoredPage, isUnjudgeable, joinablePrefixes, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLegacyOrganizationComposites, lintLivenessProperties, lintUniqueDeclarations, lintUnscopedDeclaredIndexes, lintViewRefs, listNames, nearestName, nearestRegisteredFormat, nullGuardMessage, renderBareExpressionFindings, resolveFieldPath, sectionGroupRefs, suggestName, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateComponentProps, validateComponentTypes, validateDashboardActionRefs, validateDatasetReferences, validateEmptyCombinators, validateFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewFieldRefs, validateListViewMode, validateManagedApiMethods, validateNavAccess, validateNavObjectServability, validateNavTargetRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validatePageVisualizationBindings, validatePredicatePathRefs, validatePresetComparands, validateReactPageProps, validateReactPages, validateReadonlyActionWrites, validateReadonlyFlowWrites, validateReadonlyHookWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateRlsPredicateEnforceability, validateRuleCompilability, validateRuleSchemaFormats, validateSearchableFields, validateSecurityPosture, validateSecurityRoleWord, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateSharingRuleEnforceability, validateSortableFields, validateStackExpressions, validateTranslatableSections, validateTranslationReferences, validateViewContainers, validateViewPageRefs, validateVisibilityPredicates, validateWidgetBindings, walkFilterFieldKeys, walkPageComponents };
|
|
4696
|
+
export { ACTION_API_UPDATE_READONLY_WHEN_FIELD, ACTION_BODY_SOURCE_UNPARSEABLE, ACTION_BODY_WRITE_EXCLUSIONS, ACTION_BODY_WRITE_PATTERNS, ACTION_BODY_WRITE_PATTERN_IDS, ACTION_BODY_WRITE_UNKNOWN_FIELD, ACTION_BODY_WRITE_UNPROVISIONED_ANCHOR, 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 BareExpressionFinding, type BodyWritePatternExclusion, CAPABILITY_REFERENCE_UNKNOWN, CHART_AXIS_NOT_SELECTED, CHART_CONFIG_MISSING, CHART_DATASET_UNKNOWN, CHART_DIMENSIONS_MISSING, CHART_DIMENSION_UNKNOWN, CHART_FIELD_UNKNOWN, CHART_MEASURES_MISSING, CHART_MEASURE_UNKNOWN, COMPONENT_PROPS_INVALID, COMPONENT_PROPS_UNKNOWN_KEY, COMPONENT_TYPE_UNKNOWN, type CapabilityRefFinding, type CapabilityRefSeverity, type ChartBindingFinding, type ChartBindingSeverity, type CheckedParse, type CheckedParseOptions, type ComponentPropsFinding, type ComponentPropsSeverity, type ComponentTypeFinding, DASHBOARD_ACTION_ROUTE_UNRESOLVED, DASHBOARD_ACTION_TARGET_UNDEFINED, DASHBOARD_FILTER_FIELD_NOT_INCLUDED, DASHBOARD_FILTER_FIELD_UNKNOWN, DASHBOARD_FILTER_FIELD_UNPROVISIONED, DATASET_FIELD_NOT_INCLUDED, DATASET_FIELD_UNKNOWN, DATASET_FILTER_FIELD_UNKNOWN, DATASET_INCLUDE_UNKNOWN, DEFAULT_AGENT_LEGACY_ALIAS, DEFAULT_AGENT_OUTSIDE_ROSTER, type DashboardActionRefFinding, type DashboardActionRefSeverity, type DatasetRefFinding, type DatasetRefSeverity, type EmptyCombinatorFinding, type EmptyCombinatorSeverity, type EnvelopeAuditDoor, type ExprIssue, type ExtractedHookBodyWrite, type ExtractedHookBodyWriteSet, CARRIER_ROOTS as FIELD_CARRIER_ROOTS, CONSUMER_ROOTS as FIELD_CONSUMER_ROOTS, FIELD_GROUP_EMPTY, FIELD_GROUP_SHADOWED, FIELD_GROUP_UNDECLARED, FIELD_NO_CONSUMERS, FIELD_RULE_BOUND_ROOTS, FILTER_EMPTY_COMBINATOR, FILTER_EMPTY_NODE, FILTER_PRESET_COMPARAND, 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_FILTER_TOKEN_UNKNOWN, FLOW_INERT_NODE_CONDITION, FLOW_LOOP_BODY_UNCONTAINED, FLOW_MULTIPLE_DEFAULT_EDGES, FLOW_MULTI_WRITE_UNFILTERED, FLOW_NODE_WRITE_UNKNOWN_FIELD, FLOW_NODE_WRITE_UNPROVISIONED_ANCHOR, FLOW_PHANTOM_AGGREGATION, FLOW_RUNAS_UNSCOPED, FLOW_TEMPLATE_DATE_FUNCTIONS, FLOW_TEMPLATE_FIELD_UNPROVISIONED, FLOW_TEMPLATE_LOOKUP_TRAVERSAL, FLOW_TEMPLATE_UNKNOWN_FIELD, FLOW_TEMPLATE_VALUE_FUNCTIONS, FLOW_TIME_RELATIVE_ANTIPATTERN, FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID, FLOW_TIME_RELATIVE_DESCRIPTOR_UNROUTABLE, FLOW_TRIGGER_UNKNOWN_EVENT, FLOW_TRIGGER_UNKNOWN_OBJECT, FLOW_TRIGGER_UNROUTABLE, FLOW_TRY_CATCH_WITHOUT_CATCH, FLOW_UPDATE_READONLY_FIELD, FLOW_UPDATE_READONLY_WHEN_FIELD, FLOW_WRITE_NODE_TYPES, FLOW_WRITE_NODE_TYPES_DEFERRED, FORM_COLSPAN_ABSOLUTE, FORM_FIELD_UNKNOWN, FORM_SECTION_GROUP_UNKNOWN, type FieldConsumerFinding, type FieldConsumerSeverity, type FieldConsumerVerdict, type FieldPathAccount, type FieldPathVerdict, type FilterFieldKey, type FilterTokenFinding, type FilterTokenSeverity, type FlowFilterTokenFinding, type FlowLintFinding, type FlowNodeWriteFinding, type FlowNodeWriteSeverity, type FlowTemplatePathFinding, type FlowTemplatePathSeverity, type FlowTemplateTokenVerdict, type FlowTriggerReadinessFinding, type FlowTriggerReadinessSeverity, type FlowWriteNodeDeferral, type FormLayoutFinding, type FormLayoutSeverity, type FunctionalCompletenessFinding, type FunctionalCompletenessSeverity, type GraphField, type GraphObject, HOOK_API_UPDATE_READONLY_FIELD, HOOK_API_UPDATE_READONLY_WHEN_FIELD, HOOK_BODY_SOURCE_UNPARSEABLE, HOOK_BODY_WRITE_EXCLUSIONS, HOOK_BODY_WRITE_PATTERNS, HOOK_BODY_WRITE_PATTERN_IDS, HOOK_BODY_WRITE_UNKNOWN_FIELD, HOOK_BODY_WRITE_UNPROVISIONED_ANCHOR, type HookBodyWriteFinding, type HookBodyWritePattern, type HookBodyWriteSeverity, type JsxPageFinding, type JsxPageSeverity, LIST_VIEW_FIELD_DOTTED, LIST_VIEW_FIELD_UNKNOWN, LIST_VIEW_FILTERS_IN_VIEWS_MODE, LIVENESS_DEAD_PROPERTY, LIVENESS_EXPERIMENTAL_PROPERTY, LIVENESS_LIVE_ELSEWHERE_PROPERTY, LIVENESS_PLANNED_PROPERTY, type LintIssue, type ListViewFieldRefFinding, type ListViewFieldRefSeverity, type ListViewModeFinding, type ListViewModeSeverity, type LivenessLintFinding, type LocatedLintIssue, MANAGED_API_METHOD_UNAFFORDABLE, MAX_SCHEMA_WALK_DEPTH, MEASURE_AGGREGATE_INCOHERENT, type ManagedApiMethodFinding, NAV_OBJECT_UNGRANTED, NAV_OBJECT_UNSERVABLE, NAV_TARGET_UNRESOLVED, NULL_GUARD_HINT, type NavAccessFinding, type NavAccessSeverity, type NavObjectServabilityFinding, type NavTargetRefFinding, type NavTargetRefSeverity, type NullGuardFinding, type NullGuardOptions, OBJECTUI_DERIVATION_PREDICATES, OBJECT_FIELD_REF_UNKNOWN, OBJECT_REFERENCE_UNKNOWN, OBJECT_REFERENCE_UNREGISTERED_PLATFORM, OPEN_VOCABULARY_PROBES, ORG_AXIS_CROSS_ORG_BU_GRANT, ORG_AXIS_PERMISSION_INHERITANCE, type ObjectFieldRefFinding, type ObjectFieldRefSeverity, type ObjectGraph, type ObjectRefFinding, type ObjectRefSeverity, type OrgAxisFinding, type OrgAxisSeverity, PAGE_FIELD_UNKNOWN, PAGE_FIELD_UNPROVISIONED, PAGE_SECTION_GROUP_UNKNOWN, PAGE_SOURCE_CLASSNAME, PAGE_VISUALIZATION_WITHOUT_BINDING, PARSE_FAILURE_HINT, PREDICATE_PATH_UNRESOLVED, PREDICATE_PATH_UNROOTED, PREDICATE_RHS_PATH_SHAPED, PRE_SEAL_PHASES, type PageEnvelopeAudit, type PageFieldFinding, type PageFieldSeverity, type PageVisualizationFinding, type PageVisualizationSeverity, type PredicatePathFinding, type PredicatePathOptions, type PredicatePathSeverity, type PresetComparandFinding, type PresetComparandSeverity, REACT_BLOCK_NEEDS_RECORD_CONTEXT, REACT_CHART_AGGREGATE_INVALID, REACT_CHART_AXIS_UNKNOWN, REACT_CHART_DRILLDOWN_INVALID, REACT_CHART_FIELD_UNKNOWN, REACT_CHART_FIELD_UNPROVISIONED, REACT_PAGE_SOURCE_UNPARSEABLE, REACT_PROP_DEPRECATED, REACT_PROP_RETIRED, READONLY_ACTION_WRITE_EXCLUSIONS, READONLY_ACTION_WRITE_PATTERN_IDS, READONLY_HOOK_WRITE_EXCLUSIONS, READONLY_HOOK_WRITE_PATTERN_IDS, REFERENCE_INTEGRITY_RULES, RELATIONSHIP_FIELD_TYPES, RLS_PREDICATE_OVER_BUDGET, RLS_PREDICATE_UNENFORCEABLE, RLS_PREDICATE_UNPARSEABLE, RUNTIME_AJV_OPTIONS, type ReactPageFinding, type ReactPageSeverity, type ReactPropFinding, type ReactPropSeverity, type ReadonlyActionWriteFinding, type ReadonlyActionWriteSeverity, type ReadonlyFlowWriteFinding, type ReadonlyFlowWriteSeverity, type ReadonlyHookWriteFinding, type ReadonlyHookWriteSeverity, type RecordTitleFinding, type RecordTitleSeverity, type ReferenceIntegrityFinding, type ReferenceIntegrityRule, type ReferenceIntegritySeverity, type RlsPredicateFinding, type RlsPredicateSeverity, type RuleCompilabilityFinding, type RuleCompilabilitySeverity, type RuleSchemaFormatFinding, type RuleSchemaFormatSeverity, SEAL_MARKERS, SEARCHABLE_FIELD_UNKNOWN, SEARCHABLE_FIELD_UNPROVISIONED, SEARCHABLE_FIELD_UNSEARCHABLE, SECURITY_ANCHOR_HIGH_PRIVILEGE, SECURITY_BOOK_AUDIENCE_UNKNOWN_SET, SECURITY_CBP_AMBIGUOUS_RELATION, SECURITY_CBP_NO_RELATION, SECURITY_DELEGATION_MISSING_REASON, SECURITY_EXTERNAL_WIDER, SECURITY_FLS_UNKNOWN_FIELD, 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, SEMANTIC_ROLE_FIELD_UNPROVISIONED, SHARING_RULE_OBJECT_CONTROLLED_BY_PARENT, SHARING_RULE_OBJECT_NOT_SHAREABLE, SHARING_RULE_RUNTIME_VARIABLE_CONDITION, SHARING_RULE_UNLOWERABLE_CONDITION, SORT_FIELD_UNKNOWN, SORT_FIELD_UNPROVISIONED, SORT_FIELD_UNSORTABLE, STARTUP_OPEN_VOCABULARY_VERDICT, STARTUP_SOURCE_UNPARSEABLE, STARTUP_VERDICT_ASSERTIVE_WORDING, STARTUP_VERDICT_HINT, 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 SectionGroupFinding, type SectionGroupRef, type SecurityFinding, type SecuritySeverity, type SeedReplaySafetyFinding, type SeedReplaySafetySeverity, type SeedStateMachineFinding, type SeedStateMachineSeverity, type SemanticRoleFinding, type SemanticRoleSeverity, type Severity, type SharingRuleEnforceabilityFinding, type SharingRuleEnforceabilitySeverity, type SortableFieldFinding, type SortableFieldSeverity, type SourceParseFailure, type SourceStyleFinding, type SourceStyleSeverity, type StartupRegistryVerdictFinding, type StartupRegistryVerdictOptions, type StartupRegistryVerdictSeverity, 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_PAGE_UNRESOLVED, VIEW_REF_FORM_TARGET_KIND, VIEW_REF_FORM_TARGET_MISSING, VIEW_REF_NAV_VIEW_MISSING, VISIBILITY_BARE_IDENTIFIER, VISIBILITY_PREDICATE_OVER_BUDGET, VISIBILITY_PREDICATE_SYNTAX, VISIBILITY_PREDICATE_UNKNOWN_FUNCTION, VISIBILITY_ROOT_MISLAYERED, type ViewContainerFinding, type ViewContainerSeverity, type ViewPageRefFinding, type ViewPageRefSeverity, type ViewRefFinding, type VisibilityFinding, type VisibilityLayer, type VisibilityOptions, type VisibilitySeverity, type VisualizationPredicate, WIDGET_DATASET_UNKNOWN, WIDGET_DIMENSION_UNKNOWN, WIDGET_FILTER_FIELD_NOT_INCLUDED, WIDGET_FILTER_FIELD_UNKNOWN, WIDGET_LEGACY_ANALYTICS_SHAPE, WIDGET_LEGACY_ANALYTICS_UNRENDERABLE, WIDGET_MEASURES_MISSING, WIDGET_MEASURE_UNKNOWN, WIDGET_SORTBY_UNSELECTED, type WalkedComponent, type WalkedValidationRule, type WidgetBindingFinding, type WidgetBindingSeverity, auditPageExpressionEnvelopes, authorWarnedProperties, buildAccessMatrix, checkSectionGroupRefs, checkSortDeclaration, classifyFlowTemplateToken, describeFieldPathVerdict, describeParseFailure, diffAccessMatrix, extractHookBodyWriteSet, extractHookBodyWrites, fieldRuleRootIssue, findStartupRegistryVerdicts, findUnguardedNullableOperands, indexObjectFieldGroups, indexObjectGraph, isSourceAuthoredPage, isUnjudgeable, joinablePrefixes, lintAutonumberFormats, lintDataModel, lintFlowPatterns, lintLegacyOrganizationComposites, lintLivenessProperties, lintUniqueDeclarations, lintUnscopedDeclaredIndexes, lintViewRefs, listNames, nearestName, nearestRegisteredFormat, nullGuardMessage, renderBareExpressionFindings, resolveFieldPath, sectionGroupRefs, suggestName, validateActionBodyWrites, validateActionLocations, validateActionNameRefs, validateAiAgentAuthoring, validateAiSurfaceAffinity, validateAiToolReferences, validateApprovalApprovers, validateCapabilityReferences, validateChartBindings, validateComponentProps, validateComponentTypes, validateDashboardActionRefs, validateDatasetReferences, validateEmptyCombinators, validateFieldConsumers, validateFilterTokens, validateFlowFilterTokens, validateFlowNodeWrites, validateFlowTemplatePaths, validateFlowTriggerReadiness, validateFormLayout, validateFunctionalCompleteness, validateHookBodyWrites, validateJsxPages, validateListViewFieldRefs, validateListViewMode, validateManagedApiMethods, validateNavAccess, validateNavObjectServability, validateNavTargetRefs, validateObjectFieldRefs, validateObjectReferences, validateOrgAxisRedLines, validatePageFieldBindings, validatePageSourceStyling, validatePageVisualizationBindings, validatePredicatePathRefs, validatePresetComparands, validateReactPageProps, validateReactPages, validateReadonlyActionWrites, validateReadonlyFlowWrites, validateReadonlyHookWrites, validateRecordTitle, validateReferenceIntegrity, validateResponsiveStyles, validateRlsPredicateEnforceability, validateRuleCompilability, validateRuleSchemaFormats, validateSearchableFields, validateSecurityPosture, validateSecurityRoleWord, validateSeedReplaySafety, validateSeedStateMachine, validateSemanticRoles, validateSharingRuleEnforceability, validateSortableFields, validateStackExpressions, validateTranslatableSections, validateTranslationReferences, validateViewContainers, validateViewPageRefs, validateVisibilityPredicates, validateWidgetBindings, walkFilterFieldKeys, walkPageComponents };
|