@geonosis/policy 1.0.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/LICENSE +202 -0
- package/README.md +107 -0
- package/dist/chunk-JICJ4XEX.js +17 -0
- package/dist/drizzle/index.d.ts +43 -0
- package/dist/drizzle/index.js +54 -0
- package/dist/index.d.ts +375 -0
- package/dist/index.js +779 -0
- package/dist/medusa/index.d.ts +81 -0
- package/dist/medusa/index.js +59 -0
- package/dist/permissions/index.d.ts +126 -0
- package/dist/permissions/index.js +103 -0
- package/dist/types-DzC5zTZ8.d.ts +202 -0
- package/package.json +53 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { a as PolicyRuleRow, b as PolicyAdapter, c as PolicyKindSpec, d as PolicyRule, e as PolicyTierSpec, f as Policy, P as PolicyQuery, g as PolicyData, h as PolicyDecision, i as PolicyScope, U as UnusableRule, J as JournalObservationEntry, j as PolicyJournal, k as PolicyConfigReader, l as PolicyRuleReader, m as PolicyReading } from './types-DzC5zTZ8.js';
|
|
2
|
+
export { A as Awaitable, n as POLICY_FALLBACK, o as POLICY_INVALID_VALUE, p as PolicyJournalEntry, S as SchemaLike } from './types-DzC5zTZ8.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* One suite every storage adapter passes.
|
|
6
|
+
*
|
|
7
|
+
* A real Medusa module and a real drizzle table are the consumers' to run this against; what runs
|
|
8
|
+
* here is a stub, which is the point — the checks are about what an adapter must MEAN, and neither
|
|
9
|
+
* store's presence changes one of them.
|
|
10
|
+
*
|
|
11
|
+
* It answers with a report rather than an exit code: a gate that cannot say what it measured has
|
|
12
|
+
* not been shown to measure anything.
|
|
13
|
+
*/
|
|
14
|
+
type ConformanceCheck = {
|
|
15
|
+
detail?: string;
|
|
16
|
+
name: string;
|
|
17
|
+
passed: boolean;
|
|
18
|
+
};
|
|
19
|
+
type ConformanceReport = {
|
|
20
|
+
adapter: string;
|
|
21
|
+
checks: ConformanceCheck[];
|
|
22
|
+
passed: boolean;
|
|
23
|
+
};
|
|
24
|
+
type PolicyAdapterHarness = {
|
|
25
|
+
/** An adapter whose store holds exactly this, and a way to read what its journal received. */
|
|
26
|
+
create: (input: {
|
|
27
|
+
config?: Record<string, unknown>;
|
|
28
|
+
rows: readonly PolicyRuleRow[];
|
|
29
|
+
}) => {
|
|
30
|
+
adapter: PolicyAdapter;
|
|
31
|
+
written: () => readonly unknown[];
|
|
32
|
+
};
|
|
33
|
+
/** An adapter over a store that is DOWN. Swallowing belongs inside the adapter, not around it. */
|
|
34
|
+
createBroken: () => PolicyAdapter;
|
|
35
|
+
name: string;
|
|
36
|
+
};
|
|
37
|
+
declare const runPolicyAdapterConformance: (harness: PolicyAdapterHarness) => Promise<ConformanceReport>;
|
|
38
|
+
|
|
39
|
+
type PolicyInput = {
|
|
40
|
+
/** What policy may constrain. A kind with no reader is an inert knob; a reader with no kind cannot be authored. */
|
|
41
|
+
kinds: readonly (PolicyKindSpec | string)[];
|
|
42
|
+
/**
|
|
43
|
+
* May the overriding tier beat a rule that does not say either way?
|
|
44
|
+
*
|
|
45
|
+
* dielime says yes (`rule.overridable !== false`), musa says no (`&& winner.overridable`).
|
|
46
|
+
* Neither is wrong for the other's business, so it is declared rather than assumed.
|
|
47
|
+
*/
|
|
48
|
+
overridableByDefault?: boolean;
|
|
49
|
+
rules?: readonly PolicyRule[];
|
|
50
|
+
/** VAGUEST first — the weight of a key is derived from where it sits. */
|
|
51
|
+
scopeKeys?: readonly string[];
|
|
52
|
+
/** STRONGEST first. */
|
|
53
|
+
tiers: readonly (PolicyTierSpec | string)[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Declare a policy: the authorities, the things they may constrain, the subjects they may be aimed
|
|
57
|
+
* at, and — optionally — the rules themselves.
|
|
58
|
+
*
|
|
59
|
+
* A policy with no rules is INERT. Every read falls through to the caller's own constant and says
|
|
60
|
+
* so, which is the posture the mechanism is built for: the loader is generic, the domain limits
|
|
61
|
+
* live in data, and the kernel does nothing at all until someone writes a rule.
|
|
62
|
+
*/
|
|
63
|
+
declare const definePolicy: (input: PolicyInput) => Policy;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The precedence lattice — deciding which authority wins when several speak at once.
|
|
67
|
+
*
|
|
68
|
+
* A business is governed by several at a time: law, a signed agreement, its own SOP, a buyer's
|
|
69
|
+
* stated preference, the strategy currently running, an operator override typed at 6pm on a Friday.
|
|
70
|
+
* They contradict each other constantly, so "which one wins" must not be an accident of evaluation
|
|
71
|
+
* order — it is a declared ordering, and every decision carries a TRACE naming the winner and what
|
|
72
|
+
* it suppressed.
|
|
73
|
+
*
|
|
74
|
+
* Nothing in this file names a tier, a kind or a scope key. Two consumers wrote this lattice
|
|
75
|
+
* independently and disagreed on all three (dielime's strongest tier is `regulatory`, musa's is
|
|
76
|
+
* `physics`), which is why every one of them is data.
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* The weight of a scope key, derived from where it was declared.
|
|
80
|
+
*
|
|
81
|
+
* Powers of two in declaration order, so a narrower key can never be outvoted by an accumulation of
|
|
82
|
+
* vaguer ones: an order-scoped rule beats one scoped to region + category + group together, which
|
|
83
|
+
* is the intent every time someone writes an order-scoped exception. Both consumers wrote exactly
|
|
84
|
+
* that by hand and each needed a test to catch a key that had been given no weight at all — a rule
|
|
85
|
+
* that matches but always loses. Deriving it designs the failure out.
|
|
86
|
+
*/
|
|
87
|
+
declare const specificityOf: (scopeKeys: readonly string[], scope: PolicyScope | undefined) => number;
|
|
88
|
+
/**
|
|
89
|
+
* Does this rule reach this subject?
|
|
90
|
+
*
|
|
91
|
+
* A rule scoped on a key the query does not carry does NOT apply, and neither does one scoped on a
|
|
92
|
+
* key this build has never heard of. That is the safe direction — a rule cannot reach a subject we
|
|
93
|
+
* know nothing about — but refusing quietly is the same failure in a new coat, which is what
|
|
94
|
+
* `unsupportedScopesOf` is for.
|
|
95
|
+
*/
|
|
96
|
+
declare const appliesTo: (rule: PolicyRule, query: PolicyQuery, scopeKeys: readonly string[]) => boolean;
|
|
97
|
+
declare const unsupportedScopesOf: (rules: readonly PolicyRule[], scopeKeys: readonly string[]) => {
|
|
98
|
+
id: string;
|
|
99
|
+
keys: string[];
|
|
100
|
+
}[];
|
|
101
|
+
declare const unusableRulesOf: (rules: readonly PolicyRule[], data: Pick<PolicyData, "kinds" | "tiers">) => UnusableRule[];
|
|
102
|
+
declare const usableRulesOf: (rules: readonly PolicyRule[], data: Pick<PolicyData, "kinds" | "tiers">) => PolicyRule[];
|
|
103
|
+
declare const unsetKindsOf: (rules: readonly PolicyRule[], kinds: readonly PolicyKindSpec[]) => string[];
|
|
104
|
+
/**
|
|
105
|
+
* Resolve one kind for one subject, with the whole trace.
|
|
106
|
+
*
|
|
107
|
+
* `undefined` when no rule speaks — silence is a legitimate answer and the caller's own default
|
|
108
|
+
* takes over. Never a thrown error: a missing rule is the normal state of most subjects, and of
|
|
109
|
+
* every subject in a build nobody has written a policy for yet.
|
|
110
|
+
*/
|
|
111
|
+
declare const resolveConstraint: <V = unknown>(data: PolicyData, kind: string, query?: PolicyQuery, rules?: readonly PolicyRule[]) => PolicyDecision<V> | undefined;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The learning loop — a business improves from its own operations, visibly, versioned and
|
|
115
|
+
* reversibly.
|
|
116
|
+
*
|
|
117
|
+
* Shaped after ACE (Generator / Reflector / Curator): the playbook EVOLVES by increments rather
|
|
118
|
+
* than rewrites, which is what stops accumulated context from collapsing as it grows.
|
|
119
|
+
*
|
|
120
|
+
* observeJournal deterministic signal extraction — no model, fully testable. The strongest
|
|
121
|
+
* signals are BEHAVIOURAL: a human reversing an automated decision is unambiguous
|
|
122
|
+
* feedback in a way a survey never is.
|
|
123
|
+
* reflect folds repeats into one candidate each. An agent may propose candidates too;
|
|
124
|
+
* they enter through this same gate.
|
|
125
|
+
* curate merges by stable id, ACCUMULATING evidence instead of overwriting statements.
|
|
126
|
+
* promote evidence-gated. demote is always available and always recorded — auditable
|
|
127
|
+
* unlearning is the point.
|
|
128
|
+
*
|
|
129
|
+
* The safety rail is the lattice: an active learning becomes a rule at the ADVISORY tier, which
|
|
130
|
+
* can only ever fill silence. The loop can suggest; it can never quietly change what a business does.
|
|
131
|
+
*/
|
|
132
|
+
type LearningKind =
|
|
133
|
+
/** A working practice worth repeating. */
|
|
134
|
+
'heuristic'
|
|
135
|
+
/** A trap worth naming, so the next session starts knowing it. */
|
|
136
|
+
| 'pitfall'
|
|
137
|
+
/** Policy and the people running the business disagree, repeatedly. */
|
|
138
|
+
| 'rule-friction'
|
|
139
|
+
/** The same sequence keeps being run by hand — name it. */
|
|
140
|
+
| 'macro'
|
|
141
|
+
/** A knob that exists but nothing sets, so a hardcoded default rules instead. */
|
|
142
|
+
| 'unset-policy';
|
|
143
|
+
type LearningStatus = 'active' | 'candidate' | 'demoted';
|
|
144
|
+
type LearningEvidence = {
|
|
145
|
+
/** Ids of the journal entries that support it. */
|
|
146
|
+
journalRefs: string[];
|
|
147
|
+
/** Measured effect, when there is one. */
|
|
148
|
+
metric?: {
|
|
149
|
+
delta: number;
|
|
150
|
+
name: string;
|
|
151
|
+
};
|
|
152
|
+
observations: number;
|
|
153
|
+
updatedAt: string;
|
|
154
|
+
};
|
|
155
|
+
type Learning = {
|
|
156
|
+
demotedReason?: string;
|
|
157
|
+
evidence: LearningEvidence;
|
|
158
|
+
/** Stable key — curation merges on this, so evidence accumulates. */
|
|
159
|
+
id: string;
|
|
160
|
+
kind: LearningKind;
|
|
161
|
+
scope?: PolicyScope;
|
|
162
|
+
/** What was learned, in words a human can audit and edit. */
|
|
163
|
+
statement: string;
|
|
164
|
+
status: LearningStatus;
|
|
165
|
+
/** The advisory constraint this implies, if any. */
|
|
166
|
+
suggests?: {
|
|
167
|
+
kind: string;
|
|
168
|
+
value: unknown;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
type Playbook = {
|
|
172
|
+
entries: Learning[];
|
|
173
|
+
version: number;
|
|
174
|
+
};
|
|
175
|
+
type Observation = {
|
|
176
|
+
id: string;
|
|
177
|
+
journalRefs: string[];
|
|
178
|
+
kind: LearningKind;
|
|
179
|
+
scope?: PolicyScope;
|
|
180
|
+
statement: string;
|
|
181
|
+
suggests?: {
|
|
182
|
+
kind: string;
|
|
183
|
+
value: unknown;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
declare const emptyPlaybook: () => Playbook;
|
|
187
|
+
/** Repeated evidence, not one lucky quarter. */
|
|
188
|
+
declare const DEFAULT_MIN_OBSERVATIONS = 3;
|
|
189
|
+
declare class LearningError extends Error {
|
|
190
|
+
readonly code: 'INSUFFICIENT_EVIDENCE' | 'UNKNOWN_LEARNING';
|
|
191
|
+
constructor(code: 'INSUFFICIENT_EVIDENCE' | 'UNKNOWN_LEARNING', message: string);
|
|
192
|
+
}
|
|
193
|
+
type ObserveOptions = {
|
|
194
|
+
/** How few repeats of one operation are still a one-off. */
|
|
195
|
+
minRepeatsForMacro?: number;
|
|
196
|
+
/** The prefix a refusal carries, so friction is countable per rule. That word is a repo's own. */
|
|
197
|
+
refusalPrefix?: string;
|
|
198
|
+
/** What a human doing the undoing tends to call it. */
|
|
199
|
+
reversalVerbs?: RegExp;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* The deterministic signals in a journal. Only behaviour that actually happened counts; nothing is
|
|
203
|
+
* inferred from intent alone.
|
|
204
|
+
*/
|
|
205
|
+
declare const observeJournal: (entries: readonly JournalObservationEntry[], options?: ObserveOptions) => Observation[];
|
|
206
|
+
/** Fold repeats into one candidate each — the statistical reflector. */
|
|
207
|
+
declare const reflect: (observations: readonly Observation[], now?: Date) => Learning[];
|
|
208
|
+
/**
|
|
209
|
+
* Merge candidates into the playbook. Evidence ACCUMULATES, and a statement is only refreshed while
|
|
210
|
+
* the entry is still under review — an active learning's wording is stable, which is what makes the
|
|
211
|
+
* playbook readable a year later.
|
|
212
|
+
*/
|
|
213
|
+
declare const curate: (playbook: Playbook, candidates: readonly Learning[]) => Playbook;
|
|
214
|
+
declare const promote: (playbook: Playbook, id: string, options?: {
|
|
215
|
+
metric?: {
|
|
216
|
+
delta: number;
|
|
217
|
+
name: string;
|
|
218
|
+
};
|
|
219
|
+
minObservations?: number;
|
|
220
|
+
}) => Playbook;
|
|
221
|
+
/** Demotion is always available and always recorded — auditable unlearning. */
|
|
222
|
+
declare const demote: (playbook: Playbook, id: string, reason: string) => Playbook;
|
|
223
|
+
/**
|
|
224
|
+
* Active learnings that imply a constraint, as rules at the tier the policy calls advisory.
|
|
225
|
+
*
|
|
226
|
+
* dielime writes `tier: 'learned'` into this function. Here the tier is read off the lattice,
|
|
227
|
+
* because a policy that declares none has nowhere safe to put a suggestion — and quietly choosing
|
|
228
|
+
* one would hand a suggestion the authority of an SOP.
|
|
229
|
+
*/
|
|
230
|
+
declare const playbookRules: (policy: Policy, playbook: Playbook) => PolicyRule[];
|
|
231
|
+
/** The playbook as agent-readable guidance — a delta on top of a built prompt, never a replacement. */
|
|
232
|
+
declare const playbookGuidance: (playbook: Playbook) => string;
|
|
233
|
+
|
|
234
|
+
/** One journal row derived from something that happened. */
|
|
235
|
+
type DomainJournalRow = {
|
|
236
|
+
actor_id: null | string;
|
|
237
|
+
actor_kind: 'system' | 'user';
|
|
238
|
+
event_name: string;
|
|
239
|
+
op: string;
|
|
240
|
+
subject: string;
|
|
241
|
+
};
|
|
242
|
+
type JournalRowOptions = {
|
|
243
|
+
/** Where this build puts the human who caused it, when there is one. */
|
|
244
|
+
actorKeys?: readonly string[];
|
|
245
|
+
/** Where this build puts the id of the thing an event is about. */
|
|
246
|
+
subjectKeys: readonly string[];
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* The journal row for one domain event, or `null` when there is nothing countable to say.
|
|
250
|
+
*
|
|
251
|
+
* The learning loop reads four signals: a human reversing an automated decision, repeated refusals
|
|
252
|
+
* of the same rule, readers falling back to their own defaults, and the same operation run over and
|
|
253
|
+
* over. A reader journals its own fallbacks, so the third arrives on its own — the other three are
|
|
254
|
+
* computed from things that HAPPENED, and without this they are computed over an empty table.
|
|
255
|
+
*
|
|
256
|
+
* The keys are the caller's, with no default: which field carries the id of the thing an event is
|
|
257
|
+
* about is a fact about one system, and guessing would be quietly wrong rather than loudly absent.
|
|
258
|
+
*/
|
|
259
|
+
declare const journalRowForEvent: (eventName: string, data: unknown, options: JournalRowOptions) => DomainJournalRow | null;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The policy as prose, generated beside the data it renders.
|
|
263
|
+
*
|
|
264
|
+
* musa checks in `policy/policy.json` and a `POLICY.md` written from it on every change, and the
|
|
265
|
+
* argument for generating rather than writing it is in that file's own history: two of its sections
|
|
266
|
+
* were prose, and both had gone stale and were telling agents the opposite of what the code did. A
|
|
267
|
+
* markdown that has to be remembered separately drifts, and a drifted one is worse than none — it
|
|
268
|
+
* reads authoritative while the engine enforces something else.
|
|
269
|
+
*
|
|
270
|
+
* So every count, every precedence sentence and every honesty report below is DERIVED.
|
|
271
|
+
*/
|
|
272
|
+
type PolicyMarkdownOptions = {
|
|
273
|
+
generator?: string;
|
|
274
|
+
playbook?: Playbook;
|
|
275
|
+
rules?: readonly PolicyRule[];
|
|
276
|
+
/** What a reader should edit instead of this file. */
|
|
277
|
+
source?: string;
|
|
278
|
+
title?: string;
|
|
279
|
+
};
|
|
280
|
+
declare const generatePolicyMarkdown: (policy: Policy, options?: PolicyMarkdownOptions) => string;
|
|
281
|
+
type DescribePolicyOptions = {
|
|
282
|
+
/** Instructions ride in EVERY context, so this stays bounded. */
|
|
283
|
+
maxRules?: number;
|
|
284
|
+
playbook?: Playbook;
|
|
285
|
+
rules?: readonly PolicyRule[];
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* The same policy, bounded, for the channel an agent is handed when it connects.
|
|
289
|
+
*
|
|
290
|
+
* Persisting policy is only half the job: an agent that has to discover the rules by tripping over
|
|
291
|
+
* them will trip over them in front of a customer.
|
|
292
|
+
*/
|
|
293
|
+
declare const describePolicy: (policy: Policy, options?: DescribePolicyOptions) => string;
|
|
294
|
+
|
|
295
|
+
type ReadPolicyOptions<V> = {
|
|
296
|
+
config?: PolicyConfigReader;
|
|
297
|
+
/** The caller's own constant — the floor, and the type of the answer. */
|
|
298
|
+
fallback: V;
|
|
299
|
+
journal?: PolicyJournal;
|
|
300
|
+
/** A named operation, so repeats become countable per operation rather than per request. */
|
|
301
|
+
op?: string;
|
|
302
|
+
rule?: PolicyRuleReader;
|
|
303
|
+
/** Opt out of recording. Only for a caller that runs per request inside a loop. */
|
|
304
|
+
silent?: boolean;
|
|
305
|
+
/** What the decision is about — an order id, a company id. */
|
|
306
|
+
subject?: string;
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Read one constraint, with the caller's own default as the floor.
|
|
310
|
+
*
|
|
311
|
+
* This is what a reader calls instead of reaching for a hardcoded constant. It answers with the
|
|
312
|
+
* resolved value when policy speaks, the admin-set value when it does not, and the caller's own
|
|
313
|
+
* constant when nobody has said anything — and, the part that matters, it RECORDS that last case,
|
|
314
|
+
* so "nothing sets this" becomes a countable signal rather than a silence indistinguishable from
|
|
315
|
+
* working.
|
|
316
|
+
*
|
|
317
|
+
* The resolution order is authored rule → config row → constant. A rule wins because it carries an
|
|
318
|
+
* authority, a subject and a reason where a config row carries only a value; a config row beats the
|
|
319
|
+
* constant because a value an admin actually typed must beat one a developer compiled in, or the
|
|
320
|
+
* settings screen is a screen of knobs nothing reads.
|
|
321
|
+
*/
|
|
322
|
+
declare const readPolicy: <V>(policy: Policy, kind: string, query: PolicyQuery | undefined, options: ReadPolicyOptions<V>) => Promise<PolicyReading<V>>;
|
|
323
|
+
type PolicyOrDefaultInput<V> = {
|
|
324
|
+
fallback: V;
|
|
325
|
+
journal?: PolicyJournal;
|
|
326
|
+
kind: string;
|
|
327
|
+
op: string;
|
|
328
|
+
subject?: string;
|
|
329
|
+
value: V;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Apply a resolved value, falling back to the caller's own default when it turns out to be
|
|
333
|
+
* unusable.
|
|
334
|
+
*
|
|
335
|
+
* A validator that refuses a zero-day expiry or a zero-hour SLA is right to. But a number an admin
|
|
336
|
+
* mistypes would then throw inside the work it was informing, and every one of those operations
|
|
337
|
+
* would fail until somebody noticed — the customer paying for a misconfiguration. An unusable value
|
|
338
|
+
* is a gap that arrived through a different door, so it is treated like every other gap: recorded
|
|
339
|
+
* once per boot, and the default takes over while the mistake stays visible.
|
|
340
|
+
*
|
|
341
|
+
* A default that ALSO fails still throws. That is a bug in our own code rather than a
|
|
342
|
+
* misconfiguration, and swallowing it would leave the caller with no value at all.
|
|
343
|
+
*/
|
|
344
|
+
declare const policyOrDefault: <T, V>(policy: Policy, input: PolicyOrDefaultInput<V>, apply: (value: V) => T) => Promise<T>;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* A stored row, as a rule the lattice can use.
|
|
348
|
+
*
|
|
349
|
+
* This is the one part of a storage adapter that is not the store's own vocabulary, so it lives
|
|
350
|
+
* once: two adapters that each did their own mapping would drift on what `overridable: true` means,
|
|
351
|
+
* or on whether a null scope is a scope of nothing.
|
|
352
|
+
*/
|
|
353
|
+
declare const toPolicyRule: (row: PolicyRuleRow) => PolicyRule;
|
|
354
|
+
/** The rules still in force. A retired row stays readable — it just stops deciding. */
|
|
355
|
+
declare const toPolicyRules: (rows: readonly PolicyRuleRow[]) => PolicyRule[];
|
|
356
|
+
|
|
357
|
+
/** A rule as a store hands it back: the kernel's shape, plus whether it is still in force. */
|
|
358
|
+
type ExistingPolicyRule = PolicyRule & {
|
|
359
|
+
status?: string;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Which seed rules to author, given what is already there. Idempotent by ID and by COVERAGE.
|
|
363
|
+
*
|
|
364
|
+
* The coverage half is the one that was learned the hard way: a first seeding run produced two
|
|
365
|
+
* active rules for one constraint with identical scope and value — the seed's, and one an admin had
|
|
366
|
+
* authored by hand two days earlier. Same effect, two keys, and a conflict the lattice reports and
|
|
367
|
+
* a human has to unpick.
|
|
368
|
+
*
|
|
369
|
+
* A seed provides DEFAULTS. If the business has already said something about a constraint at the
|
|
370
|
+
* same scope, it has spoken, and the seed's opinion is not wanted. A RETIRED rule is not a current
|
|
371
|
+
* opinion, so it does not block.
|
|
372
|
+
*/
|
|
373
|
+
declare const rulesToSeed: <T extends PolicyRule>(seed: readonly T[], existing: readonly ExistingPolicyRule[]) => T[];
|
|
374
|
+
|
|
375
|
+
export { type ConformanceCheck, type ConformanceReport, DEFAULT_MIN_OBSERVATIONS, type DescribePolicyOptions, type DomainJournalRow, type ExistingPolicyRule, JournalObservationEntry, type JournalRowOptions, type Learning, LearningError, type LearningEvidence, type LearningKind, type LearningStatus, type Observation, type ObserveOptions, type Playbook, Policy, PolicyAdapter, type PolicyAdapterHarness, PolicyConfigReader, PolicyData, PolicyDecision, type PolicyInput, PolicyJournal, PolicyKindSpec, type PolicyMarkdownOptions, type PolicyOrDefaultInput, PolicyQuery, PolicyReading, PolicyRule, PolicyRuleReader, PolicyRuleRow, PolicyScope, PolicyTierSpec, type ReadPolicyOptions, UnusableRule, appliesTo, curate, definePolicy, demote, describePolicy, emptyPlaybook, generatePolicyMarkdown, journalRowForEvent, observeJournal, playbookGuidance, playbookRules, policyOrDefault, promote, readPolicy, reflect, resolveConstraint, rulesToSeed, runPolicyAdapterConformance, specificityOf, toPolicyRule, toPolicyRules, unsetKindsOf, unsupportedScopesOf, unusableRulesOf, usableRulesOf };
|