@adrkit/evaluator 0.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/README.md +23 -0
- package/dist/LICENSE +201 -0
- package/dist/NOTICE +11 -0
- package/dist/assertions/evaluate.d.ts +36 -0
- package/dist/assertions/jsonpath.d.ts +20 -0
- package/dist/assertions/limits.d.ts +21 -0
- package/dist/assertions/registry.d.ts +20 -0
- package/dist/assertions/rego.d.ts +27 -0
- package/dist/catalog.d.ts +39 -0
- package/dist/compare.d.ts +10 -0
- package/dist/crypto/sha256.d.ts +10 -0
- package/dist/identity/directory.d.ts +23 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +2064 -0
- package/dist/keys.d.ts +27 -0
- package/dist/pass0.d.ts +19 -0
- package/dist/patch/project.d.ts +20 -0
- package/dist/report/aggregate.d.ts +21 -0
- package/dist/report/assemble.d.ts +16 -0
- package/dist/report/order.d.ts +19 -0
- package/dist/report/serialize.d.ts +42 -0
- package/dist/routing/accepted-assertion.d.ts +12 -0
- package/dist/routing/route.d.ts +18 -0
- package/dist/routing/target.d.ts +20 -0
- package/dist/rules/affects-overlap.d.ts +13 -0
- package/dist/rules/affects-resolvable.d.ts +14 -0
- package/dist/rules/assertions-compile.d.ts +12 -0
- package/dist/rules/assertions-pass.d.ts +13 -0
- package/dist/rules/context.d.ts +21 -0
- package/dist/rules/decider-resolvable.d.ts +10 -0
- package/dist/rules/expiry-sane.d.ts +11 -0
- package/dist/rules/id-unique.d.ts +11 -0
- package/dist/rules/kernel.d.ts +16 -0
- package/dist/rules/no-orphan-refs.d.ts +12 -0
- package/dist/rules/schema-valid.d.ts +11 -0
- package/dist/rules/scope-hierarchy.d.ts +14 -0
- package/dist/rules/supersession-consistent.d.ts +12 -0
- package/dist/targets/canonical.d.ts +37 -0
- package/dist/targets/package.d.ts +11 -0
- package/dist/targets/path.d.ts +10 -0
- package/dist/targets/registry.d.ts +11 -0
- package/dist/types.d.ts +360 -0
- package/package.json +54 -0
- package/src/assertions/evaluate.ts +214 -0
- package/src/assertions/jsonpath.ts +95 -0
- package/src/assertions/limits.ts +57 -0
- package/src/assertions/registry.ts +38 -0
- package/src/assertions/rego.ts +272 -0
- package/src/catalog.ts +263 -0
- package/src/compare.ts +13 -0
- package/src/crypto/sha256.ts +101 -0
- package/src/identity/directory.ts +69 -0
- package/src/index.ts +81 -0
- package/src/keys.ts +55 -0
- package/src/pass0.ts +163 -0
- package/src/patch/project.ts +51 -0
- package/src/report/aggregate.ts +59 -0
- package/src/report/assemble.ts +43 -0
- package/src/report/order.ts +53 -0
- package/src/report/serialize.ts +152 -0
- package/src/routing/accepted-assertion.ts +39 -0
- package/src/routing/route.ts +105 -0
- package/src/routing/target.ts +104 -0
- package/src/rules/affects-overlap.ts +55 -0
- package/src/rules/affects-resolvable.ts +83 -0
- package/src/rules/assertions-compile.ts +18 -0
- package/src/rules/assertions-pass.ts +21 -0
- package/src/rules/context.ts +31 -0
- package/src/rules/decider-resolvable.ts +55 -0
- package/src/rules/expiry-sane.ts +30 -0
- package/src/rules/id-unique.ts +57 -0
- package/src/rules/kernel.ts +33 -0
- package/src/rules/no-orphan-refs.ts +102 -0
- package/src/rules/schema-valid.ts +49 -0
- package/src/rules/scope-hierarchy.ts +108 -0
- package/src/rules/supersession-consistent.ts +138 -0
- package/src/targets/canonical.ts +114 -0
- package/src/targets/package.ts +41 -0
- package/src/targets/path.ts +32 -0
- package/src/targets/registry.ts +23 -0
- package/src/types.ts +445 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adrkit/evaluator — immutable Pass 0 contract types.
|
|
3
|
+
*
|
|
4
|
+
* All input shapes are deeply `readonly`; the pure evaluator mutates none of them
|
|
5
|
+
* (FR-006). Types marked "(runtime only)" exist only here and are never persisted or
|
|
6
|
+
* added to the committed schema (Principle V; C6). Where a contract shape already
|
|
7
|
+
* exists in `@adrkit/core` it is reused, never redefined (data-model §1).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
Adr,
|
|
12
|
+
AdrRef,
|
|
13
|
+
AffectsMatcher,
|
|
14
|
+
AffectsType,
|
|
15
|
+
Assertion,
|
|
16
|
+
DeterministicFinding,
|
|
17
|
+
EscalationReason,
|
|
18
|
+
Finding,
|
|
19
|
+
LintCorpusResult,
|
|
20
|
+
Severity,
|
|
21
|
+
} from '@adrkit/core';
|
|
22
|
+
import type { Pass0EscalationReason, ReasonCode, RuleId } from './catalog.ts';
|
|
23
|
+
|
|
24
|
+
export type { Pass0EscalationReason, ReasonCode, RuleId };
|
|
25
|
+
|
|
26
|
+
// Re-export the reused core contract types so evaluator modules and ports can import
|
|
27
|
+
// them from a single place without redefining shapes (data-model §1).
|
|
28
|
+
export type {
|
|
29
|
+
Adr,
|
|
30
|
+
AdrRef,
|
|
31
|
+
AffectsMatcher,
|
|
32
|
+
AffectsType,
|
|
33
|
+
Assertion,
|
|
34
|
+
DeterministicFinding,
|
|
35
|
+
EscalationReason,
|
|
36
|
+
Finding,
|
|
37
|
+
LintCorpusResult,
|
|
38
|
+
Severity,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/* ------------------------------------------------------------------ *
|
|
42
|
+
* JSON + scalars
|
|
43
|
+
* ------------------------------------------------------------------ */
|
|
44
|
+
|
|
45
|
+
export type JsonValue =
|
|
46
|
+
| null
|
|
47
|
+
| boolean
|
|
48
|
+
| number
|
|
49
|
+
| string
|
|
50
|
+
| readonly JsonValue[]
|
|
51
|
+
| { readonly [key: string]: JsonValue };
|
|
52
|
+
|
|
53
|
+
/** Strict `YYYY-MM-DD`; validated by the CLI boundary before entry. */
|
|
54
|
+
export type IsoDate = string;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Compact standard `JSON.stringify([record.log ?? "", record.path, assertion.id])`.
|
|
58
|
+
* Record path (not ADR id) prevents aliasing when `id-unique` fails but evaluation
|
|
59
|
+
* continues. The CLI rejects keys not byte-equal to this canonical form.
|
|
60
|
+
*/
|
|
61
|
+
export type AssertionKey = string;
|
|
62
|
+
|
|
63
|
+
/** Stable `${kind}:${id}` serialization used for equality/intersection. */
|
|
64
|
+
export type CanonicalTargetKey = string;
|
|
65
|
+
|
|
66
|
+
/* ------------------------------------------------------------------ *
|
|
67
|
+
* Target resolution model (§4)
|
|
68
|
+
* ------------------------------------------------------------------ */
|
|
69
|
+
|
|
70
|
+
export interface CanonicalTargetId {
|
|
71
|
+
readonly kind: AffectsType;
|
|
72
|
+
readonly id: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface DependencyEntry {
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly version?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface CatalogEntity {
|
|
80
|
+
readonly id: string;
|
|
81
|
+
readonly owner?: PrincipalRef;
|
|
82
|
+
}
|
|
83
|
+
export interface ResourceDescriptor {
|
|
84
|
+
readonly id: string;
|
|
85
|
+
readonly securitySurface?: boolean;
|
|
86
|
+
readonly production?: boolean;
|
|
87
|
+
readonly regulated?: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface ApiDescriptor {
|
|
90
|
+
readonly id: string;
|
|
91
|
+
readonly securitySurface?: boolean;
|
|
92
|
+
readonly production?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export interface DataDescriptor {
|
|
95
|
+
readonly id: string;
|
|
96
|
+
readonly residency?: string;
|
|
97
|
+
readonly regulated?: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Immutable per-type inventories. A missing inventory ⇒ that type's matchers are inert (C3). */
|
|
101
|
+
export interface TargetInventorySnapshots {
|
|
102
|
+
readonly trackedPaths?: readonly string[];
|
|
103
|
+
readonly dependencies?: readonly DependencyEntry[];
|
|
104
|
+
readonly entities?: readonly CatalogEntity[];
|
|
105
|
+
readonly resources?: readonly ResourceDescriptor[];
|
|
106
|
+
readonly apis?: readonly ApiDescriptor[];
|
|
107
|
+
readonly data?: readonly DataDescriptor[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface TargetResolutionContext {
|
|
111
|
+
/** Caller-supplied ADR-0009 current repo/log identity; undefined is unnamed local context. */
|
|
112
|
+
readonly log?: string;
|
|
113
|
+
readonly inventory: TargetInventorySnapshots;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface TargetResolution {
|
|
117
|
+
readonly status: 'resolved' | 'inert';
|
|
118
|
+
readonly ids: readonly CanonicalTargetId[];
|
|
119
|
+
readonly reason: ReasonCode;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A deterministic, pure resolver for one AffectsType. No I/O; never infers log context. */
|
|
123
|
+
export interface TargetResolverPort {
|
|
124
|
+
readonly type: AffectsType;
|
|
125
|
+
resolve(matcher: AffectsMatcher, context: TargetResolutionContext): TargetResolution;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Registry of resolver ports. Lookup miss ⇒ resolver-absent inert. */
|
|
129
|
+
export interface TargetResolutionRegistry {
|
|
130
|
+
get(type: AffectsType): TargetResolverPort | undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface FederatedLogSnapshot {
|
|
134
|
+
readonly log: string;
|
|
135
|
+
readonly adrIds: readonly string[];
|
|
136
|
+
readonly sourceRef?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* ------------------------------------------------------------------ *
|
|
140
|
+
* Assertion evaluation model (§5)
|
|
141
|
+
* ------------------------------------------------------------------ */
|
|
142
|
+
|
|
143
|
+
export interface ResolvedAssertionSource {
|
|
144
|
+
readonly fileContent?: string;
|
|
145
|
+
readonly sourceRef?: string;
|
|
146
|
+
readonly compiledArtifact?: RegoWasmPolicyEnvelopeV1;
|
|
147
|
+
}
|
|
148
|
+
export interface ResolvedAssertionInput {
|
|
149
|
+
readonly document?: JsonValue;
|
|
150
|
+
}
|
|
151
|
+
export interface AssertionInputSnapshot {
|
|
152
|
+
readonly sources: Readonly<Record<AssertionKey, ResolvedAssertionSource>>;
|
|
153
|
+
readonly inputs: Readonly<Record<AssertionKey, ResolvedAssertionInput>>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface RegoWasmPolicyEnvelopeV1 {
|
|
157
|
+
readonly mediaType: 'application/vnd.adrkit.rego-wasm-policy.v1+json';
|
|
158
|
+
readonly schemaVersion: 'adrkit.rego-wasm-policy/v1';
|
|
159
|
+
readonly source: string;
|
|
160
|
+
readonly sourceSha256: string;
|
|
161
|
+
readonly moduleBase64: string;
|
|
162
|
+
readonly moduleSha256: string;
|
|
163
|
+
readonly data: JsonValue;
|
|
164
|
+
readonly entrypoint: string;
|
|
165
|
+
readonly abi: { readonly major: 1; readonly minor: 3 };
|
|
166
|
+
readonly compiler: {
|
|
167
|
+
readonly name: 'opa';
|
|
168
|
+
readonly version: string;
|
|
169
|
+
readonly capabilitiesProfile: 'adrkit.rego-wasm.capabilities/v1';
|
|
170
|
+
readonly capabilitiesSha256: string;
|
|
171
|
+
};
|
|
172
|
+
readonly requiredHostBuiltins: readonly [];
|
|
173
|
+
readonly envelopeSha256: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export type AssertionEngineName = 'rego' | 'jsonpath' | 'grep' | 'custom';
|
|
177
|
+
|
|
178
|
+
export interface CompiledAssertion<E extends AssertionEngineName, Payload> {
|
|
179
|
+
readonly engine: E;
|
|
180
|
+
/** Deeply immutable by engine contract; only the owning port inspects this type. */
|
|
181
|
+
readonly payload: Payload;
|
|
182
|
+
readonly sourceRef?: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export type CompileOutcome<E extends AssertionEngineName, Payload> =
|
|
186
|
+
| { readonly ok: true; readonly compiled: CompiledAssertion<E, Payload> }
|
|
187
|
+
| { readonly ok: false; readonly reason: ReasonCode };
|
|
188
|
+
|
|
189
|
+
export type EvalOutcome =
|
|
190
|
+
| { readonly ok: true; readonly pass: boolean }
|
|
191
|
+
| { readonly ok: false; readonly reason: ReasonCode };
|
|
192
|
+
|
|
193
|
+
export interface SourceAssertionEnginePort<E extends AssertionEngineName, Payload> {
|
|
194
|
+
readonly engine: E;
|
|
195
|
+
readonly profile: 'source';
|
|
196
|
+
compile(effectiveSource: string, sourceRef?: string): CompileOutcome<E, Payload>;
|
|
197
|
+
evaluate(compiled: CompiledAssertion<E, Payload>, input: JsonValue): EvalOutcome;
|
|
198
|
+
}
|
|
199
|
+
export interface CompiledArtifactEnginePort<E extends AssertionEngineName, Payload> {
|
|
200
|
+
readonly engine: E;
|
|
201
|
+
readonly profile: 'compiled-artifact';
|
|
202
|
+
validateArtifact(artifact: RegoWasmPolicyEnvelopeV1): CompileOutcome<E, Payload>;
|
|
203
|
+
evaluate(compiled: CompiledAssertion<E, Payload>, input: JsonValue): EvalOutcome;
|
|
204
|
+
}
|
|
205
|
+
export type AssertionEnginePort<E extends AssertionEngineName, Payload> =
|
|
206
|
+
| SourceAssertionEnginePort<E, Payload>
|
|
207
|
+
| CompiledArtifactEnginePort<E, Payload>;
|
|
208
|
+
|
|
209
|
+
export interface AssertionEngineRegistry<RegoPayload, JsonPathPayload, GrepPayload, CustomPayload> {
|
|
210
|
+
readonly rego?: AssertionEnginePort<'rego', RegoPayload>;
|
|
211
|
+
readonly jsonpath?: AssertionEnginePort<'jsonpath', JsonPathPayload>;
|
|
212
|
+
readonly grep?: AssertionEnginePort<'grep', GrepPayload>;
|
|
213
|
+
readonly custom?: AssertionEnginePort<'custom', CustomPayload>;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Engine-owned immutable payload for the restricted JSONPath source profile. */
|
|
217
|
+
export interface JsonPathCompiledPayload {
|
|
218
|
+
readonly source: string;
|
|
219
|
+
readonly ast: unknown;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface ScopeContradictionEvidence {
|
|
223
|
+
readonly baseInputs?: Readonly<Record<AssertionKey, ResolvedAssertionInput>>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* ------------------------------------------------------------------ *
|
|
227
|
+
* Identity / decider directory (§6)
|
|
228
|
+
* ------------------------------------------------------------------ */
|
|
229
|
+
|
|
230
|
+
export type PrincipalRef = string;
|
|
231
|
+
export interface Principal {
|
|
232
|
+
readonly id: PrincipalRef;
|
|
233
|
+
readonly active: boolean;
|
|
234
|
+
readonly kind: 'human' | 'team';
|
|
235
|
+
}
|
|
236
|
+
export interface Team {
|
|
237
|
+
readonly id: PrincipalRef;
|
|
238
|
+
readonly members: readonly PrincipalRef[];
|
|
239
|
+
}
|
|
240
|
+
export interface CodeownersRule {
|
|
241
|
+
readonly pattern: string;
|
|
242
|
+
readonly owners: readonly PrincipalRef[];
|
|
243
|
+
}
|
|
244
|
+
export interface IdentityDirectorySnapshot {
|
|
245
|
+
readonly principals: readonly Principal[];
|
|
246
|
+
readonly teams: readonly Team[];
|
|
247
|
+
readonly codeowners?: readonly CodeownersRule[];
|
|
248
|
+
readonly catalogOwners?: Readonly<Record<string, readonly PrincipalRef[]>>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* ------------------------------------------------------------------ *
|
|
252
|
+
* Routing (§8)
|
|
253
|
+
* ------------------------------------------------------------------ */
|
|
254
|
+
|
|
255
|
+
export interface RoutingTriggerEvidence {
|
|
256
|
+
readonly costEvidence?: { readonly normalizedCost: number; readonly threshold: number };
|
|
257
|
+
readonly dataResidency?: { readonly present: boolean };
|
|
258
|
+
readonly humanRequested?: { readonly requester: PrincipalRef };
|
|
259
|
+
readonly securitySurfaceTargets?: ReadonlySet<CanonicalTargetKey>;
|
|
260
|
+
readonly regulatedTargets?: ReadonlySet<CanonicalTargetKey>;
|
|
261
|
+
readonly productionTargets?: ReadonlySet<CanonicalTargetKey>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface TriggerEvidenceStatus {
|
|
265
|
+
readonly reason: Pass0EscalationReason;
|
|
266
|
+
readonly status: 'proven' | 'not-proven';
|
|
267
|
+
readonly code: ReasonCode;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export type RouteTarget =
|
|
271
|
+
| { readonly kind: 'not-required'; readonly code: 'route.target.not-required' }
|
|
272
|
+
| {
|
|
273
|
+
readonly kind: 'resolved';
|
|
274
|
+
readonly human: PrincipalRef;
|
|
275
|
+
readonly via: 'deciders' | 'codeowners' | 'catalog';
|
|
276
|
+
readonly code: ReasonCode;
|
|
277
|
+
}
|
|
278
|
+
| { readonly kind: 'unresolved'; readonly code: 'route.target.unresolved' };
|
|
279
|
+
|
|
280
|
+
export interface RoutingDecision {
|
|
281
|
+
readonly escalate: boolean;
|
|
282
|
+
readonly reasons: readonly Pass0EscalationReason[];
|
|
283
|
+
readonly evidenceStatus: readonly TriggerEvidenceStatus[];
|
|
284
|
+
readonly target: RouteTarget;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* ------------------------------------------------------------------ *
|
|
288
|
+
* Rule results & runtime report (§7)
|
|
289
|
+
* ------------------------------------------------------------------ */
|
|
290
|
+
|
|
291
|
+
export type RuleStatus = 'pass' | 'fail' | 'inert' | 'not-evaluated';
|
|
292
|
+
|
|
293
|
+
export interface LowerLevelFindingEvidence {
|
|
294
|
+
readonly rule: string;
|
|
295
|
+
readonly path?: string;
|
|
296
|
+
readonly id?: string;
|
|
297
|
+
readonly field?: string;
|
|
298
|
+
readonly pattern?: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface RuleFinding {
|
|
302
|
+
readonly reason: ReasonCode;
|
|
303
|
+
readonly message?: string;
|
|
304
|
+
/** The ONLY identity field eligible for patch projection; MUST validate as core AdrRef. */
|
|
305
|
+
readonly adr?: AdrRef;
|
|
306
|
+
readonly candidateAdr?: AdrRef;
|
|
307
|
+
readonly relatedAdr?: AdrRef;
|
|
308
|
+
readonly matcherKey?: string;
|
|
309
|
+
readonly assertionKey?: AssertionKey;
|
|
310
|
+
readonly target?: CanonicalTargetId;
|
|
311
|
+
readonly recordPath?: string;
|
|
312
|
+
readonly field?: string;
|
|
313
|
+
readonly sourceRef?: string;
|
|
314
|
+
readonly lowerLevel?: LowerLevelFindingEvidence;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export interface RuleEvidence {
|
|
318
|
+
readonly resolvedTargets?: readonly CanonicalTargetId[];
|
|
319
|
+
readonly overlappingWith?: readonly string[];
|
|
320
|
+
readonly assertionTransitions?: readonly string[];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export interface RuleResult {
|
|
324
|
+
readonly rule: RuleId;
|
|
325
|
+
readonly status: RuleStatus;
|
|
326
|
+
readonly severity?: Severity;
|
|
327
|
+
readonly reason: ReasonCode;
|
|
328
|
+
readonly findings: readonly RuleFinding[];
|
|
329
|
+
readonly evidence?: RuleEvidence;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export interface Pass0Report {
|
|
333
|
+
readonly rubricVersion: string;
|
|
334
|
+
readonly proposalPath: string;
|
|
335
|
+
readonly results: readonly RuleResult[];
|
|
336
|
+
readonly routing: RoutingDecision;
|
|
337
|
+
readonly outcome: 'ok' | 'returned';
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* ------------------------------------------------------------------ *
|
|
341
|
+
* Patch (§9) + envelope (§10)
|
|
342
|
+
* ------------------------------------------------------------------ */
|
|
343
|
+
|
|
344
|
+
export interface EvaluationPatch {
|
|
345
|
+
readonly deterministicFindings: readonly DeterministicFinding[];
|
|
346
|
+
readonly escalate: boolean;
|
|
347
|
+
readonly escalationReasons: readonly EscalationReason[];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface Pass0Result {
|
|
351
|
+
readonly report: Pass0Report;
|
|
352
|
+
readonly patch: EvaluationPatch;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export interface RunMetadata {
|
|
356
|
+
readonly evaluatorVersion?: string;
|
|
357
|
+
readonly ranAt?: string;
|
|
358
|
+
readonly runId?: string;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* ------------------------------------------------------------------ *
|
|
362
|
+
* Proposal resolution & input contract (§3)
|
|
363
|
+
* ------------------------------------------------------------------ */
|
|
364
|
+
|
|
365
|
+
export type ProposalStatus = 'draft' | 'proposed';
|
|
366
|
+
|
|
367
|
+
export interface ProposalResolution {
|
|
368
|
+
readonly proposalPath: string;
|
|
369
|
+
readonly schemaFindings: readonly Finding[];
|
|
370
|
+
/** Present ONLY when schema-valid passed. When it fails, the other 10 rules are not-evaluated. */
|
|
371
|
+
readonly proposed?: Adr;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export interface Pass0InputContractError {
|
|
375
|
+
readonly code: 'candidate-status-not-proposal';
|
|
376
|
+
readonly proposalPath: string;
|
|
377
|
+
readonly actualStatus: 'accepted' | 'rejected' | 'superseded' | 'deprecated';
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export type Pass0Evaluation =
|
|
381
|
+
| { readonly kind: 'evaluated'; readonly result: Pass0Result }
|
|
382
|
+
| { readonly kind: 'input-error'; readonly error: Pass0InputContractError };
|
|
383
|
+
|
|
384
|
+
/* ------------------------------------------------------------------ *
|
|
385
|
+
* The evaluator input bundle (§2)
|
|
386
|
+
* ------------------------------------------------------------------ */
|
|
387
|
+
|
|
388
|
+
export interface Pass0Input<RegoPayload = unknown, JsonPathPayload = unknown, GrepPayload = unknown, CustomPayload = unknown> {
|
|
389
|
+
/** Full corpus lint result INCLUDING the candidate and malformed-file findings. */
|
|
390
|
+
readonly corpus: LintCorpusResult;
|
|
391
|
+
/** Identifies the proposal inside `corpus` (its `path`). */
|
|
392
|
+
readonly proposalPath: string;
|
|
393
|
+
readonly federatedLogs?: readonly FederatedLogSnapshot[];
|
|
394
|
+
/** Current repo/log identity for ADR-0009 `repo` qualification — NOT a record source log. */
|
|
395
|
+
readonly resolutionLog?: string;
|
|
396
|
+
readonly targets: TargetInventorySnapshots;
|
|
397
|
+
readonly targetRegistry: TargetResolutionRegistry;
|
|
398
|
+
readonly assertionInputs: AssertionInputSnapshot;
|
|
399
|
+
readonly assertionEngines: AssertionEngineRegistry<RegoPayload, JsonPathPayload, GrepPayload, CustomPayload>;
|
|
400
|
+
readonly identity?: IdentityDirectorySnapshot;
|
|
401
|
+
readonly scopeEvidence?: ScopeContradictionEvidence;
|
|
402
|
+
readonly routingEvidence?: RoutingTriggerEvidence;
|
|
403
|
+
/** REQUIRED caller-supplied evaluation date (YYYY-MM-DD). expiry-sane uses this; NO clock read. */
|
|
404
|
+
readonly evaluationDate: IsoDate;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* ------------------------------------------------------------------ *
|
|
408
|
+
* Versioned JSON wire bundle (§2.1) — data only, no ports/modules
|
|
409
|
+
* ------------------------------------------------------------------ */
|
|
410
|
+
|
|
411
|
+
export type TargetInventorySnapshotsJson = TargetInventorySnapshots;
|
|
412
|
+
export type IdentityDirectorySnapshotJson = IdentityDirectorySnapshot;
|
|
413
|
+
|
|
414
|
+
export interface SnapshotBundleJsonV1 {
|
|
415
|
+
readonly schemaVersion: 'adrkit.pass0.snapshot/v1';
|
|
416
|
+
readonly federatedLogs?: readonly FederatedLogSnapshot[];
|
|
417
|
+
/** Current repo/log identity for target resolution; omitted means unnamed local context. */
|
|
418
|
+
readonly log?: string;
|
|
419
|
+
readonly targets?: TargetInventorySnapshotsJson;
|
|
420
|
+
readonly assertionInputs?: {
|
|
421
|
+
readonly sources?: Readonly<
|
|
422
|
+
Record<
|
|
423
|
+
AssertionKey,
|
|
424
|
+
{
|
|
425
|
+
readonly fileContent?: string;
|
|
426
|
+
readonly sourceRef?: string;
|
|
427
|
+
readonly compiledArtifact?: RegoWasmPolicyEnvelopeV1;
|
|
428
|
+
}
|
|
429
|
+
>
|
|
430
|
+
>;
|
|
431
|
+
readonly inputs?: Readonly<Record<AssertionKey, { readonly document: JsonValue }>>;
|
|
432
|
+
};
|
|
433
|
+
readonly identity?: IdentityDirectorySnapshotJson;
|
|
434
|
+
readonly scopeEvidence?: {
|
|
435
|
+
readonly baseInputs?: Readonly<Record<AssertionKey, { readonly document: JsonValue }>>;
|
|
436
|
+
};
|
|
437
|
+
readonly routingEvidence?: {
|
|
438
|
+
readonly costEvidence?: { readonly normalizedCost: number; readonly threshold: number };
|
|
439
|
+
readonly dataResidency?: { readonly present: boolean };
|
|
440
|
+
readonly humanRequested?: { readonly requester: string };
|
|
441
|
+
readonly securitySurfaceTargetKeys?: readonly CanonicalTargetKey[];
|
|
442
|
+
readonly regulatedTargetKeys?: readonly CanonicalTargetKey[];
|
|
443
|
+
readonly productionTargetKeys?: readonly CanonicalTargetKey[];
|
|
444
|
+
};
|
|
445
|
+
}
|