agent-threat-rules 3.5.12 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +119 -23
  2. package/dist/action-executor.d.ts +31 -0
  3. package/dist/action-executor.d.ts.map +1 -1
  4. package/dist/action-executor.js +29 -0
  5. package/dist/action-executor.js.map +1 -1
  6. package/dist/cli/scan-handler.d.ts +9 -0
  7. package/dist/cli/scan-handler.d.ts.map +1 -1
  8. package/dist/cli/scan-handler.js +12 -2
  9. package/dist/cli/scan-handler.js.map +1 -1
  10. package/dist/cli.js +131 -8
  11. package/dist/cli.js.map +1 -1
  12. package/dist/enforcement.d.ts +233 -0
  13. package/dist/enforcement.d.ts.map +1 -0
  14. package/dist/enforcement.js +316 -0
  15. package/dist/enforcement.js.map +1 -0
  16. package/dist/engine.d.ts +18 -0
  17. package/dist/engine.d.ts.map +1 -1
  18. package/dist/engine.js +17 -3
  19. package/dist/engine.js.map +1 -1
  20. package/dist/hook-handler.d.ts +98 -3
  21. package/dist/hook-handler.d.ts.map +1 -1
  22. package/dist/hook-handler.js +119 -12
  23. package/dist/hook-handler.js.map +1 -1
  24. package/dist/index.d.ts +4 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +11 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/mcp-server.d.ts +13 -2
  29. package/dist/mcp-server.d.ts.map +1 -1
  30. package/dist/mcp-server.js +22 -5
  31. package/dist/mcp-server.js.map +1 -1
  32. package/dist/types.d.ts +13 -2
  33. package/dist/types.d.ts.map +1 -1
  34. package/package.json +4 -2
  35. package/rules/model-abuse/ATR-2026-01750-dos-repeat-word-n-times-output-amplification.yaml +14 -2
  36. package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +56 -6
  37. package/rules/prompt-injection/ATR-2026-00443-word-fragment-concat-assembly.yaml +11 -2
  38. package/rules/prompt-injection/ATR-2026-01904-link-injection.yaml +12 -3
  39. package/rules/prompt-injection/ATR-2026-02500-prompt-layer-self-replication.yaml +287 -0
  40. package/rules/prompt-injection/ATR-2026-02502-covert-remote-script-injection-into-generated-artifacts.yaml +209 -0
  41. package/rules/tool-poisoning/ATR-2026-00103-hidden-safety-bypass-instruction.yaml +1 -1
  42. package/rules/tool-poisoning/ATR-2026-00161-important-tag-cross-tool-shadowing.yaml +1 -1
  43. package/rules/tool-poisoning/ATR-2026-01775-semantic-mcp-tool-manifest-poisoning.yaml +1 -1
  44. package/rules/tool-poisoning/ATR-2026-02025-mcp-full-schema-poisoning-nondescription-field.yaml +1 -1
  45. package/spec/atr-method-v1.1.md +2 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Enforcement policy — the two operator switches, and the one precedence rule
