@ai-sdlc/orchestrator 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/file-walker.js +5 -0
- package/dist/cli/commands/git-remote.js +1 -1
- package/dist/cli/commands/init-features.d.ts +85 -0
- package/dist/cli/commands/init-features.js +443 -23
- package/dist/cli/commands/init-templates.d.ts +45 -5
- package/dist/cli/commands/init-templates.js +80 -6
- package/dist/cycle-utils.js +14 -1
- package/dist/execute.js +29 -8
- package/dist/fix-review.js +1 -1
- package/dist/journey/metric-snapshot.d.ts +403 -0
- package/dist/journey/metric-snapshot.js +370 -0
- package/dist/otel-exporter.js +0 -3
- package/dist/runners/claude-code.js +3 -3
- package/dist/runners/runner-registry.js +1 -1
- package/dist/runtime/attestations.js +15 -5
- package/dist/sa-scoring/exemplar-bank.js +3 -1
- package/dist/shared.d.ts +28 -0
- package/dist/shared.js +37 -0
- package/dist/webhook-manager.js +7 -1
- package/package.json +12 -7
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-0018 Phase 4 — MetricSnapshot resource read API (OQ-5 resolution).
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* AC #1: MetricSnapshot schema (spec/schemas/metric-snapshot.v1.schema.json)
|
|
6
|
+
* AC #2: MetricSnapshot read API — `getLatestMetricSnapshot(journey, metricId)`
|
|
7
|
+
* AC #3: Stale-metric detection (default 30d; per-Soul configurable) with
|
|
8
|
+
* `Decision: journey-metric-stale` + warn-and-unknown Cκ behavior
|
|
9
|
+
* AC #4: Graduated Eρ₅ degradation (0-30/30-60/60-90/90+ thresholds + Decisions)
|
|
10
|
+
* AC #5: Per-Soul `accessibility.auditOverdueGracePolicy` modes
|
|
11
|
+
* AC #6: RFC-0022 multi-posture composition (strictest cadence applies)
|
|
12
|
+
*
|
|
13
|
+
* ### OQ-5 design summary
|
|
14
|
+
*
|
|
15
|
+
* Operators supply MetricSnapshot resources from their analytics pipeline
|
|
16
|
+
* (Mixpanel, Amplitude, Heap, internal-pipeline). The framework reads
|
|
17
|
+
* `completion-rate` and other journey-success values; it does NOT compute
|
|
18
|
+
* them from an analytics backend.
|
|
19
|
+
*
|
|
20
|
+
* Staleness: when `recordedAt` is older than `thresholdDays` (default 30),
|
|
21
|
+
* the scorer treats the metric as an unknown input (warn-and-unknown, NOT
|
|
22
|
+
* fail-closed). A `Decision: journey-metric-stale` is emitted for operator
|
|
23
|
+
* batch review.
|
|
24
|
+
*
|
|
25
|
+
* ### OQ-6 design summary
|
|
26
|
+
*
|
|
27
|
+
* When a journey's accessibility audit is overdue, Eρ₅ degrades on this
|
|
28
|
+
* graduated schedule (per-Soul policy `auditOverdueGracePolicy`):
|
|
29
|
+
*
|
|
30
|
+
* Policy `graduated` (default):
|
|
31
|
+
* 0–30d past cadence → warn only (`journey-audit-overdue-warn`)
|
|
32
|
+
* 30–60d → Eρ₅ -25% (`journey-audit-overdue-graduated`)
|
|
33
|
+
* 60–90d → Eρ₅ -50% (`journey-audit-overdue-graduated`)
|
|
34
|
+
* 90d+ → effective block (`journey-audit-overdue-blocking`)
|
|
35
|
+
*
|
|
36
|
+
* Policy `binary-30d`:
|
|
37
|
+
* 0–30d → no impact (SOC2/HIPAA early-warning model)
|
|
38
|
+
* 30d+ → immediate Eρ₅ fail
|
|
39
|
+
*
|
|
40
|
+
* Policy `hard-block`:
|
|
41
|
+
* Immediate Eρ₅ fail at cadence+0d (strictest, no grace)
|
|
42
|
+
*
|
|
43
|
+
* ### RFC-0022 multi-posture composition (AC #6)
|
|
44
|
+
*
|
|
45
|
+
* When the RFC-0022 compliance posture declares a stricter cadence than
|
|
46
|
+
* the soul-default, the strictest constraint wins. This mirrors the
|
|
47
|
+
* RFC-0030 OQ-13.3 UNION precedent for multi-posture composition.
|
|
48
|
+
*
|
|
49
|
+
* ### Decision-routing must-consume contract
|
|
50
|
+
*
|
|
51
|
+
* `getLatestMetricSnapshot` emits `decision: 'journey-metric-stale'` when a
|
|
52
|
+
* snapshot is present but older than `thresholdDays`. Callers MUST inspect
|
|
53
|
+
* `result.decision` and route it — typically to the RFC-0035 G0 batch-review
|
|
54
|
+
* queue — before using `result.snapshot.spec.value` for Cκ scoring. Silently
|
|
55
|
+
* dropping `result.decision` defeats the operator-visibility guarantee that
|
|
56
|
+
* makes warn-and-unknown safe (non-fail-closed). A typed must-consume pattern:
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* const result = getLatestMetricSnapshot(journey, metricId, opts);
|
|
60
|
+
* if (result.decision) emitDecision(result.decision); // required
|
|
61
|
+
* if (result.freshness === 'fresh') useValue(result.snapshot!.spec.value);
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @see spec/rfcs/RFC-0018-in-soul-journey-pattern.md §10.1 OQ-5 + OQ-6
|
|
65
|
+
* @see spec/schemas/metric-snapshot.v1.schema.json
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* A single journey success-metric snapshot as supplied by the operator's
|
|
69
|
+
* analytics pipeline. Matches `spec/schemas/metric-snapshot.v1.schema.json`.
|
|
70
|
+
*/
|
|
71
|
+
export interface MetricSnapshot {
|
|
72
|
+
/** Always 'ai-sdlc.io/v1alpha1'. */
|
|
73
|
+
readonly apiVersion: 'ai-sdlc.io/v1alpha1';
|
|
74
|
+
/** Always 'MetricSnapshot'. */
|
|
75
|
+
readonly kind: 'MetricSnapshot';
|
|
76
|
+
readonly metadata: {
|
|
77
|
+
/**
|
|
78
|
+
* Path-style journey URI.
|
|
79
|
+
* Soul-scoped: `<soul-id>/<journey-id>`
|
|
80
|
+
* Variant-scoped: `<soul-id>/<variant-id>/<journey-id>`
|
|
81
|
+
*/
|
|
82
|
+
readonly journey: string;
|
|
83
|
+
/**
|
|
84
|
+
* Metric identifier (kebab-case). MUST match a `successMetrics[].id`
|
|
85
|
+
* on the parent journey declaration.
|
|
86
|
+
* Examples: 'completion-rate', 'median-time-to-first-task-done'
|
|
87
|
+
*/
|
|
88
|
+
readonly metricId: string;
|
|
89
|
+
readonly labels?: Record<string, string>;
|
|
90
|
+
readonly annotations?: Record<string, string>;
|
|
91
|
+
};
|
|
92
|
+
readonly spec: {
|
|
93
|
+
/** Metric value. Unit convention shared between operator and framework. */
|
|
94
|
+
readonly value: number;
|
|
95
|
+
/**
|
|
96
|
+
* ISO 8601 timestamp when this metric was recorded / sampled.
|
|
97
|
+
* Used to compute staleness relative to `thresholdDays`.
|
|
98
|
+
*/
|
|
99
|
+
readonly recordedAt: string;
|
|
100
|
+
/**
|
|
101
|
+
* Free-text analytics tool identifier.
|
|
102
|
+
* Examples: 'mixpanel', 'amplitude', 'heap', 'internal-pipeline'
|
|
103
|
+
*/
|
|
104
|
+
readonly sourceTool: string;
|
|
105
|
+
/** Optional ISO 8601 window start (informational). */
|
|
106
|
+
readonly windowStart?: string;
|
|
107
|
+
/** Optional ISO 8601 window end (informational). */
|
|
108
|
+
readonly windowEnd?: string;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Staleness configuration for `journey.successMetrics.staleness`.
|
|
113
|
+
* Matches the corresponding block in `journey-config.v1.schema.json`.
|
|
114
|
+
*/
|
|
115
|
+
export interface MetricStalenessConfig {
|
|
116
|
+
/** Days after last MetricSnapshot before the metric is stale. Default 30. */
|
|
117
|
+
readonly thresholdDays?: number;
|
|
118
|
+
}
|
|
119
|
+
/** Default staleness threshold per OQ-5 resolution (30 days). */
|
|
120
|
+
export declare const DEFAULT_STALENESS_THRESHOLD_DAYS = 30;
|
|
121
|
+
/**
|
|
122
|
+
* Possible states for a metric lookup result.
|
|
123
|
+
*
|
|
124
|
+
* - `'fresh'` — snapshot found AND within staleness threshold
|
|
125
|
+
* - `'stale'` — snapshot found BUT older than threshold (warn-and-unknown)
|
|
126
|
+
* - `'missing'` — no snapshot found for the journey/metricId pair
|
|
127
|
+
*/
|
|
128
|
+
export type MetricFreshness = 'fresh' | 'stale' | 'missing';
|
|
129
|
+
/**
|
|
130
|
+
* Result returned by `getLatestMetricSnapshot`.
|
|
131
|
+
*
|
|
132
|
+
* - When `freshness === 'fresh'`: `snapshot` is populated; use `snapshot.spec.value`
|
|
133
|
+
* - When `freshness === 'stale'`: `snapshot` is populated but `decision` is emitted
|
|
134
|
+
* (warn-and-unknown — Cκ treats metric as unknown input, pipeline continues)
|
|
135
|
+
* - When `freshness === 'missing'`: no snapshot; Cκ scores as unknown input
|
|
136
|
+
*/
|
|
137
|
+
export interface MetricSnapshotResult {
|
|
138
|
+
/** Journey path URI (e.g. 'spry-engage/onboarding'). */
|
|
139
|
+
readonly journey: string;
|
|
140
|
+
/** Metric ID (e.g. 'completion-rate'). */
|
|
141
|
+
readonly metricId: string;
|
|
142
|
+
/** Freshness state. */
|
|
143
|
+
readonly freshness: MetricFreshness;
|
|
144
|
+
/** The matched snapshot (populated when freshness is 'fresh' or 'stale'). */
|
|
145
|
+
readonly snapshot?: MetricSnapshot;
|
|
146
|
+
/**
|
|
147
|
+
* Decision emitted when `freshness === 'stale'`.
|
|
148
|
+
* Value: `'journey-metric-stale'`.
|
|
149
|
+
* Routing: RFC-0035 G0 (non-blocking batch review — warn-and-unknown, not fail-closed).
|
|
150
|
+
*/
|
|
151
|
+
readonly decision?: 'journey-metric-stale';
|
|
152
|
+
/** Days since `recordedAt` (populated when snapshot is present). */
|
|
153
|
+
readonly ageInDays?: number;
|
|
154
|
+
/** Staleness threshold in days that was applied. */
|
|
155
|
+
readonly thresholdDays: number;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Options for `getLatestMetricSnapshot`.
|
|
159
|
+
*/
|
|
160
|
+
export interface GetLatestMetricSnapshotOptions {
|
|
161
|
+
/**
|
|
162
|
+
* Collection of all MetricSnapshot records known to the framework.
|
|
163
|
+
* Callers are responsible for loading these from their persistence layer
|
|
164
|
+
* (filesystem, in-memory fixture, database) before calling.
|
|
165
|
+
*/
|
|
166
|
+
readonly snapshots: readonly MetricSnapshot[];
|
|
167
|
+
/**
|
|
168
|
+
* Per-Soul staleness config (from the soul's `spec.journeyConfig.successMetrics.staleness`
|
|
169
|
+
* or the org-wide `.ai-sdlc/journey-config.yaml` default).
|
|
170
|
+
* When omitted, the default 30d threshold applies.
|
|
171
|
+
*/
|
|
172
|
+
readonly stalenessConfig?: MetricStalenessConfig;
|
|
173
|
+
/**
|
|
174
|
+
* Reference "now" timestamp (ISO 8601). Defaults to `new Date().toISOString()`.
|
|
175
|
+
* Provided for deterministic testing.
|
|
176
|
+
*/
|
|
177
|
+
readonly now?: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Retrieve the **latest** MetricSnapshot for the given journey + metricId pair
|
|
181
|
+
* and classify it as fresh, stale, or missing.
|
|
182
|
+
*
|
|
183
|
+
* Selection: when multiple snapshots match, the one with the most recent
|
|
184
|
+
* `spec.recordedAt` is returned (latest-wins). This covers the case where
|
|
185
|
+
* the operator's pipeline emits snapshots on a periodic schedule.
|
|
186
|
+
*
|
|
187
|
+
* Staleness: `ageInDays = (now - recordedAt) / (1000 * 60 * 60 * 24)`.
|
|
188
|
+
* When `ageInDays > thresholdDays`, the result carries:
|
|
189
|
+
* - `freshness: 'stale'`
|
|
190
|
+
* - `decision: 'journey-metric-stale'`
|
|
191
|
+
*
|
|
192
|
+
* This Decision routes through RFC-0035 G0 (non-blocking batch review):
|
|
193
|
+
* the Cκ scorer treats a stale metric as an unknown input (same behavior as
|
|
194
|
+
* `freshness: 'missing'`), NOT as a hard fail. The pipeline continues.
|
|
195
|
+
*
|
|
196
|
+
* @param journey Path-style journey URI (e.g. 'spry-engage/onboarding')
|
|
197
|
+
* @param metricId Metric identifier (e.g. 'completion-rate')
|
|
198
|
+
* @param options Snapshot collection + optional per-Soul config
|
|
199
|
+
*/
|
|
200
|
+
export declare function getLatestMetricSnapshot(journey: string, metricId: string, options: GetLatestMetricSnapshotOptions): MetricSnapshotResult;
|
|
201
|
+
/**
|
|
202
|
+
* Per-Soul policy for Eρ₅ degradation when the accessibility audit is overdue.
|
|
203
|
+
* Matches `journey-config.v1.schema.json` `accessibility.auditOverdueGracePolicy`.
|
|
204
|
+
*
|
|
205
|
+
* - `'graduated'` — default; progressive reduction matching Vanta/Drata/Secureframe pattern
|
|
206
|
+
* - `'binary-30d'` — SOC2/HIPAA strict: no impact within 30d, then fail-closed
|
|
207
|
+
* - `'hard-block'` — immediate fail at cadence+0d (no grace)
|
|
208
|
+
*/
|
|
209
|
+
export type AuditOverdueGracePolicy = 'graduated' | 'binary-30d' | 'hard-block';
|
|
210
|
+
/**
|
|
211
|
+
* Eρ₅ impact tiers for graduated degradation.
|
|
212
|
+
*
|
|
213
|
+
* - `'warn'` — Eρ₅ unchanged; Decision emitted for operator visibility
|
|
214
|
+
* - `'reduced-25'` — Eρ₅ multiplied by 0.75 (−25%)
|
|
215
|
+
* - `'reduced-50'` — Eρ₅ multiplied by 0.50 (−50%)
|
|
216
|
+
* - `'effective-block'`— Eρ₅ set to 0 (admission blocked)
|
|
217
|
+
*/
|
|
218
|
+
export type Erho5Impact = 'warn' | 'reduced-25' | 'reduced-50' | 'effective-block';
|
|
219
|
+
/** Eρ₅ multiplier for each impact tier. */
|
|
220
|
+
export declare const ERHO5_MULTIPLIERS: Record<Erho5Impact, number>;
|
|
221
|
+
/**
|
|
222
|
+
* Graduated thresholds configuration (days past audit cadence).
|
|
223
|
+
* Matches `accessibility.graduatedThresholds` in `journey-config.v1.schema.json`.
|
|
224
|
+
*/
|
|
225
|
+
export interface GraduatedThresholds {
|
|
226
|
+
/** Days past cadence at which 'warn' Decision fires. Default 0. */
|
|
227
|
+
readonly warnAt?: number;
|
|
228
|
+
/** Days past cadence at which −25% reduction fires. Default 30. */
|
|
229
|
+
readonly reduced25At?: number;
|
|
230
|
+
/** Days past cadence at which −50% reduction fires. Default 60. */
|
|
231
|
+
readonly reduced50At?: number;
|
|
232
|
+
/** Days past cadence at which effective-block fires. Default 90. */
|
|
233
|
+
readonly effectiveBlockAt?: number;
|
|
234
|
+
}
|
|
235
|
+
/** Default graduated thresholds per OQ-6 resolution. */
|
|
236
|
+
export declare const DEFAULT_GRADUATED_THRESHOLDS: Required<GraduatedThresholds>;
|
|
237
|
+
/**
|
|
238
|
+
* Decision kinds emitted for accessibility audit overdue events.
|
|
239
|
+
* Routes through RFC-0035 G0 non-blocking pipeline contract.
|
|
240
|
+
*/
|
|
241
|
+
export type AuditOverdueDecision = 'journey-audit-overdue-warn' | 'journey-audit-overdue-graduated' | 'journey-audit-overdue-blocking';
|
|
242
|
+
/**
|
|
243
|
+
* Result of the Eρ₅ degradation calculation for an overdue accessibility audit.
|
|
244
|
+
*/
|
|
245
|
+
export interface AuditOverdueResult {
|
|
246
|
+
/** Soul identifier for which the result was computed. */
|
|
247
|
+
readonly soulId: string;
|
|
248
|
+
/** Journey identifier. */
|
|
249
|
+
readonly journeyId: string;
|
|
250
|
+
/** Days the audit is past cadence (0 means exactly at cadence). */
|
|
251
|
+
readonly daysOverdue: number;
|
|
252
|
+
/** The grace policy that was applied. */
|
|
253
|
+
readonly policy: AuditOverdueGracePolicy;
|
|
254
|
+
/** Eρ₅ impact tier. */
|
|
255
|
+
readonly impact: Erho5Impact;
|
|
256
|
+
/**
|
|
257
|
+
* Eρ₅ multiplier to apply to the base Eρ₅ score.
|
|
258
|
+
* 1.0 = no impact; 0.75 = -25%; 0.50 = -50%; 0.0 = effective block.
|
|
259
|
+
*/
|
|
260
|
+
readonly erho5Multiplier: number;
|
|
261
|
+
/**
|
|
262
|
+
* Decision to emit for this result.
|
|
263
|
+
* `null` only when daysOverdue < 0 (audit not yet due). At daysOverdue >= 0
|
|
264
|
+
* (cadence+0d — no grace) a Decision is emitted per the policy.
|
|
265
|
+
*/
|
|
266
|
+
readonly decision: AuditOverdueDecision | null;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Options for `computeAuditOverdueErho5`.
|
|
270
|
+
*/
|
|
271
|
+
export interface ComputeAuditOverdueOptions {
|
|
272
|
+
/** Soul identifier for event attribution. */
|
|
273
|
+
readonly soulId: string;
|
|
274
|
+
/** Journey identifier for event attribution. */
|
|
275
|
+
readonly journeyId: string;
|
|
276
|
+
/**
|
|
277
|
+
* Days the journey's audit is past its declared cadence.
|
|
278
|
+
* 0 = exactly at cadence; positive = overdue; negative = not yet overdue.
|
|
279
|
+
*/
|
|
280
|
+
readonly daysOverdue: number;
|
|
281
|
+
/**
|
|
282
|
+
* Per-Soul grace policy.
|
|
283
|
+
* Defaults to `'graduated'`.
|
|
284
|
+
*/
|
|
285
|
+
readonly policy?: AuditOverdueGracePolicy;
|
|
286
|
+
/**
|
|
287
|
+
* Per-org graduated threshold configuration.
|
|
288
|
+
* Only used when `policy === 'graduated'`.
|
|
289
|
+
* Defaults to `DEFAULT_GRADUATED_THRESHOLDS`.
|
|
290
|
+
*/
|
|
291
|
+
readonly graduatedThresholds?: GraduatedThresholds;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Compute the Eρ₅ impact and Decision for an overdue accessibility audit.
|
|
295
|
+
*
|
|
296
|
+
* Implements RFC-0018 §10.1 OQ-6 graduated Eρ₅ degradation:
|
|
297
|
+
*
|
|
298
|
+
* Policy `graduated` (default):
|
|
299
|
+
* - 0 ≤ daysOverdue < 30 → `warn` (multiplier 1.0)
|
|
300
|
+
* - 30 ≤ daysOverdue < 60 → `reduced-25` (multiplier 0.75)
|
|
301
|
+
* - 60 ≤ daysOverdue < 90 → `reduced-50` (multiplier 0.50)
|
|
302
|
+
* - daysOverdue ≥ 90 → `effective-block` (multiplier 0.0)
|
|
303
|
+
*
|
|
304
|
+
* Policy `binary-30d` (SOC2/HIPAA strict):
|
|
305
|
+
* - daysOverdue < 30 → no impact (multiplier 1.0, no Decision)
|
|
306
|
+
* - daysOverdue ≥ 30 → `effective-block` (multiplier 0.0)
|
|
307
|
+
*
|
|
308
|
+
* Policy `hard-block` (HIPAA/PCI-DSS ultra-strict):
|
|
309
|
+
* - daysOverdue < 0 → no impact (multiplier 1.0, no Decision; not yet due)
|
|
310
|
+
* - daysOverdue ≥ 0 → `effective-block` (multiplier 0.0) — cadence+0d, no grace
|
|
311
|
+
*
|
|
312
|
+
* When `daysOverdue < 0`, returns multiplier 1.0 and `decision: null`
|
|
313
|
+
* regardless of policy (audit is not yet due). At daysOverdue ≥ 0 each policy
|
|
314
|
+
* emits its Decision (no implicit grace day).
|
|
315
|
+
*/
|
|
316
|
+
export declare function computeAuditOverdueErho5(options: ComputeAuditOverdueOptions): AuditOverdueResult;
|
|
317
|
+
/**
|
|
318
|
+
* Audit cadence values from the journey declaration (RFC-0018 §5.2).
|
|
319
|
+
* Ordered strictest → least strict for UNION selection.
|
|
320
|
+
*/
|
|
321
|
+
export type AuditCadence = 'continuous' | 'release-gated' | 'quarterly' | 'annually';
|
|
322
|
+
/**
|
|
323
|
+
* Numeric strictness order for cadence values.
|
|
324
|
+
* Higher = stricter (shorter audit interval).
|
|
325
|
+
* Used by `resolveStrictestCadence` to pick the UNION result.
|
|
326
|
+
*/
|
|
327
|
+
export declare const AUDIT_CADENCE_STRICTNESS: Record<AuditCadence, number>;
|
|
328
|
+
/**
|
|
329
|
+
* Options for `resolveStrictestCadence`.
|
|
330
|
+
*/
|
|
331
|
+
export interface ResolveStrictestCadenceOptions {
|
|
332
|
+
/**
|
|
333
|
+
* Journey-level cadence declared in `accessibility.auditCadence`.
|
|
334
|
+
*/
|
|
335
|
+
readonly journeyCadence: AuditCadence;
|
|
336
|
+
/**
|
|
337
|
+
* Cadences required by the active RFC-0022 compliance posture(s).
|
|
338
|
+
* An empty array means no posture constraint — journey cadence is used as-is.
|
|
339
|
+
* When multiple postures are active, all are included here.
|
|
340
|
+
*/
|
|
341
|
+
readonly postureCadences: readonly AuditCadence[];
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Resolve the effective audit cadence by applying the strictest constraint
|
|
345
|
+
* from the journey declaration and all active RFC-0022 compliance postures.
|
|
346
|
+
*
|
|
347
|
+
* This implements RFC-0018 AC #6 + RFC-0030 OQ-13.3 UNION precedent:
|
|
348
|
+
* the strictest constraint among all active postures and the journey's own
|
|
349
|
+
* declaration wins.
|
|
350
|
+
*
|
|
351
|
+
* @example
|
|
352
|
+
* // Journey declares 'annually', but SOC2 posture requires 'quarterly'
|
|
353
|
+
* resolveStrictestCadence({
|
|
354
|
+
* journeyCadence: 'annually',
|
|
355
|
+
* postureCadences: ['quarterly'],
|
|
356
|
+
* })
|
|
357
|
+
* // → 'quarterly' (posture wins — stricter)
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* // Journey declares 'continuous' (strictest possible)
|
|
361
|
+
* resolveStrictestCadence({
|
|
362
|
+
* journeyCadence: 'continuous',
|
|
363
|
+
* postureCadences: ['quarterly', 'annually'],
|
|
364
|
+
* })
|
|
365
|
+
* // → 'continuous' (journey wins — already strictest)
|
|
366
|
+
*/
|
|
367
|
+
export declare function resolveStrictestCadence(options: ResolveStrictestCadenceOptions): AuditCadence;
|
|
368
|
+
/**
|
|
369
|
+
* Options for `resolveStrictestGracePolicy`.
|
|
370
|
+
*/
|
|
371
|
+
export interface ResolveStrictestGracePolicyOptions {
|
|
372
|
+
/**
|
|
373
|
+
* Per-Soul grace policy from `accessibility.auditOverdueGracePolicy`.
|
|
374
|
+
* Defaults to `'graduated'`.
|
|
375
|
+
*/
|
|
376
|
+
readonly soulPolicy?: AuditOverdueGracePolicy;
|
|
377
|
+
/**
|
|
378
|
+
* Grace policies required by the active RFC-0022 compliance postures.
|
|
379
|
+
* An empty array means no posture constraint — soul policy is used as-is.
|
|
380
|
+
* SOC2/HIPAA postures typically impose 'binary-30d' or 'hard-block'.
|
|
381
|
+
*/
|
|
382
|
+
readonly posturesPolicies: readonly AuditOverdueGracePolicy[];
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Policy strictness order (higher = stricter).
|
|
386
|
+
*/
|
|
387
|
+
export declare const GRACE_POLICY_STRICTNESS: Record<AuditOverdueGracePolicy, number>;
|
|
388
|
+
/**
|
|
389
|
+
* Resolve the effective grace policy by picking the STRICTEST among the
|
|
390
|
+
* soul-level policy and all active RFC-0022 compliance posture policies.
|
|
391
|
+
*
|
|
392
|
+
* RFC-0022 + RFC-0018 AC #6: multi-posture UNION → strictest applies.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* // Soul defaults to 'graduated'; SOC2 posture requires 'binary-30d'
|
|
396
|
+
* resolveStrictestGracePolicy({
|
|
397
|
+
* soulPolicy: 'graduated',
|
|
398
|
+
* posturesPolicies: ['binary-30d'],
|
|
399
|
+
* })
|
|
400
|
+
* // → 'binary-30d' (posture wins — stricter)
|
|
401
|
+
*/
|
|
402
|
+
export declare function resolveStrictestGracePolicy(options: ResolveStrictestGracePolicyOptions): AuditOverdueGracePolicy;
|
|
403
|
+
//# sourceMappingURL=metric-snapshot.d.ts.map
|