@dsh-enhanced/assistant-verifier 0.1.48 → 0.1.49

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 (56) hide show
  1. package/README.md +89 -0
  2. package/lib/config.d.ts +8 -0
  3. package/lib/config.d.ts.map +1 -1
  4. package/lib/config.js +4 -0
  5. package/lib/config.js.map +1 -1
  6. package/lib/creation-review-native.d.ts +30 -0
  7. package/lib/creation-review-native.d.ts.map +1 -0
  8. package/lib/creation-review-native.js +130 -0
  9. package/lib/creation-review-native.js.map +1 -0
  10. package/lib/creation-review-store.d.ts +29 -0
  11. package/lib/creation-review-store.d.ts.map +1 -0
  12. package/lib/creation-review-store.js +206 -0
  13. package/lib/creation-review-store.js.map +1 -0
  14. package/lib/creation-review.d.ts +159 -0
  15. package/lib/creation-review.d.ts.map +1 -0
  16. package/lib/creation-review.js +511 -0
  17. package/lib/creation-review.js.map +1 -0
  18. package/lib/index.d.ts +9 -0
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +4 -0
  21. package/lib/index.js.map +1 -1
  22. package/lib/memory-review-native.d.ts +38 -0
  23. package/lib/memory-review-native.d.ts.map +1 -0
  24. package/lib/memory-review-native.js +149 -0
  25. package/lib/memory-review-native.js.map +1 -0
  26. package/lib/memory-review.d.ts +48 -0
  27. package/lib/memory-review.d.ts.map +1 -0
  28. package/lib/memory-review.js +260 -0
  29. package/lib/memory-review.js.map +1 -0
  30. package/lib/plugin-behavior-runner.d.ts +46 -0
  31. package/lib/plugin-behavior-runner.d.ts.map +1 -0
  32. package/lib/plugin-behavior-runner.js +437 -0
  33. package/lib/plugin-behavior-runner.js.map +1 -0
  34. package/lib/revision-regression-review.d.ts +38 -0
  35. package/lib/revision-regression-review.d.ts.map +1 -0
  36. package/lib/revision-regression-review.js +315 -0
  37. package/lib/revision-regression-review.js.map +1 -0
  38. package/lib/revision-review.d.ts +99 -0
  39. package/lib/revision-review.d.ts.map +1 -0
  40. package/lib/revision-review.js +275 -0
  41. package/lib/revision-review.js.map +1 -0
  42. package/lib/service.d.ts +30 -0
  43. package/lib/service.d.ts.map +1 -1
  44. package/lib/service.js +139 -1
  45. package/lib/service.js.map +1 -1
  46. package/lib/source-review-native.d.ts +9 -0
  47. package/lib/source-review-native.d.ts.map +1 -1
  48. package/lib/source-review-native.js +6 -5
  49. package/lib/source-review-native.js.map +1 -1
  50. package/lib/source-review-store.d.ts +4 -0
  51. package/lib/source-review-store.d.ts.map +1 -1
  52. package/lib/source-review-store.js +65 -12
  53. package/lib/source-review-store.js.map +1 -1
  54. package/lib/version.d.ts +1 -1
  55. package/lib/version.js +1 -1
  56. package/package.json +34 -25
