tlc-claude-code 1.3.0 → 1.4.1

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 (105) hide show
  1. package/dashboard/dist/components/AuditPane.d.ts +30 -0
  2. package/dashboard/dist/components/AuditPane.js +127 -0
  3. package/dashboard/dist/components/AuditPane.test.d.ts +1 -0
  4. package/dashboard/dist/components/AuditPane.test.js +339 -0
  5. package/dashboard/dist/components/CompliancePane.d.ts +39 -0
  6. package/dashboard/dist/components/CompliancePane.js +96 -0
  7. package/dashboard/dist/components/CompliancePane.test.d.ts +1 -0
  8. package/dashboard/dist/components/CompliancePane.test.js +183 -0
  9. package/dashboard/dist/components/SSOPane.d.ts +36 -0
  10. package/dashboard/dist/components/SSOPane.js +71 -0
  11. package/dashboard/dist/components/SSOPane.test.d.ts +1 -0
  12. package/dashboard/dist/components/SSOPane.test.js +155 -0
  13. package/dashboard/dist/components/WorkspaceDocsPane.js +0 -16
  14. package/dashboard/dist/components/WorkspacePane.d.ts +1 -1
  15. package/dashboard/dist/components/ZeroRetentionPane.d.ts +44 -0
  16. package/dashboard/dist/components/ZeroRetentionPane.js +83 -0
  17. package/dashboard/dist/components/ZeroRetentionPane.test.d.ts +1 -0
  18. package/dashboard/dist/components/ZeroRetentionPane.test.js +160 -0
  19. package/package.json +1 -1
  20. package/server/lib/access-control-doc.js +541 -0
  21. package/server/lib/access-control-doc.test.js +672 -0
  22. package/server/lib/adr-generator.js +423 -0
  23. package/server/lib/adr-generator.test.js +586 -0
  24. package/server/lib/agent-progress-monitor.js +223 -0
  25. package/server/lib/agent-progress-monitor.test.js +202 -0
  26. package/server/lib/audit-attribution.js +191 -0
  27. package/server/lib/audit-attribution.test.js +359 -0
  28. package/server/lib/audit-classifier.js +202 -0
  29. package/server/lib/audit-classifier.test.js +209 -0
  30. package/server/lib/audit-command.js +275 -0
  31. package/server/lib/audit-command.test.js +325 -0
  32. package/server/lib/audit-exporter.js +380 -0
  33. package/server/lib/audit-exporter.test.js +464 -0
  34. package/server/lib/audit-logger.js +236 -0
  35. package/server/lib/audit-logger.test.js +364 -0
  36. package/server/lib/audit-query.js +257 -0
  37. package/server/lib/audit-query.test.js +352 -0
  38. package/server/lib/audit-storage.js +269 -0
  39. package/server/lib/audit-storage.test.js +272 -0
  40. package/server/lib/bulk-repo-init.js +342 -0
  41. package/server/lib/bulk-repo-init.test.js +388 -0
  42. package/server/lib/compliance-checklist.js +866 -0
  43. package/server/lib/compliance-checklist.test.js +476 -0
  44. package/server/lib/compliance-command.js +616 -0
  45. package/server/lib/compliance-command.test.js +551 -0
  46. package/server/lib/compliance-reporter.js +692 -0
  47. package/server/lib/compliance-reporter.test.js +707 -0
  48. package/server/lib/data-flow-doc.js +665 -0
  49. package/server/lib/data-flow-doc.test.js +659 -0
  50. package/server/lib/ephemeral-storage.js +249 -0
  51. package/server/lib/ephemeral-storage.test.js +254 -0
  52. package/server/lib/evidence-collector.js +627 -0
  53. package/server/lib/evidence-collector.test.js +901 -0
  54. package/server/lib/flow-diagram-generator.js +474 -0
  55. package/server/lib/flow-diagram-generator.test.js +446 -0
  56. package/server/lib/idp-manager.js +626 -0
  57. package/server/lib/idp-manager.test.js +587 -0
  58. package/server/lib/memory-exclusion.js +326 -0
  59. package/server/lib/memory-exclusion.test.js +241 -0
  60. package/server/lib/mfa-handler.js +452 -0
  61. package/server/lib/mfa-handler.test.js +490 -0
  62. package/server/lib/oauth-flow.js +375 -0
  63. package/server/lib/oauth-flow.test.js +487 -0
  64. package/server/lib/oauth-registry.js +190 -0
  65. package/server/lib/oauth-registry.test.js +306 -0
  66. package/server/lib/readme-generator.js +490 -0
  67. package/server/lib/readme-generator.test.js +493 -0
  68. package/server/lib/repo-dependency-tracker.js +261 -0
  69. package/server/lib/repo-dependency-tracker.test.js +350 -0
  70. package/server/lib/retention-policy.js +281 -0
  71. package/server/lib/retention-policy.test.js +486 -0
  72. package/server/lib/role-mapper.js +236 -0
  73. package/server/lib/role-mapper.test.js +395 -0
  74. package/server/lib/saml-provider.js +765 -0
  75. package/server/lib/saml-provider.test.js +643 -0
  76. package/server/lib/security-policy-generator.js +682 -0
  77. package/server/lib/security-policy-generator.test.js +544 -0
  78. package/server/lib/sensitive-detector.js +112 -0
  79. package/server/lib/sensitive-detector.test.js +209 -0
  80. package/server/lib/service-interaction-diagram.js +700 -0
  81. package/server/lib/service-interaction-diagram.test.js +638 -0
  82. package/server/lib/service-summary.js +553 -0
  83. package/server/lib/service-summary.test.js +619 -0
  84. package/server/lib/session-purge.js +460 -0
  85. package/server/lib/session-purge.test.js +312 -0
  86. package/server/lib/sso-command.js +544 -0
  87. package/server/lib/sso-command.test.js +552 -0
  88. package/server/lib/sso-session.js +492 -0
  89. package/server/lib/sso-session.test.js +670 -0
  90. package/server/lib/workspace-command.js +249 -0
  91. package/server/lib/workspace-command.test.js +264 -0
  92. package/server/lib/workspace-config.js +270 -0
  93. package/server/lib/workspace-config.test.js +312 -0
  94. package/server/lib/workspace-docs-command.js +547 -0
  95. package/server/lib/workspace-docs-command.test.js +692 -0
  96. package/server/lib/workspace-memory.js +451 -0
  97. package/server/lib/workspace-memory.test.js +403 -0
  98. package/server/lib/workspace-scanner.js +452 -0
  99. package/server/lib/workspace-scanner.test.js +677 -0
  100. package/server/lib/workspace-test-runner.js +315 -0
  101. package/server/lib/workspace-test-runner.test.js +294 -0
  102. package/server/lib/zero-retention-command.js +439 -0
  103. package/server/lib/zero-retention-command.test.js +448 -0
  104. package/server/lib/zero-retention.js +322 -0
  105. package/server/lib/zero-retention.test.js +258 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Zero-Retention Mode