3
+ * that governs both.
4
+ *
5
+ * ATR separates DETECTION from ENFORCEMENT. Detection always runs; enforcement
6
+ * is what the engine is allowed to DO with a detection:
7
+ *
8
+ * lane Which rule maturities may fire at all.
9
+ * 'enforce' = stable only, 'alert' = stable+test, 'hunt' = all.
10
+ * Implemented by the lane gate in engine.ts (see passesLane).
11
+ *
12
+ * blocking Whether ATR may express a blocking decision. OFF BY DEFAULT.
13
+ * When off: the Claude Code hook contract omits permissionDecision
14
+ * entirely (the host applies its own default — ATR does not vote),
15
+ * and the ActionExecutor refuses to dispatch any response action
16
+ * above the OBSERVE blast-radius tier. Detection output is
17
+ * unchanged in both modes.
18
+ *
19
+ * WHY BLOCKING IS OPT-IN
20
+ *
21
+ * The load-bearing requirement is SPEC.md §5.5, which is engine-wide:
22
+ * "Engines MUST NOT execute response actions automatically without an explicit
23
+ * configuration directive from the operator." Until this module existed there
24
+ * was no way for an operator to express that directive — no CLI flag, no
25
+ * environment variable, no documented config key. This module IS that directive.
26
+ *
27
+ * Two weaker statements point the same way but must not be quoted as general
28
+ * rules, because they are not:
29
+ * - spec/atr-method-v1.1.md §5.6 says "Engines SHOULD NOT auto-block ON A
30
+ * HASH MATCH without operator policy explicitly enabling it". That sits
31
+ * under §5 Signature Method and is scoped to hash matches. An earlier
32
+ * revision of this comment elided "on a hash match" and widened it into a
33
+ * general SHOULD NOT. It is not one.
34
+ * - docs/QUALITY-STANDARD.md restricts blocking to `maturity: stable` rules,
35
+ * but that section is deployment guidance addressed to consumers, not a
36
+ * normative engine requirement.
37
+ *
38
+ * WHY ATR NEVER SAYS "allow"
39
+ *
40
+ * In the Claude Code PreToolUse contract, `permissionDecision: "allow"` is not
41
+ * neutral — it is an affirmative approval that suppresses the host's own
42
+ * permission prompt. ATR emits a permission decision only to RESTRAIN an
43
+ * operation (deny / ask). "No rule matched" is not "I approve this": it is ATR
44
+ * having nothing to say, and the host must be left on its own default path.
45
+ * This holds in BOTH modes — advisory omits every decision, and blocking omits
46
+ * the affirmative one. See toClaudeCodePreToolUse in hook-handler.ts.
47
+ *
48
+ * WHO READS THE ENVIRONMENT
49
+ *
50
+ * For the lane and blocking switches: only the CLI. `resolveEnforcementPolicy`
51
+ * below is the only function that reads `process.env` for THESE TWO switches,
52
+ * and `src/cli.ts` is its only caller; it hands the resolved values to
53
+ * ATREngine / ActionExecutor / HookHandler explicitly.
54
+ *
55
+ * Not "the only function in the package that touches process.env" — that is
56
+ * false and an earlier revision of this comment said it. Ten files under src/
57
+ * read the environment in code, including `adapters/openshell-filter.ts` and
58
+ * `adapters/nemoclaw-preflight.ts`, which read `ATR_MIN_SEVERITY` and block by
59
+ * default. Those adapters are outside this switch and stay that way; see the
60
+ * scope limit in CHANGELOG.md.
61
+ *
62
+ * `grep -rl "process\.env" src/` returns eleven, not ten: `src/index.ts` only
63
+ * names it in a comment. The correction above was itself first written as
64
+ * "eleven" off that grep, which is the same mistake one level down.
65
+ *
66
+ * Library constructors take `laneFromConfig` / `blockingFromConfig`, which
67
+ * cannot read the environment — `resolveLane` and `resolveBlocking` require an
68
+ * EnvSource argument, so there is no overload that silently falls through to
69
+ * `process.env`. This is structural, not a convention: an embedder cannot
70
+ * accidentally opt into ambient configuration.
71
+ *
72
+ * The rule exists because ambient configuration crosses trust boundaries
73
+ * invisibly. `new ATREngine()` inside a VS Code extension, a Mastra pipeline,
74
+ * or the `/openshell-filter`, `/nemoclaw-preflight` and `/mcp` entry points did
75
+ * not ask to be reconfigured by a shell profile — and `ATR_LANE=enforce` is a
76
+ * VALID value, so the old behaviour produced no warning at all while narrowing
77
+ * those callers to maturity=stable rules only.
78
+ *
79
+ * PRECEDENCE
80
+ *
81
+ * library: explicit config > built-in default
82
+ * CLI: flag > environment variable > built-in default
83
+ *
84
+ * An invalid explicit value (config field or CLI flag) throws or exits: that is
85
+ * the caller's own bug, reported where the caller is looking. An invalid
86
+ * ENVIRONMENT value degrades loudly instead — see resolveEnforcementPolicy for
87
+ * the measurement behind that split.
88
+ *
89
+ * @module agent-threat-rules/enforcement
90
+ */
91
+ import { type Lane } from './quality/rule-contract.js';
92
+ /** Environment variable naming the detection lane. */
93
+ export declare const LANE_ENV_VAR = "ATR_LANE";
94
+ /** Environment variable enabling blocking (the operator directive). */
95
+ export declare const BLOCKING_ENV_VAR = "ATR_BLOCKING";
96
+ /**
97
+ * Lane used when neither config nor environment says otherwise.
98
+ * 'hunt' keeps every maturity visible — advisory breadth, which is safe
99
+ * precisely because blocking is off by default.
100
+ */
101
+ export declare const DEFAULT_LANE: Lane;
102
+ /** Blocking is off until an operator turns it on. */
103
+ export declare const DEFAULT_BLOCKING = false;
104
+ /** Minimal read-only view of an environment. Keeps this module testable. */
105
+ export type EnvSource = Readonly<Record<string, string | undefined>>;
106
+ /**
107
+ * Parse a lane name. Returns null for anything not in LANES, so callers that
108
+ * want to report a usage error (the CLI) can do so without a try/catch.
109
+ *
110
+ * Trimmed and case-INSENSITIVE, matching parseBooleanFlag exactly. The two were
111
+ * asymmetric: `ATR_BLOCKING=ON` worked while `ATR_LANE=ENFORCE` did not, and the
112
+ * pair `ATR_LANE=ENFORCE ATR_BLOCKING=ON` therefore turned blocking on while
113
+ * silently widening the lane to hunt — the operator asked for the narrowest
114
+ * enforcement posture and got the broadest one. The fallback direction was
115
+ * exactly the dangerous one, so the fix is to accept the spelling, not to
116
+ * document the trap.
117
+ */
118
+ export declare function parseLane(value: string): Lane | null;
119
+ /**
120
+ * Parse a boolean switch value. Returns null for anything unrecognised.
121
+ * An empty string is treated as "not set" by the resolvers, not by this
122
+ * function — it returns null here so the caller decides.
123
+ */
124
+ export declare function parseBooleanFlag(value: string): boolean | null;
125
+ /**
126
+ * Resolve the active detection lane: explicit > env > default.
127
+ *
128
+ * `env` is REQUIRED and has no `process.env` default. That is the whole
129
+ * mechanism keeping ambient configuration out of the library: a caller must
130
+ * name the environment it wants read, and library constructors pass NO_ENV via
131
+ * laneFromConfig. Only the CLI passes `process.env`.
132
+ *
133
+ * @throws TypeError when either source carries a value that is not a lane.
134
+ */
135
+ export declare function resolveLane(explicit: Lane | string | undefined, env: EnvSource): Lane;
136
+ /**
137
+ * Resolve whether blocking is enabled: explicit > env > default (false).
138
+ *
139
+ * `env` is REQUIRED — see resolveLane for why.
140
+ *
141
+ * @throws TypeError when the explicit value is not a boolean, or when the
142
+ * environment variable is set to a value that is neither truthy nor
143
+ * falsy by the table above.
144
+ *
145
+ * The explicit-value check is not decoration. `blocking` crosses from
146
+ * untyped JavaScript (and from JSON config files) as often as from
147
+ * TypeScript, and every non-empty string is truthy: without this,
148
+ * `new ActionExecutor({ adapter, blocking: "false" })` TURNS BLOCKING
149
+ * ON while reading, to its author, as an explicit "off". The lane path
150
+ * validated its explicit value from the start; this one did not, and a
151
+ * switch that fails toward "more enforcement" is the wrong asymmetry to
152
+ * leave in place.
153
+ */
154
+ export declare function resolveBlocking(explicit: boolean | undefined, env: EnvSource): boolean;
155
+ /**
156
+ * Lane for a LIBRARY caller: explicit config, or the built-in default. Never
157
+ * reads the environment.
158
+ *
159
+ * @throws TypeError when the caller passes something that is not a lane.
160
+ */
161
+ export declare function laneFromConfig(explicit?: Lane | string): Lane;
162
+ /**
163
+ * Blocking for a LIBRARY caller: explicit config, or off. Never reads the
164
+ * environment.
165
+ *
166
+ * @throws TypeError when the caller passes a non-boolean.
167
+ */
168
+ export declare function blockingFromConfig(explicit?: boolean): boolean;
169
+ /** The enforcement posture a CLI process will run under. */
170
+ export interface EnforcementPolicy {
171
+ readonly lane: Lane;
172
+ readonly blocking: boolean;
173
+ /** Human-readable problems found while resolving. Empty on a clean read. */
174
+ readonly notes: readonly string[];
175
+ }
176
+ /**
177
+ * Resolve the posture for a CLI process: flag > environment > default.
178
+ *
179
+ * THE ONLY FUNCTION IN THIS PACKAGE THAT READS `process.env`.
180
+ *
181
+ * A bad FLAG is a usage error the CLI reports and exits on (see readLaneOption
182
+ * in cli.ts): it was typed by a person at a prompt who is looking at the exit
183
+ * code. A bad ENVIRONMENT VALUE is different, and this function degrades
184
+ * instead of throwing. That split was measured, not assumed.
185
+ *
186
+ * MEASUREMENT (Claude Code 2.1.76, hook dispatcher in the shipped binary)
187
+ * A `command` hook's exit status is mapped as:
188
+ * status 0 -> `hook_success`; the renderer for that attachment returns null.
189
+ * status 2 -> `hook_blocking_error`; stderr is shown AND the tool is blocked.
190
+ * otherwise -> `hook_non_blocking_error`; the tool RUNS, the attachment maps
191
+ * to [] for the model, and the renderer prints exactly
192
+ * "<hookName> hook error" — the captured stderr is not shown.
193
+ *
194
+ * So for `atr guard`, which `atr init` installs as a PreToolUse command hook,
195
+ * exiting non-zero over a typo would: lose all detection for that call, let the
196
+ * tool run anyway, and tell the operator nothing beyond a bare "hook error".
197
+ * It buys no visibility at the cost of the entire product. The only loud exit
198
+ * status is 2 — which BLOCKS the tool, i.e. a stray shell variable would block
199
+ * every tool call. Both alternatives are worse than degrading.
200
+ *
201
+ * THE TRADE-OFF, STATED
202
+ * Degrading means an operator can believe enforcement is on when it is not.
203
+ * That is a real cost and it is why `notes` is not optional: the caller must
204
+ * print every note. It is accepted because the degraded posture is advisory —
205
+ * ATR emits no permission decision and dispatches no action above OBSERVE — so
206
+ * the failure mode is "ATR does not act", never "ATR acts wrongly". Exiting
207
+ * would produce "ATR does not act" too, and silently, minus the detection.
208
+ *
209
+ * WHY AN UNREADABLE LANE ALSO FORCES BLOCKING OFF
210
+ * Falling back to hunt while blocking is on is the one combination that makes
211
+ * the degraded posture MORE dangerous than the requested one: the operator
212
+ * asked to block on maturity=stable rules only, and would instead block on
213
+ * every maturity including draft. So when the requested lane cannot be honoured
214
+ * the process drops to advisory. An explicit `--blocking` does not override
215
+ * this: the flag says "you may block", not "block on a lane I never chose".
216
+ */
217
+ export declare function resolveEnforcementPolicy(flags?: {
218
+ readonly lane?: Lane | undefined;
219
+ readonly blocking?: boolean | undefined;
220
+ }, env?: EnvSource): EnforcementPolicy;
221
+ /**
222
+ * Is this response action enforcement rather than observation?
223
+ *
224
+ * The observe/enforce split is NOT redefined here — it reads the blast-radius
225
+ * ladder in src/quality/action-eligibility.ts, which is the project's single
226
+ * ranking of what an action destroys. OBSERVE (alert / snapshot / shadow /
227
+ * escalate) changes nothing about the agent's execution and therefore always
228
+ * runs. Everything above it (INTERRUPT / DEGRADE / TERMINATE) denies an
229
+ * operation, alters session state, or destroys the session — that is
230
+ * enforcement and requires the operator directive.
231
+ */
232
+ export declare function isEnforcementAction(action: string): boolean;
233
+ //# sourceMappingURL=enforcement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforcement.d.ts","sourceRoot":"","sources":["../src/enforcement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AAEH,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAG9D,sDAAsD;AACtD,eAAO,MAAM,YAAY,aAAa,CAAC;AAEvC,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,IAAa,CAAC;AAEzC,qDAAqD;AACrD,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAOtC,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAK9D;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,EACnC,GAAG,EAAE,SAAS,GACb,IAAI,CAuBN;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,GAAG,SAAS,EAC7B,GAAG,EAAE,SAAS,GACb,OAAO,CAyBT;AASD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAE9D;AAED,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAO,EACzF,GAAG,GAAE,SAAuB,GAC3B,iBAAiB,CAuCnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Enforcement policy — the two operator switches, and the one precedence rule
3
+ * that governs both.
4
+ *
5
+ * ATR separates DETECTION from ENFORCEMENT. Detection always runs; enforcement
6
+ * is what the engine is allowed to DO with a detection:
7
+ *
8
+ * lane Which rule maturities may fire at all.
9
+ * 'enforce' = stable only, 'alert' = stable+test, 'hunt' = all.
10
+ * Implemented by the lane gate in engine.ts (see passesLane).
11
+ *
12
+ * blocking Whether ATR may express a blocking decision. OFF BY DEFAULT.
13
+ * When off: the Claude Code hook contract omits permissionDecision
14
+ * entirely (the host applies its own default — ATR does not vote),
15
+ * and the ActionExecutor refuses to dispatch any response action
16
+ * above the OBSERVE blast-radius tier. Detection output is
17
+ * unchanged in both modes.
18
+ *
19
+ * WHY BLOCKING IS OPT-IN
20
+ *
21
+ * The load-bearing requirement is SPEC.md §5.5, which is engine-wide:
22
+ * "Engines MUST NOT execute response actions automatically without an explicit
23
+ * configuration directive from the operator." Until this module existed there
24
+ * was no way for an operator to express that directive — no CLI flag, no
25
+ * environment variable, no documented config key. This module IS that directive.
26
+ *
27
+ * Two weaker statements point the same way but must not be quoted as general
28
+ * rules, because they are not:
29
+ * - spec/atr-method-v1.1.md §5.6 says "Engines SHOULD NOT auto-block ON A
30
+ * HASH MATCH without operator policy explicitly enabling it". That sits
31
+ * under §5 Signature Method and is scoped to hash matches. An earlier
32
+ * revision of this comment elided "on a hash match" and widened it into a
33
+ * general SHOULD NOT. It is not one.
34
+ * - docs/QUALITY-STANDARD.md restricts blocking to `maturity: stable` rules,
35
+ * but that section is deployment guidance addressed to consumers, not a
36
+ * normative engine requirement.
37
+ *
38
+ * WHY ATR NEVER SAYS "allow"
39
+ *
40
+ * In the Claude Code PreToolUse contract, `permissionDecision: "allow"` is not
41
+ * neutral — it is an affirmative approval that suppresses the host's own
42
+ * permission prompt. ATR emits a permission decision only to RESTRAIN an
43
+ * operation (deny / ask). "No rule matched" is not "I approve this": it is ATR
44
+ * having nothing to say, and the host must be left on its own default path.
45
+ * This holds in BOTH modes — advisory omits every decision, and blocking omits
46
+ * the affirmative one. See toClaudeCodePreToolUse in hook-handler.ts.
47
+ *
48
+ * WHO READS THE ENVIRONMENT
49
+ *
50
+ * For the lane and blocking switches: only the CLI. `resolveEnforcementPolicy`
51
+ * below is the only function that reads `process.env` for THESE TWO switches,
52
+ * and `src/cli.ts` is its only caller; it hands the resolved values to
53
+ * ATREngine / ActionExecutor / HookHandler explicitly.
54
+ *
55
+ * Not "the only function in the package that touches process.env" — that is
56
+ * false and an earlier revision of this comment said it. Ten files under src/
57
+ * read the environment in code, including `adapters/openshell-filter.ts` and
58
+ * `adapters/nemoclaw-preflight.ts`, which read `ATR_MIN_SEVERITY` and block by
59
+ * default. Those adapters are outside this switch and stay that way; see the
60
+ * scope limit in CHANGELOG.md.
61
+ *
62
+ * `grep -rl "process\.env" src/` returns eleven, not ten: `src/index.ts` only
63
+ * names it in a comment. The correction above was itself first written as
64
+ * "eleven" off that grep, which is the same mistake one level down.
65
+ *
66
+ * Library constructors take `laneFromConfig` / `blockingFromConfig`, which
67
+ * cannot read the environment — `resolveLane` and `resolveBlocking` require an
68
+ * EnvSource argument, so there is no overload that silently falls through to
69
+ * `process.env`. This is structural, not a convention: an embedder cannot
70
+ * accidentally opt into ambient configuration.
71
+ *
72
+ * The rule exists because ambient configuration crosses trust boundaries
73
+ * invisibly. `new ATREngine()` inside a VS Code extension, a Mastra pipeline,
74
+ * or the `/openshell-filter`, `/nemoclaw-preflight` and `/mcp` entry points did
75
+ * not ask to be reconfigured by a shell profile — and `ATR_LANE=enforce` is a
76
+ * VALID value, so the old behaviour produced no warning at all while narrowing
77
+ * those callers to maturity=stable rules only.
78
+ *
79
+ * PRECEDENCE
80
+ *
81
+ * library: explicit config > built-in default
82
+ * CLI: flag > environment variable > built-in default
83
+ *
84
+ * An invalid explicit value (config field or CLI flag) throws or exits: that is
85
+ * the caller's own bug, reported where the caller is looking. An invalid
86
+ * ENVIRONMENT value degrades loudly instead — see resolveEnforcementPolicy for
87
+ * the measurement behind that split.
88
+ *
89
+ * @module agent-threat-rules/enforcement
90
+ */
91
+ import { LANES } from './quality/rule-contract.js';
92
+ import { ACTION_TIERS, actionTier } from './quality/action-eligibility.js';
93
+ /** Environment variable naming the detection lane. */
94
+ export const LANE_ENV_VAR = 'ATR_LANE';
95
+ /** Environment variable enabling blocking (the operator directive). */
96
+ export const BLOCKING_ENV_VAR = 'ATR_BLOCKING';
97
+ /**
98
+ * Lane used when neither config nor environment says otherwise.
99
+ * 'hunt' keeps every maturity visible — advisory breadth, which is safe
100
+ * precisely because blocking is off by default.
101
+ */
102
+ export const DEFAULT_LANE = 'hunt';
103
+ /** Blocking is off until an operator turns it on. */
104
+ export const DEFAULT_BLOCKING = false;
105
+ const LANE_SET = new Set(LANES);
106
+ const TRUE_VALUES = new Set(['1', 'true', 'yes', 'on']);
107
+ const FALSE_VALUES = new Set(['0', 'false', 'no', 'off']);
108
+ /**
109
+ * Parse a lane name. Returns null for anything not in LANES, so callers that
110
+ * want to report a usage error (the CLI) can do so without a try/catch.
111
+ *
112
+ * Trimmed and case-INSENSITIVE, matching parseBooleanFlag exactly. The two were
113
+ * asymmetric: `ATR_BLOCKING=ON` worked while `ATR_LANE=ENFORCE` did not, and the
114
+ * pair `ATR_LANE=ENFORCE ATR_BLOCKING=ON` therefore turned blocking on while
115
+ * silently widening the lane to hunt — the operator asked for the narrowest
116
+ * enforcement posture and got the broadest one. The fallback direction was
117
+ * exactly the dangerous one, so the fix is to accept the spelling, not to
118
+ * document the trap.
119
+ */
120
+ export function parseLane(value) {
121
+ const normalized = value.trim().toLowerCase();
122
+ return LANE_SET.has(normalized) ? normalized : null;
123
+ }
124
+ /**
125
+ * Parse a boolean switch value. Returns null for anything unrecognised.
126
+ * An empty string is treated as "not set" by the resolvers, not by this
127
+ * function — it returns null here so the caller decides.
128
+ */
129
+ export function parseBooleanFlag(value) {
130
+ const normalized = value.trim().toLowerCase();
131
+ if (TRUE_VALUES.has(normalized))
132
+ return true;
133
+ if (FALSE_VALUES.has(normalized))
134
+ return false;
135
+ return null;
136
+ }
137
+ /**
138
+ * Resolve the active detection lane: explicit > env > default.
139
+ *
140
+ * `env` is REQUIRED and has no `process.env` default. That is the whole
141
+ * mechanism keeping ambient configuration out of the library: a caller must
142
+ * name the environment it wants read, and library constructors pass NO_ENV via
143
+ * laneFromConfig. Only the CLI passes `process.env`.
144
+ *
145
+ * @throws TypeError when either source carries a value that is not a lane.
146
+ */
147
+ export function resolveLane(explicit, env) {
148
+ if (explicit !== undefined) {
149
+ const parsed = parseLane(explicit);
150
+ if (parsed === null) {
151
+ throw new TypeError(`Invalid lane "${explicit}". Expected one of: ${LANES.join(', ')}.`);
152
+ }
153
+ return parsed;
154
+ }
155
+ const fromEnv = env[LANE_ENV_VAR];
156
+ if (fromEnv !== undefined && fromEnv.trim() !== '') {
157
+ const parsed = parseLane(fromEnv);
158
+ if (parsed === null) {
159
+ throw new TypeError(`Invalid ${LANE_ENV_VAR}="${fromEnv}". Expected one of: ${LANES.join(', ')}.`);
160
+ }
161
+ return parsed;
162
+ }
163
+ return DEFAULT_LANE;
164
+ }
165
+ /**
166
+ * Resolve whether blocking is enabled: explicit > env > default (false).
167
+ *
168
+ * `env` is REQUIRED — see resolveLane for why.
169
+ *
170
+ * @throws TypeError when the explicit value is not a boolean, or when the
171
+ * environment variable is set to a value that is neither truthy nor
172
+ * falsy by the table above.
173
+ *
174
+ * The explicit-value check is not decoration. `blocking` crosses from
175
+ * untyped JavaScript (and from JSON config files) as often as from
176
+ * TypeScript, and every non-empty string is truthy: without this,
177
+ * `new ActionExecutor({ adapter, blocking: "false" })` TURNS BLOCKING
178
+ * ON while reading, to its author, as an explicit "off". The lane path
179
+ * validated its explicit value from the start; this one did not, and a
180
+ * switch that fails toward "more enforcement" is the wrong asymmetry to
181
+ * leave in place.
182
+ */
183
+ export function resolveBlocking(explicit, env) {
184
+ if (explicit !== undefined) {
185
+ if (typeof explicit !== 'boolean') {
186
+ throw new TypeError(`Invalid blocking value ${JSON.stringify(explicit)} (${typeof explicit}). ` +
187
+ `Expected a boolean. Note that any non-empty string, including "false", ` +
188
+ `would otherwise enable blocking.`);
189
+ }
190
+ return explicit;
191
+ }
192
+ const fromEnv = env[BLOCKING_ENV_VAR];
193
+ if (fromEnv !== undefined && fromEnv.trim() !== '') {
194
+ const parsed = parseBooleanFlag(fromEnv);
195
+ if (parsed === null) {
196
+ throw new TypeError(`Invalid ${BLOCKING_ENV_VAR}="${fromEnv}". Expected one of: ` +
197
+ `${[...TRUE_VALUES].join('/')} or ${[...FALSE_VALUES].join('/')}.`);
198
+ }
199
+ return parsed;
200
+ }
201
+ return DEFAULT_BLOCKING;
202
+ }
203
+ /**
204
+ * An environment that is empty by construction. Library constructors resolve
205
+ * against this, so "the library does not read the environment" is enforced by
206
+ * the type system rather than by reviewer vigilance.
207
+ */
208
+ const NO_ENV = Object.freeze({});
209
+ /**
210
+ * Lane for a LIBRARY caller: explicit config, or the built-in default. Never
211
+ * reads the environment.
212
+ *
213
+ * @throws TypeError when the caller passes something that is not a lane.
214
+ */
215
+ export function laneFromConfig(explicit) {
216
+ return resolveLane(explicit, NO_ENV);
217
+ }
218
+ /**
219
+ * Blocking for a LIBRARY caller: explicit config, or off. Never reads the
220
+ * environment.
221
+ *
222
+ * @throws TypeError when the caller passes a non-boolean.
223
+ */
224
+ export function blockingFromConfig(explicit) {
225
+ return resolveBlocking(explicit, NO_ENV);
226
+ }
227
+ /**
228
+ * Resolve the posture for a CLI process: flag > environment > default.
229
+ *
230
+ * THE ONLY FUNCTION IN THIS PACKAGE THAT READS `process.env`.
231
+ *
232
+ * A bad FLAG is a usage error the CLI reports and exits on (see readLaneOption
233
+ * in cli.ts): it was typed by a person at a prompt who is looking at the exit
234
+ * code. A bad ENVIRONMENT VALUE is different, and this function degrades
235
+ * instead of throwing. That split was measured, not assumed.
236
+ *
237
+ * MEASUREMENT (Claude Code 2.1.76, hook dispatcher in the shipped binary)
238
+ * A `command` hook's exit status is mapped as:
239
+ * status 0 -> `hook_success`; the renderer for that attachment returns null.
240
+ * status 2 -> `hook_blocking_error`; stderr is shown AND the tool is blocked.
241
+ * otherwise -> `hook_non_blocking_error`; the tool RUNS, the attachment maps
242
+ * to [] for the model, and the renderer prints exactly
243
+ * "<hookName> hook error" — the captured stderr is not shown.
244
+ *
245
+ * So for `atr guard`, which `atr init` installs as a PreToolUse command hook,
246
+ * exiting non-zero over a typo would: lose all detection for that call, let the
247
+ * tool run anyway, and tell the operator nothing beyond a bare "hook error".
248
+ * It buys no visibility at the cost of the entire product. The only loud exit
249
+ * status is 2 — which BLOCKS the tool, i.e. a stray shell variable would block
250
+ * every tool call. Both alternatives are worse than degrading.
251
+ *
252
+ * THE TRADE-OFF, STATED
253
+ * Degrading means an operator can believe enforcement is on when it is not.
254
+ * That is a real cost and it is why `notes` is not optional: the caller must
255
+ * print every note. It is accepted because the degraded posture is advisory —
256
+ * ATR emits no permission decision and dispatches no action above OBSERVE — so
257
+ * the failure mode is "ATR does not act", never "ATR acts wrongly". Exiting
258
+ * would produce "ATR does not act" too, and silently, minus the detection.
259
+ *
260
+ * WHY AN UNREADABLE LANE ALSO FORCES BLOCKING OFF
261
+ * Falling back to hunt while blocking is on is the one combination that makes
262
+ * the degraded posture MORE dangerous than the requested one: the operator
263
+ * asked to block on maturity=stable rules only, and would instead block on
264
+ * every maturity including draft. So when the requested lane cannot be honoured
265
+ * the process drops to advisory. An explicit `--blocking` does not override
266
+ * this: the flag says "you may block", not "block on a lane I never chose".
267
+ */
268
+ export function resolveEnforcementPolicy(flags = {}, env = process.env) {
269
+ const notes = [];
270
+ let lane;
271
+ let laneHonoured = true;
272
+ try {
273
+ lane = resolveLane(flags.lane, env);
274
+ }
275
+ catch (error) {
276
+ if (flags.lane !== undefined)
277
+ throw error; // a flag is the caller's bug
278
+ laneHonoured = false;
279
+ lane = DEFAULT_LANE;
280
+ notes.push(`${error.message} Falling back to lane "${DEFAULT_LANE}". ` +
281
+ `Detection still runs; this only changes which maturities may fire.`);
282
+ }
283
+ let blocking;
284
+ try {
285
+ blocking = resolveBlocking(flags.blocking, env);
286
+ }
287
+ catch (error) {
288
+ if (flags.blocking !== undefined)
289
+ throw error;
290
+ blocking = DEFAULT_BLOCKING;
291
+ notes.push(`${error.message} Falling back to blocking=${DEFAULT_BLOCKING}. ` +
292
+ `If you meant to enable enforcement, it is NOT enabled.`);
293
+ }
294
+ if (!laneHonoured && blocking) {
295
+ blocking = false;
296
+ notes.push(`Blocking disabled: ${LANE_ENV_VAR} could not be read, and blocking on the ` +
297
+ `fallback lane "${DEFAULT_LANE}" would enforce on more rule maturities ` +
298
+ `than you asked for. Fix ${LANE_ENV_VAR} to re-enable enforcement.`);
299
+ }
300
+ return Object.freeze({ lane, blocking, notes: Object.freeze(notes) });
301
+ }
302
+ /**
303
+ * Is this response action enforcement rather than observation?
304
+ *
305
+ * The observe/enforce split is NOT redefined here — it reads the blast-radius
306
+ * ladder in src/quality/action-eligibility.ts, which is the project's single
307
+ * ranking of what an action destroys. OBSERVE (alert / snapshot / shadow /
308
+ * escalate) changes nothing about the agent's execution and therefore always
309
+ * runs. Everything above it (INTERRUPT / DEGRADE / TERMINATE) denies an
310
+ * operation, alters session state, or destroys the session — that is
311
+ * enforcement and requires the operator directive.
312
+ */
313
+ export function isEnforcementAction(action) {
314
+ return actionTier(action) > ACTION_TIERS.OBSERVE;
315
+ }
316
+ //# sourceMappingURL=enforcement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforcement.js","sourceRoot":"","sources":["../src/enforcement.ts"],"names":[],"mappings":"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"}
package/dist/engine.d.ts CHANGED
@@ -12,6 +12,7 @@
12
12
  * @module agent-threat-rules/engine
