@skillsmith/core 0.4.10 → 0.4.12

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 (130) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/src/analysis/__tests__/incremental.test.d.ts +1 -1
  3. package/dist/src/analysis/__tests__/incremental.test.js +1 -1
  4. package/dist/src/analysis/__tests__/integration.test.d.ts +1 -1
  5. package/dist/src/analysis/__tests__/integration.test.js +1 -1
  6. package/dist/src/analysis/__tests__/performance.test.d.ts +1 -1
  7. package/dist/src/analysis/__tests__/performance.test.js +1 -1
  8. package/dist/src/analysis/adapters/__tests__/python.test.d.ts +1 -1
  9. package/dist/src/analysis/adapters/__tests__/python.test.js +1 -1
  10. package/dist/src/analysis/adapters/__tests__/typescript.test.d.ts +1 -1
  11. package/dist/src/analysis/adapters/__tests__/typescript.test.js +1 -1
  12. package/dist/src/analysis/adapters/base.d.ts +1 -1
  13. package/dist/src/analysis/adapters/base.js +1 -1
  14. package/dist/src/analysis/adapters/factory.d.ts +1 -1
  15. package/dist/src/analysis/adapters/factory.js +1 -1
  16. package/dist/src/analysis/adapters/go.d.ts +1 -1
  17. package/dist/src/analysis/adapters/go.js +1 -1
  18. package/dist/src/analysis/adapters/index.d.ts +1 -1
  19. package/dist/src/analysis/adapters/index.js +1 -1
  20. package/dist/src/analysis/adapters/java-parsers.d.ts +1 -1
  21. package/dist/src/analysis/adapters/java-parsers.js +1 -1
  22. package/dist/src/analysis/adapters/java.d.ts +1 -1
  23. package/dist/src/analysis/adapters/java.js +1 -1
  24. package/dist/src/analysis/adapters/python-frameworks.d.ts +1 -1
  25. package/dist/src/analysis/adapters/python-frameworks.js +1 -1
  26. package/dist/src/analysis/adapters/python.d.ts +1 -1
  27. package/dist/src/analysis/adapters/python.js +1 -1
  28. package/dist/src/analysis/adapters/rust-parsers.d.ts +1 -1
  29. package/dist/src/analysis/adapters/rust-parsers.js +1 -1
  30. package/dist/src/analysis/adapters/rust.d.ts +1 -1
  31. package/dist/src/analysis/adapters/rust.js +1 -1
  32. package/dist/src/analysis/adapters/typescript.d.ts +1 -1
  33. package/dist/src/analysis/adapters/typescript.js +1 -1
  34. package/dist/src/analysis/aggregator.d.ts +1 -1
  35. package/dist/src/analysis/aggregator.js +1 -1
  36. package/dist/src/analysis/cache.d.ts +1 -1
  37. package/dist/src/analysis/cache.js +1 -1
  38. package/dist/src/analysis/file-streamer.d.ts +1 -1
  39. package/dist/src/analysis/file-streamer.js +1 -1
  40. package/dist/src/analysis/incremental-parser.d.ts +1 -1
  41. package/dist/src/analysis/incremental-parser.js +1 -1
  42. package/dist/src/analysis/incremental.d.ts +1 -1
  43. package/dist/src/analysis/incremental.js +1 -1
  44. package/dist/src/analysis/index.d.ts +1 -1
  45. package/dist/src/analysis/index.js +1 -1
  46. package/dist/src/analysis/language-detector.d.ts +1 -1
  47. package/dist/src/analysis/language-detector.js +1 -1
  48. package/dist/src/analysis/memory-monitor.d.ts +1 -1
  49. package/dist/src/analysis/memory-monitor.js +1 -1
  50. package/dist/src/analysis/metrics.d.ts +1 -1
  51. package/dist/src/analysis/metrics.js +1 -1
  52. package/dist/src/analysis/router.d.ts +1 -1
  53. package/dist/src/analysis/router.js +1 -1
  54. package/dist/src/analysis/tree-cache.d.ts +1 -1
  55. package/dist/src/analysis/tree-cache.js +1 -1
  56. package/dist/src/analysis/tree-sitter/manager.d.ts +1 -1
  57. package/dist/src/analysis/tree-sitter/manager.js +1 -1
  58. package/dist/src/analysis/types.d.ts +1 -1
  59. package/dist/src/analysis/types.js +1 -1
  60. package/dist/src/analysis/worker-pool.d.ts +1 -1
  61. package/dist/src/analysis/worker-pool.js +1 -1
  62. package/dist/src/analysis/worker-types.d.ts +1 -1
  63. package/dist/src/analysis/worker-types.js +1 -1
  64. package/dist/src/analysis/worker-utils.d.ts +1 -1
  65. package/dist/src/analysis/worker-utils.js +1 -1
  66. package/dist/src/config/index.d.ts +49 -1
  67. package/dist/src/config/index.d.ts.map +1 -1
  68. package/dist/src/config/index.js +166 -3
  69. package/dist/src/config/index.js.map +1 -1
  70. package/dist/src/config/index.test.d.ts +11 -0
  71. package/dist/src/config/index.test.d.ts.map +1 -0
  72. package/dist/src/config/index.test.js +288 -0
  73. package/dist/src/config/index.test.js.map +1 -0
  74. package/dist/src/db/quarantine-approvals-schema.d.ts +37 -0
  75. package/dist/src/db/quarantine-approvals-schema.d.ts.map +1 -0
  76. package/dist/src/db/quarantine-approvals-schema.js +71 -0
  77. package/dist/src/db/quarantine-approvals-schema.js.map +1 -0
  78. package/dist/src/embeddings/embedding-utils.d.ts +3 -3
  79. package/dist/src/embeddings/embedding-utils.d.ts.map +1 -1
  80. package/dist/src/embeddings/embedding-utils.js +3 -3
  81. package/dist/src/embeddings/embedding-utils.js.map +1 -1
  82. package/dist/src/embeddings/index.d.ts +1 -1
  83. package/dist/src/embeddings/index.js +3 -3
  84. package/dist/src/embeddings/index.js.map +1 -1
  85. package/dist/src/index.d.ts +1 -1
  86. package/dist/src/index.d.ts.map +1 -1
  87. package/dist/src/index.js +2 -2
  88. package/dist/src/index.js.map +1 -1
  89. package/dist/src/repositories/quarantine/ApprovalRepository.d.ts +148 -0
  90. package/dist/src/repositories/quarantine/ApprovalRepository.d.ts.map +1 -0
  91. package/dist/src/repositories/quarantine/ApprovalRepository.js +212 -0
  92. package/dist/src/repositories/quarantine/ApprovalRepository.js.map +1 -0
  93. package/dist/src/repositories/quarantine/index.d.ts +2 -0
  94. package/dist/src/repositories/quarantine/index.d.ts.map +1 -1
  95. package/dist/src/repositories/quarantine/index.js +1 -0
  96. package/dist/src/repositories/quarantine/index.js.map +1 -1
  97. package/dist/src/security/audit-types.d.ts +1 -1
  98. package/dist/src/security/audit-types.d.ts.map +1 -1
  99. package/dist/src/security/audit-types.js.map +1 -1
  100. package/dist/src/security/scanner/SecurityScanner.formatters.js +1 -1
  101. package/dist/src/security/scanner/SecurityScanner.formatters.js.map +1 -1
  102. package/dist/src/services/quarantine/QuarantineService.d.ts +17 -9
  103. package/dist/src/services/quarantine/QuarantineService.d.ts.map +1 -1
  104. package/dist/src/services/quarantine/QuarantineService.js +114 -56
  105. package/dist/src/services/quarantine/QuarantineService.js.map +1 -1
  106. package/dist/tests/RawUrlSourceAdapter.security.test.js +2 -1
  107. package/dist/tests/RawUrlSourceAdapter.security.test.js.map +1 -1
  108. package/dist/tests/SecurityScanner.test.js +2 -2
  109. package/dist/tests/SecurityScanner.test.js.map +1 -1
  110. package/dist/tests/adapters-factory.test.d.ts +1 -1
  111. package/dist/tests/adapters-factory.test.js +1 -1
  112. package/dist/tests/integration/QuarantineService.test.js +49 -1
  113. package/dist/tests/integration/QuarantineService.test.js.map +1 -1
  114. package/dist/tests/integration/neural/e2e-learning.test.d.ts +1 -1
  115. package/dist/tests/integration/neural/e2e-learning.test.js +1 -1
  116. package/dist/tests/integration/neural/personalization.test.d.ts +1 -1
  117. package/dist/tests/integration/neural/personalization.test.js +1 -1
  118. package/dist/tests/integration/neural/preference-learner.test.d.ts +1 -1
  119. package/dist/tests/integration/neural/preference-learner.test.js +1 -1
  120. package/dist/tests/integration/neural/privacy.test.d.ts +1 -1
  121. package/dist/tests/integration/neural/privacy.test.js +1 -1
  122. package/dist/tests/integration/neural/signal-collection.test.d.ts +1 -1
  123. package/dist/tests/integration/neural/signal-collection.test.js +1 -1
  124. package/dist/tests/language-detector.test.d.ts +1 -1
  125. package/dist/tests/language-detector.test.js +1 -1
  126. package/dist/tests/unit/approval-repository.test.d.ts +9 -0
  127. package/dist/tests/unit/approval-repository.test.d.ts.map +1 -0
  128. package/dist/tests/unit/approval-repository.test.js +509 -0
  129. package/dist/tests/unit/approval-repository.test.js.map +1 -0
  130. package/package.json +2 -2
