@dsh-enhanced/assistant-verifier 0.1.48 → 0.1.53

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 (68) hide show
  1. package/README.md +92 -1
  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 +162 -0
  15. package/lib/creation-review.d.ts.map +1 -0
  16. package/lib/creation-review.js +526 -0
  17. package/lib/creation-review.js.map +1 -0
  18. package/lib/index.d.ts +11 -0
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +5 -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/native-behavior-artifact.d.ts +9 -0
  31. package/lib/native-behavior-artifact.d.ts.map +1 -0
  32. package/lib/native-behavior-artifact.js +144 -0
  33. package/lib/native-behavior-artifact.js.map +1 -0
  34. package/lib/native-behavior-worker.d.ts +3 -0
  35. package/lib/native-behavior-worker.d.ts.map +1 -0
  36. package/lib/native-behavior-worker.js +110 -0
  37. package/lib/native-behavior-worker.js.map +1 -0
  38. package/lib/plugin-behavior-config.d.ts +10 -0
  39. package/lib/plugin-behavior-config.d.ts.map +1 -0
  40. package/lib/plugin-behavior-config.js +73 -0
  41. package/lib/plugin-behavior-config.js.map +1 -0
  42. package/lib/plugin-behavior-runner.d.ts +51 -0
  43. package/lib/plugin-behavior-runner.d.ts.map +1 -0
  44. package/lib/plugin-behavior-runner.js +516 -0
  45. package/lib/plugin-behavior-runner.js.map +1 -0
  46. package/lib/revision-regression-review.d.ts +38 -0
  47. package/lib/revision-regression-review.d.ts.map +1 -0
  48. package/lib/revision-regression-review.js +315 -0
  49. package/lib/revision-regression-review.js.map +1 -0
  50. package/lib/revision-review.d.ts +99 -0
  51. package/lib/revision-review.d.ts.map +1 -0
  52. package/lib/revision-review.js +275 -0
  53. package/lib/revision-review.js.map +1 -0
  54. package/lib/service.d.ts +30 -0
  55. package/lib/service.d.ts.map +1 -1
  56. package/lib/service.js +139 -1
  57. package/lib/service.js.map +1 -1
  58. package/lib/source-review-native.d.ts +9 -0
  59. package/lib/source-review-native.d.ts.map +1 -1
  60. package/lib/source-review-native.js +6 -5
  61. package/lib/source-review-native.js.map +1 -1
  62. package/lib/source-review-store.d.ts +4 -0
  63. package/lib/source-review-store.d.ts.map +1 -1
  64. package/lib/source-review-store.js +65 -12
  65. package/lib/source-review-store.js.map +1 -1
  66. package/lib/version.d.ts +1 -1
  67. package/lib/version.js +1 -1
  68. package/package.json +34 -29
