@aegis-scan/core 0.16.6 → 0.18.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 +37 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/manipulation-resistance/ai-io-boundary.d.ts +84 -0
- package/dist/manipulation-resistance/ai-io-boundary.d.ts.map +1 -0
- package/dist/manipulation-resistance/ai-io-boundary.js +216 -0
- package/dist/manipulation-resistance/ai-io-boundary.js.map +1 -0
- package/dist/manipulation-resistance/config-integrity.d.ts +28 -0
- package/dist/manipulation-resistance/config-integrity.d.ts.map +1 -0
- package/dist/manipulation-resistance/config-integrity.js +53 -0
- package/dist/manipulation-resistance/config-integrity.js.map +1 -0
- package/dist/manipulation-resistance/index.d.ts +16 -0
- package/dist/manipulation-resistance/index.d.ts.map +1 -0
- package/dist/manipulation-resistance/index.js +16 -0
- package/dist/manipulation-resistance/index.js.map +1 -0
- package/dist/manipulation-resistance/instruction-boundary.d.ts +50 -0
- package/dist/manipulation-resistance/instruction-boundary.d.ts.map +1 -0
- package/dist/manipulation-resistance/instruction-boundary.js +114 -0
- package/dist/manipulation-resistance/instruction-boundary.js.map +1 -0
- package/dist/manipulation-resistance/oob-blocker.d.ts +58 -0
- package/dist/manipulation-resistance/oob-blocker.d.ts.map +1 -0
- package/dist/manipulation-resistance/oob-blocker.js +55 -0
- package/dist/manipulation-resistance/oob-blocker.js.map +1 -0
- package/dist/manipulation-resistance/redirect-policy.d.ts +43 -0
- package/dist/manipulation-resistance/redirect-policy.d.ts.map +1 -0
- package/dist/manipulation-resistance/redirect-policy.js +197 -0
- package/dist/manipulation-resistance/redirect-policy.js.map +1 -0
- package/dist/manipulation-resistance/response-validator.d.ts +33 -0
- package/dist/manipulation-resistance/response-validator.d.ts.map +1 -0
- package/dist/manipulation-resistance/response-validator.js +186 -0
- package/dist/manipulation-resistance/response-validator.js.map +1 -0
- package/dist/manipulation-resistance/scope-expansion-detector.d.ts +33 -0
- package/dist/manipulation-resistance/scope-expansion-detector.d.ts.map +1 -0
- package/dist/manipulation-resistance/scope-expansion-detector.js +68 -0
- package/dist/manipulation-resistance/scope-expansion-detector.js.map +1 -0
- package/dist/oversight/approval-gates.d.ts +77 -0
- package/dist/oversight/approval-gates.d.ts.map +1 -0
- package/dist/oversight/approval-gates.js +133 -0
- package/dist/oversight/approval-gates.js.map +1 -0
- package/dist/oversight/authority-matrix.d.ts +39 -0
- package/dist/oversight/authority-matrix.d.ts.map +1 -0
- package/dist/oversight/authority-matrix.js +75 -0
- package/dist/oversight/authority-matrix.js.map +1 -0
- package/dist/oversight/cia-scoring.d.ts +56 -0
- package/dist/oversight/cia-scoring.d.ts.map +1 -0
- package/dist/oversight/cia-scoring.js +98 -0
- package/dist/oversight/cia-scoring.js.map +1 -0
- package/dist/oversight/escalation.d.ts +58 -0
- package/dist/oversight/escalation.d.ts.map +1 -0
- package/dist/oversight/escalation.js +97 -0
- package/dist/oversight/escalation.js.map +1 -0
- package/dist/oversight/index.d.ts +15 -0
- package/dist/oversight/index.d.ts.map +1 -0
- package/dist/oversight/index.js +15 -0
- package/dist/oversight/index.js.map +1 -0
- package/dist/roe/index.d.ts +3 -0
- package/dist/roe/index.d.ts.map +1 -0
- package/dist/roe/index.js +3 -0
- package/dist/roe/index.js.map +1 -0
- package/dist/roe/loader.d.ts +15 -0
- package/dist/roe/loader.d.ts.map +1 -0
- package/dist/roe/loader.js +56 -0
- package/dist/roe/loader.js.map +1 -0
- package/dist/roe/types.d.ts +738 -0
- package/dist/roe/types.d.ts.map +1 -0
- package/dist/roe/types.js +525 -0
- package/dist/roe/types.js.map +1 -0
- package/dist/runtime/chain.d.ts +60 -0
- package/dist/runtime/chain.d.ts.map +1 -0
- package/dist/runtime/chain.js +156 -0
- package/dist/runtime/chain.js.map +1 -0
- package/dist/runtime/events.d.ts +104 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/runtime/events.js +68 -0
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/hash.d.ts +16 -0
- package/dist/runtime/hash.d.ts.map +1 -0
- package/dist/runtime/hash.js +70 -0
- package/dist/runtime/hash.js.map +1 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/notifications.d.ts +24 -0
- package/dist/runtime/notifications.d.ts.map +1 -0
- package/dist/runtime/notifications.js +41 -0
- package/dist/runtime/notifications.js.map +1 -0
- package/dist/runtime/signals.d.ts +56 -0
- package/dist/runtime/signals.d.ts.map +1 -0
- package/dist/runtime/signals.js +72 -0
- package/dist/runtime/signals.js.map +1 -0
- package/dist/runtime/state.d.ts +88 -0
- package/dist/runtime/state.d.ts.map +1 -0
- package/dist/runtime/state.js +172 -0
- package/dist/runtime/state.js.map +1 -0
- package/dist/safety-controls/boundary-monitor.d.ts +45 -0
- package/dist/safety-controls/boundary-monitor.d.ts.map +1 -0
- package/dist/safety-controls/boundary-monitor.js +77 -0
- package/dist/safety-controls/boundary-monitor.js.map +1 -0
- package/dist/safety-controls/decision-timeout.d.ts +56 -0
- package/dist/safety-controls/decision-timeout.d.ts.map +1 -0
- package/dist/safety-controls/decision-timeout.js +67 -0
- package/dist/safety-controls/decision-timeout.js.map +1 -0
- package/dist/safety-controls/health-monitor.d.ts +61 -0
- package/dist/safety-controls/health-monitor.d.ts.map +1 -0
- package/dist/safety-controls/health-monitor.js +79 -0
- package/dist/safety-controls/health-monitor.js.map +1 -0
- package/dist/safety-controls/index.d.ts +13 -0
- package/dist/safety-controls/index.d.ts.map +1 -0
- package/dist/safety-controls/index.js +13 -0
- package/dist/safety-controls/index.js.map +1 -0
- package/dist/safety-controls/kill-switch.d.ts +45 -0
- package/dist/safety-controls/kill-switch.d.ts.map +1 -0
- package/dist/safety-controls/kill-switch.js +117 -0
- package/dist/safety-controls/kill-switch.js.map +1 -0
- package/dist/safety-controls/post-test-integrity.d.ts +51 -0
- package/dist/safety-controls/post-test-integrity.d.ts.map +1 -0
- package/dist/safety-controls/post-test-integrity.js +79 -0
- package/dist/safety-controls/post-test-integrity.js.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/sbom.cdx.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/roe/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA6MxB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;QA3FlB,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAvCzE,mGAAmG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA+InG,iFAAiF;;;;;;;;;;;;;;;;;IAEjF,sEAAsE;;QAzItE,0CAA0C;;;;;;;;;;;;;;QAS1C,yEAAyE;;QAEzE,mDAAmD;;;;;;;;;;;;;;;;;;;IAgInD,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEhE,2EAA2E;;;;;;;;;;;IAE3E,0FAA0F;;QAjF1F,wEAAwE;;QAExE,8CAA8C;;;;;;;;;;;;;;QAS9C,kFAAkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyE3E,CAAC;AAEZ,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAK5C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,kBAAkB,CAuDlF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAE,IAAiB,GAAG,kBAAkB,CAkC7F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,GACP,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,aAAa,CAYxD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,GAAG,GAAE,IAAiB,GACrB,kBAAkB,CAuBpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,GAAG,CAqDL"}
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rules of Engagement (RoE) schema for AEGIS Autonomous Pentest Layer.
|
|
3
|
+
*
|
|
4
|
+
* Closes APTS Tier-1 requirements:
|
|
5
|
+
* - APTS-SE-001 — Rules of Engagement Specification and Validation
|
|
6
|
+
* - APTS-SE-003 — Domain Scope Validation and Wildcard Handling
|
|
7
|
+
* - APTS-SE-004 — Temporal Boundary and Timezone Handling
|
|
8
|
+
* - APTS-SE-005 — Asset Criticality Classification and Integration
|
|
9
|
+
* - APTS-SE-006 — Pre-Action Scope Validation
|
|
10
|
+
* - APTS-AL-006 — Basic Scope Validation and Policy Enforcement
|
|
11
|
+
* - APTS-AL-014 — Boundary Definition and Enforcement Framework
|
|
12
|
+
*
|
|
13
|
+
* Design notes:
|
|
14
|
+
* - JSON-shaped, Zod-strict-validated. Operators may author in YAML and
|
|
15
|
+
* pre-convert at load time, but the canonical on-disk form is JSON.
|
|
16
|
+
* - The schema captures authorization-attestation, in-/out-of-scope
|
|
17
|
+
* domains and IP ranges, asset criticality classification, temporal
|
|
18
|
+
* envelope (with optional blackout windows), and stop conditions.
|
|
19
|
+
* - Per-action validators are pure functions on a loaded RoE — they
|
|
20
|
+
* take a target/action and return an explicit allow/deny decision
|
|
21
|
+
* with rationale. The decision is logged by the orchestrator into
|
|
22
|
+
* the audit channel.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Sub-schemas
|
|
27
|
+
const DomainPatternSchema = z.object({
|
|
28
|
+
pattern: z
|
|
29
|
+
.string()
|
|
30
|
+
.min(1)
|
|
31
|
+
.refine((s) => !s.includes('://') && !s.includes('/'), { message: 'domain pattern must be a bare hostname or wildcard, no scheme or path' }),
|
|
32
|
+
includeSubdomains: z.boolean().default(false),
|
|
33
|
+
});
|
|
34
|
+
const CidrSchema = z
|
|
35
|
+
.string()
|
|
36
|
+
.regex(/^(?:\d{1,3}\.){3}\d{1,3}\/\d{1,2}$|^[0-9a-fA-F:]+\/\d{1,3}$/u, { message: 'CIDR must be IPv4 (a.b.c.d/n) or IPv6 (xxxx:.../n)' });
|
|
37
|
+
const InScopeSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
domains: z.array(DomainPatternSchema).default([]),
|
|
40
|
+
ip_ranges: z.array(CidrSchema).default([]),
|
|
41
|
+
repository_paths: z.array(z.string().min(1)).default([]),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
const OutOfScopeSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
domains: z.array(z.string().min(1)).default([]),
|
|
47
|
+
ip_ranges: z.array(CidrSchema).default([]),
|
|
48
|
+
paths: z.array(z.string().min(1)).default([]),
|
|
49
|
+
})
|
|
50
|
+
.strict();
|
|
51
|
+
const AssetCriticalityEntrySchema = z
|
|
52
|
+
.object({
|
|
53
|
+
pattern: z.string().min(1),
|
|
54
|
+
classification: z.enum(['critical', 'high', 'medium', 'low']),
|
|
55
|
+
notes: z.string().optional(),
|
|
56
|
+
})
|
|
57
|
+
.strict();
|
|
58
|
+
const BlackoutWindowSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
start: z.string().datetime({ offset: true }),
|
|
61
|
+
end: z.string().datetime({ offset: true }),
|
|
62
|
+
reason: z.string().min(1),
|
|
63
|
+
})
|
|
64
|
+
.strict()
|
|
65
|
+
.refine((w) => Date.parse(w.end) > Date.parse(w.start), {
|
|
66
|
+
message: 'blackout window end must be after start',
|
|
67
|
+
});
|
|
68
|
+
const TemporalSchema = z
|
|
69
|
+
.object({
|
|
70
|
+
start: z.string().datetime({ offset: true }),
|
|
71
|
+
end: z.string().datetime({ offset: true }),
|
|
72
|
+
timezone: z.string().min(1),
|
|
73
|
+
blackout_windows: z.array(BlackoutWindowSchema).default([]),
|
|
74
|
+
})
|
|
75
|
+
.strict()
|
|
76
|
+
.refine((t) => Date.parse(t.end) > Date.parse(t.start), {
|
|
77
|
+
message: 'temporal envelope end must be after start',
|
|
78
|
+
});
|
|
79
|
+
const StopConditionsSchema = z
|
|
80
|
+
.object({
|
|
81
|
+
on_critical_finding: z.enum(['halt', 'notify-and-continue', 'continue']).default('halt'),
|
|
82
|
+
max_findings: z.number().int().positive().optional(),
|
|
83
|
+
max_duration_minutes: z.number().int().positive().optional(),
|
|
84
|
+
/** APTS-HO-003 — per-phase decision timeout. Falls back to max_duration_minutes/4 when omitted. */
|
|
85
|
+
phase_timeout_minutes: z.number().int().positive().optional(),
|
|
86
|
+
on_target_unreachable_seconds: z.number().int().positive().optional(),
|
|
87
|
+
})
|
|
88
|
+
.strict();
|
|
89
|
+
const SafetyControlsSchema = z
|
|
90
|
+
.object({
|
|
91
|
+
/** APTS-SC-010 — auto-halt thresholds. */
|
|
92
|
+
health_thresholds: z
|
|
93
|
+
.object({
|
|
94
|
+
max_heap_mb: z.number().int().positive().optional(),
|
|
95
|
+
max_error_rate: z.number().min(0).max(1).optional(),
|
|
96
|
+
max_target_response_ms: z.number().int().positive().optional(),
|
|
97
|
+
})
|
|
98
|
+
.strict()
|
|
99
|
+
.optional(),
|
|
100
|
+
/** APTS-SC-009 — operator dead-man-switch heartbeat URL (HTTPS only). */
|
|
101
|
+
heartbeat_url: z.string().url().optional(),
|
|
102
|
+
/** APTS-SC-009 — heartbeat interval in seconds. */
|
|
103
|
+
heartbeat_interval_seconds: z.number().int().positive().optional(),
|
|
104
|
+
})
|
|
105
|
+
.strict();
|
|
106
|
+
const DelegationEntrySchema = z
|
|
107
|
+
.object({
|
|
108
|
+
role: z.string().min(1),
|
|
109
|
+
can_approve: z.array(z.string().min(1)).min(1),
|
|
110
|
+
})
|
|
111
|
+
.strict();
|
|
112
|
+
const AuthorizationSchema = z
|
|
113
|
+
.object({
|
|
114
|
+
statement: z.string().min(20, {
|
|
115
|
+
message: 'authorization statement must be at least 20 chars (forces explicit attestation rather than placeholder text)',
|
|
116
|
+
}),
|
|
117
|
+
authority_url: z.string().url().optional(),
|
|
118
|
+
signature_method: z.enum(['operator-attested', 'external-signed']).default('operator-attested'),
|
|
119
|
+
/** APTS-HO-004 — declarative role↔action authority delegation matrix. */
|
|
120
|
+
delegation_matrix: z.array(DelegationEntrySchema).optional(),
|
|
121
|
+
})
|
|
122
|
+
.strict();
|
|
123
|
+
const AutonomyLevelPolicySchema = z
|
|
124
|
+
.object({
|
|
125
|
+
approval_required: z.boolean().optional(),
|
|
126
|
+
pre_approved: z.boolean().optional(),
|
|
127
|
+
irreversible_action_classes: z.array(z.string().min(1)).optional(),
|
|
128
|
+
})
|
|
129
|
+
.strict();
|
|
130
|
+
const AutonomyLevelsSchema = z
|
|
131
|
+
.object({
|
|
132
|
+
L1: AutonomyLevelPolicySchema.optional(),
|
|
133
|
+
L2: AutonomyLevelPolicySchema.optional(),
|
|
134
|
+
L3: AutonomyLevelPolicySchema.optional(),
|
|
135
|
+
L4: AutonomyLevelPolicySchema.optional(),
|
|
136
|
+
})
|
|
137
|
+
.strict();
|
|
138
|
+
const ComplianceTriggersSchema = z
|
|
139
|
+
.object({
|
|
140
|
+
regulatory_class: z.array(z.string().min(1)).min(1),
|
|
141
|
+
on_match: z.enum(['halt', 'notify']).default('halt'),
|
|
142
|
+
})
|
|
143
|
+
.strict();
|
|
144
|
+
const EscalationPolicySchema = z
|
|
145
|
+
.object({
|
|
146
|
+
/** APTS-HO-011 — severity at which an unexpected-finding halt fires. */
|
|
147
|
+
severity_threshold: z.enum(['info', 'low', 'medium', 'high', 'critical', 'blocker']).optional(),
|
|
148
|
+
/** APTS-HO-012 — CIA-axis halt thresholds. */
|
|
149
|
+
cia_threshold: z
|
|
150
|
+
.object({
|
|
151
|
+
c: z.enum(['none', 'low', 'medium', 'high']).optional(),
|
|
152
|
+
i: z.enum(['none', 'low', 'medium', 'high']).optional(),
|
|
153
|
+
a: z.enum(['none', 'low', 'medium', 'high']).optional(),
|
|
154
|
+
})
|
|
155
|
+
.strict()
|
|
156
|
+
.optional(),
|
|
157
|
+
/** APTS-HO-013 — when true, low-confidence findings halt-pause the engagement. */
|
|
158
|
+
pause_on_low_confidence: z.boolean().optional(),
|
|
159
|
+
})
|
|
160
|
+
.strict();
|
|
161
|
+
const OperatorSchema = z
|
|
162
|
+
.object({
|
|
163
|
+
organization: z.string().min(1),
|
|
164
|
+
authorized_by: z.string().min(1),
|
|
165
|
+
contact: z.string().min(1),
|
|
166
|
+
})
|
|
167
|
+
.strict();
|
|
168
|
+
const NotificationChannelSchema = z
|
|
169
|
+
.object({
|
|
170
|
+
type: z.enum(['webhook', 'log']),
|
|
171
|
+
url: z.string().url().optional(),
|
|
172
|
+
events: z
|
|
173
|
+
.array(z.enum(['start', 'halt', 'critical-finding', 'completion']))
|
|
174
|
+
.min(1),
|
|
175
|
+
})
|
|
176
|
+
.strict();
|
|
177
|
+
const NotificationsSchema = z
|
|
178
|
+
.object({
|
|
179
|
+
channels: z.array(NotificationChannelSchema).default([]),
|
|
180
|
+
})
|
|
181
|
+
.strict();
|
|
182
|
+
const ReferencesSchema = z
|
|
183
|
+
.object({
|
|
184
|
+
incident_response_plan: z.string().optional(),
|
|
185
|
+
contract_id: z.string().optional(),
|
|
186
|
+
apts_conformance_claim: z.string().optional(),
|
|
187
|
+
})
|
|
188
|
+
.strict();
|
|
189
|
+
const SandboxingSchema = z
|
|
190
|
+
.object({
|
|
191
|
+
mode: z.enum(['docker', 'firejail', 'none']).default('none'),
|
|
192
|
+
docker_network: z.string().min(1).optional(),
|
|
193
|
+
image_overrides: z.record(z.string().min(1), z.string().min(1)).optional(),
|
|
194
|
+
extra_docker_args: z.array(z.string()).optional(),
|
|
195
|
+
})
|
|
196
|
+
.strict();
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
// Top-level RoE schema
|
|
199
|
+
export const RoESchema = z
|
|
200
|
+
.object({
|
|
201
|
+
roe_id: z.string().min(1),
|
|
202
|
+
spec_version: z.literal('0.1.0'),
|
|
203
|
+
operator: OperatorSchema,
|
|
204
|
+
authorization: AuthorizationSchema,
|
|
205
|
+
in_scope: InScopeSchema,
|
|
206
|
+
out_of_scope: OutOfScopeSchema.default({}),
|
|
207
|
+
asset_criticality: z.array(AssetCriticalityEntrySchema).default([]),
|
|
208
|
+
temporal: TemporalSchema,
|
|
209
|
+
stop_conditions: StopConditionsSchema.default({ on_critical_finding: 'halt' }),
|
|
210
|
+
notifications: NotificationsSchema.optional(),
|
|
211
|
+
references: ReferencesSchema.optional(),
|
|
212
|
+
/** APTS-MR-018 — declarative sandboxing constraints for LLM-pentest wrappers. */
|
|
213
|
+
sandboxing: SandboxingSchema.default({ mode: 'none' }),
|
|
214
|
+
/** APTS-SC-009/010, HO-003 — declarative safety-control overrides. */
|
|
215
|
+
safety_controls: SafetyControlsSchema.optional(),
|
|
216
|
+
/** APTS-HO-001/010 — per-autonomy-level pre-approval gating. */
|
|
217
|
+
autonomy_levels: AutonomyLevelsSchema.optional(),
|
|
218
|
+
/** APTS-HO-014 — regulatory class triggers for finding-text escalation. */
|
|
219
|
+
compliance_triggers: ComplianceTriggersSchema.optional(),
|
|
220
|
+
/** APTS-HO-011/012/013 — escalation thresholds for severity / CIA vector / confidence. */
|
|
221
|
+
escalation: EscalationPolicySchema.optional(),
|
|
222
|
+
})
|
|
223
|
+
.strict();
|
|
224
|
+
/**
|
|
225
|
+
* Validate that a target (URL, hostname, or IP) is in scope and not in the
|
|
226
|
+
* out_of_scope deny list. Closes APTS-SE-003 + APTS-SE-006 + APTS-AL-006.
|
|
227
|
+
*/
|
|
228
|
+
export function validateTargetInScope(target, roe) {
|
|
229
|
+
const host = stripToHostname(target);
|
|
230
|
+
if (!host) {
|
|
231
|
+
return {
|
|
232
|
+
allowed: false,
|
|
233
|
+
reason: `target ${target} could not be parsed to a hostname or IP`,
|
|
234
|
+
apts_refs: ['APTS-SE-003', 'APTS-SE-006'],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
// First: deny-list (out_of_scope wins over in_scope when both match)
|
|
238
|
+
for (const denied of roe.out_of_scope.domains) {
|
|
239
|
+
if (matchDomain(host, denied, false)) {
|
|
240
|
+
return {
|
|
241
|
+
allowed: false,
|
|
242
|
+
reason: `target ${host} matches out_of_scope domain pattern ${denied}`,
|
|
243
|
+
apts_refs: ['APTS-SE-009', 'APTS-AL-014'],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const denied of roe.out_of_scope.ip_ranges) {
|
|
248
|
+
if (ipInCidr(host, denied)) {
|
|
249
|
+
return {
|
|
250
|
+
allowed: false,
|
|
251
|
+
reason: `target ${host} matches out_of_scope CIDR ${denied}`,
|
|
252
|
+
apts_refs: ['APTS-SE-009', 'APTS-AL-014'],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Second: in-scope check (must match at least one)
|
|
257
|
+
for (const dom of roe.in_scope.domains) {
|
|
258
|
+
if (matchDomain(host, dom.pattern, dom.includeSubdomains)) {
|
|
259
|
+
return {
|
|
260
|
+
allowed: true,
|
|
261
|
+
reason: `target ${host} matches in_scope domain pattern ${dom.pattern}${dom.includeSubdomains ? ' (subdomains included)' : ''}`,
|
|
262
|
+
apts_refs: ['APTS-SE-003', 'APTS-SE-006', 'APTS-AL-006'],
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (const cidr of roe.in_scope.ip_ranges) {
|
|
267
|
+
if (ipInCidr(host, cidr)) {
|
|
268
|
+
return {
|
|
269
|
+
allowed: true,
|
|
270
|
+
reason: `target ${host} is within in_scope CIDR ${cidr}`,
|
|
271
|
+
apts_refs: ['APTS-SE-002', 'APTS-SE-006', 'APTS-AL-006'],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
allowed: false,
|
|
277
|
+
reason: `target ${host} is not within any in_scope domain or CIDR`,
|
|
278
|
+
apts_refs: ['APTS-SE-003', 'APTS-SE-006'],
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Validate the current time is within the temporal envelope and not in a
|
|
283
|
+
* blackout window. Closes APTS-SE-004 + APTS-SE-008.
|
|
284
|
+
*/
|
|
285
|
+
export function validateTemporalEnvelope(roe, now = new Date()) {
|
|
286
|
+
const ts = now.getTime();
|
|
287
|
+
const start = Date.parse(roe.temporal.start);
|
|
288
|
+
const end = Date.parse(roe.temporal.end);
|
|
289
|
+
if (ts < start) {
|
|
290
|
+
return {
|
|
291
|
+
allowed: false,
|
|
292
|
+
reason: `current time (${now.toISOString()}) is before engagement start (${roe.temporal.start})`,
|
|
293
|
+
apts_refs: ['APTS-SE-004'],
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
if (ts > end) {
|
|
297
|
+
return {
|
|
298
|
+
allowed: false,
|
|
299
|
+
reason: `current time (${now.toISOString()}) is after engagement end (${roe.temporal.end})`,
|
|
300
|
+
apts_refs: ['APTS-SE-004', 'APTS-SE-008'],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
for (const window of roe.temporal.blackout_windows ?? []) {
|
|
304
|
+
const ws = Date.parse(window.start);
|
|
305
|
+
const we = Date.parse(window.end);
|
|
306
|
+
if (ts >= ws && ts <= we) {
|
|
307
|
+
return {
|
|
308
|
+
allowed: false,
|
|
309
|
+
reason: `current time is inside blackout window (${window.start} → ${window.end}: ${window.reason})`,
|
|
310
|
+
apts_refs: ['APTS-SE-004', 'APTS-SE-008'],
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
allowed: true,
|
|
316
|
+
reason: 'within temporal envelope and outside any blackout window',
|
|
317
|
+
apts_refs: ['APTS-SE-004', 'APTS-SE-008'],
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Classify a target's asset criticality per APTS-SE-005. Returns
|
|
322
|
+
* `'unspecified'` if no asset_criticality entry matches.
|
|
323
|
+
*/
|
|
324
|
+
export function getAssetCriticality(target, roe) {
|
|
325
|
+
const host = stripToHostname(target);
|
|
326
|
+
if (!host)
|
|
327
|
+
return 'unspecified';
|
|
328
|
+
// Match in declaration order — first match wins. Operators can pin
|
|
329
|
+
// critical assets at the top of the list to take precedence over
|
|
330
|
+
// broader patterns.
|
|
331
|
+
for (const entry of roe.asset_criticality) {
|
|
332
|
+
if (matchDomain(host, entry.pattern, true) || pathMatches(target, entry.pattern)) {
|
|
333
|
+
return entry.classification;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return 'unspecified';
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Composite pre-action validator. Combines scope + temporal + per-action
|
|
340
|
+
* stop-condition checks. Returns an explicit allow/deny with the
|
|
341
|
+
* complete reason chain. Closes APTS-SE-006.
|
|
342
|
+
*/
|
|
343
|
+
export function validateAction(target, action, roe, now = new Date()) {
|
|
344
|
+
const temporal = validateTemporalEnvelope(roe, now);
|
|
345
|
+
if (!temporal.allowed) {
|
|
346
|
+
return {
|
|
347
|
+
allowed: false,
|
|
348
|
+
reason: `action ${action}: ${temporal.reason}`,
|
|
349
|
+
apts_refs: temporal.apts_refs,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
const scope = validateTargetInScope(target, roe);
|
|
353
|
+
if (!scope.allowed) {
|
|
354
|
+
return {
|
|
355
|
+
allowed: false,
|
|
356
|
+
reason: `action ${action}: ${scope.reason}`,
|
|
357
|
+
apts_refs: scope.apts_refs,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
const criticality = getAssetCriticality(target, roe);
|
|
361
|
+
return {
|
|
362
|
+
allowed: true,
|
|
363
|
+
reason: `action ${action} on ${target} (criticality: ${criticality}) within scope and temporal envelope`,
|
|
364
|
+
apts_refs: ['APTS-SE-006', 'APTS-SE-005', 'APTS-AL-006'],
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Synthesize a minimal RoE from a `--target` flag for back-compat with the
|
|
369
|
+
* pre-RoE `aegis siege --target URL --confirm` interface. Operator should
|
|
370
|
+
* graduate to a real RoE file for any non-trivial engagement; this helper
|
|
371
|
+
* exists so existing scripts continue to function. Marks the synthesized
|
|
372
|
+
* RoE as such so audit logs can flag the difference.
|
|
373
|
+
*
|
|
374
|
+
* Defaults are CONSERVATIVE-strict, not permissive-back-compat:
|
|
375
|
+
* - `safety_controls.health_thresholds` non-trivial so SC-010 health
|
|
376
|
+
* check actually trips on a runaway engagement.
|
|
377
|
+
* - `autonomy_levels.L3.approval_required: true` — exploitation halts
|
|
378
|
+
* unless the operator provides a real RoE that explicitly
|
|
379
|
+
* pre-approves L3. This is a back-compat BREAK from earlier
|
|
380
|
+
* versions where --confirm authorized everything; the rationale is
|
|
381
|
+
* that synthesized minimal RoE should never silently authorize
|
|
382
|
+
* exploitation phase. Operators who need exploitation must author
|
|
383
|
+
* a full RoE.
|
|
384
|
+
* - `escalation.severity_threshold: 'critical'` — matches the
|
|
385
|
+
* `stop_conditions.on_critical_finding: 'halt'` policy on the
|
|
386
|
+
* finding-text path (HO-011).
|
|
387
|
+
* - `escalation.cia_threshold: { c:'high', i:'high', a:'high' }` —
|
|
388
|
+
* CIA-axis halt on any high-impact finding (HO-012).
|
|
389
|
+
* - `pause_on_low_confidence: false` — operator opt-in for HO-013
|
|
390
|
+
* to avoid noisy halts during normal scans.
|
|
391
|
+
*
|
|
392
|
+
* The previous permissive defaults were flagged by an internal audit
|
|
393
|
+
* as "mechanism-MET but inert in default mode". Closing that gap
|
|
394
|
+
* required this BC break.
|
|
395
|
+
*/
|
|
396
|
+
export function synthesizeMinimalRoE(target, options = {}) {
|
|
397
|
+
const now = new Date();
|
|
398
|
+
const end = new Date(now.getTime() + (options.durationMinutes ?? 60) * 60_000);
|
|
399
|
+
const host = stripToHostname(target) ?? target;
|
|
400
|
+
return {
|
|
401
|
+
roe_id: `synthesized-${now.toISOString().replace(/[:.]/g, '-')}`,
|
|
402
|
+
spec_version: '0.1.0',
|
|
403
|
+
operator: {
|
|
404
|
+
organization: options.organization ?? 'unspecified-operator',
|
|
405
|
+
authorized_by: 'cli-flag-fallback',
|
|
406
|
+
contact: 'unspecified',
|
|
407
|
+
},
|
|
408
|
+
authorization: {
|
|
409
|
+
statement: 'AEGIS-synthesized minimal RoE from --target flag (no operator-attested RoE file provided)',
|
|
410
|
+
signature_method: 'operator-attested',
|
|
411
|
+
},
|
|
412
|
+
in_scope: {
|
|
413
|
+
domains: [{ pattern: host, includeSubdomains: false }],
|
|
414
|
+
ip_ranges: [],
|
|
415
|
+
repository_paths: [],
|
|
416
|
+
},
|
|
417
|
+
out_of_scope: { domains: [], ip_ranges: [], paths: [] },
|
|
418
|
+
asset_criticality: [],
|
|
419
|
+
temporal: {
|
|
420
|
+
start: now.toISOString(),
|
|
421
|
+
end: end.toISOString(),
|
|
422
|
+
timezone: 'UTC',
|
|
423
|
+
blackout_windows: [],
|
|
424
|
+
},
|
|
425
|
+
stop_conditions: { on_critical_finding: 'halt' },
|
|
426
|
+
sandboxing: { mode: 'none' },
|
|
427
|
+
safety_controls: {
|
|
428
|
+
health_thresholds: {
|
|
429
|
+
max_heap_mb: 4096,
|
|
430
|
+
max_error_rate: 0.5,
|
|
431
|
+
max_target_response_ms: 30_000,
|
|
432
|
+
},
|
|
433
|
+
heartbeat_interval_seconds: 30,
|
|
434
|
+
},
|
|
435
|
+
autonomy_levels: {
|
|
436
|
+
L1: { approval_required: false },
|
|
437
|
+
L2: { approval_required: false },
|
|
438
|
+
L3: { approval_required: true },
|
|
439
|
+
L4: { approval_required: false },
|
|
440
|
+
},
|
|
441
|
+
escalation: {
|
|
442
|
+
severity_threshold: 'critical',
|
|
443
|
+
cia_threshold: { c: 'high', i: 'high', a: 'high' },
|
|
444
|
+
pause_on_low_confidence: false,
|
|
445
|
+
},
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
// ---------------------------------------------------------------------------
|
|
449
|
+
// Helpers
|
|
450
|
+
function stripToHostname(input) {
|
|
451
|
+
const trimmed = input.trim();
|
|
452
|
+
if (!trimmed)
|
|
453
|
+
return null;
|
|
454
|
+
// If it parses as a URL, take the hostname.
|
|
455
|
+
try {
|
|
456
|
+
const u = new URL(trimmed.includes('://') ? trimmed : `https://${trimmed}`);
|
|
457
|
+
if (u.hostname)
|
|
458
|
+
return u.hostname;
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
/* fall through */
|
|
462
|
+
}
|
|
463
|
+
return trimmed;
|
|
464
|
+
}
|
|
465
|
+
function matchDomain(host, pattern, includeSubdomains) {
|
|
466
|
+
const h = host.toLowerCase();
|
|
467
|
+
const p = pattern.toLowerCase();
|
|
468
|
+
// Wildcard patterns: `*.example.com` → matches any single-level subdomain
|
|
469
|
+
// plus the bare domain when includeSubdomains is true.
|
|
470
|
+
if (p.startsWith('*.')) {
|
|
471
|
+
const bare = p.slice(2);
|
|
472
|
+
return h === bare || h.endsWith('.' + bare);
|
|
473
|
+
}
|
|
474
|
+
if (h === p)
|
|
475
|
+
return true;
|
|
476
|
+
if (includeSubdomains && h.endsWith('.' + p))
|
|
477
|
+
return true;
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
function ipInCidr(host, cidr) {
|
|
481
|
+
// IPv4-only for v0.1.0; IPv6 ranges are accepted by the schema but
|
|
482
|
+
// matching is treated as out-of-scope (returns false). A future
|
|
483
|
+
// iteration extends this. The conservative answer for IPv6 is "not
|
|
484
|
+
// matched" — so an IPv6 deny-list still blocks via domain rules.
|
|
485
|
+
const m = /^(?:\d{1,3}\.){3}\d{1,3}$/.exec(host);
|
|
486
|
+
if (!m)
|
|
487
|
+
return false;
|
|
488
|
+
const [range, bitsStr] = cidr.split('/');
|
|
489
|
+
if (!range || !bitsStr)
|
|
490
|
+
return false;
|
|
491
|
+
if (!/^(?:\d{1,3}\.){3}\d{1,3}$/.test(range))
|
|
492
|
+
return false;
|
|
493
|
+
const bits = parseInt(bitsStr, 10);
|
|
494
|
+
if (!Number.isFinite(bits) || bits < 0 || bits > 32)
|
|
495
|
+
return false;
|
|
496
|
+
const hostInt = ipv4ToInt(host);
|
|
497
|
+
const rangeInt = ipv4ToInt(range);
|
|
498
|
+
if (hostInt === null || rangeInt === null)
|
|
499
|
+
return false;
|
|
500
|
+
if (bits === 0)
|
|
501
|
+
return true;
|
|
502
|
+
const mask = bits === 32 ? 0xffffffff : (~0 << (32 - bits)) >>> 0;
|
|
503
|
+
return (hostInt & mask) === (rangeInt & mask);
|
|
504
|
+
}
|
|
505
|
+
function ipv4ToInt(ip) {
|
|
506
|
+
const parts = ip.split('.').map((p) => parseInt(p, 10));
|
|
507
|
+
if (parts.length !== 4)
|
|
508
|
+
return null;
|
|
509
|
+
let out = 0;
|
|
510
|
+
for (const p of parts) {
|
|
511
|
+
if (!Number.isFinite(p) || p < 0 || p > 255)
|
|
512
|
+
return null;
|
|
513
|
+
out = ((out << 8) | p) >>> 0;
|
|
514
|
+
}
|
|
515
|
+
return out >>> 0;
|
|
516
|
+
}
|
|
517
|
+
function pathMatches(target, pattern) {
|
|
518
|
+
// Path-prefix match — minimal implementation for asset_criticality
|
|
519
|
+
// entries that point at repo paths or URL paths. Glob support is a
|
|
520
|
+
// Phase-2 cluster-1.5 enhancement.
|
|
521
|
+
if (!pattern.includes('/'))
|
|
522
|
+
return false;
|
|
523
|
+
return target.includes(pattern);
|
|
524
|
+
}
|
|
525
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/roe/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAC9E,cAAc;AAEd,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC7C,EAAE,OAAO,EAAE,uEAAuE,EAAE,CACrF;IACH,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAC9C,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,EAAE;KACR,KAAK,CACJ,8DAA8D,EAC9D,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAClE,CAAC;AAEJ,MAAM,aAAa,GAAG,CAAC;KACpB,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACjD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACzD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/C,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC9C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,2BAA2B,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1B,CAAC;KACD,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;IACtD,OAAO,EAAE,yCAAyC;CACnD,CAAC,CAAC;AAEL,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC5D,CAAC;KACD,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;IACtD,OAAO,EAAE,2CAA2C;CACrD,CAAC,CAAC;AAEL,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACxF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACpD,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5D,mGAAmG;IACnG,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7D,6BAA6B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACtE,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,0CAA0C;IAC1C,iBAAiB,EAAE,CAAC;SACjB,MAAM,CAAC;QACN,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QACnD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;QACnD,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KAC/D,CAAC;SACD,MAAM,EAAE;SACR,QAAQ,EAAE;IACb,yEAAyE;IACzE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC1C,mDAAmD;IACnD,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACnE,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,qBAAqB,GAAG,CAAC;KAC5B,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE;QAC5B,OAAO,EACL,8GAA8G;KACjH,CAAC;IACF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC1C,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;IAC/F,yEAAyE;IACzE,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;CAC7D,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,yBAAyB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACzC,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACpC,2BAA2B,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnE,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,oBAAoB,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,EAAE,EAAE,yBAAyB,CAAC,QAAQ,EAAE;IACxC,EAAE,EAAE,yBAAyB,CAAC,QAAQ,EAAE;IACxC,EAAE,EAAE,yBAAyB,CAAC,QAAQ,EAAE;IACxC,EAAE,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CACzC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,wBAAwB,GAAG,CAAC;KAC/B,MAAM,CAAC;IACN,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACrD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,sBAAsB,GAAG,CAAC;KAC7B,MAAM,CAAC;IACN,wEAAwE;IACxE,kBAAkB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/F,8CAA8C;IAC9C,aAAa,EAAE,CAAC;SACb,MAAM,CAAC;QACN,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;QACvD,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;QACvD,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;KACxD,CAAC;SACD,MAAM,EAAE;SACR,QAAQ,EAAE;IACb,kFAAkF;IAClF,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAChD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,cAAc,GAAG,CAAC;KACrB,MAAM,CAAC;IACN,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,yBAAyB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAChC,MAAM,EAAE,CAAC;SACN,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;SAClE,GAAG,CAAC,CAAC,CAAC;CACV,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,mBAAmB,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACzD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,gBAAgB,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5D,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC5C,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1E,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAClD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,8EAA8E;AAC9E,uBAAuB;AAEvB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAChC,QAAQ,EAAE,cAAc;IACxB,aAAa,EAAE,mBAAmB;IAClC,QAAQ,EAAE,aAAa;IACvB,YAAY,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,iBAAiB,EAAE,CAAC,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACnE,QAAQ,EAAE,cAAc;IACxB,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9E,aAAa,EAAE,mBAAmB,CAAC,QAAQ,EAAE;IAC7C,UAAU,EAAE,gBAAgB,CAAC,QAAQ,EAAE;IACvC,iFAAiF;IACjF,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACtD,sEAAsE;IACtE,eAAe,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAChD,gEAAgE;IAChE,eAAe,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAChD,2EAA2E;IAC3E,mBAAmB,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IACxD,0FAA0F;IAC1F,UAAU,EAAE,sBAAsB,CAAC,QAAQ,EAAE;CAC9C,CAAC;KACD,MAAM,EAAE,CAAC;AAcZ;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,GAAQ;IAC5D,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,UAAU,MAAM,0CAA0C;YAClE,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC9C,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACrC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,UAAU,IAAI,wCAAwC,MAAM,EAAE;gBACtE,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;aAC1C,CAAC;QACJ,CAAC;IACH,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QAChD,IAAI,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,UAAU,IAAI,8BAA8B,MAAM,EAAE;gBAC5D,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;aAC1C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACvC,IAAI,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1D,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,UAAU,IAAI,oCAAoC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC/H,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC;aACzD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAI,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,UAAU,IAAI,4BAA4B,IAAI,EAAE;gBACxD,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC;aACzD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,UAAU,IAAI,4CAA4C;QAClE,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAQ,EAAE,MAAY,IAAI,IAAI,EAAE;IACvE,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,iBAAiB,GAAG,CAAC,WAAW,EAAE,iCAAiC,GAAG,CAAC,QAAQ,CAAC,KAAK,GAAG;YAChG,SAAS,EAAE,CAAC,aAAa,CAAC;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,iBAAiB,GAAG,CAAC,WAAW,EAAE,8BAA8B,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG;YAC3F,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;SAC1C,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,2CAA2C,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,MAAM,GAAG;gBACpG,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;aAC1C,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,0DAA0D;QAClE,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc,EACd,GAAQ;IAER,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI;QAAE,OAAO,aAAa,CAAC;IAChC,mEAAmE;IACnE,iEAAiE;IACjE,oBAAoB;IACpB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC1C,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACjF,OAAO,KAAK,CAAC,cAAc,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,MAAc,EACd,GAAQ,EACR,MAAY,IAAI,IAAI,EAAE;IAEtB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,UAAU,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE;YAC9C,SAAS,EAAE,QAAQ,CAAC,SAAS;SAC9B,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,UAAU,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;YAC3C,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,UAAU,MAAM,OAAO,MAAM,kBAAkB,WAAW,sCAAsC;QACxG,SAAS,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC;KACzD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,UAGI,EAAE;IAEN,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;IAE/C,OAAO;QACL,MAAM,EAAE,eAAe,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;QAChE,YAAY,EAAE,OAAO;QACrB,QAAQ,EAAE;YACR,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,sBAAsB;YAC5D,aAAa,EAAE,mBAAmB;YAClC,OAAO,EAAE,aAAa;SACvB;QACD,aAAa,EAAE;YACb,SAAS,EACP,2FAA2F;YAC7F,gBAAgB,EAAE,mBAAmB;SACtC;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;YACtD,SAAS,EAAE,EAAE;YACb,gBAAgB,EAAE,EAAE;SACrB;QACD,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QACvD,iBAAiB,EAAE,EAAE;QACrB,QAAQ,EAAE;YACR,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE;YACxB,GAAG,EAAE,GAAG,CAAC,WAAW,EAAE;YACtB,QAAQ,EAAE,KAAK;YACf,gBAAgB,EAAE,EAAE;SACrB;QACD,eAAe,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE;QAChD,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QAC5B,eAAe,EAAE;YACf,iBAAiB,EAAE;gBACjB,WAAW,EAAE,IAAI;gBACjB,cAAc,EAAE,GAAG;gBACnB,sBAAsB,EAAE,MAAM;aAC/B;YACD,0BAA0B,EAAE,EAAE;SAC/B;QACD,eAAe,EAAE;YACf,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE;YAChC,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE;YAChC,EAAE,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE;YAC/B,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE;SACjC;QACD,UAAU,EAAE;YACV,kBAAkB,EAAE,UAAU;YAC9B,aAAa,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;YAClD,uBAAuB,EAAE,KAAK;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AAEV,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,CAAC,QAAQ;YAAE,OAAO,CAAC,CAAC,QAAQ,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,iBAA0B;IAC5E,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAChC,0EAA0E;IAC1E,uDAAuD;IACvD,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxB,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,iBAAiB,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAY;IAC1C,mEAAmE;IACnE,gEAAgE;IAChE,mEAAmE;IACnE,iEAAiE;IACjE,MAAM,CAAC,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAClE,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IAClE,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,SAAS,CAAC,EAAU;IAC3B,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QACzD,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,OAAe;IAClD,mEAAmE;IACnE,mEAAmE;IACnE,mCAAmC;IACnC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { EngagementEvent, EventSink } from './events.js';
|
|
2
|
+
export interface ChainedEmitterOpts {
|
|
3
|
+
sink: EventSink;
|
|
4
|
+
/** Initial prev-hash. null = chain starts here. Use the prior chain's tail when continuing across resume. */
|
|
5
|
+
initialPrevHash?: string | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Stateful emitter that maintains the running prev_hash → this_hash chain.
|
|
9
|
+
* Each `emit` call pours the chain forward by one link. The current chain
|
|
10
|
+
* tail is exposed via `getTail()` so a resume operation can pick up where
|
|
11
|
+
* the prior session left off.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ChainedEmitter {
|
|
14
|
+
private readonly opts;
|
|
15
|
+
private prevHash;
|
|
16
|
+
constructor(opts: ChainedEmitterOpts);
|
|
17
|
+
emit(event: EngagementEvent): EngagementEvent;
|
|
18
|
+
getTail(): string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface ChainVerifyOk {
|
|
21
|
+
ok: true;
|
|
22
|
+
total_events: number;
|
|
23
|
+
tail_hash: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface ChainVerifyFailure {
|
|
26
|
+
ok: false;
|
|
27
|
+
error: string;
|
|
28
|
+
/** 0-indexed line number where the chain broke. */
|
|
29
|
+
broken_at: number;
|
|
30
|
+
total_events_processed: number;
|
|
31
|
+
}
|
|
32
|
+
export type ChainVerifyResult = ChainVerifyOk | ChainVerifyFailure;
|
|
33
|
+
/**
|
|
34
|
+
* Verify the integrity of a JSONL audit-log file. Each EVENT line must:
|
|
35
|
+
* - parse as JSON
|
|
36
|
+
* - carry this_hash + prev_hash fields
|
|
37
|
+
* - have a this_hash that matches the canonical hash of its other fields
|
|
38
|
+
* - have a prev_hash that matches the previous line's this_hash (null on line 0)
|
|
39
|
+
*
|
|
40
|
+
* Snapshot lines (those with `state_version` but no `event` field) are
|
|
41
|
+
* SKIPPED — they exist alongside events in the same JSONL file (audit-fix
|
|
42
|
+
* 2026-04-27 made writeEngagementState append-not-overwrite).
|
|
43
|
+
*
|
|
44
|
+
* KNOWN SCOPE LIMIT (audit-fix-2 2026-04-27):
|
|
45
|
+
* Snapshot lines are NOT part of the hash chain. An attacker with
|
|
46
|
+
* write access to the state-file can post-hoc tamper with snapshot
|
|
47
|
+
* fields (`completed_phases`, `findings_so_far`, `paused_at`,
|
|
48
|
+
* `reason`) without breaking chain verification. The EVENT timeline
|
|
49
|
+
* remains tamper-evident — every state transition emits an event,
|
|
50
|
+
* so a tampered snapshot is contradicted by the unchanged event
|
|
51
|
+
* stream. Resume-from-snapshot consumers MUST cross-check snapshot
|
|
52
|
+
* contents against the event chain before trusting them. Closing
|
|
53
|
+
* this gap fully would require chaining snapshot writes through
|
|
54
|
+
* ChainedEmitter (snapshot becomes an event with prev_hash +
|
|
55
|
+
* this_hash); deferred to a future cluster.
|
|
56
|
+
*
|
|
57
|
+
* Returns ok-with-tail-hash on success, or failure-at-line-N with reason.
|
|
58
|
+
*/
|
|
59
|
+
export declare function verifyAuditChain(path: string): ChainVerifyResult;
|
|
60
|
+
//# sourceMappingURL=chain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../src/runtime/chain.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI9D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,6GAA6G;IAC7G,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IAEb,OAAO,CAAC,QAAQ,CAAC,IAAI;IADjC,OAAO,CAAC,QAAQ,CAAgB;gBACH,IAAI,EAAE,kBAAkB;IAIrD,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,eAAe;IAc7C,OAAO,IAAI,MAAM,GAAG,IAAI;CAGzB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AACD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AACD,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CA8EhE"}
|