@@ -0,0 +1,212 @@
1
+ /**
2
+ * SMI-2277: Approval Repository
3
+ *
4
+ * Persists multi-approval state to SQLite instead of in-memory Map.
5
+ * This ensures pending approvals survive service restarts.
6
+ *
7
+ * @module @skillsmith/core/repositories/quarantine/ApprovalRepository
8
+ */
9
+ import { randomUUID } from 'crypto';
10
+ import { initializeQuarantineApprovalsSchema } from '../../db/quarantine-approvals-schema.js';
11
+ // ============================================================================
12
+ // SQL Queries
13
+ // ============================================================================
14
+ const INSERT_APPROVAL_QUERY = `
15
+ INSERT INTO quarantine_approvals (
16
+ id, skill_id, reviewer_id, reviewer_email, decision, reason,
17
+ created_at, required_approvals, is_complete
18
+ )
19
+ VALUES (?, ?, ?, ?, ?, ?, datetime('now') || 'Z', ?, 0)
20
+ `;
21
+ const SELECT_BY_SKILL_ID_QUERY = `
22
+ SELECT * FROM quarantine_approvals
23
+ WHERE skill_id = ?
24
+ ORDER BY created_at ASC
25
+ `;
26
+ const SELECT_PENDING_BY_SKILL_ID_QUERY = `
27
+ SELECT * FROM quarantine_approvals
28
+ WHERE skill_id = ? AND is_complete = 0
29
+ ORDER BY created_at ASC
30
+ `;
31
+ const COUNT_PENDING_APPROVALS_QUERY = `
32
+ SELECT COUNT(*) as count FROM quarantine_approvals
33
+ WHERE skill_id = ? AND is_complete = 0 AND decision = 'approved'
34
+ `;
35
+ const CHECK_REVIEWER_EXISTS_QUERY = `
36
+ SELECT id FROM quarantine_approvals
37
+ WHERE skill_id = ? AND reviewer_id = ? AND is_complete = 0
38
+ `;
39
+ const MARK_COMPLETE_QUERY = `
40
+ UPDATE quarantine_approvals
41
+ SET is_complete = 1, completed_at = datetime('now') || 'Z'
42
+ WHERE skill_id = ? AND is_complete = 0
43
+ `;
44
+ const DELETE_BY_SKILL_ID_QUERY = `
45
+ DELETE FROM quarantine_approvals WHERE skill_id = ?
46
+ `;
47
+ const SELECT_FIRST_PENDING_QUERY = `
48
+ SELECT created_at FROM quarantine_approvals
49
+ WHERE skill_id = ? AND is_complete = 0
50
+ ORDER BY created_at ASC
51
+ LIMIT 1
52
+ `;
53
+ // ============================================================================
54
+ // Repository Implementation
55
+ // ============================================================================
56
+ /**
57
+ * Repository for persisting multi-approval workflow state.
58
+ *
59
+ * Replaces the in-memory Map<string, MultiApprovalStatus> with
60
+ * database-backed storage to survive service restarts.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const repo = new ApprovalRepository(db)
65
+ *
66
+ * // Record a reviewer's approval
67
+ * repo.recordApproval({
68
+ * skillId: 'quarantine-123',
69
+ * reviewerId: 'user-456',
70
+ * reviewerRole: 'reviewer@example.com',
71
+ * decision: 'approved',
72
+ * reason: 'Code verified safe',
73
+ * })
74
+ *
75
+ * // Check if enough approvals have been collected
76
+ * const complete = repo.isComplete('quarantine-123')
77
+ * ```
78
+ */
79
+ export class ApprovalRepository {
80
+ db;
81
+ constructor(db) {
82
+ this.db = db;
83
+ this.ensureTableExists();
84
+ }
85
+ /**
86
+ * Ensure the quarantine_approvals table exists
87
+ */
88
+ ensureTableExists() {
89
+ initializeQuarantineApprovalsSchema(this.db);
90
+ }
91
+ /**
92
+ * Record a new approval or rejection for a quarantine entry
93
+ *
94
+ * @param input - Approval details
95
+ * @returns The created approval entry
96
+ * @throws Error if reviewer has already submitted for this skill
97
+ */
98
+ recordApproval(input) {
99
+ const id = randomUUID();
100
+ const requiredApprovals = input.requiredApprovals ?? 2;
101
+ this.db
102
+ .prepare(INSERT_APPROVAL_QUERY)
103
+ .run(id, input.skillId, input.reviewerId, input.reviewerEmail, input.decision, input.reason ?? null, requiredApprovals);
104
+ const row = this.db
105
+ .prepare('SELECT * FROM quarantine_approvals WHERE id = ?')
106
+ .get(id);
107
+ return rowToEntry(row);
108
+ }
109
+ /**
110
+ * Get all approvals for a quarantine entry (both pending and complete)
111
+ *
112
+ * @param skillId - The quarantine entry ID
113
+ * @returns All approval entries for this skill
114
+ */
115
+ getApprovals(skillId) {
116
+ const rows = this.db.prepare(SELECT_BY_SKILL_ID_QUERY).all(skillId);
117
+ return rows.map(rowToEntry);
118
+ }
119
+ /**
120
+ * Get only pending (non-complete) approvals for a quarantine entry
121
+ *
122
+ * @param skillId - The quarantine entry ID
123
+ * @returns Pending approval entries
124
+ */
125
+ getPendingApprovals(skillId) {
126
+ const rows = this.db.prepare(SELECT_PENDING_BY_SKILL_ID_QUERY).all(skillId);
127
+ return rows.map(rowToEntry);
128
+ }
129
+ /**
130
+ * Check if a specific reviewer has already submitted for a skill
131
+ *
132
+ * @param skillId - The quarantine entry ID
133
+ * @param reviewerId - The reviewer's user ID
134
+ * @returns True if the reviewer already has a pending approval
135
+ */
136
+ hasReviewerApproved(skillId, reviewerId) {
137
+ const row = this.db.prepare(CHECK_REVIEWER_EXISTS_QUERY).get(skillId, reviewerId);
138
+ return !!row;
139
+ }
140
+ /**
141
+ * Check if the required number of approvals have been reached
142
+ *
143
+ * @param skillId - The quarantine entry ID
144
+ * @param requiredApprovals - Number of approvals needed (default: 2)
145
+ * @returns True if approval count meets or exceeds required
146
+ */
147
+ isComplete(skillId, requiredApprovals = 2) {
148
+ const { count } = this.db.prepare(COUNT_PENDING_APPROVALS_QUERY).get(skillId);
149
+ return count >= requiredApprovals;
150
+ }
151
+ /**
152
+ * Mark all pending approvals for a skill as complete
153
+ *
154
+ * @param skillId - The quarantine entry ID
155
+ * @returns Number of rows updated
156
+ */
157
+ markComplete(skillId) {
158
+ const result = this.db.prepare(MARK_COMPLETE_QUERY).run(skillId);
159
+ return result.changes;
160
+ }
161
+ /**
162
+ * Delete all approvals for a skill (for cleanup/reset/cancellation)
163
+ *
164
+ * @param skillId - The quarantine entry ID
165
+ * @returns Number of rows deleted
166
+ */
167
+ clearApprovals(skillId) {
168
+ const result = this.db.prepare(DELETE_BY_SKILL_ID_QUERY).run(skillId);
169
+ return result.changes;
170
+ }
171
+ /**
172
+ * Get the timestamp of the first pending approval for timeout checks
173
+ *
174
+ * @param skillId - The quarantine entry ID
175
+ * @returns ISO date string of the first approval, or null if none
176
+ */
177
+ getWorkflowStartTime(skillId) {
178
+ const row = this.db.prepare(SELECT_FIRST_PENDING_QUERY).get(skillId);
179
+ return row?.created_at ?? null;
180
+ }
181
+ /**
182
+ * Get the count of pending approvals for a skill
183
+ *
184
+ * @param skillId - The quarantine entry ID
185
+ * @returns Count of pending approved entries
186
+ */
187
+ getPendingApprovalCount(skillId) {
188
+ const { count } = this.db.prepare(COUNT_PENDING_APPROVALS_QUERY).get(skillId);
189
+ return count;
190
+ }
191
+ }
192
+ // ============================================================================
193
+ // Helpers
194
+ // ============================================================================
195
+ /**
196
+ * Convert a database row to a domain object
197
+ */
198
+ function rowToEntry(row) {
199
+ return {
200
+ id: row.id,
201
+ skillId: row.skill_id,
202
+ reviewerId: row.reviewer_id,
203
+ reviewerEmail: row.reviewer_email,
204
+ decision: row.decision,
205
+ reason: row.reason,
206
+ createdAt: row.created_at,
207
+ completedAt: row.completed_at,
208
+ requiredApprovals: row.required_approvals,
209
+ isComplete: row.is_complete === 1,
210
+ };
211
+ }
212
+ //# sourceMappingURL=ApprovalRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApprovalRepository.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/ApprovalRepository.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,mCAAmC,EAAE,MAAM,yCAAyC,CAAA;AAkD7F,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,MAAM,qBAAqB,GAAG;;;;;;CAM7B,CAAA;AAED,MAAM,wBAAwB,GAAG;;;;CAIhC,CAAA;AAED,MAAM,gCAAgC,GAAG;;;;CAIxC,CAAA;AAED,MAAM,6BAA6B,GAAG;;;CAGrC,CAAA;AAED,MAAM,2BAA2B,GAAG;;;CAGnC,CAAA;AAED,MAAM,mBAAmB,GAAG;;;;CAI3B,CAAA;AAED,MAAM,wBAAwB,GAAG;;CAEhC,CAAA;AAED,MAAM,0BAA0B,GAAG;;;;;CAKlC,CAAA;AAED,+EAA+E;AAC/E,4BAA4B;AAC5B,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,kBAAkB;IACrB,EAAE,CAAc;IAExB,YAAY,EAAgB;QAC1B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,iBAAiB,EAAE,CAAA;IAC1B,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,mCAAmC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,KAA0B;QACvC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAA;QACvB,MAAM,iBAAiB,GAAG,KAAK,CAAC,iBAAiB,IAAI,CAAC,CAAA;QAEtD,IAAI,CAAC,EAAE;aACJ,OAAO,CAAC,qBAAqB,CAAC;aAC9B,GAAG,CACF,EAAE,EACF,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,MAAM,IAAI,IAAI,EACpB,iBAAiB,CAClB,CAAA;QAEH,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,iDAAiD,CAAC;aAC1D,GAAG,CAAC,EAAE,CAAgB,CAAA;QAEzB,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAe;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAA;QAEpF,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;OAKG;IACH,mBAAmB,CAAC,OAAe;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAkB,CAAA;QAE5F,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAe,EAAE,UAAkB;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAEjF,OAAO,CAAC,CAAC,GAAG,CAAA;IACd,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,OAAe,EAAE,oBAA4B,CAAC;QACvD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GAAG,CAAC,OAAO,CAE3E,CAAA;QAED,OAAO,KAAK,IAAI,iBAAiB,CAAA;IACnC,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAe;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEhE,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,OAAe;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAErE,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,OAAe;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,OAAO,CAEtD,CAAA;QAEb,OAAO,GAAG,EAAE,UAAU,IAAI,IAAI,CAAA;IAChC,CAAC;IAED;;;;;OAKG;IACH,uBAAuB,CAAC,OAAe;QACrC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GAAG,CAAC,OAAO,CAE3E,CAAA;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AAED,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;GAEG;AACH,SAAS,UAAU,CAAC,GAAgB;IAClC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,iBAAiB,EAAE,GAAG,CAAC,kBAAkB;QACzC,UAAU,EAAE,GAAG,CAAC,WAAW,KAAK,CAAC;KAClC,CAAA;AACH,CAAC"}
@@ -7,4 +7,6 @@ export * from './types.js';
7
7
  export * from './queries.js';