@@ -0,0 +1,516 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { IsolatedVerifierRunner, NativeMacVerifierRunner } from '@dsh-enhanced/assistant-isolation';
3
+ import { behaviorNativeRuntimeDigest, NATIVE_BEHAVIOR_BOUNDARY, validatePluginBehaviorRunnerConfig } from './plugin-behavior-config.js';
4
+ export { NATIVE_BEHAVIOR_BOUNDARY, validatePluginBehaviorRunnerConfig, validatePluginBehaviorDeploymentConfig } from './plugin-behavior-config.js';
5
+ import { nativeBehaviorFiles } from './native-behavior-artifact.js';
6
+ import { NATIVE_BEHAVIOR_SOURCE } from './native-behavior-worker.js';
7
+ const MAX_PACK_BYTES = 512 * 1024;
8
+ const MAX_OPERATION_BYTES = 64 * 1024;
9
+ const MAX_WORKER_OUTPUT_BYTES = 64 * 1024;
10
+ const SHA256 = /^[a-f0-9]{64}$/u;
11
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/u;
12
+ const SAFE_TOOL = /^[a-z][a-z0-9_-]{0,95}$/u;
13
+ 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';
14
+ const BOUNDARY = 'process-seccomp-v1';
15
+ function canonicalJson(value) {
16
+ try {
17
+ if (!deepJson(value))
18
+ return undefined;
19
+ const serialized = JSON.stringify(value);
20
+ return serialized === undefined ? undefined : serialized;
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ function deepJson(value, seen = new Set()) {
27
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
28
+ return true;
29
+ if (typeof value === 'number')
30
+ return Number.isFinite(value);
31
+ if (typeof value !== 'object' || seen.has(value))
32
+ return false;
33
+ seen.add(value);
34
+ if (Array.isArray(value)) {
35
+ const valid = value.every(item => deepJson(item, seen));
36
+ seen.delete(value);
37
+ return valid;
38
+ }
39
+ if (Object.getPrototypeOf(value) !== Object.prototype)
40
+ return false;
41
+ const valid = Object.keys(value).every(key => {
42
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
43
+ return descriptor !== undefined && Object.hasOwn(descriptor, 'value') && deepJson(descriptor.value, seen);
44
+ });
45
+ seen.delete(value);
46
+ return valid;
47
+ }
48
+ function validOperation(value) {
49
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
50
+ return false;
51
+ const operation = value;
52
+ if (operation.kind === 'discover')
53
+ return Object.keys(operation).length === 1;
54
+ if (operation.kind !== 'invoke' || typeof operation.schemaDigest !== 'string' || !SHA256.test(operation.schemaDigest)
55
+ || !Array.isArray(operation.calls) || operation.calls.length < 1 || operation.calls.length > 8
56
+ || Object.keys(operation).length !== 3)
57
+ return false;
58
+ const ids = new Set();
59
+ for (const call of operation.calls) {
60
+ if (!call || typeof call !== 'object' || Object.keys(call).length !== 3
61
+ || !SAFE_ID.test(call.id) || !SAFE_TOOL.test(call.toolName) || ids.has(call.id) || !deepJson(call.arguments))
62
+ return false;
63
+ ids.add(call.id);
64
+ }
65
+ return true;
66
+ }
67
+ function validObservation(value, operation, sha256) {
68
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
69
+ return false;
70
+ const record = value;
71
+ if (record.schemaVersion !== 2 || record.boundary !== BOUNDARY || record.status !== 'observed' || record.artifactSha256 !== sha256
72
+ || record.quiescent !== true || !SHA256.test(record.schemaDigest)
73
+ || !record.environment || typeof record.environment !== 'object')
74
+ return false;
75
+ const environment = record.environment;
76
+ if (['node', 'cordis', 'tools', 'systemPrompt'].some(key => typeof environment[key] !== 'string'
77
+ || environment[key].length > 80))
78
+ return false;
79
+ if (operation.kind === 'discover') {
80
+ if (!Array.isArray(record.schemas) || record.schemas.length < 1 || record.schemas.length > 64 || record.calls !== undefined)
81
+ return false;
82
+ if (createHash('sha256').update(JSON.stringify(record.schemas)).digest('hex') !== record.schemaDigest)
83
+ return false;
84
+ const names = new Set();
85
+ for (const schema of record.schemas) {
86
+ if (!schema || typeof schema !== 'object' || !SAFE_TOOL.test(schema.name ?? '')
87
+ || names.has(schema.name))
88
+ return false;
89
+ names.add(schema.name);
90
+ }
91
+ }
92
+ else if (!Array.isArray(record.calls) || record.calls.length !== operation.calls.length
93
+ || record.schemaDigest !== operation.schemaDigest || record.schemas !== undefined
94
+ || record.calls.some((call, index) => !call || typeof call !== 'object'
95
+ || call.id !== operation.calls[index].id
96
+ || call.toolName !== operation.calls[index].toolName
97
+ || !Object.hasOwn(call, 'result')))
98
+ return false;
99
+ return true;
100
+ }
101
+ /** Host-only behavior observation. The candidate and worker receive no oracle or promotion authority. */
102
+ export class PluginBehaviorRunner {
103
+ #runner;
104
+ #native;
105
+ #runtimeDigest;
106
+ #authorityDigest;
107
+ #environment;
108
+ #modulesPath;
109
+ constructor(input) {
110
+ const config = validatePluginBehaviorRunnerConfig(input);
111
+ this.#authorityDigest = config.authorityDigest;
112
+ this.#native = 'backend' in config && config.backend === 'macos-seatbelt';
113
+ if (this.#native) {
114
+ const native = config;
115
+ this.#runtimeDigest = behaviorNativeRuntimeDigest(native.runtime);
116
+ this.#environment = { node: native.runtime.versions.node, cordis: native.runtime.versions.cordis,
117
+ tools: native.runtime.versions.tools, systemPrompt: native.runtime.versions.systemPrompt };
118
+ this.#modulesPath = native.runtime.modulesPath;
119
+ this.#runner = new NativeMacVerifierRunner({ ...native, source: NATIVE_BEHAVIOR_SOURCE });
120
+ }
121
+ else
122
+ this.#runner = new IsolatedVerifierRunner({ ...config, command: COMMAND });
123
+ }
124
+ async run(input) {
125
+ const artifactSha256 = Buffer.isBuffer(input.artifact)
126
+ ? createHash('sha256').update(input.artifact).digest('hex') : '';
127
+ const unknown = (reason, quiescent = false, jobId) => ({ status: 'unknown', quiescent, artifactSha256, reason, ...(jobId ? { jobId } : {}) });
128
+ if (!Buffer.isBuffer(input.artifact) || input.artifact.length < 1 || input.artifact.length > MAX_PACK_BYTES)
129
+ return unknown('plugin-artifact-out-of-bound', true);
130
+ try {
131
+ if (!validOperation(input.operation))
132
+ return unknown('plugin-operation-invalid', true);
133
+ }
134
+ catch {
135
+ return unknown('plugin-operation-invalid', true);
136
+ }
137
+ let staged;
138
+ if (this.#native) {
139
+ try {
140
+ staged = nativeBehaviorFiles(input.artifact);
141
+ }
142
+ catch {
143
+ return unknown('plugin-artifact-invalid', true);
144
+ }
145
+ }
146
+ // Stable per frozen request: the durable runner must see identical bytes for a replay key.
147
+ // This is only frame correlation. Single-process candidate output is untrusted.
148
+ const nonce = this.#native ? createHash('sha256').update(JSON.stringify({ authorityDigest: this.#authorityDigest,
149
+ key: input.key, artifactSha256, operation: input.operation })).digest('hex') : undefined;
150
+ const request = this.#native
151
+ ? { schemaVersion: 1, nonce, artifactSha256, entry: staged.entry,
152
+ modulesPath: this.#modulesPath, operation: input.operation }
153
+ : { schemaVersion: 1, sha256: artifactSha256, sizeBytes: input.artifact.length, operation: input.operation };
154
+ const stdin = canonicalJson(request);
155
+ if (stdin === undefined || Buffer.byteLength(stdin) > MAX_OPERATION_BYTES)
156
+ return unknown('plugin-operation-out-of-bound', true);
157
+ let isolated;
158
+ try {
159
+ isolated = this.#native
160
+ ? await this.#runner.run(input.key, staged.files, stdin, input.signal)
161
+ : await this.#runner.run(input.key, input.artifact.toString('base64'), stdin, input.signal);
162
+ }
163
+ catch {
164
+ return unknown('plugin-runner-unavailable');
165
+ }
166
+ if (isolated.status !== 'succeeded' || isolated.quiescent !== true || isolated.exitCode !== 0)
167
+ return unknown(isolated.reason ?? 'plugin-runner-unsettled', isolated.quiescent, isolated.jobId);
168
+ if (Buffer.byteLength(isolated.stdout) > MAX_WORKER_OUTPUT_BYTES || !isolated.stdout.endsWith('\n')
169
+ || isolated.stdout.indexOf('\n') !== isolated.stdout.length - 1)
170
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
171
+ try {
172
+ const value = JSON.parse(isolated.stdout.slice(0, -1));
173
+ if (this.#native) {
174
+ if (!value || typeof value !== 'object' || Array.isArray(value))
175
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
176
+ const frame = value;
177
+ const header = frame.wireVersion === 1 && frame.nonce === nonce && frame.artifactSha256 === artifactSha256
178
+ && frame.operationDigest === createHash('sha256').update(JSON.stringify(input.operation)).digest('hex');
179
+ if (!header)
180
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
181
+ if (frame.status === 'unknown' && typeof frame.reason === 'string' && frame.reason.length > 0
182
+ && frame.reason.length <= 128 && Object.keys(frame).length === 6)
183
+ return unknown(frame.reason, true, isolated.jobId);
184
+ if (frame.status !== 'result' || !SHA256.test(frame.schemaDigest)
185
+ || Object.keys(frame).length !== 7)
186
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
187
+ if (input.operation.kind === 'discover') {
188
+ if (!Array.isArray(frame.schemas) || frame.schemas.length < 1 || frame.schemas.length > 64
189
+ || frame.calls !== undefined || createHash('sha256').update(JSON.stringify(frame.schemas)).digest('hex') !== frame.schemaDigest)
190
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
191
+ const names = new Set();
192
+ for (const schema of frame.schemas) {
193
+ const name = schema?.name;
194
+ if (typeof name !== 'string' || !SAFE_TOOL.test(name) || names.has(name))
195
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
196
+ names.add(name);
197
+ }
198
+ }
199
+ else {
200
+ const calls = input.operation.calls;
201
+ if (frame.schemaDigest !== input.operation.schemaDigest || !Array.isArray(frame.calls)
202
+ || frame.calls.length !== calls.length || frame.schemas !== undefined
203
+ || frame.calls.some((call, index) => !call || typeof call !== 'object'
204
+ || call.id !== calls[index].id
205
+ || call.toolName !== calls[index].toolName
206
+ || !Object.hasOwn(call, 'result')))
207
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
208
+ }
209
+ return { status: 'observed', quiescent: true, artifactSha256, jobId: isolated.jobId,
210
+ boundary: NATIVE_BEHAVIOR_BOUNDARY, runtimeDigest: this.#runtimeDigest, environment: this.#environment,
211
+ schemaDigest: frame.schemaDigest,
212
+ ...(input.operation.kind === 'discover' ? { schemas: frame.schemas }
213
+ : { calls: frame.calls }) };
214
+ }
215
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
216
+ const record = value;
217
+ if (record.schemaVersion === 2 && record.boundary === BOUNDARY && record.status === 'unknown'
218
+ && typeof record.reason === 'string' && record.reason.length > 0 && record.reason.length <= 128
219
+ && Object.keys(record).length === 4)
220
+ return unknown(record.reason, true, isolated.jobId);
221
+ }
222
+ if (!validObservation(value, input.operation, artifactSha256))
223
+ return unknown('plugin-worker-observation-invalid', true, isolated.jobId);
224
+ const observation = value;
225
+ return { status: 'observed', quiescent: true, artifactSha256, jobId: isolated.jobId,
226
+ environment: observation.environment, schemaDigest: observation.schemaDigest,
227
+ ...(input.operation.kind === 'discover' ? { schemas: observation.schemas } : { calls: observation.calls }) };
228
+ }
229
+ catch {
230
+ return unknown('plugin-worker-output-invalid', true, isolated.jobId);
231
+ }
232
+ }
233
+ close() { return this.#runner.close(); }
234
+ }
235
+ /* DSH_PLUGIN_VERIFIER_WORKER_START
236
+ // Copied verbatim into the manifest-only image by build-plugin-verifier-image.mjs.
237
+ // This code executes inside the isolation worker, never in the Host process.
238
+ import { createHash } from 'node:crypto'
239
+ import { spawn } from 'node:child_process'
240
+ import { existsSync, mkdirSync, readFileSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs'
241
+ import { dirname, join, resolve } from 'node:path'
242
+ import { gunzipSync } from 'node:zlib'
243
+
244
+ const limit = 512 * 1024
245
+ const safeId = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/
246
+ const safeTool = /^[a-z][a-z0-9_-]{0,95}$/
247
+ const shaPattern = /^[a-f0-9]{64}$/
248
+ const fail = reason => { throw new Error(reason) }
249
+ const digest = bytes => createHash('sha256').update(bytes).digest('hex')
250
+ const text = bytes => {
251
+ const end = bytes.indexOf(0)
252
+ const sliced = end < 0 ? bytes : bytes.subarray(0, end)
253
+ const value = sliced.toString('utf8')
254
+ if (!Buffer.from(value, 'utf8').equals(sliced)) fail('invalid-utf8-tar')
255
+ return value
256
+ }
257
+ const octal = bytes => {
258
+ const raw = text(bytes).trim()
259
+ if (!/^[0-7]+$/.test(raw)) fail('invalid-tar-number')
260
+ const value = Number.parseInt(raw, 8)
261
+ if (!Number.isSafeInteger(value)) fail('invalid-tar-number')
262
+ return value
263
+ }
264
+ const parsePax = bytes => {
265
+ const values = {}
266
+ for (let at = 0; at < bytes.length;) {
267
+ const space = bytes.indexOf(32, at)
268
+ if (space < 0) fail('invalid-pax')
269
+ const size = Number(bytes.subarray(at, space).toString('ascii'))
270
+ if (!Number.isSafeInteger(size) || size <= space - at + 2 || at + size > bytes.length || bytes[at + size - 1] !== 10) fail('invalid-pax')
271
+ const line = bytes.subarray(space + 1, at + size - 1).toString('utf8')
272
+ const equal = line.indexOf('=')
273
+ if (equal < 1 || Object.hasOwn(values, line.slice(0, equal))) fail('invalid-pax')
274
+ values[line.slice(0, equal)] = line.slice(equal + 1)
275
+ at += size
276
+ }
277
+ return values
278
+ }
279
+ function extract(bytes) {
280
+ let tar
281
+ try { tar = gunzipSync(bytes, { maxOutputLength: 16 * 1024 * 1024 }) }
282
+ catch { fail('invalid-or-oversized-tgz') }
283
+ const destination = '/workspace/plugin'
284
+ mkdirSync(destination, { mode: 0o700 })
285
+ let at = 0, extension = {}, global = {}, count = 0
286
+ const seen = new Set()
287
+ while (at + 512 <= tar.length) {
288
+ const header = tar.subarray(at, at + 512)
289
+ if (header.every(byte => byte === 0)) break
290
+ const expectedChecksum = octal(header.subarray(148, 156))
291
+ let checksum = 0
292
+ for (let index = 0; index < 512; index += 1) checksum += index >= 148 && index < 156 ? 32 : header[index]
293
+ if (expectedChecksum !== checksum) fail('invalid-tar-checksum')
294
+ const size = octal(header.subarray(124, 136))
295
+ const end = at + 512 + size
296
+ if (!Number.isSafeInteger(end) || end > tar.length || ++count > 256) fail('invalid-tar-member')
297
+ const kind = String.fromCharCode(header[156] || 48)
298
+ if (kind === 'g' || kind === 'x') {
299
+ if (size > 1_048_576) fail('oversized-tar-extension')
300
+ const parsed = parsePax(tar.subarray(at + 512, end))
301
+ if (kind === 'g') global = { ...global, ...parsed }
302
+ else extension = parsed
303
+ } else {
304
+ const attributes = { ...global, ...extension }
305
+ if (Object.keys(attributes).some(key => !['path', 'mtime', 'atime', 'ctime', 'comment', 'uid', 'gid', 'uname', 'gname', 'mode'].includes(key))) fail('unsupported-tar-extension')
306
+ const prefix = text(header.subarray(345, 500))
307
+ const rawName = prefix ? prefix + '/' + text(header.subarray(0, 100)) : text(header.subarray(0, 100))
308
+ const raw = attributes.path ?? rawName
309
+ const name = typeof raw === 'string' && raw.endsWith('/') ? raw.slice(0, -1) : raw
310
+ if (typeof name !== 'string' || name.length > 256
311
+ || name !== 'package' && (!name.startsWith('package/')
312
+ || name.slice(8).split('/').some(part => !part || part === '.' || part === '..' || !/^[A-Za-z0-9._-]+$/.test(part)))) fail('unsafe-tar-path')
313
+ if (seen.has(name) || (kind !== '0' && kind !== '5' && kind !== '7')
314
+ || name === 'package' && kind !== '5') fail('duplicate-or-unsafe-tar-entry')
315
+ seen.add(name)
316
+ const target = join(destination, name)
317
+ if (resolve(target) !== target || target !== join(destination, 'package') && !target.startsWith(destination + '/')) fail('unsafe-tar-path')
318
+ if (kind === '5') mkdirSync(target, { recursive: true, mode: 0o700 })
319
+ else {
320
+ mkdirSync(dirname(target), { recursive: true, mode: 0o700 })
321
+ writeFileSync(target, tar.subarray(at + 512, end), { flag: 'wx', mode: 0o600 })
322
+ }
323
+ extension = {}
324
+ }
325
+ at = end + (512 - size % 512) % 512
326
+ }
327
+ if (at + 1024 > tar.length || !tar.subarray(at).every(byte => byte === 0)) fail('invalid-tar-trailer')
328
+ if (!seen.has('package/package.json')) fail('missing-package-manifest')
329
+ const manifest = JSON.parse(readFileSync(join(destination, 'package/package.json'), 'utf8'))
330
+ if (!manifest || typeof manifest !== 'object' || typeof manifest.main !== 'string'
331
+ || !/^\.\/lib\/[A-Za-z0-9._/-]+\.js$/.test(manifest.main)
332
+ || manifest.main.split('/').includes('..')) fail('invalid-package-entry')
333
+ const entry = join(destination, 'package', manifest.main)
334
+ if (!existsSync(entry)) fail('missing-package-entry')
335
+ symlinkSync('/opt/dsh-plugin-verifier/node_modules', join(destination, 'package/node_modules'))
336
+ return entry
337
+ }
338
+ function validOperation(value) {
339
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false
340
+ if (value.kind === 'discover') return Object.keys(value).length === 1
341
+ if (value.kind !== 'invoke' || Object.keys(value).length !== 3 || !shaPattern.test(value.schemaDigest)
342
+ || !Array.isArray(value.calls) || value.calls.length < 1 || value.calls.length > 8) return false
343
+ const ids = new Set()
344
+ for (const call of value.calls) {
345
+ if (!call || typeof call !== 'object' || Object.keys(call).length !== 3
346
+ || !safeId.test(call.id) || !safeTool.test(call.toolName) || ids.has(call.id)) return false
347
+ ids.add(call.id)
348
+ }
349
+ return true
350
+ }
351
+ function version(name) {
352
+ return JSON.parse(readFileSync('/opt/dsh-plugin-verifier/node_modules/' + name + '/package.json', 'utf8')).version
353
+ }
354
+ const unknown = reason => ({ schemaVersion: 2, boundary: 'process-seccomp-v1', status: 'unknown', reason })
355
+ const decoded = bytes => new TextDecoder('utf-8', { fatal: true }).decode(bytes)
356
+ function validChild(value, operation) {
357
+ if (!value || typeof value !== 'object' || Array.isArray(value) || value.wireVersion !== 1) return false
358
+ if (value.status === 'unknown') return Object.keys(value).length === 3
359
+ && typeof value.reason === 'string' && value.reason.length > 0 && value.reason.length <= 128
360
+ if (value.status !== 'result' || !Array.isArray(value.schemas) || value.schemas.length < 1
361
+ || value.schemas.length > 64 || Object.keys(value).length !== (operation.kind === 'discover' ? 3 : 4)) return false
362
+ const names = new Set()
363
+ for (const schema of value.schemas) {
364
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema)
365
+ || !safeTool.test(schema.name) || names.has(schema.name)) return false
366
+ names.add(schema.name)
367
+ }
368
+ if (operation.kind === 'discover') return value.calls === undefined
369
+ if (!Array.isArray(value.calls) || value.calls.length !== operation.calls.length) return false
370
+ for (let index = 0; index < value.calls.length; index += 1) {
371
+ const call = value.calls[index], requested = operation.calls[index]
372
+ if (!call || typeof call !== 'object' || Array.isArray(call) || Object.keys(call).length !== 3
373
+ || call.id !== requested.id || call.toolName !== requested.toolName || !names.has(call.toolName)
374
+ || !Object.hasOwn(call, 'result')) return false
375
+ }
376
+ return true
377
+ }
378
+ function observeChild(entry, operation) {
379
+ return new Promise(resolvePromise => {
380
+ let child
381
+ try {
382
+ child = spawn('/opt/dsh-plugin-verifier/candidate-launcher', [], {
383
+ cwd: '/workspace/plugin/package',
384
+ env: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C', NODE_ENV: 'production' },
385
+ stdio: ['pipe', 'ignore', 'ignore', 'pipe'],
386
+ })
387
+ } catch { resolvePromise({ reason: 'candidate-launch-failed' }); return }
388
+ let bytes = Buffer.alloc(0), overflow = false, error = false, timedOut = false
389
+ const timer = setTimeout(() => { timedOut = true; child.kill('SIGKILL') }, 8000)
390
+ child.stdio[3].on('data', chunk => {
391
+ if (overflow) return
392
+ if (bytes.length + chunk.length > 60 * 1024) {
393
+ overflow = true
394
+ child.kill('SIGKILL')
395
+ } else bytes = Buffer.concat([bytes, chunk])
396
+ })
397
+ child.once('error', () => { error = true })
398
+ child.stdin.on('error', () => { error = true })
399
+ child.once('close', (code, signal) => {
400
+ clearTimeout(timer)
401
+ if (timedOut || overflow || error || code !== 0 || signal !== null) {
402
+ resolvePromise({ reason: timedOut ? 'candidate-timeout' : 'candidate-process-unsettled' }); return
403
+ }
404
+ try {
405
+ const text = decoded(bytes)
406
+ if (!text.endsWith('\n') || text.indexOf('\n') !== text.length - 1) fail('candidate-result-invalid')
407
+ const value = JSON.parse(text.slice(0, -1))
408
+ resolvePromise(validChild(value, operation) ? { value } : { reason: 'candidate-result-invalid' })
409
+ } catch { resolvePromise({ reason: 'candidate-result-invalid' }) }
410
+ })
411
+ child.stdin.end(JSON.stringify({ operation, entry }) + '\n')
412
+ })
413
+ }
414
+ let result
415
+ try {
416
+ const encoded = readFileSync('/workspace/artifact', 'utf8')
417
+ const request = JSON.parse(readFileSync('/workspace/input', 'utf8'))
418
+ // Remove both staged files before any candidate process exists. The candidate
419
+ // gets only its operation and the extracted package through its stdin/path.
420
+ unlinkSync('/workspace/artifact')
421
+ unlinkSync('/workspace/input')
422
+ if (!request || request.schemaVersion !== 1 || !shaPattern.test(request.sha256)
423
+ || !Number.isSafeInteger(request.sizeBytes) || request.sizeBytes < 1 || request.sizeBytes > limit
424
+ || !validOperation(request.operation) || !/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) fail('invalid-worker-input')
425
+ const packed = Buffer.from(encoded, 'base64')
426
+ if (packed.length !== request.sizeBytes || packed.toString('base64') !== encoded || digest(packed) !== request.sha256) fail('artifact-mismatch')
427
+ const entry = extract(packed)
428
+ const child = await observeChild(entry, request.operation)
429
+ if (!child.value) fail(child.reason)
430
+ if (child.value.status === 'unknown') fail(child.value.reason)
431
+ const schemas = child.value.schemas
432
+ const schemaDigest = digest(Buffer.from(JSON.stringify(schemas)))
433
+ if (request.operation.kind === 'invoke' && schemaDigest !== request.operation.schemaDigest) fail('schema-digest-changed')
434
+ const base = { schemaVersion: 2, boundary: 'process-seccomp-v1', status: 'observed',
435
+ artifactSha256: request.sha256, quiescent: true,
436
+ environment: { node: process.version, cordis: version('@deepseek-ai/cordis'),
437
+ tools: version('@deepseek-ai/dsh-tools'), systemPrompt: version('@deepseek-ai/dsh-system-prompt') }, schemaDigest }
438
+ result = request.operation.kind === 'discover' ? { ...base, schemas } : { ...base, calls: child.value.calls }
439
+ } catch (error) {
440
+ result = unknown(error instanceof Error ? error.message.slice(0, 128) : 'worker-error')
441
+ }
442
+ const output = JSON.stringify(result)
443
+ if (Buffer.byteLength(output) > 60 * 1024) process.stdout.write(JSON.stringify(unknown('worker-output-too-large')) + '\n')
444
+ else process.stdout.write(output + '\n')
445
+ DSH_PLUGIN_VERIFIER_WORKER_END */
446
+ /* DSH_PLUGIN_VERIFIER_CANDIDATE_START
447
+ // Executes only after the fixed launcher installs seccomp and Node permissions.
448
+ import { createHash } from 'node:crypto'
449
+ import { writeSync } from 'node:fs'
450
+ import { pathToFileURL } from 'node:url'
451
+ import { Context } from '@deepseek-ai/cordis'
452
+ import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
453
+ import ToolRuntime from '@deepseek-ai/dsh-tools'
454
+
455
+ const safeTool = /^[a-z][a-z0-9_-]{0,95}$/
456
+ let fiber, ctx, result, disposed = true
457
+ try {
458
+ const chunks = []
459
+ let total = 0
460
+ for await (const chunk of process.stdin) {
461
+ total += chunk.length
462
+ if (total > 64 * 1024) throw new Error('candidate-input-too-large')
463
+ chunks.push(chunk)
464
+ }
465
+ const request = JSON.parse(Buffer.concat(chunks).toString('utf8'))
466
+ if (!request || typeof request.entry !== 'string'
467
+ || !/^\/workspace\/plugin\/package\/lib\/[A-Za-z0-9._/-]+\.js$/.test(request.entry)
468
+ || request.entry.split('/').includes('..')
469
+ || !request.operation || !['discover', 'invoke'].includes(request.operation.kind)) throw new Error('candidate-input-invalid')
470
+ ctx = new Context()
471
+ await ctx.plugin(SystemPrompt, { includeHarnessIdentity: false, includeRuntimeContext: false, personaPrefix: '' })
472
+ await ctx.plugin(ToolRuntime, { mode: 'native' })
473
+ const mod = await import(pathToFileURL(request.entry).href)
474
+ fiber = ctx.plugin(mod.default ?? mod)
475
+ let activationTimer
476
+ try {
477
+ await Promise.race([fiber, new Promise((_, reject) => {
478
+ activationTimer = setTimeout(() => reject(new Error('plugin-activation-timeout')), 5000)
479
+ })])
480
+ } finally { clearTimeout(activationTimer) }
481
+ if (fiber.state !== 2) throw new Error('plugin-fiber-not-active')
482
+ const schemas = (await ctx.systemPrompt.assemble({})).tools
483
+ if (!Array.isArray(schemas) || schemas.length < 1 || schemas.length > 64) throw new Error('invalid-tool-schemas')
484
+ const names = new Set()
485
+ for (const schema of schemas) {
486
+ if (!schema || !safeTool.test(schema.name) || names.has(schema.name)) throw new Error('invalid-tool-schemas')
487
+ names.add(schema.name)
488
+ }
489
+ const schemaDigest = createHash('sha256').update(JSON.stringify(schemas)).digest('hex')
490
+ if (request.operation.kind === 'invoke' && request.operation.schemaDigest !== schemaDigest)
491
+ throw new Error('schema-digest-changed')
492
+ if (request.operation.kind === 'discover') result = { wireVersion: 1, status: 'result', schemas }
493
+ else {
494
+ const calls = []
495
+ for (const call of request.operation.calls) {
496
+ if (!names.has(call.toolName)) throw new Error('unknown-invoked-tool')
497
+ const observed = await ctx.tools.execute({ callId: call.id, name: call.toolName,
498
+ arguments: call.arguments, signal: new AbortController().signal })
499
+ calls.push({ id: call.id, toolName: call.toolName, result: observed })
500
+ }
501
+ result = { wireVersion: 1, status: 'result', schemas, calls }
502
+ }
503
+ } catch (error) {
504
+ result = { wireVersion: 1, status: 'unknown', reason: error instanceof Error ? error.message.slice(0, 128) : 'candidate-error' }
505
+ } finally {
506
+ try { if (fiber) await fiber.dispose() } catch { disposed = false }
507
+ try { if (ctx) await ctx.fiber.dispose() } catch { disposed = false }
508
+ }
509
+ if (!disposed) result = { wireVersion: 1, status: 'unknown', reason: 'plugin-disposal-unconfirmed' }
510
+ try {
511
+ const output = JSON.stringify(result)
512
+ if (Buffer.byteLength(output) > 60 * 1024) throw new Error('candidate-output-too-large')
513
+ writeSync(3, output + '\n')
514
+ } catch { process.exitCode = 1 }
515
+ DSH_PLUGIN_VERIFIER_CANDIDATE_END */
516
+ //# 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"}