@objectstack/lint 17.0.0-rc.6 → 17.1.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 +7618 -1
- package/dist/index.cjs +1890 -607
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +445 -78
- package/dist/index.d.ts +445 -78
- package/dist/index.js +1851 -582
- package/dist/index.js.map +1 -1
- package/dist/{runtime-B50yywI_.d.cts → runtime-s3X9D9hm.d.cts} +173 -6
- package/dist/{runtime-B50yywI_.d.ts → runtime-s3X9D9hm.d.ts} +173 -6
- package/dist/runtime.cjs +1888 -653
- 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 +1874 -629
- package/dist/runtime.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type AnyRec = Record<string, unknown>;
|
|
1
|
+
type AnyRec$1 = Record<string, unknown>;
|
|
2
2
|
/** The three commands that hold a stack to the same author-time bar. */
|
|
3
3
|
declare const AUTHORING_COMMANDS: readonly ["validate", "build", "lint"];
|
|
4
4
|
type AuthoringCommand = (typeof AUTHORING_COMMANDS)[number];
|
|
@@ -152,7 +152,7 @@ interface AuthoringRule {
|
|
|
152
152
|
runtimeTypes?: readonly string[];
|
|
153
153
|
/** REQUIRED when `surfaces` omits `'runtime-publish'`: why the runtime gate does not run it. */
|
|
154
154
|
surfaceReason?: string;
|
|
155
|
-
run: (stack: AnyRec, ctx: AuthoringRuleContext) => readonly AuthoringFinding[];
|
|
155
|
+
run: (stack: AnyRec$1, ctx: AuthoringRuleContext) => readonly AuthoringFinding[];
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
158
|
* `ExprIssue` is the one rule finding that carries no rule id of its own — it
|
|
@@ -168,12 +168,12 @@ declare const AUTHORING_RULES: readonly AuthoringRule[];
|
|
|
168
168
|
/** The stack tiers a command has in hand when it runs the registry. */
|
|
169
169
|
interface AuthoringRuleRun extends AuthoringRuleContext {
|
|
170
170
|
/** `normalizeStackInput` output — pre-Zod-parse. Always required. */
|
|
171
|
-
normalized: AnyRec;
|
|
171
|
+
normalized: AnyRec$1;
|
|
172
172
|
/**
|
|
173
173
|
* Post-Zod-parse stack. Omitted by `os lint`, which does not parse; `parsed`
|
|
174
174
|
* rules then read `normalized` (see `AuthoringRuleInputTier`).
|
|
175
175
|
*/
|
|
176
|
-
parsed?: AnyRec;
|
|
176
|
+
parsed?: AnyRec$1;
|
|
177
177
|
}
|
|
178
178
|
/** The rules `command` runs, in registry order. */
|
|
179
179
|
declare function authoringRulesFor(command: AuthoringCommand): readonly AuthoringRule[];
|
|
@@ -243,7 +243,21 @@ declare function splitBySeverity(findings: readonly AuthoringFinding[]): {
|
|
|
243
243
|
* a draft autosave). That is the correct place to spend it.
|
|
244
244
|
*/
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
type AnyRec = Record<string, unknown>;
|
|
247
|
+
/**
|
|
248
|
+
* Everything the gate needs from the host runtime to build a snapshot.
|
|
249
|
+
*
|
|
250
|
+
* [#8309] Each key here doubles as the stack key the collection occupies in
|
|
251
|
+
* the per-write snapshot — see {@link CONTEXT_STACK_KEYS}, which is derived
|
|
252
|
+
* from this shape and keeps the two from drifting. The set is deliberately
|
|
253
|
+
* BOUNDED to what the runtime-wired rules actually read (measured, not
|
|
254
|
+
* projected): the three cross-collection security rules compare
|
|
255
|
+
* objects × permissions × books, `validateWidgetBindings` resolves widget
|
|
256
|
+
* bindings against datasets (#7529), and nothing on the runtime surface reads
|
|
257
|
+
* `positions` / `apps` — so those are NOT carried. Widening the snapshot is a
|
|
258
|
+
* one-key edit here plus a `CONTEXT_STACK_KEYS` entry, made when a rule that
|
|
259
|
+
* reads the collection actually crosses the wall, never in advance.
|
|
260
|
+
*/
|
|
247
261
|
interface RuntimeStackContext {
|
|
248
262
|
/**
|
|
249
263
|
* The live object declarations (registry + tenant overlay), as authored.
|
|
@@ -254,7 +268,102 @@ interface RuntimeStackContext {
|
|
|
254
268
|
* package's config file and has to hedge.
|
|
255
269
|
*/
|
|
256
270
|
objects?: readonly unknown[];
|
|
271
|
+
/**
|
|
272
|
+
* The live permission-set declarations (stack key `permissions`).
|
|
273
|
+
*
|
|
274
|
+
* [#8309] The collection the three cross-collection security rules compare
|
|
275
|
+
* against. Without it a per-write snapshot holds exactly ONE permission set
|
|
276
|
+
* (the written item), so `security-master-detail-ungranted` reads every
|
|
277
|
+
* detail object the tenant's OTHER sets grant as ungranted — measured as 38
|
|
278
|
+
* phantom findings per-write vs 4 whole-stack over the shipped corpus
|
|
279
|
+
* (PR #7886). `security-book-audience-unknown-set` needs the set NAMES to
|
|
280
|
+
* resolve a book's `audience.permissionSet` for the same reason.
|
|
281
|
+
*/
|
|
282
|
+
permissions?: readonly unknown[];
|
|
283
|
+
/**
|
|
284
|
+
* The live documentation-book declarations (stack key `books`).
|
|
285
|
+
*
|
|
286
|
+
* [#8309] Carried so a `book` write is judged with its siblings present and
|
|
287
|
+
* replace-not-erase semantics apply to it (an updated book must not read as
|
|
288
|
+
* a second book of the same name), and so book-derived findings cancel in
|
|
289
|
+
* the differential for every other write type.
|
|
290
|
+
*/
|
|
291
|
+
books?: readonly unknown[];
|
|
292
|
+
/**
|
|
293
|
+
* The live dataset declarations (stack key `datasets`).
|
|
294
|
+
*
|
|
295
|
+
* [#7529] The resolution universe `validateWidgetBindings` links a widget's
|
|
296
|
+
* `dataset` / `dimensions` / `values` against. Without it a per-write
|
|
297
|
+
* dashboard snapshot holds no datasets at all, so every widget on a fully
|
|
298
|
+
* legitimate board reads as dangling — measured as 3 phantom
|
|
299
|
+
* `widget-dataset-unknown` errors on a 3-widget board bound to a real
|
|
300
|
+
* dataset, vs 0 with the collection carried (and the genuinely dangling
|
|
301
|
+
* binding still yields exactly its 1 true error). Carrying it in BOTH
|
|
302
|
+
* passes also cancels dataset-level findings (`measure-aggregate-incoherent`
|
|
303
|
+
* is judged per dataset, independent of any widget) in the differential, so
|
|
304
|
+
* a stored dataset's pre-existing condition is not this write's to answer
|
|
305
|
+
* for (#4463 D4).
|
|
306
|
+
*/
|
|
307
|
+
datasets?: readonly unknown[];
|
|
257
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Which package a write belongs to, and what that package is allowed to reach.
|
|
311
|
+
*
|
|
312
|
+
* [#9612] The maintainer's ruling, verbatim, is the product decision this type
|
|
313
|
+
* exists for:
|
|
314
|
+
*
|
|
315
|
+
* > 大客户(420 个对象),就不应该出现在一个软件包中啊,这就是划分软件包的价值。
|
|
316
|
+
* > 客户开发开发,校验是否也应该基于软件包
|
|
317
|
+
* > 当然这里面要考虑系统对象
|
|
318
|
+
*
|
|
319
|
+
* A tenant that has grown to 420 objects is not ONE package — it is many — and
|
|
320
|
+
* judging one package's write against all 420 is validating against the wrong
|
|
321
|
+
* unit, not merely validating slowly. A package's declared `dependencies`
|
|
322
|
+
* bound what it MAY reference, so `package + declared deps + platform/system`
|
|
323
|
+
* is a closure the platform computes EXACTLY rather than estimates. That is
|
|
324
|
+
* what separates this from "narrow to whatever the rule can be proven to
|
|
325
|
+
* reach", which was considered and refused: a per-rule proof is a second
|
|
326
|
+
* opinion that drifts the moment a rule changes.
|
|
327
|
+
*
|
|
328
|
+
* ⛔ Absent — or carrying a package whose dependency declaration cannot be
|
|
329
|
+
* read — narrows NOTHING. The whole collection is handed over, exactly as
|
|
330
|
+
* before. The fallback direction is deliberate and is the opposite of a size
|
|
331
|
+
* threshold: an unknown provenance buys MORE validation input, never less, so
|
|
332
|
+
* the gate never stops judging (the #9798 / #9261 / ADR-0110 D3 fail-open
|
|
333
|
+
* shape this card was explicitly forbidden from re-creating).
|
|
334
|
+
*/
|
|
335
|
+
interface RuntimePackageScope {
|
|
336
|
+
/** The package the written item belongs to. */
|
|
337
|
+
packageId: string;
|
|
338
|
+
/**
|
|
339
|
+
* Every OTHER package this one may reference — the transitive closure of the
|
|
340
|
+
* written package's declared `dependencies`. Resolved by the host, which is
|
|
341
|
+
* the side that holds the package registry; this module only reads the set.
|
|
342
|
+
*/
|
|
343
|
+
dependencies: readonly string[];
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* `objects` reduced to the written item's package closure (#9612).
|
|
347
|
+
*
|
|
348
|
+
* An object survives when ANY of these holds — the four limbs are the closure
|
|
349
|
+
* the ruling names, and each one is load-bearing:
|
|
350
|
+
*
|
|
351
|
+
* 1. it is a **platform / system object** ({@link isSystemObject}, imported
|
|
352
|
+
* rather than re-decided). ⛔ Unconditional: a package legitimately
|
|
353
|
+
* references `sys_*` objects it never declares a dependency on, and a
|
|
354
|
+
* closure that dropped them would manufacture "unresolved reference"
|
|
355
|
+
* findings that describe nothing — the false-positive class PR #7886
|
|
356
|
+
* already paid for on the `permissions` collection;
|
|
357
|
+
* 2. it carries **no package provenance** — a tenant-authored overlay row.
|
|
358
|
+
* Nothing declares what such a row may reference, so nothing bounds it and
|
|
359
|
+
* it is kept. Conservative by construction;
|
|
360
|
+
* 3. it belongs to the **written package** itself;
|
|
361
|
+
* 4. it belongs to one of that package's **declared dependencies**.
|
|
362
|
+
*
|
|
363
|
+
* Pure, allocation-light, and total: a non-object member is kept rather than
|
|
364
|
+
* inspected, because deciding it is not this function's job.
|
|
365
|
+
*/
|
|
366
|
+
declare function narrowObjectsToPackageClosure(objects: readonly unknown[], scope: RuntimePackageScope | undefined): readonly unknown[];
|
|
258
367
|
/** One rule's verdict at the runtime surface, carrying which rule produced it. */
|
|
259
368
|
interface RuntimeGateResult {
|
|
260
369
|
/** Findings the written item ADDED, severity `error` — the reason to refuse the write. */
|
|
@@ -275,6 +384,58 @@ declare function runtimeAuthoringRulesFor(type: string): readonly AuthoringRule[
|
|
|
275
384
|
declare function runtimeGatedTypes(): string[];
|
|
276
385
|
/** The stack key a metadata type occupies in a stack view, or null when unmapped. */
|
|
277
386
|
declare function stackKeyForType(type: string): string | null;
|
|
387
|
+
/**
|
|
388
|
+
* The baseline/candidate stack pair the gate judges one write against, or
|
|
389
|
+
* `null` when no snapshot can be built (unmapped type, non-object body).
|
|
390
|
+
*
|
|
391
|
+
* Exported (#8309) so the tests that measure per-write vs whole-stack
|
|
392
|
+
* agreement exercise the REAL construction instead of a hand-kept mirror —
|
|
393
|
+
* `validate-security-posture.runtime-surface.test.ts` used to mirror this
|
|
394
|
+
* logic in a local `wouldGateAdd`, which is exactly the drift surface a
|
|
395
|
+
* snapshot change here would have missed.
|
|
396
|
+
*
|
|
397
|
+
* Shape:
|
|
398
|
+
* - The baseline carries every context collection ({@link CONTEXT_STACK_KEYS})
|
|
399
|
+
* WITHOUT the written item. Anything found there is somebody else's
|
|
400
|
+
* pre-existing condition and is not this write's to answer for (#4463 D4 —
|
|
401
|
+
* the gate blocks new writes, never stored rows). Carrying the sibling
|
|
402
|
+
* collections in BOTH passes is what makes their findings cancel in the
|
|
403
|
+
* diff — and what gives the cross-collection rules the sibling collection
|
|
404
|
+
* they compare against, so the per-write verdict agrees with the
|
|
405
|
+
* whole-stack one instead of inventing findings (the 38-vs-4 measurement,
|
|
406
|
+
* PR #7886).
|
|
407
|
+
* - The candidate is the same context with this write's item added. When the
|
|
408
|
+
* written type IS one of the context collections (an `object`, `permission`
|
|
409
|
+
* or `book` write), the item REPLACES its stored self rather than appearing
|
|
410
|
+
* beside it — otherwise an update reads as a duplicate name, and for
|
|
411
|
+
* `objects` every lookup in the tenant's model would read as dangling. For
|
|
412
|
+
* any other type the item is the sole member of its own collection, so
|
|
413
|
+
* index-0 paths in the findings are unambiguously this write.
|
|
414
|
+
*
|
|
415
|
+
* Cost (the #4463 D2 question, measured rather than assumed): built per
|
|
416
|
+
* write, never cached. The construction is one filter + one spread over the
|
|
417
|
+
* written type's collection; the sibling collections are passed by reference.
|
|
418
|
+
* Over the shipped corpus (30 objects, 10 permission sets, 1 book) that is
|
|
419
|
+
* microseconds on a PUBLISH (never a draft autosave, D1) — a cache would buy
|
|
420
|
+
* nothing and would need cross-org invalidation the gate has no seam for.
|
|
421
|
+
*/
|
|
422
|
+
declare function buildRuntimeWriteSnapshots(args: {
|
|
423
|
+
/** Singular metadata type of the item being written. */
|
|
424
|
+
type: string;
|
|
425
|
+
/** The item body as it will be persisted. */
|
|
426
|
+
item: unknown;
|
|
427
|
+
/** Live resolution context from the host runtime. */
|
|
428
|
+
context?: RuntimeStackContext;
|
|
429
|
+
/**
|
|
430
|
+
* [#9612] The written item's package and what it may reach. Omitted — or
|
|
431
|
+
* carrying a package whose dependencies the host could not read — hands the
|
|
432
|
+
* rules the WHOLE `objects` collection, exactly as before.
|
|
433
|
+
*/
|
|
434
|
+
packageScope?: RuntimePackageScope;
|
|
435
|
+
}): {
|
|
436
|
+
baseline: AnyRec;
|
|
437
|
+
candidate: AnyRec;
|
|
438
|
+
} | null;
|
|
278
439
|
/**
|
|
279
440
|
* Judge one about-to-be-published metadata item against the shared registry.
|
|
280
441
|
*
|
|
@@ -292,8 +453,14 @@ declare function runRuntimeAuthoringRules(args: {
|
|
|
292
453
|
item: unknown;
|
|
293
454
|
/** Live resolution context from the host runtime. */
|
|
294
455
|
context?: RuntimeStackContext;
|
|
456
|
+
/**
|
|
457
|
+
* [#9612] The written item's package closure. Omit to judge against the
|
|
458
|
+
* whole collection — the pre-#9612 behaviour, and the behaviour every caller
|
|
459
|
+
* that cannot state a package keeps.
|
|
460
|
+
*/
|
|
461
|
+
packageScope?: RuntimePackageScope;
|
|
295
462
|
/** ADR-0080 SDUI manifest, when the host has one. */
|
|
296
463
|
sduiManifest?: unknown;
|
|
297
464
|
}): RuntimeGateResult;
|
|
298
465
|
|
|
299
|
-
export { AUTHORING_COMMANDS as A, EXPRESSION_INVALID as E, type RuntimeGateResult as R, AUTHORING_RULES as a, AUTHORING_SURFACES as b, type AuthoringCommand as c, type AuthoringFinding as d, type AuthoringRule as e, type AuthoringRuleContext as f, type AuthoringRuleInputTier as g, type AuthoringRuleRun as h, type AuthoringRuleTier as i, type AuthoringSeverity as j, type AuthoringSurface as k, type
|
|
466
|
+
export { AUTHORING_COMMANDS as A, EXPRESSION_INVALID as E, type RuntimeGateResult as R, AUTHORING_RULES as a, AUTHORING_SURFACES as b, type AuthoringCommand as c, type AuthoringFinding as d, type AuthoringRule as e, type AuthoringRuleContext as f, type AuthoringRuleInputTier as g, type AuthoringRuleRun as h, type AuthoringRuleTier as i, type AuthoringSeverity as j, type AuthoringSurface as k, type RuntimePackageScope as l, type RuntimeStackContext as m, authoringRulesFor as n, buildRuntimeWriteSnapshots as o, narrowObjectsToPackageClosure as p, runRuntimeAuthoringRules as q, runAuthoringRules as r, runtimeAuthoringRulesFor as s, runtimeGatedTypes as t, splitBySeverity as u, stackKeyForType as v };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type AnyRec = Record<string, unknown>;
|
|
1
|
+
type AnyRec$1 = Record<string, unknown>;
|
|
2
2
|
/** The three commands that hold a stack to the same author-time bar. */
|
|
3
3
|
declare const AUTHORING_COMMANDS: readonly ["validate", "build", "lint"];
|
|
4
4
|
type AuthoringCommand = (typeof AUTHORING_COMMANDS)[number];
|
|
@@ -152,7 +152,7 @@ interface AuthoringRule {
|
|
|
152
152
|
runtimeTypes?: readonly string[];
|
|
153
153
|
/** REQUIRED when `surfaces` omits `'runtime-publish'`: why the runtime gate does not run it. */
|
|
154
154
|
surfaceReason?: string;
|
|
155
|
-
run: (stack: AnyRec, ctx: AuthoringRuleContext) => readonly AuthoringFinding[];
|
|
155
|
+
run: (stack: AnyRec$1, ctx: AuthoringRuleContext) => readonly AuthoringFinding[];
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
158
|
* `ExprIssue` is the one rule finding that carries no rule id of its own — it
|
|
@@ -168,12 +168,12 @@ declare const AUTHORING_RULES: readonly AuthoringRule[];
|
|
|
168
168
|
/** The stack tiers a command has in hand when it runs the registry. */
|
|
169
169
|
interface AuthoringRuleRun extends AuthoringRuleContext {
|
|
170
170
|
/** `normalizeStackInput` output — pre-Zod-parse. Always required. */
|
|
171
|
-
normalized: AnyRec;
|
|
171
|
+
normalized: AnyRec$1;
|
|
172
172
|
/**
|
|
173
173
|
* Post-Zod-parse stack. Omitted by `os lint`, which does not parse; `parsed`
|
|
174
174
|
* rules then read `normalized` (see `AuthoringRuleInputTier`).
|
|
175
175
|
*/
|
|
176
|
-
parsed?: AnyRec;
|
|
176
|
+
parsed?: AnyRec$1;
|
|
177
177
|
}
|
|
178
178
|
/** The rules `command` runs, in registry order. */
|
|
179
179
|
declare function authoringRulesFor(command: AuthoringCommand): readonly AuthoringRule[];
|
|
@@ -243,7 +243,21 @@ declare function splitBySeverity(findings: readonly AuthoringFinding[]): {
|
|
|
243
243
|
* a draft autosave). That is the correct place to spend it.
|
|
244
244
|
*/
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
type AnyRec = Record<string, unknown>;
|
|
247
|
+
/**
|
|
248
|
+
* Everything the gate needs from the host runtime to build a snapshot.
|
|
249
|
+
*
|
|
250
|
+
* [#8309] Each key here doubles as the stack key the collection occupies in
|
|
251
|
+
* the per-write snapshot — see {@link CONTEXT_STACK_KEYS}, which is derived
|
|
252
|
+
* from this shape and keeps the two from drifting. The set is deliberately
|
|
253
|
+
* BOUNDED to what the runtime-wired rules actually read (measured, not
|
|
254
|
+
* projected): the three cross-collection security rules compare
|
|
255
|
+
* objects × permissions × books, `validateWidgetBindings` resolves widget
|
|
256
|
+
* bindings against datasets (#7529), and nothing on the runtime surface reads
|
|
257
|
+
* `positions` / `apps` — so those are NOT carried. Widening the snapshot is a
|
|
258
|
+
* one-key edit here plus a `CONTEXT_STACK_KEYS` entry, made when a rule that
|
|
259
|
+
* reads the collection actually crosses the wall, never in advance.
|
|
260
|
+
*/
|
|
247
261
|
interface RuntimeStackContext {
|
|
248
262
|
/**
|
|
249
263
|
* The live object declarations (registry + tenant overlay), as authored.
|
|
@@ -254,7 +268,102 @@ interface RuntimeStackContext {
|
|
|
254
268
|
* package's config file and has to hedge.
|
|
255
269
|
*/
|
|
256
270
|
objects?: readonly unknown[];
|
|
271
|
+
/**
|
|
272
|
+
* The live permission-set declarations (stack key `permissions`).
|
|
273
|
+
*
|
|
274
|
+
* [#8309] The collection the three cross-collection security rules compare
|
|
275
|
+
* against. Without it a per-write snapshot holds exactly ONE permission set
|
|
276
|
+
* (the written item), so `security-master-detail-ungranted` reads every
|
|
277
|
+
* detail object the tenant's OTHER sets grant as ungranted — measured as 38
|
|
278
|
+
* phantom findings per-write vs 4 whole-stack over the shipped corpus
|
|
279
|
+
* (PR #7886). `security-book-audience-unknown-set` needs the set NAMES to
|
|
280
|
+
* resolve a book's `audience.permissionSet` for the same reason.
|
|
281
|
+
*/
|
|
282
|
+
permissions?: readonly unknown[];
|
|
283
|
+
/**
|
|
284
|
+
* The live documentation-book declarations (stack key `books`).
|
|
285
|
+
*
|
|
286
|
+
* [#8309] Carried so a `book` write is judged with its siblings present and
|
|
287
|
+
* replace-not-erase semantics apply to it (an updated book must not read as
|
|
288
|
+
* a second book of the same name), and so book-derived findings cancel in
|
|
289
|
+
* the differential for every other write type.
|
|
290
|
+
*/
|
|
291
|
+
books?: readonly unknown[];
|
|
292
|
+
/**
|
|
293
|
+
* The live dataset declarations (stack key `datasets`).
|
|
294
|
+
*
|
|
295
|
+
* [#7529] The resolution universe `validateWidgetBindings` links a widget's
|
|
296
|
+
* `dataset` / `dimensions` / `values` against. Without it a per-write
|
|
297
|
+
* dashboard snapshot holds no datasets at all, so every widget on a fully
|
|
298
|
+
* legitimate board reads as dangling — measured as 3 phantom
|
|
299
|
+
* `widget-dataset-unknown` errors on a 3-widget board bound to a real
|
|
300
|
+
* dataset, vs 0 with the collection carried (and the genuinely dangling
|
|
301
|
+
* binding still yields exactly its 1 true error). Carrying it in BOTH
|
|
302
|
+
* passes also cancels dataset-level findings (`measure-aggregate-incoherent`
|
|
303
|
+
* is judged per dataset, independent of any widget) in the differential, so
|
|
304
|
+
* a stored dataset's pre-existing condition is not this write's to answer
|
|
305
|
+
* for (#4463 D4).
|
|
306
|
+
*/
|
|
307
|
+
datasets?: readonly unknown[];
|
|
257
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Which package a write belongs to, and what that package is allowed to reach.
|
|
311
|
+
*
|
|
312
|
+
* [#9612] The maintainer's ruling, verbatim, is the product decision this type
|
|
313
|
+
* exists for:
|
|
314
|
+
*
|
|
315
|
+
* > 大客户(420 个对象),就不应该出现在一个软件包中啊,这就是划分软件包的价值。
|
|
316
|
+
* > 客户开发开发,校验是否也应该基于软件包
|
|
317
|
+
* > 当然这里面要考虑系统对象
|
|
318
|
+
*
|
|
319
|
+
* A tenant that has grown to 420 objects is not ONE package — it is many — and
|
|
320
|
+
* judging one package's write against all 420 is validating against the wrong
|
|
321
|
+
* unit, not merely validating slowly. A package's declared `dependencies`
|
|
322
|
+
* bound what it MAY reference, so `package + declared deps + platform/system`
|
|
323
|
+
* is a closure the platform computes EXACTLY rather than estimates. That is
|
|
324
|
+
* what separates this from "narrow to whatever the rule can be proven to
|
|
325
|
+
* reach", which was considered and refused: a per-rule proof is a second
|
|
326
|
+
* opinion that drifts the moment a rule changes.
|
|
327
|
+
*
|
|
328
|
+
* ⛔ Absent — or carrying a package whose dependency declaration cannot be
|
|
329
|
+
* read — narrows NOTHING. The whole collection is handed over, exactly as
|
|
330
|
+
* before. The fallback direction is deliberate and is the opposite of a size
|
|
331
|
+
* threshold: an unknown provenance buys MORE validation input, never less, so
|
|
332
|
+
* the gate never stops judging (the #9798 / #9261 / ADR-0110 D3 fail-open
|
|
333
|
+
* shape this card was explicitly forbidden from re-creating).
|
|
334
|
+
*/
|
|
335
|
+
interface RuntimePackageScope {
|
|
336
|
+
/** The package the written item belongs to. */
|
|
337
|
+
packageId: string;
|
|
338
|
+
/**
|
|
339
|
+
* Every OTHER package this one may reference — the transitive closure of the
|
|
340
|
+
* written package's declared `dependencies`. Resolved by the host, which is
|
|
341
|
+
* the side that holds the package registry; this module only reads the set.
|
|
342
|
+
*/
|
|
343
|
+
dependencies: readonly string[];
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* `objects` reduced to the written item's package closure (#9612).
|
|
347
|
+
*
|
|
348
|
+
* An object survives when ANY of these holds — the four limbs are the closure
|
|
349
|
+
* the ruling names, and each one is load-bearing:
|
|
350
|
+
*
|
|
351
|
+
* 1. it is a **platform / system object** ({@link isSystemObject}, imported
|
|
352
|
+
* rather than re-decided). ⛔ Unconditional: a package legitimately
|
|
353
|
+
* references `sys_*` objects it never declares a dependency on, and a
|
|
354
|
+
* closure that dropped them would manufacture "unresolved reference"
|
|
355
|
+
* findings that describe nothing — the false-positive class PR #7886
|
|
356
|
+
* already paid for on the `permissions` collection;
|
|
357
|
+
* 2. it carries **no package provenance** — a tenant-authored overlay row.
|
|
358
|
+
* Nothing declares what such a row may reference, so nothing bounds it and
|
|
359
|
+
* it is kept. Conservative by construction;
|
|
360
|
+
* 3. it belongs to the **written package** itself;
|
|
361
|
+
* 4. it belongs to one of that package's **declared dependencies**.
|
|
362
|
+
*
|
|
363
|
+
* Pure, allocation-light, and total: a non-object member is kept rather than
|
|
364
|
+
* inspected, because deciding it is not this function's job.
|
|
365
|
+
*/
|
|
366
|
+
declare function narrowObjectsToPackageClosure(objects: readonly unknown[], scope: RuntimePackageScope | undefined): readonly unknown[];
|
|
258
367
|
/** One rule's verdict at the runtime surface, carrying which rule produced it. */
|
|
259
368
|
interface RuntimeGateResult {
|
|
260
369
|
/** Findings the written item ADDED, severity `error` — the reason to refuse the write. */
|
|
@@ -275,6 +384,58 @@ declare function runtimeAuthoringRulesFor(type: string): readonly AuthoringRule[
|
|
|
275
384
|
declare function runtimeGatedTypes(): string[];
|
|
276
385
|
/** The stack key a metadata type occupies in a stack view, or null when unmapped. */
|
|
277
386
|
declare function stackKeyForType(type: string): string | null;
|
|
387
|
+
/**
|
|
388
|
+
* The baseline/candidate stack pair the gate judges one write against, or
|
|
389
|
+
* `null` when no snapshot can be built (unmapped type, non-object body).
|
|
390
|
+
*
|
|
391
|
+
* Exported (#8309) so the tests that measure per-write vs whole-stack
|
|
392
|
+
* agreement exercise the REAL construction instead of a hand-kept mirror —
|
|
393
|
+
* `validate-security-posture.runtime-surface.test.ts` used to mirror this
|
|
394
|
+
* logic in a local `wouldGateAdd`, which is exactly the drift surface a
|
|
395
|
+
* snapshot change here would have missed.
|
|
396
|
+
*
|
|
397
|
+
* Shape:
|
|
398
|
+
* - The baseline carries every context collection ({@link CONTEXT_STACK_KEYS})
|
|
399
|
+
* WITHOUT the written item. Anything found there is somebody else's
|
|
400
|
+
* pre-existing condition and is not this write's to answer for (#4463 D4 —
|
|
401
|
+
* the gate blocks new writes, never stored rows). Carrying the sibling
|
|
402
|
+
* collections in BOTH passes is what makes their findings cancel in the
|
|
403
|
+
* diff — and what gives the cross-collection rules the sibling collection
|
|
404
|
+
* they compare against, so the per-write verdict agrees with the
|
|
405
|
+
* whole-stack one instead of inventing findings (the 38-vs-4 measurement,
|
|
406
|
+
* PR #7886).
|
|
407
|
+
* - The candidate is the same context with this write's item added. When the
|
|
408
|
+
* written type IS one of the context collections (an `object`, `permission`
|
|
409
|
+
* or `book` write), the item REPLACES its stored self rather than appearing
|
|
410
|
+
* beside it — otherwise an update reads as a duplicate name, and for
|
|
411
|
+
* `objects` every lookup in the tenant's model would read as dangling. For
|
|
412
|
+
* any other type the item is the sole member of its own collection, so
|
|
413
|
+
* index-0 paths in the findings are unambiguously this write.
|
|
414
|
+
*
|
|
415
|
+
* Cost (the #4463 D2 question, measured rather than assumed): built per
|
|
416
|
+
* write, never cached. The construction is one filter + one spread over the
|
|
417
|
+
* written type's collection; the sibling collections are passed by reference.
|
|
418
|
+
* Over the shipped corpus (30 objects, 10 permission sets, 1 book) that is
|
|
419
|
+
* microseconds on a PUBLISH (never a draft autosave, D1) — a cache would buy
|
|
420
|
+
* nothing and would need cross-org invalidation the gate has no seam for.
|
|
421
|
+
*/
|
|
422
|
+
declare function buildRuntimeWriteSnapshots(args: {
|
|
423
|
+
/** Singular metadata type of the item being written. */
|
|
424
|
+
type: string;
|
|
425
|
+
/** The item body as it will be persisted. */
|
|
426
|
+
item: unknown;
|
|
427
|
+
/** Live resolution context from the host runtime. */
|
|
428
|
+
context?: RuntimeStackContext;
|
|
429
|
+
/**
|
|
430
|
+
* [#9612] The written item's package and what it may reach. Omitted — or
|
|
431
|
+
* carrying a package whose dependencies the host could not read — hands the
|
|
432
|
+
* rules the WHOLE `objects` collection, exactly as before.
|
|
433
|
+
*/
|
|
434
|
+
packageScope?: RuntimePackageScope;
|
|
435
|
+
}): {
|
|
436
|
+
baseline: AnyRec;
|
|
437
|
+
candidate: AnyRec;
|
|
438
|
+
} | null;
|
|
278
439
|
/**
|
|
279
440
|
* Judge one about-to-be-published metadata item against the shared registry.
|
|
280
441
|
*
|
|
@@ -292,8 +453,14 @@ declare function runRuntimeAuthoringRules(args: {
|
|
|
292
453
|
item: unknown;
|
|
293
454
|
/** Live resolution context from the host runtime. */
|
|
294
455
|
context?: RuntimeStackContext;
|
|
456
|
+
/**
|
|
457
|
+
* [#9612] The written item's package closure. Omit to judge against the
|
|
458
|
+
* whole collection — the pre-#9612 behaviour, and the behaviour every caller
|
|
459
|
+
* that cannot state a package keeps.
|
|
460
|
+
*/
|
|
461
|
+
packageScope?: RuntimePackageScope;
|
|
295
462
|
/** ADR-0080 SDUI manifest, when the host has one. */
|
|
296
463
|
sduiManifest?: unknown;
|
|
297
464
|
}): RuntimeGateResult;
|
|
298
465
|
|
|
299
|
-
export { AUTHORING_COMMANDS as A, EXPRESSION_INVALID as E, type RuntimeGateResult as R, AUTHORING_RULES as a, AUTHORING_SURFACES as b, type AuthoringCommand as c, type AuthoringFinding as d, type AuthoringRule as e, type AuthoringRuleContext as f, type AuthoringRuleInputTier as g, type AuthoringRuleRun as h, type AuthoringRuleTier as i, type AuthoringSeverity as j, type AuthoringSurface as k, type
|
|
466
|
+
export { AUTHORING_COMMANDS as A, EXPRESSION_INVALID as E, type RuntimeGateResult as R, AUTHORING_RULES as a, AUTHORING_SURFACES as b, type AuthoringCommand as c, type AuthoringFinding as d, type AuthoringRule as e, type AuthoringRuleContext as f, type AuthoringRuleInputTier as g, type AuthoringRuleRun as h, type AuthoringRuleTier as i, type AuthoringSeverity as j, type AuthoringSurface as k, type RuntimePackageScope as l, type RuntimeStackContext as m, authoringRulesFor as n, buildRuntimeWriteSnapshots as o, narrowObjectsToPackageClosure as p, runRuntimeAuthoringRules as q, runAuthoringRules as r, runtimeAuthoringRulesFor as s, runtimeGatedTypes as t, splitBySeverity as u, stackKeyForType as v };
|