8
8
  export * from './query-builder.js';
9
9
  export { QuarantineRepository } from './QuarantineRepository.js';
10
+ export { ApprovalRepository } from './ApprovalRepository.js';
11
+ export type { ApprovalRow, ApprovalEntry, RecordApprovalInput } from './ApprovalRepository.js';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -7,4 +7,5 @@ export * from './types.js';
7
7
  export * from './queries.js';
8
8
  export * from './query-builder.js';
9
9
  export { QuarantineRepository } from './QuarantineRepository.js';
10
+ export { ApprovalRepository } from './ApprovalRepository.js';
10
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/repositories/quarantine/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -7,7 +7,7 @@
7
7
  /**
8
8
  * Types of security events that are audited
9
9
  */
10
- export type AuditEventType = 'url_fetch' | 'file_access' | 'skill_install' | 'skill_uninstall' | 'security_scan' | 'cache_operation' | 'source_sync' | 'config_change' | 'quarantine_authenticated_review' | 'quarantine_multi_approval' | 'quarantine_multi_approval_complete' | 'quarantine_multi_approval_cancelled' | 'security_feature_flag_override';
10
+ export type AuditEventType = 'url_fetch' | 'file_access' | 'skill_install' | 'skill_uninstall' | 'security_scan' | 'cache_operation' | 'source_sync' | 'config_change' | 'quarantine_authenticated_review' | 'quarantine_multi_approval' | 'quarantine_multi_approval_complete' | 'quarantine_multi_approval_cancelled' | 'quarantine_multi_approval_timeout' | 'security_feature_flag_override';
11
11
  /**
12
12
  * Actor performing the action
13
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"audit-types.d.ts","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,eAAe,GAEf,iCAAiC,GACjC,2BAA2B,GAC3B,oCAAoC,GACpC,qCAAqC,GAErC,gCAAgC,CAAA;AAEpC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAE/E;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;GAEG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;IAC9C,gBAAgB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC7C,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B"}
1
+ {"version":3,"file":"audit-types.d.ts","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,aAAa,GACb,eAAe,GAEf,iCAAiC,GACjC,2BAA2B,GAC3B,oCAAoC,GACpC,qCAAqC,GACrC,mCAAmC,GAEnC,gCAAgC,CAAA;AAEpC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAE/E;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;GAEG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAA;IAC9C,gBAAgB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC7C,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit-types.js","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4EH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA,CAAC,WAAW"}
1
+ {"version":3,"file":"audit-types.js","sourceRoot":"","sources":["../../../src/security/audit-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6EH;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA,CAAC,WAAW"}
@@ -19,7 +19,7 @@ export function toMinimalRefs(report) {
19
19
  return report.findings.map((finding) => {
20
20
  const line = finding.lineNumber ?? 0;
21
21
  const severity = finding.severity.toUpperCase();
22
- const message = finding.message.replace(/"/g, '\\"');
22
+ const message = finding.message.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
23
23
  // Format: skill_id:line:severity:type:message
24
24
  return `${report.skillId}:${line}:${severity}:${finding.type}:${message}`;
25
25
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityScanner.formatters.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.formatters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkB;IAC9C,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAA;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACpD,8CAA8C;QAC9C,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,CAAA;IAC3E,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,MAAkB;IACxC,MAAM,KAAK,GAAG;QACZ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,OAAO,EAAE;QACjE,EAAE,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE;QAC7E,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE;QACnE,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE;QAC3E,EAAE,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,EAAE;QAC/E,EAAE,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE;QAC7E,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE;QACrE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE;QACrD,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE;KAC9D,CAAA;IAED,MAAM,eAAe,GAA2B;QAC9C,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,SAAS;QACjB,GAAG,EAAE,MAAM;KACZ,CAAA;IAED,OAAO;QACL,OAAO,EAAE,+CAA+C;QACxD,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ;gBACE,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,6BAA6B;wBACnC,OAAO,EAAE,OAAO;wBAChB,cAAc,EAAE,0CAA0C;wBAC1D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;4BAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;4BACX,IAAI,EAAE,IAAI,CAAC,IAAI;4BACf,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;4BACrC,oBAAoB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE;yBAC/C,CAAC,CAAC;qBACJ;iBACF;gBACD,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACzC,MAAM,EAAE,OAAO,CAAC,IAAI;oBACpB,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,SAAS;oBACrD,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE;oBAClC,SAAS,EAAE;wBACT;4BACE,gBAAgB,EAAE;gCAChB,gBAAgB,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE;gCACzC,MAAM,EAAE;oCACN,SAAS,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC;oCAClC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS;iCACnE;6BACF;yBACF;qBACF;oBACD,UAAU,EAAE;wBACV,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;wBACxC,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,IAAI,KAAK;qBAChE;iBACF,CAAC,CAAC;gBACH,WAAW,EAAE;oBACX;wBACE,mBAAmB,EAAE,IAAI;wBACzB,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE;qBAC3C;iBACF;aACF;SACF;KACF,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACrC,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ,KAAK,UAAU,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;QACtF,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAA;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAChG,OAAO,KAAK,QAAQ,SAAS,MAAM,CAAC,OAAO,SAAS,IAAI,KAAK,OAAO,EAAE,CAAA;IACxE,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,MAAkB;IAS1C,MAAM,UAAU,GAA2B,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAA;IACtF,MAAM,MAAM,GAA2B,EAAE,CAAA;IAEzC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACtE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IACxD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QACrC,UAAU;QACV,MAAM;QACN,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"SecurityScanner.formatters.js","sourceRoot":"","sources":["../../../../src/security/scanner/SecurityScanner.formatters.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * SMI-2269: Quarantine Service with Authentication
3
+ * SMI-2277: Persist multi-approval state to database
3
4
  *
4
5
  * Service layer for quarantine operations that enforces authentication
5
6
  * and authorization. Wraps QuarantineRepository with security controls.
@@ -13,10 +14,12 @@
13
14
  * - Enforces security_reviewer permission for review access
14
15
  * - Multi-approval workflow for MALICIOUS severity
15
16
  * - Audit logs include verified reviewer identity
17
+ * - Approval state persisted to database (survives restarts)
16
18
  *
17
19
  * @module @skillsmith/core/services/quarantine/QuarantineService
18
20
  */