@@ -0,0 +1,437 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { IsolatedVerifierRunner } from '@dsh-enhanced/assistant-isolation';
3
+ const MAX_PACK_BYTES = 512 * 1024;
4
+ const MAX_OPERATION_BYTES = 64 * 1024;
5
+ const MAX_WORKER_OUTPUT_BYTES = 64 * 1024;
6
+ const SHA256 = /^[a-f0-9]{64}$/u;
7
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/u;
8
+ const SAFE_TOOL = /^[a-z][a-z0-9_-]{0,95}$/u;
9
+ const COMMAND = 'exec /usr/bin/env LD_PRELOAD=/opt/dsh-plugin-verifier/parent-protect.so /usr/local/bin/node --disable-sigusr1 /opt/dsh-plugin-verifier/worker.mjs';
10
+ const BOUNDARY = 'process-seccomp-v1';
11
+ function canonicalJson(value) {
12
+ try {
13
+ if (!deepJson(value))
14
+ return undefined;
15
+ const serialized = JSON.stringify(value);
16
+ return serialized === undefined ? undefined : serialized;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
22
+ function deepJson(value, seen = new Set()) {
23
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
24
+ return true;
25
+ if (typeof value === 'number')
26
+ return Number.isFinite(value);
27
+ if (typeof value !== 'object' || seen.has(value))
28
+ return false;
29
+ seen.add(value);
30
+ if (Array.isArray(value)) {
31
+ const valid = value.every(item => deepJson(item, seen));
32
+ seen.delete(value);
33
+ return valid;
34
+ }
35
+ if (Object.getPrototypeOf(value) !== Object.prototype)
36
+ return false;
37
+ const valid = Object.keys(value).every(key => {
38
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
39
+ return descriptor !== undefined && Object.hasOwn(descriptor, 'value') && deepJson(descriptor.value, seen);
40
+ });
41
+ seen.delete(value);
42
+ return valid;
43
+ }
44
+ function validOperation(value) {
45
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
46
+ return false;
47
+ const operation = value;
48
+ if (operation.kind === 'discover')
49
+ return Object.keys(operation).length === 1;
50
+ if (operation.kind !== 'invoke' || typeof operation.schemaDigest !== 'string' || !SHA256.test(operation.schemaDigest)
51
+ || !Array.isArray(operation.calls) || operation.calls.length < 1 || operation.calls.length > 8
52
+ || Object.keys(operation).length !== 3)
53
+ return false;
54
+ const ids = new Set();
55
+ for (const call of operation.calls) {
56
+ if (!call || typeof call !== 'object' || Object.keys(call).length !== 3
57
+ || !SAFE_ID.test(call.id) || !SAFE_TOOL.test(call.toolName) || ids.has(call.id) || !deepJson(call.arguments))
58
+ return false;
59
+ ids.add(call.id);
60
+ }
61
+ return true;
62
+ }
63
+ function validObservation(value, operation, sha256) {
64
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
65
+ return false;
66
+ const record = value;
67
+ if (record.schemaVersion !== 2 || record.boundary !== BOUNDARY || record.status !== 'observed' || record.artifactSha256 !== sha256
68
+ || record.quiescent !== true || !SHA256.test(record.schemaDigest)
69
+ || !record.environment || typeof record.environment !== 'object')
70
+ return false;
71
+ const environment = record.environment;
72
+ if (['node', 'cordis', 'tools', 'systemPrompt'].some(key => typeof environment[key] !== 'string'
73
+ || environment[key].length > 80))
74
+ return false;
75
+ if (operation.kind === 'discover') {
76
+ if (!Array.isArray(record.schemas) || record.schemas.length < 1 || record.schemas.length > 64 || record.calls !== undefined)
77
+ return false;
78
+ if (createHash('sha256').update(JSON.stringify(record.schemas)).digest('hex') !== record.schemaDigest)
79
+ return false;
80
+ const names = new Set();
81
+ for (const schema of record.schemas) {
82
+ if (!schema || typeof schema !== 'object' || !SAFE_TOOL.test(schema.name ?? '')
83
+ || names.has(schema.name))
84
+ return false;
85
+ names.add(schema.name);
86
+ }
87
+ }
88
+ else if (!Array.isArray(record.calls) || record.calls.length !== operation.calls.length
89
+ || record.schemaDigest !== operation.schemaDigest || record.schemas !== undefined
90
+ || record.calls.some((call, index) => !call || typeof call !== 'object'
91
+ || call.id !== operation.calls[index].id
92
+ || call.toolName !== operation.calls[index].toolName
93
+ || !Object.hasOwn(call, 'result')))
94
+ return false;
95
+ return true;
96
+ }
97
+ /** Host-only behavior observation. The candidate and worker receive no oracle or promotion authority. */
98
+ export class PluginBehaviorRunner {
99
+ #runner;
100
+ constructor(input) {
101
+ if (input.maxOutputBytes < MAX_WORKER_OUTPUT_BYTES)
102
+ throw new Error('plugin behavior output budget must be at least 64 KiB');
103
+ this.#runner = new IsolatedVerifierRunner({ ...input, command: COMMAND });
104
+ }
105
+ async run(input) {
106
+ const artifactSha256 = Buffer.isBuffer(input.artifact)
107
+ ? createHash('sha256').update(input.artifact).digest('hex') : '';
108
+ const unknown = (reason, quiescent = false, jobId) => ({ status: 'unknown', quiescent, artifactSha256, reason, ...(jobId ? { jobId } : {}) });
109
+ if (!Buffer.isBuffer(input.artifact) || input.artifact.length < 1 || input.artifact.length > MAX_PACK_BYTES)
110
+ return unknown('plugin-artifact-out-of-bound', true);
111
+ try {
112
+ if (!validOperation(input.operation))
113
+ return unknown('plugin-operation-invalid', true);
114
+ }
115
+ catch {
116
+ return unknown('plugin-operation-invalid', true);
117
+ }
118
+ const request = { schemaVersion: 1, sha256: artifactSha256, sizeBytes: input.artifact.length, operation: input.operation };
119
+ const stdin = canonicalJson(request);
120
+ if (stdin === undefined || Buffer.byteLength(stdin) > MAX_OPERATION_BYTES)
121
+ return unknown('plugin-operation-out-of-bound', true);
122
+ let isolated;
123
+ try {
124
+ isolated = await this.#runner.run(input.key, input.artifact.toString('base64'), stdin, input.signal);
125
+ }
126
+ catch {
127
+ return unknown('plugin-runner-unavailable');
128
+ }
129
+ if (isolated.status !== 'succeeded' || isolated.quiescent !== true || isolated.exitCode !== 0)
130
+ return unknown(isolated.reason ?? 'plugin-runner-unsettled', isolated.quiescent, isolated.jobId);
131
+ if (Buffer.byteLength(isolated.stdout) > MAX_WORKER_OUTPUT_BYTES || !isolated.stdout.endsWith('\n')
132
+ || isolated.stdout.indexOf('\n') !== isolated.stdout.length - 1)
133
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
134
+ try {
135
+ const value = JSON.parse(isolated.stdout.slice(0, -1));
136
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
137
+ const record = value;
138
+ if (record.schemaVersion === 2 && record.boundary === BOUNDARY && record.status === 'unknown'
139
+ && typeof record.reason === 'string' && record.reason.length > 0 && record.reason.length <= 128
140
+ && Object.keys(record).length === 4)
141
+ return unknown(record.reason, true, isolated.jobId);
142
+ }
143
+ if (!validObservation(value, input.operation, artifactSha256))
144
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
145
+ const observation = value;
146
+ return { status: 'observed', quiescent: true, artifactSha256, jobId: isolated.jobId,
147
+ environment: observation.environment, schemaDigest: observation.schemaDigest,
148
+ ...(input.operation.kind === 'discover' ? { schemas: observation.schemas } : { calls: observation.calls }) };
149
+ }
150
+ catch {
151
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
152
+ }
153
+ }
154
+ close() { return this.#runner.close(); }
155
+ }
156
+ /* DSH_PLUGIN_VERIFIER_WORKER_START
157
+ // Copied verbatim into the manifest-only image by build-plugin-verifier-image.mjs.
158
+ // This code executes inside the isolation worker, never in the Host process.
159
+ import { createHash } from 'node:crypto'
160
+ import { spawn } from 'node:child_process'
161
+ import { existsSync, mkdirSync, readFileSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'
162
+ import { dirname, join, resolve } from 'node:path'
163
+ import { gunzipSync } from 'node:zlib'
164
+
165
+ const limit = 512 * 1024
166
+ const safeId = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/
167
+ const safeTool = /^[a-z][a-z0-9_-]{0,95}$/
168
+ const shaPattern = /^[a-f0-9]{64}$/
169
+ const fail = reason => { throw new Error(reason) }
170
+ const digest = bytes => createHash('sha256').update(bytes).digest('hex')
171
+ const text = bytes => {
172
+ const end = bytes.indexOf(0)
173
+ const sliced = end < 0 ? bytes : bytes.subarray(0, end)
174
+ const value = sliced.toString('utf8')
175
+ if (!Buffer.from(value, 'utf8').equals(sliced)) fail('invalid-utf8-tar')
176
+ return value
177
+ }
178
+ const octal = bytes => {
179
+ const raw = text(bytes).trim()
180
+ if (!/^[0-7]+$/.test(raw)) fail('invalid-tar-number')
181
+ const value = Number.parseInt(raw, 8)
182
+ if (!Number.isSafeInteger(value)) fail('invalid-tar-number')
183
+ return value
184
+ }
185
+ const parsePax = bytes => {
186
+ const values = {}
187
+ for (let at = 0; at < bytes.length;) {
188
+ const space = bytes.indexOf(32, at)
189
+ if (space < 0) fail('invalid-pax')
190
+ const size = Number(bytes.subarray(at, space).toString('ascii'))
191
+ if (!Number.isSafeInteger(size) || size <= space - at + 2 || at + size > bytes.length || bytes[at + size - 1] !== 10) fail('invalid-pax')
192
+ const line = bytes.subarray(space + 1, at + size - 1).toString('utf8')
193
+ const equal = line.indexOf('=')
194
+ if (equal < 1 || Object.hasOwn(values, line.slice(0, equal))) fail('invalid-pax')
195
+ values[line.slice(0, equal)] = line.slice(equal + 1)
196
+ at += size
197
+ }
198
+ return values
199
+ }
200
+ function extract(bytes) {
201
+ let tar
202
+ try { tar = gunzipSync(bytes, { maxOutputLength: 16 * 1024 * 1024 }) }
203
+ catch { fail('invalid-or-oversized-tgz') }
204
+ const destination = '/workspace/plugin'
205
+ mkdirSync(destination, { mode: 0o700 })
206
+ let at = 0, extension = {}, global = {}, count = 0
207
+ const seen = new Set()
208
+ while (at + 512 <= tar.length) {
209
+ const header = tar.subarray(at, at + 512)
210
+ if (header.every(byte => byte === 0)) break
211
+ const expectedChecksum = octal(header.subarray(148, 156))
212
+ let checksum = 0
213
+ for (let index = 0; index < 512; index += 1) checksum += index >= 148 && index < 156 ? 32 : header[index]
214
+ if (expectedChecksum !== checksum) fail('invalid-tar-checksum')
215
+ const size = octal(header.subarray(124, 136))
216
+ const end = at + 512 + size
217
+ if (!Number.isSafeInteger(end) || end > tar.length || ++count > 256) fail('invalid-tar-member')
218
+ const kind = String.fromCharCode(header[156] || 48)
219
+ if (kind === 'g' || kind === 'x') {
220
+ if (size > 1_048_576) fail('oversized-tar-extension')
221
+ const parsed = parsePax(tar.subarray(at + 512, end))
222
+ if (kind === 'g') global = { ...global, ...parsed }
223
+ else extension = parsed
224
+ } else {
225
+ const attributes = { ...global, ...extension }
226
+ if (Object.keys(attributes).some(key => !['path', 'mtime', 'atime', 'ctime', 'comment', 'uid', 'gid', 'uname', 'gname', 'mode'].includes(key))) fail('unsupported-tar-extension')
227
+ const prefix = text(header.subarray(345, 500))
228
+ const rawName = prefix ? prefix + '/' + text(header.subarray(0, 100)) : text(header.subarray(0, 100))
229
+ const raw = attributes.path ?? rawName
230
+ const name = typeof raw === 'string' && raw.endsWith('/') ? raw.slice(0, -1) : raw
231
+ if (typeof name !== 'string' || name.length > 256
232
+ || name !== 'package' && (!name.startsWith('package/')
233
+ || name.slice(8).split('/').some(part => !part || part === '.' || part === '..' || !/^[A-Za-z0-9._-]+$/.test(part)))) fail('unsafe-tar-path')
234
+ if (seen.has(name) || (kind !== '0' && kind !== '5' && kind !== '7')
235
+ || name === 'package' && kind !== '5') fail('duplicate-or-unsafe-tar-entry')
236
+ seen.add(name)
237
+ const target = join(destination, name)
238
+ if (resolve(target) !== target || target !== join(destination, 'package') && !target.startsWith(destination + '/')) fail('unsafe-tar-path')
239
+ if (kind === '5') mkdirSync(target, { recursive: true, mode: 0o700 })
240
+ else {
241
+ mkdirSync(dirname(target), { recursive: true, mode: 0o700 })
242
+ writeFileSync(target, tar.subarray(at + 512, end), { flag: 'wx', mode: 0o600 })
243
+ }
244
+ extension = {}
245
+ }
246
+ at = end + (512 - size % 512) % 512
247
+ }
248
+ if (at + 1024 > tar.length || !tar.subarray(at).every(byte => byte === 0)) fail('invalid-tar-trailer')
249
+ if (!seen.has('package/package.json')) fail('missing-package-manifest')
250
+ const manifest = JSON.parse(readFileSync(join(destination, 'package/package.json'), 'utf8'))
251
+ if (!manifest || typeof manifest !== 'object' || typeof manifest.main !== 'string'
252
+ || !/^\.\/lib\/[A-Za-z0-9._/-]+\.js$/.test(manifest.main)
253
+ || manifest.main.split('/').includes('..')) fail('invalid-package-entry')
254
+ const entry = join(destination, 'package', manifest.main)
255
+ if (!existsSync(entry)) fail('missing-package-entry')
256
+ symlinkSync('/opt/dsh-plugin-verifier/node_modules', join(destination, 'package/node_modules'))
257
+ return entry
258
+ }
259
+ function validOperation(value) {
260
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false
261
+ if (value.kind === 'discover') return Object.keys(value).length === 1
262
+ if (value.kind !== 'invoke' || Object.keys(value).length !== 3 || !shaPattern.test(value.schemaDigest)
263
+ || !Array.isArray(value.calls) || value.calls.length < 1 || value.calls.length > 8) return false
264
+ const ids = new Set()
265
+ for (const call of value.calls) {
266
+ if (!call || typeof call !== 'object' || Object.keys(call).length !== 3
267
+ || !safeId.test(call.id) || !safeTool.test(call.toolName) || ids.has(call.id)) return false
268
+ ids.add(call.id)
269
+ }
270
+ return true
271
+ }
272
+ function version(name) {
273
+ return JSON.parse(readFileSync('/opt/dsh-plugin-verifier/node_modules/' + name + '/package.json', 'utf8')).version
274
+ }
275
+ const unknown = reason => ({ schemaVersion: 2, boundary: 'process-seccomp-v1', status: 'unknown', reason })
276
+ const decoded = bytes => new TextDecoder('utf-8', { fatal: true }).decode(bytes)
277
+ function validChild(value, operation) {
278
+ if (!value || typeof value !== 'object' || Array.isArray(value) || value.wireVersion !== 1) return false
279
+ if (value.status === 'unknown') return Object.keys(value).length === 3
280
+ && typeof value.reason === 'string' && value.reason.length > 0 && value.reason.length <= 128
281
+ if (value.status !== 'result' || !Array.isArray(value.schemas) || value.schemas.length < 1
282
+ || value.schemas.length > 64 || Object.keys(value).length !== (operation.kind === 'discover' ? 3 : 4)) return false
283
+ const names = new Set()
284
+ for (const schema of value.schemas) {
285
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema)
286
+ || !safeTool.test(schema.name) || names.has(schema.name)) return false
287
+ names.add(schema.name)
288
+ }
289
+ if (operation.kind === 'discover') return value.calls === undefined
290
+ if (!Array.isArray(value.calls) || value.calls.length !== operation.calls.length) return false
291
+ for (let index = 0; index < value.calls.length; index += 1) {
292
+ const call = value.calls[index], requested = operation.calls[index]
293
+ if (!call || typeof call !== 'object' || Array.isArray(call) || Object.keys(call).length !== 3
294
+ || call.id !== requested.id || call.toolName !== requested.toolName || !names.has(call.toolName)
295
+ || !Object.hasOwn(call, 'result')) return false
296
+ }
297
+ return true
298
+ }
299
+ function observeChild(entry, operation) {
300
+ return new Promise(resolvePromise => {
301
+ let child
302
+ try {
303
+ child = spawn('/opt/dsh-plugin-verifier/candidate-launcher', [], {
304
+ cwd: '/workspace/plugin/package',
305
+ env: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C', NODE_ENV: 'production' },
306
+ stdio: ['pipe', 'ignore', 'ignore', 'pipe'],
307
+ })
308
+ } catch { resolvePromise({ reason: 'candidate-launch-failed' }); return }
309
+ let bytes = Buffer.alloc(0), overflow = false, error = false, timedOut = false
310
+ const timer = setTimeout(() => { timedOut = true; child.kill('SIGKILL') }, 8000)
311
+ child.stdio[3].on('data', chunk => {
312
+ if (overflow) return
313
+ if (bytes.length + chunk.length > 60 * 1024) {
314
+ overflow = true
315
+ child.kill('SIGKILL')
316
+ } else bytes = Buffer.concat([bytes, chunk])
317
+ })
318
+ child.once('error', () => { error = true })
319
+ child.stdin.on('error', () => { error = true })
320
+ child.once('close', (code, signal) => {
321
+ clearTimeout(timer)
322
+ if (timedOut || overflow || error || code !== 0 || signal !== null) {
323
+ resolvePromise({ reason: timedOut ? 'candidate-timeout' : 'candidate-process-unsettled' }); return
324
+ }
325
+ try {
326
+ const text = decoded(bytes)
327
+ if (!text.endsWith('\n') || text.indexOf('\n') !== text.length - 1) fail('candidate-result-invalid')
328
+ const value = JSON.parse(text.slice(0, -1))
329
+ resolvePromise(validChild(value, operation) ? { value } : { reason: 'candidate-result-invalid' })
330
+ } catch { resolvePromise({ reason: 'candidate-result-invalid' }) }
331
+ })
332
+ child.stdin.end(JSON.stringify({ operation, entry }) + '\n')
333
+ })
334
+ }
335
+ let result
336
+ try {
337
+ const encoded = readFileSync('/workspace/artifact', 'utf8')
338
+ const request = JSON.parse(readFileSync('/workspace/input', 'utf8'))
339
+ // Remove both staged files before any candidate process exists. The candidate
340
+ // gets only its operation and the extracted package through its stdin/path.
341
+ unlinkSync('/workspace/artifact')
342
+ unlinkSync('/workspace/input')
343
+ if (!request || request.schemaVersion !== 1 || !shaPattern.test(request.sha256)
344
+ || !Number.isSafeInteger(request.sizeBytes) || request.sizeBytes < 1 || request.sizeBytes > limit
345
+ || !validOperation(request.operation) || !/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) fail('invalid-worker-input')
346
+ const packed = Buffer.from(encoded, 'base64')
347
+ if (packed.length !== request.sizeBytes || packed.toString('base64') !== encoded || digest(packed) !== request.sha256) fail('artifact-mismatch')
348
+ const entry = extract(packed)
349
+ const child = await observeChild(entry, request.operation)
350
+ if (!child.value) fail(child.reason)
351
+ if (child.value.status === 'unknown') fail(child.value.reason)
352
+ const schemas = child.value.schemas
353
+ const schemaDigest = digest(Buffer.from(JSON.stringify(schemas)))
354
+ if (request.operation.kind === 'invoke' && schemaDigest !== request.operation.schemaDigest) fail('schema-digest-changed')
355
+ const base = { schemaVersion: 2, boundary: 'process-seccomp-v1', status: 'observed',
356
+ artifactSha256: request.sha256, quiescent: true,
357
+ environment: { node: process.version, cordis: version('@deepseek-ai/cordis'),
358
+ tools: version('@deepseek-ai/dsh-tools'), systemPrompt: version('@deepseek-ai/dsh-system-prompt') }, schemaDigest }
359
+ result = request.operation.kind === 'discover' ? { ...base, schemas } : { ...base, calls: child.value.calls }
360
+ } catch (error) {
361
+ result = unknown(error instanceof Error ? error.message.slice(0, 128) : 'worker-error')
362
+ }
363
+ const output = JSON.stringify(result)
364
+ if (Buffer.byteLength(output) > 60 * 1024) process.stdout.write(JSON.stringify(unknown('worker-output-too-large')) + '\n')
365
+ else process.stdout.write(output + '\n')
366
+ DSH_PLUGIN_VERIFIER_WORKER_END */
367
+ /* DSH_PLUGIN_VERIFIER_CANDIDATE_START
368
+ // Executes only after the fixed launcher installs seccomp and Node permissions.
369
+ import { createHash } from 'node:crypto'
370
+ import { writeSync } from 'node:fs'
371
+ import { pathToFileURL } from 'node:url'
372
+ import { Context } from '@deepseek-ai/cordis'
373
+ import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
374
+ import ToolRuntime from '@deepseek-ai/dsh-tools'
375
+
376
+ const safeTool = /^[a-z][a-z0-9_-]{0,95}$/
377
+ let fiber, ctx, result, disposed = true
378
+ try {
379
+ const chunks = []
380
+ let total = 0
381
+ for await (const chunk of process.stdin) {
382
+ total += chunk.length
383
+ if (total > 64 * 1024) throw new Error('candidate-input-too-large')
384
+ chunks.push(chunk)
385
+ }
386
+ const request = JSON.parse(Buffer.concat(chunks).toString('utf8'))
387
+ if (!request || typeof request.entry !== 'string'
388
+ || !/^\/workspace\/plugin\/package\/lib\/[A-Za-z0-9._/-]+\.js$/.test(request.entry)
389
+ || request.entry.split('/').includes('..')
390
+ || !request.operation || !['discover', 'invoke'].includes(request.operation.kind)) throw new Error('candidate-input-invalid')
391
+ ctx = new Context()
392
+ await ctx.plugin(SystemPrompt, { includeHarnessIdentity: false, includeRuntimeContext: false, personaPrefix: '' })
393
+ await ctx.plugin(ToolRuntime, { mode: 'native' })
394
+ const mod = await import(pathToFileURL(request.entry).href)
395
+ fiber = ctx.plugin(mod.default ?? mod)
396
+ let activationTimer
397
+ try {
398
+ await Promise.race([fiber, new Promise((_, reject) => {
399
+ activationTimer = setTimeout(() => reject(new Error('plugin-activation-timeout')), 5000)
400
+ })])
401
+ } finally { clearTimeout(activationTimer) }
402
+ if (fiber.state !== 2) throw new Error('plugin-fiber-not-active')
403
+ const schemas = (await ctx.systemPrompt.assemble({})).tools
404
+ if (!Array.isArray(schemas) || schemas.length < 1 || schemas.length > 64) throw new Error('invalid-tool-schemas')
405
+ const names = new Set()
406
+ for (const schema of schemas) {
407
+ if (!schema || !safeTool.test(schema.name) || names.has(schema.name)) throw new Error('invalid-tool-schemas')
408
+ names.add(schema.name)
409
+ }
410
+ const schemaDigest = createHash('sha256').update(JSON.stringify(schemas)).digest('hex')
411
+ if (request.operation.kind === 'invoke' && request.operation.schemaDigest !== schemaDigest)
412
+ throw new Error('schema-digest-changed')
413
+ if (request.operation.kind === 'discover') result = { wireVersion: 1, status: 'result', schemas }
414
+ else {
415
+ const calls = []
416
+ for (const call of request.operation.calls) {
417
+ if (!names.has(call.toolName)) throw new Error('unknown-invoked-tool')
418
+ const observed = await ctx.tools.execute({ callId: call.id, name: call.toolName,
419
+ arguments: call.arguments, signal: new AbortController().signal })
420
+ calls.push({ id: call.id, toolName: call.toolName, result: observed })
421
+ }
422
+ result = { wireVersion: 1, status: 'result', schemas, calls }
423
+ }
424
+ } catch (error) {
425
+ result = { wireVersion: 1, status: 'unknown', reason: error instanceof Error ? error.message.slice(0, 128) : 'candidate-error' }
426
+ } finally {
427
+ try { if (fiber) await fiber.dispose() } catch { disposed = false }
428
+ try { if (ctx) await ctx.fiber.dispose() } catch { disposed = false }
429
+ }
430
+ if (!disposed) result = { wireVersion: 1, status: 'unknown', reason: 'plugin-disposal-unconfirmed' }
431
+ try {
432
+ const output = JSON.stringify(result)
433
+ if (Buffer.byteLength(output) > 60 * 1024) throw new Error('candidate-output-too-large')
434
+ writeSync(3, output + '\n')
435
+ } catch { process.exitCode = 1 }
436
+ DSH_PLUGIN_VERIFIER_CANDIDATE_END */
437
+ //# sourceMappingURL=plugin-behavior-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-behavior-runner.js","sourceRoot":"","sources":["../src/plugin-behavior-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { type PluginCreationVerificationCertificate, type PluginRevisionRegressionRequest, type PluginRevisionRegressionResult, type RevisionRegressionAcceptanceAuthorityRef } from '@dsh-enhanced/assistant-growth-contract';
3
+ import { type CreationReviewConfig } from './creation-review.js';
4
+ export type RevisionRegressionReviewConfig = Omit<CreationReviewConfig, 'policy' | 'maxInputBytes' | 'maxOutputTokens'>;
5
+ export interface RevisionRegressionReviewAuthorityInspection {
6
+ authority: RevisionRegressionAcceptanceAuthorityRef;
7
+ publicKey: string;
8
+ remainingVerifications: number;
9
+ available: boolean;
10
+ }
11
+ export declare function validateRevisionRegressionReviewConfig(input: RevisionRegressionReviewConfig): RevisionRegressionReviewConfig;
12
+ export declare function compileRevisionRegressionReviewConfig(input: RevisionRegressionReviewConfig): {
13
+ config: RevisionRegressionReviewConfig;
14
+ authority: RevisionRegressionAcceptanceAuthorityRef;
15
+ publicKey: string;
16
+ privateKey: ReturnType<typeof import('node:crypto').createPrivateKey>;
17
+ };
18
+ type RetainedCases = Readonly<{
19
+ certificate: PluginCreationVerificationCertificate;
20
+ discovery: unknown;
21
+ contract: unknown;
22
+ cases: Record<string, unknown>;
23
+ }>;
24
+ type ReadParentCases = (certificate: PluginCreationVerificationCertificate) => RetainedCases | undefined;
25
+ /** Independent paired Docker regression; this runtime has no LLM service and cannot switch a tool. */
26
+ export declare class RevisionRegressionReviewRuntime {
27
+ #private;
28
+ private readonly ctx;
29
+ private readonly readParentCases;
30
+ constructor(ctx: Context, input: RevisionRegressionReviewConfig, databasePath: string, readParentCases: ReadParentCases);
31
+ inspect(input: {
32
+ owner: RevisionRegressionReviewConfig['owner'];
33
+ }): RevisionRegressionReviewAuthorityInspection | undefined;
34
+ run(request: PluginRevisionRegressionRequest, external?: AbortSignal): Promise<PluginRevisionRegressionResult>;
35
+ close(): Promise<void>;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=revision-regression-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-regression-review.d.ts","sourceRoot":"","sources":["../src/revision-regression-review.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAKL,KAAK,qCAAqC,EAC1C,KAAK,+BAA+B,EAAE,KAAK,8BAA8B,EAEzE,KAAK,wCAAwC,EAAE,MAAM,yCAAyC,CAAA;AAEhG,OAAO,EAC0C,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAQxG,MAAM,MAAM,8BAA8B,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,eAAe,GAAG,iBAAiB,CAAC,CAAA;AACvH,MAAM,WAAW,2CAA2C;IAC1D,SAAS,EAAE,wCAAwC,CAAA;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,SAAS,EAAE,OAAO,CAAA;CACnB;AAcD,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,8BAA8B,GAAG,8BAA8B,CAO5H;AAED,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,8BAA8B,GAAG;IAC5F,MAAM,EAAE,8BAA8B,CAAC;IAAC,SAAS,EAAE,wCAAwC,CAAC;IAC5F,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAC,cAAc,aAAa,EAAE,gBAAgB,CAAC,CAAA;CACzF,CAYA;AAkBD,KAAK,aAAa,GAAG,QAAQ,CAAC;IAAE,WAAW,EAAE,qCAAqC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IACrG,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAAA;AACtD,KAAK,eAAe,GAAG,CAAC,WAAW,EAAE,qCAAqC,KAAK,aAAa,GAAG,SAAS,CAAA;AAgCxG,sGAAsG;AACtG,qBAAa,+BAA+B;;IAS9B,OAAO,CAAC,QAAQ,CAAC,GAAG;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADL,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE,YAAY,EAAE,MAAM,EACnF,eAAe,EAAE,eAAe;IAenD,OAAO,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,8BAA8B,CAAC,OAAO,CAAC,CAAA;KAAE,GAAG,2CAA2C,GAAG,SAAS;IAQ3H,GAAG,CAAC,OAAO,EAAE,+BAA+B,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAoL9G,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAUvB"}