13
13
  */
14
14
  import type { ATRRule, ATRMatch, AgentEvent, ATRVerdict, ActionResult, ScanResult, ATRLanguage, ATRSemanticJudge } from './types.js';
15
+ import { type Lane } from './quality/rule-contract.js';
15
16
  import type { SessionTracker } from './session-tracker.js';
16
17
  import type { ActionExecutor } from './action-executor.js';
17
18
  import type { SkillFingerprintStore } from './skill-fingerprint.js';
@@ -79,6 +80,15 @@ export interface ATREngineConfig {
79
80
  * 'alert' : maturity stable + test (analyst/correlation lane).
80
81
  * 'hunt' : all maturities (advisory/eval; default, backward-compatible).
81
82
  * Deprecated/draft rules are always skipped regardless of lane.
83
+ *
84
+ * This field is the ONLY input: the engine does not read `ATR_LANE` or any
85
+ * other environment variable. Leaving it undefined pins the lane to 'hunt',
86
+ * the widest and most advisory setting, no matter what the surrounding shell
87
+ * says. A CLI that wants environment support resolves it itself and passes
88
+ * the result here (src/cli.ts, resolveEnforcementPolicy).
89
+ *
90
+ * An unrecognised value throws at construction time — that is a caller bug,
91
+ * not ambient noise.
82
92
  */
83
93
  lane?: 'enforce' | 'alert' | 'hunt';
84
94
  /**
@@ -95,6 +105,12 @@ export declare class ATREngine {
95
105
  private rules;
96
106
  private readonly compiledPatterns;
97
107
  private readonly semanticModuleInstance;
108
+ /**
109
+ * Active detection lane, resolved ONCE at construction from config alone.
110
+ * Held as a field so every gate in this engine sees the same lane for its
111
+ * lifetime.
112
+ */
113
+ private readonly lane;
98
114
  /**
99
115
  * Find bundled rules directory shipped with the npm package.
100
116
  * Checks: ../rules (from dist/), ./rules (repo root)
@@ -111,6 +127,8 @@ export declare class ATREngine {
111
127
  * Keeps experimental content out of the auto-block path without deleting it.
112
128
  */
113
129
  private passesLane;
130
+ /** Active detection lane (config, else 'hunt'). Diagnostics/tests. */
131
+ getLane(): Lane;
114
132
  /**
115
133
  * Load a single rule file and add it to the engine.
116
134
  */
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,QAAQ,EACR,UAAU,EAGV,UAAU,EACV,YAAY,EACZ,UAAU,EAEV,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAA+B,KAAK,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAQlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA8D9D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB5D;AAsBD;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,sEAAsE;IACtE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IACzC,qFAAqF;IACrF,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,0EAA0E;IAC1E,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,SAAS;IA8BR,OAAO,CAAC,QAAQ,CAAC,MAAM;IA7BnC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAwB;IAC/D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAE5B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;gBAeE,MAAM,GAAE,eAAoB;IAczD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IA2BlC;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAMlB,sEAAsE;IACtE,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMnC;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAK5B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,EAAE;IAOvC;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAkKnB;;;;;;OAMG;IACG,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAuH3D;;;OAGG;IACH,OAAO,CAAC,YAAY;IAyDpB,qFAAqF;IACrF,OAAO,CAAC,mBAAmB;IAY3B;;;OAGG;YACW,iBAAiB;IAgC/B;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAgC/B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IA8C/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA8G9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAoC/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA0FhC;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAwBlC;;;;OAIG;IACH,OAAO,CAAC,2BAA2B;IAoBnC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAiBrB;;;;;;;;OAQG;IACH,OAAO,CAAC,yBAAyB;IAmBjC;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAyErC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA4BnC;;OAEG;IACH,OAAO,CAAC,YAAY;IAkDpB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAsC1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;;OAGG;IACH,OAAO,CAAC,eAAe;IA4CvB;;;;;OAKG;IACG,mBAAmB,CACvB,KAAK,EAAE,UAAU,EACjB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC;QACT,OAAO,EAAE,UAAU,CAAC;QACpB,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;QACvC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;KAC/B,CAAC;IAiIF,4BAA4B;IAC5B,YAAY,IAAI,MAAM;IAItB,2BAA2B;IAC3B,QAAQ,IAAI,SAAS,OAAO,EAAE;IAI9B,uBAAuB;IACvB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI5C,4BAA4B;IAC5B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAI/C;;;;;;;OAOG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE;IA4BtC;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IA2B1D,8EAA8E;IAC9E,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU;IAa7D,6DAA6D;IACvD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAajF,qFAAqF;IACrF,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU;IAiB9D,8DAA8D;IACxD,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAenF;AAcD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AAiDD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBpD;AAoBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAwC7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,SAAS,EAAE,WAAW,GACrB,OAAO,CAUT;AAwDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA2BnD"}