19
21
  import type { QuarantineRepository } from '../../repositories/quarantine/index.js';
22
+ import type { ApprovalRepository } from '../../repositories/quarantine/ApprovalRepository.js';
20
23
  import type { AuditLogger } from '../../security/AuditLogger.js';
21
24
  import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedReviewResult, MultiApprovalStatus } from './types.js';
22
25
  /**
@@ -27,10 +30,11 @@ import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedRevie
27
30
  * - Permission checks (security_reviewer role)
28
31
  * - Multi-approval workflow for MALICIOUS severity
29
32
  * - Audit logging with verified identities
33
+ * - Database-persisted approval state (SMI-2277)
30
34
  *
31
35
  * @example
32
36
  * ```typescript
33
- * const service = new QuarantineService(repository, auditLogger)
37
+ * const service = new QuarantineService(repository, approvalRepository, auditLogger)
34
38
  *
35
39
  * // Review a quarantined skill (requires authentication)
36
40
  * const result = await service.review(
@@ -42,15 +46,9 @@ import type { AuthenticatedSession, AuthenticatedReviewInput, AuthenticatedRevie
42
46
  */
43
47
  export declare class QuarantineService {
44
48
  private readonly repository;
49
+ private readonly approvalRepository;
45
50
  private readonly auditLogger;
46
- /**
47
- * In-memory store for pending multi-approvals
48
- * Key: quarantineId, Value: MultiApprovalStatus
49
- *
50
- * Note: In production, this should be persisted to database
51
- */
52
- private pendingApprovals;
53
- constructor(repository: QuarantineRepository, auditLogger: AuditLogger);
51
+ constructor(repository: QuarantineRepository, approvalRepository: ApprovalRepository, auditLogger: AuditLogger);
54
52
  /**
55
53
  * Find a quarantine entry by ID
56
54
  *
@@ -106,6 +104,9 @@ export declare class QuarantineService {
106
104
  * before a skill can be unquarantined. This prevents single
107
105
  * reviewer compromise from allowing malicious skills.
108
106
  *
107
+ * Approval state is persisted to the database (SMI-2277) so
108
+ * pending approvals survive service restarts.
109
+ *
109
110
  * @param session - Authenticated session
110
111
  * @param quarantineId - Quarantine entry ID
111
112
  * @param skillId - Skill ID
@@ -145,5 +146,12 @@ export declare class QuarantineService {
145
146
  * @returns Whether the entry was deleted
146
147
  */
147
148
  delete(session: AuthenticatedSession, id: string): boolean;
149
+ /**
150
+ * Build a MultiApprovalStatus from database rows
151
+ *
152
+ * Converts persisted approval entries into the MultiApprovalStatus
153
+ * interface expected by consumers.
154
+ */
155
+ private buildMultiApprovalStatus;
148
156
  }
