@principles/core 1.114.0 → 1.115.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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Activation Types Helper Functions Tests
3
+ *
4
+ * Unit tests for helper functions in activation-types.ts:
5
+ * - makeIdempotencyKey()
6
+ * - isLowRiskChannel()
7
+ * - getChannelRiskLevel()
8
+ * - mapConfidenceToLabel()
9
+ *
10
+ * These functions are critical for activation dispatch decisions and
11
+ * approval queue operations. Tests verify boundary conditions and
12
+ * all possible input combinations.
13
+ *
14
+ * ERR checklist:
15
+ * - ERR-002: Every decision path carries reason + nextAction
16
+ * - ERR-009: Malformed state fails loud
17
+ * - ERR-025: Production-path tests, not just helpers
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=activation-types-helpers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activation-types-helpers.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/activation-types-helpers.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Activation Types Helper Functions Tests
3
+ *
4
+ * Unit tests for helper functions in activation-types.ts:
5
+ * - makeIdempotencyKey()
6
+ * - isLowRiskChannel()
7
+ * - getChannelRiskLevel()
8
+ * - mapConfidenceToLabel()
9
+ *
10
+ * These functions are critical for activation dispatch decisions and
11
+ * approval queue operations. Tests verify boundary conditions and
12
+ * all possible input combinations.
13
+ *
14
+ * ERR checklist:
15
+ * - ERR-002: Every decision path carries reason + nextAction
16
+ * - ERR-009: Malformed state fails loud
17
+ * - ERR-025: Production-path tests, not just helpers
18
+ */
19
+ import { describe, it, expect } from 'vitest';
20
+ import { makeIdempotencyKey, isLowRiskChannel, getChannelRiskLevel, mapConfidenceToLabel, LOW_RISK_CHANNELS, HIGH_RISK_CHANNEL_MAP, AUTO_PROMOTION_CONFIDENCE_THRESHOLD, AUTO_PROMOTABLE_CHANNELS, } from '../activation/activation-types';
21
+ // ── makeIdempotencyKey Tests ──────────────────────────────────────────────────
22
+ describe('makeIdempotencyKey', () => {
23
+ it('produces expected format: artifactId::channel', () => {
24
+ expect(makeIdempotencyKey('art-001', 'prompt')).toBe('art-001::prompt');
25
+ expect(makeIdempotencyKey('art-abc', 'code_tool_hook')).toBe('art-abc::code_tool_hook');
26
+ expect(makeIdempotencyKey('art-xyz', 'defer_archive')).toBe('art-xyz::defer_archive');
27
+ });
28
+ it('handles empty artifactId', () => {
29
+ expect(makeIdempotencyKey('', 'prompt')).toBe('::prompt');
30
+ });
31
+ it('handles artifactId with special characters', () => {
32
+ expect(makeIdempotencyKey('art-with-dashes', 'prompt')).toBe('art-with-dashes::prompt');
33
+ expect(makeIdempotencyKey('art_with_underscores', 'prompt')).toBe('art_with_underscores::prompt');
34
+ expect(makeIdempotencyKey('art.with.dots', 'prompt')).toBe('art.with.dots::prompt');
35
+ });
36
+ it('handles artifactId with colons (edge case)', () => {
37
+ // Colons in artifactId could cause ambiguity, but function doesn't escape
38
+ expect(makeIdempotencyKey('art:001', 'prompt')).toBe('art:001::prompt');
39
+ });
40
+ it('handles all valid channels', () => {
41
+ const channels = [
42
+ 'prompt', 'defer_archive', 'skill', 'code_tool_hook', 'model_training',
43
+ ];
44
+ for (const channel of channels) {
45
+ const key = makeIdempotencyKey('art-001', channel);
46
+ expect(key).toContain('::');
47
+ expect(key.endsWith(channel)).toBe(true);
48
+ }
49
+ });
50
+ it('is deterministic — same inputs produce same output', () => {
51
+ const key1 = makeIdempotencyKey('art-001', 'prompt');
52
+ const key2 = makeIdempotencyKey('art-001', 'prompt');
53
+ expect(key1).toBe(key2);
54
+ });
55
+ it('is reversible — can parse back artifactId and channel', () => {
56
+ const key = makeIdempotencyKey('art-001', 'prompt');
57
+ const [artifactId, channel] = key.split('::');
58
+ expect(artifactId).toBe('art-001');
59
+ expect(channel).toBe('prompt');
60
+ });
61
+ });
62
+ // ── isLowRiskChannel Tests ───────────────────────────────────────────────────
63
+ describe('isLowRiskChannel', () => {
64
+ it('returns true for prompt channel', () => {
65
+ expect(isLowRiskChannel('prompt')).toBe(true);
66
+ });
67
+ it('returns true for defer_archive channel', () => {
68
+ expect(isLowRiskChannel('defer_archive')).toBe(true);
69
+ });
70
+ it('returns false for skill channel', () => {
71
+ expect(isLowRiskChannel('skill')).toBe(false);
72
+ });
73
+ it('returns false for code_tool_hook channel', () => {
74
+ expect(isLowRiskChannel('code_tool_hook')).toBe(false);
75
+ });
76
+ it('returns false for model_training channel', () => {
77
+ expect(isLowRiskChannel('model_training')).toBe(false);
78
+ });
79
+ it('LOW_RISK_CHANNELS contains exactly prompt and defer_archive', () => {
80
+ expect(LOW_RISK_CHANNELS).toHaveLength(2);
81
+ expect(LOW_RISK_CHANNELS).toContain('prompt');
82
+ expect(LOW_RISK_CHANNELS).toContain('defer_archive');
83
+ });
84
+ it('isLowRiskChannel matches LOW_RISK_CHANNELS membership', () => {
85
+ const allChannels = [
86
+ 'prompt', 'defer_archive', 'skill', 'code_tool_hook', 'model_training',
87
+ ];
88
+ for (const channel of allChannels) {
89
+ expect(isLowRiskChannel(channel)).toBe(LOW_RISK_CHANNELS.includes(channel));
90
+ }
91
+ });
92
+ it('returns false for unknown channel (safe default)', () => {
93
+ expect(isLowRiskChannel('unknown')).toBe(false);
94
+ });
95
+ });
96
+ // ── getChannelRiskLevel Tests ────────────────────────────────────────────────
97
+ describe('getChannelRiskLevel', () => {
98
+ it('returns low for prompt channel', () => {
99
+ expect(getChannelRiskLevel('prompt')).toBe('low');
100
+ });
101
+ it('returns low for defer_archive channel', () => {
102
+ expect(getChannelRiskLevel('defer_archive')).toBe('low');
103
+ });
104
+ it('returns medium for skill channel', () => {
105
+ expect(getChannelRiskLevel('skill')).toBe('medium');
106
+ });
107
+ it('returns high for code_tool_hook channel', () => {
108
+ expect(getChannelRiskLevel('code_tool_hook')).toBe('high');
109
+ });
110
+ it('returns critical for model_training channel', () => {
111
+ expect(getChannelRiskLevel('model_training')).toBe('critical');
112
+ });
113
+ it('returns high for unknown channel (safe default)', () => {
114
+ expect(getChannelRiskLevel('unknown')).toBe('high');
115
+ });
116
+ it('HIGH_RISK_CHANNEL_MAP has correct entries', () => {
117
+ expect(HIGH_RISK_CHANNEL_MAP.skill).toBe('medium');
118
+ expect(HIGH_RISK_CHANNEL_MAP.code_tool_hook).toBe('high');
119
+ expect(HIGH_RISK_CHANNEL_MAP.model_training).toBe('critical');
120
+ });
121
+ it('getChannelRiskLevel returns low for LOW_RISK_CHANNELS', () => {
122
+ for (const channel of LOW_RISK_CHANNELS) {
123
+ expect(getChannelRiskLevel(channel)).toBe('low');
124
+ }
125
+ });
126
+ it('getChannelRiskLevel returns HIGH_RISK_CHANNEL_MAP value for high-risk channels', () => {
127
+ for (const [channel, riskLevel] of Object.entries(HIGH_RISK_CHANNEL_MAP)) {
128
+ expect(getChannelRiskLevel(channel)).toBe(riskLevel);
129
+ }
130
+ });
131
+ it('risk levels are ordered: low < medium < high < critical', () => {
132
+ // This is a semantic ordering test, not a numeric comparison
133
+ const levels = ['low', 'medium', 'high', 'critical'];
134
+ expect(getChannelRiskLevel('prompt')).toBe(levels[0]);
135
+ expect(getChannelRiskLevel('skill')).toBe(levels[1]);
136
+ expect(getChannelRiskLevel('code_tool_hook')).toBe(levels[2]);
137
+ expect(getChannelRiskLevel('model_training')).toBe(levels[3]);
138
+ });
139
+ });
140
+ // ── mapConfidenceToLabel Tests ───────────────────────────────────────────────
141
+ describe('mapConfidenceToLabel', () => {
142
+ it('returns high for confidence >= 0.8', () => {
143
+ expect(mapConfidenceToLabel(0.8)).toBe('high');
144
+ expect(mapConfidenceToLabel(0.85)).toBe('high');
145
+ expect(mapConfidenceToLabel(0.9)).toBe('high');
146
+ expect(mapConfidenceToLabel(1.0)).toBe('high');
147
+ });
148
+ it('returns medium for confidence >= 0.5 and < 0.8', () => {
149
+ expect(mapConfidenceToLabel(0.5)).toBe('medium');
150
+ expect(mapConfidenceToLabel(0.55)).toBe('medium');
151
+ expect(mapConfidenceToLabel(0.6)).toBe('medium');
152
+ expect(mapConfidenceToLabel(0.7)).toBe('medium');
153
+ expect(mapConfidenceToLabel(0.79)).toBe('medium');
154
+ });
155
+ it('returns low for confidence < 0.5', () => {
156
+ expect(mapConfidenceToLabel(0.0)).toBe('low');
157
+ expect(mapConfidenceToLabel(0.1)).toBe('low');
158
+ expect(mapConfidenceToLabel(0.2)).toBe('low');
159
+ expect(mapConfidenceToLabel(0.3)).toBe('low');
160
+ expect(mapConfidenceToLabel(0.4)).toBe('low');
161
+ expect(mapConfidenceToLabel(0.49)).toBe('low');
162
+ });
163
+ it('returns medium for undefined confidence', () => {
164
+ expect(mapConfidenceToLabel(undefined)).toBe('medium');
165
+ });
166
+ it('returns medium for null confidence', () => {
167
+ expect(mapConfidenceToLabel(null)).toBe('medium');
168
+ });
169
+ // Boundary tests
170
+ it('returns high at exact boundary 0.8', () => {
171
+ expect(mapConfidenceToLabel(0.8)).toBe('high');
172
+ });
173
+ it('returns medium just below boundary 0.79', () => {
174
+ expect(mapConfidenceToLabel(0.79)).toBe('medium');
175
+ });
176
+ it('returns medium at exact boundary 0.5', () => {
177
+ expect(mapConfidenceToLabel(0.5)).toBe('medium');
178
+ });
179
+ it('returns low just below boundary 0.49', () => {
180
+ expect(mapConfidenceToLabel(0.49)).toBe('low');
181
+ });
182
+ // Edge cases
183
+ it('returns low for negative confidence (invalid but handled)', () => {
184
+ expect(mapConfidenceToLabel(-0.1)).toBe('low');
185
+ });
186
+ it('returns high for confidence > 1.0 (invalid but handled)', () => {
187
+ expect(mapConfidenceToLabel(1.5)).toBe('high');
188
+ });
189
+ it('all possible return values are valid ConfidenceLabels', () => {
190
+ const validLabels = ['high', 'medium', 'low'];
191
+ const testValues = [undefined, null, 0, 0.25, 0.5, 0.75, 1.0];
192
+ for (const val of testValues) {
193
+ const label = mapConfidenceToLabel(val);
194
+ expect(validLabels).toContain(label);
195
+ }
196
+ });
197
+ });
198
+ // ── Constants Tests ──────────────────────────────────────────────────────────
199
+ describe('constants', () => {
200
+ it('AUTO_PROMOTION_CONFIDENCE_THRESHOLD is 0.95', () => {
201
+ expect(AUTO_PROMOTION_CONFIDENCE_THRESHOLD).toBe(0.95);
202
+ });
203
+ it('AUTO_PROMOTABLE_CHANNELS contains only skill', () => {
204
+ expect(AUTO_PROMOTABLE_CHANNELS).toEqual(['skill']);
205
+ expect(AUTO_PROMOTABLE_CHANNELS).toHaveLength(1);
206
+ });
207
+ it('LOW_RISK_CHANNELS and HIGH_RISK_CHANNEL_MAP are disjoint', () => {
208
+ for (const channel of LOW_RISK_CHANNELS) {
209
+ expect(HIGH_RISK_CHANNEL_MAP[channel]).toBeUndefined();
210
+ }
211
+ });
212
+ it('all InternalizationChannel values are covered', () => {
213
+ const allChannels = [
214
+ 'prompt', 'defer_archive', 'skill', 'code_tool_hook', 'model_training',
215
+ ];
216
+ // Every channel should have a defined risk level
217
+ for (const channel of allChannels) {
218
+ const riskLevel = getChannelRiskLevel(channel);
219
+ expect(['low', 'medium', 'high', 'critical']).toContain(riskLevel);
220
+ }
221
+ });
222
+ });
223
+ //# sourceMappingURL=activation-types-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activation-types-helpers.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/activation-types-helpers.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Evidence Guards Tests — PRI-345
3
+ *
4
+ * Unit tests for shared evidence guard functions used by admission gate
5
+ * and pain signal bridge.
6
+ *
7
+ * Tests verify:
8
+ * - isOwnerExplicitManual() correctly identifies owner manual provenance
9
+ * - shouldShortCircuitEmptyEvidence() correctly determines short-circuit conditions
10
+ * - Boundary conditions and edge cases
11
+ *
12
+ * ERR checklist:
13
+ * - ERR-002: Every decision path carries reason + nextAction
14
+ * - ERR-009: Malformed state fails loud
15
+ * - ERR-025: Production-path tests, not just helpers
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=evidence-guards.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-guards.test.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/evidence-guards.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Evidence Guards Tests — PRI-345
3
+ *
4
+ * Unit tests for shared evidence guard functions used by admission gate
5
+ * and pain signal bridge.
6
+ *
7
+ * Tests verify:
8
+ * - isOwnerExplicitManual() correctly identifies owner manual provenance
9
+ * - shouldShortCircuitEmptyEvidence() correctly determines short-circuit conditions
10
+ * - Boundary conditions and edge cases
11
+ *
12
+ * ERR checklist:
13
+ * - ERR-002: Every decision path carries reason + nextAction
14
+ * - ERR-009: Malformed state fails loud
15
+ * - ERR-025: Production-path tests, not just helpers
16
+ */
17
+ import { describe, it, expect } from 'vitest';
18
+ import { isOwnerExplicitManual, shouldShortCircuitEmptyEvidence, } from '../evidence-guards';
19
+ // ── isOwnerExplicitManual Tests ───────────────────────────────────────────────
20
+ describe('isOwnerExplicitManual', () => {
21
+ it('returns true for owner_reported_no_host_trace provenance', () => {
22
+ expect(isOwnerExplicitManual('owner_reported_no_host_trace')).toBe(true);
23
+ });
24
+ it('returns false for openclaw_context_bound provenance', () => {
25
+ expect(isOwnerExplicitManual('openclaw_context_bound')).toBe(false);
26
+ });
27
+ it('returns false for automatic_hook provenance', () => {
28
+ expect(isOwnerExplicitManual('automatic_hook')).toBe(false);
29
+ });
30
+ it('returns false for undefined provenance', () => {
31
+ expect(isOwnerExplicitManual(undefined)).toBe(false);
32
+ });
33
+ it('returns false for null provenance (treated as undefined)', () => {
34
+ expect(isOwnerExplicitManual(null)).toBe(false);
35
+ });
36
+ it('is strict — only owner_reported_no_host_trace returns true', () => {
37
+ const allProvenances = [
38
+ 'openclaw_context_bound',
39
+ 'automatic_hook',
40
+ undefined,
41
+ ];
42
+ for (const p of allProvenances) {
43
+ expect(isOwnerExplicitManual(p)).toBe(false);
44
+ }
45
+ });
46
+ it('does not accept string variants — exact match required', () => {
47
+ // These are NOT valid provenance values, but test strictness
48
+ expect(isOwnerExplicitManual('owner_reported')).toBe(false);
49
+ expect(isOwnerExplicitManual('owner_manual')).toBe(false);
50
+ expect(isOwnerExplicitManual('OWNER_REPORTED_NO_HOST_TRACE')).toBe(false);
51
+ });
52
+ });
53
+ // ── shouldShortCircuitEmptyEvidence Tests ─────────────────────────────────────
54
+ describe('shouldShortCircuitEmptyEvidence', () => {
55
+ // Core case: evidence empty + non-owner source → short circuit
56
+ it('returns true when evidence is empty and source is tool_failure', () => {
57
+ expect(shouldShortCircuitEmptyEvidence(0, 'tool_failure')).toBe(true);
58
+ });
59
+ it('returns true when evidence is empty and source is subagent_error', () => {
60
+ expect(shouldShortCircuitEmptyEvidence(0, 'subagent_error')).toBe(true);
61
+ });
62
+ it('returns true when evidence is empty and source is dispatch_error', () => {
63
+ expect(shouldShortCircuitEmptyEvidence(0, 'dispatch_error')).toBe(true);
64
+ });
65
+ it('returns true when evidence is empty and source is provider_failure', () => {
66
+ expect(shouldShortCircuitEmptyEvidence(0, 'provider_failure')).toBe(true);
67
+ });
68
+ it('returns true when evidence is empty and source is rate_limit', () => {
69
+ expect(shouldShortCircuitEmptyEvidence(0, 'rate_limit')).toBe(true);
70
+ });
71
+ it('returns true when evidence is empty and source is rulehost_block', () => {
72
+ expect(shouldShortCircuitEmptyEvidence(0, 'rulehost_block')).toBe(true);
73
+ });
74
+ it('returns true when evidence is empty and source is empathy_inferred', () => {
75
+ expect(shouldShortCircuitEmptyEvidence(0, 'empathy_inferred')).toBe(true);
76
+ });
77
+ it('returns true when evidence is empty and source is unknown', () => {
78
+ expect(shouldShortCircuitEmptyEvidence(0, 'unknown')).toBe(true);
79
+ });
80
+ // Owner-initiated sources bypass short circuit (PRI-311 regression guard)
81
+ it('returns false when evidence is empty but source is manual (owner-initiated)', () => {
82
+ expect(shouldShortCircuitEmptyEvidence(0, 'manual')).toBe(false);
83
+ });
84
+ it('returns false when evidence is empty but source is pain (owner-initiated)', () => {
85
+ expect(shouldShortCircuitEmptyEvidence(0, 'pain')).toBe(false);
86
+ });
87
+ it('returns false when evidence is empty but source is skill:pain (owner-initiated)', () => {
88
+ expect(shouldShortCircuitEmptyEvidence(0, 'skill:pain')).toBe(false);
89
+ });
90
+ // Evidence non-empty → no short circuit regardless of source
91
+ it('returns false when evidence has 1 entry regardless of source', () => {
92
+ expect(shouldShortCircuitEmptyEvidence(1, 'tool_failure')).toBe(false);
93
+ expect(shouldShortCircuitEmptyEvidence(1, 'subagent_error')).toBe(false);
94
+ expect(shouldShortCircuitEmptyEvidence(1, 'unknown')).toBe(false);
95
+ });
96
+ it('returns false when evidence has multiple entries regardless of source', () => {
97
+ expect(shouldShortCircuitEmptyEvidence(5, 'tool_failure')).toBe(false);
98
+ expect(shouldShortCircuitEmptyEvidence(10, 'dispatch_error')).toBe(false);
99
+ });
100
+ // Boundary tests
101
+ it('returns true for evidenceLength=0 (exact boundary)', () => {
102
+ expect(shouldShortCircuitEmptyEvidence(0, 'tool_failure')).toBe(true);
103
+ });
104
+ it('returns false for evidenceLength=1 (just above boundary)', () => {
105
+ expect(shouldShortCircuitEmptyEvidence(1, 'tool_failure')).toBe(false);
106
+ });
107
+ // Edge case: negative evidence length (invalid input)
108
+ it('returns false for negative evidenceLength (invalid but safe default)', () => {
109
+ // Negative length is invalid input, but function returns false (no short circuit)
110
+ // This is a safe default — don't short circuit on invalid data
111
+ expect(shouldShortCircuitEmptyEvidence(-1, 'tool_failure')).toBe(false);
112
+ });
113
+ // Edge case: source string variations
114
+ it('is case-sensitive for source matching', () => {
115
+ expect(shouldShortCircuitEmptyEvidence(0, 'MANUAL')).toBe(true);
116
+ expect(shouldShortCircuitEmptyEvidence(0, 'Pain')).toBe(true);
117
+ expect(shouldShortCircuitEmptyEvidence(0, 'Skill:Pain')).toBe(true);
118
+ });
119
+ it('does not match partial source strings', () => {
120
+ expect(shouldShortCircuitEmptyEvidence(0, 'manual_')).toBe(true);
121
+ expect(shouldShortCircuitEmptyEvidence(0, 'pain_report')).toBe(true);
122
+ expect(shouldShortCircuitEmptyEvidence(0, 'skill:pain:extra')).toBe(true);
123
+ });
124
+ // Invariant: only manual, pain, skill:pain bypass short circuit
125
+ it('only three sources bypass short circuit when evidence is empty', () => {
126
+ const bypassSources = ['manual', 'pain', 'skill:pain'];
127
+ const allSources = [
128
+ 'tool_failure', 'subagent_error', 'dispatch_error', 'provider_failure',
129
+ 'rate_limit', 'rulehost_block', 'empathy_inferred', 'semantic',
130
+ 'llm_paralysis', 'gfi_threshold', 'unknown', 'automatic', 'hook',
131
+ ];
132
+ for (const source of bypassSources) {
133
+ expect(shouldShortCircuitEmptyEvidence(0, source)).toBe(false);
134
+ }
135
+ for (const source of allSources) {
136
+ expect(shouldShortCircuitEmptyEvidence(0, source)).toBe(true);
137
+ }
138
+ });
139
+ });
140
+ // ── Integration with Admission Gate (PRI-345 regression guard) ────────────────
141
+ describe('integration with admission gate logic', () => {
142
+ it('isOwnerExplicitManual matches the provenance check in admission gate', () => {
143
+ // Admission gate uses isOwnerExplicitManual for inputEvidenceCount=0 gate
144
+ // owner_reported_no_host_trace should bypass the gate
145
+ const ownerProvenance = 'owner_reported_no_host_trace';
146
+ expect(isOwnerExplicitManual(ownerProvenance)).toBe(true);
147
+ });
148
+ it('shouldShortCircuitEmptyEvidence matches pain signal bridge logic', () => {
149
+ // Pain signal bridge short-circuits when evidence empty and source not owner-initiated
150
+ // This test verifies the same logic is used in both places
151
+ expect(shouldShortCircuitEmptyEvidence(0, 'tool_failure')).toBe(true);
152
+ expect(shouldShortCircuitEmptyEvidence(0, 'manual')).toBe(false);
153
+ });
154
+ });
155
+ //# sourceMappingURL=evidence-guards.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-guards.test.js","sourceRoot":"","sources":["../../../src/runtime-v2/__tests__/evidence-guards.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,17 @@
1
+ /**
2
+ * Approval Queue Tests — PRI-145
3
+ *
4
+ * Unit tests for ApprovalQueue class and decideAutoPromotion function.
5
+ *
6
+ * Tests verify:
7
+ * - decideAutoPromotion() correctly evaluates auto-promotion conditions
8
+ * - ApprovalQueue class methods work correctly with mock store
9
+ * - Boundary conditions for confidence threshold
10
+ *
11
+ * ERR checklist:
12
+ * - ERR-002: Every decision path carries reason + nextAction
13
+ * - ERR-009: Malformed state fails loud
14
+ * - ERR-025: Production-path tests, not just helpers
15
+ */
1
16
  export {};
2
17
  //# sourceMappingURL=approval-queue.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"approval-queue.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/activation/__tests__/approval-queue.test.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"approval-queue.test.d.ts","sourceRoot":"","sources":["../../../../src/runtime-v2/activation/__tests__/approval-queue.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}