3
+ *
4
+ * Master switch that configures all subsystems for zero-data-retention.
5
+ * When enabled, ensures no sensitive data persists beyond the current session.
6
+ *
7
+ * Integrates with:
8
+ * - sensitive-detector.js - Detects sensitive data types
9
+ * - retention-policy.js - Configures immediate purge policies
10
+ * - ephemeral-storage.js - In-memory only storage
11
+ * - session-purge.js - Automatic session end purging
12
+ * - memory-exclusion.js - Excludes all files from memory
13
+ */
14
+
15
+ import { detectSensitive, getSensitivityLevel } from './sensitive-detector.js';
16
+ import {
17
+ getPolicy,
18
+ evaluateRetention,
19
+ loadPolicies,
20
+ } from './retention-policy.js';
21
+ import { EphemeralStorage } from './ephemeral-storage.js';
22
+ import { SessionPurgeManager, createPurgeManager } from './session-purge.js';
23
+ import { shouldExclude, loadPatterns } from './memory-exclusion.js';
24
+
25
+ /**
26
+ * Zero-Retention Mode Class
27
+ *
28
+ * Provides a master switch to configure all subsystems for zero data retention.
29
+ */
30
+ export class ZeroRetentionMode {
31
+ constructor(options = {}) {
32
+ this._enabled = false;
33
+ this._config = null;
34
+ this._options = options;
35
+ this._subsystems = {
36
+ ephemeralStorage: null,
37
+ sessionPurge: null,
38
+ memoryExclusion: null,
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Enable zero-retention mode
44
+ * Configures all subsystems for immediate data purging and no persistence.
45
+ *
46
+ * @param {Object} options - Configuration options
47
+ * @param {boolean} options.auditLogging - Enable audit logging (conflicts with zero-retention)
48
+ * @returns {Object} Result with success status and configuration
49
+ */
50
+ enable(options = {}) {
51
+ const enableOptions = { ...this._options, ...options };
52
+
53
+ // Configure ephemeral storage - memory only, encrypted
54
+ const ephemeralStorageConfig = {
55
+ encrypt: true,
56
+ registerExitHandler: true,
57
+ basePath: null, // No disk persistence
58
+ };
59
+
60
+ // Configure session purge - aggressive purging
61
+ const sessionPurgeConfig = {
62
+ aggressive: true,
63
+ purgeOnSessionEnd: true,
64
+ purgeOnTimeout: true,
65
+ idleTimeout: 5 * 60 * 1000, // 5 minutes
66
+ };
67
+
68
+ // Configure memory exclusion - exclude everything
69
+ const memoryExclusionConfig = {
70
+ excludeAll: true,
71
+ mode: 'blacklist',
72
+ filePatterns: ['*'],
73
+ contentPatterns: ['*'],
74
+ };
75
+
76
+ // Configure retention policy - immediate purge, no persistence
77
+ const retentionPolicyConfig = {
78
+ retention: 'immediate',
79
+ persist: false,
80
+ };
81
+
82
+ // Store subsystem configurations
83
+ this._subsystems = {
84
+ ephemeralStorage: true,
85
+ sessionPurge: true,
86
+ memoryExclusion: true,
87
+ };
88
+
89
+ // Build full configuration
90
+ this._config = {
91
+ enabled: true,
92
+ ephemeralStorage: ephemeralStorageConfig,
93
+ sessionPurge: sessionPurgeConfig,
94
+ memoryExclusion: memoryExclusionConfig,
95
+ retentionPolicy: retentionPolicyConfig,
96
+ auditLogging: enableOptions.auditLogging || false,
97
+ };
98
+
99
+ this._enabled = true;
100
+
101
+ return {
102
+ success: true,
103
+ enabled: true,
104
+ subsystems: { ...this._subsystems },
105
+ config: { ...this._config },
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Disable zero-retention mode
111
+ * Returns all subsystems to normal operation.
112
+ *
113
+ * @returns {Object} Result with success status
114
+ */
115
+ disable() {
116
+ this._enabled = false;
117
+ this._config = {
118
+ enabled: false,
119
+ ephemeralStorage: null,
120
+ sessionPurge: null,
121
+ memoryExclusion: null,
122
+ retentionPolicy: null,
123
+ };
124
+ this._subsystems = {
125
+ ephemeralStorage: null,
126
+ sessionPurge: null,
127
+ memoryExclusion: null,
128
+ };
129
+
130
+ return {
131
+ success: true,
132
+ enabled: false,
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Check if zero-retention mode is enabled
138
+ *
139
+ * @returns {boolean} True if enabled
140
+ */
141
+ isEnabled() {
142
+ return this._enabled;
143
+ }
144
+
145
+ /**
146
+ * Get the current configuration
147
+ *
148
+ * @returns {Object} Current configuration
149
+ */
150
+ getConfig() {
151
+ if (!this._enabled) {
152
+ return {
153
+ enabled: false,
154
+ ephemeralStorage: null,
155
+ sessionPurge: null,
156
+ memoryExclusion: null,
157
+ retentionPolicy: null,
158
+ };
159
+ }
160
+
161
+ return { ...this._config };
162
+ }
163
+
164
+ /**
165
+ * Validate the current configuration for conflicts
166
+ *
167
+ * @returns {Object} Validation result with conflicts and warnings
168
+ */
169
+ validate() {
170
+ const conflicts = [];
171
+ const warnings = [];
172
+
173
+ // Check for audit logging conflict
174
+ if (this._config && this._config.auditLogging) {
175
+ warnings.push(
176
+ 'Audit logging is enabled but conflicts with zero-retention mode. ' +
177
+ 'Audit logs may retain sensitive data references.'
178
+ );
179
+ }
180
+
181
+ // Check for persistence conflicts
182
+ if (this._enabled && this._config) {
183
+ // Ephemeral storage should not persist
184
+ if (
185
+ this._config.ephemeralStorage &&
186
+ this._config.ephemeralStorage.basePath
187
+ ) {
188
+ conflicts.push(
189
+ 'Ephemeral storage has basePath set, which may enable disk persistence.'
190
+ );
191
+ }
192
+
193
+ // Retention policy should be immediate
194
+ if (
195
+ this._config.retentionPolicy &&
196
+ this._config.retentionPolicy.retention !== 'immediate'
197
+ ) {
198
+ conflicts.push(
199
+ 'Retention policy is not set to immediate in zero-retention mode.'
200
+ );
201
+ }
202
+
203
+ // Retention policy should not persist
204
+ if (
205
+ this._config.retentionPolicy &&
206
+ this._config.retentionPolicy.persist === true
207
+ ) {
208
+ conflicts.push('Retention policy has persist enabled in zero-retention mode.');
209
+ }
210
+ }
211
+
212
+ return {
213
+ valid: conflicts.length === 0,
214
+ conflicts,
215
+ warnings,
216
+ };
217
+ }
218
+
219
+ /**
220
+ * Create configured subsystem instances
221
+ * Returns ready-to-use instances of all subsystems configured for zero-retention.
222
+ *
223
+ * @returns {Object} Configured subsystem instances
224
+ */
225
+ createSubsystems() {
226
+ if (!this._enabled) {
227
+ throw new Error('Zero-retention mode must be enabled before creating subsystems');
228
+ }
229
+
230
+ const ephemeralStorage = new EphemeralStorage(this._config.ephemeralStorage);
231
+
232
+ const sessionPurge = createPurgeManager({
233
+ storage: ephemeralStorage,
234
+ auditEnabled: false, // Audit logging disabled in zero-retention
235
+ policies: {
236
+ sensitivityLevels: {
237
+ critical: { retention: 'immediate', persist: false },
238
+ high: { retention: 'immediate', persist: false },
239
+ medium: { retention: 'immediate', persist: false },
240
+ low: { retention: 'immediate', persist: false },
241
+ },
242
+ dataTypes: {
243
+ secrets: { retention: 'immediate', persist: false },
244
+ pii: { retention: 'immediate', persist: false },
245
+ general: { retention: 'immediate', persist: false },
246
+ },
247
+ default: { retention: 'immediate', persist: false },
248
+ },
249
+ });
250
+
251
+ return {
252
+ ephemeralStorage,
253
+ sessionPurge,
254
+ config: this._config,
255
+ };
256
+ }
257
+ }
258
+
259
+ // Global singleton instance
260
+ let globalInstance = new ZeroRetentionMode();
261
+
262
+ /**
263
+ * Enable zero-retention mode globally
264
+ *
265
+ * @param {Object} options - Configuration options
266
+ * @returns {Object} Result with success status
267
+ */
268
+ export function enable(options = {}) {
269
+ return globalInstance.enable(options);
270
+ }
271
+
272
+ /**
273
+ * Disable zero-retention mode globally
274
+ *
275
+ * @returns {Object} Result with success status
276
+ */
277
+ export function disable() {
278
+ return globalInstance.disable();
279
+ }
280
+
281
+ /**
282
+ * Check if zero-retention mode is enabled globally
283
+ *
284
+ * @returns {boolean} True if enabled
285
+ */
286
+ export function isEnabled() {
287
+ return globalInstance.isEnabled();
288
+ }
289
+
290
+ /**
291
+ * Get the current global configuration
292
+ *
293
+ * @returns {Object} Current configuration
294
+ */
295
+ export function getConfig() {
296
+ return globalInstance.getConfig();
297
+ }
298
+
299
+ /**
300
+ * Validate the current global configuration
301
+ *
302
+ * @returns {Object} Validation result
303
+ */
304
+ export function validate() {
305
+ return globalInstance.validate();
306
+ }
307
+
308
+ /**
309
+ * Reset the global instance (for testing)
310
+ */
311
+ export function _resetGlobalInstance() {
312
+ globalInstance = new ZeroRetentionMode();
313
+ }
314
+
315
+ export default {
316
+ ZeroRetentionMode,
317
+ enable,
318
+ disable,
319
+ isEnabled,
320
+ getConfig,
321
+ validate,
322
+ };
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Zero-Retention Mode Tests
3
+ *
4
+ * Tests for the master switch that configures all subsystems for zero-data-retention.
5
+ */
6
+
7
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
+ import {
9
+ enable,
10
+ disable,
11
+ isEnabled,
12
+ getConfig,
13
+ validate,
14
+ ZeroRetentionMode,
15
+ _resetGlobalInstance,
16
+ } from './zero-retention.js';
17
+
18
+ // Mock dependencies
19
+ vi.mock('./sensitive-detector.js', () => ({
20
+ detectSensitive: vi.fn(() => []),
21
+ getSensitivityLevel: vi.fn(() => 'low'),
22
+ }));
23
+
24
+ vi.mock('./retention-policy.js', () => ({
25
+ getPolicy: vi.fn(() => ({ retention: 'immediate', persist: false })),
26
+ evaluateRetention: vi.fn(() => 'purge'),
27
+ loadPolicies: vi.fn(() => ({})),
28
+ }));
29
+
30
+ vi.mock('./ephemeral-storage.js', () => ({
31
+ EphemeralStorage: vi.fn().mockImplementation(() => ({
32
+ set: vi.fn(),
33
+ get: vi.fn(),
34
+ delete: vi.fn(),
35
+ clear: vi.fn(),
36
+ keys: vi.fn(() => []),
37
+ })),
38
+ }));
39
+
40
+ vi.mock('./session-purge.js', () => ({
41
+ SessionPurgeManager: vi.fn().mockImplementation(() => ({
42
+ onSessionEnd: vi.fn(),
43
+ onProcessExit: vi.fn(),
44
+ startIdleTimer: vi.fn(),
45
+ stopIdleTimer: vi.fn(),
46
+ forcePurge: vi.fn(),
47
+ })),
48
+ createPurgeManager: vi.fn((options) => ({
49
+ onSessionEnd: vi.fn(),
50
+ onProcessExit: vi.fn(),
51
+ startIdleTimer: vi.fn(),
52
+ stopIdleTimer: vi.fn(),
53
+ forcePurge: vi.fn(),
54
+ ...options,
55
+ })),
56
+ }));
57
+
58
+ vi.mock('./memory-exclusion.js', () => ({
59
+ shouldExclude: vi.fn(() => true),
60
+ loadPatterns: vi.fn(() => ({
61
+ mode: 'blacklist',
62
+ filePatterns: ['*'],
63
+ contentPatterns: ['*'],
64
+ })),
65
+ }));
66
+
67
+ describe('Zero-Retention Mode', () => {
68
+ let zeroRetention;
69
+
70
+ beforeEach(() => {
71
+ vi.clearAllMocks();
72
+ // Reset global instance to prevent state leakage
73
+ _resetGlobalInstance();
74
+ // Create a fresh instance for each test
75
+ zeroRetention = new ZeroRetentionMode();
76
+ });
77
+
78
+ afterEach(() => {
79
+ // Ensure mode is disabled after each test
80
+ if (zeroRetention && zeroRetention.isEnabled()) {
81
+ zeroRetention.disable();
82
+ }
83
+ });
84
+
85
+ describe('enable', () => {
86
+ it('activates zero-retention mode', () => {
87
+ const result = zeroRetention.enable();
88
+
89
+ expect(result.success).toBe(true);
90
+ expect(result.enabled).toBe(true);
91
+ expect(zeroRetention.isEnabled()).toBe(true);
92
+ });
93
+
94
+ it('configures ephemeral storage', () => {
95
+ const result = zeroRetention.enable();
96
+
97
+ expect(result.success).toBe(true);
98
+ expect(result.subsystems.ephemeralStorage).toBe(true);
99
+ expect(result.config.ephemeralStorage).toBeDefined();
100
+ expect(result.config.ephemeralStorage.encrypt).toBe(true);
101
+ });
102
+
103
+ it('configures session purge', () => {
104
+ const result = zeroRetention.enable();
105
+
106
+ expect(result.success).toBe(true);
107
+ expect(result.subsystems.sessionPurge).toBe(true);
108
+ expect(result.config.sessionPurge).toBeDefined();
109
+ expect(result.config.sessionPurge.aggressive).toBe(true);
110
+ });
111
+
112
+ it('configures memory exclusions', () => {
113
+ const result = zeroRetention.enable();
114
+
115
+ expect(result.success).toBe(true);
116
+ expect(result.subsystems.memoryExclusion).toBe(true);
117
+ expect(result.config.memoryExclusion).toBeDefined();
118
+ expect(result.config.memoryExclusion.excludeAll).toBe(true);
119
+ });
120
+ });
121
+
122
+ describe('disable', () => {
123
+ it('returns to normal mode', () => {
124
+ // First enable
125
+ zeroRetention.enable();
126
+ expect(zeroRetention.isEnabled()).toBe(true);
127
+
128
+ // Then disable
129
+ const result = zeroRetention.disable();
130
+
131
+ expect(result.success).toBe(true);
132
+ expect(result.enabled).toBe(false);
133
+ expect(zeroRetention.isEnabled()).toBe(false);
134
+ });
135
+ });
136
+
137
+ describe('isEnabled', () => {
138
+ it('returns current state', () => {
139
+ expect(zeroRetention.isEnabled()).toBe(false);
140
+
141
+ zeroRetention.enable();
142
+ expect(zeroRetention.isEnabled()).toBe(true);
143
+
144
+ zeroRetention.disable();
145
+ expect(zeroRetention.isEnabled()).toBe(false);
146
+ });
147
+ });
148
+
149
+ describe('getConfig', () => {
150
+ it('returns active configuration', () => {
151
+ zeroRetention.enable();
152
+
153
+ const config = zeroRetention.getConfig();
154
+
155
+ expect(config).toBeDefined();
156
+ expect(config.enabled).toBe(true);
157
+ expect(config.ephemeralStorage).toBeDefined();
158
+ expect(config.sessionPurge).toBeDefined();
159
+ expect(config.memoryExclusion).toBeDefined();
160
+ expect(config.retentionPolicy).toBeDefined();
161
+ });
162
+
163
+ it('returns default configuration when disabled', () => {
164
+ const config = zeroRetention.getConfig();
165
+
166
+ expect(config).toBeDefined();
167
+ expect(config.enabled).toBe(false);
168
+ });
169
+ });
170
+
171
+ describe('validate', () => {
172
+ it('checks for conflicts', () => {
173
+ const result = zeroRetention.validate();
174
+
175
+ expect(result).toBeDefined();
176
+ expect(result.valid).toBeDefined();
177
+ expect(result.conflicts).toBeDefined();
178
+ expect(Array.isArray(result.conflicts)).toBe(true);
179
+ });
180
+
181
+ it('warns about audit logging conflict', () => {
182
+ // Enable with audit logging (which conflicts with zero-retention)
183
+ zeroRetention.enable({ auditLogging: true });
184
+
185
+ const result = zeroRetention.validate();
186
+
187
+ expect(result.warnings).toBeDefined();
188
+ expect(Array.isArray(result.warnings)).toBe(true);
189
+ expect(
190
+ result.warnings.some((w) => w.toLowerCase().includes('audit'))
191
+ ).toBe(true);
192
+ });
193
+
194
+ it('returns valid when no conflicts', () => {
195
+ zeroRetention.enable();
196
+
197
+ const result = zeroRetention.validate();
198
+
199
+ expect(result.valid).toBe(true);
200
+ expect(result.conflicts.length).toBe(0);
201
+ });
202
+ });
203
+
204
+ describe('module-level functions', () => {
205
+ it('enable function works', () => {
206
+ const result = enable();
207
+ expect(result.success).toBe(true);
208
+ expect(isEnabled()).toBe(true);
209
+ disable(); // cleanup
210
+ });
211
+
212
+ it('disable function works', () => {
213
+ enable();
214
+ const result = disable();
215
+ expect(result.success).toBe(true);
216
+ expect(isEnabled()).toBe(false);
217
+ });
218
+
219
+ it('isEnabled function works', () => {
220
+ expect(isEnabled()).toBe(false);
221
+ enable();
222
+ expect(isEnabled()).toBe(true);
223
+ disable();
224
+ });
225
+
226
+ it('getConfig function works', () => {
227
+ enable();
228
+ const config = getConfig();
229
+ expect(config).toBeDefined();
230
+ expect(config.enabled).toBe(true);
231
+ disable();
232
+ });
233
+
234
+ it('validate function works', () => {
235
+ const result = validate();
236
+ expect(result).toBeDefined();
237
+ expect(result.valid).toBeDefined();
238
+ });
239
+ });
240
+
241
+ describe('integration with subsystems', () => {
242
+ it('sets immediate retention policy on enable', () => {
243
+ zeroRetention.enable();
244
+
245
+ const config = zeroRetention.getConfig();
246
+ expect(config.retentionPolicy.retention).toBe('immediate');
247
+ expect(config.retentionPolicy.persist).toBe(false);
248
+ });
249
+
250
+ it('restores normal retention policy on disable', () => {
251
+ zeroRetention.enable();
252
+ zeroRetention.disable();
253
+
254
+ const config = zeroRetention.getConfig();
255
+ expect(config.retentionPolicy).toBeNull();
256
+ });
257
+ });
258
+ });