149
157
  //# sourceMappingURL=QuarantineService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QuarantineService.d.ts","sourceRoot":"","sources":["../../../../src/services/quarantine/QuarantineService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EAEpB,MAAM,YAAY,CAAA;AAqBnB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAiB;IAU1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAV9B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAA8C;gBAGnD,UAAU,EAAE,oBAAoB,EAChC,WAAW,EAAE,WAAW;IAO3C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM;IAKlD;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;IAK5D;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAK9F;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAStC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CACJ,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,wBAAwB,GAC9B,yBAAyB;IAoF5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,uBAAuB;IAkJ/B;;;;;;OAMG;IACH,sBAAsB,CACpB,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,GACnB,mBAAmB,GAAG,IAAI;IAK7B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IA8BjF;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAK1F;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;CAQ3D"}
1
+ {"version":3,"file":"QuarantineService.d.ts","sourceRoot":"","sources":["../../../../src/services/quarantine/QuarantineService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAA;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,mBAAmB,EAEpB,MAAM,YAAY,CAAA;AAqBnB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,UAAU,EAAE,oBAAoB,EAChC,kBAAkB,EAAE,kBAAkB,EACtC,WAAW,EAAE,WAAW;IAO3C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM;IAKlD;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM;IAK5D;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAK9F;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAStC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CACJ,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,wBAAwB,GAC9B,yBAAyB;IAoF5B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,uBAAuB;IA2K/B;;;;;;OAMG;IACH,sBAAsB,CACpB,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,GACnB,mBAAmB,GAAG,IAAI;IAW7B;;;;;;OAMG;IACH,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IA8BjF;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAK1F;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAa1D;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;CA+BjC"}