dsh 0.2.0-rc.2: in-container update (experimental channel), path-agnostic compose, upstream patches adapted to 0.1.x/0.2.x

This commit is contained in:
hermes committed 2026-10-01 19:21:19 +00:00
commit e6dcef9bf5
302 files changed
+75178

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,353 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { mkdir, mkdtemp, readFile, stat, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { MANIFEST_MEDIA_TYPE, SIGNATURE_MEDIA_TYPE, VerifiedObjectStore } from '../stage0/lib/artifacts.mjs'
import { TrustLedger } from '../stage0/lib/ledger.mjs'
import { document, officialDshPolicy, keyPair, keyring, registryCandidate, registryKeyPair, signature } from './helpers.mjs'
function descriptor(id, content, mediaType = 'application/octet-stream') {
return {
id,
mediaType,
sha256: createHash('sha256').update(content).digest('hex'),
size: content.byteLength,
url: `https://github.com/example/releases/download/v1/${id}`,
}
}
function releaseTarget(generation, sequence, artifacts, policy = officialDshPolicy()) {
const selected = artifacts[0]
const signatureArtifact = descriptor('stable-signature', Buffer.from('signature'), 'application/vnd.dsh-platform.signature.v1+json')
const targetArtifacts = artifacts.some(artifact => artifact.id === signatureArtifact.id)
? artifacts
: [...artifacts, signatureArtifact]
return {
schema: 1,
updateApi: 1,
keyringGeneration: generation,
targetSequence: sequence,
issuedAt: '2026-08-19T00:00:00.000Z',
artifacts: targetArtifacts,
desired: {
bootstrap: { version: '1.0.0', manifestArtifactId: selected.id, signatureArtifactId: signatureArtifact.id },
environment: { version: '1.0.0', manifestArtifactId: selected.id, signatureArtifactId: signatureArtifact.id },
dsh: {
version: '0.1.0-rc.7',
integrity: `sha512-${Buffer.alloc(64).toString('base64')}`,
},
},
officialDshPolicy: policy,
}
}
function manifest(generation, sequence, artifacts) {
return {
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: generation,
targetSequence: sequence,
issuedAt: '2026-08-19T00:00:00.000Z',
artifacts,
bootstrapApi: 1,
components: [],
patches: [],
systemPlugins: [],
}
}
async function fixture(targetArtifacts, policy = officialDshPolicy()) {
const directory = await mkdtemp(join(tmpdir(), 'dsh-object-store-'))
const recovery = keyPair()
const current = keyPair()
const next = keyPair()
const ledger = new TrustLedger(join(directory, 'trust'), recovery.publicKey)
const ringBytes = document(keyring(1, current, next))
await ledger.acceptKeyring(ringBytes, signature(ringBytes, recovery))
const artifacts = typeof targetArtifacts === 'function' ? targetArtifacts(current) : targetArtifacts
const targetBytes = document(releaseTarget(1, 1, artifacts, policy))
await ledger.acceptTarget(targetBytes, signature(targetBytes, current))
const untrustedRoot = join(directory, 'downloads', 'untrusted')
await mkdir(untrustedRoot, { recursive: true })
return {
current,
directory,
ledger,
next,
recovery,
store: new VerifiedObjectStore({ root: join(directory, 'trust'), untrustedRoot, ledger }),
untrustedRoot,
}
}
test('empty activation succeeds before release trust is initialized', async () => {
const directory = await mkdtemp(join(tmpdir(), 'dsh-empty-activation-'))
const recovery = keyPair()
const ledger = new TrustLedger(join(directory, 'trust'), recovery.publicKey)
const untrustedRoot = join(directory, 'downloads', 'untrusted')
await mkdir(untrustedRoot, { recursive: true })
const store = new VerifiedObjectStore({ root: join(directory, 'trust'), untrustedRoot, ledger })
assert.deepEqual(await store.activate([]), [])
})
async function importSignature(store, untrustedRoot, signatureBytes) {
const path = join(untrustedRoot, 'manifest.sig.json')
await writeFile(path, signatureBytes)
return store.importFromTarget('stable-signature', path)
}
async function officialSources(untrustedRoot, candidate, content, suffix = '') {
const metadataPath = join(untrustedRoot, `official-dsh${suffix}.json`)
const tarballPath = join(untrustedRoot, `official-dsh${suffix}.tgz`)
await writeFile(metadataPath, JSON.stringify({ versions: { [candidate.version]: candidate } }))
await writeFile(tarballPath, content)
return { metadataPath, tarballPath }
}
test('imports only target-authorized bytes from the untrusted directory', async () => {
const content = Buffer.from('verified artifact')
const expected = descriptor('gateway', content)
const { store, untrustedRoot, directory } = await fixture([expected])
const source = join(untrustedRoot, 'gateway.bin')
await writeFile(source, content)
const receipt = await store.importFromTarget('gateway', source)
assert.equal(receipt.objectSha256, expected.sha256)
assert.deepEqual(await readFile(receipt.path), content)
assert.equal((await stat(receipt.path)).mode & 0o777, 0o444)
await assert.rejects(store.importFromTarget('missing', source), /not authorized/)
await assert.rejects(store.importFromTarget('gateway', join(directory, 'outside.bin')), /untrusted/)
})
test('treats receipts written before authority typing as Stable receipts', async () => {
const content = Buffer.from('legacy stable artifact')
const { store, untrustedRoot } = await fixture([descriptor('legacy', content)])
const source = join(untrustedRoot, 'legacy')
await writeFile(source, content)
const receipt = await store.importFromTarget('legacy', source)
const persisted = JSON.parse(await readFile(store.receiptPath(receipt.token), 'utf8'))
delete persisted.authorityType
await writeFile(store.receiptPath(receipt.token), `${JSON.stringify(persisted)}\n`)
assert.equal((await store.readReceipt(receipt.token)).authorityType, 'stable')
})
test('verifies updater-downloaded official DSH metadata and tarball without networking', async () => {
const content = Buffer.from('official tarball')
const registry = registryKeyPair()
const candidate = registryCandidate(registry, '0.1.0-rc.8', content)
const policy = officialDshPolicy(registry)
const { current, ledger, untrustedRoot, directory } = await fixture(
[descriptor('stable-only', Buffer.alloc(0))],
policy,
)
const store = new VerifiedObjectStore({ root: join(directory, 'trust'), untrustedRoot, ledger })
const advanced = document(releaseTarget(1, 2, [descriptor('stable-only', Buffer.alloc(0))], policy))
await ledger.acceptTarget(advanced, signature(advanced, current))
const sources = await officialSources(untrustedRoot, candidate, content)
const receipt = await store.ensureOfficialDsh(candidate.version, sources.metadataPath, sources.tarballPath)
assert.equal(receipt.authorityType, 'official-dsh')
assert.equal(receipt.authorityVersion, candidate.version)
assert.equal(receipt.targetSequence, 2)
assert.deepEqual(await readFile(receipt.path), content)
await store.activate([receipt.token])
assert.equal((await store.readReceipt(receipt.token)).status, 'active')
})
test('official DSH import accepts only regular files inside the untrusted directory', async () => {
const content = Buffer.from('official tarball')
const registry = registryKeyPair()
const candidate = registryCandidate(registry, '0.1.0-rc.8', content)
const { store, untrustedRoot, directory } = await fixture(
[descriptor('stable-only', Buffer.alloc(0))],
officialDshPolicy(registry),
)
const outside = await officialSources(directory, candidate, content)
await assert.rejects(store.ensureOfficialDsh(candidate.version, outside.metadataPath, outside.tarballPath), /untrusted/)
const sources = await officialSources(untrustedRoot, candidate, content)
const metadataLink = join(untrustedRoot, 'metadata-link.json')
await symlink(sources.metadataPath, metadataLink)
await assert.rejects(store.ensureOfficialDsh(candidate.version, metadataLink, sources.tarballPath), /ELOOP|symbolic/i)
})
test('official DSH import rejects malformed metadata and mismatched tarball bytes', async () => {
const content = Buffer.from('official tarball')
const registry = registryKeyPair()
const candidate = registryCandidate(registry, '0.1.0-rc.8', content)
const { store, untrustedRoot } = await fixture(
[descriptor('stable-only', Buffer.alloc(0))],
officialDshPolicy(registry),
)
const malformed = join(untrustedRoot, 'malformed.json')
const tarball = join(untrustedRoot, 'official.tgz')
await writeFile(malformed, '{')
await writeFile(tarball, content)
await assert.rejects(store.ensureOfficialDsh(candidate.version, malformed, tarball), /valid JSON/)
const sources = await officialSources(untrustedRoot, candidate, Buffer.from('different bytes'), '-mismatch')
await assert.rejects(
store.ensureOfficialDsh(candidate.version, sources.metadataPath, sources.tarballPath),
{ code: 'TRUST_ARTIFACT_MISMATCH' },
)
})
test('revokes staged official DSH receipts after Registry delegation changes but retains active objects', async () => {
const content = Buffer.from('official tarball')
const registry = registryKeyPair()
const replacement = registryKeyPair()
const candidate = registryCandidate(registry, '0.1.0-rc.8', content)
const { current, directory, ledger, untrustedRoot } = await fixture(
[descriptor('stable-only', Buffer.alloc(0))],
officialDshPolicy(registry),
)
const store = new VerifiedObjectStore({ root: join(directory, 'trust'), untrustedRoot, ledger })
const first = await officialSources(untrustedRoot, candidate, content, '-active')
const active = await store.ensureOfficialDsh(candidate.version, first.metadataPath, first.tarballPath)
await store.activate([active.token])
const second = await officialSources(untrustedRoot, candidate, content, '-staged')
const staged = await store.ensureOfficialDsh(candidate.version, second.metadataPath, second.tarballPath)
const advanced = document(releaseTarget(
1,
2,
[descriptor('stable-only', Buffer.alloc(0))],
officialDshPolicy(replacement),
))
await ledger.acceptTarget(advanced, signature(advanced, current))
await store.reconcileRevocations((await ledger.currentKeyring()).value)
assert.equal((await store.readReceipt(active.token)).status, 'active')
assert.equal((await store.readReceipt(staged.token)).status, 'revoked')
})
test('rejects mismatched content and symbolic-link sources', async () => {
const expected = descriptor('gateway', Buffer.from('expected'))
const { store, untrustedRoot } = await fixture([expected])
const bad = join(untrustedRoot, 'bad.bin')
await writeFile(bad, 'different')
await assert.rejects(store.importFromTarget('gateway', bad), { code: 'TRUST_ARTIFACT_MISMATCH' })
const real = join(untrustedRoot, 'real.bin')
const link = join(untrustedRoot, 'link.bin')
await writeFile(real, 'expected')
await symlink(real, link)
await assert.rejects(store.importFromTarget('gateway', link), /ELOOP|symbolic/i)
})
test('verifies a signed manifest before authorizing its child artifacts', async () => {
const component = Buffer.from('component')
const manifestBytes = document(manifest(1, 1, [descriptor('component', component)]))
const manifestDescriptor = descriptor('environment-manifest', manifestBytes, MANIFEST_MEDIA_TYPE)
let signatureBytes
const { store, untrustedRoot } = await fixture(current => {
signatureBytes = document(signature(manifestBytes, current))
return [manifestDescriptor, descriptor('stable-signature', signatureBytes, SIGNATURE_MEDIA_TYPE)]
})
const manifestPath = join(untrustedRoot, 'manifest.json')
await writeFile(manifestPath, manifestBytes)
const imported = await store.importFromTarget('environment-manifest', manifestPath)
await assert.rejects(store.importFromManifest(imported.token, 'component', manifestPath), /verified manifest/)
const signatureReceipt = await importSignature(store, untrustedRoot, signatureBytes)
await store.acceptManifest(imported.token, signatureReceipt.token)
const componentPath = join(untrustedRoot, 'component.bin')
await writeFile(componentPath, component)
const child = await store.importFromManifest(imported.token, 'component', componentPath)
assert.equal(child.parentReceipt, imported.token)
})
test('revokes unactivated receipts after key rotation but retains active and previous objects', async () => {
const one = Buffer.from('one')
const two = Buffer.from('two')
const third = Buffer.from('three')
const descriptors = [descriptor('one', one), descriptor('two', two), descriptor('three', third)]
const { current, next, recovery, ledger, store, untrustedRoot } = await fixture(descriptors)
for (const [name, content] of [['one', one], ['two', two], ['three', third]]) {
await writeFile(join(untrustedRoot, name), content)
}
const first = await store.importFromTarget('one', join(untrustedRoot, 'one'))
const second = await store.importFromTarget('two', join(untrustedRoot, 'two'))
const unactivated = await store.importFromTarget('three', join(untrustedRoot, 'three'))
await store.activate([first.token])
await store.activate([second.token])
const future = keyPair()
const rotated = document(keyring(2, next, future, [current.keyId]))
const rotatedValue = await ledger.acceptKeyring(rotated, signature(rotated, recovery))
await assert.rejects(store.importFromTarget('three', join(untrustedRoot, 'three')), { code: 'TRUST_REVOKED' })
await assert.rejects(store.activate([unactivated.token]), { code: 'TRUST_REVOKED' })
const revoked = await store.reconcileRevocations(rotatedValue)
assert.deepEqual(revoked, [unactivated.token])
assert.equal((await store.readReceipt(first.token)).status, 'previous')
assert.equal((await store.readReceipt(second.token)).status, 'active')
await store.collectGarbage()
await assert.rejects(store.readReceipt(unactivated.token), /does not exist/)
assert.deepEqual(await readFile(store.objectPath(descriptors[0].sha256)), one)
assert.deepEqual(await readFile(store.objectPath(descriptors[1].sha256)), two)
})
test('activation includes manifest ancestors and rollback swaps current and previous', async () => {
const component = Buffer.from('component')
const other = Buffer.from('other')
const manifestBytes = document(manifest(1, 1, [descriptor('component', component)]))
const manifestDescriptor = descriptor('environment-manifest', manifestBytes, MANIFEST_MEDIA_TYPE)
let signatureBytes
const { store, untrustedRoot } = await fixture(current => {
signatureBytes = document(signature(manifestBytes, current))
return [
manifestDescriptor,
descriptor('stable-signature', signatureBytes, SIGNATURE_MEDIA_TYPE),
descriptor('other', other),
]
})
await writeFile(join(untrustedRoot, 'manifest'), manifestBytes)
await writeFile(join(untrustedRoot, 'component'), component)
await writeFile(join(untrustedRoot, 'other'), other)
const parent = await store.importFromTarget('environment-manifest', join(untrustedRoot, 'manifest'))
const signatureReceipt = await importSignature(store, untrustedRoot, signatureBytes)
await store.acceptManifest(parent.token, signatureReceipt.token)
const child = await store.importFromManifest(parent.token, 'component', join(untrustedRoot, 'component'))
const selected = await store.activate([child.token])
assert.deepEqual(new Set(selected), new Set([parent.token, child.token]))
assert.equal((await store.readReceipt(parent.token)).status, 'active')
const nextReceipt = await store.importFromTarget('other', join(untrustedRoot, 'other'))
await store.activate([nextReceipt.token])
assert.equal((await store.readReceipt(parent.token)).status, 'previous')
await store.rollback()
assert.equal((await store.readReceipt(parent.token)).status, 'active')
assert.equal((await store.readReceipt(nextReceipt.token)).status, 'previous')
})
test('rejects staged receipts after the current Release Key advances targetSequence', async () => {
const content = Buffer.from('old target artifact')
const expected = descriptor('artifact', content)
const { current, ledger, store, untrustedRoot } = await fixture([expected])
const source = join(untrustedRoot, 'artifact')
await writeFile(source, content)
const receipt = await store.importFromTarget('artifact', source)
const advanced = document(releaseTarget(1, 2, [expected]))
await ledger.acceptTarget(advanced, signature(advanced, current))
await assert.rejects(store.activate([receipt.token]), { code: 'TRUST_REVOKED' })
})
test('rejects child imports through a manifest from an older targetSequence', async () => {
const component = Buffer.from('component')
const componentDescriptor = descriptor('component', component)
const manifestBytes = document(manifest(1, 1, [componentDescriptor]))
const manifestDescriptor = descriptor('environment-manifest', manifestBytes, MANIFEST_MEDIA_TYPE)
let signatureBytes
const { current, ledger, store, untrustedRoot } = await fixture(release => {
signatureBytes = document(signature(manifestBytes, release))
return [manifestDescriptor, descriptor('stable-signature', signatureBytes, SIGNATURE_MEDIA_TYPE)]
})
await writeFile(join(untrustedRoot, 'manifest'), manifestBytes)
await writeFile(join(untrustedRoot, 'component'), component)
const parent = await store.importFromTarget('environment-manifest', join(untrustedRoot, 'manifest'))
const signatureReceipt = await importSignature(store, untrustedRoot, signatureBytes)
await store.acceptManifest(parent.token, signatureReceipt.token)
const advanced = document(releaseTarget(1, 2, [manifestDescriptor]))
await ledger.acceptTarget(advanced, signature(advanced, current))
await assert.rejects(
store.importFromManifest(parent.token, 'component', join(untrustedRoot, 'component')),
{ code: 'TRUST_REVOKED' },
)
})
@@ -0,0 +1,80 @@
import assert from 'node:assert/strict'
import { mkdtemp } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
AUTOMATIC_CHECK_INTERVALS,
AutomaticCheckStateStore,
} from '../../control-plane/modules/updater/lib/automatic-check.mjs'
function target(targetSequence, dsh) {
return {
targetSequence,
desired: {
dsh: { version: dsh },
environment: { version: '1.0.0' },
},
}
}
test('automatic checks use persistent defaults and fixed user-facing intervals', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-automatic-check-'))
const store = new AutomaticCheckStateStore(join(root, 'automatic-check.json'))
assert.deepEqual(AUTOMATIC_CHECK_INTERVALS, [3_600, 10_800, 21_600, 43_200, 86_400])
assert.deepEqual(await store.read(), {
schema: 1,
automaticCheck: { enabled: true, intervalSeconds: 21_600, notificationsEnabled: true },
latestAutomatic: { stable: null, upstream: null },
})
assert.throws(() => store.configure({ enabled: true, intervalSeconds: 60, notificationsEnabled: true }), /interval/)
})
test('automatic checks retain only the newest Stable and Upstream candidates', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-automatic-candidates-'))
const store = new AutomaticCheckStateStore(join(root, 'automatic-check.json'), () => new Date('2026-08-20T08:00:00Z'))
const current = { targetSequence: 1, dsh: '0.1.0-rc.7', environment: '1.0.0' }
await store.record({ channel: 'experimental', current, target: target(2, '0.1.0-rc.8'), upstream: { version: '0.1.0-rc.10' }, stableAvailable: true })
await store.record({ channel: 'experimental', current, target: target(3, '0.1.0-rc.9'), upstream: { version: '0.1.0-rc.11' }, stableAvailable: true })
await store.record({ channel: 'experimental', current, target: target(2, '0.1.0-rc.8'), upstream: { version: '0.1.0-rc.10' }, stableAvailable: true })
const state = await store.read()
assert.equal(state.latestAutomatic.stable.targetSequence, 3)
assert.equal(state.latestAutomatic.upstream.version, '0.1.0-rc.11')
await store.clearSatisfied({ targetSequence: 3, dsh: '0.1.0-rc.11', environment: '1.0.0' })
assert.deepEqual((await store.read()).latestAutomatic, { stable: null, upstream: null })
})
test('Stable channel, Holds, and disabled settings suppress notification candidates', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-automatic-suppression-'))
const store = new AutomaticCheckStateStore(join(root, 'automatic-check.json'))
const current = { targetSequence: 1, dsh: '0.1.0-rc.7', environment: '1.0.0' }
const stable = target(2, '0.1.0-rc.8')
await store.record({ channel: 'experimental', current, target: stable, upstream: { version: '0.1.0-rc.10' }, stableAvailable: true })
await store.record({ channel: 'stable', current, target: stable, upstream: { version: '0.1.0-rc.11' }, stableAvailable: true })
assert.equal((await store.read()).latestAutomatic.upstream, null)
await store.record({
channel: 'experimental', current, target: stable, upstream: { version: '0.1.0-rc.11' },
stableAvailable: true, holds: [{ type: 'version', dshVersion: '0.1.0-rc.11' }],
})
assert.equal((await store.read()).latestAutomatic.upstream, null)
await store.configure({ enabled: false, intervalSeconds: 3_600, notificationsEnabled: true })
assert.deepEqual((await store.read()).latestAutomatic, { stable: null, upstream: null })
})
test('a sequence-only metadata advance does not advertise a Stable update', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-automatic-ahead-'))
const store = new AutomaticCheckStateStore(join(root, 'automatic-check.json'))
await store.record({
channel: 'experimental',
current: { targetSequence: 2, dsh: '0.1.0-rc.10', environment: '1.0.0' },
target: target(3, '0.1.0-rc.10'),
upstream: null,
stableAvailable: false,
})
assert.equal((await store.read()).latestAutomatic.stable, null)
})
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,67 @@
import assert from 'node:assert/strict'
import { chmod, mkdir, mkdtemp, readFile, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
async function fixture(environment = '2.3.4') {
const root = await mkdtemp(join(tmpdir(), 'dsh-bump-environment-'))
const definitionPath = join(root, 'container/environment/definition.json')
const targetPath = join(root, 'release/supported-target.json')
const scriptPath = join(root, 'scripts/bump-environment.sh')
await mkdir(join(root, 'container/environment'), { recursive: true })
await mkdir(join(root, 'container/platform'), { recursive: true })
await mkdir(join(root, 'release'), { recursive: true })
await mkdir(join(root, 'scripts'), { recursive: true })
await symlink(new URL('../lib', import.meta.url).pathname, join(root, 'container/platform/lib'))
await symlink(new URL('../tools', import.meta.url).pathname, join(root, 'container/platform/tools'))
await writeFile(scriptPath, await readFile(new URL('../../../scripts/bump-environment.sh', import.meta.url)))
await chmod(scriptPath, 0o755)
await writeFile(definitionPath, `${JSON.stringify({ version: environment, bootstrapApi: 1 }, null, 2)}\n`)
await writeFile(targetPath, `${JSON.stringify({
schema: 1,
latestSupportedDsh: '9.8.7-rc.6',
environment,
}, null, 2)}\n`)
return { definitionPath, root, scriptPath, targetPath }
}
function run(paths, version) {
return spawnSync(paths.scriptPath, [version], { cwd: paths.root, encoding: 'utf8' })
}
test('bumps both authoritative Environment versions and is idempotent', async () => {
const paths = await fixture()
let result = run(paths, '2.4.0')
assert.equal(result.status, 0, result.stderr)
assert.deepEqual(JSON.parse(result.stdout), { changed: true, previousVersion: '2.3.4', version: '2.4.0' })
assert.equal(JSON.parse(await readFile(paths.definitionPath, 'utf8')).version, '2.4.0')
const target = JSON.parse(await readFile(paths.targetPath, 'utf8'))
assert.equal(target.environment, '2.4.0')
assert.equal(target.latestSupportedDsh, '9.8.7-rc.6')
result = run(paths, '2.4.0')
assert.equal(result.status, 0, result.stderr)
assert.deepEqual(JSON.parse(result.stdout), { changed: false, version: '2.4.0' })
})
test('rejects invalid, rollback, and mismatched Environment versions without writing', async () => {
const paths = await fixture()
let result = run(paths, 'not-a-version')
assert.notEqual(result.status, 0)
assert.match(result.stderr, /semantic version/)
result = run(paths, '2.3.3')
assert.notEqual(result.status, 0)
assert.match(result.stderr, /roll back/)
assert.equal(JSON.parse(await readFile(paths.definitionPath, 'utf8')).version, '2.3.4')
assert.equal(JSON.parse(await readFile(paths.targetPath, 'utf8')).environment, '2.3.4')
await writeFile(paths.targetPath, `${JSON.stringify({
schema: 1,
latestSupportedDsh: '9.8.7-rc.6',
environment: '2.3.3',
}, null, 2)}\n`)
result = run(paths, '2.4.0')
assert.notEqual(result.status, 0)
assert.match(result.stderr, /does not match/)
})
@@ -0,0 +1,73 @@
import assert from 'node:assert/strict'
import { mkdtemp } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { ChannelStateStore, planDesiredState } from '../../control-plane/modules/updater/lib/channel-state.mjs'
const current = { dsh: '0.1.0-rc.7', environment: 'env-1', runtime: 'runtime-a' }
const supported = { dsh: '0.1.0-rc.7', environment: 'env-1' }
test('persists channel selection and retryable version or combination Holds', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-channel-state-'))
const store = new ChannelStateStore(join(root, 'channel.json'), () => new Date('2026-08-19T00:00:00.000Z'))
assert.equal((await store.read()).updateChannel, 'stable')
await store.setChannel('experimental')
const version = await store.addHold({ type: 'version', dshVersion: '0.1.0-rc.8', reason: 'build failed' })
const combination = await store.addHold({
type: 'combination', dshVersion: '0.1.0-rc.9', environmentVersion: 'env-1', reason: 'health failed',
})
assert.deepEqual((await store.read()).holds.map(hold => hold.type), ['version', 'combination'])
await store.retry(version.id)
assert.deepEqual((await store.read()).holds.map(hold => hold.id), [combination.id])
})
test('plans Stable convergence before Experimental and freezes Ahead-of-Stable combinations', () => {
const local = { updateChannel: 'experimental', holds: [], experimentalBlocked: null }
assert.equal(planDesiredState({
local, current: { ...current, environment: 'env-old' }, supported,
upstream: { version: '0.1.0-rc.8' },
}).action, 'stable')
assert.equal(planDesiredState({
local, current: { ...current, dsh: '0.1.0-rc.8' }, supported,
upstream: { version: '0.1.0-rc.9' },
}).action, 'frozen')
assert.equal(planDesiredState({ local, current, supported, upstream: { version: '0.1.0-rc.8' } }).action, 'experimental')
assert.equal(planDesiredState({
local,
current: { ...current, authority: 'development', targetSequence: 0 },
supported, stableTargetSequence: 11,
upstream: { version: '0.1.0-rc.8' },
}).action, 'stable')
assert.equal(planDesiredState({
local,
current: { ...current, authority: 'stable', targetSequence: 11 },
supported, stableTargetSequence: 11,
upstream: { version: '0.1.0-rc.8' },
}).action, 'experimental')
})
test('suppresses only the held Experimental candidate and Environment combination', () => {
const local = {
updateChannel: 'experimental',
experimentalBlocked: null,
holds: [{
id: 'hold', type: 'combination', dshVersion: '0.1.0-rc.8', environmentVersion: 'env-1',
reason: 'incompatible', createdAt: '2026-08-19T00:00:00.000Z',
}],
}
const plan = planDesiredState({ local, current, supported, upstream: { version: '0.1.0-rc.8' } })
assert.equal(plan.action, 'held')
assert.equal(plan.hold.id, 'hold')
})
test('retries an Experimental Block independently of ordinary Holds', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-channel-block-'))
const store = new ChannelStateStore(join(root, 'channel.json'), () => new Date('2026-08-19T00:00:00.000Z'))
const blocked = await store.block({
dshVersion: '0.1.0-rc.8', environmentVersion: 'env-2', reason: 'combination failed',
})
assert.equal((await store.read()).experimentalBlocked.id, blocked.experimentalBlocked.id)
await store.retry(blocked.experimentalBlocked.id)
assert.equal((await store.read()).experimentalBlocked, null)
})
@@ -0,0 +1,233 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
test('container smoke targets ephemeral views and the separated persistent layout', async () => {
const script = await readFile(new URL('../../test/container-smoke.sh', import.meta.url), 'utf8')
assert.match(script, /\/run\/dsh-platform\/views\/runtime/)
assert.match(script, /\/run\/dsh-platform\/bootstrap\.sock/)
assert.match(script, /\/data\/platform\/state\/updater\/transaction\.json/)
assert.match(script, /\/data\/platform\/store\/snapshots/)
assert.match(script, /recovery\.sock/)
assert.match(script, /dsh-platform restart/)
assert.match(script, /dsh-platform stop/)
assert.match(script, /dsh web --no-open/)
assert.match(script, /requested managed DSH start/)
assert.match(script, /bundled-plugins\/action/)
assert.match(script, /"action":"uninstall"/)
assert.match(script, /managed by the platform/)
assert.match(script, /\.dshLifecycle\.taskId == \$task and \.dshLifecycle\.state == "running"/)
assert.match(script, /stage0_pid/)
assert.match(script, /\.source == "stage0" and \.message == "stage0\.ready"/)
assert.match(script, /\.source == "bootstrap" and \.message == "platform\.ready"/)
assert.match(script, /\.source == "gateway" and \.message == "gateway\.ready"/)
assert.match(script, /dsh_pid/)
assert.match(script, /kill -9 "\$dsh_pid"/)
assert.match(script, /managed-lifecycle-restart-smoke\.mjs/)
assert.match(script, /\.helperExitCode == 0 and \.sawRestarting == true and \.dshCount == 1/)
assert.match(script, /\.dshLifecycle\.state == "running" and \.recoveryMode == null/)
assert.match(script, /DSH recovered after an explicit stop/)
assert.match(script, /\.RestartCount/)
assert.match(script, /gateway\.upstream\.failed/)
assert.match(script, /gateway\.upstream\.recovered/)
assert.match(script, /standalone-recovery-smoke\.mjs/)
assert.match(script, /standalone-file-management-smoke\.mjs/)
assert.match(script, /profile-package-compatibility-smoke\.sh/)
assert.match(script, /--group-add dsh-sudo-false/)
assert.match(script, /sudo -n true/)
assert.match(script, /--unix-socket \/run\/dsh-platform\/maintenance\.sock/)
assert.match(script, /file-task\.copy\.completed/)
assert.match(script, /files\.content\.saved/)
assert.match(script, /runtime\.reset\.completed/)
assert.match(script, /runtime-reset-sentinel/)
assert.match(script, /terminal\.session\.created/)
assert.match(script, /user-plugin\.apply\.completed/)
assert.match(script, /readiness_timeout_ms=30000/)
assert.match(script, /platform readiness exceeded 30 seconds/)
assert.match(script, /DSH orphaned-bundle restart did not complete within the readiness timeout/)
assert.match(script, /DSH started before interrupted update recovery completed/)
assert.doesNotMatch(script, /echo "DSH restart did not complete"/)
assert.match(script, /clear only \/data\/platform/)
assert.match(script, /Do not delete \/data\/dsh/)
assert.doesNotMatch(script, /\/data\/platform\/(?:runtime|environments|system-plugins|bootstrap|run)\//)
})
test('Bootstrap resolves update and User Plugin recovery before concurrent startup', async () => {
const bootstrap = await readFile(new URL('../bootstrap/index.mjs', import.meta.url), 'utf8')
const updateRecovery = bootstrap.indexOf('await recoverPlatformUpdateBeforeDshStart(')
const userPluginRecovery = bootstrap.indexOf('await recoverUserPluginBeforeDshStart(')
const runtimeStart = bootstrap.indexOf('await runtime.start({')
assert.ok(updateRecovery >= 0)
assert.ok(userPluginRecovery > updateRecovery)
assert.ok(runtimeStart > userPluginRecovery)
})
test('Profile compatibility smoke migrates old stores and preserves node ownership', async () => {
const script = await readFile(new URL('../../test/profile-package-compatibility-smoke.sh', import.meta.url), 'utf8')
assert.match(script, /dsh-platform stop --wait/)
assert.match(script, /pnpm install --offline --frozen-lockfile/)
assert.match(script, /dsh-platform start --wait/)
assert.match(script, /npm_config_userconfig=\/root\/\.config\/npm\/npmrc/)
assert.match(script, /dsh plugin --profile web add/)
assert.match(script, /stat -c %U/)
assert.match(script, /dsh plugin --profile web remove/)
})
test('the public DSH shim keeps Profile operations under the node identity', async () => {
const script = await readFile(new URL('../tools/dsh-shim.sh', import.meta.url), 'utf8')
assert.match(script, /if \[ "\$\(id -u\)" -eq 0 \]/)
assert.match(script, /--reuid=1000/)
assert.match(script, /--regid=1000/)
assert.match(script, /--keep-groups/)
assert.match(script, /-u npm_config_userconfig/)
assert.match(script, /-u NPM_CONFIG_USERCONFIG/)
assert.match(script, /-u PNPM_HOME/)
assert.match(script, /HOME=\/home\/node/)
assert.match(script, /XDG_CONFIG_HOME=\/home\/node\/\.config/)
assert.match(script, /XDG_STATE_HOME=\/home\/node\/\.local\/state/)
assert.match(script, /DSH_HOME="\$\{DSH_HOME:-\/data\/dsh\}"/)
assert.doesNotMatch(script, /HOME=\/root|XDG_CONFIG_HOME=\/root/)
})
test('managed lifecycle smoke rejects replacement instances and converts SIGTERM into restart', async () => {
const script = await readFile(new URL('../../test/managed-lifecycle-restart-smoke.mjs', import.meta.url), 'utf8')
assert.match(script, /spawn\(DSH_EXECUTABLE, \['web', '--no-open'\]/)
assert.match(script, /detached: true/)
assert.match(script, /DSH_PLATFORM_LAUNCH_TOKEN: ''/)
assert.match(script, /process\.kill\(oldPid, 'SIGTERM'\)/)
assert.match(script, /unregistered SIGTERM did not create a managed restart task/)
assert.match(script, /newPids\.length === 1/)
assert.doesNotMatch(script, /dsh-market|better-sidebar|net-proxy/)
})
test('standalone file smoke covers recovery-mode transfer, edit, search, symlink, and mutations', async () => {
const script = await readFile(new URL('../../test/standalone-file-management-smoke.mjs', import.meta.url), 'utf8')
assert.match(script, /files\/upload/)
assert.match(script, /range: 'bytes=3-6'/)
assert.match(script, /edited in recovery mode/)
assert.match(script, /operation: 'copy'/)
assert.match(script, /operation: 'move'/)
assert.match(script, /operation: 'delete'/)
assert.match(script, /operation: 'search'/)
assert.match(script, /operation: 'size'/)
assert.match(script, /operation: 'attributes'/)
assert.match(script, /recursive: true/)
assert.match(script, /type, 'symlink'/)
assert.match(script, /\/data\/dsh\/file-management-smoke/)
assert.match(script, /\/root\/dsh-maintenance-smoke/)
assert.match(script, /config\.privileged, true/)
assert.match(script, /\['queued', 'running'\]\.includes\(state\.status\)/)
})
test('standalone recovery smoke covers live terminal and consecutive faulty plugins', async () => {
const script = await readFile(new URL('../../test/standalone-recovery-smoke.mjs', import.meta.url), 'utf8')
assert.match(script, /terminal-before-restart/)
assert.match(script, /terminal-after-restart-中文/)
assert.match(script, /operation\?\.status \?\? operation\?\.state/)
assert.match(script, /uid=0/)
assert.match(script, /cwd=\\\/root/)
assert.match(script, /smoke-fault-one/)
assert.match(script, /smoke-fault-two/)
assert.match(script, /firstOutcome/)
assert.match(script, /userPluginOperation/)
assert.match(script, /recoveryMode === null/)
assert.match(script, /assert\.doesNotMatch\(JSON\.stringify\(logEntries\.filter/)
})
test('Stage-0 owns privileged User Skill mutations behind a constrained local API', async () => {
const [stage0, management, paths] = await Promise.all([
readFile(new URL('../stage0/index.mjs', import.meta.url), 'utf8'),
readFile(new URL('../../control-plane/services/management/index.mjs', import.meta.url), 'utf8'),
readFile(new URL('../lib/paths.mjs', import.meta.url), 'utf8'),
])
assert.match(stage0, /prepareUserSkillRoots, UserSkillManager/)
assert.match(stage0, /new UserSkillManager\(\{ dshHome, agentsHome \}\)/)
assert.match(stage0, /listenUserSkills\(userSkillServer, paths\.userSkillSocket\)/)
assert.match(management, /new LocalApiClient\(paths\.userSkillSocket\)/)
assert.match(management, /configureUserSkill: value => userSkillApi\.request\('POST', '\/v1\/action', value\)/)
assert.match(paths, /this\.userSkillSocket = join\(this\.runRoot, 'user-skills\.sock'\)/)
})
test('isolated service identities can traverse the runtime root without inheriting platform socket access', async () => {
const paths = await readFile(new URL('../lib/paths.mjs', import.meta.url), 'utf8')
const accessLaunch = await readFile(new URL('../stage0/lib/access-launch-server.mjs', import.meta.url), 'utf8')
assert.match(paths, /chmod\(paths\.runRoot, 0o1771\)/)
assert.match(accessLaunch, /'--clear-groups'/)
assert.doesNotMatch(accessLaunch, /--groups=/)
})
test('Docker health reports Gateway control-plane liveness independently of DSH', async () => {
const dockerfile = await readFile(new URL('../../../Dockerfile', import.meta.url), 'utf8')
const healthcheck = dockerfile.split('HEALTHCHECK')[1]?.split('\n\n')[0] ?? ''
assert.match(healthcheck, /--start-period=60s/)
assert.match(healthcheck, /127\.0\.0\.1:3080\/_dsh_gateway\/health/)
assert.doesNotMatch(healthcheck, /127\.0\.0\.1:3079\/|stage0-trust\.sock/)
})
test('Management readiness does not depend on an authenticated management API', async () => {
const component = JSON.parse(await readFile(new URL('../../control-plane/services/management/component.json', import.meta.url)))
assert.equal(component.health.type, 'exec')
assert.equal(component.health.command.executable, '/usr/local/bin/node')
assert.deepEqual(component.health.command.args, [
'/run/dsh-platform/views/bootstrap/control-plane/services/management/healthcheck.mjs',
])
const probe = await readFile(new URL('../../control-plane/services/management/healthcheck.mjs', import.meta.url), 'utf8')
assert.match(probe, /\/_dsh_platform\/internal\/health/)
assert.doesNotMatch(probe, /\/_dsh_platform\/api\/v1/)
})
test('public platform CLI and Gateway status probes use a separate restricted Management socket', async () => {
const [paths, cli, management, gateway] = await Promise.all([
readFile(new URL('../lib/paths.mjs', import.meta.url), 'utf8'),
readFile(new URL('../../control-plane/services/management/cli.mjs', import.meta.url), 'utf8'),
readFile(new URL('../../control-plane/services/management/index.mjs', import.meta.url), 'utf8'),
readFile(new URL('../../control-plane/services/gateway/lib/lifecycle.mjs', import.meta.url), 'utf8'),
])
assert.match(paths, /this\.managementCliSocket = join\(this\.runRoot, 'management-cli\.sock'\)/)
assert.match(cli, /DSH_PLATFORM_MANAGEMENT_CLI_SOCKET.*management-cli\.sock/)
assert.match(management, /restrictedCliRoute/)
assert.match(gateway, /DSH_PLATFORM_MANAGEMENT_CLI_SOCKET.*management-cli\.sock/)
})
test('Docker installs locked Management dependencies inside the Seed stage only', async () => {
const dockerfile = await readFile(new URL('../../../Dockerfile', import.meta.url), 'utf8')
const ignore = await readFile(new URL('../../../.dockerignore', import.meta.url), 'utf8')
const seed = await readFile(new URL('../stage0/lib/seed.mjs', import.meta.url), 'utf8')
const buildSeed = await readFile(new URL('../tools/build-seed.mjs', import.meta.url), 'utf8')
assert.match(dockerfile, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund[\s\S]*--prefix \/opt\/dsh-platform-source\/control-plane\/services\/management/)
assert.match(dockerfile, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps[\s\S]*--prefix \/opt\/dsh-platform-source\/environment\/resources\/plugins\/platform-management\/package/)
assert.match(dockerfile, /util-linux/)
assert.match(dockerfile, /\n\s+g\+\+ \\\n/)
assert.match(dockerfile, /\n\s+make \\\n/)
assert.equal(ignore.split('\n').includes('**/node_modules'), true)
assert.match(seed, /paths\.managementStateRoot/)
assert.match(seed, /paths\.managementStateRoot, paths\.fileTasksRoot/)
assert.match(seed, /paths\.userPluginSnapshotsRoot/)
assert.match(buildSeed, /file-manager/)
const managementManifest = dockerfile.indexOf('COPY container/control-plane/services/management/package.json')
const pluginManifest = dockerfile.indexOf('COPY container/environment/resources/plugins/platform-management/package/package.json')
const dependencyInstall = dockerfile.indexOf('RUN npm ci --omit=dev --ignore-scripts --no-audit --no-fund')
const sourceCopy = dockerfile.indexOf('COPY container /opt/dsh-platform-source')
assert.ok(managementManifest >= 0 && pluginManifest > managementManifest)
assert.ok(dependencyInstall > pluginManifest && sourceCopy > dependencyInstall)
})
test('local Docker builds resolve the default DSH from the supported target without a sticky latest cache', async () => {
const dockerfile = await readFile(new URL('../../../Dockerfile', import.meta.url), 'utf8')
assert.match(dockerfile, /COPY release\/supported-target\.json \/opt\/dsh-supported-target\.json/)
assert.match(dockerfile, /ARG SIGNED_IMAGE_INPUT=false/)
assert.match(dockerfile, /case "\$SIGNED_IMAGE_INPUT" in[\s\S]*true\)[\s\S]*npm install --global \/opt\/dsh-platform-image-input\/dsh\.tgz[\s\S]*false\)[\s\S]*latestSupportedDsh/)
assert.match(dockerfile, /if \[ "\$requested_version" = latest \]; then[\s\S]*latestSupportedDsh/)
assert.match(dockerfile, /npm install --global "@deepseek-ai\/dsh@\$\{requested_version\}"/)
assert.match(dockerfile, /false\) image_input=-/)
assert.doesNotMatch(dockerfile, /if \[ -f \/opt\/dsh-platform-(?:image-input|source\/platform\/image-input)/)
})
test('formal images identify DSH, Environment, target sequence, and the signed update channel', async () => {
const dockerfile = await readFile(new URL('../../../Dockerfile', import.meta.url), 'utf8')
assert.match(dockerfile, /org\.opencontainers\.image\.version="\$DSH_VERSION"/)
assert.match(dockerfile, /io\.dsh-docker\.environment\.version="\$ENVIRONMENT_VERSION"/)
assert.match(dockerfile, /io\.dsh-docker\.target-sequence="\$TARGET_SEQUENCE"/)
assert.match(dockerfile, /DSH_UPDATE_METADATA_URL=https:\/\/raw\.githubusercontent\.com\/yjrszcq\/dsh-docker\/release-channel\//)
assert.doesNotMatch(dockerfile, /releases\/latest\/download/)
})
@@ -0,0 +1,197 @@
import assert from 'node:assert/strict'
import { generateKeyPairSync } from 'node:crypto'
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import { canonicalJson } from '../lib/canonical-json.mjs'
import { parseBootstrapManifest, parseComponentManifest, parseEnvironmentManifest, parseOfficialDshPolicy, parseStable } from '../lib/contracts.mjs'
import {
deriveImageBuildId,
deriveRecordId,
parseArtifactReference,
parseBootstrapRecord,
parseDeploymentRecord,
parseImageInventory,
parseSlots,
recordsFromImageInventory,
} from '../lib/deployment-contracts.mjs'
import { verifyDetached } from '../stage0/lib/signature.mjs'
import { document, officialDshPolicy, registryKeyPair, target } from './helpers.mjs'
const common = manifestType => ({
schema: 1,
manifestType,
version: manifestType === 'bootstrap' ? '1.0.0' : '1.0.0',
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-19T00:00:00.000Z',
artifacts: [],
})
const lifecycle = {
prepare: null,
preStart: null,
postStart: null,
preStop: null,
stop: null,
postStop: null,
}
test('canonical JSON recursively orders keys and rejects unsafe numbers', () => {
assert.equal(canonicalJson({ z: 1, a: { y: 2, x: 3 } }).toString(), '{"a":{"x":3,"y":2},"z":1}\n')
assert.throws(() => canonicalJson({ value: 1.5 }))
})
function imageInventory(overrides = {}) {
const content = {
schema: 1,
authority: 'stable',
platformRevision: 'fixture-revision',
targetSequence: 10,
bootstrapApi: 1,
updateApi: 1,
bootstrap: { version: '1.0.0', id: 'bootstrap-fixture', sha256: '1'.repeat(64) },
deployment: {
id: 'deployment-fixture',
dshVersion: '0.1.0-rc.10',
environmentVersion: '1.0.0',
environment: { id: 'environment-fixture', sha256: '2'.repeat(64) },
pristine: { id: 'pristine-fixture', sha256: '3'.repeat(64) },
runtime: { id: 'runtime-fixture', sha256: '4'.repeat(64) },
systemPlugins: { id: 'system-plugins-fixture', sha256: '5'.repeat(64) },
},
...overrides,
}
return { ...content, imageBuildId: deriveImageBuildId(content) }
}
test('parses content-bound image inventory and derives immutable image Records', () => {
const inventory = parseImageInventory(document(imageInventory()))
const records = recordsFromImageInventory(inventory)
assert.match(inventory.imageBuildId, /^sha256:[a-f0-9]{64}$/)
assert.equal(records.bootstrap.version, '1.0.0')
assert.equal(records.deployment.runtime.imageBuildId, inventory.imageBuildId)
assert.equal(records.deployment.targetSequence, 10)
assert.doesNotThrow(() => parseBootstrapRecord(records.bootstrap))
assert.doesNotThrow(() => parseDeploymentRecord(records.deployment))
const changed = imageInventory({ platformRevision: 'different-revision' })
assert.notEqual(changed.imageBuildId, inventory.imageBuildId)
assert.throws(() => parseImageInventory(document({ ...imageInventory(), targetSequence: 11 })), /imageBuildId/)
})
test('restricts inventory authority and Artifact References without accepting paths', () => {
const development = imageInventory({ authority: 'development', targetSequence: 0 })
development.imageBuildId = deriveImageBuildId(Object.fromEntries(Object.entries(development).filter(([key]) => key !== 'imageBuildId')))
assert.equal(parseImageInventory(document(development)).targetSequence, 0)
assert.throws(() => parseImageInventory(document(imageInventory({ authority: 'development' }))), /targetSequence 0/)
assert.throws(() => parseArtifactReference({
storage: 'store', kind: 'runtime', id: '../escape', sha256: 'a'.repeat(64),
}), /invalid/)
assert.throws(() => parseArtifactReference({
storage: 'store', kind: 'runtime', id: 'runtime-one', sha256: 'a'.repeat(64), path: '/tmp/runtime',
}), /fields/)
assert.throws(() => parseArtifactReference({
storage: 'image', imageBuildId: `sha256:${'b'.repeat(64)}`, kind: 'unknown', id: 'one', sha256: 'a'.repeat(64),
}), /kind/)
})
test('rejects mutated Records and invalid atomic slot generations', () => {
const { bootstrap, deployment } = recordsFromImageInventory(parseImageInventory(document(imageInventory())))
assert.throws(() => parseDeploymentRecord({ ...deployment, dshVersion: 'changed' }), /canonical content/)
assert.throws(() => parseBootstrapRecord({ ...bootstrap, artifact: { ...bootstrap.artifact, id: 'changed' } }), /canonical content/)
assert.deepEqual(parseSlots({
schema: 1, generation: 2, current: deployment.id, previous: null,
}, 'deployment-record'), {
schema: 1, generation: 2, current: deployment.id, previous: null,
})
assert.throws(() => parseSlots({
schema: 1, generation: 0, current: deployment.id, previous: null,
}, 'deployment-record'), /positive/)
assert.throws(() => parseSlots({
schema: 1, generation: 1, current: deployment.id, previous: deployment.id,
}, 'deployment-record'), /must differ/)
const content = { schema: 1, authority: 'development' }
assert.equal(deriveRecordId('fixture', content), deriveRecordId('fixture', { authority: 'development', schema: 1 }))
})
test('parses the exact stable desired state and rejects missing referenced Artifacts', () => {
const parsed = parseStable(document(target(1, 1)))
assert.equal(parsed.desired.dsh.version, '0.1.0-rc.7')
const invalid = target(1, 1)
invalid.desired.bootstrap.manifestArtifactId = 'missing'
assert.throws(() => parseStable(document(invalid)), /missing/)
assert.throws(() => parseStable(document({ ...target(1, 1), unknown: true })), /fields/)
})
test('parses the Release-delegated official DSH policy with Stable schema 1', () => {
const policy = officialDshPolicy(registryKeyPair())
assert.equal(parseOfficialDshPolicy(policy).packageName, '@deepseek-ai/dsh')
assert.equal(parseStable(document(target(1, 1, policy))).officialDshPolicy.keys[0].keyId, policy.keys[0].keyId)
const wrongRegistry = { ...policy, registry: 'https://registry.example/' }
assert.throws(() => parseOfficialDshPolicy(wrongRegistry), /official npm registry/)
})
test('parses bootstrap and environment manifests with ordered references', () => {
const bootstrap = { ...common('bootstrap'), bootstrapApi: 1, entrypoint: '/opt/bootstrap/index.mjs' }
assert.equal(parseBootstrapManifest(document(bootstrap)).entrypoint, bootstrap.entrypoint)
const hashes = {
component: '1'.repeat(64),
patch: '2'.repeat(64),
plugin: '3'.repeat(64),
}
const environment = {
...common('environment'),
artifacts: Object.entries(hashes).map(([id, sha256]) => ({
id,
mediaType: 'application/octet-stream',
sha256,
size: 1,
url: `https://release.example/${id}`,
})),
bootstrapApi: 1,
components: [{ id: 'gateway', sha256: hashes.component }],
patches: [{ id: 'directory-picker', sha256: hashes.patch }],
systemPlugins: [{ id: 'update-ui', sha256: hashes.plugin }],
}
assert.equal(parseEnvironmentManifest(document(environment)).components[0].id, 'gateway')
assert.throws(() => parseEnvironmentManifest(document({ ...environment, components: [...environment.components, environment.components[0]] })), /unique/)
})
test('parses service, oneshot, and hook component lifecycle declarations', () => {
const value = {
schema: 1,
id: 'gateway',
type: 'service',
command: { executable: '/usr/local/bin/node', args: ['/opt/gateway/index.mjs'], timeoutSeconds: 30 },
environment: { PLATFORM_SOCKET: '/data/platform/run/platform.sock' },
lifecycle,
health: { type: 'http', host: '127.0.0.1', port: 3080, path: '/health', intervalSeconds: 1, timeoutSeconds: 5 },
logging: { stdout: true, stderr: true },
}
assert.equal(parseComponentManifest(document(value)).type, 'service')
assert.throws(() => parseComponentManifest(document({ ...value, version: '1.0.0' })), /fields/)
assert.throws(() => parseComponentManifest(document({ ...value, type: 'unknown' })), /type/)
assert.throws(() => parseComponentManifest(document({ ...value, command: { ...value.command, executable: 'node' } })), /absolute/)
})
test('offline signing tool emits a signature accepted by Stage-0', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-sign-tool-'))
const pair = generateKeyPairSync('ed25519')
const privatePath = join(root, 'private.pem')
const documentPath = join(root, 'document.json')
const signaturePath = join(root, 'document.sig.json')
await writeFile(privatePath, pair.privateKey.export({ format: 'pem', type: 'pkcs8' }), { mode: 0o600 })
const bytes = canonicalJson({ stable: true })
await writeFile(documentPath, bytes)
const result = spawnSync(process.execPath, [
new URL('../tools/sign.mjs', import.meta.url).pathname,
'sign', privatePath, documentPath, signaturePath,
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const publicKey = pair.publicKey.export({ format: 'der', type: 'spki' }).toString('base64')
const signature = JSON.parse(await readFile(signaturePath, 'utf8'))
assert.doesNotThrow(() => verifyDetached(bytes, signature, publicKey))
})
@@ -0,0 +1,953 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { chmod, lstat, mkdtemp, mkdir, readFile, readdir, readlink, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { DeploymentManager, DeploymentResolutionError } from '../bootstrap/lib/deployments.mjs'
import { PlatformGarbageCollector } from '../bootstrap/lib/gc.mjs'
import { canonicalJson } from '../lib/canonical-json.mjs'
import {
deriveImageBuildId,
deriveRecordId,
parseDeploymentRecord,
parseImageInventory,
recordsFromImageInventory,
} from '../lib/deployment-contracts.mjs'
import { PlatformPaths, preparePersistentLayout, resetRuntimeLayout } from '../lib/paths.mjs'
import { hashTree } from '../lib/tree-hash.mjs'
import { buildRuntime } from '../../control-plane/modules/patch-manager/index.mjs'
const kinds = ['environment', 'pristine', 'runtime', 'system-plugins']
async function fixture({
root,
paths,
authority = 'stable',
targetSequence = 1,
marker = 'image',
} = {}) {
root ??= await mkdtemp(join(tmpdir(), 'dsh-deployments-'))
paths ??= new PlatformPaths(join(root, 'data'), join(root, 'run'))
const seedRoot = join(root, `seed-${marker}`)
const assets = {}
for (const kind of kinds) {
const plural = kind === 'environment' ? 'environments' : kind === 'runtime' ? 'runtimes' : kind
const id = `image-${kind}-${marker}`
const path = join(seedRoot, plural, id)
await mkdir(path, { recursive: true })
await writeFile(join(path, 'sentinel'), `${kind}:${marker}`)
assets[kind] = { id, sha256: await hashTree(path) }
}
const content = {
schema: 1,
authority,
platformRevision: `deployment-fixture-${marker}`,
targetSequence,
bootstrapApi: 1,
updateApi: 1,
bootstrap: { version: '1.0.0', id: 'bootstrap', sha256: 'a'.repeat(64) },
deployment: {
id: `image-deployment-${marker}`,
dshVersion: '0.1.0-rc.1',
environmentVersion: '1.0.0',
environment: assets.environment,
pristine: assets.pristine,
runtime: assets.runtime,
systemPlugins: assets['system-plugins'],
},
}
const inventory = parseImageInventory({ ...content, imageBuildId: deriveImageBuildId(content) })
await preparePersistentLayout(paths)
await resetRuntimeLayout(paths)
const manager = new DeploymentManager({ paths, seedRoot, inventory })
return { root, seedRoot, paths, inventory, manager, image: recordsFromImageInventory(inventory).deployment }
}
async function repairableFixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-reset-'))
const paths = new PlatformPaths(join(root, 'data'), join(root, 'run'))
const seedRoot = join(root, 'seed')
const pristineRoot = join(seedRoot, 'pristine', 'dsh')
const environmentRoot = join(seedRoot, 'environments', 'environment')
const runtimeRoot = join(seedRoot, 'runtimes', 'dsh')
const systemPluginsRoot = join(seedRoot, 'system-plugins', 'environment')
await mkdir(join(pristineRoot, 'lib'), { recursive: true })
await mkdir(join(environmentRoot, 'artifacts'), { recursive: true })
await mkdir(systemPluginsRoot, { recursive: true })
await writeFile(join(pristineRoot, 'lib', 'bin.js'), '#!/usr/bin/env node\n')
const patch = [
"import { readFile, writeFile } from 'node:fs/promises'",
"import { join } from 'node:path'",
"export async function applyPatch(root) { await writeFile(join(root, 'patched.txt'), 'patched\\n') }",
"export async function verifyPatch(root) { if (await readFile(join(root, 'patched.txt'), 'utf8') !== 'patched\\n') throw new Error('patch missing') }",
'',
].join('\n')
const patchBytes = Buffer.from(patch)
const patchSha256 = createHash('sha256').update(patchBytes).digest('hex')
await writeFile(join(environmentRoot, 'artifacts', 'runtime-patch'), patchBytes)
await writeFile(join(environmentRoot, 'environment.manifest.json'), JSON.stringify({
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-20T00:00:00.000Z',
artifacts: [{
id: 'runtime-patch',
mediaType: 'text/javascript',
sha256: patchSha256,
size: patchBytes.byteLength,
url: 'https://example.invalid/runtime-patch',
}],
bootstrapApi: 1,
components: [],
patches: [{ id: 'runtime-patch', sha256: patchSha256 }],
systemPlugins: [],
}))
await buildRuntime({
pristineRoot,
versionsRoot: join(seedRoot, 'runtimes'),
runtimeId: 'dsh',
patchPaths: [join(environmentRoot, 'artifacts', 'runtime-patch')],
})
const assets = {
environment: { id: 'environment', sha256: await hashTree(environmentRoot) },
pristine: { id: 'dsh', sha256: await hashTree(pristineRoot) },
runtime: { id: 'dsh', sha256: await hashTree(runtimeRoot) },
systemPlugins: { id: 'environment', sha256: await hashTree(systemPluginsRoot) },
}
const content = {
schema: 1,
authority: 'development',
platformRevision: 'runtime-reset-fixture',
targetSequence: 0,
bootstrapApi: 1,
updateApi: 1,
bootstrap: { version: '1.0.0', id: 'bootstrap', sha256: 'a'.repeat(64) },
deployment: {
id: 'image-deployment-runtime-reset',
dshVersion: '0.1.0-rc.1',
environmentVersion: '1.0.0',
...assets,
},
}
const inventory = parseImageInventory({ ...content, imageBuildId: deriveImageBuildId(content) })
await preparePersistentLayout(paths)
await resetRuntimeLayout(paths)
const manager = new DeploymentManager({ paths, seedRoot, inventory })
const image = recordsFromImageInventory(inventory).deployment
await manager.initialize(image)
return { root, paths, seedRoot, manager, image, environmentRoot }
}
async function managedRecord(
context,
suffix,
sequence = 2,
authority = 'stable',
dshVersion = `0.1.0-rc.${String(sequence)}`,
receiptTokens = [],
) {
const references = {}
for (const kind of kinds) {
const root = kind === 'environment'
? context.paths.environmentsRoot
: kind === 'pristine'
? context.paths.pristineRoot
: kind === 'runtime'
? context.paths.runtimesRoot
: context.paths.systemPluginsRoot
const id = `managed-${kind}-${suffix}`
const path = join(root, id)
await mkdir(path, { recursive: true })
await writeFile(join(path, 'sentinel'), `${kind}:${suffix}`)
references[kind] = { storage: 'store', kind, id, sha256: await hashTree(path) }
}
const content = {
schema: 1,
authority,
targetSequence: sequence,
dshVersion,
environmentVersion: '1.0.0',
environment: references.environment,
pristine: references.pristine,
runtime: references.runtime,
systemPlugins: references['system-plugins'],
receiptTokens,
snapshotId: null,
}
return parseDeploymentRecord({ ...content, id: deriveRecordId('deployment-record', content) })
}
async function experimentalRecord(context, from, suffix, dshVersion, receiptTokens = []) {
const built = await managedRecord(context, suffix, from.targetSequence, 'experimental', dshVersion, receiptTokens)
const content = {
...built,
environmentVersion: from.environmentVersion,
environment: from.environment,
systemPlugins: from.systemPlugins,
}
delete content.id
return parseDeploymentRecord({ ...content, id: deriveRecordId('deployment-record', content) })
}
test('initializes an Image Deployment through one atomic runtime view', async () => {
const context = await fixture()
const state = await context.manager.initialize(context.image)
assert.equal(state.current, context.image.id)
assert.equal(state.previous, null)
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
assert.match(await readlink(context.paths.deploymentView), new RegExp(`${context.image.id}$`))
assert.equal(
await readlink(join(context.paths.viewsRoot, 'system-plugins')),
join('..', 'system-plugin-views', 'current'),
)
assert.equal(
await readlink(join(context.paths.systemPluginViewsRoot, 'current')),
join(context.paths.deploymentView, 'system-plugins'),
)
assert.equal((await context.manager.selected()).record.id, context.image.id)
const status = await context.manager.publishStatus()
assert.equal(status.platformLayout, 1)
assert.equal(status.imageBaseline.imageBuildId, context.inventory.imageBuildId)
assert.equal(status.current.recordId, context.image.id)
assert.equal(status.current.source, 'image')
assert.equal(status.recoveryMode, null)
})
test('rebuilds image and managed Runtime bytes without changing versions or previous Deployment', async () => {
const context = await repairableFixture()
let pauses = 0
let restarts = 0
const reset = () => context.manager.resetCurrentRuntime({
pauseDsh: async () => { pauses += 1 },
restartDsh: async () => {
restarts += 1
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'package', 'patched.txt'), 'utf8'), 'patched\n')
},
})
const first = await reset()
assert.notEqual(first.recordId, context.image.id)
assert.equal(first.slots.previous, null)
const repaired = await context.manager.record(first.recordId)
assert.equal(repaired.runtime.storage, 'store')
assert.equal(repaired.dshVersion, context.image.dshVersion)
assert.equal(repaired.environmentVersion, context.image.environmentVersion)
assert.deepEqual(await readdir(context.paths.runtimesRoot), [repaired.runtime.id])
const materialized = await context.manager.materializeCurrent()
assert.equal(materialized.runtime.storage, 'store')
assert.notEqual(materialized.id, repaired.id)
assert.equal(materialized.runtime.id, repaired.runtime.id)
assert.equal((await context.manager.state()).previous, null)
const managedRuntime = join(context.paths.runtimesRoot, materialized.runtime.id)
await writeFile(join(managedRuntime, 'package', 'patched.txt'), 'corrupt-again\n')
const second = await reset()
assert.equal(second.recordId, materialized.id)
assert.equal(second.slots.previous, null)
assert.equal(await hashTree(managedRuntime), materialized.runtime.sha256)
assert.equal(pauses, 2)
assert.equal(restarts, 2)
await writeFile(join(managedRuntime, 'package', 'patched.txt'), 'runtime-before-failed-reset\n')
let failedResetRestarts = 0
await assert.rejects(context.manager.resetCurrentRuntime({
pauseDsh: async () => { pauses += 1 },
restartDsh: async () => {
failedResetRestarts += 1
const content = await readFile(join(context.paths.viewsRoot, 'runtime', 'package', 'patched.txt'), 'utf8')
if (failedResetRestarts === 1) {
assert.equal(content, 'patched\n')
throw new Error('repaired Runtime failed to start')
}
assert.equal(content, 'runtime-before-failed-reset\n')
},
}), /repaired Runtime failed to start/)
assert.equal(failedResetRestarts, 2)
assert.equal(await readFile(join(managedRuntime, 'package', 'patched.txt'), 'utf8'), 'runtime-before-failed-reset\n')
assert.deepEqual(await context.manager.state(), second.slots)
await writeFile(join(context.paths.environmentsRoot, materialized.environment.id, 'artifacts', 'runtime-patch'), 'corrupt artifact\n')
await assert.rejects(reset(), /differs from (?:its Record|the Environment Manifest)/)
assert.equal(pauses, 3)
assert.equal(restarts, 2)
})
test('updates a runtime operation without replacing deployment identity fields', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const before = await context.manager.publishStatus({ recoveryMode: 'diagnostic-state' })
const restarting = await context.manager.setOperation('restarting')
assert.deepEqual(restarting, { ...before, operation: 'restarting' })
const ready = await context.manager.setOperation(null)
assert.deepEqual(ready, before)
})
test('commits a complete managed Deployment only after candidate health succeeds', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await context.manager.writeRecord(await managedRecord(context, 'next'))
let observed
const state = await context.manager.activate(candidate.id, async () => {
observed = await Promise.all(kinds.map(kind => readFile(join(context.paths.deploymentView, kind, 'sentinel'), 'utf8')))
})
assert.deepEqual(observed, kinds.map(kind => `${kind}:next`))
assert.equal(state.current, candidate.id)
assert.equal(state.previous, context.image.id)
})
test('restores the prior complete view and leaves slots unchanged when health fails', async () => {
const context = await fixture()
const before = await context.manager.initialize(context.image)
const candidate = await context.manager.writeRecord(await managedRecord(context, 'broken'))
await assert.rejects(context.manager.activate(candidate.id, async () => {
const value = await readFile(join(context.paths.deploymentView, 'runtime', 'sentinel'), 'utf8')
if (value === 'runtime:broken') throw new Error('candidate unhealthy')
}), /candidate unhealthy/)
assert.deepEqual(await context.manager.state(), before)
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
})
test('rejects modified managed content and stale Image References', async () => {
const context = await fixture()
const candidate = await context.manager.writeRecord(await managedRecord(context, 'tampered'))
await writeFile(join(context.paths.runtimesRoot, candidate.runtime.id, 'sentinel'), 'changed')
await assert.rejects(context.manager.prepareView(candidate.id), /content hash differs/)
await context.manager.writeRecord(context.image)
const changedContent = { ...context.inventory.document, platformRevision: 'new-image' }
delete changedContent.imageBuildId
const changedInventory = parseImageInventory({ ...changedContent, imageBuildId: deriveImageBuildId(changedContent) })
const changedManager = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: changedInventory })
await assert.rejects(changedManager.prepareView(context.image.id), /different image/)
})
test('writes immutable Deployment Record bytes', async () => {
const context = await fixture()
await context.manager.writeRecord(context.image)
assert.deepEqual(
await readFile(context.manager.recordPath(context.image.id)),
canonicalJson(context.image),
)
})
test('materializes an Image Deployment as a complete Managed previous state', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const materialized = await context.manager.materializeCurrent()
assert.notEqual(materialized.id, context.image.id)
assert.equal(materialized.dshVersion, context.image.dshVersion)
for (const field of ['environment', 'pristine', 'runtime', 'systemPlugins']) {
assert.equal(materialized[field].storage, 'store')
const resolved = await context.manager.resolveReference(materialized[field])
assert.equal((await lstat(resolved)).isDirectory(), true)
}
assert.equal((await context.manager.state()).current, materialized.id)
})
test('advances to a newer image only after startup acceptance', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const nextContent = {
...context.inventory.document,
platformRevision: 'deployment-fixture-next',
targetSequence: 2,
}
delete nextContent.imageBuildId
const nextInventory = parseImageInventory({ ...nextContent, imageBuildId: deriveImageBuildId(nextContent) })
const nextRecord = recordsFromImageInventory(nextInventory).deployment
const restarted = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: nextInventory })
const plan = await restarted.prepareImage(nextRecord)
assert.equal(plan.action, 'image-forward')
assert.equal((await restarted.state()).current, context.image.id)
const state = await restarted.acceptImage(plan)
assert.equal(state.current, nextRecord.id)
assert.equal(state.previous, context.image.id)
})
test('does not advertise a rollback to assets owned by another Docker image', async () => {
const first = await fixture({ targetSequence: 1, marker: 'rollback-first' })
await first.manager.initialize(first.image)
const second = await fixture({
root: first.root,
paths: first.paths,
targetSequence: 2,
marker: 'rollback-second',
})
const plan = await second.manager.prepareImage(second.image)
await second.manager.acceptImage(plan)
const rollback = await second.manager.rollbackPlan()
assert.equal(rollback.current.id, second.image.id)
assert.equal(rollback.previous, null)
})
test('selects the prior Deployment directly after an explicit Docker image rollback', async () => {
const first = await fixture({ targetSequence: 1, marker: 'docker-rollback-first' })
await first.manager.initialize(first.image)
const second = await fixture({
root: first.root,
paths: first.paths,
targetSequence: 2,
marker: 'docker-rollback-second',
})
await second.manager.acceptImage(await second.manager.prepareImage(second.image))
const rolledBack = new DeploymentManager({
paths: first.paths,
seedRoot: first.seedRoot,
inventory: first.inventory,
})
const rollback = await rolledBack.prepareImage(first.image)
assert.equal(rollback.action, 'image-rollback')
assert.equal(rollback.target, first.image.id)
await rolledBack.acceptImage(rollback)
assert.equal((await rolledBack.state()).current, first.image.id)
})
test('rejects an unresolvable newer image candidate and keeps the valid current Deployment', async () => {
const current = await fixture({ targetSequence: 1, marker: 'current' })
await current.manager.initialize(current.image)
const managed = await current.manager.materializeCurrent()
const candidateContent = {
...current.inventory.document,
platformRevision: 'deployment-fixture-candidate-missing',
targetSequence: 2,
}
delete candidateContent.imageBuildId
const inventory = parseImageInventory({
...candidateContent,
imageBuildId: deriveImageBuildId(candidateContent),
})
const candidate = recordsFromImageInventory(inventory).deployment
await rm(join(current.seedRoot, 'runtimes', inventory.deployment.runtime.id), { recursive: true })
const manager = new DeploymentManager({ paths: current.paths, seedRoot: current.seedRoot, inventory })
const plan = await manager.prepareImage(candidate)
assert.equal(plan.action, 'image-rejected')
assert.equal(plan.target, managed.id)
assert.match(plan.candidateError, /ENOENT/)
assert.equal((await manager.selected()).record.id, managed.id)
assert.equal((await manager.state()).current, managed.id)
})
test('commits previous only after an invalid current resolves and previous receipts activate', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const previous = await managedRecord(context, 'previous-valid', 2, 'stable', '0.1.0-rc.2', ['receipt-previous'])
const current = await managedRecord(context, 'current-invalid', 3, 'stable', '0.1.0-rc.3', ['receipt-current'])
await context.manager.activateManaged(previous, { healthCheck: async () => {}, activateReceipts: async () => {} })
await context.manager.activateManaged(current, { healthCheck: async () => {}, activateReceipts: async () => {} })
await rm(join(context.paths.runtimesRoot, current.runtime.id), { recursive: true })
const manager = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: context.inventory })
await assert.rejects(manager.prepareImage(context.image), DeploymentResolutionError)
const plan = await manager.preparePreviousRecovery()
assert.equal((await manager.selected()).record.id, previous.id)
assert.deepEqual(await manager.state(), { schema: 1, generation: 4, current: current.id, previous: previous.id })
const activations = []
await manager.acceptPreviousRecovery(plan, async tokens => { activations.push(tokens) })
assert.deepEqual(activations, [['receipt-previous']])
assert.deepEqual(await manager.state(), { schema: 1, generation: 5, current: previous.id, previous: current.id })
})
test('finishes automatic previous recovery after interruption between receipts and slots', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const previous = await managedRecord(context, 'recovery-interrupted-previous', 2, 'stable', '0.1.0-rc.2', ['receipt-previous'])
const current = await managedRecord(context, 'recovery-interrupted-current', 3, 'stable', '0.1.0-rc.3', ['receipt-current'])
await context.manager.activateManaged(previous, { healthCheck: async () => {}, activateReceipts: async () => {} })
await context.manager.activateManaged(current, { healthCheck: async () => {}, activateReceipts: async () => {} })
const manager = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: context.inventory })
const plan = await manager.preparePreviousRecovery()
manager.commit = async () => { throw new Error('simulated interruption before slots commit') }
await assert.rejects(
manager.acceptPreviousRecovery(plan, async tokens => assert.deepEqual(tokens, ['receipt-previous'])),
/simulated interruption/,
)
assert.equal((await manager.activation()).phase, 'receipts-active')
assert.equal((await manager.state()).current, current.id)
const restarted = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: context.inventory })
const recovered = await restarted.recoverActivation({
activeReceipts: async () => ({ receipts: [{ token: 'receipt-previous' }] }),
activate: async () => { throw new Error('active previous must be completed') },
})
assert.deepEqual(recovered, { action: 'committed', recordId: previous.id })
assert.deepEqual(await restarted.state(), { schema: 1, generation: 5, current: previous.id, previous: current.id })
assert.equal(await restarted.activation(), undefined)
})
test('does not automatically downgrade an unparseable current Deployment Record', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const previous = await managedRecord(context, 'record-valid-previous', 2)
const current = await managedRecord(context, 'record-corrupt-current', 3)
await context.manager.activateManaged(previous, { healthCheck: async () => {}, activateReceipts: async () => {} })
await context.manager.activateManaged(current, { healthCheck: async () => {}, activateReceipts: async () => {} })
await writeFile(context.manager.recordPath(current.id), '{invalid')
const manager = new DeploymentManager({ paths: context.paths, seedRoot: context.seedRoot, inventory: context.inventory })
await assert.rejects(manager.prepareImage(context.image), error => {
assert.equal(error instanceof DeploymentResolutionError, false)
assert.match(error.message, /valid JSON/)
return true
})
await assert.rejects(manager.preparePreviousRecovery(), /valid JSON/)
assert.deepEqual(await manager.state(), { schema: 1, generation: 4, current: current.id, previous: previous.id })
})
test('keeps a newer managed Deployment when the image is behind', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const managed = await context.manager.writeRecord(await managedRecord(context, 'ahead', 3))
await context.manager.activate(managed.id, async () => {})
const plan = await context.manager.prepareImage(context.image)
assert.equal(plan.action, 'retain')
assert.equal(plan.imageBehindCurrent, true)
assert.equal(plan.target, managed.id)
})
test('rejects same-sequence Stable content conflicts', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const conflicting = await context.manager.writeRecord(await managedRecord(context, 'conflict', 1))
await context.manager.activate(conflicting.id, async () => {})
await assert.rejects(context.manager.prepareImage(context.image), /same targetSequence/)
})
test('prefers a same-sequence image when the managed Environment differs only by file mode', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const managed = await context.manager.materializeCurrent()
const environmentPath = await context.manager.resolveReference(managed.environment)
await chmod(join(environmentPath, 'sentinel'), 0o444)
const content = {
...managed,
environment: { ...managed.environment, sha256: await hashTree(environmentPath) },
}
delete content.id
const current = await context.manager.writeRecord({
...content,
id: deriveRecordId('deployment-record', content),
})
await context.manager.commit(current.id, null)
const plan = await context.manager.prepareImage(context.image)
assert.equal(plan.action, 'prefer-image')
assert.equal(plan.target, context.image.id)
})
test('rejects a same-sequence image when the managed Environment content differs', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const managed = await context.manager.materializeCurrent()
const environmentPath = await context.manager.resolveReference(managed.environment)
await writeFile(join(environmentPath, 'sentinel'), 'different environment content')
const content = {
...managed,
environment: { ...managed.environment, sha256: await hashTree(environmentPath) },
}
delete content.id
const current = await context.manager.writeRecord({
...content,
id: deriveRecordId('deployment-record', content),
})
await context.manager.commit(current.id, null)
await assert.rejects(context.manager.prepareImage(context.image), /same targetSequence/)
})
test('replaces a rebuilt development image without retaining stale image slots', async () => {
const first = await fixture({ authority: 'development', targetSequence: 0, marker: 'development-one' })
await first.manager.initialize(first.image)
const rebuilt = await fixture({
root: first.root,
paths: first.paths,
authority: 'development',
targetSequence: 0,
marker: 'development-two',
})
const plan = await rebuilt.manager.prepareImage(rebuilt.image)
assert.equal(plan.action, 'development-refresh')
assert.equal(plan.fallback, null)
assert.equal(await readFile(join(rebuilt.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:development-two')
const state = await rebuilt.manager.acceptImage(plan)
assert.equal(state.current, rebuilt.image.id)
assert.equal(state.previous, null)
})
test('replaces stale formal Image Deployment slots when starting a development image', async () => {
const formal = await fixture({ authority: 'stable', targetSequence: 11, marker: 'formal-eleven' })
await formal.manager.initialize(formal.image)
const development = await fixture({
root: formal.root,
paths: formal.paths,
authority: 'development',
targetSequence: 0,
marker: 'local-rebuild',
})
const plan = await development.manager.prepareImage(development.image)
assert.equal(plan.action, 'development-refresh')
assert.equal(plan.fallback, null)
const state = await development.manager.acceptImage(plan)
assert.equal(state.current, development.image.id)
assert.equal(state.previous, null)
assert.equal(await readFile(join(development.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:local-rebuild')
})
test('replaces stale Managed Deployment assets when starting a compatible development image', async () => {
const formal = await fixture({ authority: 'stable', targetSequence: 11, marker: 'formal-eleven' })
await formal.manager.initialize(formal.image)
const managed = await formal.manager.writeRecord(await managedRecord(
formal,
'managed-eleven',
11,
'stable',
'0.1.0-rc.1',
))
await formal.manager.activate(managed.id, async () => {})
const development = await fixture({
root: formal.root,
paths: formal.paths,
authority: 'development',
targetSequence: 0,
marker: 'local-managed-refresh',
})
const plan = await development.manager.prepareImage(development.image)
assert.equal(plan.action, 'development-refresh')
assert.equal(plan.fallback, null)
const state = await development.manager.acceptImage(plan)
assert.equal(state.current, development.image.id)
assert.equal(state.previous, null)
assert.equal(
await readFile(join(development.paths.viewsRoot, 'system-plugins', 'sentinel'), 'utf8'),
'system-plugins:local-managed-refresh',
)
})
test('preserves Experimental DSH until a Stable image catches up', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const experimental = await context.manager.writeRecord(await managedRecord(
context,
'experimental',
1,
'experimental',
'0.1.0-rc.3',
))
await context.manager.activate(experimental.id, async () => {})
const behindDshContent = {
...context.inventory.document,
platformRevision: 'stable-environment-forward',
targetSequence: 2,
}
delete behindDshContent.imageBuildId
const behindDshInventory = parseImageInventory({
...behindDshContent,
imageBuildId: deriveImageBuildId(behindDshContent),
})
const environmentForward = new DeploymentManager({
paths: context.paths,
seedRoot: context.seedRoot,
inventory: behindDshInventory,
})
const retained = await environmentForward.prepareImage(recordsFromImageInventory(behindDshInventory).deployment)
assert.equal(retained.target, experimental.id)
assert.equal(retained.requiresExperimentalRebuild, true)
const caughtUpContent = structuredClone(behindDshContent)
caughtUpContent.platformRevision = 'stable-caught-up'
caughtUpContent.deployment.dshVersion = '0.1.0-rc.3'
const caughtUpInventory = parseImageInventory({
...caughtUpContent,
imageBuildId: deriveImageBuildId(caughtUpContent),
})
const caughtUpManager = new DeploymentManager({
paths: context.paths,
seedRoot: context.seedRoot,
inventory: caughtUpInventory,
})
const caughtUp = await caughtUpManager.prepareImage(recordsFromImageInventory(caughtUpInventory).deployment)
assert.equal(caughtUp.action, 'stable-caught-up')
assert.notEqual(caughtUp.target, experimental.id)
})
test('activates receipts and commits one complete Managed Deployment transaction', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await managedRecord(context, 'transaction', 2, 'stable', '0.1.0-rc.2', ['candidate-receipt'])
let active = []
const trust = {
activate: async tokens => { active = [...tokens] },
activeReceipts: async () => ({ receipts: active.map(token => ({ token })) }),
}
const slots = await context.manager.activateManaged(candidate, {
healthCheck: async () => {
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:transaction')
},
activateReceipts: tokens => trust.activate(tokens),
})
assert.equal(slots.current, candidate.id)
assert.deepEqual(active, ['candidate-receipt'])
const previous = await context.manager.record(slots.previous)
assert.equal(previous.runtime.storage, 'store')
assert.equal(await context.manager.activation(), undefined)
})
test('rolls back only the exact previous Deployment with receipts and health checks', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await managedRecord(context, 'rollback-target', 2, 'stable', '0.1.0-rc.2', ['candidate-receipt'])
const active = []
await context.manager.activateManaged(candidate, {
healthCheck: async () => {},
activateReceipts: async tokens => active.push([...tokens]),
})
const before = await context.manager.state()
const previous = await context.manager.record(before.previous)
let healthChecks = 0
const rolledBack = await context.manager.rollback({
healthCheck: async () => {
healthChecks += 1
assert.equal(JSON.parse(await readFile(context.paths.deploymentStatusPath, 'utf8')).operation, 'recovering')
},
activateReceipts: async tokens => active.push([...tokens]),
})
assert.equal(rolledBack.current, previous.id)
assert.equal(rolledBack.previous, candidate.id)
assert.deepEqual(active.at(-1), previous.receiptTokens)
assert.equal(healthChecks, 1)
assert.equal(await context.manager.activation(), undefined)
const status = await context.manager.publishStatus()
assert.equal(status.current.recordId, previous.id)
assert.equal(status.operation, null)
})
test('reports an image behind a newly activated Managed Deployment immediately', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await managedRecord(context, 'status-ahead', 2, 'stable', '0.1.0-rc.2')
await context.manager.activateManaged(candidate, {
healthCheck: async () => {},
activateReceipts: async () => {},
})
const status = await context.manager.publishStatus()
assert.equal(status.current.recordId, candidate.id)
assert.equal(status.imageBehindCurrent, true)
})
test('restores the materialized previous Deployment when receipt activation fails', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await managedRecord(context, 'receipt-failure', 2, 'stable', '0.1.0-rc.2', ['candidate-receipt'])
await assert.rejects(context.manager.activateManaged(candidate, {
healthCheck: async () => {},
activateReceipts: async () => { throw new Error('receipt activation failed') },
}), /receipt activation failed/)
const state = await context.manager.state()
assert.notEqual(state.current, context.image.id)
assert.equal((await context.manager.record(state.current)).runtime.storage, 'store')
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
assert.equal(await context.manager.activation(), undefined)
})
test('publishes switching and recovering states around a failed atomic activation', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
await context.manager.publishStatus()
const candidate = await managedRecord(context, 'operation-status', 2, 'stable', '0.1.0-rc.2')
const observed = []
await assert.rejects(context.manager.activateManaged(candidate, {
healthCheck: async () => {
observed.push(JSON.parse(await readFile(context.paths.deploymentStatusPath, 'utf8')).operation)
if (observed.length === 1) throw new Error('candidate failed')
},
activateReceipts: async () => {},
}), /candidate failed/)
assert.deepEqual(observed, ['switching', 'recovering'])
assert.equal(JSON.parse(await readFile(context.paths.deploymentStatusPath, 'utf8')).operation, null)
})
test('turns a failed image recovery operation into an explicit recovery failure', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
await context.manager.publishStatus({ recoveryMode: 'current deployment failed' })
let operation
await assert.rejects(context.manager.recoverImageBaseline(context.image, {
healthCheck: async () => {
const status = JSON.parse(await readFile(context.paths.deploymentStatusPath, 'utf8'))
operation = status.operation
assert.equal(status.recoveryMode, 'current deployment failed')
throw new Error('image recovery health failed')
},
activateReceipts: async () => {},
}), /image recovery health failed/)
assert.equal(operation, 'recovering')
const failed = JSON.parse(await readFile(context.paths.deploymentStatusPath, 'utf8'))
assert.equal(failed.operation, null)
assert.equal(failed.recoveryMode, 'image recovery health failed')
})
test('finishes a journaled activation after receipts became active before restart', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const from = await context.manager.materializeCurrent()
const candidate = await context.manager.writeRecord(await managedRecord(
context,
'resume',
2,
'stable',
'0.1.0-rc.2',
['candidate-receipt'],
))
await context.manager.writeActivation({ phase: 'healthy', from: from.id, to: candidate.id })
const recovered = await context.manager.recoverActivation({
activeReceipts: async () => ({ receipts: [{ token: 'candidate-receipt' }] }),
activate: async () => { throw new Error('active candidate must be completed') },
})
assert.deepEqual(recovered, { action: 'committed', recordId: candidate.id })
assert.equal((await context.manager.state()).current, candidate.id)
assert.equal(await context.manager.activation(), undefined)
})
test('keeps Experimental candidate slots uncommitted through probation and supports cancellation', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await experimentalRecord(
context,
context.image,
'probation',
'0.1.0-rc.2',
['experimental-receipt'],
)
await context.manager.stageCandidate(candidate, async () => {
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:probation')
})
const during = await context.manager.state()
assert.notEqual(during.current, candidate.id)
assert.equal((await context.manager.activation()).phase, 'probation')
const cancelled = await context.manager.cancelCandidate()
assert.equal(cancelled.cancelled, true)
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
assert.equal(await context.manager.activation(), undefined)
})
test('rejects rollback and cross-authority candidates at the Bootstrap boundary', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const advanced = await managedRecord(context, 'advanced', 3)
await context.manager.activateManaged(advanced, { healthCheck: async () => {}, activateReceipts: async () => {} })
const rollback = await managedRecord(context, 'rollback', 2)
await assert.rejects(context.manager.activateManaged(rollback, {
healthCheck: async () => {}, activateReceipts: async () => {},
}), /roll back/)
const wrongExperimental = await managedRecord(context, 'wrong-environment', 3, 'experimental', '0.1.0-rc.4')
await assert.rejects(context.manager.stageCandidate(wrongExperimental, async () => {}), /retain the current Environment/)
})
test('does not restart previous DSH before snapshot recovery after candidate health failure', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const candidate = await experimentalRecord(context, context.image, 'health-failure', '0.1.0-rc.2')
let healthCalls = 0
await assert.rejects(context.manager.stageCandidate(candidate, async () => {
healthCalls += 1
throw new Error('candidate failed health')
}), /candidate failed health/)
assert.equal(healthCalls, 1)
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
})
test('collects only Store assets and records outside slots, transactions, Holds, and snapshots', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const current = await context.manager.writeRecord(await managedRecord(context, 'current', 2))
await context.manager.activateManaged(current, {
healthCheck: async () => {},
activateReceipts: async () => {},
})
const orphan = await context.manager.writeRecord(await managedRecord(context, 'orphan', 3))
const held = await context.manager.writeRecord(await managedRecord(
context,
'held',
4,
'experimental',
'0.1.0-rc.held',
))
await writeFile(join(context.paths.updaterStateRoot, 'channel.json'), JSON.stringify({
schema: 1,
updateChannel: 'experimental',
holds: [{
id: 'hold', type: 'version', dshVersion: held.dshVersion, environmentVersion: null,
reason: 'fixture', createdAt: '2026-08-19T00:00:00.000Z',
}],
experimentalBlocked: null,
}))
await mkdir(join(context.paths.snapshotsRoot, 'versions', 'snapshot-kept'), { recursive: true })
await mkdir(join(context.paths.snapshotsRoot, 'versions', 'snapshot-orphan'), { recursive: true })
await writeFile(join(context.paths.updaterStateRoot, 'transaction.json'), JSON.stringify({
from: { runtime: current.id }, to: { runtime: current.id }, snapshotId: 'snapshot-kept',
}))
await writeFile(join(context.paths.downloadsRoot, 'disposable'), 'cache')
await mkdir(context.paths.systemSkillCatalogsRoot, { recursive: true })
await writeFile(join(context.paths.systemSkillCatalogsRoot, 'catalog-marker'), 'retained')
const removedSnapshots = []
const result = await new PlatformGarbageCollector({
paths: context.paths,
deployments: context.manager,
snapshots: {
remove: async id => {
removedSnapshots.push(id)
await rm(join(context.paths.snapshotsRoot, 'versions', id), { recursive: true, force: true })
return true
},
},
}).collect()
assert.equal(result.deployments.records.includes(orphan.id), true)
assert.equal(result.deployments.records.includes(held.id), false)
await assert.rejects(lstat(context.manager.recordPath(orphan.id)), { code: 'ENOENT' })
assert.equal((await lstat(context.manager.recordPath(held.id))).isFile(), true)
await assert.rejects(lstat(join(context.paths.runtimesRoot, orphan.runtime.id)), { code: 'ENOENT' })
assert.equal((await lstat(join(context.paths.runtimesRoot, held.runtime.id))).isDirectory(), true)
assert.equal((await lstat(join(context.paths.snapshotsRoot, 'versions', 'snapshot-kept'))).isDirectory(), true)
assert.deepEqual(removedSnapshots, ['snapshot-orphan'])
await assert.rejects(lstat(join(context.paths.snapshotsRoot, 'versions', 'snapshot-orphan')), { code: 'ENOENT' })
await assert.rejects(lstat(join(context.paths.downloadsRoot, 'disposable')), { code: 'ENOENT' })
assert.equal(await readFile(join(context.paths.systemSkillCatalogsRoot, 'catalog-marker'), 'utf8'), 'retained')
})
test('explicit recovery replaces an invalid Managed current with the exact Image Baseline', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const managed = await managedRecord(context, 'invalid-managed', 3)
await context.manager.activateManaged(managed, { healthCheck: async () => {}, activateReceipts: async () => {} })
let activated
const state = await context.manager.recoverImageBaseline(context.image, {
healthCheck: async () => {
assert.equal(await readFile(join(context.paths.viewsRoot, 'runtime', 'sentinel'), 'utf8'), 'runtime:image')
},
activateReceipts: async tokens => { activated = tokens },
})
assert.equal(state.current, context.image.id)
assert.equal(state.previous, managed.id)
assert.deepEqual(activated, [])
})
test('explicit recovery repairs only the exact image Record after its persisted bytes are damaged', async () => {
const context = await fixture()
await context.manager.initialize(context.image)
const managed = await managedRecord(context, 'managed-before-repair', 3)
await context.manager.activateManaged(managed, { healthCheck: async () => {}, activateReceipts: async () => {} })
await writeFile(context.manager.recordPath(context.image.id), '{"damaged":true}\n')
const state = await context.manager.recoverImageBaseline(context.image, {
healthCheck: async () => {},
activateReceipts: async () => {},
})
assert.equal(state.current, context.image.id)
assert.deepEqual(await context.manager.record(context.image.id), context.image)
await assert.rejects(context.manager.repairImageRecord(managed), /differs from the current image inventory/)
})
@@ -0,0 +1,135 @@
import assert from 'node:assert/strict'
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
DSH_COMPATIBILITY_PACKAGES,
DSH_REMOTE_METHODS,
DSH_STATIC_CLIENT_MODULES,
DSH_WEB_ROWS,
verifyDshCompatibility,
} from '../lib/dsh-compatibility.mjs'
const VERSION = '0.1.5-rc.1'
async function writeJson(path, value) {
await writeFile(path, `${JSON.stringify(value)}\n`)
}
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-compatibility-fixture-'))
await mkdir(join(root, 'lib'), { recursive: true })
await writeJson(join(root, 'package.json'), {
name: '@deepseek-ai/dsh',
version: VERSION,
type: 'module',
bin: { dsh: 'lib/bin.js' },
dependencies: Object.fromEntries(Object.keys(DSH_COMPATIBILITY_PACKAGES).map(name => [name, `^${VERSION}`])),
})
const config = Object.entries(DSH_WEB_ROWS)
.map(([id, name]) => `- id: ${id}\n name: '${name}'`)
.join('\n')
await writeFile(join(root, 'lib/bin.js'), `console.log(${JSON.stringify(config)})\n`)
for (const [name, exports] of Object.entries(DSH_COMPATIBILITY_PACKAGES)) {
const directory = join(root, 'node_modules', ...name.split('/'))
await mkdir(join(directory, 'lib'), { recursive: true })
await writeJson(join(directory, 'package.json'), {
name,
version: VERSION,
exports: Object.fromEntries(exports.map(subpath => [subpath, './lib/index.js'])),
})
await writeFile(join(directory, 'lib/index.js'), '')
}
await writeFile(
packageFile(root, '@deepseek-ai/dsh-api-remotes', 'lib/client.js'),
DSH_REMOTE_METHODS.join('\n'),
)
const frontendAssets = packageFile(root, '@deepseek-ai/dsh-web-frontend', 'dist/assets')
await mkdir(frontendAssets, { recursive: true })
await writeFile(join(frontendAssets, 'index.js'), `{${DSH_STATIC_CLIENT_MODULES
.map(name => `${JSON.stringify(name)}:fixture`)
.join(',')}}\n`)
return root
}
function packageFile(root, packageName, file) {
return join(root, 'node_modules', ...packageName.split('/'), file)
}
function removeAfter(t, ...paths) {
t.after(() => Promise.all(paths.map(path => rm(path, { recursive: true, force: true }))))
}
test('accepts the complete DSH package, Web profile, and Remote contract', async t => {
const packageRoot = await fixture()
const home = await mkdtemp(join(tmpdir(), 'dsh-compatibility-home-'))
removeAfter(t, packageRoot, home)
assert.deepEqual(await verifyDshCompatibility({ packageRoot, expectedVersion: VERSION, home }), {
name: '@deepseek-ai/dsh',
version: VERSION,
packages: 10,
remoteMethods: 3,
webRows: 5,
})
})
test('rejects a stale installed package in the DSH dependency closure', async t => {
const packageRoot = await fixture()
const home = await mkdtemp(join(tmpdir(), 'dsh-compatibility-home-'))
removeAfter(t, packageRoot, home)
const manifestPath = packageFile(packageRoot, '@deepseek-ai/dsh-client-connection', 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
await writeJson(manifestPath, { ...manifest, version: '0.1.2-rc.1' })
await assert.rejects(
verifyDshCompatibility({ packageRoot, expectedVersion: VERSION, home }),
/dsh-client-connection is not installed at DSH version 0\.1\.5-rc\.1/,
)
})
test('rejects missing Web rows and management Remote methods', async t => {
const packageRoot = await fixture()
const home = await mkdtemp(join(tmpdir(), 'dsh-compatibility-home-'))
removeAfter(t, packageRoot, home)
await writeFile(join(packageRoot, 'lib/bin.js'), 'console.log("- id: connection\\n name: missing")\n')
await assert.rejects(
verifyDshCompatibility({ packageRoot, expectedVersion: VERSION, home }),
/DSH Web profile does not contain/,
)
await writeFile(
packageFile(packageRoot, '@deepseek-ai/dsh-api-remotes', 'lib/client.js'),
DSH_REMOTE_METHODS.slice(1).join('\n'),
)
await assert.rejects(
verifyDshCompatibility({ packageRoot, expectedVersion: VERSION, home }),
/Remote registry is missing/,
)
})
test('rejects each missing static module required by a bundled System Plugin', async t => {
for (const missing of DSH_STATIC_CLIENT_MODULES) {
await t.test(missing, async t => {
const packageRoot = await fixture()
const home = await mkdtemp(join(tmpdir(), 'dsh-compatibility-home-'))
removeAfter(t, packageRoot, home)
const present = DSH_STATIC_CLIENT_MODULES.filter(name => name !== missing)
await writeFile(
packageFile(packageRoot, '@deepseek-ai/dsh-web-frontend', 'dist/assets/index.js'),
`{${present.map(name => `${JSON.stringify(name)}:fixture`).join(',')}}\n`,
)
await assert.rejects(
verifyDshCompatibility({ packageRoot, expectedVersion: VERSION, home }),
new RegExp(`Web static module table is missing ${JSON.stringify(missing).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`),
)
})
}
})
test('requires every static browser module consumed directly by bundled System Plugins', () => {
assert.deepEqual(DSH_STATIC_CLIENT_MODULES, [
'@deepseek-ai/dsh-client-ui-primitives',
'react',
'react-dom',
])
})
@@ -0,0 +1,145 @@
import assert from 'node:assert/strict'
import { request } from 'node:http'
import { mkdtemp, stat } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
createDshLifecycleServer,
DshLifecycleBroker,
listenDshLifecycle,
} from '../bootstrap/lib/dsh-lifecycle.mjs'
function call(socketPath, path, body) {
return new Promise((resolve, reject) => {
const req = request({ socketPath, path, method: 'POST', headers: { 'content-type': 'application/json' } }, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.on('end', () => resolve({ status: response.statusCode, body: JSON.parse(Buffer.concat(chunks)) }))
})
req.once('error', reject)
req.end(JSON.stringify(body))
})
}
test('authorizes exactly one claim for each supervised DSH launch', async () => {
const reports = []
const broker = new DshLifecycleBroker({ report: (message, fields) => reports.push({ message, fields }) })
const unrelated = broker.prepareLaunch('gateway')
assert.deepEqual(unrelated.environment, {})
const launch = broker.prepareLaunch('dsh-runtime')
const first = broker.claim(launch.environment.DSH_PLATFORM_LAUNCH_TOKEN)
assert.match(first.sessionId, /^[0-9a-f-]{36}$/)
assert.deepEqual(broker.readiness(), {
generation: first.sessionId, publicReady: false, ready: false, readyUrl: null, verified: false,
})
assert.deepEqual(broker.ready(first.sessionId), { ready: true })
assert.deepEqual(broker.readiness(), {
generation: first.sessionId, publicReady: false, ready: true, readyUrl: null, verified: false,
})
broker.verify()
assert.equal(broker.readiness().publicReady, false)
broker.publish()
assert.equal(broker.readiness().publicReady, true)
assert.throws(() => broker.claim(launch.environment.DSH_PLATFORM_LAUNCH_TOKEN), /already consumed/)
launch.release()
await assert.rejects(broker.signal(first.sessionId, 'SIGTERM'), /session is invalid/)
await new Promise(resolve => setImmediate(resolve))
assert.deepEqual(reports.map(value => value.message), [
'dsh.launch.authorized', 'dsh.launch.claimed', 'dsh.launch.ready', 'dsh.launch.verified',
'platform.public-ready', 'dsh.launch.released',
])
assert.doesNotMatch(JSON.stringify(reports), new RegExp(launch.environment.DSH_PLATFORM_LAUNCH_TOKEN))
assert.doesNotMatch(JSON.stringify(reports), new RegExp(first.sessionId))
})
test('invalidates an old launch without allowing its cleanup to release the replacement', () => {
const broker = new DshLifecycleBroker()
const oldLaunch = broker.prepareLaunch('dsh-runtime')
const oldSession = broker.claim(oldLaunch.environment.DSH_PLATFORM_LAUNCH_TOKEN)
broker.ready(oldSession.sessionId)
broker.verify()
broker.publish()
assert.equal(broker.readiness().publicReady, true)
const nextLaunch = broker.prepareLaunch('dsh-runtime')
assert.equal(broker.readiness().publicReady, false)
oldLaunch.release()
const session = broker.claim(nextLaunch.environment.DSH_PLATFORM_LAUNCH_TOKEN)
assert.match(session.sessionId, /^[0-9a-f-]{36}$/)
})
test('returns restart only for an active session outside an owned shutdown', async () => {
let owned = false
const broker = new DshLifecycleBroker({ shouldTerminate: async () => owned })
const launch = broker.prepareLaunch('dsh-runtime')
const { sessionId } = broker.claim(launch.environment.DSH_PLATFORM_LAUNCH_TOKEN)
assert.deepEqual(await broker.signal(sessionId, 'SIGTERM'), { disposition: 'terminate' })
broker.ready(sessionId)
assert.deepEqual(await broker.signal(sessionId, 'SIGTERM'), { disposition: 'request-restart' })
owned = true
assert.deepEqual(await broker.signal(sessionId, 'SIGTERM'), { disposition: 'terminate' })
owned = false
broker.beginShutdown()
assert.deepEqual(await broker.signal(sessionId, 'SIGTERM'), { disposition: 'terminate' })
await assert.rejects(broker.signal(sessionId, 'SIGINT'), /signal is invalid/)
})
test('serves launch ownership and readiness over a private Unix socket', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-lifecycle-broker-'))
const socketPath = join(root, 'dsh-lifecycle.sock')
const reports = []
const broker = new DshLifecycleBroker({ report: (message, fields) => reports.push({ message, fields }) })
const server = createDshLifecycleServer(broker)
t.after(() => server.close())
await listenDshLifecycle(server, socketPath)
assert.equal((await stat(socketPath)).mode & 0o777, 0o600)
const launch = broker.prepareLaunch('dsh-runtime')
const claim = await call(socketPath, '/v1/runtime/claim', {
launchToken: launch.environment.DSH_PLATFORM_LAUNCH_TOKEN,
})
assert.equal(claim.status, 200)
assert.deepEqual(await call(socketPath, '/v1/runtime/readiness', {}), {
status: 200,
body: {
generation: claim.body.sessionId, publicReady: false, ready: false, readyUrl: null, verified: false,
},
})
const readyUrl = 'http://127.0.0.1:3079/?token=fixture-token'
assert.deepEqual(await call(socketPath, '/v1/runtime/ready', { readyUrl, sessionId: claim.body.sessionId }), {
status: 200,
body: { ready: true },
})
assert.deepEqual(await call(socketPath, '/v1/runtime/ready', { sessionId: claim.body.sessionId }), {
status: 200,
body: { ready: true },
})
assert.deepEqual(await call(socketPath, '/v1/runtime/readiness', {}), {
status: 200,
body: {
generation: claim.body.sessionId, publicReady: false, ready: true, readyUrl, verified: false,
},
})
broker.verify()
broker.publish()
assert.equal((await call(socketPath, '/v1/runtime/readiness', {})).body.publicReady, true)
const signal = await call(socketPath, '/v1/runtime/signal', {
sessionId: claim.body.sessionId,
signal: 'SIGTERM',
})
assert.deepEqual(signal, { status: 200, body: { disposition: 'request-restart' } })
assert.equal((await call(socketPath, '/v1/runtime/claim', {
launchToken: launch.environment.DSH_PLATFORM_LAUNCH_TOKEN,
})).status, 409)
assert.equal((await call(socketPath, '/v1/runtime/signal', {
sessionId: claim.body.sessionId,
signal: 'SIGTERM',
unexpected: true,
})).status, 400)
assert.equal((await call(socketPath, '/v1/unknown', {})).status, 404)
assert.equal(reports.at(-2).message, 'dsh.lifecycle-request.failed')
assert.equal(reports.at(-2).fields.level, 'warning')
assert.equal(reports.at(-1).message, 'dsh.lifecycle-request.failed')
assert.equal(reports.at(-1).fields.level, 'error')
})
@@ -0,0 +1,303 @@
import assert from 'node:assert/strict'
import { spawn } from 'node:child_process'
import { createServer } from 'node:http'
import { mkdtemp, symlink } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { verifyDshWebReady } from '../../control-plane/hooks/dsh-web-ready.mjs'
async function fixture(routes) {
const requests = new Map()
const server = createServer((request, response) => {
requests.set(request.url, (requests.get(request.url) ?? 0) + 1)
const configured = routes.get(`${request.method} ${request.url}`) ?? routes.get(request.url)
const route = typeof configured === 'function' ? configured(requests.get(request.url)) : configured
response.writeHead(route?.status ?? 404, {
'content-type': route?.type ?? 'text/plain',
...route?.headers,
})
response.end(route?.body ?? '')
})
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve))
return { server, port: server.address().port, requests }
}
test('DSH web readiness requires every boot manifest Plugin bundle', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [
{ id: 'one', url: '/plugins/one/client.js?rev=one', rev: 'one' },
{ id: 'two', url: '/plugins/two/client.js?rev=two', rev: 'two' },
] })
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>globalThis["__DSH_BOOT__"] = ${manifest}</script>` }],
['/plugins/one/client.js?rev=one', { status: 200, type: 'text/javascript', body: 'one' }],
['/plugins/two/client.js?rev=two', { status: 404 }],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [{ moduleName: 'ready', enabled: true, fiberPhase: 'active' }] } },
}) }],
])
const context = await fixture(routes)
try {
await assert.rejects(verifyDshWebReady({ port: context.port, managedReady: async () => {} }), /returned HTTP 404/)
routes.set('/plugins/two/client.js?rev=two', { status: 200, type: 'text/javascript', body: 'two' })
await verifyDshWebReady({ port: context.port, managedReady: async () => {} })
assert.equal(context.requests.get('/'), 3)
assert.equal(context.requests.get('/plugins/one/client.js?rev=one'), 3)
assert.equal(context.requests.get('/plugins/two/client.js?rev=two'), 3)
assert.equal(context.requests.get('/api/pluginInventory/list'), 2)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness verifies 0.1.5 initial combo batches', async () => {
const entryUrl = '/plugins/??one/client.js&rev=entry-one'
const batchUrl = '/plugins/??one/client.js,two/client.js&rev=batch-one'
const manifest = JSON.stringify({
rev: 'graph-one',
entries: [{ id: 'one', url: entryUrl, rev: 'entry-one' }],
batches: [{ phase: 'application', url: batchUrl, rev: 'batch-one', entries: ['one', 'two'] }],
})
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
[entryUrl, { status: 200, type: 'text/javascript', body: 'one' }],
[batchUrl, { status: 404 }],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [{ moduleName: 'ready', enabled: true, fiberPhase: 'active' }] } },
}) }],
])
const context = await fixture(routes)
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => ({}) }),
/returned HTTP 404/,
)
routes.set(batchUrl, { status: 200, type: 'text/javascript', body: 'one and two' })
await verifyDshWebReady({ port: context.port, managedReady: async () => ({}) })
assert.equal(context.requests.get(entryUrl), 3)
assert.equal(context.requests.get(batchUrl), 3)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects a malformed combo batch contract', async () => {
const manifest = JSON.stringify({
rev: 'graph-one',
entries: [{ id: 'one', url: '/plugins/one/client.js?rev=one', rev: 'one' }],
batches: { phase: 'application', url: '/plugins/??one/client.js&rev=one' },
})
const context = await fixture(new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
]))
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => ({}) }),
/boot manifest batches are invalid/,
)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness exchanges the private launch token for an authenticated cookie', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [
{ id: 'one', url: '/plugins/one/client.js?rev=one', rev: 'one' },
] })
let expectedCookie = ''
const routes = new Map([
['/?token=fixture-token', {
status: 303,
headers: { location: '/', 'set-cookie': 'dsh-auth-fixture=session; Path=/; HttpOnly; SameSite=Strict' },
}],
])
const context = await fixture(routes)
context.server.removeAllListeners('request')
context.server.on('request', (request, response) => {
context.requests.set(request.url, (context.requests.get(request.url) ?? 0) + 1)
if (request.url === '/?token=fixture-token') {
response.writeHead(303, {
location: '/',
'set-cookie': 'dsh-auth-fixture=session; Path=/; HttpOnly; SameSite=Strict',
})
response.end()
return
}
expectedCookie = request.headers.cookie ?? ''
if (expectedCookie !== 'dsh-auth-fixture=session') {
response.writeHead(401)
response.end('unauthorized')
return
}
if (request.url === '/') {
response.writeHead(200, { 'content-type': 'text/html' })
response.end(`<script>window.__DSH_BOOT__ = ${manifest}</script>`)
} else if (request.url === '/plugins/one/client.js?rev=one') {
response.writeHead(200, { 'content-type': 'text/javascript' })
response.end('one')
} else if (request.url === '/api/pluginInventory/list') {
response.writeHead(200, { 'content-type': 'application/json' })
response.end(JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [{ moduleName: 'ready', enabled: true, fiberPhase: 'active' }] } },
}))
} else {
response.writeHead(404)
response.end()
}
})
try {
await verifyDshWebReady({
port: context.port,
managedReady: async () => ({ ready: true, readyUrl: `http://127.0.0.1:${String(context.port)}/?token=fixture-token` }),
})
assert.equal(expectedCookie, 'dsh-auth-fixture=session')
assert.equal(context.requests.get('/?token=fixture-token'), 1)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects enabled Plugins that are not active', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [] })
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [
{ moduleName: 'active', enabled: true, fiberPhase: 'active' },
{ moduleName: 'disabled', enabled: false, fiberPhase: null },
{ moduleName: 'broken', enabled: true, fiberPhase: 'failed' },
] } },
}) }],
])
const context = await fixture(routes)
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => {} }),
/DSH Plugins are not active: broken \(failed\)/,
)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects Plugin inventory RPC failures', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [] })
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: false, error: { code: 'internal', message: 'loader unavailable', details: {} } },
}) }],
])
const context = await fixture(routes)
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => {} }),
/DSH Plugin inventory is unavailable: loader unavailable/,
)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects a lifecycle generation change during verification', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [] })
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [] } },
}) }],
])
const context = await fixture(routes)
let observation = 0
try {
await assert.rejects(verifyDshWebReady({
port: context.port,
managedReady: async () => ({ generation: ++observation === 1 ? 'one' : 'two', ready: true, readyUrl: null }),
}), /lifecycle changed during Web readiness verification/)
assert.equal(context.requests.get('/'), 1)
assert.equal(context.requests.get('/api/pluginInventory/list'), 1)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects a boot manifest mutation between observations', async () => {
const manifest = rev => JSON.stringify({ rev, entries: [] })
const routes = new Map([
['/', observation => ({
status: 200,
type: 'text/html',
body: `<script>window.__DSH_BOOT__ = ${manifest(observation === 1 ? 'one' : 'two')}</script>`,
})],
['POST /api/pluginInventory/list', { status: 200, type: 'application/json', body: JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [] } },
}) }],
])
const context = await fixture(routes)
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => ({ generation: 'one' }) }),
/boot manifest changed during Web readiness verification/,
)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('DSH web readiness rejects a Plugin inventory mutation between observations', async () => {
const manifest = JSON.stringify({ rev: 'one', entries: [] })
const inventory = moduleName => JSON.stringify({
type: 'server-response',
rpcId: 'dsh-platform-readiness',
result: { ok: true, value: { entries: [{ moduleName, enabled: true, fiberPhase: 'active' }] } },
})
const routes = new Map([
['/', { status: 200, type: 'text/html', body: `<script>window.__DSH_BOOT__ = ${manifest}</script>` }],
['POST /api/pluginInventory/list', observation => ({
status: 200,
type: 'application/json',
body: inventory(observation === 1 ? 'one' : 'two'),
})],
])
const context = await fixture(routes)
try {
await assert.rejects(
verifyDshWebReady({ port: context.port, managedReady: async () => ({ generation: 'one' }) }),
/Plugin inventory changed during Web readiness verification/,
)
} finally {
await new Promise(resolve => context.server.close(resolve))
}
})
test('executes readiness checks when launched through the Bootstrap view symlink', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-web-ready-view-'))
const executable = join(root, 'dsh-web-ready.mjs')
await symlink(new URL('../../control-plane/hooks/dsh-web-ready.mjs', import.meta.url), executable)
const result = await new Promise((resolve, reject) => {
const child = spawn(process.execPath, [executable], {
env: { ...process.env, DSH_PLATFORM_RUN: join(root, 'missing-run') },
stdio: ['ignore', 'pipe', 'pipe'],
})
const stderr = []
child.stderr.on('data', chunk => stderr.push(chunk))
child.once('error', reject)
child.once('exit', code => resolve({ code, stderr: Buffer.concat(stderr).toString('utf8') }))
})
assert.notEqual(result.code, 0)
assert.match(result.stderr, /dsh-lifecycle\.sock/)
})
@@ -0,0 +1,42 @@
import assert from 'node:assert/strict'
import { chmod, mkdtemp, readFile, readdir, stat, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { AtomicFileEditor } from '../../control-plane/modules/file-manager/editor.mjs'
import { FileInventory } from '../../control-plane/modules/file-manager/index.mjs'
test('atomically replaces text with optimistic revision and preserves mode', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-editor-'))
const path = join(root, 'file.txt')
await writeFile(path, 'before')
await chmod(path, 0o640)
const inventory = new FileInventory()
const before = await inventory.content(path)
const saved = await new AtomicFileEditor().write(path, 'after\n', before.revision)
assert.equal(await readFile(path, 'utf8'), 'after\n')
assert.equal((await stat(path)).mode & 0o777, 0o640)
assert.notEqual(saved.revision, before.revision)
await assert.rejects(new AtomicFileEditor().write(path, 'stale', before.revision), error => error.statusCode === 409)
assert.equal(await readFile(path, 'utf8'), 'after\n')
assert.equal((await readdir(root)).some(name => name.startsWith('.dsh-edit-')), false)
})
test('creates a new text file without overwriting a concurrent target', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-create-'))
const path = join(root, 'new.txt')
const editor = new AtomicFileEditor()
const created = await editor.write(path, 'new', null, { create: true })
assert.equal(created.size, 3)
await assert.rejects(editor.write(path, 'replace', null, { create: true }), error => error.statusCode === 409)
assert.equal(await readFile(path, 'utf8'), 'new')
})
test('rejects binary, oversized, missing, and non-file edits', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-editor-invalid-'))
const editor = new AtomicFileEditor()
await assert.rejects(editor.write(join(root, 'nul'), 'a\0b', null, { create: true }), error => error.statusCode === 415)
await assert.rejects(editor.write(join(root, 'large'), 'x'.repeat(2 * 1024 * 1024 + 1), null, { create: true }), error => error.statusCode === 413)
await assert.rejects(editor.write(join(root, 'missing'), 'x', 'sha256:missing'), error => error.statusCode === 404)
await assert.rejects(editor.write(root, 'x', 'sha256:missing'), error => error.statusCode === 415)
})
@@ -0,0 +1,146 @@
import assert from 'node:assert/strict'
import { mkdtemp, mkdir, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
createManagedPathMatcher, fileManagerLocations, FileInventory, FileManagerError,
FileRevisionConflictError, FileSearchManager, FileSizeManager, isManagedPath, normalizeAbsolutePath,
} from '../../control-plane/modules/file-manager/index.mjs'
test('normalizes absolute paths and rejects unsafe path representations', () => {
assert.equal(normalizeAbsolutePath('/workspace/a/../b'), '/workspace/b')
assert.throws(() => normalizeAbsolutePath('workspace'), /absolute/)
assert.throws(() => normalizeAbsolutePath('/workspace/a\nb'), /control/)
assert.throws(() => normalizeAbsolutePath(`/${'a'.repeat(4097)}`), /too long/)
})
test('identifies only exact platform-managed roots and descendants', () => {
assert.equal(isManagedPath('/data/platform/state'), true)
assert.equal(isManagedPath('/data/platform/state/updater/status.json'), true)
assert.equal(isManagedPath('/data/platform/stateful'), false)
assert.equal(isManagedPath('/data/dsh'), false)
const custom = createManagedPathMatcher('/srv/platform')
assert.equal(custom('/srv/platform/store/objects'), true)
assert.equal(custom('/data/platform/store/objects'), false)
})
test('derives the default directory and unique shortcuts from existing environment paths', () => {
assert.deepEqual(fileManagerLocations({
defaultWorkspace: '/work/current', dshHome: '/srv/dsh', platformData: '/srv/platform',
}), {
defaultPath: '/work/current', shortcuts: ['/work/current', '/srv/dsh', '/srv/platform', '/'],
})
assert.deepEqual(fileManagerLocations({ defaultWorkspace: '/data/dsh' }).shortcuts, ['/data/dsh', '/data/platform', '/'])
assert.throws(() => fileManagerLocations({ defaultWorkspace: 'relative' }), /absolute/)
})
test('lists directories with stable metadata, directory-first sorting, and revision cursors', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-list-'))
await mkdir(join(root, 'folder'))
await writeFile(join(root, 'z.txt'), 'z')
await writeFile(join(root, '.hidden'), 'hidden')
await symlink('missing', join(root, 'dangling'))
const inventory = new FileInventory()
const first = await inventory.list(root, { limit: 2 })
assert.equal(first.entries[0].name, 'folder')
assert.equal(first.entries.some(entry => entry.name === '.hidden'), true)
assert.equal(first.total, 4)
assert.equal(typeof first.nextCursor, 'string')
const second = await inventory.list(root, { limit: 2, cursor: first.nextCursor })
assert.equal(second.entries.length, 2)
const dangling = [...first.entries, ...second.entries].find(entry => entry.name === 'dangling')
assert.deepEqual([dangling.type, dangling.targetExists], ['symlink', false])
await writeFile(join(root, 'new.txt'), 'new')
await assert.rejects(inventory.list(root, { cursor: first.nextCursor }), FileRevisionConflictError)
})
test('name pagination resolves detailed metadata only for the requested page', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-page-'))
for (let index = 0; index < 20; index += 1) await writeFile(join(root, `${String(index).padStart(2, '0')}.txt`), 'x')
let resolutions = 0
const inventory = new FileInventory({
identity: { resolve: async () => { resolutions += 1; return { user: 'node', group: 'node' } } },
})
const page = await inventory.list(root, { limit: 5 })
assert.equal(page.entries.length, 5)
assert.equal(page.total, 20)
assert.equal(resolutions, 5)
const thirdPage = await inventory.list(root, { limit: 5, offset: 10 })
assert.deepEqual(thirdPage.entries.map(entry => entry.name), ['10.txt', '11.txt', '12.txt', '13.txt', '14.txt'])
assert.equal(resolutions, 10)
})
test('reads only bounded UTF-8 regular files and detects binary content', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-content-'))
const text = join(root, '中文.txt')
await writeFile(text, 'hello\r\n世界\r\n')
const inventory = new FileInventory()
const result = await inventory.content(text)
assert.equal(result.content, 'hello\r\n世界\r\n')
assert.equal(result.newline, 'crlf')
assert.match(result.revision, /^sha256:[a-f0-9]{64}$/)
await writeFile(join(root, 'binary'), Buffer.from([1, 0, 2]))
await assert.rejects(inventory.content(join(root, 'binary')), error => error.statusCode === 415)
await assert.rejects(inventory.content(root), error => error.statusCode === 415)
})
test('reports container user and group and calculates directory size without following links', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-size-'))
await mkdir(join(root, 'nested'))
await writeFile(join(root, 'one.txt'), '1234')
await writeFile(join(root, 'nested', 'two.txt'), '567890')
await symlink('one.txt', join(root, 'link'))
const identity = { resolve: async () => ({ user: 'node', group: 'node' }) }
const inventory = new FileInventory({ identity })
const listing = await inventory.list(root)
assert.equal(listing.entries.every(entry => entry.user === 'node' && entry.group === 'node'), true)
const size = new FileSizeManager({ inventory })
const directory = await inventory.stat(root)
const task = size.start({ path: root, revision: directory.revision })
await size.tasks.get(task.taskId).completion
const result = size.get(task.taskId)
assert.equal(result.status, 'success')
assert.equal(result.bytes, 10)
assert.equal(result.entries, 4)
const stale = size.start({ path: root, revision: listing.revision })
await size.tasks.get(stale.taskId).completion
assert.equal(size.get(stale.taskId).status, 'failed')
})
test('bounded search does not follow symlinked directories and can be cancelled', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-search-'))
await mkdir(join(root, 'nested'))
await writeFile(join(root, 'nested', 'Needle.txt'), 'found')
await symlink(root, join(root, 'nested', 'loop'))
const states = []
const manager = new FileSearchManager({ onState: state => states.push(state) })
const task = manager.start({ path: root, query: 'needle' })
await manager.tasks.get(task.taskId).completion
const result = manager.get(task.taskId)
assert.equal(result.status, 'success')
assert.deepEqual(result.results.map(entry => entry.name), ['Needle.txt'])
assert.equal(result.scanned, 3)
assert.equal(states.at(-1).status, 'success')
const cancelled = manager.start({ path: root, query: 'x' })
manager.cancel(cancelled.taskId)
await manager.tasks.get(cancelled.taskId).completion
assert.equal(manager.get(cancelled.taskId).status, 'cancelled')
})
test('rejects invalid list, search, and task parameters', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-invalid-'))
const inventory = new FileInventory()
await assert.rejects(inventory.list(root, { limit: 1001 }), FileManagerError)
await assert.rejects(inventory.list(root, { sort: 'owner' }), /sort/)
await assert.rejects(inventory.list(root, { offset: -1 }), /offset/)
await assert.rejects(inventory.list(root, { offset: 1.5 }), /offset/)
await writeFile(join(root, 'one'), '1')
await writeFile(join(root, 'two'), '2')
const first = await inventory.list(root, { limit: 1 })
await assert.rejects(inventory.list(root, { cursor: first.nextCursor, offset: 0 }), /cannot be combined/)
const manager = new FileSearchManager()
assert.throws(() => manager.start({ path: root, query: '' }), /query/)
assert.throws(() => manager.get('missing'), error => error.statusCode === 404)
})
@@ -0,0 +1,450 @@
import assert from 'node:assert/strict'
import { chmod, mkdir, mkdtemp, readFile, readdir, stat, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { FileInventory } from '../../control-plane/modules/file-manager/index.mjs'
import { FileTaskManager, fileTaskInternals } from '../../control-plane/modules/file-manager/tasks.mjs'
async function setup(prefix = 'dsh-file-tasks-') {
const root = await mkdtemp(join(tmpdir(), prefix))
const files = join(root, 'files')
const tasks = join(root, 'tasks')
await mkdir(files)
const manager = new FileTaskManager({ root: tasks })
await manager.initialize()
return { root, files, tasks, manager, inventory: new FileInventory() }
}
async function finish(manager, task) {
await manager.tasks.get(task.taskId).completion
return manager.get(task.taskId)
}
test('runs mkdir, touch, rename, copy, move, and permanent delete tasks', async () => {
const { files, manager, inventory } = await setup()
assert.equal((await finish(manager, manager.start({ operation: 'mkdir', destination: join(files, 'dir') }))).status, 'success')
assert.equal((await stat(join(files, 'dir'))).isDirectory(), true)
assert.equal((await finish(manager, manager.start({ operation: 'touch', destination: join(files, 'empty') }))).status, 'success')
const empty = await inventory.stat(join(files, 'empty'))
const renamed = await finish(manager, manager.start({
operation: 'rename', sources: [{ path: empty.path, revision: empty.revision }], destination: join(files, 'renamed'),
}))
assert.equal(renamed.status, 'success')
await writeFile(join(files, 'dir', 'nested.txt'), 'nested')
await symlink('nested.txt', join(files, 'dir', 'link'))
await mkdir(join(files, 'copies'))
const source = await inventory.stat(join(files, 'dir'))
const copied = await finish(manager, manager.start({
operation: 'copy', sources: [{ path: source.path, revision: source.revision }], destination: join(files, 'copies'), conflict: 'reject',
}))
assert.equal(copied.status, 'success')
assert.equal(await readFile(join(files, 'copies', 'dir', 'nested.txt'), 'utf8'), 'nested')
const link = await inventory.stat(join(files, 'copies', 'dir', 'link'))
assert.equal(link.type, 'symlink')
const movedSource = await inventory.stat(join(files, 'renamed'))
const moved = await finish(manager, manager.start({
operation: 'move', sources: [{ path: movedSource.path, revision: movedSource.revision }], destination: join(files, 'copies'),
}))
assert.equal(moved.status, 'success')
const deleteSource = await inventory.stat(join(files, 'copies', 'dir'))
const removed = await finish(manager, manager.start({ operation: 'delete', sources: [{ path: deleteSource.path, revision: deleteSource.revision }] }))
assert.equal(removed.status, 'success')
assert.equal(removed.processedBytes, removed.totalBytes)
assert.equal(removed.processedEntries, removed.totalEntries)
assert.equal(await stat(deleteSource.path).then(() => true, error => error.code !== 'ENOENT'), false)
assert.equal((await readdir(join(files, 'copies'))).some(name => name.startsWith('.dsh-')), false)
})
test('releases the mutation lease before publishing a terminal task state', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-terminal-lease-'))
const files = join(root, 'files')
const tasks = join(root, 'tasks')
const destination = join(files, 'destination')
await mkdir(destination, { recursive: true })
await writeFile(join(files, 'item.txt'), 'source')
await writeFile(join(destination, 'item.txt'), 'existing')
let releaseReport
const blockedReport = new Promise(resolve => { releaseReport = resolve })
let observeFailure
const failurePublished = new Promise(resolve => { observeFailure = resolve })
const inventory = new FileInventory()
const manager = new FileTaskManager({
root: tasks,
onState: task => { if (task.status === 'failed') observeFailure() },
report: message => message === 'file-task.copy.failed' ? blockedReport : undefined,
})
await manager.initialize()
const source = await inventory.stat(join(files, 'item.txt'))
const rejected = manager.start({
operation: 'copy', sources: [{ path: source.path, revision: source.revision }], destination, conflict: 'reject',
})
await failurePublished
assert.equal(manager.activeMutation, undefined)
assert.equal(manager.queue.some(task => task.taskId === rejected.taskId), false)
manager.activeMutation = manager.tasks.get(rejected.taskId)
const renamed = manager.start({
operation: 'copy', sources: [{ path: source.path, revision: source.revision }], destination, conflict: 'rename',
})
releaseReport()
assert.equal((await finish(manager, renamed)).status, 'success')
assert.equal((await finish(manager, rejected)).status, 'failed')
assert.equal((await readdir(destination)).length, 2)
})
test('changes file ownership and permissions recursively without following symbolic links', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-attributes-'))
const files = join(root, 'files')
const tasks = join(root, 'tasks')
const tree = join(files, 'tree')
const nested = join(tree, 'nested')
const target = join(root, 'outside.txt')
await mkdir(nested, { recursive: true })
await writeFile(join(nested, 'inside.txt'), 'inside')
await writeFile(target, 'outside')
await chmod(target, 0o640)
await symlink(target, join(tree, 'outside-link'))
const identity = {
resolve: async () => ({ user: 'current', group: 'current' }),
userId: async value => value === 'current' ? process.getuid() : Promise.reject(new Error('unknown user')),
groupId: async value => value === 'current' ? process.getgid() : Promise.reject(new Error('unknown group')),
}
const inventory = new FileInventory({ identity })
const reports = []
const manager = new FileTaskManager({ root: tasks, inventory, identity, report: (message, fields) => reports.push({ message, fields }) })
await manager.initialize()
const source = await inventory.stat(tree)
const started = manager.start({
operation: 'attributes',
sources: [{ path: tree, revision: source.revision }],
attributes: { user: 'current', group: 'current', mode: '0750', recursive: true },
})
const result = await manager.completion(started.taskId)
assert.equal(result.status, 'success')
assert.equal(result.errorCode, null)
assert.equal(result.processedEntries, 4)
assert.equal((await stat(tree)).mode & 0o7777, 0o750)
assert.equal((await stat(nested)).mode & 0o7777, 0o750)
assert.equal((await stat(join(nested, 'inside.txt'))).mode & 0o7777, 0o750)
assert.equal((await stat(target)).mode & 0o7777, 0o640)
assert.equal(reports.at(-1).message, 'file-task.attributes.completed')
})
test('rejects filesystems that silently ignore Unix ownership or mode changes', () => {
const attributes = { uid: 0, gid: 0, mode: 0o600 }
assert.doesNotThrow(() => fileTaskInternals.assertAttributesApplied('/supported', { uid: 0, gid: 0, mode: 0o100600 }, attributes, false))
assert.throws(
() => fileTaskInternals.assertAttributesApplied('/unsupported', { uid: 1000, gid: 1000, mode: 0o100755 }, attributes, false),
error => error.code === 'FILE_ATTRIBUTES_UNSUPPORTED' && error.statusCode === 403,
)
})
test('reports attribute failures instead of a false completion', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-attributes-failed-log-'))
const path = join(root, 'item')
await writeFile(path, 'value')
const identity = {
resolve: async () => ({ user: 'current', group: 'current' }),
userId: async () => { throw Object.assign(new Error('ownership is unsupported'), { code: 'FILE_ATTRIBUTES_UNSUPPORTED' }) },
groupId: async () => process.getgid(),
}
const inventory = new FileInventory({ identity })
const reports = []
const manager = new FileTaskManager({ root: join(root, 'tasks'), inventory, identity, report: message => reports.push(message) })
await manager.initialize()
const source = await inventory.stat(path)
const started = manager.start({
operation: 'attributes', sources: [{ path, revision: source.revision }],
attributes: { user: 'current', group: 'current', mode: '0600', recursive: false },
})
const result = await manager.completion(started.taskId)
assert.equal(result.status, 'failed')
assert.equal(result.errorCode, 'FILE_ATTRIBUTES_UNSUPPORTED')
assert.deepEqual(reports, ['file-task.attributes.failed'])
})
test('validates attribute requests and resumes an interrupted idempotent change', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-attributes-recovery-'))
const files = join(root, 'files')
const tasks = join(root, 'tasks')
await mkdir(files)
await mkdir(tasks)
const path = join(files, 'item')
await writeFile(path, 'value')
const identity = {
resolve: async () => ({ user: 'current', group: 'current' }),
userId: async () => process.getuid(),
groupId: async () => process.getgid(),
}
const inventory = new FileInventory({ identity })
const source = await inventory.stat(path)
const manager = new FileTaskManager({ root: tasks, inventory, identity })
assert.throws(() => manager.start({
operation: 'attributes', sources: [{ path, revision: source.revision }],
attributes: { user: 'current', group: 'current', mode: '888', recursive: false },
}), /attributes/)
const task = {
schema: 1, taskId: '55555555-5555-4555-8555-555555555555', operation: 'attributes', status: 'running', phase: 'mutating',
sources: [{ path, revision: source.revision }], destination: null, destinationRevision: null, conflict: 'reject', managed: false,
attributes: { user: 'current', group: 'current', mode: '0600', recursive: false },
processedBytes: 0, totalBytes: 5, processedEntries: 0, totalEntries: 1,
published: [], staging: [], hidden: [], currentPath: path, currentSource: null, currentDestination: null,
error: null, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), cancelRequested: false,
}
await writeFile(join(tasks, `${task.taskId}.json`), JSON.stringify(task))
const recovered = new FileTaskManager({ root: tasks, inventory, identity })
await recovered.initialize()
assert.equal(recovered.get(task.taskId).status, 'success')
assert.equal((await stat(path)).mode & 0o7777, 0o600)
})
test('rejects stale revisions, protected roots, and recursive copies while queueing concurrent mutations', async () => {
const { files, manager, inventory } = await setup()
const sourcePath = join(files, 'source')
await writeFile(sourcePath, 'one')
const source = await inventory.stat(sourcePath)
await writeFile(sourcePath, 'two')
const stale = manager.start({ operation: 'delete', sources: [{ path: sourcePath, revision: source.revision }] })
assert.equal((await finish(manager, stale)).status, 'failed')
assert.throws(() => manager.start({ operation: 'delete', sources: [{ path: '/', revision: 'x' }] }), error => error.statusCode === 403)
await mkdir(join(files, 'tree'))
const tree = await inventory.stat(join(files, 'tree'))
const recursive = manager.start({ operation: 'copy', sources: [{ path: tree.path, revision: tree.revision }], destination: tree.path })
assert.equal((await finish(manager, recursive)).status, 'failed')
const first = manager.start({ operation: 'touch', destination: join(files, 'first') })
const second = manager.start({ operation: 'touch', destination: join(files, 'second') })
assert.equal(second.status, 'queued')
assert.equal(second.queuePosition, 1)
await finish(manager, first)
assert.equal((await finish(manager, second)).status, 'success')
})
test('runs queued mutations in FIFO order and cancels queued work without touching files', async () => {
const { files, manager } = await setup('dsh-file-queue-')
const first = manager.start({ operation: 'touch', destination: join(files, 'first') })
const second = manager.start({ operation: 'touch', destination: join(files, 'second') })
const third = manager.start({ operation: 'touch', destination: join(files, 'third') })
assert.deepEqual([second.queuePosition, third.queuePosition], [1, 2])
assert.equal(manager.cancel(second.taskId).status, 'cancelled')
assert.equal(manager.get(third.taskId).queuePosition, 1)
assert.equal((await finish(manager, first)).status, 'success')
assert.equal((await finish(manager, second)).status, 'cancelled')
assert.equal((await finish(manager, third)).status, 'success')
assert.equal(await stat(join(files, 'second')).then(() => true, error => error.code !== 'ENOENT'), false)
})
test('persists queued work before the active task releases its lease', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-queue-persisted-'))
const files = join(root, 'files')
const tasks = join(root, 'tasks')
await mkdir(files)
let releaseReport
const blocked = new Promise(resolve => { releaseReport = resolve })
const manager = new FileTaskManager({ root: tasks, report: message => message === 'file-task.touch.completed' ? blocked : undefined })
await manager.initialize()
const first = manager.start({ operation: 'touch', destination: join(files, 'first') })
const second = manager.start({ operation: 'touch', destination: join(files, 'second') })
await manager.tasks.get(second.taskId).persisted
const journal = JSON.parse(await readFile(join(tasks, `${second.taskId}.json`), 'utf8'))
assert.equal(journal.status, 'queued')
assert.equal(journal.queuePosition, 1)
releaseReport()
assert.equal((await finish(manager, first)).status, 'success')
assert.equal((await finish(manager, second)).status, 'success')
})
test('reports real transfer progress and cancels a queued transfer', async () => {
const { files, manager } = await setup('dsh-file-transfer-progress-')
const transfer = manager.startTransfer({ operation: 'upload', path: join(files, 'upload.bin'), totalBytes: 10 }, async ({ progress }) => {
progress({ processedBytes: 4, totalBytes: 10 })
progress({ processedBytes: 10, totalBytes: 10 })
return { size: 10 }
})
assert.deepEqual(await transfer.result, { size: 10 })
await manager.completion(transfer.task.taskId)
assert.deepEqual(
[manager.get(transfer.task.taskId).status, manager.get(transfer.task.taskId).processedBytes],
['success', 10],
)
let release
const blocked = new Promise(resolve => { release = resolve })
const active = manager.startTransfer({ operation: 'download', path: join(files, 'active') }, () => blocked)
const queued = manager.startTransfer({ operation: 'download', path: join(files, 'queued') }, async () => undefined)
const rejection = assert.rejects(queued.result, error => error.code === 'FILE_TASK_CANCELLED')
assert.equal(manager.cancel(queued.task.taskId).status, 'cancelled')
await rejection
release()
await active.result
})
test('marks persisted transfers interrupted because HTTP streams cannot resume', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-transfer-recovery-'))
const tasks = join(root, 'tasks')
await mkdir(tasks)
for (const [index, status] of ['running', 'queued'].entries()) {
const taskId = `${String(index + 8).repeat(8)}-${String(index + 8).repeat(4)}-4${String(index + 8).repeat(3)}-8${String(index + 8).repeat(3)}-${String(index + 8).repeat(12)}`
await writeFile(join(tasks, `${taskId}.json`), JSON.stringify({
schema: 1, taskId, operation: index === 0 ? 'upload' : 'download', status,
phase: status === 'queued' ? 'queued' : 'transferring', path: join(root, 'value'),
managed: false, staging: [], hidden: [], published: [], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}))
}
const recovered = new FileTaskManager({ root: tasks })
await recovered.initialize()
assert.equal(recovered.list().filter(task => ['upload', 'download'].includes(task.operation)).every(task => task.status === 'interrupted'), true)
})
test('recovers committed deletes and marks uncommitted tasks interrupted', async () => {
const { files, tasks } = await setup()
const hidden = join(files, '.dsh-delete-task.tmp')
await writeFile(hidden, 'remove')
const runningDelete = {
schema: 1, taskId: '11111111-1111-4111-8111-111111111111', operation: 'delete', status: 'running', phase: 'source-hidden',
sources: [], destination: null, managed: false, hidden: [hidden], staging: [], published: [], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}
const staging = join(files, '.dsh-file-task.tmp')
await writeFile(staging, 'partial')
const runningCopy = {
...runningDelete, taskId: '22222222-2222-4222-8222-222222222222', operation: 'copy', phase: 'mutating', hidden: [], staging: [staging],
}
await writeFile(join(tasks, `${runningDelete.taskId}.json`), JSON.stringify(runningDelete))
await writeFile(join(tasks, `${runningCopy.taskId}.json`), JSON.stringify(runningCopy))
const recovered = new FileTaskManager({ root: tasks })
await recovered.initialize()
assert.equal(recovered.get(runningDelete.taskId).status, 'success')
assert.equal(recovered.get(runningCopy.taskId).status, 'interrupted')
assert.equal(await stat(hidden).then(() => true, error => error.code !== 'ENOENT'), false)
assert.equal(await stat(staging).then(() => true, error => error.code !== 'ENOENT'), false)
})
test('move recovery cleans only the source bound to the committed destination', async () => {
const { files, tasks } = await setup('dsh-file-move-recovery-')
const committedSource = join(files, 'committed-source')
const untouchedSource = join(files, 'untouched-source')
const destination = join(files, 'destination')
await writeFile(committedSource, 'old duplicate')
await writeFile(untouchedSource, 'must remain')
await writeFile(destination, 'committed')
const task = {
schema: 1, taskId: '33333333-3333-4333-8333-333333333333', operation: 'move', status: 'running', phase: 'destination-committed',
sources: [{ path: committedSource, revision: 'old' }, { path: untouchedSource, revision: 'untouched' }],
destination: files, currentSource: committedSource, currentDestination: destination,
managed: false, hidden: [], staging: [], published: [destination], createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}
await writeFile(join(tasks, `${task.taskId}.json`), JSON.stringify(task))
const recovered = new FileTaskManager({ root: tasks })
await recovered.initialize()
assert.equal(recovered.get(task.taskId).status, 'success')
assert.equal(await stat(committedSource).then(() => true, error => error.code !== 'ENOENT'), false)
assert.equal(await readFile(untouchedSource, 'utf8'), 'must remain')
})
test('move recovery recognizes an atomic rename completed before its journal commit', async () => {
const { files, tasks } = await setup('dsh-file-rename-recovery-')
const source = join(files, 'source')
const destination = join(files, 'destination')
await writeFile(destination, 'moved')
const task = {
schema: 1, taskId: '44444444-4444-4444-8444-444444444444', operation: 'move', status: 'running', phase: 'move-prepared',
sources: [{ path: source, revision: 'old' }], destination: files,
currentSource: source, currentDestination: destination, managed: false, hidden: [], staging: [], published: [],
createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}
await writeFile(join(tasks, `${task.taskId}.json`), JSON.stringify(task))
const recovered = new FileTaskManager({ root: tasks })
await recovered.initialize()
assert.equal(recovered.get(task.taskId).status, 'success')
assert.deepEqual(recovered.get(task.taskId).published, [destination])
})
test('managed mutations expose a lease and reject active platform work', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-managed-tasks-'))
const manager = new FileTaskManager({ root: join(root, 'tasks'), platformBusy: () => true })
await manager.initialize()
assert.equal(manager.wouldManage({ operation: 'touch', destination: '/data/platform/state/test' }), true)
assert.throws(() => manager.start({ operation: 'touch', destination: '/data/platform/state/test' }), error => error.statusCode === 409)
const custom = new FileTaskManager({ root: join(root, 'custom-tasks'), protectedRoots: ['/custom/workspace'] })
assert.throws(() => custom.start({
operation: 'delete', sources: [{ path: '/custom/workspace', revision: 'sha256:unused' }],
}), error => error.statusCode === 403)
})
test('creates and extracts zip, 7z, and tar.gz archives through file tasks', async () => {
for (const [format, extension] of [['zip', 'zip'], ['7z', '7z'], ['tar.gz', 'tar.gz']]) {
const { files, manager, inventory } = await setup(`dsh-file-archive-${format.replace('.', '-')}-`)
const sourcePath = join(files, 'source')
await mkdir(sourcePath)
await writeFile(join(sourcePath, 'nested.txt'), `content-${format}`)
const source = await inventory.stat(sourcePath)
const archivePath = join(files, `bundle.${extension}`)
const archived = await finish(manager, manager.start({
operation: 'archive', archiveFormat: format,
sources: [{ path: source.path, revision: source.revision }], destination: archivePath,
}))
assert.equal(archived.status, 'success')
assert.equal((await stat(archivePath)).isFile(), true)
const extractRoot = join(files, 'extracted')
await mkdir(extractRoot)
const archive = await inventory.stat(archivePath)
const extracted = await finish(manager, manager.start({
operation: 'extract', archiveFormat: format,
sources: [{ path: archive.path, revision: archive.revision }], destination: extractRoot,
}))
assert.equal(extracted.status, 'success')
assert.equal(await readFile(join(extractRoot, 'source', 'nested.txt'), 'utf8'), `content-${format}`)
}
})
test('rejects invalid archive formats and escaping extracted links', async () => {
const { files, manager, inventory } = await setup('dsh-file-archive-unsafe-')
const sourcePath = join(files, 'source')
await mkdir(sourcePath)
await symlink('../../outside', join(sourcePath, 'escape'))
const source = await inventory.stat(sourcePath)
assert.throws(() => manager.start({
operation: 'archive', archiveFormat: 'rar', sources: [{ path: source.path, revision: source.revision }],
destination: join(files, 'bad.rar'),
}), /format/)
const archivePath = join(files, 'unsafe.tar.gz')
assert.equal((await finish(manager, manager.start({
operation: 'archive', archiveFormat: 'tar.gz', sources: [{ path: source.path, revision: source.revision }], destination: archivePath,
}))).status, 'success')
const archive = await inventory.stat(archivePath)
const destination = join(files, 'destination')
await mkdir(destination)
const extracted = await finish(manager, manager.start({
operation: 'extract', archiveFormat: 'tar.gz', sources: [{ path: archive.path, revision: archive.revision }], destination,
}))
assert.equal(extracted.status, 'failed')
assert.equal(extracted.errorCode, 'ARCHIVE_UNSAFE')
})
test('recovers committed archives and resumes staged extraction publication', async () => {
const { files, tasks } = await setup('dsh-file-archive-recovery-')
const archivePath = join(files, 'published.zip')
await writeFile(archivePath, 'published')
const archiveTask = {
schema: 1, taskId: '66666666-6666-4666-8666-666666666666', operation: 'archive', status: 'running', phase: 'destination-committed',
sources: [], destination: archivePath, managed: false, hidden: [], staging: [], published: [archivePath],
createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
}
const destination = join(files, 'destination')
const staging = join(destination, '.dsh-extract-recovery.tmp')
await mkdir(staging, { recursive: true })
await writeFile(join(staging, 'remaining.txt'), 'remaining')
const extractTask = {
schema: 1, taskId: '77777777-7777-4777-8777-777777777777', operation: 'extract', status: 'running', phase: 'publishing',
sources: [], destination, conflict: 'reject', managed: false, hidden: [], staging: [staging], published: [],
processedBytes: 0, totalBytes: 9, processedEntries: 0, totalEntries: 1,
createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), cancelRequested: false,
}
await writeFile(join(tasks, `${archiveTask.taskId}.json`), JSON.stringify(archiveTask))
await writeFile(join(tasks, `${extractTask.taskId}.json`), JSON.stringify(extractTask))
const recovered = new FileTaskManager({ root: tasks })
await recovered.initialize()
assert.equal(recovered.get(archiveTask.taskId).status, 'success')
assert.equal(recovered.get(extractTask.taskId).status, 'success')
assert.equal(await readFile(join(destination, 'remaining.txt'), 'utf8'), 'remaining')
})
@@ -0,0 +1,92 @@
import assert from 'node:assert/strict'
import { mkdir, mkdtemp, readFile, stat, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { Readable } from 'node:stream'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import { FileTransferManager, fileTransferInternals } from '../../control-plane/modules/file-manager/transfers.mjs'
async function collect(stream) {
const chunks = []
for await (const chunk of stream) chunks.push(chunk)
return Buffer.concat(chunks)
}
test('streams complete, ranged, suffix, and empty downloads', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-download-'))
const path = join(root, '中文 name.txt')
await writeFile(path, '0123456789')
const transfers = new FileTransferManager()
const complete = await transfers.openDownload(path)
assert.equal((await collect(complete.stream)).toString(), '0123456789')
await complete.handle.close()
assert.equal(complete.headers['content-length'], '10')
assert.match(complete.headers['content-disposition'], /filename\*=UTF-8''/)
const ranged = await transfers.openDownload(path, { range: 'bytes=2-5', revision: complete.revision })
assert.equal(ranged.status, 206)
assert.equal((await collect(ranged.stream)).toString(), '2345')
await ranged.handle.close()
const suffix = await transfers.openDownload(path, { range: 'bytes=-3' })
assert.equal((await collect(suffix.stream)).toString(), '789')
await suffix.handle.close()
const emptyPath = join(root, 'empty')
await writeFile(emptyPath, '')
const empty = await transfers.openDownload(emptyPath)
assert.equal((await collect(empty.stream)).byteLength, 0)
await empty.handle.close()
await assert.rejects(transfers.openDownload(path, { range: 'bytes=20-30' }), error => error.statusCode === 416)
})
test('streams directories as temporary zip downloads', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-directory-download-'))
const directory = join(root, 'folder')
await mkdir(directory)
await writeFile(join(directory, 'entry.txt'), 'directory-content')
const transfers = new FileTransferManager({ stagingRoot: join(root, 'cache') })
const download = await transfers.openDownload(directory)
const archive = join(root, 'folder.zip')
await writeFile(archive, await collect(download.stream))
await download.handle.close()
await download.cleanup()
assert.match(download.headers['content-disposition'], /folder\.zip/)
const extracted = spawnSync('unzip', ['-p', archive, 'folder/entry.txt'], { encoding: 'utf8' })
assert.equal(extracted.status, 0, extracted.stderr)
assert.equal(extracted.stdout, 'directory-content')
})
test('uploads through sibling staging with reject, overwrite, and rename policies', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-upload-'))
const path = join(root, 'file.txt')
const transfers = new FileTransferManager()
const first = await transfers.upload(Readable.from(['first']), path, { contentLength: 5 })
assert.equal(first.path, path)
assert.equal(await readFile(path, 'utf8'), 'first')
await assert.rejects(transfers.upload(Readable.from(['no']), path), error => error.statusCode === 409)
const renamed = await transfers.upload(Readable.from(['second']), path, { conflict: 'rename' })
assert.equal(renamed.path, join(root, 'file (1).txt'))
assert.equal(await readFile(renamed.path, 'utf8'), 'second')
await mkdir(join(root, 'directory'))
const directoryConflict = await transfers.upload(Readable.from(['safe']), join(root, 'directory'), { conflict: 'rename' })
assert.equal(directoryConflict.path, join(root, 'directory (1)'))
const oldMode = (await stat(path)).mode & 0o777
await transfers.upload(Readable.from(['replacement']), path, { conflict: 'overwrite' })
assert.equal(await readFile(path, 'utf8'), 'replacement')
assert.equal((await stat(path)).mode & 0o777, oldMode)
})
test('cleans staging files after interrupted or mismatched uploads', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-file-upload-failure-'))
const path = join(root, 'file')
const transfers = new FileTransferManager()
await assert.rejects(transfers.upload(Readable.from(['short']), path, { contentLength: 100 }), /Content-Length/)
assert.equal(await readFile(path).then(() => true, error => error.code !== 'ENOENT'), false)
const entries = await import('node:fs/promises').then(fs => fs.readdir(root))
assert.deepEqual(entries, [])
})
test('sanitizes download names and parses only a single byte range', () => {
assert.match(fileTransferInternals.disposition('a"b.txt'), /filename="a_b.txt"/)
assert.deepEqual(fileTransferInternals.parseRange('bytes=0-0', 5), { start: 0, end: 0, partial: true })
assert.throws(() => fileTransferInternals.parseRange('bytes=0-1,3-4', 5), /invalid/)
})
@@ -0,0 +1,30 @@
import { mkdir, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
export async function writeDshEntrypointFixture(packageRoot) {
await mkdir(join(packageRoot, 'lib'), { recursive: true })
await writeFile(join(packageRoot, 'lib/bin.js'), `#!/usr/bin/env node
const invocation = parseDshArgs(process.argv.slice(2), readVersion());
switch (invocation.mode) {
case "profile": {
const { runProfile } = await import("./profile-boot-fixture.js");
}
}
`)
await writeFile(join(packageRoot, 'lib/profile-boot-fixture.js'), 'import { r as runProfile } from "./profile-boot-implementation.js";\nexport { runProfile };\n')
await writeFile(join(packageRoot, 'lib/profile-boot-implementation.js'), `async function runProfile(options) {
\tprocess.on("SIGTERM", () => {
\t\tinterrupt(0);
\t});
\tprocess.on("SIGINT", () => { interrupt(130); });
\tconst ctx = await boot(NAME, rootConfig, patches, (hostCtx) => {
\t\thostCtx.provide(DSH_LAUNCH_ENVIRONMENT_KEY, options.environment);
\t});
\treturn {
\t\tctx,
\t\tshutdown
\t};
}
export { runProfile as r };
`)
}
@@ -0,0 +1,102 @@
import { createHash, generateKeyPairSync, sign } from 'node:crypto'
export function keyPair() {
const pair = generateKeyPairSync('ed25519')
const der = pair.publicKey.export({ format: 'der', type: 'spki' })
return {
privateKey: pair.privateKey,
publicKey: der.toString('base64'),
keyId: createHash('sha256').update(der).digest('hex'),
}
}
export function registryKeyPair() {
const pair = generateKeyPairSync('ec', { namedCurve: 'prime256v1' })
const der = pair.publicKey.export({ format: 'der', type: 'spki' })
return {
privateKey: pair.privateKey,
publicKey: der.toString('base64'),
keyId: `SHA256:${createHash('sha256').update(der).digest('base64').replace(/=$/, '')}`,
}
}
const defaultRegistry = registryKeyPair()
export function officialDshPolicy(pair = defaultRegistry, expires = null) {
return {
registry: 'https://registry.npmjs.org/',
packageName: '@deepseek-ai/dsh',
keys: [{ algorithm: 'ECDSA-P256-SHA256', keyId: pair.keyId, publicKey: pair.publicKey, expires }],
}
}
export function registryCandidate(pair, version = '0.1.0-rc.8', content = Buffer.alloc(0)) {
const integrity = `sha512-${createHash('sha512').update(content).digest('base64')}`
const message = `@deepseek-ai/dsh@${version}:${integrity}`
return {
schema: 1,
name: '@deepseek-ai/dsh',
version,
dist: {
integrity,
tarball: `https://registry.npmjs.org/@deepseek-ai/dsh/-/dsh-${version}.tgz`,
signatures: [{ keyid: pair.keyId, sig: sign('sha256', Buffer.from(message), pair.privateKey).toString('base64') }],
},
}
}
export function releaseKey(pair) {
return { algorithm: 'Ed25519', keyId: pair.keyId, publicKey: pair.publicKey }
}
export function document(value) {
return Buffer.from(`${JSON.stringify(value)}\n`)
}
export function signature(bytes, pair) {
return {
schema: 1,
algorithm: 'Ed25519',
keyId: pair.keyId,
signature: sign(null, bytes, pair.privateKey).toString('base64'),
}
}
export function keyring(generation, current, next, revokedKeyIds = []) {
return {
schema: 1,
generation,
issuedAt: new Date(Date.UTC(2026, 7, 19, 0, 0, generation)).toISOString(),
current: releaseKey(current),
next: releaseKey(next),
revokedKeyIds: [...revokedKeyIds].sort(),
}
}
export function target(generation, sequence, policy = officialDshPolicy()) {
const emptyHash = '0'.repeat(64)
const artifacts = ['bootstrap-manifest', 'bootstrap-signature', 'environment-manifest', 'environment-signature'].map(id => ({
id,
mediaType: 'application/octet-stream',
sha256: emptyHash,
size: 0,
url: `https://example.com/${id}`,
}))
return {
schema: 1,
updateApi: 1,
keyringGeneration: generation,
targetSequence: sequence,
issuedAt: new Date(Date.UTC(2026, 7, 19, 1, 0, sequence)).toISOString(),
artifacts,
desired: {
bootstrap: { version: '1.0.0', manifestArtifactId: 'bootstrap-manifest', signatureArtifactId: 'bootstrap-signature' },
environment: { version: '1.0.0', manifestArtifactId: 'environment-manifest', signatureArtifactId: 'environment-signature' },
dsh: {
version: '0.1.0-rc.7',
integrity: `sha512-${Buffer.alloc(64).toString('base64')}`,
},
},
officialDshPolicy: policy,
}
}
@@ -0,0 +1,59 @@
import assert from 'node:assert/strict'
import { mkdtemp } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { UpdateJournal } from '../../control-plane/modules/updater/lib/journal.mjs'
const transaction = {
transactionId: 'transaction-one',
mode: 'experimental',
from: {
dsh: '0.1.0-rc.7', environment: 'env-1', runtime: 'runtime-a', dataSnapshot: null, receiptTokens: [],
},
to: { dsh: '0.1.0-rc.8', environment: 'env-1', runtime: 'runtime-b' },
}
test('persists a complete update transaction across process restarts', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-journal-'))
const path = join(root, 'state', 'update-transaction.json')
let tick = 0
const now = () => new Date(Date.UTC(2026, 7, 19, 0, 0, tick++))
const journal = new UpdateJournal(path, now)
await journal.begin(transaction)
await journal.transition('candidate-ready', { receiptTokens: ['receipt-one'] })
await journal.transition('suspended')
await journal.transition('snapshot-created', { snapshotId: 'snapshot-one' })
const resumed = await new UpdateJournal(path, now).read()
assert.equal(resumed.phase, 'snapshot-created')
assert.equal(resumed.from.runtime, 'runtime-a')
assert.equal(resumed.to.runtime, 'runtime-b')
assert.equal(resumed.snapshotId, 'snapshot-one')
assert.deepEqual(resumed.receiptTokens, ['receipt-one'])
})
test('rejects skipped phases and clears only terminal journals', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-journal-transition-'))
const journal = new UpdateJournal(join(root, 'state', 'update-transaction.json'))
await journal.begin(transaction)
await assert.rejects(journal.transition('switched'), /cannot transition/)
await assert.rejects(journal.clear(), /nonterminal/)
await journal.transition('failed', { error: 'candidate build failed' })
await journal.clear()
assert.equal(await journal.read(), undefined)
})
test('records an idempotent data-restoration phase before rollback completion', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-journal-restore-'))
const path = join(root, 'state', 'update-transaction.json')
const journal = new UpdateJournal(path)
await journal.begin(transaction)
await journal.transition('candidate-ready')
await journal.transition('suspended')
await journal.transition('snapshot-created', { snapshotId: 'snapshot-one' })
await journal.transition('switched')
await journal.transition('restoring-data')
assert.equal((await new UpdateJournal(path).read()).phase, 'restoring-data')
await journal.transition('rolled-back')
})
@@ -0,0 +1,50 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { parseKeyring, validateKeyringTransition, verifyRecoveryKeyring } from '../stage0/lib/keyring.mjs'
import { document, keyPair, keyring, signature } from './helpers.mjs'
test('accepts a Recovery-signed keyring with derived current and next IDs', () => {
const recovery = keyPair()
const value = keyring(1, keyPair(), keyPair())
const bytes = document(value)
assert.deepEqual(verifyRecoveryKeyring(bytes, signature(bytes, recovery), recovery.publicKey), value)
})
test('rejects a keyring signed by a non-Recovery key or modified after signing', () => {
const recovery = keyPair()
const other = keyPair()
const bytes = document(keyring(1, keyPair(), keyPair()))
assert.throws(() => verifyRecoveryKeyring(bytes, signature(bytes, other), recovery.publicKey), {
code: 'TRUST_UNKNOWN_KEY',
})
const signed = signature(bytes, recovery)
assert.throws(() => verifyRecoveryKeyring(Buffer.concat([bytes, Buffer.from(' ')]), signed, recovery.publicKey), {
code: 'TRUST_BAD_SIGNATURE',
})
})
test('rejects mismatched IDs, duplicate active keys, revoked active keys, and unknown algorithms', () => {
const current = keyPair()
const next = keyPair()
const cases = [
{ ...keyring(1, current, next), current: { ...keyring(1, current, next).current, keyId: next.keyId } },
{ ...keyring(1, current, next), next: { ...keyring(1, current, next).current } },
{ ...keyring(1, current, next), revokedKeyIds: [current.keyId] },
{ ...keyring(1, current, next), current: { ...keyring(1, current, next).current, algorithm: 'RSA' } },
]
for (const value of cases) assert.throws(() => parseKeyring(document(value)))
})
test('requires transitions to preserve revocations and revoke removed keys', () => {
const first = keyPair()
const second = keyPair()
const third = keyPair()
const fourth = keyPair()
const initial = parseKeyring(document(keyring(1, first, second)))
const rotated = parseKeyring(document(keyring(2, second, third, [first.keyId])))
assert.equal(validateKeyringTransition(initial, rotated), rotated)
assert.throws(() => validateKeyringTransition(initial, parseKeyring(document(keyring(2, second, third)))))
const next = parseKeyring(document(keyring(3, third, fourth, [first.keyId, second.keyId])))
assert.equal(validateKeyringTransition(rotated, next), next)
assert.throws(() => validateKeyringTransition(next, parseKeyring(document(keyring(4, first, fourth, [second.keyId, third.keyId])))))
})
@@ -0,0 +1,162 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { TrustLedger } from '../stage0/lib/ledger.mjs'
import { document, officialDshPolicy, keyPair, keyring, registryCandidate, registryKeyPair, signature, target } from './helpers.mjs'
async function fixture() {
const recovery = keyPair()
return {
recovery,
ledger: new TrustLedger(await mkdtemp(join(tmpdir(), 'dsh-trust-ledger-')), recovery.publicKey),
}
}
test('persists only increasing keyring generations and identical repeats', async () => {
const { ledger, recovery } = await fixture()
const current = keyPair()
const next = keyPair()
const first = document(keyring(1, current, next))
await ledger.acceptKeyring(first, signature(first, recovery))
await ledger.acceptKeyring(first, signature(first, recovery))
const conflicting = document({ ...keyring(1, current, next), issuedAt: '2026-08-19T02:00:00.000Z' })
await assert.rejects(ledger.acceptKeyring(conflicting, signature(conflicting, recovery)))
const older = document(keyring(1, current, next))
const third = keyPair()
const rotated = document(keyring(2, next, third, [current.keyId]))
await ledger.acceptKeyring(rotated, signature(rotated, recovery))
await assert.rejects(ledger.acceptKeyring(older, signature(older, recovery)), { code: 'TRUST_ROLLBACK' })
})
test('accepts targets only from current release key and prevents sequence rollback', async () => {
const { ledger, recovery } = await fixture()
const current = keyPair()
const next = keyPair()
const ring = document(keyring(1, current, next))
await ledger.acceptKeyring(ring, signature(ring, recovery))
const first = document(target(1, 1))
await assert.rejects(ledger.acceptTarget(first, signature(first, next)), { code: 'TRUST_UNKNOWN_KEY' })
await ledger.acceptTarget(first, signature(first, current))
await ledger.acceptTarget(first, signature(first, current))
const conflicting = document({ ...target(1, 1), target: { changed: true } })
await assert.rejects(ledger.acceptTarget(conflicting, signature(conflicting, current)))
const second = document(target(1, 2))
await ledger.acceptTarget(second, signature(second, current))
await assert.rejects(ledger.acceptTarget(first, signature(first, current)), { code: 'TRUST_ROLLBACK' })
})
test('requires an accepted keyring before accepting a target', async () => {
const { ledger } = await fixture()
const release = keyPair()
const bytes = document(target(1, 1))
await assert.rejects(ledger.acceptTarget(bytes, signature(bytes, release)), /keyring/)
})
test('records official DSH identity monotonically without choosing an update channel', async () => {
const { ledger, recovery } = await fixture()
const current = keyPair()
const next = keyPair()
const registry = registryKeyPair()
const ring = document(keyring(1, current, next))
await ledger.acceptKeyring(ring, signature(ring, recovery))
const stable = document(target(1, 4, officialDshPolicy(registry)))
await ledger.acceptTarget(stable, signature(stable, current))
const content = Buffer.from('rc8')
const first = registryCandidate(registry, '0.1.0-rc.8', content)
const digest = createHash('sha256').update(content).digest('hex')
await ledger.acceptOfficialDsh(first, digest, content.byteLength)
await ledger.acceptOfficialDsh(first, digest, content.byteLength)
assert.equal((await ledger.currentOfficialDsh()).value.version, first.version)
const older = registryCandidate(registry, '0.1.0-rc.6', content)
await assert.rejects(ledger.acceptOfficialDsh(older, digest, content.byteLength), { code: 'TRUST_ROLLBACK' })
const conflicting = registryCandidate(registry, first.version, Buffer.from('changed'))
await assert.rejects(
ledger.acceptOfficialDsh(conflicting, createHash('sha256').update('changed').digest('hex'), 7),
/different content/,
)
})
test('rejects new official DSH imports after the target Release Key is revoked', async () => {
const { ledger, recovery } = await fixture()
const current = keyPair()
const next = keyPair()
const registry = registryKeyPair()
const ring = document(keyring(1, current, next))
await ledger.acceptKeyring(ring, signature(ring, recovery))
const stable = document(target(1, 4, officialDshPolicy(registry)))
await ledger.acceptTarget(stable, signature(stable, current))
const content = Buffer.from('rc8')
const candidate = registryCandidate(registry, '0.1.0-rc.8', content)
const digest = createHash('sha256').update(content).digest('hex')
await ledger.acceptOfficialDsh(candidate, digest, content.byteLength)
const future = keyPair()
const rotated = document(keyring(2, next, future, [current.keyId]))
await ledger.acceptKeyring(rotated, signature(rotated, recovery))
await assert.rejects(ledger.acceptOfficialDsh(candidate, digest, content.byteLength), { code: 'TRUST_REVOKED' })
await assert.rejects(ledger.currentOfficialDsh(), { code: 'TRUST_REVOKED' })
})
test('retains historical keyrings so an accepted target remains verifiable after rotation', async () => {
const { ledger, recovery } = await fixture()
const first = keyPair()
const second = keyPair()
const third = keyPair()
const initialRing = document(keyring(1, first, second))
await ledger.acceptKeyring(initialRing, signature(initialRing, recovery))
const initialTarget = document(target(1, 7))
await ledger.acceptTarget(initialTarget, signature(initialTarget, first))
const rotatedRing = document(keyring(2, second, third, [first.keyId]))
await ledger.acceptKeyring(rotatedRing, signature(rotatedRing, recovery))
assert.equal((await ledger.currentTarget()).value.targetSequence, 7)
const rotatedTarget = document(target(2, 8))
await ledger.acceptTarget(rotatedTarget, signature(rotatedTarget, second))
assert.equal((await ledger.currentTarget()).value.keyId, second.keyId)
})
test('serializes concurrent target acceptance in call order', async () => {
const { ledger, recovery } = await fixture()
const current = keyPair()
const next = keyPair()
const ring = document(keyring(1, current, next))
await ledger.acceptKeyring(ring, signature(ring, recovery))
const first = document(target(1, 1))
const second = document(target(1, 2))
await Promise.all([
ledger.acceptTarget(first, signature(first, current)),
ledger.acceptTarget(second, signature(second, current)),
])
assert.equal((await ledger.currentTarget()).value.targetSequence, 2)
})
test('does not overwrite a conflicting historical generation after interrupted promotion', async () => {
const { ledger, recovery } = await fixture()
const first = keyPair()
const second = keyPair()
const third = keyPair()
const initial = document(keyring(1, first, second))
await ledger.acceptKeyring(initial, signature(initial, recovery))
const rotated = document(keyring(2, second, third, [first.keyId]))
await ledger.acceptKeyring(rotated, signature(rotated, recovery))
const rotatedRecord = await readFile(ledger.keyringPath('current.record.json'))
const initialRecord = await readFile(ledger.keyringPath('generations/1.record.json'))
await writeFile(ledger.keyringPath('current.record.json'), initialRecord)
const replacement = keyPair()
const conflicting = document(keyring(2, second, replacement, [first.keyId, third.keyId]))
await assert.rejects(
ledger.acceptKeyring(conflicting, signature(conflicting, recovery)),
/history conflicts/,
)
assert.deepEqual(await readFile(ledger.keyringPath('generations/2.record.json')), rotatedRecord)
})
@@ -0,0 +1,321 @@
import assert from 'node:assert/strict'
import { EventEmitter } from 'node:events'
import { appendFile, chmod, mkdtemp, readFile, readdir, stat, utimes, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { PassThrough } from 'node:stream'
import test from 'node:test'
import { errorDetails, JsonlLogManager } from '../../control-plane/modules/log-manager/index.mjs'
test('writes source-separated JSONL and queries bounded chronological entries', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-logs-'))
const logs = new JsonlLogManager({ root })
await logs.append('gateway', 'stdout', 'ready')
await logs.append('updater', 'platform', 'checked', { taskId: 'one' })
const entries = await logs.query({ sources: ['updater'], limit: 10 })
assert.equal(entries.length, 1)
assert.equal(entries[0].taskId, 'one')
assert.equal(entries[0].level, 'info')
assert.deepEqual((await readdir(root)).sort(), ['gateway.jsonl', 'updater.jsonl'])
assert.equal((await logs.query({ limit: 5_000 })).length, 2)
await assert.rejects(logs.query({ limit: 5_001 }), /log query limit is invalid/)
})
test('filters transaction logs by task, operation, and phase', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-transaction-'))
const logs = new JsonlLogManager({ root })
await logs.append('updater', 'platform', 'download', { taskId: 'task-a', operation: 'update', phase: 'downloading' })
await logs.append('updater', 'platform', 'health', { taskId: 'task-a', operation: 'update', phase: 'switching' })
await logs.append('updater', 'platform', 'other', { taskId: 'task-b', operation: 'rollback', phase: 'switching' })
const entries = await logs.query({ taskId: 'task-a', operation: 'update', phase: 'downloading' })
assert.deepEqual(entries.map(entry => entry.message), ['download'])
const received = []
const follower = await logs.follow({ taskId: 'task-a', operation: 'update', phase: 'switching' }, entry => received.push(entry), { intervalMs: 50 })
try {
await logs.append('updater', 'platform', 'switching-now', { taskId: 'task-a', operation: 'update', phase: 'switching' })
await new Promise(resolve => setTimeout(resolve, 100))
assert.deepEqual(received.map(entry => entry.message), ['switching-now'])
} finally {
follower.close()
}
})
test('follows entries appended by another process without replaying existing logs', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-follow-'))
const logs = new JsonlLogManager({ root })
await logs.append('gateway', 'stdout', 'existing')
const received = []
const follower = await logs.follow({}, entry => received.push(entry), { intervalMs: 50 })
try {
const external = {
timestamp: '2026-08-21T00:00:00.000Z', source: 'gateway', stream: 'stdout', level: 'info', message: '外部日志',
}
const encoded = Buffer.from(`${JSON.stringify(external)}\n`)
const split = encoded.indexOf(Buffer.from('外')) + 1
await appendFile(logs.currentPath('gateway'), encoded.subarray(0, split))
await new Promise(resolve => setTimeout(resolve, 80))
await appendFile(logs.currentPath('gateway'), encoded.subarray(split))
await new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
clearInterval(poll)
reject(new Error('timed out waiting for followed log'))
}, 1_000)
const poll = setInterval(() => {
if (received.length === 0) return
clearTimeout(timeout)
clearInterval(poll)
resolve()
}, 10)
})
assert.deepEqual(received.map(entry => entry.message), ['外部日志'])
} finally {
follower.close()
}
})
test('assigns default levels and accepts only explicit supported levels', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-levels-'))
const logs = new JsonlLogManager({ root })
await logs.append('component', 'stdout', 'ordinary')
await logs.append('component', 'stderr', 'failed')
await logs.append('component', 'platform', 'slow response', { level: 'warning' })
await logs.diagnostic('component', 'completed', { error: null })
assert.deepEqual((await logs.query()).map(entry => entry.level), ['info', 'error', 'warning', 'info'])
await assert.rejects(logs.append('component', 'stdout', 'invalid', { level: 'fatal' }), /log level is invalid/)
})
test('rate-limits repeated diagnostics and reports the suppressed count', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-suppression-'))
let now = Date.parse('2026-08-19T00:00:00.000Z')
const logs = new JsonlLogManager({ root, now: () => new Date(now) })
await logs.diagnosticRateLimited('authentication.failed', 'access-manager', 'access.authentication.failed', {
level: 'warning', kind: 'main',
})
now += 1_000
await logs.diagnosticRateLimited('authentication.failed', 'access-manager', 'access.authentication.failed', {
level: 'warning', kind: 'main',
})
now += 30_000
await logs.diagnosticRateLimited('authentication.failed', 'access-manager', 'access.authentication.failed', {
level: 'warning', kind: 'main',
})
const entries = await logs.query({ sources: ['access-manager'] })
assert.equal(entries.length, 2)
assert.equal(entries[0].suppressedCount, undefined)
assert.equal(entries[1].suppressedCount, 1)
await assert.rejects(
Promise.resolve().then(() => logs.diagnosticRateLimited('invalid key', 'gateway', 'failed')),
/suppression key is invalid/,
)
})
test('applies an explicit shared-reader mode to newly created and rotated log files', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-mode-'))
const logs = new JsonlLogManager({ root, fileMode: 0o640, rotateBytes: 1_024 })
await logs.append('stage0', 'platform', 'first')
assert.equal((await stat(join(root, 'stage0.jsonl'))).mode & 0o777, 0o640)
await logs.append('stage0', 'platform', 'x'.repeat(1_000))
await logs.append('stage0', 'platform', 'rotated')
assert.equal((await stat(join(root, 'stage0.jsonl'))).mode & 0o777, 0o640)
})
test('repairs existing log files for shared Control Plane writers', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-shared-writers-'))
const path = join(root, 'audit.jsonl')
await writeFile(path, '{}\n')
await chmod(path, 0o640)
const logs = new JsonlLogManager({ root, fileMode: 0o660 })
await logs.prepare()
assert.equal((await stat(path)).mode & 0o777, 0o660)
await logs.append('audit', 'audit', 'shared-writer.ready')
assert.equal((await readFile(path, 'utf8')).includes('shared-writer.ready'), true)
})
test('rotates files and enforces the aggregate byte budget', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-rotation-'))
const logs = new JsonlLogManager({ root, maxBytes: 70_000, rotateBytes: 10_000 })
for (let index = 0; index < 150; index += 1) await logs.append('gateway', 'stdout', 'x'.repeat(800))
const files = await logs.files()
assert.ok(files.length > 1)
assert.ok(files.reduce((sum, file) => sum + file.details.size, 0) <= 70_000)
})
test('prunes expired logs and captures complete child output lines', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-retention-'))
const logs = new JsonlLogManager({ root, retentionDays: 1 })
await logs.append('old', 'stdout', 'expired')
const oldPath = join(root, 'old.jsonl')
const old = new Date(Date.now() - 2 * 86_400_000)
await utimes(oldPath, old, old)
await logs.prune()
await assert.rejects(stat(oldPath), { code: 'ENOENT' })
const child = new EventEmitter()
child.stdout = new PassThrough()
child.stderr = new PassThrough()
logs.capture(child, 'component', { stdout: true, stderr: false })
child.stdout.end('one\ntwo')
await new Promise(resolve => setImmediate(resolve))
await logs.queue
assert.deepEqual((await logs.query({ sources: ['component'] })).map(entry => entry.message), ['one', 'two'])
})
test('captures one multiline Node error as one log entry', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-multiline-error-'))
const logs = new JsonlLogManager({ root })
const child = new EventEmitter()
child.stderr = new PassThrough()
logs.capture(child, 'dsh-runtime', { stdout: false, stderr: true })
child.stderr.write('ordinary before\nfile:///app/index.js:2\n throw new Error("startup failed")\n')
child.stderr.end(' ^\n\nError: startup failed\n at file:///app/index.js:2:9\n\nNode.js v24.20.0\nordinary after\n')
await new Promise(resolve => setImmediate(resolve))
await logs.queue
assert.deepEqual((await logs.query({ sources: ['dsh-runtime'] })).map(entry => ({
level: entry.level,
message: entry.message,
})), [
{ level: 'info', message: 'ordinary before' },
{
level: 'error',
message: 'file:///app/index.js:2\n throw new Error("startup failed")\n ^\n\nError: startup failed\n at file:///app/index.js:2:9\n\nNode.js v24.20.0',
},
{ level: 'info', message: 'ordinary after' },
])
})
test('does not group multiline stderr from other components', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-other-stderr-'))
const logs = new JsonlLogManager({ root })
const child = new EventEmitter()
child.stderr = new PassThrough()
logs.capture(child, 'gateway', { stdout: false, stderr: true })
child.stderr.end('Error: first line\n at second line\nordinary line\n')
await new Promise(resolve => setImmediate(resolve))
await logs.queue
assert.deepEqual((await logs.query({ sources: ['gateway'] })).map(entry => entry.message), [
'Error: first line', ' at second line', 'ordinary line',
])
})
test('mirrors new entries to the matching container output without replaying history', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-output-'))
const stdout = []
const stderr = []
const logs = new JsonlLogManager({
root,
now: () => new Date('2026-08-19T00:00:00.000Z'),
output: {
stdout: { write: value => stdout.push(value) },
stderr: { write: value => stderr.push(value) },
},
})
await logs.append('gateway', 'stdout', 'ready')
await logs.append('dsh-runtime', 'stderr', 'failed')
assert.deepEqual(stdout.map(line => JSON.parse(line)), [{
timestamp: '2026-08-19T00:00:00.000Z', source: 'gateway', stream: 'stdout', message: 'ready',
level: 'info', platformLog: 'dsh-platform-log-v1',
}])
assert.deepEqual(stderr.map(line => JSON.parse(line)), [{
timestamp: '2026-08-19T00:00:00.000Z', source: 'dsh-runtime', stream: 'stderr', message: 'failed',
level: 'error', platformLog: 'dsh-platform-log-v1',
}])
const secondOutput = []
const restarted = new JsonlLogManager({
root,
output: { stdout: { write: value => secondOutput.push(value) }, stderr: { write: value => secondOutput.push(value) } },
})
assert.equal((await restarted.query()).length, 2)
assert.deepEqual(secondOutput, [])
})
test('passes a platform-management envelope through without persisting it twice', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-forwarded-'))
const stdout = []
const stderr = []
const logs = new JsonlLogManager({
root,
output: {
stdout: { write: value => stdout.push(value) },
stderr: { write: value => stderr.push(value) },
},
})
const child = new EventEmitter()
child.stdout = new PassThrough()
child.stderr = new PassThrough()
logs.capture(child, 'platform-management', { stdout: true, stderr: true }, { acceptForwarded: true })
const audit = JSON.stringify({
timestamp: '2026-08-19T00:00:00.000Z', source: 'audit', stream: 'audit', message: 'update.started',
platformLog: 'dsh-platform-log-v1', taskId: 'task-one',
})
child.stdout.end(`${audit}\nplain output\n`)
child.stderr.end('[net-proxy] 已启用代理 http://172.17.0.1:7890\nwarning: slow proxy\nplain error\n')
await new Promise(resolve => setImmediate(resolve))
await logs.queue
assert.equal(stdout[0], `${audit}\n`)
assert.equal(JSON.parse(stdout[1]).source, 'platform-management')
assert.equal(JSON.parse(stderr[0]).stream, 'stderr')
assert.deepEqual(
(await logs.query({ sources: ['platform-management'] })).map(entry => [entry.stream, entry.level, entry.message]),
[
['stdout', 'info', 'plain output'],
['stderr', 'info', '[net-proxy] 已启用代理 http://172.17.0.1:7890'],
['stderr', 'warning', 'warning: slow proxy'],
['stderr', 'error', 'plain error'],
],
)
assert.deepEqual(await logs.query({ sources: ['audit'] }), [])
const bootstrap = await readFile(new URL('../bootstrap/index.mjs', import.meta.url), 'utf8')
assert.match(bootstrap, /acceptForwarded: \['gateway', 'platform-management'\]\.includes\(source\)/)
})
test('records bounded structured error diagnostics in JSONL and container output', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-log-diagnostic-'))
const stdout = []
const logs = new JsonlLogManager({
root,
now: () => new Date('2026-08-20T00:00:00.000Z'),
output: { stdout: { write: value => stdout.push(value) } },
})
const cause = Object.assign(new Error('socket unavailable'), { code: 'ECONNREFUSED' })
const failure = new AggregateError([cause, 'secondary failure'], 'startup failed', { cause })
await logs.diagnostic('stage0', 'bootstrap.launch.failed', { error: failure, recordId: 'bootstrap-one' })
const [entry] = await logs.query({ sources: ['stage0'] })
assert.equal(entry.message, 'bootstrap.launch.failed')
assert.equal(entry.recordId, 'bootstrap-one')
assert.equal(entry.error, 'startup failed')
assert.equal(entry.errorCause.errorCode, 'ECONNREFUSED')
assert.equal(entry.errors[1].error, 'secondary failure')
assert.match(entry.errorStack, /AggregateError: startup failed/)
assert.equal(JSON.parse(stdout[0]).platformLog, 'dsh-platform-log-v1')
})
test('falls back to container stderr when a diagnostic cannot be persisted', async () => {
const stderr = []
const logs = new JsonlLogManager({
root: '/dev/null/not-a-directory',
now: () => new Date('2026-08-20T00:00:00.000Z'),
output: { stderr: { write: value => stderr.push(value) } },
})
await logs.diagnostic('updater', 'update.failed', { error: new Error('network failed'), taskId: 'one' })
const fallback = JSON.parse(stderr[0])
assert.equal(fallback.message, 'diagnostic.write.failed')
assert.equal(fallback.diagnostic.message, 'update.failed')
assert.equal(fallback.diagnostic.error, 'network failed')
assert.equal(fallback.loggingError.errorCode, 'ENOTDIR')
})
test('bounds recursive and oversized error details', () => {
let failure = new Error('root')
for (let index = 0; index < 6; index += 1) failure = new Error(`level-${String(index)}`, { cause: failure })
const details = errorDetails(new AggregateError(Array.from({ length: 10 }, (_, index) => new Error(String(index))), 'x'.repeat(20_000), { cause: failure }))
assert.equal(details.error.endsWith('...[truncated]'), true)
assert.equal(details.errors.length, 8)
assert.equal(details.errorsTruncated, 2)
assert.equal(details.errorCause.errorCause.errorCause.errorCause, undefined)
})
@@ -0,0 +1,372 @@
import assert from 'node:assert/strict'
import { chmod, mkdir, mkdtemp, readFile, rename, rm, writeFile } from 'node:fs/promises'
import { createServer } from 'node:http'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { pathToFileURL } from 'node:url'
import test from 'node:test'
import {
applyPatch,
MANAGED_LIFECYCLE_MODULE,
PROFILE_PACKAGE_STORAGE_MODULE,
verifyPatch,
} from '../../environment/resources/patches/managed-lifecycle.mjs'
async function fixture({ duplicateImport = false, sigterm = true, wrapper = true } = {}) {
const root = await mkdtemp(join(tmpdir(), 'dsh-managed-lifecycle-patch-'))
await mkdir(join(root, 'lib'))
await writeFile(join(root, 'package.json'), '{"type":"module"}\n')
const dynamicImport = 'const { runProfile } = await import("./profile-boot-wrapper_42.js");'
await writeFile(join(root, 'lib/bin.js'), `#!/usr/bin/env node
const invocation = parseDshArgs(process.argv.slice(2), readVersion());
switch (invocation.mode) {
case "profile": {
${dynamicImport}
${duplicateImport ? dynamicImport : ''}
}
}
`)
await writeFile(join(root, 'lib/profile-boot-wrapper_42.js'), wrapper
? 'import { x as runProfile } from "./profile-boot-anyHash.js";\nexport { runProfile };\n'
: 'export const unrelated = true;\n')
await writeFile(join(root, 'lib/profile-boot-anyHash.js'), `async function runProfile(options) {
${sigterm ? '\tprocess.on("SIGTERM", () => {\n\t\tinterrupt(0);\n\t});' : '\tprocess.on("SIGHUP", () => interrupt(0));'}
\tprocess.on("SIGINT", () => { interrupt(130); });
\tconst ctx = await boot(NAME, rootConfig, patches, (hostCtx) => {
\t\thostCtx.provide(DSH_LAUNCH_ENVIRONMENT_KEY, options.environment);
\t});
\treturn {
\t\tctx,
\t\tshutdown
\t};
}
export { runProfile as x };
`)
return root
}
async function listen(socketPath, handler) {
const server = createServer(handler)
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(socketPath, resolve)
})
await chmod(socketPath, 0o600)
return server
}
function json(response, status, value) {
response.writeHead(status, { 'content-type': 'application/json' })
response.end(JSON.stringify(value))
}
test('patches a hash-independent Profile import chain exactly once', async () => {
const root = await fixture()
applyPatch(root)
verifyPatch(root)
assert.match(await readFile(join(root, 'lib/bin.js'), 'utf8'), /prepareManagedInvocation/)
assert.match(await readFile(join(root, 'lib/profile-boot-anyHash.js'), 'utf8'), /managedSigtermHandler/)
assert.match(await readFile(join(root, MANAGED_LIFECYCLE_MODULE), 'utf8'), /dshPlatformLifecycle/)
assert.match(await readFile(join(root, PROFILE_PACKAGE_STORAGE_MODULE), 'utf8'), /prepareProfilePackageStorage/)
assert.throws(() => applyPatch(root), /already applied/)
})
test('fails closed when upstream Profile anchors are missing or ambiguous', async () => {
await assert.rejects(Promise.resolve().then(async () => applyPatch(await fixture({ duplicateImport: true }))), /found 2/)
await assert.rejects(Promise.resolve().then(async () => applyPatch(await fixture({ wrapper: false }))), /found 0/)
await assert.rejects(Promise.resolve().then(async () => applyPatch(await fixture({ sigterm: false }))), /SIGTERM handler.*found 0/)
})
async function fakePnpm(root) {
const bin = join(root, 'bin')
await mkdir(bin, { recursive: true })
const executable = join(bin, 'pnpm')
await writeFile(executable, `#!/usr/bin/env node
import { mkdirSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
if (process.env.DSH_TEST_PNPM_FAIL === '1') {
process.stderr.write('fixture pnpm failed\\n')
process.exit(1)
}
const workspace = await import('node:fs').then(({ readFileSync }) => readFileSync('pnpm-workspace.yaml', 'utf8'))
const match = /^storeDir:\\s*(.+)$/m.exec(workspace)
if (match === null) process.exit(2)
const storeRoot = JSON.parse(match[1])
mkdirSync('node_modules', { recursive: true })
writeFileSync(join('node_modules', '.modules.yaml'), JSON.stringify({ storeDir: join(storeRoot, 'v11') }))
writeFileSync(join('node_modules', 'migration-marker'), 'rebuilt\\n')
`)
await chmod(executable, 0o755)
return bin
}
test('pins compatible Profiles to their custom DSH_HOME store', async () => {
const root = await fixture()
applyPatch(root)
const storage = await import(`${pathToFileURL(join(root, PROFILE_PACKAGE_STORAGE_MODULE)).href}?storage`)
const dshHome = await mkdtemp(join(tmpdir(), 'dsh-profile-storage-home-'))
const profileDir = join(dshHome, 'profiles', 'web')
const workspacePath = join(profileDir, 'pnpm-workspace.yaml')
const modulesRoot = join(profileDir, 'node_modules')
await mkdir(modulesRoot, { recursive: true })
await writeFile(join(profileDir, 'package.json'), '{"name":"dsh-profile-web"}\n')
await writeFile(workspacePath, 'packages:\n - .\n\nnodeLinker: hoisted\n')
const previousHome = process.env.DSH_HOME
process.env.DSH_HOME = dshHome
try {
assert.deepEqual(storage.prepareProfilePackageStorage('web'), {
status: 'ready',
currentStore: null,
storeRoot: join(dshHome, '.pnpm-store'),
})
assert.match(await readFile(workspacePath, 'utf8'), new RegExp(
`storeDir: ${JSON.stringify(join(dshHome, '.pnpm-store')).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`,
))
await writeFile(join(modulesRoot, '.modules.yaml'), JSON.stringify({
storeDir: join(dshHome, '.pnpm-store', 'v11'),
}))
assert.equal(storage.prepareProfilePackageStorage('web').status, 'ready')
assert.equal((await readFile(workspacePath, 'utf8')).match(/^storeDir:/gm)?.length, 1)
const ambiguous = `${await readFile(workspacePath, 'utf8')}storeDir: "/another/store"\n`
await writeFile(workspacePath, ambiguous)
assert.throws(() => storage.prepareProfilePackageStorage('web'), /multiple storeDir entries/)
assert.equal(await readFile(workspacePath, 'utf8'), ambiguous)
} finally {
if (previousHome === undefined) delete process.env.DSH_HOME
else process.env.DSH_HOME = previousHome
}
})
test('migrates a legacy Profile store and recovers a failed or interrupted rebuild', async () => {
const root = await fixture()
applyPatch(root)
const storage = await import(`${pathToFileURL(join(root, PROFILE_PACKAGE_STORAGE_MODULE)).href}?migration`)
const dshHome = await mkdtemp(join(tmpdir(), 'dsh-profile-migration-home-'))
const profileDir = join(dshHome, 'profiles', 'web')
const modulesRoot = join(profileDir, 'node_modules')
const workspacePath = join(profileDir, 'pnpm-workspace.yaml')
const legacyStore = join(root, 'workspace', '.pnpm-store', 'v11')
const originalWorkspace = `packages:\n - .\n\nstoreDir: ${JSON.stringify(dirname(legacyStore))}\n`
await mkdir(modulesRoot, { recursive: true })
await mkdir(legacyStore, { recursive: true })
await writeFile(join(legacyStore, 'store-marker'), 'cached\n')
await writeFile(join(modulesRoot, '.modules.yaml'), JSON.stringify({ storeDir: legacyStore }))
await writeFile(join(modulesRoot, 'original-marker'), 'original\n')
await writeFile(join(profileDir, 'package.json'), '{"name":"dsh-profile-web","private":true}\n')
await writeFile(join(profileDir, 'pnpm-lock.yaml'), 'lockfileVersion: 9\n')
await writeFile(workspacePath, originalWorkspace)
const bin = await fakePnpm(root)
const previous = {
DSH_HOME: process.env.DSH_HOME,
PATH: process.env.PATH,
DSH_TEST_PNPM_FAIL: process.env.DSH_TEST_PNPM_FAIL,
}
process.env.DSH_HOME = dshHome
process.env.PATH = `${bin}:${process.env.PATH}`
try {
assert.deepEqual(storage.prepareProfilePackageStorage('web'), {
status: 'migrated',
currentStore: join(dshHome, '.pnpm-store', 'v11'),
storeRoot: join(dshHome, '.pnpm-store'),
})
assert.equal(await readFile(join(dshHome, '.pnpm-store', 'v11', 'store-marker'), 'utf8'), 'cached\n')
assert.equal(await readFile(join(modulesRoot, 'migration-marker'), 'utf8'), 'rebuilt\n')
await assert.rejects(readFile(join(profileDir, '.dsh-platform-node_modules.previous')), { code: 'ENOENT' })
await assert.rejects(readFile(join(profileDir, '.dsh-platform-pnpm-workspace.previous')), { code: 'ENOENT' })
await rm(modulesRoot, { recursive: true })
await mkdir(modulesRoot)
await writeFile(join(modulesRoot, '.modules.yaml'), JSON.stringify({ storeDir: legacyStore }))
await writeFile(join(modulesRoot, 'original-marker'), 'restored\n')
await writeFile(workspacePath, originalWorkspace)
process.env.DSH_TEST_PNPM_FAIL = '1'
assert.throws(() => storage.prepareProfilePackageStorage('web'), /fixture pnpm failed/)
assert.equal(await readFile(join(modulesRoot, 'original-marker'), 'utf8'), 'restored\n')
assert.equal(await readFile(workspacePath, 'utf8'), originalWorkspace)
delete process.env.DSH_TEST_PNPM_FAIL
await writeFile(join(profileDir, '.dsh-platform-pnpm-workspace.previous'), originalWorkspace)
await writeFile(workspacePath, `packages:\n - .\n\nstoreDir: ${JSON.stringify(join(dshHome, '.pnpm-store'))}\n`)
assert.equal(storage.prepareProfilePackageStorage('web').status, 'migrated')
assert.equal(await readFile(join(modulesRoot, 'migration-marker'), 'utf8'), 'rebuilt\n')
await rm(modulesRoot, { recursive: true })
await mkdir(modulesRoot)
await writeFile(join(modulesRoot, '.modules.yaml'), JSON.stringify({ storeDir: legacyStore }))
await writeFile(join(modulesRoot, 'original-marker'), 'interrupted\n')
await writeFile(workspacePath, originalWorkspace)
await writeFile(join(profileDir, '.dsh-platform-pnpm-workspace.previous'), originalWorkspace)
await rename(modulesRoot, join(profileDir, '.dsh-platform-node_modules.previous'))
await writeFile(workspacePath, `packages:\n - .\n\nstoreDir: ${JSON.stringify(join(dshHome, '.pnpm-store'))}\n`)
assert.equal(storage.prepareProfilePackageStorage('web').status, 'migrated')
assert.equal(await readFile(join(modulesRoot, 'migration-marker'), 'utf8'), 'rebuilt\n')
await rm(modulesRoot, { recursive: true })
await mkdir(modulesRoot)
await writeFile(join(modulesRoot, '.modules.yaml'), JSON.stringify({
storeDir: join(dshHome, '.pnpm-store', 'v11'),
}))
await writeFile(join(modulesRoot, 'partial-marker'), 'partial\n')
await writeFile(workspacePath, `packages:\n - .\n\nstoreDir: ${JSON.stringify(join(dshHome, '.pnpm-store'))}\n`)
await mkdir(join(profileDir, '.dsh-platform-node_modules.previous'))
await writeFile(join(profileDir, '.dsh-platform-node_modules.previous', '.modules.yaml'), JSON.stringify({
storeDir: legacyStore,
}))
await writeFile(join(profileDir, '.dsh-platform-node_modules.previous', 'original-marker'), 'original\n')
await writeFile(join(profileDir, '.dsh-platform-pnpm-workspace.previous'), originalWorkspace)
assert.equal(storage.prepareProfilePackageStorage('web').status, 'migrated')
assert.equal(await readFile(join(modulesRoot, 'migration-marker'), 'utf8'), 'rebuilt\n')
await assert.rejects(readFile(join(modulesRoot, 'partial-marker')), { code: 'ENOENT' })
} finally {
for (const [name, value] of Object.entries(previous)) {
if (value === undefined) delete process.env[name]
else process.env[name] = value
}
}
})
test('gates only managed Web launches and routes restart through Management', async t => {
const root = await fixture()
applyPatch(root)
const runRoot = await mkdtemp(join(tmpdir(), 'dsh-managed-lifecycle-run-'))
const dshHome = await mkdtemp(join(tmpdir(), 'dsh-managed-lifecycle-home-'))
const profileDir = join(dshHome, 'profiles', 'web')
await mkdir(profileDir, { recursive: true })
await mkdir(join(root, 'node_modules', 'built-in-bundle'), { recursive: true })
await writeFile(join(root, 'node_modules', 'built-in-bundle', 'package.json'), '{"name":"built-in-bundle"}\n')
const profileManifest = join(profileDir, 'package.json')
await writeFile(join(profileDir, 'pnpm-workspace.yaml'), 'packages:\n - .\n\nnodeLinker: hoisted\n')
await writeFile(profileManifest, JSON.stringify({
dependencies: { 'missing-dependency': '1.0.0' },
dsh: { profile: { bundles: ['built-in-bundle', 'removed-plugin', '../../outside', 'missing-dependency'] } },
}, null, 2))
const calls = []
let claimStatus = 200
let disposition = 'request-restart'
let lifecycleState = 'running'
let signalDelayMs = 0
const broker = await listen(join(runRoot, 'dsh-lifecycle.sock'), async (request, response) => {
const chunks = []
for await (const chunk of request) chunks.push(chunk)
calls.push({ socket: 'broker', path: request.url, body: JSON.parse(Buffer.concat(chunks)) })
if (claimStatus !== 200) json(response, claimStatus, { error: 'launch already claimed' })
else if (request.url === '/v1/runtime/claim') json(response, 200, { sessionId: 'session-1' })
else if (request.url === '/v1/runtime/ready') json(response, 200, { ready: true })
else {
if (signalDelayMs > 0) await new Promise(resolve => setTimeout(resolve, signalDelayMs))
json(response, 200, { disposition })
}
})
const management = await listen(join(runRoot, 'management-cli.sock'), (request, response) => {
calls.push({ socket: 'management', path: request.url })
if (request.url?.endsWith('/status')) json(response, 200, { dshLifecycle: { state: lifecycleState }, recoveryMode: null })
else json(response, 202, { taskId: request.url?.endsWith('/start-dsh') ? 'start-task' : 'restart-task' })
})
t.after(() => { broker.close(); management.close() })
const previous = Object.fromEntries(['DSH_HOME', 'DSH_PLATFORM_MANAGED', 'DSH_PLATFORM_RUN', 'DSH_PLATFORM_LAUNCH_TOKEN']
.map(name => [name, process.env[name]]))
process.env.DSH_HOME = dshHome
process.env.DSH_PLATFORM_MANAGED = '1'
process.env.DSH_PLATFORM_RUN = runRoot
process.env.DSH_PLATFORM_LAUNCH_TOKEN = 'launch-token'
try {
const adapter = await import(`${pathToFileURL(join(root, MANAGED_LIFECYCLE_MODULE)).href}?authorized`)
assert.equal(await adapter.prepareManagedInvocation({ mode: 'plugin', profile: 'web' }), null)
assert.equal(calls.length, 0)
assert.match(await readFile(join(profileDir, 'pnpm-workspace.yaml'), 'utf8'), new RegExp(
`storeDir: ${JSON.stringify(join(dshHome, '.pnpm-store')).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`,
))
assert.equal(await adapter.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), null)
assert.equal(process.env.DSH_PLATFORM_LAUNCH_TOKEN, undefined)
assert.deepEqual(
JSON.parse(await readFile(profileManifest, 'utf8')).dsh.profile.bundles,
['built-in-bundle', 'missing-dependency'],
)
await adapter.markManagedReady({
get: name => name === 'connection'
? { authenticatedUrl: base => `${base}/?token=fixture-token` }
: name === 'webServer' ? { port: 3079 } : undefined,
})
assert.equal(calls.some(value => value.socket === 'broker' && value.path === '/v1/runtime/ready'), true)
assert.deepEqual(calls.find(value => value.path === '/v1/runtime/ready')?.body, {
sessionId: 'session-1',
readyUrl: 'http://127.0.0.1:3079/?token=fixture-token',
})
let provided
adapter.provideManagedLifecycle({ provide: (name, value) => { provided = { name, value } } })
assert.equal(provided.name, 'dshPlatformLifecycle')
assert.deepEqual(await provided.value.restart(), { taskId: 'restart-task' })
const restartCallsBeforeSigterm = calls.filter(value => value.path?.endsWith('/restart-dsh')).length
let interrupts = 0
const onSigterm = adapter.managedSigtermHandler(() => { interrupts += 1 })
onSigterm()
for (let attempt = 0; attempt < 50 && calls.filter(value => value.path?.endsWith('/restart-dsh')).length === restartCallsBeforeSigterm; attempt += 1) {
await new Promise(resolve => setTimeout(resolve, 5))
}
assert.equal(calls.some(value => value.socket === 'broker' && value.path === '/v1/runtime/signal'), true)
assert.equal(calls.filter(value => value.path?.endsWith('/restart-dsh')).length, restartCallsBeforeSigterm + 1)
assert.equal(interrupts, 0)
onSigterm()
assert.equal(interrupts, 1)
const restartCallsBeforeCancellation = calls.filter(value => value.path?.endsWith('/restart-dsh')).length
signalDelayMs = 30
let cancellationInterrupts = 0
const cancelSigterm = adapter.managedSigtermHandler(() => { cancellationInterrupts += 1 })
cancelSigterm()
cancelSigterm()
await new Promise(resolve => setTimeout(resolve, 50))
assert.equal(cancellationInterrupts, 1)
assert.equal(calls.filter(value => value.path?.endsWith('/restart-dsh')).length, restartCallsBeforeCancellation)
signalDelayMs = 0
disposition = 'terminate'
let terminationInterrupts = 0
const managementCalls = calls.filter(value => value.path?.endsWith('/restart-dsh')).length
adapter.managedSigtermHandler(() => { terminationInterrupts += 1 })()
for (let attempt = 0; attempt < 50 && terminationInterrupts === 0; attempt += 1) {
await new Promise(resolve => setTimeout(resolve, 5))
}
assert.equal(terminationInterrupts, 1)
assert.equal(calls.filter(value => value.path?.endsWith('/restart-dsh')).length, managementCalls)
claimStatus = 409
disposition = 'request-restart'
const duplicate = await import(`${pathToFileURL(join(root, MANAGED_LIFECYCLE_MODULE)).href}?duplicate`)
assert.equal(await duplicate.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), 0)
lifecycleState = 'stopped'
const stopped = await import(`${pathToFileURL(join(root, MANAGED_LIFECYCLE_MODULE)).href}?stopped`)
assert.equal(await stopped.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), 0)
assert.equal(calls.some(value => value.path?.endsWith('/start-dsh')), true)
lifecycleState = 'failed'
const failed = await import(`${pathToFileURL(join(root, MANAGED_LIFECYCLE_MODULE)).href}?failed`)
assert.equal(await failed.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), 1)
} finally {
for (const [name, value] of Object.entries(previous)) {
if (value === undefined) delete process.env[name]
else process.env[name] = value
}
}
})
test('keeps native behavior without the image marker and fails closed without the Broker', async () => {
const root = await fixture()
applyPatch(root)
const adapter = await import(`${pathToFileURL(join(root, MANAGED_LIFECYCLE_MODULE)).href}?fail-closed`)
const previous = Object.fromEntries(['DSH_PLATFORM_MANAGED', 'DSH_PLATFORM_RUN']
.map(name => [name, process.env[name]]))
try {
delete process.env.DSH_PLATFORM_MANAGED
assert.equal(await adapter.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), null)
process.env.DSH_PLATFORM_MANAGED = '1'
process.env.DSH_PLATFORM_RUN = await mkdtemp(join(tmpdir(), 'dsh-no-broker-'))
assert.equal(await adapter.prepareManagedInvocation({ mode: 'profile', profile: 'web' }), 1)
} finally {
for (const [name, value] of Object.entries(previous)) {
if (value === undefined) delete process.env[name]
else process.env[name] = value
}
}
})
@@ -0,0 +1,208 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { spawnSync } from 'node:child_process'
import { lstat, mkdir, mkdtemp, readFile, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { ManagedDeploymentBuilder } from '../../control-plane/modules/updater/lib/managed-store.mjs'
import { canonicalJson } from '../lib/canonical-json.mjs'
import { deriveRecordId } from '../lib/deployment-contracts.mjs'
import { PlatformPaths, preparePersistentLayout } from '../lib/paths.mjs'
test('builds a complete content-addressed Managed Deployment from verified inputs', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-managed-store-'))
const paths = new PlatformPaths(join(root, 'data'), join(root, 'run'))
await preparePersistentLayout(paths)
const dependencyRoot = join(root, 'dependency', 'package')
await mkdir(join(dependencyRoot, 'lib'), { recursive: true })
await writeFile(join(dependencyRoot, 'package.json'), JSON.stringify({ name: 'fixture-dependency', version: '1.0.0' }))
await writeFile(join(dependencyRoot, 'lib', 'index.js'), 'export const installed = true\n')
const dependencyArchive = join(root, 'fixture-dependency.tgz')
const packedDependency = spawnSync('tar', ['-czf', dependencyArchive, '-C', join(root, 'dependency'), 'package'], { encoding: 'utf8' })
assert.equal(packedDependency.status, 0, packedDependency.stderr)
const packageRoot = join(root, 'source', 'package')
await mkdir(join(packageRoot, 'lib'), { recursive: true })
await writeFile(join(packageRoot, 'package.json'), JSON.stringify({
name: '@deepseek-ai/dsh',
version: '0.1.0-rc.8',
dependencies: { 'fixture-dependency': `file:${dependencyArchive}` },
}))
await writeFile(join(packageRoot, 'lib', 'bin.js'), '#!/usr/bin/env node\n')
const archive = join(root, 'dsh.tgz')
const packed = spawnSync('tar', ['-czf', archive, '-C', join(root, 'source'), 'package'], { encoding: 'utf8' })
assert.equal(packed.status, 0, packed.stderr)
const archiveBytes = await readFile(archive)
const objectSha256 = createHash('sha256').update(archiveBytes).digest('hex')
const trustedObjectPath = join(paths.objectsRoot, objectSha256)
await writeFile(trustedObjectPath, archiveBytes)
const manifestPath = join(root, 'environment.manifest.json')
const manifest = {
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: 1,
targetSequence: 2,
issuedAt: '2026-08-19T00:00:00.000Z',
artifacts: [],
bootstrapApi: 1,
components: [],
patches: [],
systemPlugins: [],
}
await writeFile(manifestPath, canonicalJson(manifest))
const prepared = {
stable: {
targetSequence: 2,
desired: { environment: { manifestArtifactId: 'environment-manifest' } },
},
environment: {
manifest,
manifestReceipt: { objectSha256: createHash('sha256').update(await readFile(manifestPath)).digest('hex') },
},
paths: new Map([['environment-manifest', manifestPath]]),
dsh: { version: '0.1.0-rc.8', receipt: { path: trustedObjectPath, objectSha256 } },
receiptTokens: ['stable-receipt', 'dsh-receipt'],
}
const builder = new ManagedDeploymentBuilder({ paths })
const progress = []
const first = await builder.buildStable(prepared, { onProgress: async value => progress.push(value) })
assert.deepEqual(progress.filter(value => typeof value === 'number'), [80, 82, 87, 89])
const runtimeProgress = progress.filter(value => typeof value === 'object')
assert.ok(runtimeProgress.length > 0)
assert.equal(runtimeProgress.at(-1).processedBytes, runtimeProgress.at(-1).totalBytes)
assert.equal(runtimeProgress.at(-1).processedItems, runtimeProgress.at(-1).totalItems)
assert.equal(first.assets.pristine.id, `pristine-npm-${objectSha256}`)
assert.equal(first.record.authority, 'stable')
assert.equal(first.record.targetSequence, 2)
assert.equal(first.record.dshVersion, '0.1.0-rc.8')
assert.deepEqual(first.record.receiptTokens, ['stable-receipt', 'dsh-receipt'])
for (const reference of [
first.record.environment,
first.record.pristine,
first.record.runtime,
first.record.systemPlugins,
]) {
assert.equal(reference.storage, 'store')
const storeRoot = reference.kind === 'environment'
? paths.environmentsRoot
: reference.kind === 'pristine'
? paths.pristineRoot
: reference.kind === 'runtime'
? paths.runtimesRoot
: paths.systemPluginsRoot
assert.equal((await lstat(join(storeRoot, reference.id))).isDirectory(), true)
}
assert.equal(await readFile(join(first.assets.runtime.path, 'package', 'package.json'), 'utf8'), await readFile(join(packageRoot, 'package.json'), 'utf8'))
assert.equal(
await readFile(join(first.assets.pristine.path, 'node_modules', 'fixture-dependency', 'lib', 'index.js'), 'utf8'),
'export const installed = true\n',
)
await assert.rejects(lstat(join(first.assets.pristine.path, 'npm-cache')), error => error?.code === 'ENOENT')
assert.deepEqual(await readFile(trustedObjectPath), archiveBytes)
assert.equal((await lstat(trustedObjectPath)).isSymbolicLink(), false)
assert.equal((await readFile(join(first.assets.systemPlugins.path, 'cordis.patch.yml'), 'utf8')).trim(), '[]')
const repeated = await builder.buildStable(prepared)
assert.equal(repeated.record.id, first.record.id)
assert.deepEqual(repeated.record, first.record)
const experimentalPackage = join(root, 'experimental-source', 'package')
await mkdir(join(experimentalPackage, 'lib'), { recursive: true })
await writeFile(join(experimentalPackage, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', version: '0.1.0-rc.9' }))
await writeFile(join(experimentalPackage, 'lib', 'bin.js'), '#!/usr/bin/env node\n')
const experimentalArchive = join(root, 'experimental.tgz')
const experimentalPacked = spawnSync('tar', [
'-czf', experimentalArchive, '-C', join(root, 'experimental-source'), 'package',
], { encoding: 'utf8' })
assert.equal(experimentalPacked.status, 0, experimentalPacked.stderr)
await mkdir(paths.viewsRoot, { recursive: true })
await symlink(first.assets.environment.path, join(paths.viewsRoot, 'environment'), 'dir')
const { id: _stableId, ...developmentContent } = first.record
developmentContent.authority = 'development'
developmentContent.targetSequence = 0
const developmentRecord = { ...developmentContent, id: deriveRecordId('deployment-record', developmentContent) }
const experimental = await builder.buildExperimental({
version: '0.1.0-rc.9',
receipt: {
path: experimentalArchive,
objectSha256: createHash('sha256').update(await readFile(experimentalArchive)).digest('hex'),
},
}, developmentRecord, ['stable-receipt', 'experimental-receipt'], { targetSequence: 11 })
assert.equal(experimental.record.authority, 'experimental')
assert.equal(experimental.record.targetSequence, 11)
assert.equal(experimental.record.dshVersion, '0.1.0-rc.9')
assert.deepEqual(experimental.record.environment, first.record.environment)
assert.deepEqual(experimental.record.systemPlugins, first.record.systemPlugins)
assert.notEqual(experimental.record.pristine.id, first.record.pristine.id)
assert.notEqual(experimental.record.runtime.id, first.record.runtime.id)
assert.deepEqual(experimental.record.receiptTokens, ['stable-receipt', 'experimental-receipt'])
})
test('retries a partially published npm dependency graph in fresh install roots', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-managed-store-retry-'))
const paths = new PlatformPaths(join(root, 'data'), join(root, 'run'))
await preparePersistentLayout(paths)
const packageRoot = join(root, 'source', 'package')
await mkdir(packageRoot, { recursive: true })
await writeFile(join(packageRoot, 'package.json'), JSON.stringify({
name: '@deepseek-ai/dsh', version: '0.1.5-rc.1',
}))
const archive = join(root, 'dsh.tgz')
const packed = spawnSync('tar', ['-czf', archive, '-C', join(root, 'source'), 'package'], { encoding: 'utf8' })
assert.equal(packed.status, 0, packed.stderr)
const attempts = []
const delays = []
const builder = new ManagedDeploymentBuilder({
paths,
sleep: async milliseconds => delays.push(milliseconds),
npmInstall: async (installRoot, _archivePath, options) => {
attempts.push({ installRoot, options })
if (attempts.length === 1) {
throw new Error('npm error code E404\nnpm error 404 A dependency package is not published yet.')
}
if (attempts.length === 2) {
throw new Error('npm error code ETARGET\nnpm error notarget No matching version found for a dependency.')
}
if (attempts.length === 3) {
throw new Error('npm error code ENOVERSIONS\nnpm error No versions available for a dependency.')
}
const installed = join(installRoot, 'lib', 'node_modules', '@deepseek-ai', 'dsh')
await mkdir(installed, { recursive: true })
await writeFile(join(installed, 'package.json'), JSON.stringify({
name: '@deepseek-ai/dsh', version: '0.1.5-rc.1',
}))
},
})
const pristine = await builder.pristine('0.1.5-rc.1', {
path: archive,
objectSha256: createHash('sha256').update(await readFile(archive)).digest('hex'),
})
assert.equal(attempts.length, 4)
assert.equal(new Set(attempts.map(attempt => attempt.installRoot)).size, 4)
assert.deepEqual(attempts.map(attempt => attempt.options.preferOnline), [false, true, true, true])
assert.deepEqual(delays, [5_000, 10_000, 20_000])
assert.equal(JSON.parse(await readFile(join(pristine.path, 'package.json'))).version, '0.1.5-rc.1')
let permanentAttempts = 0
const permanent = new ManagedDeploymentBuilder({
paths,
sleep: async () => assert.fail('a permanent npm failure must not wait for a retry'),
npmInstall: async () => {
permanentAttempts += 1
throw new Error('npm error code EACCES\nnpm error permission denied')
},
})
await assert.rejects(permanent.pristine('0.1.5-rc.1', {
path: archive,
objectSha256: 'permanent-error-fixture',
}), /EACCES/)
assert.equal(permanentAttempts, 1)
})
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,35 @@
import assert from 'node:assert/strict'
import { mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { applyPatch, verifyPatch, NATIVE_CORNERS_RELATIVE_TARGET } from '../../environment/resources/patches/native-corners.mjs'
const BEFORE = 'var corner_shape_css_default = "@supports (corner-shape:superellipse(1.5)){:root{--dsw-corner-shape:superellipse(1.5)}*,:before,:after{corner-shape:var(--dsw-corner-shape)}}";'
async function fixture(source = BEFORE) {
const root = await mkdtemp(join(tmpdir(), 'dsh-native-corners-'))
const target = join(root, NATIVE_CORNERS_RELATIVE_TARGET)
await mkdir(join(root, 'node_modules/@deepseek-ai/dsh-client-ui-theme/lib'), { recursive: true })
await writeFile(target, source + '\n')
return { root, target }
}
test('removes the image-injected global superellipse rule exactly once', async () => {
const { root, target } = await fixture()
applyPatch(root)
verifyPatch(root)
assert.equal(await readFile(target, 'utf8'), 'var corner_shape_css_default = "";\n')
assert.throws(() => applyPatch(root), /found 0/)
})
test('fails closed when the upstream theme anchor changes', async () => {
const { root } = await fixture('var corner_shape_css_default = "changed";')
assert.throws(() => applyPatch(root), /found 0/)
})
test('allows upstream packages without the optional theme module', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-native-corners-absent-'))
assert.doesNotThrow(() => applyPatch(root))
assert.doesNotThrow(() => verifyPatch(root))
})
@@ -0,0 +1,57 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
import { parseOfficialDshPolicy } from '../lib/contracts.mjs'
import { verifyOfficialDshCandidate } from '../stage0/lib/official-dsh.mjs'
import { officialDshPolicy, registryCandidate, registryKeyPair } from './helpers.mjs'
const candidate = {
schema: 1,
name: '@deepseek-ai/dsh',
version: '0.1.0-rc.7',
dist: {
integrity: 'sha512-ZceDCJ8FAywih+USW/OMk9jEhunlvJBGEz4kqrhau23hPzbciOazZrywH0nBRsaalSeAJ1JGBmjtw4OSjToStw==',
tarball: 'https://registry.npmjs.org/@deepseek-ai/dsh/-/dsh-0.1.0-rc.7.tgz',
signatures: [{
keyid: 'SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U',
sig: 'MEUCIQD2wLkZaghGyVZ5rWsOZdS2ue69pTRoGlnAEXvOk/zyOwIgRG6dOCTpAaSYCoYR7PXG6bB/O5ET57rGkBWJSVpvBkQ=',
}],
},
}
test('verifies the official npm Registry signature delegated by Stable metadata', async () => {
const policy = parseOfficialDshPolicy(JSON.parse(await readFile(
new URL('../../../release/official-dsh-policy.json', import.meta.url),
)))
assert.equal(verifyOfficialDshCandidate(candidate, candidate.version, policy).version, candidate.version)
assert.throws(() => verifyOfficialDshCandidate({
...candidate,
dist: { ...candidate.dist, integrity: candidate.dist.integrity.replace('Zce', 'Ace') },
}, candidate.version, policy), { code: 'TRUST_UNKNOWN_KEY' })
assert.throws(() => verifyOfficialDshCandidate(
candidate, candidate.version, { ...policy, keys: [] },
), { code: 'TRUST_UNKNOWN_KEY' })
})
test('accepts an exact requested version and rejects noncanonical npm tarball origins', async () => {
const policy = parseOfficialDshPolicy(JSON.parse(await readFile(
new URL('../../../release/official-dsh-policy.json', import.meta.url),
)))
assert.equal(verifyOfficialDshCandidate(candidate, candidate.version, policy).version, candidate.version)
assert.throws(() => verifyOfficialDshCandidate(candidate, '0.1.0-rc.8', policy), /different version/)
assert.throws(() => verifyOfficialDshCandidate({
...candidate,
dist: { ...candidate.dist, tarball: 'https://mirror.example/dsh.tgz' },
}, candidate.version, policy), /canonical/)
})
test('rejects candidates after a delegated npm Registry key expires', () => {
const registry = registryKeyPair()
const policy = parseOfficialDshPolicy(officialDshPolicy(registry, '2026-08-18T00:00:00.000Z'))
assert.throws(() => verifyOfficialDshCandidate(
registryCandidate(registry),
'0.1.0-rc.8',
policy,
new Date('2026-08-19T00:00:00.000Z'),
), { code: 'TRUST_UNKNOWN_KEY' })
})
@@ -0,0 +1,170 @@
import assert from 'node:assert/strict'
import { mkdtemp, mkdir, readFile, readdir, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import { parseComponentManifest, parseEnvironmentManifest } from '../lib/contracts.mjs'
import {
materializeSystemSkillCatalog,
readSystemSkillCatalog,
retainLegacySystemSkillCatalog,
} from '../../control-plane/modules/skill-manager/index.mjs'
const platformRoot = dirname(dirname(fileURLToPath(import.meta.url)))
const containerRoot = dirname(platformRoot)
const definition = join(containerRoot, 'environment', 'definition.json')
const tool = join(platformRoot, 'tools', 'package-environment.mjs')
async function build() {
const root = await mkdtemp(join(tmpdir(), 'dsh-environment-package-'))
const output = join(root, 'output')
const result = spawnSync(process.execPath, [tool, definition, output], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
return output
}
test('packages the initial Environment deterministically from real resources', async () => {
const first = await build()
const second = await build()
const firstManifest = await readFile(join(first, 'environment.manifest.json'))
const secondManifest = await readFile(join(second, 'environment.manifest.json'))
assert.deepEqual(firstManifest, secondManifest)
const manifest = parseEnvironmentManifest(firstManifest)
assert.deepEqual(manifest.components.map(component => component.id), ['dsh-runtime'])
assert.deepEqual(manifest.patches.map(patch => patch.id), [
'directory-picker', 'browser-loopback', 'managed-lifecycle', 'native-corners',
])
assert.deepEqual(manifest.systemPlugins.map(plugin => plugin.id), [
'platform-management', 'settings-navigation', 'settings-document-editor',
])
for (const reference of [...manifest.components, ...manifest.patches, ...manifest.systemPlugins]) {
assert.deepEqual(Object.keys(reference).sort(), ['id', 'sha256'])
}
assert.deepEqual(await readdir(join(first, 'artifacts')), await readdir(join(second, 'artifacts')))
const skillArtifact = manifest.artifacts.find(artifact => artifact.id === 'system-skill-catalog')
assert.equal(skillArtifact?.mediaType, 'application/vnd.dsh-platform.system-skill-catalog.v1+tar+gzip')
const skillArchive = join(first, 'artifacts', 'system-skill-catalog')
const skillListing = spawnSync('tar', ['-tzf', skillArchive], { encoding: 'utf8' })
assert.equal(skillListing.status, 0, skillListing.stderr)
assert.match(skillListing.stdout, /^skills\/catalog\.json$/m)
assert.match(skillListing.stdout, /^skills\/dsh-docker-operations\/SKILL\.md$/m)
const navigationArchive = join(first, 'artifacts', 'system-plugin-settings-navigation')
const listing = spawnSync('tar', ['-tzf', navigationArchive], { encoding: 'utf8' })
assert.equal(listing.status, 0, listing.stderr)
assert.match(listing.stdout, /^package\/lib\/client\.bundle\.js$/m)
assert.match(listing.stdout, /^package\/cordis\.patch\.json$/m)
})
test('can emit flat Artifact URLs for GitHub Release assets', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-environment-flat-'))
const output = join(root, 'output')
const result = spawnSync(process.execPath, [
tool, definition, output, '1', '1', 'https://release.example/platform-1/', 'flat',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const manifest = parseEnvironmentManifest(await readFile(join(output, 'environment.manifest.json')))
assert.equal(manifest.artifacts.every(artifact => artifact.url.startsWith('https://release.example/platform-1/')), true)
assert.equal(manifest.artifacts.every(artifact => !artifact.url.includes('/artifacts/')), true)
})
test('materializes the verified System Skill catalog from an Environment Artifact', async () => {
const environmentRoot = await build()
const outputRoot = await mkdtemp(join(tmpdir(), 'dsh-system-skill-catalogs-'))
const materialized = await materializeSystemSkillCatalog({ environmentRoot, outputRoot })
const catalog = await readSystemSkillCatalog(materialized)
assert.deepEqual(catalog.map(skill => skill.id), ['dsh-docker-operations'])
await writeFile(join(environmentRoot, 'artifacts', 'system-skill-catalog'), 'tampered')
await assert.rejects(
materializeSystemSkillCatalog({ environmentRoot, outputRoot }),
/differs from its Environment manifest/,
)
})
test('retains a legacy Bootstrap System Skill catalog without reading Stage-0 state', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-legacy-system-skill-'))
const source = join(root, 'seed', 'bootstrap', '1.0.9', 'control-plane', 'skills')
const skill = join(source, 'legacy-skill')
const output = join(root, 'environments', 'versions', '.system-skill-catalogs')
await mkdir(skill, { recursive: true })
await writeFile(join(source, 'catalog.json'), JSON.stringify({
schema: 1,
skills: [{
id: 'legacy-skill',
source: 'legacy-skill',
description: { en: 'Legacy skill', zh: 'Legacy skill' },
}],
}))
await writeFile(join(skill, 'SKILL.md'), '---\nname: legacy-skill\ndescription: Legacy skill\n---\n')
const retained = await retainLegacySystemSkillCatalog({ sourceRoot: source, outputRoot: output })
assert.equal(retained, join(output, 'legacy-bootstrap'))
assert.deepEqual((await readSystemSkillCatalog(retained)).map(entry => entry.id), ['legacy-skill'])
assert.equal(await retainLegacySystemSkillCatalog({ sourceRoot: join(root, 'missing'), outputRoot: output }), retained)
const bootstrap = await readFile(new URL('../bootstrap/index.mjs', import.meta.url), 'utf8')
assert.match(bootstrap, /inventory\.bootstrap\.id, 'control-plane', 'skills'/)
assert.doesNotMatch(bootstrap, /bootstrapStateRoot/)
})
test('checked-in Component manifests satisfy the public contract', async () => {
for (const path of [
join(containerRoot, 'control-plane', 'services', 'gateway', 'component.json'),
join(containerRoot, 'environment', 'dsh-runtime', 'component.json'),
join(containerRoot, 'control-plane', 'services', 'management', 'component.json'),
join(containerRoot, 'control-plane', 'hooks', 'recovery', 'component.json'),
]) {
const bytes = await readFile(path)
const component = parseComponentManifest(bytes)
assert.equal(Object.hasOwn(component, 'version'), false)
}
})
test('DSH Runtime uses the generic node home environment without package-manager overrides', async () => {
const component = parseComponentManifest(await readFile(
join(containerRoot, 'environment', 'dsh-runtime', 'component.json'),
))
assert.deepEqual(component.environment, {
DSH_BUNDLED_SKILL_DIR: '/run/dsh-platform/views/skills',
HOME: '/home/node',
LOGNAME: 'node',
USER: 'node',
XDG_CACHE_HOME: '/home/node/.cache',
XDG_CONFIG_HOME: '/home/node/.config',
XDG_DATA_HOME: '/home/node/.local/share',
})
assert.doesNotMatch(JSON.stringify(component.environment), /NPM_CONFIG_CACHE|PNPM_HOME/)
})
test('container images opt into the managed DSH lifecycle without exposing a user setting', async () => {
const dockerfile = await readFile(join(dirname(containerRoot), 'Dockerfile'), 'utf8')
assert.match(dockerfile, /ENV DSH_PLATFORM_DATA=\/data\/platform \\\n+ DSH_PLATFORM_MANAGED=1 \\\n+ DSH_PLATFORM_RUN=\/run\/dsh-platform \\/)
})
test('platform CLI shim follows the current verified Bootstrap view', async () => {
const dockerfile = await readFile(join(dirname(containerRoot), 'Dockerfile'), 'utf8')
const shim = await readFile(join(platformRoot, 'tools', 'dsh-platform-shim.sh'), 'utf8')
assert.match(dockerfile, /COPY container\/platform\/tools\/dsh-platform-shim\.sh \/usr\/local\/bin\/dsh-platform/)
assert.match(shim, /views\/bootstrap\/control-plane\/services\/management\/dsh-platform\.mjs/)
assert.match(shim, /opt\/dsh-platform\/runtime\/control-plane\/services\/management\/dsh-platform\.mjs/)
assert.ok(shim.indexOf('managed_cli') < shim.indexOf('image_cli'))
})
test('packager rejects source escapes and duplicate Artifact IDs without publishing output', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-environment-invalid-'))
const original = JSON.parse(await readFile(definition, 'utf8'))
original.components[0].source = '../../../../README.md'
original.components.push({ ...original.components[0] })
const invalid = join(dirname(definition), `invalid-${process.pid}.json`)
const output = join(root, 'output')
try {
await writeFile(invalid, JSON.stringify(original))
const result = spawnSync(process.execPath, [tool, invalid, output], { encoding: 'utf8' })
assert.notEqual(result.status, 0)
await assert.rejects(readdir(output), { code: 'ENOENT' })
} finally {
await import('node:fs/promises').then(({ rm }) => rm(invalid, { force: true }))
}
})
@@ -0,0 +1,82 @@
import assert from 'node:assert/strict'
import { lstat, mkdir, mkdtemp, readFile, readlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
PlatformPaths,
preparePersistentLayout,
rejectLegacyLayout,
resetRuntimeLayout,
trustStateRootForAuthority,
} from '../lib/paths.mjs'
test('creates state, store, cache, and logs without persistent runtime views', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-layout-'))
const paths = new PlatformPaths(join(root, 'platform'), join(root, 'run'))
await preparePersistentLayout(paths)
assert.equal(paths.developmentTrustStateRoot, join(paths.trustStateRoot, 'development'))
assert.equal(paths.proxyStateRoot, join(paths.stateRoot, 'proxy'))
assert.equal(paths.proxyTestStatePath, join(paths.proxyStateRoot, 'test-tasks.json'))
assert.equal(paths.accessStateRoot, join(paths.stateRoot, 'access'))
assert.equal(paths.accessSocket, join(paths.runRoot, 'access', 'access.sock'))
assert.equal(paths.accessRecoverySocket, join(paths.runRoot, 'access', 'recovery.sock'))
assert.equal(paths.accessLaunchSocket, join(paths.runRoot, 'access-launch.sock'))
assert.equal(paths.proxyProviderInventoryPath, join(paths.managementStateRoot, 'proxy-provider-inventory.json'))
for (const path of [
paths.trustStateRoot, paths.bootstrapStateRoot, paths.deploymentStateRoot, paths.updaterStateRoot,
paths.managementStateRoot,
paths.objectsRoot, paths.bootstrapStoreRoot, paths.environmentsRoot, paths.pristineRoot,
paths.runtimesRoot, paths.systemPluginsRoot, paths.snapshotsRoot, paths.userPluginSnapshotsRoot,
paths.downloadsRoot, paths.npmCacheRoot, paths.logsRoot,
]) assert.equal((await lstat(path)).isDirectory(), true)
assert.equal(paths.systemSkillCatalogsRoot, join(paths.environmentsRoot, 'versions', '.system-skill-catalogs'))
await assert.rejects(lstat(paths.systemSkillCatalogsRoot), { code: 'ENOENT' })
await assert.rejects(lstat(paths.runRoot), { code: 'ENOENT' })
})
test('isolates development trust without changing the formal trust ledger', () => {
const paths = new PlatformPaths('/data/platform', '/run/dsh-platform')
assert.equal(trustStateRootForAuthority(paths, 'development'), paths.developmentTrustStateRoot)
assert.equal(trustStateRootForAuthority(paths, 'stable'), paths.trustStateRoot)
})
test('rejects legacy platform volumes without changing DSH user data', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-legacy-layout-'))
const dataRoot = join(root, 'platform')
const dshRoot = join(root, 'dsh')
const paths = new PlatformPaths(dataRoot, join(root, 'run'))
await mkdir(join(dataRoot, 'runtime'), { recursive: true })
await mkdir(dshRoot)
await writeFile(join(dshRoot, 'sentinel'), 'user-data')
await assert.rejects(rejectLegacyLayout(paths), error => (
/clear only .*platform/.test(error.message) && /Do not delete \/data\/dsh/.test(error.message)
))
assert.equal(await readFile(join(dshRoot, 'sentinel'), 'utf8'), 'user-data')
})
test('rebuilds only the ephemeral run directory', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-run-layout-'))
const paths = new PlatformPaths(join(root, 'platform'), join(root, 'run'))
await preparePersistentLayout(paths)
await mkdir(paths.runRoot)
await writeFile(join(paths.runRoot, 'stale.sock'), 'stale')
await writeFile(join(paths.updaterStateRoot, 'sentinel'), 'persistent')
await resetRuntimeLayout(paths)
await assert.rejects(lstat(join(paths.runRoot, 'stale.sock')), { code: 'ENOENT' })
assert.equal((await lstat(paths.viewsRoot)).isDirectory(), true)
assert.equal((await lstat(paths.deploymentViewsRoot)).isDirectory(), true)
assert.equal(await readlink(join(paths.viewsRoot, 'runtime')), join('..', 'deployment', 'runtime'))
assert.equal(await readlink(join(paths.viewsRoot, 'environment')), join('..', 'deployment', 'environment'))
assert.equal(await readlink(join(paths.viewsRoot, 'system-plugins')), join('..', 'system-plugin-views', 'current'))
assert.equal((await lstat(paths.systemPluginViewsRoot)).isDirectory(), true)
assert.equal(paths.dshLifecycleSocket, join(paths.runRoot, 'dsh-lifecycle.sock'))
assert.equal(paths.proxyControlSocket, join(paths.runRoot, 'outbound-proxy.sock'))
assert.equal(paths.proxyRoutingStatePath, join(paths.runRoot, 'outbound-proxy-routing.json'))
assert.equal(paths.proxyLaunchSocket, join(paths.runRoot, 'proxy-launch.sock'))
assert.equal(
await readlink(join(paths.systemPluginViewsRoot, 'current')),
join('..', 'deployment', 'system-plugins'),
)
assert.equal(await readFile(join(paths.updaterStateRoot, 'sentinel'), 'utf8'), 'persistent')
})
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,424 @@
import assert from 'node:assert/strict'
import { chmod, mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises'
import { spawn } from 'node:child_process'
import { once } from 'node:events'
import { createServer, request } from 'node:http'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import {
defaultProxyConfiguration,
PROXY_PORTS,
sanitizedProxyConfiguration,
validateProxyConfiguration,
} from '../../control-plane/services/outbound-proxy/lib/contracts.mjs'
import { ProxyConfigurationError, proxyErrorBody } from '../../control-plane/services/outbound-proxy/lib/errors.mjs'
import {
matchesProxyRules,
noProxyEnvironment,
normalizeProxyRules,
} from '../../control-plane/services/outbound-proxy/lib/rules.mjs'
import { ProxyConfigurationStore } from '../../control-plane/services/outbound-proxy/lib/store.mjs'
import { PROXY_SCOPE_CATALOG } from '../../control-plane/services/outbound-proxy/lib/scope-catalog.mjs'
import { createOutboundProxyControl } from '../../control-plane/services/outbound-proxy/lib/control.mjs'
import { OutboundProxyControlClient } from '../../control-plane/services/management/outbound-proxy-client.mjs'
function configured(overrides = {}) {
const defaults = defaultProxyConfiguration()
return {
...defaults,
enabled: true,
proxy: {
...defaults.proxy,
host: 'Proxy.Example.COM.',
port: 1080,
username: 'user:@/',
password: 'secret:@/',
...overrides.proxy,
},
scopes: { ...defaults.scopes, updates: true, ...overrides.scopes },
environment: { ...defaults.environment, ...overrides.environment },
modelApi: { ...defaults.modelApi, providers: {}, ...overrides.modelApi },
noProxy: { user: ['GOOGLE.com.', '.Example.COM', 'google.com'], ...overrides.noProxy },
bypass: { additional: ['192.168.1.0/24', '[::1]:8443'], ...overrides.bypass },
}
}
async function listen(server) {
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(0, '127.0.0.1', resolve)
})
return server.address().port
}
function exchange(port, method, path, body) {
return new Promise((resolve, reject) => {
const bytes = body === undefined ? undefined : Buffer.from(JSON.stringify(body))
const outgoing = request({
host: '127.0.0.1', port, method, path,
headers: bytes === undefined ? {} : { 'content-type': 'application/json', 'content-length': bytes.byteLength },
}, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.on('end', () => resolve({
status: response.statusCode,
body: JSON.parse(Buffer.concat(chunks).toString('utf8')),
}))
})
outgoing.once('error', reject)
outgoing.end(bytes)
})
}
test('normalizes strict proxy configuration without exposing a password', () => {
const { configuration, credentials } = validateProxyConfiguration(configured())
assert.equal(configuration.proxy.host, 'proxy.example.com')
assert.equal(configuration.proxy.passwordConfigured, true)
assert.equal('password' in configuration.proxy, false)
assert.deepEqual(configuration.noProxy.user, ['.example.com', 'google.com'])
assert.deepEqual(configuration.bypass.additional, ['[::1]:8443', '192.168.1.0/24'])
assert.equal(credentials.password, 'secret:@/')
assert.equal(Object.isFrozen(configuration.proxy), true)
assert.equal(Object.isFrozen(configuration.scopes), true)
assert.deepEqual(PROXY_PORTS, {
updates: 17891, platform: 17892, dshCore: 17893, dshPlugins: 17894,
agentNetwork: 17895, managementTerminal: 17896, modelApi: 17897, sharedDsh: 17898,
})
const view = sanitizedProxyConfiguration(configuration, 'revision')
assert.equal(JSON.stringify(view).includes('secret'), false)
})
test('rejects unknown schemas, fields, wildcards, URLs, incomplete endpoints, and CIDR in NO_PROXY', () => {
for (const value of [
{ ...configured(), schema: 2 },
{ ...configured(), unexpected: true },
configured({ proxy: { host: '', port: 1080 } }),
configured({ noProxy: { user: ['*.example.com'] } }),
configured({ noProxy: { user: ['https://example.com'] } }),
configured({ noProxy: { user: ['192.168.0.0/16'] } }),
]) assert.throws(() => validateProxyConfiguration(value), ProxyConfigurationError)
})
test('enforces SOCKS5 credential byte limits without rejecting valid UTF-8 credentials', () => {
const boundary = validateProxyConfiguration(configured({ proxy: {
username: 'u'.repeat(255), password: 'p'.repeat(255), protocol: 'socks5',
} }))
assert.equal(Buffer.byteLength(boundary.credentials.username), 255)
assert.equal(Buffer.byteLength(boundary.credentials.password), 255)
assert.equal(validateProxyConfiguration(configured({ proxy: {
username: '代理', password: '密钥', protocol: 'socks5',
} })).credentials.username, '代理')
assert.throws(() => validateProxyConfiguration(configured({ proxy: { username: 'u'.repeat(256) } })), ProxyConfigurationError)
assert.throws(() => validateProxyConfiguration(configured({ proxy: { password: 'p'.repeat(256) } })), ProxyConfigurationError)
})
test('matches exact, suffix, port, IPv6, CIDR, wildcard, and domain boundaries', () => {
const noProxy = normalizeProxyRules(['example.com', '.example.net', 'service.local:8443', '*'], { allowWildcard: true })
assert.equal(matchesProxyRules(noProxy, 'anything.invalid', 443), true)
const precise = normalizeProxyRules(['example.com', '.example.net', 'service.local:8443'])
assert.equal(matchesProxyRules(precise, 'example.com', 443), true)
assert.equal(matchesProxyRules(precise, 'sub.example.com', 443), false)
assert.equal(matchesProxyRules(precise, 'example.net', 443), true)
assert.equal(matchesProxyRules(precise, 'sub.example.net.', 443), true)
assert.equal(matchesProxyRules(precise, 'badexample.net', 443), false)
assert.equal(matchesProxyRules(precise, 'service.local', 8443), true)
assert.equal(matchesProxyRules(precise, 'service.local', 443), false)
const bypass = normalizeProxyRules(['192.168.0.0/16', 'fd00::/8', '[::1]:8443'], { allowCidr: true })
assert.equal(matchesProxyRules(bypass, '192.168.1.4', 80), true)
assert.equal(matchesProxyRules(bypass, '192.169.1.4', 80), false)
assert.equal(matchesProxyRules(bypass, 'fd00::1', 80), true)
assert.equal(matchesProxyRules(bypass, '::1', 8443), true)
assert.equal(noProxyEnvironment(['.example.com']), '::1,127.0.0.1,localhost,.example.com')
})
test('atomically stores revisions, preserves and clears write-only credentials, and rejects stale writes', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-state-'))
const store = new ProxyConfigurationStore(root, { now: () => new Date('2026-08-25T00:00:00.000Z') })
const initial = await store.load()
assert.match(initial.revision, /^[A-Za-z0-9_-]{43}$/)
const saved = await store.commit({ baseRevision: initial.revision, value: configured() })
assert.equal(saved.credentials.password, 'secret:@/')
assert.equal((await stat(root)).mode & 0o777, 0o700)
assert.equal((await stat(join(root, 'revisions', saved.revision, 'credentials.json'))).mode & 0o777, 0o600)
assert.equal((await readFile(join(root, 'revisions', saved.revision, 'config.json'), 'utf8')).includes('secret'), false)
const preserving = configured({ proxy: { password: null } })
const preserved = await store.commit({ baseRevision: saved.revision, value: preserving })
assert.equal(preserved.credentials.password, 'secret:@/')
const clearing = configured({ proxy: { password: null, clearPassword: true } })
const cleared = await store.commit({ baseRevision: preserved.revision, value: clearing })
assert.equal(cleared.credentials.password, null)
assert.equal(cleared.configuration.proxy.passwordConfigured, false)
await assert.rejects(store.commit({ baseRevision: saved.revision, value: configured() }), error => (
error.code === 'REVISION_CONFLICT' && error.statusCode === 409
))
})
test('control API returns only sanitized configuration and hot-activates one current revision', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-control-'))
const store = new ProxyConfigurationStore(root)
let snapshot = Object.freeze({ ...await store.load(), recovery: 'none' })
let handlesCleared = 0
const server = createOutboundProxyControl({
getSnapshot: () => snapshot,
routeHealth: { status: current => ({ updates: current.configuration.scopes.updates ? 'unknown' : 'direct' }) },
providerHandles: { clear: () => { handlesCleared += 1 } },
commitConfiguration: async update => {
snapshot = Object.freeze({ ...await store.commit(update), recovery: 'none' })
return snapshot
},
})
const port = await listen(server)
t.after(() => new Promise(resolve => server.close(resolve)))
const initial = await exchange(port, 'GET', '/v1/configuration')
assert.equal(initial.status, 200)
assert.equal(initial.body.componentReady, true)
assert.equal(initial.body.enabled, false)
assert.equal('credentials' in initial.body, false)
const activated = await exchange(port, 'PUT', '/v1/configuration', {
baseRevision: initial.body.revision,
value: configured(),
})
assert.equal(activated.status, 200)
assert.equal(activated.body.enabled, true)
assert.equal(activated.body.proxy.passwordConfigured, true)
assert.equal(JSON.stringify(activated.body).includes('secret:@/'), false)
assert.equal(snapshot.credentials.password, 'secret:@/')
assert.equal(handlesCleared, 1)
const stale = await exchange(port, 'PUT', '/v1/configuration', {
baseRevision: initial.body.revision,
value: configured(),
})
assert.equal(stale.status, 409)
assert.equal(stale.body.error.code, 'REVISION_CONFLICT')
assert.equal(snapshot.revision, activated.body.revision)
})
test('control API accepts dynamic model Provider routing before persistence', async t => {
const current = Object.freeze({
revision: 'revision-one', recovery: 'none',
...validateProxyConfiguration(defaultProxyConfiguration()),
})
let committed = false
const server = createOutboundProxyControl({
getSnapshot: () => current,
routeHealth: { status: () => ({}) },
commitConfiguration: async request => {
committed = true
return Object.freeze({ revision: 'revision-two', recovery: 'none', ...validateProxyConfiguration(request.value) })
},
})
const port = await listen(server)
t.after(() => new Promise(resolve => server.close(resolve)))
const value = configured({ modelApi: { providers: { unsupported: { proxyEnabled: true } } } })
const result = await exchange(port, 'PUT', '/v1/configuration', { baseRevision: current.revision, value })
assert.equal(result.status, 200)
assert.deepEqual(result.body.modelApi.providers.unsupported, { proxyEnabled: true })
assert.equal(committed, true)
})
test('rejects unreleased legacy Provider policy shapes', () => {
assert.throws(() => validateProxyConfiguration(configured({
modelApi: { default: 'direct', providers: {} },
})), /must be an object/)
assert.throws(() => validateProxyConfiguration(configured({
modelApi: { default: { proxyEnabled: false }, providers: { legacy: { followDsh: true, proxyEnabled: true } } },
})), /unsupported fields: followDsh/)
})
test('Management outbound proxy client preserves structured control errors', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-client-'))
const socket = join(root, 'control.sock')
const server = createServer((_request, response) => {
response.writeHead(409, { 'content-type': 'application/json' })
response.end(JSON.stringify({ error: {
code: 'REVISION_CONFLICT', message: 'proxy configuration changed', stage: 'activate', retryable: true,
} }))
})
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(socket, resolve)
})
t.after(() => new Promise(resolve => server.close(resolve)))
const client = new OutboundProxyControlClient(socket)
await assert.rejects(client.updateConfiguration({}), error => (
error.statusCode === 409 && error.code === 'REVISION_CONFLICT'
&& error.stage === 'activate' && error.retryable === true
))
})
test('Management outbound proxy client redacts unavailable control sockets', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-client-unavailable-'))
const client = new OutboundProxyControlClient(join(root, 'missing.sock'), { timeoutMs: 100 })
await assert.rejects(client.configuration(), error => (
error.statusCode === 503
&& error.code === 'PROXY_MANAGER_UNAVAILABLE'
&& error.stage === 'control'
&& error.retryable === true
&& !error.message.includes(root)
&& !error.message.includes('missing.sock')
))
})
test('recovers the newest intact immutable revision when current state is corrupt', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-recovery-'))
let tick = 0
const store = new ProxyConfigurationStore(root, { now: () => new Date(Date.UTC(2026, 7, 25, 0, 0, tick++)) })
const initial = await store.load()
const first = await store.commit({ baseRevision: initial.revision, value: configured() })
const second = await store.commit({ baseRevision: first.revision, value: configured({ proxy: { port: 1081 } }) })
await writeFile(join(root, 'revisions', second.revision, 'config.json'), '{}\n')
const recovered = await store.load()
assert.equal(recovered.revision, first.revision)
assert.equal(JSON.parse(await readFile(join(root, 'current.json'), 'utf8')).revision, first.revision)
})
test('returns stable redacted error structures', () => {
const body = proxyErrorBody(new ProxyConfigurationError('proxy configuration changed', {
code: 'REVISION_CONFLICT', statusCode: 409, stage: 'activate',
}))
assert.deepEqual(body, {
error: { code: 'REVISION_CONFLICT', message: 'proxy configuration changed', stage: 'activate', retryable: false },
})
})
test('recovers a corrupt pointer and safely disables proxy when every revision is corrupt', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-reset-'))
const store = new ProxyConfigurationStore(root)
const initial = await store.load()
await writeFile(join(root, 'revisions', initial.revision, 'credentials.json'), '{broken')
await writeFile(join(root, 'current.json'), '{broken')
const recovered = await store.load()
assert.equal(recovered.recovery, 'reset-disabled')
assert.equal(recovered.configuration.enabled, false)
assert.equal(recovered.configuration.proxy.passwordConfigured, false)
assert.equal((await readFile(join(root, 'revisions', initial.revision, 'credentials.json'), 'utf8')), '{broken')
const names = await import('node:fs/promises').then(({ readdir }) => readdir(root))
assert.equal(names.some(name => name.startsWith('current.corrupt.')), true)
})
test('publishes one complete bilingual proxy scope catalog', () => {
assert.equal(PROXY_SCOPE_CATALOG.schema, 1)
assert.equal(PROXY_SCOPE_CATALOG.entries.length, 24)
assert.equal(new Set(PROXY_SCOPE_CATALOG.entries.map(entry => entry.id)).size, 24)
assert.deepEqual(new Set(PROXY_SCOPE_CATALOG.entries.map(entry => entry.group)), new Set(Object.keys(PROXY_SCOPE_CATALOG.groups)))
for (const entry of PROXY_SCOPE_CATALOG.entries) {
assert.equal(typeof entry.source.zh, 'string')
assert.equal(typeof entry.source.en, 'string')
assert.equal(typeof entry.detail.zh, 'string')
assert.equal(typeof entry.detail.en, 'string')
}
const pluginTerminal = PROXY_SCOPE_CATALOG.entries.find(entry => entry.id === 'plugin-terminal')
assert.match(pluginTerminal.detail.zh, /可识别子进程接口/)
assert.match(pluginTerminal.detail.zh, /共享 DSH/)
assert.match(pluginTerminal.detail.en, /identifiable subprocess interface/)
assert.match(pluginTerminal.detail.en, /shared DSH policy/)
})
test('keeps the Bootstrap proxy supervisor alive until an explicit stop', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-supervisor-'))
const runRoot = join(root, 'run')
const socket = join(runRoot, 'proxy-launch.sock')
await mkdir(runRoot)
let running = false
const calls = []
const server = createServer((request, response) => {
const chunks = []
request.on('data', chunk => chunks.push(chunk))
request.on('end', () => {
calls.push(`${request.method} ${request.url}`)
if (request.method === 'POST' && request.url === '/v1/start') running = true
if (request.method === 'POST' && request.url === '/v1/stop') running = false
response.writeHead(200, { 'content-type': 'application/json' })
response.end(JSON.stringify({ running, componentReady: running }))
})
})
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(socket, resolve)
})
const script = new URL('../../control-plane/services/outbound-proxy/supervisor.mjs', import.meta.url).pathname
const child = spawn(process.execPath, [script], {
env: {
...process.env,
DSH_PLATFORM_DATA: join(root, 'data'),
DSH_PLATFORM_RUN: runRoot,
DSH_PROXY_LAUNCH_TOKEN: 'x'.repeat(43),
},
stdio: ['ignore', 'pipe', 'pipe'],
})
try {
await new Promise((resolve, reject) => {
const deadline = setTimeout(() => reject(new Error('proxy supervisor did not start')), 3_000)
const check = setInterval(() => {
if (calls.includes('POST /v1/start')) {
clearInterval(check)
clearTimeout(deadline)
resolve()
}
}, 20)
})
await new Promise(resolve => setTimeout(resolve, 750))
assert.equal(child.exitCode, null)
child.kill('SIGTERM')
const [code] = await once(child, 'exit')
assert.equal(code, 0)
assert.equal(calls.includes('POST /v1/stop'), true)
} finally {
if (child.exitCode === null) child.kill('SIGKILL')
await new Promise(resolve => server.close(resolve))
await rm(root, { recursive: true, force: true })
}
})
test('stops the Bootstrap proxy supervisor cleanly after its launch socket disappears', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-supervisor-missing-socket-'))
const runRoot = join(root, 'run')
const socket = join(runRoot, 'proxy-launch.sock')
await mkdir(runRoot)
let started = false
const server = createServer((request, response) => {
request.resume()
request.on('end', () => {
if (request.method === 'POST' && request.url === '/v1/start') started = true
response.writeHead(200, { 'content-type': 'application/json' })
response.end(JSON.stringify({ running: true, componentReady: true }))
})
})
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(socket, resolve)
})
const script = new URL('../../control-plane/services/outbound-proxy/supervisor.mjs', import.meta.url).pathname
const child = spawn(process.execPath, [script], {
env: {
...process.env,
DSH_PLATFORM_DATA: join(root, 'data'),
DSH_PLATFORM_RUN: runRoot,
DSH_PROXY_LAUNCH_TOKEN: 'x'.repeat(43),
},
stdio: ['ignore', 'ignore', 'pipe'],
})
const stderr = []
child.stderr.on('data', chunk => stderr.push(chunk))
try {
const deadline = Date.now() + 3_000
while (!started && Date.now() < deadline) await new Promise(resolve => setTimeout(resolve, 20))
assert.equal(started, true)
await new Promise(resolve => setTimeout(resolve, 50))
await new Promise(resolve => server.close(resolve))
await rm(socket, { force: true })
child.kill('SIGTERM')
const [code] = await once(child, 'exit')
assert.equal(code, 0)
assert.equal(Buffer.concat(stderr).toString('utf8'), '')
} finally {
if (child.exitCode === null) child.kill('SIGKILL')
if (server.listening) await new Promise(resolve => server.close(resolve))
await rm(root, { recursive: true, force: true })
}
})
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,159 @@
import assert from 'node:assert/strict'
import { request } from 'node:http'
import test from 'node:test'
import { createOutboundProxyControl } from '../../control-plane/services/outbound-proxy/lib/control.mjs'
import {
OUTBOUND_PROXY_PORTS,
outboundProxyEnvironment,
outboundProxyScopeEnabled,
outboundProxyUrl,
parseOutboundProxyEnvironment,
} from '../lib/outbound-proxy.mjs'
function get(port, path) {
return new Promise((resolve, reject) => {
const outgoing = request({ host: '127.0.0.1', port, path }, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.once('end', () => resolve({
status: response.statusCode,
body: JSON.parse(Buffer.concat(chunks).toString('utf8')),
}))
})
outgoing.once('error', reject)
outgoing.end()
})
}
test('managed proxy environments use only fixed loopback entries', () => {
assert.equal(outboundProxyUrl('agentNetwork'), 'http://127.0.0.1:17895')
assert.deepEqual(Object.keys(OUTBOUND_PROXY_PORTS), [
'updates', 'platform', 'dshCore', 'dshPlugins', 'agentNetwork',
'managementTerminal', 'modelApi', 'sharedDsh',
])
const environment = outboundProxyEnvironment('managementTerminal', {
noProxy: ['localhost', '127.0.0.1', 'localhost', '.example.com'],
allProxy: true,
})
assert.deepEqual(environment, {
HTTP_PROXY: 'http://127.0.0.1:17896',
HTTPS_PROXY: 'http://127.0.0.1:17896',
http_proxy: 'http://127.0.0.1:17896',
https_proxy: 'http://127.0.0.1:17896',
NO_PROXY: 'localhost,127.0.0.1,.example.com',
no_proxy: 'localhost,127.0.0.1,.example.com',
ALL_PROXY: 'http://127.0.0.1:17896',
all_proxy: 'http://127.0.0.1:17896',
})
assert.deepEqual(parseOutboundProxyEnvironment(environment, 'managementTerminal'), environment)
assert.throws(() => parseOutboundProxyEnvironment({ ...environment, PASSWORD: 'secret' }, 'managementTerminal'), /unsupported fields/)
assert.throws(() => outboundProxyEnvironment('unknown'), /scope unknown is invalid/)
})
test('scope policy selects direct transport whenever the configured route is disabled', () => {
const direct = {
enabled: false,
scopes: { updates: true, platform: true, dshCore: true, dshPlugins: true, agentNetwork: true, managementTerminal: true },
modelApi: { default: { proxyEnabled: true }, providers: {} },
}
for (const scope of ['updates', 'platform', 'dshCore', 'dshPlugins', 'agentNetwork', 'managementTerminal', 'sharedDsh']) {
assert.equal(outboundProxyScopeEnabled(direct, scope), false, scope)
}
assert.equal(outboundProxyScopeEnabled(direct, 'modelApi', 'deepseek'), false)
const configured = {
...direct,
enabled: true,
scopes: { updates: true, platform: false, dshCore: false, dshPlugins: false, agentNetwork: true, managementTerminal: false },
modelApi: {
default: { proxyEnabled: true },
providers: {
direct: { proxyEnabled: false },
independent: { proxyEnabled: true },
},
},
}
assert.equal(outboundProxyScopeEnabled(configured, 'updates'), true)
assert.equal(outboundProxyScopeEnabled(configured, 'platform'), false)
assert.equal(outboundProxyScopeEnabled(configured, 'agentNetwork'), true)
assert.equal(outboundProxyScopeEnabled(configured, 'managementTerminal'), false)
assert.equal(outboundProxyScopeEnabled(configured, 'sharedDsh'), false)
assert.equal(outboundProxyScopeEnabled(configured, 'modelApi', 'direct'), false)
assert.equal(outboundProxyScopeEnabled(configured, 'modelApi', 'independent'), true)
assert.equal(outboundProxyScopeEnabled(configured, 'modelApi', 'default'), true)
configured.scopes.dshCore = true
assert.equal(outboundProxyScopeEnabled(configured, 'sharedDsh'), true)
assert.equal(outboundProxyScopeEnabled(configured, 'modelApi', 'default'), true)
})
test('outbound proxy control returns sanitized process environments', async () => {
const snapshot = Object.freeze({
revision: 'revision-one',
recovery: 'none',
credentials: Object.freeze({ username: 'alice', password: 'never-return-this' }),
configuration: Object.freeze({
noProxy: Object.freeze({ system: Object.freeze(['localhost', '127.0.0.1', '::1']), user: Object.freeze(['.example.com']) }),
environment: Object.freeze({ allProxy: 'scope-proxy' }),
enabled: true,
scopes: Object.freeze({ agentNetwork: true }),
modelApi: Object.freeze({ default: Object.freeze({ proxyEnabled: false }), providers: Object.freeze({}) }),
}),
})
const server = createOutboundProxyControl({
getSnapshot: () => snapshot,
routeHealth: { status: () => ({ updates: 'direct' }) },
})
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(0, '127.0.0.1', resolve)
})
try {
const result = await get(server.address().port, '/v1/environment?scope=agentNetwork')
assert.equal(result.status, 200)
assert.equal(result.body.revision, 'revision-one')
assert.equal(result.body.environment.HTTP_PROXY, 'http://127.0.0.1:17895')
assert.equal(result.body.environment.NO_PROXY, 'localhost,127.0.0.1,::1,.example.com')
assert.equal(result.body.environment.ALL_PROXY, 'http://127.0.0.1:17895')
assert.doesNotMatch(JSON.stringify(result.body), /alice|never-return-this/)
assert.equal((await get(server.address().port, '/v1/environment?scope=invalid')).status, 400)
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('outbound proxy control omits proxy entries for every disabled process scope', async () => {
const scopes = ['updates', 'platform', 'dshCore', 'dshPlugins', 'agentNetwork', 'managementTerminal', 'sharedDsh']
const snapshot = Object.freeze({
revision: 'direct-revision', recovery: 'none', credentials: Object.freeze({ username: '', password: null }),
configuration: Object.freeze({
enabled: true,
scopes: Object.freeze({
updates: false, platform: false, dshCore: false, dshPlugins: false,
agentNetwork: false, managementTerminal: false,
}),
modelApi: Object.freeze({ default: Object.freeze({ proxyEnabled: false }), providers: Object.freeze({}) }),
noProxy: Object.freeze({ system: Object.freeze(['localhost', '127.0.0.1', '::1']), user: Object.freeze([]) }),
environment: Object.freeze({ allProxy: 'scope-proxy' }),
}),
})
const server = createOutboundProxyControl({
getSnapshot: () => snapshot,
routeHealth: { status: () => ({}) },
})
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(0, '127.0.0.1', resolve)
})
try {
for (const scope of scopes) {
const result = await get(server.address().port, `/v1/environment?scope=${scope}`)
assert.equal(result.status, 200)
assert.equal(result.body.environment.HTTP_PROXY, undefined, scope)
assert.equal(result.body.environment.HTTPS_PROXY, undefined, scope)
assert.equal(result.body.environment.ALL_PROXY, undefined, scope)
}
} finally {
await new Promise(resolve => server.close(resolve))
}
})
@@ -0,0 +1,195 @@
import assert from 'node:assert/strict'
import { mkdtemp, readFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { defaultProxyConfiguration, validateProxyConfiguration } from '../../control-plane/services/outbound-proxy/lib/contracts.mjs'
import { ProviderInventory } from '../../control-plane/services/management/provider-inventory.mjs'
function response(value) {
return new Response(JSON.stringify({
type: 'server-response',
rpcId: 'fixture',
result: { ok: true, value },
}), { status: 200, headers: { 'content-type': 'application/json' } })
}
function proxySnapshot() {
const defaults = defaultProxyConfiguration()
return Object.freeze({
revision: 'revision-one',
recovery: 'none',
...validateProxyConfiguration({
...defaults,
modelApi: { default: defaults.modelApi.default, providers: {
adapted: { proxyEnabled: true },
shared: { proxyEnabled: true },
'shared-explicit': { proxyEnabled: true },
local: { proxyEnabled: true },
} },
}),
})
}
test('builds a sanitized Provider capability inventory from controlled DSH RPCs', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-provider-inventory-'))
t.after(() => rm(root, { recursive: true, force: true }))
const calls = []
const inventory = new ProviderInventory({
cachePath: join(root, 'providers.json'),
now: () => new Date('2026-08-25T00:00:00.000Z'),
authentication: { cookie: async () => 'dsh-auth-fixture=signed' },
fetchImpl: async (url, init) => {
const body = JSON.parse(init.body)
calls.push({ url, method: body.method, payload: body.payload, cookie: init.headers.cookie })
if (body.method === 'llm/listProviders') return response([
{ id: 'shared', name: 'Shared' },
{ id: 'shared-explicit', name: 'Shared explicit' },
{ id: 'custom', name: 'Custom route' },
{ id: 'adapted', name: 'Adapted' },
{ id: 'local', name: 'Local' },
])
if (body.method === 'llm/listConfigurableProviders') return response([
{ provider: 'dormant', displayName: 'Dormant', settingsNs: 'llm-pi-ai', settingsPath: ['providers', 'dormant'] },
{ provider: 'shared', displayName: 'Shared', settingsNs: 'llm-pi-ai', settingsPath: ['providers', 'shared'] },
{ provider: 'shared-explicit', displayName: 'Shared explicit', settingsNs: 'llm-pi-ai', settingsPath: ['providers', 'shared-explicit'], supportsIndependentRouting: false },
{ provider: 'custom', displayName: 'Custom route', settingsNs: 'llm-pi-ai', settingsPath: ['providers', 'custom'], declared: true },
{ provider: 'adapted', displayName: 'Adapted', settingsNs: 'adapted', settingsPath: [] },
{ provider: 'local', displayName: 'Local', settingsNs: 'local', settingsPath: [] },
{ provider: '../invalid', displayName: 'Invalid', settingsNs: 'invalid', settingsPath: [] },
])
assert.equal(body.method, 'settings/describe')
return response({ namespaces: [
{ ns: 'llm-pi-ai', value: { providers: { shared: { baseURL: 'https://api.example.test' }, 'shared-explicit': { baseURL: 'https://shared.example.test' }, custom: { baseURL: 'https://custom.example.test' } } }, base: {} },
{ ns: 'adapted', value: {}, base: {} },
{ ns: 'local', value: { baseURL: 'http://127.0.0.1:11434/v1' }, base: {} },
] })
},
})
const result = await inventory.list(proxySnapshot())
assert.equal(result.source, 'live')
assert.equal(result.error, null)
assert.equal(result.updatedAt, '2026-08-25T00:00:00.000Z')
assert.deepEqual(result.providers.map(provider => ({
id: provider.id,
capability: provider.routingCapability,
requested: provider.requestedPolicy,
effective: provider.effectivePolicy,
reason: provider.reason,
})), [
{ id: 'adapted', capability: 'provider', requested: { proxyEnabled: true }, effective: 'proxy', reason: null },
{ id: 'custom', capability: 'provider', requested: { proxyEnabled: false }, effective: 'direct', reason: null },
{ id: 'local', capability: 'forced-direct', requested: null, effective: 'direct', reason: 'local-provider' },
{ id: 'shared', capability: 'provider', requested: { proxyEnabled: true }, effective: 'proxy', reason: null },
{ id: 'shared-explicit', capability: 'shared-dsh', requested: { proxyEnabled: true }, effective: 'shared-dsh', reason: 'client-uses-shared-dsh-route' },
])
assert.deepEqual(calls.map(call => call.method).sort(), [
'llm/listConfigurableProviders', 'llm/listProviders', 'settings/describe',
])
assert.equal(calls.every(call => call.url.endsWith(`/api/${call.method}`)), true)
assert.equal(calls.every(call => call.cookie === 'dsh-auth-fixture=signed'), true)
assert.equal(calls.every(call => JSON.stringify(call.payload) === JSON.stringify({ args: {} })), true)
assert.equal(result.providers.some(provider => provider.id === 'dormant'), false)
const cache = JSON.parse(await readFile(join(root, 'providers.json'), 'utf8'))
assert.doesNotMatch(JSON.stringify(cache), /api\.example|127\.0\.0\.1|baseURL|secret/i)
})
test('keeps the last sanitized Provider inventory when DSH is unavailable', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-provider-cache-'))
t.after(() => rm(root, { recursive: true, force: true }))
let online = true
const inventory = new ProviderInventory({
cachePath: join(root, 'providers.json'),
fetchImpl: async (_url, init) => {
if (!online) throw new Error('DSH is stopped')
const method = JSON.parse(init.body).method
if (method === 'llm/listProviders') return response([{ id: 'deepseek', name: 'DeepSeek' }])
if (method === 'llm/listConfigurableProviders') {
return response([{ provider: 'deepseek', displayName: 'DeepSeek', settingsNs: 'deepseek', settingsPath: [] }])
}
return response({ namespaces: [{ ns: 'deepseek', value: {}, base: {} }] })
},
})
assert.equal((await inventory.list(proxySnapshot())).source, 'live')
online = false
const cached = await inventory.list(proxySnapshot())
assert.equal(cached.source, 'cache')
assert.equal(cached.providers[0].id, 'deepseek')
assert.equal(cached.error, 'DSH is stopped')
const empty = new ProviderInventory({
cachePath: join(root, 'missing.json'),
fetchImpl: async () => { throw new Error('DSH is stopped') },
})
const unavailable = await empty.list(proxySnapshot())
assert.equal(unavailable.source, 'unavailable')
assert.deepEqual(unavailable.providers, [])
assert.equal(unavailable.error, 'DSH is stopped')
})
test('replaces deleted Providers with newly configured Providers on refresh', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-provider-refresh-'))
t.after(() => rm(root, { recursive: true, force: true }))
let current = { id: 'removed', displayName: 'Removed' }
const inventory = new ProviderInventory({
cachePath: join(root, 'providers.json'),
fetchImpl: async (_url, init) => {
const method = JSON.parse(init.body).method
if (method === 'llm/listProviders') return response([{ id: current.id, name: current.displayName }])
if (method === 'llm/listConfigurableProviders') return response([{
provider: current.id,
displayName: current.displayName,
settingsNs: 'llm-pi-ai',
settingsPath: ['providers', current.id],
declared: true,
}])
return response({ namespaces: [{
ns: 'llm-pi-ai',
value: { providers: { [current.id]: { baseURL: 'https://provider.example.test' } } },
base: {},
}] })
},
})
assert.deepEqual((await inventory.list(proxySnapshot())).providers.map(provider => provider.id), ['removed'])
current = { id: 'created', displayName: 'Created' }
assert.deepEqual((await inventory.list(proxySnapshot())).providers.map(provider => provider.id), ['created'])
assert.deepEqual(JSON.parse(await readFile(join(root, 'providers.json'), 'utf8')).providers.map(provider => provider.id), ['created'])
})
test('keeps configured DSH 0.1.5 Providers with catalog diagnostics manageable', async t => {
const root = await mkdtemp(join(tmpdir(), 'dsh-provider-diagnostic-'))
t.after(() => rm(root, { recursive: true, force: true }))
const inventory = new ProviderInventory({
cachePath: join(root, 'providers.json'),
fetchImpl: async (_url, init) => {
const method = JSON.parse(init.body).method
if (method === 'llm/listProviders') return response([])
if (method === 'llm/listConfigurableProviders') return response([{
provider: 'repairable',
displayName: 'Repairable Provider',
settingsNs: 'llm-pi-ai',
settingsPath: ['providers', 'repairable'],
declared: false,
error: 'configured model needs an api',
}])
return response({ namespaces: [{
ns: 'llm-pi-ai',
value: { providers: { repairable: { baseURL: 'https://repairable.example.test/v1' } } },
base: {},
}] })
},
})
const listed = await inventory.list(proxySnapshot())
assert.equal(listed.source, 'live')
assert.deepEqual(listed.providers.map(provider => ({
id: provider.id,
displayName: provider.displayName,
active: provider.active,
declared: provider.declared,
})), [{
id: 'repairable',
displayName: 'Repairable Provider',
active: false,
declared: false,
}])
})
@@ -0,0 +1,293 @@
import assert from 'node:assert/strict'
import { once } from 'node:events'
import { createServer, request as httpRequest } from 'node:http'
import { createServer as createNetServer, connect } from 'node:net'
import test from 'node:test'
import { defaultProxyConfiguration, validateProxyConfiguration } from '../../control-plane/services/outbound-proxy/lib/contracts.mjs'
import { createOutboundProxyControl } from '../../control-plane/services/outbound-proxy/lib/control.mjs'
import { createScopedProxyServer } from '../../control-plane/services/outbound-proxy/lib/data-plane.mjs'
import { ProviderHandleStore, providerHandleInternals } from '../../control-plane/services/outbound-proxy/lib/provider-handles.mjs'
import { selectProxyRoute } from '../../control-plane/services/outbound-proxy/lib/policy.mjs'
const sockets = new WeakMap()
async function listen(server) {
const active = new Set()
sockets.set(server, active)
server.on('connection', socket => {
active.add(socket)
socket.once('close', () => active.delete(socket))
})
server.listen(0, '127.0.0.1')
await once(server, 'listening')
return server.address().port
}
async function close(server) {
for (const socket of sockets.get(server) ?? []) socket.destroy()
if (!server.listening) return
server.closeAllConnections?.()
await new Promise(resolve => server.close(resolve))
}
function snapshot({ revision = 'revision-one', proxyPort = null, policy = { proxyEnabled: false } } = {}) {
const defaults = defaultProxyConfiguration()
const value = validateProxyConfiguration({
...defaults,
enabled: proxyPort !== null,
proxy: {
...defaults.proxy,
host: proxyPort === null ? '' : '127.0.0.1',
port: proxyPort,
username: proxyPort === null ? '' : 'external-user',
password: proxyPort === null ? undefined : 'external-password',
},
modelApi: { default: defaults.modelApi.default, providers: { deepseek: policy } },
})
return Object.freeze({ revision, recovery: 'none', ...value })
}
test('model Provider switch selects direct or independent proxy routing', async () => {
const defaults = defaultProxyConfiguration()
const make = (policy, scopes = {}) => Object.freeze({
revision: 'revision-one',
recovery: 'none',
...validateProxyConfiguration({
...defaults,
enabled: true,
proxy: { ...defaults.proxy, host: '127.0.0.1', port: 7890 },
scopes: { ...defaults.scopes, ...scopes },
modelApi: { default: defaults.modelApi.default, providers: { custom: policy } },
}),
})
const route = state => selectProxyRoute({
snapshot: state, scope: 'modelApi', providerId: 'custom', host: 'api.example.test', port: 443,
})
assert.equal((await route(make({ proxyEnabled: false }, { dshCore: true }))).reason, 'provider-direct')
assert.equal((await route(make({ proxyEnabled: true }, { dshCore: false, dshPlugins: false }))).reason, 'provider-proxy')
assert.equal((await route(make({ proxyEnabled: true }, { dshPlugins: true }))).reason, 'provider-proxy')
})
test('unconfigured model Providers inherit the complete default policy', async () => {
const defaults = defaultProxyConfiguration()
const snapshot = Object.freeze({
revision: 'revision-one', recovery: 'none',
...validateProxyConfiguration({
...defaults,
enabled: true,
proxy: { ...defaults.proxy, host: '127.0.0.1', port: 7890 },
scopes: { ...defaults.scopes, dshCore: true },
modelApi: { default: { proxyEnabled: true }, providers: {} },
}),
})
const result = await selectProxyRoute({
snapshot, scope: 'modelApi', providerId: 'new-provider', host: 'api.example.test', port: 443,
})
assert.equal(result.reason, 'provider-proxy')
})
function request({ port, path = '/', method = 'GET', headers = {}, body }) {
return new Promise((resolve, reject) => {
const outgoing = httpRequest({ host: '127.0.0.1', port, path, method, headers }, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.once('end', () => resolve({
status: response.statusCode,
headers: response.headers,
body: Buffer.concat(chunks),
}))
})
outgoing.once('error', reject)
if (body !== undefined) outgoing.end(body)
else outgoing.end()
})
}
function rawExchange(port, value, waitFor = '\r\n\r\n') {
return new Promise((resolve, reject) => {
const socket = connect({ host: '127.0.0.1', port })
let bytes = Buffer.alloc(0)
const timer = setTimeout(() => {
socket.destroy()
reject(new Error('provider CONNECT fixture timed out'))
}, 3_000)
socket.once('connect', () => socket.write(value))
socket.on('data', chunk => {
bytes = Buffer.concat([bytes, chunk])
if (!bytes.includes(waitFor)) return
clearTimeout(timer)
resolve({ socket, bytes })
})
socket.once('error', reject)
socket.once('close', () => clearTimeout(timer))
})
}
test('issues opaque provider handles and rejects expiry or policy revision changes', () => {
let now = 1_000
let generated = 0
const handles = new ProviderHandleStore({
ttlMs: 100,
now: () => now,
random: size => Buffer.alloc(size, ++generated),
})
const state = snapshot()
const issued = handles.issue({ providerId: 'deepseek', policyRevision: state.revision }, state)
assert.match(issued.handle, providerHandleInternals.HANDLE_PATTERN)
assert.equal(Buffer.from(issued.handle, 'base64url').byteLength, providerHandleInternals.HANDLE_BYTES)
assert.equal(handles.resolve(`DSH-Provider ${issued.handle}`, state), 'deepseek')
assert.throws(() => handles.resolve(`Basic ${issued.handle}`, state), error => error.code === 'PROVIDER_HANDLE_INVALID')
assert.throws(() => handles.resolve(`DSH-Provider ${issued.handle}`, snapshot({ revision: 'revision-two' })), error => error.code === 'PROVIDER_HANDLE_INVALID')
const expiring = handles.issue({ providerId: 'deepseek', policyRevision: state.revision }, state)
now += 101
assert.throws(() => handles.resolve(`DSH-Provider ${expiring.handle}`, state), error => error.code === 'PROVIDER_HANDLE_INVALID')
assert.throws(() => handles.issue({ providerId: '../secret', policyRevision: state.revision }, state), /provider ID/)
assert.throws(() => handles.issue({ providerId: 'deepseek', policyRevision: 'stale' }, state), error => error.code === 'REVISION_CONFLICT' && error.statusCode === 409)
})
test('control socket issues a provider handle only for the current revision', async () => {
const state = snapshot()
const handles = new ProviderHandleStore()
const control = createOutboundProxyControl({
getSnapshot: () => state,
routeHealth: { status: () => ({}) },
providerHandles: handles,
})
const port = await listen(control)
try {
const current = await request({
port,
path: '/v1/provider-handles',
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ providerId: 'deepseek', policyRevision: state.revision }),
})
assert.equal(current.status, 201)
const issued = JSON.parse(current.body)
assert.equal(handles.resolve(`DSH-Provider ${issued.handle}`, state), 'deepseek')
const stale = await request({
port,
path: '/v1/provider-handles',
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ providerId: 'deepseek', policyRevision: 'stale' }),
})
assert.equal(stale.status, 409)
assert.equal(JSON.parse(stale.body).error.code, 'REVISION_CONFLICT')
const oversized = await request({
port,
path: '/v1/provider-handles',
method: 'POST',
body: JSON.stringify({ providerId: 'deepseek', policyRevision: state.revision, padding: 'x'.repeat(4096) }),
})
assert.equal(oversized.status, 400)
} finally {
await close(control)
}
})
test('model Provider entry requires a valid handle and strips it from a direct request', async () => {
let authorization
const target = createServer((incoming, response) => {
authorization = incoming.headers['proxy-authorization']
response.end('provider-direct')
})
const targetPort = await listen(target)
const state = snapshot()
const handles = new ProviderHandleStore()
const proxy = createScopedProxyServer({ scope: 'modelApi', getSnapshot: () => state, providerHandles: handles })
const proxyPort = await listen(proxy)
try {
const missing = await request({ port: proxyPort, path: `http://127.0.0.1:${targetPort}/` })
assert.equal(missing.status, 407)
assert.equal(missing.headers['x-dsh-proxy-error'], 'PROVIDER_HANDLE_INVALID')
assert.equal(missing.headers['proxy-authenticate'], 'DSH-Provider')
const issued = handles.issue({ providerId: 'deepseek', policyRevision: state.revision }, state)
const accepted = await request({
port: proxyPort,
path: `http://127.0.0.1:${targetPort}/`,
headers: { 'proxy-authorization': `DSH-Provider ${issued.handle}` },
})
assert.equal(accepted.status, 200)
assert.equal(accepted.body.toString(), 'provider-direct')
assert.equal(authorization, undefined)
} finally {
await close(proxy)
await close(target)
}
})
test('model Provider proxy replaces the internal handle with external Basic authentication', async () => {
let observed
const upstream = createServer((incoming, response) => {
observed = { path: incoming.url, authorization: incoming.headers['proxy-authorization'] }
response.end('provider-proxied')
})
const upstreamPort = await listen(upstream)
const state = snapshot({ proxyPort: upstreamPort, policy: { proxyEnabled: true } })
const handles = new ProviderHandleStore()
const issued = handles.issue({ providerId: 'deepseek', policyRevision: state.revision }, state)
const proxy = createScopedProxyServer({ scope: 'modelApi', getSnapshot: () => state, providerHandles: handles })
const proxyPort = await listen(proxy)
try {
const result = await request({
port: proxyPort,
path: 'http://provider.example/v1/models',
headers: { 'proxy-authorization': `DSH-Provider ${issued.handle}` },
})
assert.equal(result.status, 200)
assert.equal(result.body.toString(), 'provider-proxied')
assert.equal(observed.path, 'http://provider.example/v1/models')
assert.equal(observed.authorization, `Basic ${Buffer.from('external-user:external-password').toString('base64')}`)
assert.doesNotMatch(observed.authorization, new RegExp(issued.handle))
} finally {
await close(proxy)
await close(upstream)
}
})
test('model Provider CONNECT requires a handle and never forwards it to the external proxy', async () => {
let observed = ''
const upstream = createNetServer(socket => {
let requestBytes = Buffer.alloc(0)
socket.on('data', chunk => {
requestBytes = Buffer.concat([requestBytes, chunk])
if (!requestBytes.includes('\r\n\r\n')) return
observed = requestBytes.toString('latin1')
socket.removeAllListeners('data')
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n')
socket.on('data', value => socket.write(value))
})
})
const upstreamPort = await listen(upstream)
const state = snapshot({ proxyPort: upstreamPort, policy: { proxyEnabled: true } })
const handles = new ProviderHandleStore()
const issued = handles.issue({ providerId: 'deepseek', policyRevision: state.revision }, state)
const proxy = createScopedProxyServer({ scope: 'modelApi', getSnapshot: () => state, providerHandles: handles })
const proxyPort = await listen(proxy)
let socket
try {
const rejected = await rawExchange(proxyPort, 'CONNECT provider.example:443 HTTP/1.1\r\nHost: provider.example:443\r\n\r\n')
rejected.socket.destroy()
assert.match(rejected.bytes.toString('latin1'), /^HTTP\/1\.1 407/)
const accepted = await rawExchange(proxyPort, [
'CONNECT provider.example:443 HTTP/1.1',
'Host: provider.example:443',
`Proxy-Authorization: DSH-Provider ${issued.handle}`,
'',
'',
].join('\r\n'))
socket = accepted.socket
assert.match(accepted.bytes.toString('latin1'), /^HTTP\/1\.1 200/)
assert.match(observed, new RegExp(`Proxy-Authorization: Basic ${Buffer.from('external-user:external-password').toString('base64')}`, 'i'))
assert.doesNotMatch(observed, new RegExp(issued.handle))
} finally {
socket?.destroy()
await close(proxy)
await close(upstream)
}
})
@@ -0,0 +1,151 @@
import assert from 'node:assert/strict'
import { spawn } from 'node:child_process'
import { once } from 'node:events'
import { createServer } from 'node:http'
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { createScopedFetch, PROXY_SCOPE_PORTS } from '../../control-plane/services/management/scoped-fetch.mjs'
async function listen(server, options = {}) {
server.listen(options)
await once(server, 'listening')
return server.address()
}
async function close(server) {
if (!server.listening) return
server.closeAllConnections?.()
await new Promise((resolve, reject) => server.close(error => error === undefined ? resolve() : reject(error)))
}
test('routes enabled update fetches through the fixed outbound proxy entry', async context => {
const target = createServer((_request, response) => response.end('scoped response'))
context.after(() => close(target))
const targetAddress = await listen(target, { host: '127.0.0.1', port: 0 })
const authorities = []
const proxy = createServer((request, response) => {
authorities.push(request.url)
response.end('scoped response')
})
const proxySockets = new Set()
proxy.on('connection', socket => {
proxySockets.add(socket)
socket.once('close', () => proxySockets.delete(socket))
})
context.after(() => close(proxy))
await listen(proxy, { host: '127.0.0.1', port: PROXY_SCOPE_PORTS.updates })
const root = await mkdtemp(join(tmpdir(), 'dsh-scoped-fetch-'))
context.after(() => rm(root, { recursive: true, force: true }))
const routingStatePath = join(root, 'routing.json')
await writeFile(routingStatePath, JSON.stringify({ schema: 1, enabled: true, scopes: { updates: true } }))
const scopedFetch = createScopedFetch('updates', { routingStatePath })
try {
const url = `http://127.0.0.1:${String(targetAddress.port)}/metadata`
const response = await scopedFetch(url)
assert.equal(await response.text(), 'scoped response')
assert.deepEqual(authorities, [url])
} finally {
await scopedFetch.close()
for (const socket of proxySockets) socket.destroy()
await close(proxy)
}
const unavailable = createScopedFetch('updates', { routingStatePath })
try {
await assert.rejects(
unavailable(`http://127.0.0.1:${String(targetAddress.port)}/would-be-direct`, {
signal: AbortSignal.timeout(500),
}),
/fetch failed|ECONNREFUSED|proxy/i,
)
} finally {
await unavailable.close()
}
})
test('restarts Proxy Manager after an unclean exit leaves its control socket behind', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-process-restart-'))
const runRoot = join(root, 'run')
const dataRoot = join(root, 'data')
await mkdir(runRoot)
const script = new URL('../../control-plane/services/outbound-proxy/index.mjs', import.meta.url).pathname
const launch = () => spawn(process.execPath, [script], {
env: { ...process.env, DSH_PLATFORM_DATA: dataRoot, DSH_PLATFORM_RUN: runRoot },
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
})
const ready = child => {
const stderr = []
child.stderr.on('data', chunk => stderr.push(chunk))
return Promise.race([
once(child, 'message').then(([message]) => {
assert.equal(message.componentReady, true)
}),
once(child, 'exit').then(([code, signal]) => {
const detail = Buffer.concat(stderr).toString('utf8').trim()
throw new Error(`Proxy Manager exited before readiness (${String(code)}, ${String(signal)})${detail === '' ? '' : `: ${detail}`}`)
}),
])
}
const first = launch()
let second
let blocker
let releaseBlocker
try {
await ready(first)
const routing = JSON.parse(await readFile(join(runRoot, 'outbound-proxy-routing.json'), 'utf8'))
assert.equal(routing.schema, 1)
assert.equal(routing.enabled, false)
assert.equal(routing.scopes.agentNetwork, false)
assert.deepEqual(routing.environment, { allProxy: null })
assert.deepEqual(routing.noProxy.system, ['localhost', '127.0.0.1', '::1'])
assert.equal(JSON.stringify(routing).includes('password'), false)
first.kill('SIGKILL')
await once(first, 'exit')
blocker = createServer()
await new Promise((resolve, reject) => {
blocker.once('error', reject)
blocker.listen(PROXY_SCOPE_PORTS.updates, '127.0.0.1', resolve)
})
releaseBlocker = setTimeout(() => blocker.close(), 100)
second = launch()
await ready(second)
assert.equal(second.exitCode, null)
} finally {
clearTimeout(releaseBlocker)
if (blocker?.listening) await new Promise(resolve => blocker.close(resolve))
if (first.exitCode === null) first.kill('SIGKILL')
if (second?.exitCode === null) {
second.kill('SIGTERM')
await once(second, 'exit')
}
await rm(root, { recursive: true, force: true })
}
})
test('bypasses Proxy Manager when an update scope or the global proxy is disabled', async context => {
const target = createServer((_request, response) => response.end('direct response'))
context.after(() => close(target))
const address = await listen(target, { host: '127.0.0.1', port: 0 })
const root = await mkdtemp(join(tmpdir(), 'dsh-direct-fetch-'))
context.after(() => rm(root, { recursive: true, force: true }))
const routingStatePath = join(root, 'routing.json')
const url = `http://127.0.0.1:${String(address.port)}/direct`
for (const state of [
{ schema: 1, enabled: false, scopes: { updates: true } },
{ schema: 1, enabled: true, scopes: { updates: false } },
]) {
await writeFile(routingStatePath, JSON.stringify(state))
const fetch = createScopedFetch('updates', { routingStatePath })
try {
assert.equal(await (await fetch(url)).text(), 'direct response')
} finally {
await fetch.close()
}
}
})
test('rejects unknown outbound proxy scopes', () => {
assert.throws(() => createScopedFetch('unknown'), /unknown outbound proxy scope/)
})
@@ -0,0 +1,141 @@
import assert from 'node:assert/strict'
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { defaultProxyConfiguration, validateProxyConfiguration } from '../../control-plane/services/outbound-proxy/lib/contracts.mjs'
import { ProxyTestManager, proxyTestInternals } from '../../control-plane/services/outbound-proxy/lib/test-manager.mjs'
function current() {
const validated = validateProxyConfiguration(defaultProxyConfiguration())
return Object.freeze({ revision: 'current-revision', ...validated })
}
function candidate(overrides = {}) {
const defaults = defaultProxyConfiguration()
return {
...defaults,
...overrides,
proxy: { ...defaults.proxy, ...overrides.proxy },
scopes: { ...defaults.scopes, ...overrides.scopes },
environment: { ...defaults.environment, ...overrides.environment },
modelApi: { ...defaults.modelApi, providers: {}, ...overrides.modelApi },
noProxy: { user: [], ...overrides.noProxy },
bypass: { additional: [], ...overrides.bypass },
}
}
async function terminal(manager, taskId) {
for (let attempt = 0; attempt < 1_000; attempt += 1) {
const state = manager.get(taskId)
if (state.status !== 'running') return state
await new Promise(resolve => setTimeout(resolve, 2))
}
throw new Error('proxy test did not reach a terminal state')
}
test('proxy test requires and exercises the candidate proxy without changing current configuration', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-test-candidate-'))
const manager = new ProxyTestManager({
statePath: join(root, 'tasks.json'),
resolve: async host => {
if (host === 'proxy.invalid') throw Object.assign(new Error('proxy host was not found'), { code: 'ENOTFOUND' })
return [{ address: '127.0.0.1', family: 4 }]
},
targets: [{ id: 'unreachable', host: 'target.invalid', port: 443, path: '/' }],
phaseTimeoutMs: 500,
})
const state = current()
await assert.rejects(
manager.start({ baseRevision: state.revision, value: candidate() }, state),
error => error.code === 'INVALID_CONFIG' && /requires a host and port/.test(error.message),
)
const started = await manager.start({
baseRevision: state.revision,
value: candidate({ proxy: { host: 'proxy.invalid', port: 8080 } }),
}, state)
const completed = await terminal(manager, started.taskId)
assert.equal(completed.status, 'failed')
assert.equal(completed.mode, 'proxy')
assert.equal(completed.stages.find(stage => stage.stage === 'proxy-address').status, 'failed')
assert.deepEqual(completed.stages.slice(1).map(stage => stage.status), ['skipped', 'skipped', 'skipped', 'skipped'])
assert.equal(completed.stages.some(stage => stage.stage === 'target-dns'), false)
assert.equal(completed.stages.find(stage => stage.stage === 'target-http').status, 'skipped')
assert.equal(state.configuration.enabled, false)
})
test('proxy tests list target DNS only when SOCKS5 resolves names locally', () => {
const remote = candidate({ proxy: { protocol: 'socks5', remoteDns: true } })
const local = candidate({ proxy: { protocol: 'socks5', remoteDns: false } })
assert.equal(proxyTestInternals.stagesFor(remote).includes('target-dns'), false)
assert.equal(proxyTestInternals.stagesFor(local).includes('target-dns'), true)
})
test('proxy test details carry locale-independent result data', () => {
assert.deepEqual(
proxyTestInternals.stageDetail(
'resolved 2 proxy address record(s)',
'proxy-addresses-resolved',
{ count: 2 },
),
{
detail: 'resolved 2 proxy address record(s)',
detailCode: 'proxy-addresses-resolved',
detailData: { count: 2 },
},
)
})
test('proxy tests allow one in-memory candidate, persist no credentials, and cancel safely', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-test-cancel-'))
const statePath = join(root, 'tasks.json')
const never = () => new Promise(() => {})
const manager = new ProxyTestManager({
statePath,
resolve: never,
targets: [{ id: 'blocked', host: 'blocked.example', port: 443, path: '/' }],
})
const state = current()
const value = candidate({
enabled: true,
proxy: { host: 'proxy.example', port: 1080, username: 'alice', password: 'never-persist-this' },
scopes: { updates: true },
})
const started = await manager.start({ baseRevision: state.revision, value }, state)
await assert.rejects(manager.start({ baseRevision: state.revision, value, unexpected: true }, state), error => (
error.code === 'INVALID_CONFIG' && error.stage === 'test'
))
await assert.rejects(manager.start({ baseRevision: state.revision, value }, state), error => error.code === 'PROXY_TEST_BUSY')
assert.equal((await readFile(statePath, 'utf8')).includes('never-persist-this'), false)
await manager.cancel(started.taskId)
const cancelled = await terminal(manager, started.taskId)
assert.equal(cancelled.status, 'cancelled')
assert.equal(cancelled.error.errorCode, 'REQUEST_CANCELLED')
assert.equal(cancelled.stages.find(stage => stage.stage === 'proxy-address').status, 'cancelled')
assert.equal(cancelled.stages.find(stage => stage.stage === 'proxy-address').errorCode, 'REQUEST_CANCELLED')
assert.equal((await readFile(statePath, 'utf8')).includes('alice'), false)
})
test('proxy test reload marks an interrupted credential-free task failed', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-test-reload-'))
const statePath = join(root, 'tasks.json')
const taskId = '123e4567-e89b-42d3-a456-426614174000'
const timestamp = '2026-08-25T00:00:00.000Z'
await writeFile(statePath, `${JSON.stringify({
schema: 1,
tasks: [{
schema: 1, taskId, status: 'running', baseRevision: 'old-revision',
candidateHash: `sha256:${'a'.repeat(64)}`, mode: 'proxy', currentStage: 'proxy-connect',
stages: proxyTestInternals.STAGES.map(stage => ({
stage, status: stage === 'proxy-connect' ? 'running' : 'pending', durationMs: null, errorCode: null, detail: null,
})),
error: null, createdAt: timestamp, updatedAt: timestamp,
}],
})}\n`)
const manager = new ProxyTestManager({ statePath, now: () => new Date('2026-08-25T00:00:01.000Z') })
await manager.initialize(async path => JSON.parse(await readFile(path, 'utf8')))
const restored = manager.get(taskId)
assert.equal(restored.status, 'failed')
assert.equal(restored.error.errorCode, 'PROXY_TEST_INTERRUPTED')
assert.equal(restored.stages.every(stage => !['running', 'pending'].includes(stage.status)), true)
})
@@ -0,0 +1,434 @@
import assert from 'node:assert/strict'
import { createHash, generateKeyPairSync } from 'node:crypto'
import { cp, lstat, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import { verifyRecoveryKeyring } from '../stage0/lib/keyring.mjs'
import { parseEnvironmentManifest, parseStable } from '../lib/contracts.mjs'
import { parseImageInventory } from '../lib/deployment-contracts.mjs'
import { verifyDetached } from '../stage0/lib/signature.mjs'
import { verifyImageRelease } from '../tools/verify-image-release.mjs'
import { createEnvironmentRelease } from '../tools/environment-release.mjs'
import { verifyManagementDependencies } from '../tools/verify-management-dependencies.mjs'
import { parseBootstrapVersion, validateBootstrapContentTransition } from '../lib/bootstrap-version.mjs'
import { writeDshEntrypointFixture } from './fixtures/dsh-package.mjs'
const supportedTargetUrl = new URL('../../../release/supported-target.json', import.meta.url)
const environmentDefinitionUrl = new URL('../../environment/definition.json', import.meta.url)
const supportedDshVersion = JSON.parse(await readFile(supportedTargetUrl, 'utf8')).latestSupportedDsh
const environmentVersion = JSON.parse(await readFile(environmentDefinitionUrl, 'utf8')).version
test('Bootstrap content changes require a strictly newer Bootstrap version', () => {
assert.equal(parseBootstrapVersion('1.0.1'), '1.0.1')
assert.equal(parseBootstrapVersion('1.0.1\n'), '1.0.1')
assert.throws(() => parseBootstrapVersion('1.0'), /Bootstrap VERSION is invalid/)
assert.throws(() => parseBootstrapVersion(' 1.0.1\n'), /Bootstrap VERSION is invalid/)
assert.throws(() => parseBootstrapVersion('1.0.1\nextra'), /Bootstrap VERSION is invalid/)
assert.throws(() => parseBootstrapVersion('99999999999999999999.0.0'), /Bootstrap VERSION is invalid/)
assert.doesNotThrow(() => validateBootstrapContentTransition({
previousVersion: '1.0.0', previousSha256: 'a'.repeat(64),
nextVersion: '1.0.0', nextSha256: 'a'.repeat(64),
}))
assert.doesNotThrow(() => validateBootstrapContentTransition({
previousVersion: '1.0.0', previousSha256: 'a'.repeat(64),
nextVersion: '1.0.1', nextSha256: 'b'.repeat(64),
}))
for (const nextVersion of ['1.0.0', '0.9.9']) {
assert.throws(() => validateBootstrapContentTransition({
previousVersion: '1.0.0', previousSha256: 'a'.repeat(64),
nextVersion, nextSha256: 'b'.repeat(64),
}), /content changed without increasing Bootstrap VERSION/)
}
})
test('Stage-0 launches the packaged outbound proxy entrypoint', async () => {
const source = await readFile(new URL('../stage0/index.mjs', import.meta.url), 'utf8')
assert.match(source, /'services', 'outbound-proxy', 'index\.mjs'/)
assert.doesNotMatch(source, /'services', 'proxy', 'index\.mjs'/)
})
test('Stage-0 launches the packaged Access Manager entrypoint', async () => {
const source = await readFile(new URL('../stage0/index.mjs', import.meta.url), 'utf8')
assert.match(source, /'services', 'access-manager', 'index\.mjs'/)
})
function pair(root, name) {
const value = generateKeyPairSync('ed25519')
const privatePath = join(root, `${name}-private.pem`)
const publicPath = join(root, `${name}-public.pem`)
return Promise.all([
writeFile(privatePath, value.privateKey.export({ format: 'pem', type: 'pkcs8' })),
writeFile(publicPath, value.publicKey.export({ format: 'pem', type: 'spki' })),
]).then(() => ({ ...value, privatePath, publicPath }))
}
test('offline keyring tool emits a Recovery-verifiable monotonic public bundle', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-keyring-tool-'))
const recovery = await pair(root, 'recovery')
const current = await pair(root, 'current')
const next = await pair(root, 'next')
const output = join(root, 'output')
const result = spawnSync(process.execPath, [
new URL('../tools/keyring.mjs', import.meta.url).pathname,
recovery.privatePath, current.publicPath, next.publicPath, '1', output, '-',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const bytes = await readFile(join(output, 'keyring.json'))
const signature = JSON.parse(await readFile(join(output, 'keyring.sig.json')))
const publicKey = (await readFile(join(output, 'recovery-root.spki.base64'), 'utf8')).trim()
assert.equal(verifyRecoveryKeyring(bytes, signature, publicKey).generation, 1)
})
test('release tool signs an exact supported target with the configured current key', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-release-tool-'))
const release = await pair(root, 'release')
const publicDer = release.publicKey.export({ format: 'der', type: 'spki' })
const currentKeyId = createHash('sha256').update(publicDer).digest('hex')
const names = ['bootstrap-manifest', 'bootstrap-signature', 'environment-manifest', 'environment-signature']
const artifacts = []
for (const id of names) {
const path = join(root, id)
await writeFile(path, id)
artifacts.push({ id, path, mediaType: 'application/octet-stream' })
}
const config = {
currentKeyId,
keyringGeneration: 1,
targetSequence: 2,
artifactBaseUrl: 'https://release.example/v2/',
artifacts,
officialDshPolicy: JSON.parse(await readFile(new URL('../../../release/official-dsh-policy.json', import.meta.url))),
desired: {
bootstrap: { version: '1', manifestArtifactId: 'bootstrap-manifest', signatureArtifactId: 'bootstrap-signature' },
environment: { version: '2', manifestArtifactId: 'environment-manifest', signatureArtifactId: 'environment-signature' },
dsh: { version: '0.1.0-rc.7', integrity: `sha512-${Buffer.alloc(64).toString('base64')}` },
},
}
const configPath = join(root, 'config.json')
const output = join(root, 'output')
await writeFile(configPath, JSON.stringify(config))
const result = spawnSync(process.execPath, [
new URL('../tools/build-release.mjs', import.meta.url).pathname,
configPath, release.privatePath, output,
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const stable = await readFile(join(output, 'stable.json'))
assert.equal(parseStable(stable).targetSequence, 2)
verifyDetached(stable, JSON.parse(await readFile(join(output, 'stable.sig.json'))), publicDer.toString('base64'))
})
test('Management terminal dependencies are exact, licensed, and architecture-neutral', async () => {
const root = new URL('../../control-plane/services/management/', import.meta.url).pathname
const manifest = JSON.parse(await readFile(join(root, 'package.json')))
const lock = JSON.parse(await readFile(join(root, 'package-lock.json')))
assert.equal(Object.hasOwn(manifest, 'version'), false)
assert.equal(Object.hasOwn(lock, 'version'), false)
assert.equal(Object.hasOwn(lock.packages[''], 'version'), false)
const result = await verifyManagementDependencies(root)
assert.deepEqual(result.packages, {
'@xterm/addon-fit': '0.11.0', '@xterm/xterm': '6.0.0', 'qrcode-generator': '2.0.4', undici: '8.10.0', ws: '8.21.3',
})
assert.equal(result.nativeModules, 0)
})
test('Environment release identity ignores target metadata but covers packaged content and official DSH policy', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-environment-release-'))
const bootstrapPath = join(root, 'bootstrap.json')
const environmentPath = join(root, 'environment.json')
const policyPath = new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname
const common = {
schema: 1,
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-21T00:00:00.000Z',
artifacts: [{
id: 'artifact', mediaType: 'application/octet-stream', sha256: 'a'.repeat(64), size: 1,
url: 'https://release.example/targets/1/artifact',
}],
}
const bootstrap = { ...common, manifestType: 'bootstrap', version: '1.0.0', bootstrapApi: 1, entrypoint: '/platform/bootstrap/index.mjs' }
const environment = {
...common, manifestType: 'environment', version: '1.0.0', bootstrapApi: 1,
components: [{ id: 'component', sha256: 'a'.repeat(64) }], patches: [], systemPlugins: [],
}
await writeFile(bootstrapPath, JSON.stringify(bootstrap))
await writeFile(environmentPath, JSON.stringify(environment))
const first = await createEnvironmentRelease({ bootstrapManifestPath: bootstrapPath, environmentManifestPath: environmentPath, officialDshPolicyPath: policyPath })
bootstrap.targetSequence = 2
bootstrap.issuedAt = '2026-08-22T00:00:00.000Z'
bootstrap.artifacts[0].url = 'https://release.example/targets/2/artifact'
environment.targetSequence = 2
environment.issuedAt = '2026-08-22T00:00:00.000Z'
environment.artifacts[0].url = 'https://release.example/targets/2/artifact'
await writeFile(bootstrapPath, JSON.stringify(bootstrap))
await writeFile(environmentPath, JSON.stringify(environment))
const second = await createEnvironmentRelease({ bootstrapManifestPath: bootstrapPath, environmentManifestPath: environmentPath, officialDshPolicyPath: policyPath })
assert.deepEqual(second, first)
environment.artifacts[0].sha256 = 'b'.repeat(64)
environment.components[0].sha256 = 'b'.repeat(64)
await writeFile(environmentPath, JSON.stringify(environment))
const changed = await createEnvironmentRelease({ bootstrapManifestPath: bootstrapPath, environmentManifestPath: environmentPath, officialDshPolicyPath: policyPath })
assert.notEqual(changed.environmentContentSha256, first.environmentContentSha256)
environment.artifacts[0].sha256 = 'a'.repeat(64)
environment.components[0].sha256 = 'a'.repeat(64)
await writeFile(environmentPath, JSON.stringify(environment))
const changedPolicyPath = join(root, 'official-dsh-policy.json')
const changedPolicy = JSON.parse(await readFile(policyPath, 'utf8'))
changedPolicy.keys[0].expires = '2027-08-21T00:00:00.000Z'
await writeFile(changedPolicyPath, JSON.stringify(changedPolicy))
const policyChanged = await createEnvironmentRelease({
bootstrapManifestPath: bootstrapPath,
environmentManifestPath: environmentPath,
officialDshPolicyPath: changedPolicyPath,
})
assert.notEqual(policyChanged.officialDshPolicySha256, first.officialDshPolicySha256)
})
test('prepares one flat Recovery-rooted release from the reviewed Supported Target', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-prepare-release-'))
const recovery = await pair(root, 'recovery')
const current = await pair(root, 'current')
const next = await pair(root, 'next')
const trust = join(root, 'trust')
let result = spawnSync(process.execPath, [
new URL('../tools/keyring.mjs', import.meta.url).pathname,
recovery.privatePath, current.publicPath, next.publicPath, '1', trust, '-',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const packageRoot = join(root, 'npm', 'package')
await writeDshEntrypointFixture(packageRoot)
await writeFile(join(packageRoot, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', version: supportedDshVersion }))
const picker = join(packageRoot, 'node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib')
const connection = join(packageRoot, 'node_modules/@deepseek-ai/dsh-client-connection/lib')
await mkdir(picker, { recursive: true })
await mkdir(connection, { recursive: true })
await writeFile(join(picker, 'index.js'), 'const target = resolve(path ?? home);\n')
await writeFile(join(connection, 'client.js'), 'isLoopback: pageLocation === void 0 || isLoopbackHostname(pageLocation.hostname),\n')
const tarball = join(root, `deepseek-ai-dsh-${supportedDshVersion}.tgz`)
result = spawnSync('tar', ['-czf', tarball, '-C', join(root, 'npm'), 'package'], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const output = join(root, 'release')
result = spawnSync(process.execPath, [
new URL('../tools/prepare-release.mjs', import.meta.url).pathname,
supportedTargetUrl.pathname,
environmentDefinitionUrl.pathname,
new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname,
trust, current.privatePath, tarball, '-', '1', 'https://release.example/release-channel/targets/1/', output,
], { encoding: 'utf8', env: { ...process.env, SOURCE_DATE_EPOCH: '1787068800' } })
assert.equal(result.status, 0, result.stderr)
const files = await readdir(output)
for (const name of [
'bootstrap.tgz', 'bootstrap.manifest.json', 'bootstrap.manifest.sig.json',
'environment.manifest.json', 'environment.manifest.sig.json',
'stable.json', 'stable.sig.json', 'keyring.json', 'keyring.sig.json',
]) assert.ok(files.includes(name), `${name} is missing`)
assert.equal(files.includes(`deepseek-ai-dsh-${supportedDshVersion}.tgz`), false)
assert.equal(files.some(name => name.startsWith('.')), false)
const bootstrapArchive = spawnSync('tar', ['-tzf', join(output, 'bootstrap.tgz')], { encoding: 'utf8' })
assert.equal(bootstrapArchive.status, 0, bootstrapArchive.stderr)
const bootstrapEntries = bootstrapArchive.stdout.trim().split('\n')
for (const name of [
'platform/bootstrap/index.mjs',
'control-plane/definition.json',
'control-plane/hooks/dsh-web-ready.mjs',
'control-plane/hooks/recovery/index.mjs',
'control-plane/services/gateway/index.mjs',
'control-plane/services/access-manager/index.mjs',
'control-plane/services/access-manager/supervisor.mjs',
'control-plane/services/access-manager/lib/server.mjs',
'control-plane/services/outbound-proxy/index.mjs',
'control-plane/services/outbound-proxy/supervisor.mjs',
'control-plane/services/management/index.mjs',
'control-plane/services/management/public/index.html',
'control-plane/services/management/package-lock.json',
'control-plane/services/management/node_modules/ws/index.js',
'control-plane/services/management/node_modules/ws/LICENSE',
'control-plane/services/management/node_modules/undici/index.js',
'control-plane/services/management/node_modules/undici/LICENSE',
'control-plane/services/management/node_modules/@xterm/xterm/lib/xterm.mjs',
'control-plane/services/management/node_modules/@xterm/xterm/css/xterm.css',
'control-plane/services/management/node_modules/@xterm/addon-fit/lib/addon-fit.mjs',
'control-plane/services/management/terminal/pty-helper.py',
'control-plane/services/management/terminal/sessions.mjs',
'control-plane/modules/file-manager/index.mjs',
'control-plane/modules/file-manager/transfers.mjs',
'control-plane/modules/file-manager/editor.mjs',
'control-plane/modules/file-manager/tasks.mjs',
'control-plane/modules/file-manager/archives.mjs',
'control-plane/modules/skill-manager/index.mjs',
]) assert.ok(bootstrapEntries.includes(name), `${name} is missing from bootstrap.tgz`)
assert.equal(bootstrapEntries.some(name => name.startsWith('control-plane/skills/')), false)
const skillArchive = spawnSync('tar', ['-tzf', join(output, 'system-skill-catalog')], { encoding: 'utf8' })
assert.equal(skillArchive.status, 0, skillArchive.stderr)
assert.match(skillArchive.stdout, /^skills\/catalog\.json$/m)
assert.match(skillArchive.stdout, /^skills\/dsh-docker-operations\/SKILL\.md$/m)
assert.equal(bootstrapEntries.some(name => name.endsWith('.node')), false)
const stableBytes = await readFile(join(output, 'stable.json'))
const stable = parseStable(stableBytes)
const ring = JSON.parse(await readFile(join(trust, 'keyring.json'), 'utf8'))
verifyDetached(stableBytes, JSON.parse(await readFile(join(output, 'stable.sig.json'))), ring.current.publicKey)
assert.equal(stable.desired.dsh.version, supportedDshVersion)
assert.equal(stable.desired.environment.version, environmentVersion)
assert.equal(stable.desired.bootstrap.version, (await readFile(new URL('../bootstrap/VERSION', import.meta.url), 'utf8')).trim())
assert.equal(stable.officialDshPolicy.packageName, '@deepseek-ai/dsh')
assert.equal(stable.artifacts.some(artifact => artifact.mediaType === 'application/vnd.npm.package+gzip'), false)
assert.equal(stable.artifacts.every(artifact => !artifact.url.includes('/artifacts/')), true)
const verifiedImage = await verifyImageRelease({
releaseRoot: output,
recoveryPublicKeyPath: join(trust, 'recovery-root.spki.base64'),
dshTarballPath: tarball,
supportedTargetPath: supportedTargetUrl.pathname,
environmentDefinitionPath: environmentDefinitionUrl.pathname,
})
assert.equal(verifiedImage.stable.targetSequence, 1)
assert.equal(verifiedImage.environment.manifest.version, environmentVersion)
const imageInput = join(root, 'image-input')
const seedOutput = join(root, 'formal-seed')
await mkdir(imageInput)
await cp(output, join(imageInput, 'release'), { recursive: true })
await cp(join(trust, 'recovery-root.spki.base64'), join(imageInput, 'recovery-root.spki.base64'))
await cp(tarball, join(imageInput, 'dsh.tgz'))
await cp(supportedTargetUrl, join(imageInput, 'supported-target.json'))
await cp(environmentDefinitionUrl, join(imageInput, 'environment-definition.json'))
result = spawnSync(process.execPath, [
new URL('../tools/build-seed.mjs', import.meta.url).pathname,
packageRoot, seedOutput, imageInput, 'fixture-revision',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const inventory = parseImageInventory(await readFile(join(seedOutput, 'inventory.json')))
assert.equal(inventory.authority, 'stable')
assert.equal(inventory.targetSequence, 1)
assert.equal(inventory.deployment.dshVersion, supportedDshVersion)
assert.equal((await lstat(join(seedOutput, 'environments', environmentVersion, 'environment.manifest.json'))).mode & 0o777, 0o444)
assert.equal(
await readFile(join(seedOutput, 'trust', 'recovery-root.spki.base64'), 'utf8'),
await readFile(join(trust, 'recovery-root.spki.base64'), 'utf8'),
)
assert.deepEqual(
await readFile(join(seedOutput, 'trust', 'keyring.json')),
await readFile(join(trust, 'keyring.json')),
)
assert.deepEqual(
await readFile(join(seedOutput, 'trust', 'keyring.sig.json')),
await readFile(join(trust, 'keyring.sig.json')),
)
await assert.rejects(lstat(join(seedOutput, 'trust', 'DEVELOPMENT_FIXTURE')), { code: 'ENOENT' })
const environment = parseEnvironmentManifest(await readFile(join(output, 'environment.manifest.json')))
assert.equal(environment.artifacts.every(artifact => !artifact.url.includes('/artifacts/')), true)
const changedBootstrapRelease = join(root, 'changed-bootstrap-release')
await cp(output, changedBootstrapRelease, { recursive: true })
const changedBootstrapManifestPath = join(changedBootstrapRelease, 'bootstrap.manifest.json')
const changedBootstrapManifest = JSON.parse(await readFile(changedBootstrapManifestPath, 'utf8'))
changedBootstrapManifest.artifacts[0].sha256 = 'f'.repeat(64)
await writeFile(changedBootstrapManifestPath, JSON.stringify(changedBootstrapManifest))
await rm(join(changedBootstrapRelease, 'bootstrap.manifest.sig.json'))
result = spawnSync(process.execPath, [
new URL('../tools/sign.mjs', import.meta.url).pathname,
'sign', current.privatePath, changedBootstrapManifestPath,
join(changedBootstrapRelease, 'bootstrap.manifest.sig.json'),
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const changedStablePath = join(changedBootstrapRelease, 'stable.json')
const changedStable = JSON.parse(await readFile(changedStablePath, 'utf8'))
for (const [id, name] of [
['bootstrap-manifest', 'bootstrap.manifest.json'],
['bootstrap-signature', 'bootstrap.manifest.sig.json'],
]) {
const bytes = await readFile(join(changedBootstrapRelease, name))
const artifact = changedStable.artifacts.find(candidate => candidate.id === id)
artifact.sha256 = createHash('sha256').update(bytes).digest('hex')
artifact.size = bytes.byteLength
}
await writeFile(changedStablePath, JSON.stringify(changedStable))
await rm(join(changedBootstrapRelease, 'stable.sig.json'))
result = spawnSync(process.execPath, [
new URL('../tools/sign.mjs', import.meta.url).pathname,
'sign', current.privatePath, changedStablePath, join(changedBootstrapRelease, 'stable.sig.json'),
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const invalidBootstrapOutput = join(root, 'unchanged-bootstrap-version-release')
result = spawnSync(process.execPath, [
new URL('../tools/prepare-release.mjs', import.meta.url).pathname,
supportedTargetUrl.pathname,
environmentDefinitionUrl.pathname,
new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname,
trust, current.privatePath, tarball, changedBootstrapRelease, '2',
'https://release.example/platform-bootstrap-conflict/', invalidBootstrapOutput,
], { encoding: 'utf8', env: { ...process.env, SOURCE_DATE_EPOCH: '1787068801' } })
assert.notEqual(result.status, 0)
assert.match(result.stderr, /Bootstrap content changed without increasing Bootstrap VERSION/)
await assert.rejects(lstat(invalidBootstrapOutput), error => error?.code === 'ENOENT')
const rollbackOutput = join(root, 'rollback-release')
result = spawnSync(process.execPath, [
new URL('../tools/prepare-release.mjs', import.meta.url).pathname,
supportedTargetUrl.pathname,
new URL('../../environment/definition.json', import.meta.url).pathname,
new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname,
trust, current.privatePath, tarball, output, '1',
'https://release.example/platform-1-repeat/', rollbackOutput,
], { encoding: 'utf8' })
assert.notEqual(result.status, 0)
const futureTrust = join(root, 'future-trust')
result = spawnSync(process.execPath, [
new URL('../tools/keyring.mjs', import.meta.url).pathname,
recovery.privatePath, current.publicPath, next.publicPath, '2', futureTrust, '-',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
const futureRelease = join(root, 'future-release')
await cp(output, futureRelease, { recursive: true })
await cp(join(futureTrust, 'keyring.json'), join(futureRelease, 'keyring.json'), { force: true })
await cp(join(futureTrust, 'keyring.sig.json'), join(futureRelease, 'keyring.sig.json'), { force: true })
const futureStable = JSON.parse(await readFile(join(futureRelease, 'stable.json'), 'utf8'))
futureStable.keyringGeneration = 2
await writeFile(join(futureRelease, 'stable.json'), JSON.stringify(futureStable))
await rm(join(futureRelease, 'stable.sig.json'))
result = spawnSync(process.execPath, [
new URL('../tools/sign.mjs', import.meta.url).pathname,
'sign', current.privatePath, join(futureRelease, 'stable.json'), join(futureRelease, 'stable.sig.json'),
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
result = spawnSync(process.execPath, [
new URL('../tools/prepare-release.mjs', import.meta.url).pathname,
supportedTargetUrl.pathname,
new URL('../../environment/definition.json', import.meta.url).pathname,
new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname,
trust, current.privatePath, tarball, futureRelease, '2',
'https://release.example/platform-2/', join(root, 'generation-rollback-release'),
], { encoding: 'utf8' })
assert.notEqual(result.status, 0)
assert.match(result.stderr, /keyring generation must not roll back/)
const conflictingTrust = join(root, 'conflicting-trust')
const conflictingNext = await pair(root, 'conflicting-next')
result = spawnSync(process.execPath, [
new URL('../tools/keyring.mjs', import.meta.url).pathname,
recovery.privatePath, current.publicPath, conflictingNext.publicPath, '1', conflictingTrust, '-',
], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
result = spawnSync(process.execPath, [
new URL('../tools/prepare-release.mjs', import.meta.url).pathname,
supportedTargetUrl.pathname,
new URL('../../environment/definition.json', import.meta.url).pathname,
new URL('../../../release/official-dsh-policy.json', import.meta.url).pathname,
conflictingTrust, current.privatePath, tarball, output, '2',
'https://release.example/platform-conflict/', join(root, 'conflicting-release'),
], { encoding: 'utf8' })
assert.notEqual(result.status, 0)
assert.match(result.stderr, /same keyring generation must be byte-identical/)
})
@@ -0,0 +1,82 @@
import assert from 'node:assert/strict'
import { createServer, request as httpRequest } from 'node:http'
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { LocalApiClient } from '../../control-plane/modules/updater/lib/client.mjs'
import {
createRestrictedCliServer,
restrictedCliRoute,
} from '../../control-plane/services/management/restricted-cli.mjs'
import { listenManagement } from '../../control-plane/services/management/server.mjs'
test('restricted CLI channel forwards only documented public operations', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-restricted-cli-'))
const managementSocket = join(root, 'management.sock')
const cliSocket = join(root, 'management-cli.sock')
const seen = []
const management = createServer((request, response) => {
seen.push({ method: request.method, url: request.url, headers: request.headers })
request.resume()
response.writeHead(200, { 'content-type': 'application/json' })
response.end('{"ok":true}')
})
const cli = createRestrictedCliServer({ managementSocketPath: managementSocket, token: 'x'.repeat(32) })
try {
await listenManagement(management, managementSocket)
await listenManagement(cli, cliSocket)
const client = new LocalApiClient(cliSocket)
assert.deepEqual(await client.request('GET', '/_dsh_platform/api/v1/status'), { ok: true })
assert.deepEqual(await client.request('GET', '/_dsh_platform/api/v1/logs?limit=10'), { ok: true })
assert.deepEqual(await client.request('POST', '/_dsh_platform/api/v1/restart-dsh'), { ok: true })
await assert.rejects(
client.request('GET', '/_dsh_platform/api/v1/auth-settings'),
error => error.statusCode === 404 && error.code === 'CLI_ROUTE_NOT_AVAILABLE',
)
await assert.rejects(
client.request('GET', '/_dsh_platform/api/v1/files/list?path=%2F'),
error => error.statusCode === 404 && error.code === 'CLI_ROUTE_NOT_AVAILABLE',
)
await new Promise((resolve, reject) => {
const outgoing = httpRequest({
socketPath: cliSocket,
method: 'GET',
path: '/_dsh_platform/api/v1/status',
headers: {
authorization: 'Basic forged',
cookie: 'dsh_management=forged',
origin: 'https://forged.example',
'x-dsh-csrf': 'forged',
'x-dsh-internal-capability': 'forged',
'x-dsh-restricted-cli': 'forged',
},
}, response => {
response.resume()
response.once('end', resolve)
})
outgoing.once('error', reject)
outgoing.end()
})
assert.equal(seen.length, 4)
assert.equal(seen.every(value => value.headers['x-dsh-restricted-cli'] === 'x'.repeat(32)), true)
const hardened = seen.at(-1).headers
for (const name of ['authorization', 'cookie', 'origin', 'x-dsh-csrf', 'x-dsh-internal-capability']) {
assert.equal(hardened[name], undefined)
}
} finally {
await Promise.all([
new Promise(resolve => cli.close(resolve)),
new Promise(resolve => management.close(resolve)),
])
await rm(root, { recursive: true, force: true })
}
})
test('restricted CLI allowlist binds both method and normalized pathname', () => {
assert.equal(restrictedCliRoute('GET', '/_dsh_platform/api/v1/status'), true)
assert.equal(restrictedCliRoute('POST', '/_dsh_platform/api/v1/status'), false)
assert.equal(restrictedCliRoute('GET', '/_dsh_platform/api/v1/logs?source=stage0'), true)
assert.equal(restrictedCliRoute('GET', '/_dsh_platform/api/v1/terminal/sessions'), false)
assert.equal(restrictedCliRoute('GET', '/_dsh_platform/api/v1/status/../auth-settings'), false)
})
@@ -0,0 +1,148 @@
import assert from 'node:assert/strict'
import { mkdtemp } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { UpdateJournal } from '../../control-plane/modules/updater/lib/journal.mjs'
import { CompleteStateRecovery } from '../../control-plane/modules/updater/lib/rollback.mjs'
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-complete-rollback-'))
const journal = new UpdateJournal(join(root, 'journal.json'))
const from = {
dsh: '0.1.0-rc.7', environment: 'env-1', runtime: 'runtime-a', dataSnapshot: null,
receiptTokens: ['stable-b', 'stable-a'],
}
const to = { dsh: '0.1.0-rc.8', environment: 'env-1', runtime: 'runtime-b' }
await journal.begin({ transactionId: 'transaction-a', mode: 'experimental', from, to })
await journal.transition('candidate-ready', { receiptTokens: ['experimental'] })
await journal.transition('suspended')
await journal.transition('snapshot-created', { snapshotId: 'snapshot-a' })
await journal.transition('switched')
await journal.transition('probation', { probationUntil: '2026-08-19T00:02:00.000Z' })
await journal.transition('committed')
const calls = []
const current = { ...to, dataSnapshot: null, receiptTokens: ['experimental', 'stable-a', 'stable-b'] }
const activator = {
currentDeployment: async () => current,
rollbackDeployments: async () => ({
current: {
id: current.runtime,
dshVersion: current.dsh,
environmentVersion: current.environment,
receiptTokens: current.receiptTokens,
},
previous: {
id: 'runtime-a-materialized',
dshVersion: from.dsh,
environmentVersion: from.environment,
receiptTokens: from.receiptTokens,
},
}),
suspendDsh: async () => calls.push('suspend'),
restoreDeployment: async (value, options) => calls.push(`restore:${value.runtime}:${String(options.resume)}`),
resumeDsh: async () => calls.push('resume'),
}
const snapshots = {
inspect: async id => ({
id, createdAt: '2026-08-19T00:00:00.000Z', archiveSha256: 'a'.repeat(64), archiveSize: 42,
runtimeId: from.runtime, environmentVersion: from.environment, dshVersion: from.dsh,
}),
restore: async id => calls.push(`data:${id}`),
}
return { journal, from, to, current, activator, snapshots, calls, recovery: new CompleteStateRecovery({ journal, snapshots, activator }) }
}
test('binds a complete rollback plan to current Runtime, receipts, and verified snapshot', async () => {
const value = await fixture()
const plan = await value.recovery.plan()
assert.equal(plan.previous.runtime, 'runtime-a-materialized')
assert.deepEqual(plan.previous.receiptTokens, ['stable-a', 'stable-b'])
value.current.runtime = 'different-runtime'
assert.equal((await value.recovery.plan()).snapshot, null)
})
test('restores the previous complete state only with the current plan ID', async () => {
const value = await fixture()
const plan = await value.recovery.plan()
const progress = []
await assert.rejects(value.recovery.restore('stale'), /stale/)
await assert.rejects(value.recovery.restore(plan.planId, { requireConfirmation: true }), /confirmation/)
const result = await value.recovery.restore(plan.planId, {
requireConfirmation: true,
confirmDataLoss: true,
onProgress: async (phase, percent) => progress.push([phase, percent]),
})
assert.equal(result.status, 'rolled-back')
assert.deepEqual(progress, [['stopping', 15], ['switching', 35], ['restoring-data', 65], ['verifying', 85]])
assert.deepEqual(value.calls, ['suspend', 'restore:runtime-a-materialized:false', 'data:snapshot-a', 'resume'])
assert.equal((await value.journal.read()).phase, 'rolled-back')
assert.equal((await value.recovery.plan()).snapshot, null)
})
test('rejects a valid snapshot archive bound to a different deployment', async () => {
const value = await fixture()
const inspect = value.snapshots.inspect
value.snapshots.inspect = async id => ({ ...await inspect(id), environmentVersion: 'other-env' })
await assert.rejects(value.recovery.plan(), /does not describe/)
})
test('binds Stable rollback to the exact Bootstrap previous slot without a data snapshot', async () => {
const calls = []
const progress = []
const references = {
environment: { sha256: 'a'.repeat(64) },
pristine: { sha256: 'b'.repeat(64) },
runtime: { sha256: 'c'.repeat(64) },
systemPlugins: { sha256: 'd'.repeat(64) },
}
const current = {
id: 'deployment-record-current', authority: 'stable', targetSequence: 2,
dshVersion: '0.1.0-rc.8', environmentVersion: 'env-2', receiptTokens: ['stable-2'], ...references,
}
const previous = {
id: 'deployment-record-previous', authority: 'stable', targetSequence: 1,
dshVersion: '0.1.0-rc.7', environmentVersion: 'env-1', receiptTokens: ['stable-1'], ...references,
}
const recovery = new CompleteStateRecovery({
journal: { read: async () => undefined },
snapshots: {},
activator: {
rollbackDeployments: async () => ({ current, previous }),
rollback: async recordId => calls.push(recordId),
},
})
const plan = await recovery.plan()
assert.equal(plan.mode, 'stable')
assert.equal(plan.snapshot, null)
assert.equal(plan.previous.runtime, previous.id)
await assert.rejects(recovery.restore(plan.planId, {
requireConfirmation: true,
confirmDataLoss: true,
}), /snapshot/)
assert.deepEqual(calls, [])
assert.deepEqual(await recovery.restore(plan.planId, {
onProgress: async (phase, percent) => progress.push([phase, percent]),
}), { status: 'rolled-back', transactionId: null })
assert.deepEqual(calls, [previous.id])
assert.deepEqual(progress, [['switching', 35], ['verifying', 90]])
})
test('does not expose a rollback between Image and Managed Records with identical content', async () => {
const reference = { sha256: 'a'.repeat(64) }
const base = {
authority: 'stable', targetSequence: 1, dshVersion: '0.1.0-rc.7', environmentVersion: 'env-1',
environment: reference, pristine: reference, runtime: reference, systemPlugins: reference, receiptTokens: [],
}
const recovery = new CompleteStateRecovery({
journal: { read: async () => undefined },
snapshots: {},
activator: {
rollbackDeployments: async () => ({
current: { ...base, id: 'deployment-record-image' },
previous: { ...base, id: 'deployment-record-materialized' },
}),
},
})
assert.equal(await recovery.plan(), null)
})
@@ -0,0 +1,245 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { cp, mkdir, mkdtemp, readFile, readdir, readlink, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import test from 'node:test'
import {
buildRuntime,
RuntimeSlots,
verifyNpmIntegrity,
verifyPatchSet,
verifyRuntimePatches,
} from '../../control-plane/modules/patch-manager/index.mjs'
import { verifyDshCompatibility } from '../lib/dsh-compatibility.mjs'
const containerRoot = dirname(dirname(dirname(fileURLToPath(import.meta.url))))
async function pristine() {
const root = await mkdtemp(join(tmpdir(), 'dsh-pristine-'))
await mkdir(join(root, 'lib'), { recursive: true })
await writeFile(join(root, 'lib', 'bin.js'), `#!/usr/bin/env node
const invocation = parseDshArgs(process.argv.slice(2), readVersion());
switch (invocation.mode) {
case "profile": {
const { runProfile } = await import("./profile-boot-fixture.js");
}
}
`)
await writeFile(join(root, 'lib', 'profile-boot-fixture.js'), 'import { r as runProfile } from "./profile-boot-implementation.js";\nexport { runProfile };\n')
await writeFile(join(root, 'lib', 'profile-boot-implementation.js'), `async function runProfile(options) {
\tprocess.on("SIGTERM", () => {
\t\tinterrupt(0);
\t});
\tprocess.on("SIGINT", () => { interrupt(130); });
\tconst ctx = await boot(NAME, rootConfig, patches, (hostCtx) => {
\t\thostCtx.provide(DSH_LAUNCH_ENVIRONMENT_KEY, options.environment);
\t});
\treturn {
\t\tctx,
\t\tshutdown
\t};
}
export { runProfile as r };
`)
const picker = join(root, 'node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib')
const connection = join(root, 'node_modules/@deepseek-ai/dsh-client-connection/lib')
const theme = join(root, 'node_modules/@deepseek-ai/dsh-client-ui-theme/lib')
await mkdir(picker, { recursive: true })
await mkdir(connection, { recursive: true })
await mkdir(theme, { recursive: true })
await writeFile(join(picker, 'index.js'), 'const target = resolve(path ?? home);\n')
await writeFile(join(connection, 'client.js'), 'isLoopback: pageLocation === void 0 || isLoopbackHostname(pageLocation.hostname),\n')
await writeFile(join(theme, 'client.js'), 'var corner_shape_css_default = "@supports (corner-shape:superellipse(1.5)){:root{--dsw-corner-shape:superellipse(1.5)}*,:before,:after{corner-shape:var(--dsw-corner-shape)}}";\n')
await mkdir(join(root, 'node_modules/.bin'), { recursive: true })
await symlink('../tool/bin.js', join(root, 'node_modules/.bin/tool'))
return root
}
async function transportOwnedPristine() {
const root = await pristine()
await writeFile(
join(root, 'node_modules/@deepseek-ai/dsh-client-connection/lib/client.js'),
'isLoopback: transport?.ownsHost === true || pageLocation === void 0 || isLoopbackHostname(pageLocation.hostname),\n',
)
return root
}
async function environment(root, patches) {
const environmentRoot = join(root, 'environment')
await mkdir(join(environmentRoot, 'artifacts'), { recursive: true })
const artifacts = []
const references = []
for (const [index, path] of patches.entries()) {
const bytes = await readFile(path)
const sha256 = createHash('sha256').update(bytes).digest('hex')
const id = `patch-${String(index + 1)}`
await cp(path, join(environmentRoot, 'artifacts', id))
artifacts.push({
id,
mediaType: 'text/javascript',
sha256,
size: bytes.byteLength,
url: `https://example.invalid/${id}`,
})
references.push({ id, sha256 })
}
await writeFile(join(environmentRoot, 'environment.manifest.json'), JSON.stringify({
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-20T00:00:00.000Z',
artifacts,
bootstrapApi: 1,
components: [],
patches: references,
systemPlugins: [],
}))
return environmentRoot
}
test('rebuilds each Runtime from unchanged Pristine with the complete ordered Patch set', async () => {
const source = await pristine()
const originalPicker = await readFile(join(source, 'node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib/index.js'))
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-'))
const patches = [
join(containerRoot, 'environment/resources/patches/directory-picker.mjs'),
join(containerRoot, 'environment/resources/patches/browser-loopback.mjs'),
join(containerRoot, 'environment/resources/patches/managed-lifecycle.mjs'),
join(containerRoot, 'environment/resources/patches/native-corners.mjs'),
]
const first = await buildRuntime({ pristineRoot: source, versionsRoot: join(root, 'versions'), runtimeId: 'one', patchPaths: patches })
const second = await buildRuntime({ pristineRoot: source, versionsRoot: join(root, 'versions'), runtimeId: 'two', patchPaths: patches })
assert.deepEqual(await readFile(join(source, 'node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib/index.js')), originalPicker)
for (const runtime of [first, second]) {
assert.match(await readFile(join(runtime, 'package/node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib/index.js'), 'utf8'), /DSH_DEFAULT_WORKSPACE/)
assert.match(await readFile(join(runtime, 'package/node_modules/@deepseek-ai/dsh-client-connection/lib/client.js'), 'utf8'), /isLoopback: true/)
assert.match(await readFile(join(runtime, 'package/lib/bin.js'), 'utf8'), /prepareManagedInvocation/)
assert.match(await readFile(join(runtime, 'package/lib/profile-boot-implementation.js'), 'utf8'), /managedSigtermHandler/)
assert.match(await readFile(join(runtime, 'package/node_modules/@deepseek-ai/dsh-client-ui-theme/lib/client.js'), 'utf8'), /corner_shape_css_default = ""/)
assert.equal(await readlink(join(runtime, 'package/node_modules/.bin/tool')), '../tool/bin.js')
}
})
test('rejects a Patch mismatch without publishing a partial Runtime', async () => {
const source = await pristine()
await writeFile(join(source, 'node_modules/@deepseek-ai/dsh-client-connection/lib/client.js'), 'changed upstream\n')
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-failure-'))
await assert.rejects(buildRuntime({
pristineRoot: source,
versionsRoot: join(root, 'versions'),
runtimeId: 'broken',
patchPaths: [join(containerRoot, 'environment/resources/patches/browser-loopback.mjs')],
}), /found 0/)
await assert.rejects(readFile(join(root, 'versions/broken/package/lib/bin.js')), { code: 'ENOENT' })
})
test('builds a Runtime from the transport-owned browser classification', async () => {
const source = await transportOwnedPristine()
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-transport-loopback-'))
const runtime = await buildRuntime({
pristineRoot: source,
versionsRoot: join(root, 'versions'),
runtimeId: 'transport-loopback',
patchPaths: [join(containerRoot, 'environment/resources/patches/browser-loopback.mjs')],
})
assert.equal(
await readFile(join(runtime, 'package/node_modules/@deepseek-ai/dsh-client-connection/lib/client.js'), 'utf8'),
'isLoopback: true,\n',
)
})
test('verifies mandatory Patch Artifacts and their applied Runtime effects before startup', async () => {
const source = await pristine()
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-verification-'))
const patches = [
join(containerRoot, 'environment/resources/patches/directory-picker.mjs'),
join(containerRoot, 'environment/resources/patches/browser-loopback.mjs'),
join(containerRoot, 'environment/resources/patches/managed-lifecycle.mjs'),
join(containerRoot, 'environment/resources/patches/native-corners.mjs'),
]
const runtimeRoot = await buildRuntime({
pristineRoot: source,
versionsRoot: join(root, 'versions'),
runtimeId: 'verified',
patchPaths: patches,
})
const environmentRoot = await environment(root, patches)
assert.deepEqual(await verifyRuntimePatches({ runtimeRoot, environmentRoot }), ['patch-1', 'patch-2', 'patch-3', 'patch-4'])
await writeFile(
join(runtimeRoot, 'package/node_modules/@deepseek-ai/dsh-client-connection/lib/client.js'),
'isLoopback: false,\n',
)
await assert.rejects(verifyRuntimePatches({ runtimeRoot, environmentRoot }), /Patch verification failed/)
await writeFile(join(environmentRoot, 'artifacts', 'patch-2'), 'modified artifact\n')
await assert.rejects(verifyRuntimePatches({ runtimeRoot, environmentRoot }), /differs from the Environment Manifest/)
})
test('checks npm SHA-512 integrity and tracks Runtime current/previous slots', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-slots-'))
const tarball = join(root, 'dsh.tgz')
const bytes = Buffer.from('tarball fixture')
await writeFile(tarball, bytes)
await verifyNpmIntegrity(tarball, `sha512-${createHash('sha512').update(bytes).digest('base64')}`)
await assert.rejects(verifyNpmIntegrity(tarball, `sha512-${Buffer.alloc(64).toString('base64')}`), { code: 'TRUST_ARTIFACT_MISMATCH' })
await mkdir(join(root, 'runtime/versions/one'), { recursive: true })
await mkdir(join(root, 'runtime/versions/two'), { recursive: true })
const slots = new RuntimeSlots(join(root, 'runtime'))
await slots.promote('one')
await slots.promote('two')
assert.deepEqual(await slots.state(), { current: 'two', previous: 'one' })
await slots.rollback()
assert.deepEqual(await slots.state(), { current: 'one', previous: 'two' })
})
test('prunes only Runtime versions outside current and previous slots', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-runtime-prune-'))
const slots = new RuntimeSlots(root)
for (const version of ['one', 'two', 'old']) await mkdir(join(root, 'versions', version), { recursive: true })
const imageSeed = await mkdtemp(join(tmpdir(), 'dsh-runtime-image-seed-'))
await writeFile(join(imageSeed, 'sentinel'), 'keep')
await symlink(imageSeed, join(root, 'versions/image-old'), 'dir')
await slots.promote('one')
await slots.promote('two')
assert.deepEqual(await slots.prune(), ['image-old', 'old'])
assert.deepEqual((await readdir(join(root, 'versions'))).sort(), ['one', 'two'])
assert.equal(await readFile(join(imageSeed, 'sentinel'), 'utf8'), 'keep')
})
test('builds and verifies the real DSH 0.1.5 Runtime when its npm tree is provided', {
skip: process.env.DSH_COMPAT_PACKAGE_ROOT === undefined,
}, async t => {
const source = resolve(process.env.DSH_COMPAT_PACKAGE_ROOT)
const root = await mkdtemp(join(tmpdir(), 'dsh-real-runtime-'))
t.after(() => rm(root, { recursive: true, force: true }))
const patches = [
join(containerRoot, 'environment/resources/patches/directory-picker.mjs'),
join(containerRoot, 'environment/resources/patches/browser-loopback.mjs'),
join(containerRoot, 'environment/resources/patches/managed-lifecycle.mjs'),
join(containerRoot, 'environment/resources/patches/native-corners.mjs'),
]
const runtime = await buildRuntime({
pristineRoot: source,
versionsRoot: join(root, 'versions'),
runtimeId: 'dsh-0.1.5-rc.1',
patchPaths: patches,
})
const packageRoot = join(runtime, 'package')
await verifyPatchSet(packageRoot, patches)
assert.deepEqual(await verifyDshCompatibility({
packageRoot,
expectedVersion: '0.1.5-rc.1',
home: join(root, 'home'),
}), {
name: '@deepseek-ai/dsh',
version: '0.1.5-rc.1',
packages: 10,
remoteMethods: 3,
webRows: 5,
})
})
@@ -0,0 +1,156 @@
import assert from 'node:assert/strict'
import { execFile, spawnSync } from 'node:child_process'
import { lstat, mkdtemp, mkdir, readFile, readlink, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { promisify } from 'node:util'
import test from 'node:test'
import { provisionPlatformSeed } from '../stage0/lib/seed.mjs'
import { TrustLedger } from '../stage0/lib/ledger.mjs'
import { verifyRuntimePatches } from '../../control-plane/modules/patch-manager/index.mjs'
import { writeDshEntrypointFixture } from './fixtures/dsh-package.mjs'
const execute = promisify(execFile)
test('checked-in development seed is Recovery-signed and contains no private key', async () => {
const trust = new URL('../seed/trust/', import.meta.url)
const publicKey = (await readFile(new URL('recovery-root.spki.base64', trust), 'utf8')).trim()
const keyring = await readFile(new URL('keyring.json', trust))
const signature = JSON.parse(await readFile(new URL('keyring.sig.json', trust), 'utf8'))
const root = await mkdtemp(join(tmpdir(), 'dsh-seed-trust-'))
const accepted = await new TrustLedger(root, publicKey).acceptKeyring(keyring, signature)
assert.equal(accepted.generation, 1)
for (const name of ['recovery-root.spki.base64', 'keyring.json', 'keyring.sig.json', 'DEVELOPMENT_FIXTURE']) {
assert.doesNotMatch(await readFile(new URL(name, trust), 'utf8'), /PRIVATE KEY/)
}
})
test('registers immutable image seed trees once and preserves later current links', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-platform-seed-'))
const seed = join(root, 'seed')
const data = join(root, 'data')
for (const [group, version] of [['environment', 'env-one'], ['runtime', 'runtime-one']]) {
await mkdir(join(seed, group, version), { recursive: true })
await writeFile(join(seed, group, 'VERSION'), `${version}\n`)
}
await mkdir(join(seed, 'pristine', 'runtime-one', 'node_modules/.bin'), { recursive: true })
await symlink('../package/bin.js', join(seed, 'pristine', 'runtime-one', 'node_modules/.bin/tool'))
await mkdir(join(seed, 'system-plugins', 'env-one'), { recursive: true })
const first = await provisionPlatformSeed(seed, data)
assert.equal(first.seededLinks.length, 4)
for (const [entry, source] of [
['store/environments/versions/env-one', 'environment/env-one'],
['store/runtimes/versions/runtime-one', 'runtime/runtime-one'],
['store/pristine/runtime-one', 'pristine/runtime-one'],
['store/system-plugins/versions/env-one', 'system-plugins/env-one'],
]) {
assert.equal((await lstat(join(data, entry))).isSymbolicLink(), true)
assert.equal(await readlink(join(data, entry)), join(seed, source))
}
assert.equal(await readlink(join(data, 'store/environments', 'current')), 'versions/env-one')
assert.equal(await readlink(join(data, 'store/pristine/runtime-one/node_modules/.bin/tool')), '../package/bin.js')
assert.equal((await lstat(join(data, 'store/snapshots'))).isDirectory(), true)
await writeFile(join(data, 'state/updater', 'sentinel'), 'keep')
const repeated = await provisionPlatformSeed(seed, data)
assert.deepEqual(repeated.seededLinks, [])
assert.equal(await readFile(join(data, 'state/updater', 'sentinel'), 'utf8'), 'keep')
})
test('preserves an existing materialized version instead of replacing it with an image seed link', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-platform-materialized-'))
const seed = join(root, 'seed')
const data = join(root, 'data')
for (const [group, version] of [['environment', 'env-one'], ['runtime', 'runtime-one']]) {
await mkdir(join(seed, group, version), { recursive: true })
await writeFile(join(seed, group, 'VERSION'), `${version}\n`)
}
await mkdir(join(seed, 'pristine/runtime-one'), { recursive: true })
await mkdir(join(seed, 'system-plugins/env-one'), { recursive: true })
await mkdir(join(data, 'store/runtimes/versions/runtime-one'), { recursive: true })
await writeFile(join(data, 'store/runtimes/versions/runtime-one/sentinel'), 'materialized')
await provisionPlatformSeed(seed, data)
assert.equal((await lstat(join(data, 'store/runtimes/versions/runtime-one'))).isDirectory(), true)
assert.equal(await readFile(join(data, 'store/runtimes/versions/runtime-one/sentinel'), 'utf8'), 'materialized')
})
test('repairs broken image entries and current slots after an image replacement', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-platform-replaced-image-'))
const seed = join(root, 'seed')
const data = join(root, 'data')
for (const [group, version] of [['environment', 'env-one'], ['runtime', 'runtime-one']]) {
await mkdir(join(seed, group, version), { recursive: true })
await writeFile(join(seed, group, 'VERSION'), `${version}\n`)
}
await mkdir(join(seed, 'pristine/runtime-one'), { recursive: true })
await mkdir(join(seed, 'system-plugins/env-one'), { recursive: true })
await mkdir(join(data, 'store/runtimes/versions'), { recursive: true })
await symlink('/missing-old-image/runtime-old', join(data, 'store/runtimes/versions/runtime-old'))
await symlink('versions/runtime-old', join(data, 'store/runtimes/current'))
await provisionPlatformSeed(seed, data)
assert.equal(await readlink(join(data, 'store/runtimes/versions/runtime-one')), join(seed, 'runtime/runtime-one'))
assert.equal(await readlink(join(data, 'store/runtimes/current')), 'versions/runtime-one')
assert.equal((await lstat(join(data, 'store/runtimes/current'))).isSymbolicLink(), true)
})
test('rejects seed IDs that could escape their image roots', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-platform-invalid-seed-'))
const seed = join(root, 'seed')
await mkdir(join(seed, 'environment'), { recursive: true })
await mkdir(join(seed, 'runtime'), { recursive: true })
await writeFile(join(seed, 'environment/VERSION'), '../escape\n')
await writeFile(join(seed, 'runtime/VERSION'), 'runtime-one\n')
await assert.rejects(provisionPlatformSeed(seed, join(root, 'data')), /Environment seed ID is invalid/)
})
test('builds a self-contained Bootstrap seed and preserves npm bin links', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-build-seed-'))
const installed = join(root, 'installed')
const output = join(root, 'output')
await writeDshEntrypointFixture(installed)
await writeFile(join(installed, 'package.json'), JSON.stringify({ name: '@deepseek-ai/dsh', version: '0.1.0-rc.fixture' }))
const picker = join(installed, 'node_modules/@deepseek-ai/dsh-host-directory-picker-browse/lib')
const connection = join(installed, 'node_modules/@deepseek-ai/dsh-client-connection/lib')
const theme = join(installed, 'node_modules/@deepseek-ai/dsh-client-ui-theme/lib')
await mkdir(picker, { recursive: true })
await mkdir(connection, { recursive: true })
await mkdir(theme, { recursive: true })
await writeFile(join(picker, 'index.js'), 'const target = resolve(path ?? home);\n')
await writeFile(join(connection, 'client.js'), 'isLoopback: pageLocation === void 0 || isLoopbackHostname(pageLocation.hostname),\n')
await writeFile(join(theme, 'client.js'), 'var corner_shape_css_default = "@supports (corner-shape:superellipse(1.5)){:root{--dsw-corner-shape:superellipse(1.5)}*,:before,:after{corner-shape:var(--dsw-corner-shape)}}";\n')
await mkdir(join(installed, 'node_modules/.bin'), { recursive: true })
await symlink('../tool/bin.js', join(installed, 'node_modules/.bin/tool'))
await execute(process.execPath, [fileURLToPath(new URL('../tools/build-seed.mjs', import.meta.url)), installed, output])
const bootstrapVersion = (await readFile(new URL('../bootstrap/VERSION', import.meta.url), 'utf8')).trim()
const bootstrapRoot = join(output, 'bootstrap', bootstrapVersion)
const contracts = await import(pathToFileURL(join(bootstrapRoot, 'platform/lib/contracts.mjs')).href)
const { parseImageInventory } = await import('../lib/deployment-contracts.mjs')
assert.equal(typeof contracts.parseStable, 'function')
const inventory = parseImageInventory(await readFile(join(output, 'inventory.json')))
assert.equal(inventory.authority, 'development')
assert.equal(inventory.targetSequence, 0)
assert.equal(inventory.bootstrap.version, bootstrapVersion)
assert.equal(inventory.deployment.dshVersion, '0.1.0-rc.fixture')
assert.equal((await lstat(join(bootstrapRoot, 'control-plane/services/management/node_modules/ws/index.js'))).isFile(), true)
assert.equal((await lstat(join(bootstrapRoot, 'control-plane/services/management/node_modules/@xterm/xterm/css/xterm.css'))).isFile(), true)
assert.equal((await lstat(join(bootstrapRoot, 'control-plane/services/outbound-proxy/index.mjs'))).isFile(), true)
assert.equal((await lstat(join(bootstrapRoot, 'control-plane/services/access-manager/index.mjs'))).isFile(), true)
await assert.rejects(lstat(join(bootstrapRoot, 'control-plane/skills')), { code: 'ENOENT' })
const skillArchive = join(
output, 'environments', inventory.deployment.environment.id, 'artifacts', 'system-skill-catalog',
)
const skillListing = spawnSync('tar', ['-tzf', skillArchive], { encoding: 'utf8' })
assert.equal(skillListing.status, 0, skillListing.stderr)
assert.match(skillListing.stdout, /^skills\/dsh-docker-operations\/SKILL\.md$/m)
assert.equal(await readlink(join(output, 'pristine/0.1.0-rc.fixture/node_modules/.bin/tool')), '../tool/bin.js')
assert.equal(await readlink(join(output, 'runtime/0.1.0-rc.fixture/package/node_modules/.bin/tool')), '../tool/bin.js')
assert.deepEqual(await verifyRuntimePatches({
runtimeRoot: join(output, 'runtimes', inventory.deployment.runtime.id),
environmentRoot: join(output, 'environments', inventory.deployment.environment.id),
}), ['directory-picker', 'browser-loopback', 'managed-lifecycle', 'native-corners'])
})
@@ -0,0 +1,143 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
import { buildSystemPluginClient } from '../tools/build-system-plugin-client.mjs'
const root = new URL('../../environment/resources/plugins/settings-document-editor/package/', import.meta.url)
test('Settings Document Editor is an optional DSH web System Plugin', async () => {
const metadata = JSON.parse(await readFile(new URL('package.json', root)))
const patch = JSON.parse(await readFile(new URL('cordis.patch.json', root)))
assert.equal(metadata.name, '@dsh-docker/settings-document-editor')
assert.equal(metadata.dshDocker.description.zh, '在浏览器中查看和编辑 DSH 配置文件。')
assert.equal(metadata.dsh.client.platform, 'web')
assert.ok(metadata.dsh.client.inject.includes('@deepseek-ai/dsh-api-remotes'))
assert.equal(metadata.dsh.client.inject.includes('@deepseek-ai/dsh-client-runtime'), false)
assert.equal(metadata.peerDependencies['@deepseek-ai/dsh-client-runtime'], undefined)
assert.equal(metadata.exports['./client'], './lib/client.bundle.js')
assert.equal(patch[0].insert[0].id, 'dsh-docker.settings-document-editor.plugin')
})
test('Settings Document Editor checked-in bundle matches its source', async () => {
const bundle = await readFile(new URL('lib/client.bundle.js', root), 'utf8')
const rebuilt = await buildSystemPluginClient({
pluginId: '@dsh-docker/settings-document-editor',
sourcePath: new URL('lib/client.js', root),
stylePath: new URL('lib/style.module.css', root),
})
assert.equal(bundle, rebuilt)
assert.doesNotThrow(() => new Function(bundle))
assert.match(bundle, /^window\.__ModuleLoader__\.load\(/)
})
test('Settings Document Editor replaces and restores both pathless DSH open actions', async () => {
const source = await readFile(new URL('lib/client.js', root), 'utf8')
assert.match(source, /\/_dsh_platform\/plugin-api\/v1\/settings-document/)
assert.doesNotMatch(source, /\/_dsh_platform\/api\/v1\/settings-document/)
assert.match(source, /interceptDocumentOpen\([\s\S]*connection\.api\.settings,[\s\S]*'openDocument'/)
assert.match(source, /interceptDocumentOpen\([\s\S]*child\.remote\.settings,[\s\S]*'openSettingsDocument'/)
assert.match(source, /ctx\.inject\(\['remote\.settings'\]/)
assert.match(source, /\{ ok: true, value: \{ opened: true \} \}/)
assert.match(source, /\{ result: \{ ok: true, value: \{ opened: true \} \} \}/)
assert.doesNotMatch(source, /openDocument\(.*path|body:.*path/s)
assert.match(source, /settings\.dshDocumentEditor/)
assert.match(source, /shell\.overlay/)
assert.match(source, /createPortal\([\s\S]*document\.body\)/)
assert.match(source, /zh: \{[\s\S]*en: \{/)
assert.match(source, /error\.status === 409/)
assert.match(source, /event\.key\.toLowerCase\(\) === 's'/)
assert.match(source, /className: css\.lineNumbers/)
assert.match(source, /lineNumbers\.current\.scrollTop = event\.currentTarget\.scrollTop/)
assert.match(source, /wrap: 'off'/)
})
test('Settings Document Editor intercepts old and getter-backed open methods with their native result shapes', async () => {
const source = await readFile(new URL('lib/client.js', root), 'utf8')
const definition = source.slice(source.indexOf('function interceptDocumentOpen'), source.indexOf('\n\nexport function apply'))
const interceptDocumentOpen = new Function(`${definition}; return interceptDocumentOpen`)()
let opens = 0
const controller = { open: async () => { opens += 1 } }
for (const [method, result, getterBacked] of [
['openDocument', { result: { ok: true, value: { opened: true } } }, false],
['openSettingsDocument', { ok: true, value: { opened: true } }, true],
]) {
const original = async () => ({ original: true })
const target = getterBacked ? {} : { [method]: original }
if (getterBacked) Object.defineProperty(target, method, {
configurable: true,
enumerable: true,
get: () => original,
})
const restore = interceptDocumentOpen(target, method, controller, result)
assert.deepEqual(await target[method](), result)
restore()
assert.equal(target[method], original)
}
assert.equal(opens, 2)
})
test('Settings Document Editor follows DSH tokens and has a mobile layout', async () => {
const style = await readFile(new URL('lib/style.module.css', root), 'utf8')
assert.match(style, /--dsw-alias-label-primary/)
assert.match(style, /--dsw-alias-border-l2/)
assert.match(style, /@media \(max-width: 640px\)/)
assert.match(style, /height: 100dvh/)
assert.match(style, /\.editorFrame \{[\s\S]*grid-template-columns: auto minmax\(0, 1fr\)/)
assert.match(style, /\.lineNumbers \{[\s\S]*text-align: right/)
assert.match(style, /\.editorFrame:focus-within \{ border-color: var\(--dsw-alias-border-l2\); \}/)
assert.match(style, /\.lineNumbers \{[\s\S]*background: color-mix\(in srgb, var\(--dsw-alias-bg-base\) 72%, var\(--dsw-alias-bg-module-platform\)\)/)
assert.match(style, /\.overlay,[\s\S]*?\.overlay \*::after \{[^}]*corner-shape: round;/)
assert.doesNotMatch(style, /--dsw-alias-state-business-primary/)
assert.equal((style.match(/ui-monospace/g) ?? []).length, 2)
assert.doesNotMatch(style, /#[0-9a-f]{3,8}\b/i)
})
test('Settings Document Editor state discards stale loads and rejects stale saves', async () => {
const source = await readFile(new URL('lib/client.js', root), 'utf8')
const definition = source.slice(source.indexOf('class DocumentController'), source.indexOf('function Editor('))
const calls = []
const responses = [
{ content: 'language: zh\n', revision: 'a'.repeat(64), exists: true },
{ content: 'language: en\n', revision: 'b'.repeat(64), exists: true },
]
const DocumentController = new Function('request', `${definition}; return DocumentController`)(async (method, body) => {
calls.push([method, body])
return responses.shift()
})
const controller = new DocumentController()
await controller.open()
assert.equal(controller.state.content, 'language: zh\n')
controller.edit('language: en\n')
await controller.save()
assert.equal(controller.state.content, 'language: en\n')
assert.equal(controller.state.savedContent, 'language: en\n')
assert.deepEqual(calls.map(call => call[0]), ['GET', 'PUT'])
controller.close()
controller.state.content = 'stale'
const conflict = Object.assign(new Error('changed'), { status: 409 })
const FailingController = new Function('request', `${definition}; return DocumentController`)(async () => { throw conflict })
const failing = new FailingController()
failing.state.content = 'old content'
failing.state.savedContent = 'old content'
failing.state.revision = 'c'.repeat(64)
await failing.open()
assert.equal(failing.state.content, '')
assert.equal(failing.state.revision, null)
assert.equal(failing.state.error, 'changed')
let conflictCall = 0
const ConflictController = new Function('request', `${definition}; return DocumentController`)(async () => {
conflictCall += 1
if (conflictCall === 1) return { content: 'one: 1\n', revision: 'd'.repeat(64), exists: true }
throw conflict
})
const stale = new ConflictController()
await stale.open()
stale.edit('one: 2\n')
await stale.save()
assert.equal(stale.state.conflict, true)
assert.equal(stale.state.savedContent, 'one: 1\n')
assert.equal(stale.state.content, 'one: 2\n')
})
@@ -0,0 +1,117 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
import { buildSystemPluginClient } from '../tools/build-system-plugin-client.mjs'
const root = new URL('../../environment/resources/plugins/settings-navigation/package/', import.meta.url)
test('Settings Navigation is a browser-only optional System Plugin', async () => {
const metadata = JSON.parse(await readFile(new URL('package.json', root)))
const patch = JSON.parse(await readFile(new URL('cordis.patch.json', root)))
assert.equal(metadata.name, '@dsh-docker/settings-navigation')
assert.equal(metadata.dshDocker.description.zh, '优化 DSH 设置目录滚动和窄屏分级导航。')
assert.equal(metadata.dsh.client.platform, 'web')
assert.equal(metadata.dsh.client.inject.includes('@deepseek-ai/dsh-client-runtime'), false)
assert.equal(metadata.peerDependencies['@deepseek-ai/dsh-client-runtime'], undefined)
assert.equal(metadata.exports['./client'], './lib/client.bundle.js')
assert.equal(patch[0].insert[0].id, 'dsh-docker.settings-navigation.plugin')
assert.equal(patch[0].insert[0].name, metadata.name)
})
test('Settings Navigation checked-in bundle matches its source', async () => {
const bundle = await readFile(new URL('lib/client.bundle.js', root), 'utf8')
const style = await readFile(new URL('lib/style.module.css', root), 'utf8')
const rebuilt = await buildSystemPluginClient({
pluginId: '@dsh-docker/settings-navigation',
sourcePath: new URL('lib/client.js', root),
stylePath: new URL('lib/style.module.css', root),
})
assert.equal(bundle, rebuilt)
assert.doesNotThrow(() => new Function(bundle))
assert.match(bundle, /^window\.__ModuleLoader__\.load\(/)
assert.doesNotMatch(style, /corner-shape/)
assert.doesNotMatch(style, /\.header button:not\(\[aria-label\]\)/)
})
test('Settings Navigation recognizes the Settings shell without text or generated classes', async () => {
const source = await readFile(new URL('lib/client.js', root), 'utf8')
const matcher = source.slice(source.indexOf('function directChildren'), source.indexOf('\nfunction findSettingsDialog'))
const matchSettingsDialog = new Function(`${matcher}; return matchSettingsDialog`)()
class Element {
constructor(tagName, ownerDocument) {
this.tagName = tagName.toUpperCase()
this.ownerDocument = ownerDocument
this.children = []
this.attributes = new Map()
}
append(...children) { this.children.push(...children) }
contains(target) { return this === target || this.children.some(child => child.contains(target)) }
getAttribute(name) { return this.attributes.get(name) ?? null }
setAttribute(name, value) { this.attributes.set(name, value) }
querySelector(selector) {
return this.querySelectorAll(selector)[0] ?? null
}
querySelectorAll(selector) {
const result = []
for (const child of this.children) {
if (selector === 'button' && child.tagName === 'BUTTON') result.push(child)
result.push(...child.querySelectorAll(selector))
}
return result
}
}
const ids = new Map()
const document = { getElementById: id => ids.get(id) ?? null }
const dialog = new Element('div', document)
dialog.setAttribute('role', 'dialog')
dialog.setAttribute('aria-modal', 'true')
dialog.setAttribute('aria-labelledby', 'settings-title')
const nav = new Element('nav', document)
const title = new Element('div', document)
ids.set('settings-title', title)
const list = new Element('div', document)
const selected = new Element('button', document)
selected.setAttribute('aria-current', 'true')
list.append(selected)
nav.append(title, list)
const content = new Element('div', document)
const header = new Element('div', document)
header.append(new Element('button', document))
content.append(header, new Element('div', document))
dialog.append(nav, content)
assert.equal(matchSettingsDialog(dialog)?.current, selected)
dialog.append(new Element('aside', document))
assert.equal(matchSettingsDialog(dialog), null)
dialog.children.pop()
dialog.setAttribute('aria-labelledby', 'unknown')
assert.equal(matchSettingsDialog(dialog), null)
})
test('Settings Navigation owns compact navigation without moving native nodes', async () => {
const source = await readFile(new URL('lib/client.js', root), 'utf8')
const style = await readFile(new URL('lib/style.module.css', root), 'utf8')
assert.match(source, /const COMPACT_WIDTH = 640/)
assert.match(source, /shell\.overlay/)
assert.match(source, /IconChevronLeftOutline14/)
assert.match(source, /MutationObserverImpl/)
assert.match(source, /ResizeObserverImpl/)
assert.match(source, /attributeFilter: \['aria-current', 'aria-labelledby'\]/)
assert.match(source, /\['dialog', 'nav', 'navTitle', 'navList', 'content', 'header', 'options'\]/)
assert.match(source, /\.every\(key => next\[key\] === this\.match\[key\]\)/)
assert.match(source, /this\.view = match\.buttons\.indexOf\(match\.current\) > 0 \? 'detail' : 'directory'/)
assert.match(source, /this\.modeInitialized && compact && !this\.compact/)
assert.match(source, /this\.directoryScrollTop = this\.match\.navList\.scrollTop/)
assert.match(source, /current\?\.focus\(\{ preventScroll: true \}\)/)
assert.match(source, /this\.requestFrame\(\(\) => \{ navList\.scrollTop = scrollTop \}\)/)
assert.match(source, /delete this\.match\.dialog\.dataset\.dshSettingsNavigationMode/)
assert.match(source, /delete this\.match\.dialog\.dataset\.dshSettingsNavigationView/)
assert.match(source, /node\.classList\.remove\(className\)/)
assert.doesNotMatch(source, /textContent|innerHTML|appendChild\(match\.|replaceChild/)
assert.match(style, /scrollbar-gutter: stable/)
assert.match(style, /data-dsh-settings-navigation-view='directory'/)
assert.match(style, /data-dsh-settings-navigation-view='detail'/)
assert.match(style, /--dsw-alias-label-primary/)
assert.doesNotMatch(style, /#[0-9a-f]{3,8}\b/i)
})
@@ -0,0 +1,111 @@
import assert from 'node:assert/strict'
import { chmod, lstat, mkdir, mkdtemp, readFile, readlink, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { PersistentStateSnapshots } from '../../control-plane/modules/updater/lib/snapshots.mjs'
import { SnapshotClient } from '../../control-plane/modules/updater/lib/snapshot-client.mjs'
import { UserPluginSnapshots } from '../../control-plane/modules/plugin-manager/user-snapshots.mjs'
import { LocalApiClient } from '../../control-plane/modules/updater/lib/client.mjs'
import { createSnapshotServer, listenSnapshots } from '../stage0/lib/snapshot-server.mjs'
async function fixture(options = {}) {
const root = await mkdtemp(join(tmpdir(), 'dsh-snapshots-'))
const sourceRoot = join(root, 'home')
await mkdir(join(sourceRoot, 'nested'), { recursive: true })
return {
root,
sourceRoot,
snapshots: new PersistentStateSnapshots({ root: join(root, 'snapshots'), sourceRoot, ...options }),
}
}
const state = {
id: 'before-rc8',
runtimeId: '0.1.0-rc.7-1',
environmentVersion: '1.0.0',
dshVersion: '0.1.0-rc.7',
}
test('snapshots and restores complete DSH_HOME contents and permissions', async () => {
const { sourceRoot, snapshots } = await fixture({ now: () => new Date('2026-08-19T00:00:00.000Z') })
await writeFile(join(sourceRoot, '.config'), 'before')
await writeFile(join(sourceRoot, 'nested', 'database'), 'rows')
await chmod(join(sourceRoot, 'nested', 'database'), 0o640)
await symlink('nested/database', join(sourceRoot, 'database-link'))
const createProgress = []
const snapshot = await snapshots.create({ ...state, onProgress: value => { createProgress.push(value) } })
assert.equal(snapshot.createdAt, '2026-08-19T00:00:00.000Z')
assert.equal(createProgress.at(-1).processedItems, createProgress.at(-1).totalItems)
await writeFile(join(sourceRoot, '.config'), 'after')
await writeFile(join(sourceRoot, 'new-data'), 'remove me')
const restoreProgress = []
await snapshots.restore(state.id, { onProgress: value => { restoreProgress.push(value) } })
assert.equal(await readFile(join(sourceRoot, '.config'), 'utf8'), 'before')
assert.equal(await readFile(join(sourceRoot, 'nested', 'database'), 'utf8'), 'rows')
assert.equal((await lstat(join(sourceRoot, 'nested', 'database'))).mode & 0o777, 0o640)
assert.equal(await readlink(join(sourceRoot, 'database-link')), 'nested/database')
await assert.rejects(readFile(join(sourceRoot, 'new-data')), { code: 'ENOENT' })
assert.equal(restoreProgress.at(-1).processedItems, restoreProgress.at(-1).totalItems)
assert.equal((await snapshots.list())[0].id, state.id)
})
test('verifies a snapshot before clearing current DSH_HOME', async () => {
const { sourceRoot, snapshots } = await fixture()
await writeFile(join(sourceRoot, 'database'), 'before')
const snapshot = await snapshots.create(state)
await writeFile(join(snapshot.path, 'data.tar.gz'), 'corrupt')
await writeFile(join(sourceRoot, 'database'), 'current')
await assert.rejects(snapshots.restore(state.id), { code: 'TRUST_ARTIFACT_MISMATCH' })
assert.equal(await readFile(join(sourceRoot, 'database'), 'utf8'), 'current')
})
test('does not publish a partial snapshot when archive creation fails', async () => {
const { snapshots } = await fixture({ runImpl: async () => { throw new Error('no space left') } })
await assert.rejects(snapshots.create(state), /no space/)
assert.deepEqual(await snapshots.list(), [])
})
test('removing an absent snapshot is idempotent while corrupt snapshots remain errors', async () => {
const { snapshots } = await fixture()
assert.equal(await snapshots.remove('already-removed'), false)
const snapshot = await snapshots.create(state)
await writeFile(join(snapshot.path, 'data.tar.gz'), 'corrupt')
await assert.rejects(snapshots.remove(state.id), { code: 'TRUST_ARTIFACT_MISMATCH' })
})
test('Stage-0 serves only fixed DSH and Web Profile snapshot scopes', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-snapshot-server-'))
const dshHome = join(root, 'dsh')
const profileRoot = join(dshHome, 'profiles', 'web')
await mkdir(profileRoot, { recursive: true })
await writeFile(join(dshHome, 'settings.yaml'), 'before')
await writeFile(join(profileRoot, 'package.json'), '{"before":true}')
const server = createSnapshotServer({
dshSnapshots: new PersistentStateSnapshots({ root: join(root, 'snapshots'), sourceRoot: dshHome }),
userPluginSnapshots: new UserPluginSnapshots({ root: join(root, 'user-plugin-snapshots'), profileRoot }),
})
const socket = join(root, 'snapshot.sock')
await listenSnapshots(server, socket)
const api = new LocalApiClient(socket)
const dsh = new SnapshotClient(api, 'dsh')
const userPlugin = new SnapshotClient(api, 'user-plugin')
try {
const created = await dsh.create(state)
assert.equal(created.id, state.id)
assert.equal(created.path, undefined)
await writeFile(join(dshHome, 'settings.yaml'), 'after')
await dsh.restore(state.id)
assert.equal(await readFile(join(dshHome, 'settings.yaml'), 'utf8'), 'before')
const plugin = await userPlugin.create('profile-before-change')
assert.equal(plugin.id, 'profile-before-change')
assert.equal(plugin.path, undefined)
await writeFile(join(profileRoot, 'package.json'), '{"after":true}')
await userPlugin.restore('profile-before-change')
assert.equal(await readFile(join(profileRoot, 'package.json'), 'utf8'), '{"before":true}')
} finally {
await new Promise(resolve => server.close(resolve))
}
})
@@ -0,0 +1,811 @@
import assert from 'node:assert/strict'
import { cp, lstat, mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { request } from 'node:http'
import { spawn, spawnSync } from 'node:child_process'
import test from 'node:test'
import { BootstrapManager } from '../stage0/lib/slots.mjs'
import {
BootstrapSupervisor,
bootstrapLaunchCommand,
bootstrapLaunchEnvironment,
} from '../stage0/lib/supervisor.mjs'
import { createTrustServer, listenUnix } from '../stage0/lib/trust-server.mjs'
import { createRecoveryServer, listenRecovery } from '../stage0/lib/recovery-server.mjs'
import {
ProxyLaunchBroker,
createProxyLaunchServer,
listenProxyLaunch,
proxyLaunchCommand,
proxyLaunchEnvironment,
} from '../stage0/lib/proxy-launch-server.mjs'
import {
AccessLaunchBroker,
accessLaunchCommand,
accessLaunchEnvironment,
createAccessLaunchServer,
listenAccessLaunch,
} from '../stage0/lib/access-launch-server.mjs'
import { TrustLedger } from '../stage0/lib/ledger.mjs'
import { VerifiedObjectStore } from '../stage0/lib/artifacts.mjs'
import { LocalApiClient } from '../../control-plane/modules/updater/lib/client.mjs'
import { keyPair } from './helpers.mjs'
import {
deriveImageBuildId,
deriveRecordId,
parseImageInventory,
recordsFromImageInventory,
} from '../lib/deployment-contracts.mjs'
import { hashTree } from '../lib/tree-hash.mjs'
test('Stage-0 checks the Management status endpoint before managed file mutations', async () => {
const source = await readFile(new URL('../stage0/index.mjs', import.meta.url), 'utf8')
assert.match(source, /management\.request\('GET', '\/_dsh_platform\/api\/v1\/status'\)/)
assert.doesNotMatch(source, /management\.status\(\)/)
})
test('Bootstrap releases its parent IPC channel after shutdown', async () => {
const source = await readFile(new URL('../bootstrap/index.mjs', import.meta.url), 'utf8')
assert.match(source, /process\.off\('message', onRecoveryMessage\)/)
assert.match(source, /if \(process\.connected\) process\.disconnect\(\)/)
})
async function bootstrap(root, version, behavior) {
const directory = join(root, version)
await mkdir(directory, { recursive: true })
await writeFile(join(directory, 'index.mjs'), behavior)
return directory
}
async function imageBootstrap(root, version, sequence, behavior = 'seed', revision = `revision-${String(sequence)}`, authority = 'stable') {
const seedRoot = join(root, `seed-${revision}`)
const bootstrapRoot = await bootstrap(join(seedRoot, 'bootstrap'), version, behavior)
const bootstrapSha256 = await hashTree(bootstrapRoot)
const content = {
schema: 1,
authority,
platformRevision: revision,
targetSequence: sequence,
bootstrapApi: 1,
updateApi: 1,
bootstrap: { version, id: version, sha256: bootstrapSha256 },
deployment: {
id: `deployment-${String(sequence)}`,
dshVersion: `0.1.0-rc.${String(sequence)}`,
environmentVersion: '1.0.0',
environment: { id: 'environment', sha256: '1'.repeat(64) },
pristine: { id: 'pristine', sha256: '2'.repeat(64) },
runtime: { id: 'runtime', sha256: '3'.repeat(64) },
systemPlugins: { id: 'system-plugins', sha256: '4'.repeat(64) },
},
}
const inventory = parseImageInventory({ ...content, imageBuildId: deriveImageBuildId(content) })
return { seedRoot, inventory, record: recordsFromImageInventory(inventory).bootstrap }
}
function bootstrapManager(root, image) {
return new BootstrapManager({
stateRoot: join(root, 'state'),
storeRoot: join(root, 'store'),
seedRoot: image.seedRoot,
inventory: image.inventory,
})
}
async function storeBootstrap(manager, version, sequence, behavior) {
const id = `bootstrap-${version}`
const path = await bootstrap(manager.storeRoot, id, behavior)
const sha256 = await hashTree(path)
const content = {
schema: 1,
version,
bootstrapApi: 1,
targetSequence: sequence,
artifact: { storage: 'store', kind: 'bootstrap', id, sha256 },
}
return manager.writeRecord({ ...content, id: deriveRecordId('bootstrap-record', content) })
}
test('preserves container supplementary groups while lowering Bootstrap privileges', () => {
assert.deepEqual(bootstrapLaunchCommand({
node: '/usr/local/bin/node',
script: '/opt/bootstrap/index.mjs',
}), {
executable: '/usr/local/bin/node',
args: ['/opt/bootstrap/index.mjs'],
})
assert.deepEqual(bootstrapLaunchCommand({
node: '/usr/local/bin/node',
script: '/opt/bootstrap/index.mjs',
uid: 1000,
gid: 1000,
}), {
executable: '/usr/bin/setpriv',
args: [
'--reuid=1000',
'--regid=1000',
'--keep-groups',
'--',
'/usr/local/bin/node',
'/opt/bootstrap/index.mjs',
],
})
assert.throws(() => bootstrapLaunchCommand({
node: '/usr/local/bin/node',
script: '/opt/bootstrap/index.mjs',
uid: 1000,
}), /UID and GID/)
})
test('launches Proxy Manager with a dedicated identity and isolated environment', () => {
assert.deepEqual(proxyLaunchCommand({
node: '/usr/local/bin/node', script: '/opt/proxy/index.mjs', uid: 991, gid: 991, platformGid: 1000,
}), {
executable: '/usr/bin/setpriv',
args: [
'--reuid=991', '--regid=991', '--groups=1000', '--',
'/usr/local/bin/node', '/opt/proxy/index.mjs',
],
})
assert.throws(() => proxyLaunchCommand({
node: 'node', script: 'proxy.mjs', uid: 0, gid: 0, platformGid: 1000,
}), /positive/)
assert.deepEqual(proxyLaunchEnvironment({
environment: { PATH: '/usr/bin', DSH_PROXY_MASTER_KEY: 'secret', HOME: '/root', LEAK: 'value' },
dataRoot: '/data/platform', runRoot: '/run/dsh-platform',
}), {
HOME: '/nonexistent', USER: 'dsh-proxy', LOGNAME: 'dsh-proxy', PATH: '/usr/bin',
DSH_PLATFORM_DATA: '/data/platform', DSH_PLATFORM_RUN: '/run/dsh-platform',
DSH_PROXY_MASTER_KEY: 'secret',
})
})
test('launches Access Manager without platform supplementary groups or inherited secrets', () => {
assert.deepEqual(accessLaunchCommand({
node: '/usr/local/bin/node', script: '/opt/access/index.mjs', uid: 992, gid: 992,
}), {
executable: '/usr/bin/setpriv',
args: [
'--reuid=992', '--regid=992', '--clear-groups', '--',
'/usr/local/bin/node', '/opt/access/index.mjs',
],
})
assert.throws(() => accessLaunchCommand({ node: 'node', script: 'access.mjs', uid: 0, gid: 0 }), /positive/)
assert.deepEqual(accessLaunchEnvironment({
environment: { PATH: '/usr/bin', HOME: '/root', DSH_PROXY_PASSWORD: 'secret', LEAK: 'value' },
dataRoot: '/data/platform', runRoot: '/run/dsh-platform', classificationToken: 'classification-token',
}), {
HOME: '/nonexistent', USER: 'dsh-access', LOGNAME: 'dsh-access', PATH: '/usr/bin',
DSH_PLATFORM_DATA: '/data/platform', DSH_PLATFORM_RUN: '/run/dsh-platform',
DSH_ACCESS_CLASSIFICATION_TOKEN: 'classification-token',
})
})
test('Access Manager launch broker exposes only fixed lifecycle operations', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-access-launch-'))
const worker = join(root, 'worker.mjs')
const socket = join(root, 'launch.sock')
const accessSocket = join(root, 'access.sock')
const recoverySocket = join(root, 'recovery.sock')
await writeFile(worker, `
import { writeFileSync } from 'node:fs'
writeFileSync(${JSON.stringify(accessSocket)}, '')
writeFileSync(${JSON.stringify(recoverySocket)}, '')
process.send({ type: 'ready', componentReady: true })
process.once('SIGTERM', () => process.exit(0))
setInterval(() => {}, 1000)
`)
const broker = new AccessLaunchBroker({
token: 'valid-token', dataRoot: root, runRoot: root, script: worker,
accessSocket, recoverySocket, uid: 992, gid: 992,
platformGid: process.getgid?.() ?? 1000,
spawnImpl: (_executable, _args, options) => spawn(process.execPath, [worker], {
...options, env: process.env,
}),
})
const server = createAccessLaunchServer({ broker, token: 'valid-token' })
await listenAccessLaunch(server, socket)
const client = new LocalApiClient(socket)
try {
assert.deepEqual(await client.request('GET', '/v1/status'), {
running: false, componentReady: false, pid: null,
})
await assert.rejects(client.request('POST', '/v1/start', { token: 'invalid' }), error => error.statusCode === 403)
const started = await client.request('POST', '/v1/start', { token: 'valid-token' })
assert.equal(started.running, true)
assert.equal(started.componentReady, true)
await assert.rejects(client.request('POST', '/v1/arbitrary', { token: 'valid-token' }), error => error.statusCode === 404)
assert.equal((await client.request('POST', '/v1/stop', { token: 'valid-token' })).running, false)
} finally {
await broker.stop()
await new Promise(resolve => server.close(resolve))
}
})
test('Proxy Manager launch broker requires its token and exposes only fixed operations', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-launch-'))
const worker = join(root, 'worker.mjs')
const socket = join(root, 'launch.sock')
const controlSocket = join(root, 'control.sock')
await writeFile(worker, `
import { writeFileSync } from 'node:fs'
writeFileSync(${JSON.stringify(controlSocket)}, '')
process.send({ type: 'ready', componentReady: true, revision: 'revision', ports: [17891] })
process.once('SIGTERM', () => process.exit(0))
setInterval(() => {}, 1000)
`)
const broker = new ProxyLaunchBroker({
token: 'valid-token', dataRoot: root, runRoot: root, script: worker,
controlSocket, uid: 991, gid: 991,
platformGid: process.getgid?.() ?? 1000,
spawnImpl: (_executable, _args, options) => {
const child = spawn(process.execPath, [worker], {
...options, env: process.env,
})
return child
},
})
const server = createProxyLaunchServer({ broker, token: 'valid-token' })
await listenProxyLaunch(server, socket)
const client = new LocalApiClient(socket)
try {
assert.deepEqual(await client.request('GET', '/v1/status'), {
running: false, componentReady: false, pid: null, revision: null, ports: [],
})
await assert.rejects(client.request('POST', '/v1/start', { token: 'invalid' }), error => error.statusCode === 403)
const started = await client.request('POST', '/v1/start', { token: 'valid-token' })
assert.equal(started.running, true)
assert.equal(started.componentReady, true)
assert.equal((await client.request('GET', '/v1/status')).revision, 'revision')
await assert.rejects(client.request('POST', '/v1/arbitrary', { token: 'valid-token' }), error => error.statusCode === 404)
assert.equal((await client.request('POST', '/v1/stop', { token: 'valid-token' })).running, false)
} finally {
await broker.stop()
await new Promise(resolve => server.close(resolve))
}
})
test('Proxy Manager launch failure returns after an already-exited child without waiting for another exit', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-proxy-launch-failure-'))
const worker = join(root, 'worker.mjs')
await writeFile(worker, 'process.exit(9)')
const broker = new ProxyLaunchBroker({
token: 'valid-token', dataRoot: root, runRoot: root, script: worker,
controlSocket: join(root, 'control.sock'), uid: 991, gid: 991,
platformGid: process.getgid?.() ?? 1000,
spawnImpl: (_executable, _args, options) => spawn(process.execPath, [worker], {
...options, env: process.env,
}),
})
await assert.rejects(Promise.race([
broker.start(),
new Promise((_, reject) => setTimeout(() => reject(new Error('launch failure timed out')), 1_000)),
]), /exited before readiness.*code=9/)
assert.equal(broker.status().running, false)
})
test('replaces the root login environment when lowering Bootstrap privileges', () => {
const accessEvidence = {
dshSettings: false,
webProfile: true,
dshSessions: false,
userSkills: false,
deploymentState: true,
managementState: false,
updaterState: false,
legacyAuthenticationConfigured: true,
}
assert.deepEqual(bootstrapLaunchEnvironment({
environment: {
HOME: '/root', USER: 'root', LOGNAME: 'root', PATH: '/usr/local/bin:/usr/bin',
DSH_PROXY_MASTER_KEY: 'must-not-leak', DSH_PROXY_LAUNCH_TOKEN: 'old-token',
DSH_PROXY_USERNAME: 'legacy-user', DSH_PROXY_PASSWORD: 'legacy-password',
DSH_PLATFORM_PASSWORD: 'legacy-platform-password',
},
dataRoot: '/data/platform',
runRoot: '/run/dsh-platform',
seedRoot: '/opt/dsh-platform/seed',
bootstrapVersion: '1.0.0',
user: 'node',
home: '/home/node',
proxyLaunchToken: 'new-token',
accessEvidence,
}), {
HOME: '/home/node',
USER: 'node',
LOGNAME: 'node',
PATH: '/usr/local/bin:/usr/bin',
XDG_CACHE_HOME: '/home/node/.cache',
XDG_CONFIG_HOME: '/home/node/.config',
XDG_DATA_HOME: '/home/node/.local/share',
DSH_PLATFORM_DATA: '/data/platform',
DSH_PLATFORM_RUN: '/run/dsh-platform',
DSH_PLATFORM_SEED: '/opt/dsh-platform/seed',
DSH_BOOTSTRAP_VERSION: '1.0.0',
DSH_PROXY_LAUNCH_TOKEN: 'new-token',
DSH_LEGACY_INSTALLATION_EVIDENCE: JSON.stringify(accessEvidence),
})
})
test('tracks immutable Bootstrap Records in one generation-based slots file', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-records-'))
const image = await imageBootstrap(root, '1.0.0', 1)
const manager = bootstrapManager(root, image)
await manager.reconcileImage(image.record)
const managed = await storeBootstrap(manager, '2.0.0', 2, 'next')
await manager.promote(managed.id)
let state = await manager.state()
assert.equal(state.current, managed.id)
assert.equal(state.previous, image.record.id)
assert.equal(state.generation, 2)
await manager.rollback()
state = await manager.state()
assert.equal(state.current, image.record.id)
assert.equal(state.previous, managed.id)
assert.equal(state.generation, 3)
})
test('Stage-0 collects only Bootstrap assets outside current and previous', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-gc-'))
const image = await imageBootstrap(root, '1.0.0', 1)
const manager = bootstrapManager(root, image)
await manager.reconcileImage(image.record)
const retained = await storeBootstrap(manager, '2.0.0', 2, 'retained')
await manager.promote(retained.id)
const orphan = await storeBootstrap(manager, '3.0.0', 3, 'orphan')
const removed = await manager.collectGarbage()
assert.deepEqual(removed.records, [orphan.id])
await assert.rejects(lstat(manager.recordPath(orphan.id)), { code: 'ENOENT' })
await assert.rejects(lstat(join(manager.storeRoot, orphan.artifact.id)), { code: 'ENOENT' })
assert.equal((await lstat(join(manager.storeRoot, retained.artifact.id))).isDirectory(), true)
})
test('advances to a newer image without reinterpreting an old Image Reference', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-image-forward-'))
const first = await imageBootstrap(root, '1.0.0', 1)
const initial = bootstrapManager(root, first)
await initial.reconcileImage(first.record)
const second = await imageBootstrap(root, '1.0.0', 2, 'new-seed')
const upgraded = bootstrapManager(root, second)
await upgraded.reconcileImage(second.record)
const state = await upgraded.state()
assert.equal(state.current, second.record.id)
assert.equal(state.previous, first.record.id)
await assert.rejects(upgraded.resolveRecord(first.record.id), /different image/)
})
test('uses an older image Bootstrap after an explicit Docker image rollback', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-image-rollback-'))
const first = await imageBootstrap(root, '1.0.0', 1)
await bootstrapManager(root, first).reconcileImage(first.record)
const second = await imageBootstrap(root, '1.0.0', 2, 'new-seed')
await bootstrapManager(root, second).reconcileImage(second.record)
const rolledBack = bootstrapManager(root, first)
const state = await rolledBack.reconcileImage(first.record)
assert.equal(state.current, first.record.id)
assert.equal(state.previous, second.record.id)
assert.equal((await rolledBack.current()).record.id, first.record.id)
})
test('rejects same-sequence Bootstrap content conflicts', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-image-conflict-'))
const first = await imageBootstrap(root, '1.0.0', 1, 'one', 'revision-one')
await bootstrapManager(root, first).reconcileImage(first.record)
const conflicting = await imageBootstrap(root, '1.0.0', 1, 'two', 'revision-two')
await assert.rejects(bootstrapManager(root, conflicting).reconcileImage(conflicting.record), /conflicts/)
})
test('replaces a rebuilt development Bootstrap without retaining a stale Image Reference', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-development-refresh-'))
const first = await imageBootstrap(root, '1.0.0', 0, 'one', 'development-one', 'development')
await bootstrapManager(root, first).reconcileImage(first.record)
const rebuilt = await imageBootstrap(root, '1.0.0', 0, 'two', 'development-two', 'development')
const manager = bootstrapManager(root, rebuilt)
const state = await manager.reconcileImage(rebuilt.record)
assert.equal(state.current, rebuilt.record.id)
assert.equal(state.previous, null)
assert.equal((await manager.current()).path, join(rebuilt.seedRoot, 'bootstrap', '1.0.0'))
})
test('replaces a stale formal Image Bootstrap when starting a development image', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-development-after-formal-'))
const formal = await imageBootstrap(root, '1.0.0', 11, 'formal', 'formal-eleven', 'stable')
await bootstrapManager(root, formal).reconcileImage(formal.record)
const development = await imageBootstrap(root, '1.0.0', 0, 'development', 'local-rebuild', 'development')
const manager = bootstrapManager(root, development)
const state = await manager.reconcileImage(development.record)
assert.equal(state.current, development.record.id)
assert.equal(state.previous, null)
assert.equal((await manager.current()).path, join(development.seedRoot, 'bootstrap', '1.0.0'))
})
test('replaces a stale Managed Bootstrap when starting a development image', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-development-after-managed-'))
const formal = await imageBootstrap(root, '1.0.0', 11, 'formal', 'formal-eleven', 'stable')
const initial = bootstrapManager(root, formal)
await initial.reconcileImage(formal.record)
const managed = await storeBootstrap(initial, '2.0.0', 12, 'managed')
await initial.promote(managed.id)
const development = await imageBootstrap(root, '1.0.0', 0, 'development', 'local-rebuild', 'development')
const manager = bootstrapManager(root, development)
const state = await manager.reconcileImage(development.record)
assert.equal(state.current, development.record.id)
assert.equal(state.previous, null)
assert.equal((await manager.current()).path, join(development.seedRoot, 'bootstrap', '1.0.0'))
})
test('preserves a higher Managed Bootstrap when the image is behind', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-image-behind-'))
const first = await imageBootstrap(root, '1.0.0', 1)
const initial = bootstrapManager(root, first)
await initial.reconcileImage(first.record)
const managed = await storeBootstrap(initial, '3.0.0', 3, 'managed')
await initial.promote(managed.id)
const second = await imageBootstrap(root, '2.0.0', 2)
const restarted = bootstrapManager(root, second)
const state = await restarted.reconcileImage(second.record)
assert.equal(state.current, managed.id)
assert.equal((await restarted.current()).record.version, '3.0.0')
})
test('prefers the current image when Store and Image content match at one sequence', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-image-preferred-'))
const image = await imageBootstrap(root, '1.0.0', 1)
const manager = bootstrapManager(root, image)
await manager.reconcileImage(image.record)
const storeId = 'bootstrap-identical'
await cp(
join(image.seedRoot, 'bootstrap', '1.0.0'),
join(manager.storeRoot, storeId),
{ recursive: true },
)
const content = {
schema: 1,
version: '1.0.0',
bootstrapApi: 1,
targetSequence: 1,
artifact: { storage: 'store', kind: 'bootstrap', id: storeId, sha256: image.inventory.bootstrap.sha256 },
}
const managed = await manager.writeRecord({ ...content, id: deriveRecordId('bootstrap-record', content) })
await manager.promote(managed.id)
const state = await manager.reconcileImage(image.record)
assert.equal(state.current, image.record.id)
assert.equal(state.previous, managed.id)
})
test('rolls back when the current Bootstrap exits before readiness', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-supervisor-'))
const image = await imageBootstrap(root, '1.0.0', 1, 'process.send({ type: "ready", bootstrapApi: 1 }); setInterval(() => {}, 1000)')
const slots = bootstrapManager(root, image)
await slots.reconcileImage(image.record)
const candidate = await storeBootstrap(slots, '2.0.0', 2, 'process.exit(2)')
await slots.promote(candidate.id)
const reports = []
const supervisor = new BootstrapSupervisor({
slots,
dataRoot: root,
readyTimeoutMs: 1_000,
report: (message, fields) => { reports.push({ message, fields }) },
})
const child = await supervisor.startWithRollback()
assert.equal(child.exitCode, null)
const state = await slots.state()
assert.equal(state.current, image.record.id)
assert.equal(state.previous, candidate.id)
assert.equal(reports.some(entry => entry.message === 'bootstrap.launch.failed' && entry.fields.error instanceof Error), true)
assert.equal(reports.some(entry => entry.message === 'bootstrap.rollback.started'), true)
assert.equal(reports.some(entry => entry.message === 'bootstrap.rollback.completed'), true)
assert.equal(reports.some(entry => entry.message === 'bootstrap.ready' && entry.fields.pid === child.pid), true)
await supervisor.stop()
assert.equal(reports.some(entry => entry.message === 'bootstrap.stop.completed'), true)
})
test('serializes a staged Bootstrap restart behind initial readiness', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-supervisor-transition-'))
const image = await imageBootstrap(root, '1.0.0', 1, `
setTimeout(() => process.send({ type: 'ready', bootstrapApi: 1 }), 100)
setInterval(() => {}, 1000)
`)
const slots = bootstrapManager(root, image)
await slots.reconcileImage(image.record)
const candidate = await storeBootstrap(
slots,
'2.0.0',
2,
'process.send({ type: "ready", bootstrapApi: 1 }); setInterval(() => {}, 1000)',
)
const reports = []
let resolveLaunch
const launchStarted = new Promise(resolve => { resolveLaunch = resolve })
const supervisor = new BootstrapSupervisor({
slots,
dataRoot: root,
readyTimeoutMs: 1_000,
report: (message, fields) => {
reports.push({ message, fields })
if (message === 'bootstrap.launch.started' && fields.bootstrapVersion === '1.0.0') resolveLaunch()
},
})
const initial = supervisor.startWithRollback()
await launchStarted
await slots.promote(candidate.id)
const restart = supervisor.restart()
const initialChild = await initial
const restartedChild = await restart
assert.notEqual(initialChild.pid, restartedChild.pid)
assert.equal((await slots.state()).current, candidate.id)
assert.equal(reports.some(entry => entry.message === 'bootstrap.launch.failed'), false)
const initialReady = reports.findIndex(entry => (
entry.message === 'bootstrap.ready' && entry.fields.bootstrapVersion === '1.0.0'
))
const restartStarted = reports.findIndex(entry => entry.message === 'bootstrap.restart.started')
assert.notEqual(initialReady, -1)
assert.equal(restartStarted > initialReady, true)
assert.equal(reports.some(entry => (
entry.message === 'bootstrap.ready' && entry.fields.bootstrapVersion === '2.0.0'
)), true)
await supervisor.stop()
})
test('rejects an in-flight recovery request when Bootstrap exits', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-recovery-exit-'))
const behavior = `
process.send({ type: 'ready', bootstrapApi: 1 })
process.on('message', () => process.exit(7))
setInterval(() => {}, 1000)
`
const image = await imageBootstrap(root, '1.0.0', 1, behavior)
const slots = bootstrapManager(root, image)
await slots.reconcileImage(image.record)
const reports = []
const supervisor = new BootstrapSupervisor({
slots,
dataRoot: root,
readyTimeoutMs: 1_000,
report: (message, fields) => { reports.push({ message, fields }) },
})
await supervisor.startWithRollback()
await assert.rejects(supervisor.recoverImageBaseline(), /Bootstrap exited unexpectedly/)
assert.equal(supervisor.requests.size, 0)
assert.equal(reports.some(entry => entry.message === 'bootstrap.recovery.started'), true)
assert.equal(reports.some(entry => entry.message === 'bootstrap.recovery.failed' && entry.fields.error instanceof Error), true)
assert.equal(reports.some(entry => entry.message === 'bootstrap.exited' && entry.fields.code === 7), true)
})
function unixRequest(socketPath, method, path, body) {
return new Promise((resolve, reject) => {
const requestBody = body === undefined ? undefined : Buffer.from(JSON.stringify(body))
const req = request({ socketPath, method, path, headers: requestBody === undefined ? {} : { 'content-length': requestBody.length } }, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.on('end', () => resolve({ status: response.statusCode, body: JSON.parse(Buffer.concat(chunks)) }))
})
req.once('error', reject)
req.end(requestBody)
})
}
test('root-only recovery server requires the exact current imageBuildId', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-recovery-server-'))
const image = await imageBootstrap(root, '1.0.0', 2)
let recoveries = 0
const reports = []
const server = createRecoveryServer({
inventory: image.inventory,
deployments: async () => ({ current: { recordId: 'broken' } }),
supervisor: { recoverImageBaseline: async () => { recoveries += 1; return { current: image.record.id } } },
report: (message, fields) => { reports.push({ message, fields }) },
})
const socketPath = join(root, 'run', 'recovery.sock')
await listenRecovery(server, socketPath)
try {
const status = await unixRequest(socketPath, 'GET', '/v1/status')
assert.equal(status.status, 200)
assert.equal(status.body.imageBaseline.imageBuildId, image.inventory.imageBuildId)
assert.equal((await unixRequest(socketPath, 'POST', '/v1/recover-image-baseline', { confirm: 'wrong' })).status, 400)
assert.equal((await unixRequest(socketPath, 'POST', '/v1/recover-image-baseline', {
confirm: image.inventory.imageBuildId,
})).status, 200)
assert.equal((await unixRequest(socketPath, 'POST', '/v1/recover-image-baseline', {
confirm: 'x'.repeat(17 * 1024),
})).status, 400)
assert.equal(recoveries, 1)
assert.equal(reports.some(entry => entry.message === 'recovery.request.failed' && entry.fields.error instanceof Error), true)
assert.equal(reports.some(entry => entry.message === 'image-baseline.requested'), true)
assert.equal(reports.some(entry => entry.message === 'image-baseline.recovered'), true)
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('exposes a bounded local Trust API without trust-root mutation routes', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-trust-server-'))
const recovery = keyPair()
const ledger = new TrustLedger(join(root, 'trust'), recovery.publicKey)
const objects = new VerifiedObjectStore({ root: join(root, 'trust'), untrustedRoot: join(root, 'downloads'), ledger })
const reports = []
const server = createTrustServer({
ledger,
objects,
report: (message, fields) => { reports.push({ message, fields }) },
})
const socketPath = join(root, 'run', 'trust.sock')
await listenUnix(server, socketPath)
try {
assert.deepEqual(await unixRequest(socketPath, 'GET', '/v1/status'), {
status: 200,
body: { keyringGeneration: null, targetSequence: null, officialDshVersion: null },
})
assert.equal((await unixRequest(socketPath, 'POST', '/v1/trust/reset', {})).status, 404)
assert.equal((await unixRequest(socketPath, 'POST', '/v1/dsh/ensure', { version: 'bad', sourcePath: '/tmp/x' })).status, 400)
assert.equal(reports.some(entry => entry.message === 'trust.request.failed'
&& entry.fields.pathname === '/v1/dsh/ensure'
&& entry.fields.error instanceof Error), true)
assert.equal((await readFile(socketPath).catch(error => error.code)), 'ENXIO')
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('returns structured Trust errors to local clients', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-trust-error-server-'))
const error = Object.assign(new Error('keyring signature key is not trusted'), { code: 'TRUST_UNKNOWN_KEY' })
const server = createTrustServer({
ledger: { acceptKeyring: async () => { throw error } },
objects: {},
})
const socketPath = join(root, 'run', 'trust.sock')
await listenUnix(server, socketPath)
try {
assert.deepEqual(await unixRequest(socketPath, 'POST', '/v1/keyring', { document: '', signature: {} }), {
status: 400,
body: { error: error.message, code: error.code },
})
await assert.rejects(new LocalApiClient(socketPath).acceptKeyring(Buffer.alloc(0), {}), failure => {
assert.equal(failure.code, error.code)
assert.equal(failure.localApiPath, '/v1/keyring')
return true
})
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('exposes only an injected Stage-0 Bootstrap staging operation', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-stage-bootstrap-api-'))
const recovery = keyPair()
const ledger = new TrustLedger(join(root, 'trust'), recovery.publicKey)
const objects = new VerifiedObjectStore({ root: join(root, 'trust'), untrustedRoot: join(root, 'downloads'), ledger })
let staged
const server = createTrustServer({
ledger,
objects,
stageBootstrap: async (receipt, version) => {
staged = { receipt, version }
return { recordId: 'bootstrap-record-one', targetSequence: 2, recordChanged: false, restartRequired: false }
},
})
const socketPath = join(root, 'run', 'trust.sock')
await listenUnix(server, socketPath)
try {
assert.deepEqual(await unixRequest(socketPath, 'POST', '/v1/bootstrap/stage', {
receipt: 'receipt-token', version: '2.0.0',
}), {
status: 202,
body: {
status: 'staged',
version: '2.0.0',
recordId: 'bootstrap-record-one',
targetSequence: 2,
recordChanged: false,
restartRequired: false,
},
})
assert.deepEqual(staged, { receipt: 'receipt-token', version: '2.0.0' })
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('official DSH Trust API accepts only a version and two untrusted source paths', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-official-api-'))
const recovery = keyPair()
const ledger = new TrustLedger(join(root, 'trust'), recovery.publicKey)
const calls = []
const objects = {
ensureOfficialDsh: async (version, metadataPath, tarballPath) => {
calls.push({ version, metadataPath, tarballPath })
return { authorityType: 'official-dsh', authorityVersion: version }
},
reconcileRevocations: async () => [],
activeReceipts: async () => [],
}
const server = createTrustServer({ ledger, objects })
const socketPath = join(root, 'run', 'trust.sock')
await listenUnix(server, socketPath)
try {
const request = {
version: '0.1.0-rc.8',
metadataPath: '/data/platform/cache/downloads/official.json',
tarballPath: '/data/platform/cache/downloads/official.tgz',
}
const accepted = await unixRequest(socketPath, 'POST', '/v1/dsh/ensure', request)
assert.equal(accepted.status, 200)
assert.deepEqual(calls, [request])
for (const extra of [
{ ...request, url: 'https://mirror.example/dsh.tgz' },
{ ...request, expectedHash: '0'.repeat(64) },
{ ...request, candidate: {} },
{ version: request.version, metadataPath: request.metadataPath },
]) {
assert.equal((await unixRequest(socketPath, 'POST', '/v1/dsh/ensure', extra)).status, 400)
}
assert.equal((await unixRequest(socketPath, 'POST', '/v1/artifacts/import-experimental', {
candidate: {}, sourcePath: '/data/platform/downloads/untrusted/dsh.tgz',
})).status, 404)
assert.deepEqual(calls, [request])
} finally {
await new Promise(resolve => server.close(resolve))
}
})
test('Bootstrap archive installation rejects traversal before extraction', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-archive-'))
const image = await imageBootstrap(root, '1.0.0', 1)
const slots = bootstrapManager(root, image)
await slots.reconcileImage(image.record)
const source = join(root, 'source')
await mkdir(join(source, 'platform', 'bootstrap'), { recursive: true })
await writeFile(join(source, 'platform', 'bootstrap', 'index.mjs'), 'process.exit(0)')
const valid = join(root, 'valid.tgz')
assert.equal(spawnSync('tar', ['-czf', valid, '-C', source, 'platform']).status, 0)
const installed = await slots.installArchive(valid, { version: '2.0.0', targetSequence: 2 })
const resolved = await slots.resolveRecord(installed.id)
assert.match(await readFile(join(resolved.path, 'platform', 'bootstrap', 'index.mjs'), 'utf8'), /exit/)
const unsafe = join(root, 'unsafe.tgz')
assert.equal(spawnSync('tar', ['-czf', unsafe, '--transform=s,^,../,', '-C', source, 'platform']).status, 0)
await assert.rejects(slots.installArchive(unsafe, { version: '3.0.0', targetSequence: 3 }), /unsafe path/)
})
test('stages Bootstrap by content identity even when its version does not change', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-bootstrap-content-stage-'))
const image = await imageBootstrap(root, '1.0.0', 1)
const slots = bootstrapManager(root, image)
await slots.reconcileImage(image.record)
const archive = async (name, behavior) => {
const source = join(root, `source-${name}`)
await mkdir(join(source, 'platform', 'bootstrap'), { recursive: true })
await writeFile(join(source, 'platform', 'bootstrap', 'index.mjs'), behavior)
const destination = join(root, `${name}.tgz`)
assert.equal(spawnSync('tar', ['-czf', destination, '-C', source, 'platform']).status, 0)
return destination
}
const first = await slots.stageArchive(await archive('first', 'console.log("first")'), {
version: '1.0.0', targetSequence: 2,
})
assert.equal(first.recordChanged, true)
assert.equal(first.restartRequired, true)
const identical = await slots.stageArchive(join(root, 'first.tgz'), {
version: '1.0.0', targetSequence: 3,
})
assert.equal(identical.recordChanged, true)
assert.equal(identical.restartRequired, false)
assert.equal((await slots.state()).current, identical.record.id)
const changed = await slots.stageArchive(await archive('changed', 'console.log("changed")'), {
version: '1.0.0', targetSequence: 4,
})
assert.equal(changed.recordChanged, true)
assert.equal(changed.restartRequired, true)
assert.equal((await slots.state()).previous, identical.record.id)
})
@@ -0,0 +1,64 @@
import assert from 'node:assert/strict'
import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import {
advanceSupportedDsh,
compareDshVersions,
parseSupportedTarget,
validateSupportedTarget,
} from '../lib/supported-target.mjs'
const target = {
schema: 1,
latestSupportedDsh: '0.1.0-rc.7',
environment: '1.0.0-dev',
}
const bytes = value => Buffer.from(`${JSON.stringify(value)}\n`)
test('parses the exact Supported Target contract and matching Environment', () => {
assert.deepEqual(parseSupportedTarget(bytes(target)), target)
assert.equal(validateSupportedTarget(bytes(target), bytes({ version: target.environment })).environment, target.environment)
assert.throws(() => parseSupportedTarget(bytes({ ...target, extra: true })), /exactly/)
assert.throws(() => validateSupportedTarget(bytes(target), bytes({ version: 'different' })), /does not match/)
})
test('compares release and prerelease DSH semantic versions without downgrade ambiguity', () => {
assert.equal(compareDshVersions('0.1.0-rc.21', '0.1.0-rc.7'), 1)
assert.equal(compareDshVersions('0.1.0', '0.1.0-rc.21'), 1)
assert.equal(compareDshVersions('0.1.0-rc.7', '0.1.0-rc.7+rebuilt'), 0)
assert.equal(compareDshVersions('0.1.0-2', '0.1.0-beta'), -1)
assert.equal(compareDshVersions('999999999999999999999.0.0', '999999999999999999998.0.0'), 1)
assert.throws(() => compareDshVersions('0.1.0-rc.07', '0.1.0-rc.7'), /numeric prerelease/)
})
test('advances only DSH and rejects an upstream rollback', () => {
const advanced = advanceSupportedDsh(target, '0.1.0-rc.8')
assert.equal(advanced.changed, true)
assert.deepEqual(advanced.target, { ...target, latestSupportedDsh: '0.1.0-rc.8' })
assert.equal(advanceSupportedDsh(target, target.latestSupportedDsh).changed, false)
assert.throws(() => advanceSupportedDsh(target, '0.1.0-rc.6'), /roll back/)
})
test('CLI validates and atomically updates the candidate target', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-supported-target-'))
const targetPath = join(root, 'supported-target.json')
const definitionPath = join(root, 'definition.json')
await writeFile(targetPath, bytes(target))
await writeFile(definitionPath, bytes({ version: target.environment }))
const tool = new URL('../tools/supported-target.mjs', import.meta.url).pathname
const result = spawnSync(process.execPath, [tool, 'advance', targetPath, definitionPath, '0.1.0-rc.8'], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
assert.equal(JSON.parse(result.stdout).changed, true)
assert.equal(JSON.parse(await readFile(targetPath, 'utf8')).latestSupportedDsh, '0.1.0-rc.8')
const rollback = spawnSync(process.execPath, [tool, 'advance', targetPath, definitionPath, '0.1.0-rc.7'], { encoding: 'utf8' })
assert.notEqual(rollback.status, 0)
assert.equal(JSON.parse(await readFile(targetPath, 'utf8')).latestSupportedDsh, '0.1.0-rc.8')
const extraArgument = spawnSync(process.execPath, [tool, 'validate', targetPath, definitionPath, 'ignored'], { encoding: 'utf8' })
assert.equal(extraArgument.status, 64)
})
@@ -0,0 +1,329 @@
import assert from 'node:assert/strict'
import { cp, lstat, mkdtemp, mkdir, readFile, readlink, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import test from 'node:test'
import {
discardSystemPluginSelection,
linkSystemPluginScope,
listBundledSystemPlugins,
listManagedSystemPlugins,
materializeSystemPluginSelection,
rebuildBundledSystemPluginView,
reconcileSystemPlugins,
SystemPluginSelectionStore,
} from '../../control-plane/modules/plugin-manager/system.mjs'
import { createHash } from 'node:crypto'
import { hashTree } from '../lib/tree-hash.mjs'
test('Bootstrap lists System Plugins from the selected runtime view without rehashing the Deployment', async () => {
const source = await readFile(new URL('../bootstrap/index.mjs', import.meta.url), 'utf8')
const list = source.slice(source.indexOf('const systemPlugins = {'), source.indexOf(' mutate:', source.indexOf('const systemPlugins = {')))
assert.match(list, /realpath\(paths\.deploymentView\)/)
assert.match(list, /environmentRoot: join\(deploymentRoot, 'environment'\)/)
assert.match(list, /sourceRoot: join\(deploymentRoot, 'system-plugins'\)/)
assert.doesNotMatch(list, /deployments\.selected\(\)/)
})
async function archive(root, id, patch) {
const source = join(root, `source-${id}`, 'package')
await mkdir(source, { recursive: true })
await writeFile(join(source, 'package.json'), JSON.stringify({
name: `@dsh-docker/${id}`,
type: 'module',
main: 'plugin.mjs',
dshDocker: { description: { zh: `${id} 功能`, en: `${id} feature` } },
}))
await writeFile(join(source, 'cordis.patch.json'), JSON.stringify(patch))
await writeFile(join(source, 'plugin.mjs'), `export const id = ${JSON.stringify(id)}\n`)
const path = join(root, `${id}.tgz`)
const result = spawnSync('tar', ['-czf', path, '-C', dirname(source), 'package'], { encoding: 'utf8' })
assert.equal(result.status, 0, result.stderr)
return path
}
function dirname(path) {
return path.slice(0, path.lastIndexOf('/'))
}
test('reconciles only declared System Plugins into a separate immutable overlay', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugins-'))
const userHome = join(root, 'user-home')
await mkdir(join(userHome, 'profiles/web'), { recursive: true })
await writeFile(join(userHome, 'cordis.patch.yml'), '[{"id":"user-owned"}]\n')
await writeFile(join(userHome, 'profiles/web/package.json'), '{"dependencies":{"third-party":"1.0.0"}}\n')
const first = await archive(root, 'update-ui', [{ insert: [{ id: 'dsh-docker.update-ui.host', name: '@dsh-docker/update-ui' }] }])
const second = await archive(root, 'diagnostics', [{ insert: [{ id: 'dsh-docker.diagnostics.host', name: '@dsh-docker/diagnostics' }] }])
const artifacts = new Map([['update-ui', first], ['diagnostics', second]])
await reconcileSystemPlugins({
root: join(root, 'managed'),
environmentVersion: '1.0.0',
plugins: [
{ id: 'update-ui', sha256: '1'.repeat(64) },
{ id: 'diagnostics', sha256: '2'.repeat(64) },
],
artifactPath: reference => artifacts.get(reference.id),
})
const overlay = JSON.parse(await readFile(join(root, 'managed/current/cordis.patch.yml'), 'utf8'))
assert.deepEqual(overlay.flatMap(entry => entry.insert).map(entry => entry.id), ['dsh-docker.update-ui.host', 'dsh-docker.diagnostics.host'])
assert.deepEqual(overlay.flatMap(entry => entry.insert).map(entry => entry.name), [
'@dsh-docker/update-ui',
'@dsh-docker/diagnostics',
])
assert.equal(await readFile(join(userHome, 'cordis.patch.yml'), 'utf8'), '[{"id":"user-owned"}]\n')
assert.match(await readFile(join(userHome, 'profiles/web/package.json'), 'utf8'), /third-party/)
})
test('rejects a System Plugin which claims another namespace', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugin-invalid-'))
const artifact = await archive(root, 'update-ui', [{ insert: [{ id: 'unowned-row', name: '@dsh-docker/update-ui' }] }])
await assert.rejects(reconcileSystemPlugins({
root: join(root, 'managed'),
environmentVersion: 'invalid',
plugins: [{ id: 'update-ui', sha256: '1'.repeat(64) }],
artifactPath: () => artifact,
}), /namespace/)
})
test('rejects a System Plugin which patches an existing DSH row', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugin-mutation-'))
const artifact = await archive(root, 'update-ui', [{
id: 'dsh-docker.update-ui.host',
name: '@dsh-docker/update-ui',
}])
await assert.rejects(reconcileSystemPlugins({
root: join(root, 'managed'),
environmentVersion: 'invalid',
plugins: [{ id: 'update-ui', sha256: '1'.repeat(64) }],
artifactPath: () => artifact,
}), /only a non-empty insert list/)
})
test('retargets only the reserved System Plugin scope without changing persistent Profile data', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugin-scope-'))
const dshHome = join(root, 'dsh')
const profileRoot = join(dshHome, 'profiles', 'web')
const modulesRoot = join(dshHome, 'profiles', 'node_modules')
const userPackageRoot = join(modulesRoot, '@example', 'persistent-plugin')
const firstView = join(root, 'run', 'system-plugins-v1')
const secondView = join(root, 'run', 'system-plugins-v2')
await mkdir(join(profileRoot, 'node_modules'), { recursive: true })
await mkdir(userPackageRoot, { recursive: true })
await mkdir(join(firstView, 'packages'), { recursive: true })
await mkdir(join(secondView, 'packages'), { recursive: true })
await writeFile(join(profileRoot, 'package.json'), '{"dependencies":{"persistent-plugin":"1.0.0"}}\n')
await writeFile(join(profileRoot, 'pnpm-lock.yaml'), 'lockfileVersion: 9\n')
await writeFile(join(userPackageRoot, 'package.json'), '{"name":"@example/persistent-plugin"}\n')
await symlink(userPackageRoot, join(profileRoot, 'node_modules', 'persistent-plugin'), 'dir')
const profileBefore = await hashTree(profileRoot)
const link = await linkSystemPluginScope({ dshHome, viewRoot: firstView })
assert.equal(await readlink(link), join(firstView, 'packages'))
assert.equal(await linkSystemPluginScope({ dshHome, viewRoot: firstView }), link)
assert.equal(await linkSystemPluginScope({ dshHome, viewRoot: secondView }), link)
assert.equal(await readlink(link), join(secondView, 'packages'))
assert.equal(await hashTree(profileRoot), profileBefore)
assert.equal(await readFile(join(userPackageRoot, 'package.json'), 'utf8'), '{"name":"@example/persistent-plugin"}\n')
})
test('rebuilds a bundled System Plugin view only from the current Environment artifacts', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugin-repair-'))
const environment = join(root, 'environment')
const artifact = await archive(root, 'platform-management', [{
insert: [{ id: 'dsh-docker.platform-management.plugin', name: '@dsh-docker/platform-management' }],
}])
const bytes = await readFile(artifact)
const sha256 = createHash('sha256').update(bytes).digest('hex')
await mkdir(join(environment, 'artifacts'), { recursive: true })
await cp(artifact, join(environment, 'artifacts', 'system-plugin-platform-management'))
await writeFile(join(environment, 'environment.manifest.json'), JSON.stringify({
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-20T00:00:00.000Z',
artifacts: [{
id: 'system-plugin-platform-management',
mediaType: 'application/vnd.dsh-platform.system-plugin.v1+tar+gzip',
sha256,
size: bytes.byteLength,
url: 'https://example.invalid/system-plugin-platform-management',
}],
bootstrapApi: 1,
components: [],
patches: [],
systemPlugins: [{ id: 'platform-management', sha256 }],
}))
const initialRoot = join(root, 'initial')
const initial = await reconcileSystemPlugins({
root: initialRoot,
environmentVersion: 'fixture',
plugins: [{ id: 'platform-management', sha256 }],
artifactPath: () => artifact,
})
const expectedSha256 = await hashTree(initial)
const rebuilt = await rebuildBundledSystemPluginView({
environmentRoot: environment,
outputRoot: join(root, 'views'),
expectedSha256,
requestedPluginId: 'platform-management',
})
assert.equal(await hashTree(rebuilt), expectedSha256)
assert.deepEqual(await listBundledSystemPlugins({ environmentRoot: environment, viewRoot: rebuilt }), [{
id: 'platform-management',
artifactId: 'system-plugin-platform-management',
sha256,
installed: true,
reason: null,
}])
await rm(join(rebuilt, 'packages', 'platform-management'), { recursive: true })
const repairedAgain = await rebuildBundledSystemPluginView({
environmentRoot: environment,
outputRoot: join(root, 'views'),
expectedSha256,
requestedPluginId: 'platform-management',
})
assert.equal(await hashTree(repairedAgain), expectedSha256)
await assert.rejects(rebuildBundledSystemPluginView({
environmentRoot: environment,
outputRoot: join(root, 'views'),
expectedSha256,
requestedPluginId: 'unknown',
}), /not bundled/)
})
test('persists install and enable selection while protecting Platform Management', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-plugin-selection-'))
const environment = join(root, 'environment')
const definitions = [
['platform-management', '1'],
['diagnostics', '2'],
]
const artifacts = []
await mkdir(join(environment, 'artifacts'), { recursive: true })
for (const [id] of definitions) {
const artifact = await archive(root, id, [{
insert: [{ id: `dsh-docker.${id}.plugin`, name: `@dsh-docker/${id}` }],
}])
const bytes = await readFile(artifact)
const sha256 = createHash('sha256').update(bytes).digest('hex')
const artifactId = `system-plugin-${id}`
await cp(artifact, join(environment, 'artifacts', artifactId))
artifacts.push({ id: artifactId, sha256, size: bytes.byteLength, pluginId: id, path: artifact })
}
await writeFile(join(environment, 'environment.manifest.json'), JSON.stringify({
schema: 1,
manifestType: 'environment',
version: '1.0.0',
keyringGeneration: 1,
targetSequence: 1,
issuedAt: '2026-08-20T00:00:00.000Z',
artifacts: artifacts.map(artifact => ({
id: artifact.id,
mediaType: 'application/vnd.dsh-platform.system-plugin.v1+tar+gzip',
sha256: artifact.sha256,
size: artifact.size,
url: `https://example.invalid/${artifact.id}`,
})),
bootstrapApi: 1,
components: [],
patches: [],
systemPlugins: artifacts.map(artifact => ({ id: artifact.pluginId, sha256: artifact.sha256 })),
}))
const source = await reconcileSystemPlugins({
root: join(root, 'source'),
environmentVersion: 'fixture',
plugins: artifacts.map(artifact => ({ id: artifact.pluginId, sha256: artifact.sha256 })),
artifactPath: reference => artifacts.find(artifact => artifact.pluginId === reference.id).path,
})
const store = new SystemPluginSelectionStore(join(root, 'state', 'system-plugins.json'))
const pluginIds = artifacts.map(artifact => artifact.pluginId)
const initial = await listManagedSystemPlugins({ environmentRoot: environment, sourceRoot: source, selectionStore: store })
assert.deepEqual(initial.map(plugin => [plugin.id, plugin.description, plugin.installed, plugin.enabled, plugin.protected]), [
['platform-management', { zh: 'platform-management 功能', en: 'platform-management feature' }, true, true, true],
['diagnostics', { zh: 'diagnostics 功能', en: 'diagnostics feature' }, true, true, false],
])
const active = await materializeSystemPluginSelection({
environmentRoot: environment,
sourceRoot: source,
outputRoot: join(root, 'views'),
selectionStore: store,
})
await assert.rejects(store.configure(pluginIds, 'platform-management', 'uninstall'), /managed by the platform/)
await assert.rejects(store.recover(pluginIds, 'diagnostics', 'uninstall'), /not a platform recovery target/)
await store.recover(pluginIds, 'platform-management', 'uninstall')
assert.deepEqual(await store.read(pluginIds).then(value => value['platform-management']), {
installed: false, enabled: false, protected: true,
})
await store.recover(pluginIds, 'platform-management', 'install')
await store.configure(pluginIds, 'diagnostics', 'disable')
const pending = await listManagedSystemPlugins({
environmentRoot: environment,
sourceRoot: source,
selectionStore: store,
activeRoot: active.path,
})
assert.deepEqual(pending.find(plugin => plugin.id === 'diagnostics'), {
id: 'diagnostics',
artifactId: 'system-plugin-diagnostics',
sha256: artifacts.find(artifact => artifact.pluginId === 'diagnostics').sha256,
description: { zh: 'diagnostics 功能', en: 'diagnostics feature' },
installed: true,
enabled: false,
activeInstalled: true,
activeEnabled: true,
pendingRestart: true,
protected: false,
reason: null,
})
const discarded = await discardSystemPluginSelection({
environmentRoot: environment,
sourceRoot: source,
selectionStore: store,
activeRoot: active.path,
})
assert.equal(discarded.find(plugin => plugin.id === 'diagnostics').pendingRestart, false)
assert.deepEqual((await store.read(pluginIds)).diagnostics, {
installed: true, enabled: true, protected: false,
})
await store.configure(pluginIds, 'diagnostics', 'disable')
const disabled = await materializeSystemPluginSelection({
environmentRoot: environment,
sourceRoot: source,
outputRoot: join(root, 'views'),
selectionStore: store,
})
assert.equal((await lstat(join(disabled.path, 'packages', 'diagnostics'))).isSymbolicLink(), true)
assert.deepEqual(JSON.parse(await readFile(join(disabled.path, 'cordis.patch.yml'), 'utf8'))
.flatMap(entry => entry.insert).map(row => row.name), ['@dsh-docker/platform-management'])
assert.equal((await listManagedSystemPlugins({
environmentRoot: environment,
sourceRoot: source,
selectionStore: store,
activeRoot: disabled.path,
})).find(plugin => plugin.id === 'diagnostics').pendingRestart, false)
await store.configure(pluginIds, 'diagnostics', 'uninstall')
const deleted = await materializeSystemPluginSelection({
environmentRoot: environment,
sourceRoot: source,
outputRoot: join(root, 'views'),
selectionStore: store,
})
await assert.rejects(lstat(join(deleted.path, 'packages', 'diagnostics')), error => error.code === 'ENOENT')
assert.deepEqual((await listManagedSystemPlugins({ environmentRoot: environment, sourceRoot: source, selectionStore: store }))
.map(plugin => [plugin.id, plugin.installed, plugin.enabled]), [
['platform-management', true, true],
['diagnostics', false, false],
])
await store.configure(pluginIds, 'diagnostics', 'install')
assert.deepEqual((await new SystemPluginSelectionStore(join(root, 'state', 'system-plugins.json')).read(pluginIds)).diagnostics, {
installed: true,
enabled: true,
protected: false,
})
})
@@ -0,0 +1,113 @@
import assert from 'node:assert/strict'
import { lstat, mkdir, readFile, readlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { mkdtemp } from 'node:fs/promises'
import test from 'node:test'
import {
readSystemSkillCatalog,
SystemSkillManager,
} from '../../control-plane/modules/skill-manager/index.mjs'
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-system-skills-'))
const sourceRoot = join(root, 'source')
const bundle = join(sourceRoot, 'operations')
await mkdir(join(bundle, 'references'), { recursive: true })
await writeFile(join(sourceRoot, 'catalog.json'), JSON.stringify({
schema: 1,
skills: [{
id: 'operations',
source: 'operations',
description: { en: 'Operate DSH.', zh: '操作 DSH。' },
}],
}))
await writeFile(join(bundle, 'SKILL.md'), '---\nname: operations\ndescription: Operate DSH.\n---\n\n# Operations\n')
await writeFile(join(bundle, 'references', 'guide.md'), '# Guide\n')
return {
root,
sourceRoot,
viewRoot: join(root, 'run', 'skills'),
statePath: join(root, 'state', 'skills.json'),
}
}
test('System Skills are identified by signed catalog ID and content hash', async () => {
const { sourceRoot } = await fixture()
const catalog = await readSystemSkillCatalog(sourceRoot)
assert.equal(catalog.length, 1)
assert.equal(catalog[0].id, 'operations')
assert.match(catalog[0].sha256, /^[0-9a-f]{64}$/)
assert.deepEqual(catalog[0].description, { en: 'Operate DSH.', zh: '操作 DSH。' })
})
test('System Skill selection hot-updates one stable view and persists install state', async () => {
const paths = await fixture()
const manager = new SystemSkillManager(paths)
assert.deepEqual(await manager.initialize(), [{
id: 'operations',
sha256: (await manager.list())[0].sha256,
description: { en: 'Operate DSH.', zh: '操作 DSH。' },
installed: true,
enabled: true,
}])
assert.equal(await readlink(join(paths.viewRoot, 'operations')), join(paths.sourceRoot, 'operations'))
assert.equal((await manager.configure('operations', 'disable'))[0].enabled, false)
await assert.rejects(lstat(join(paths.viewRoot, 'operations')), { code: 'ENOENT' })
assert.equal((await manager.configure('operations', 'enable'))[0].enabled, true)
assert.equal(await readlink(join(paths.viewRoot, 'operations')), join(paths.sourceRoot, 'operations'))
const uninstalled = (await manager.configure('operations', 'uninstall'))[0]
assert.deepEqual({ installed: uninstalled.installed, enabled: uninstalled.enabled }, { installed: false, enabled: false })
await assert.rejects(manager.configure('operations', 'enable'), /must be installed/)
assert.equal((await new SystemSkillManager(paths).initialize())[0].installed, false)
assert.equal((await manager.configure('operations', 'install'))[0].enabled, true)
})
test('System Skill state ignores removed entries and defaults newly signed skills on', async () => {
const paths = await fixture()
const manager = new SystemSkillManager(paths)
await manager.initialize()
await manager.configure('operations', 'uninstall')
const second = join(paths.sourceRoot, 'second')
await mkdir(second)
await writeFile(join(second, 'SKILL.md'), '---\nname: second\ndescription: Second.\n---\n\n# Second\n')
await writeFile(join(paths.sourceRoot, 'catalog.json'), JSON.stringify({
schema: 1,
skills: [{ id: 'second', source: 'second', description: { en: 'Second.', zh: '第二个。' } }],
}))
const listed = await manager.initialize()
assert.deepEqual(listed.map(skill => ({ id: skill.id, installed: skill.installed, enabled: skill.enabled })), [
{ id: 'second', installed: true, enabled: true },
])
const saved = JSON.parse(await readFile(paths.statePath, 'utf8'))
assert.deepEqual(Object.keys(saved.skills), ['second'])
})
test('System Skill manager switches to a newly selected Environment catalog', async () => {
const paths = await fixture()
const manager = new SystemSkillManager(paths)
await manager.initialize()
const replacementRoot = join(paths.root, 'replacement')
const replacement = join(replacementRoot, 'replacement')
await mkdir(replacement, { recursive: true })
await writeFile(join(replacement, 'SKILL.md'), '---\nname: replacement\ndescription: Replacement.\n---\n')
await writeFile(join(replacementRoot, 'catalog.json'), JSON.stringify({
schema: 1,
skills: [{ id: 'replacement', source: 'replacement', description: { en: 'Replacement.', zh: '替代。' } }],
}))
assert.deepEqual((await manager.useSourceRoot(replacementRoot)).map(skill => skill.id), ['replacement'])
await assert.rejects(lstat(join(paths.viewRoot, 'operations')), { code: 'ENOENT' })
assert.equal(await readlink(join(paths.viewRoot, 'replacement')), replacement)
await assert.rejects(manager.configure('operations', 'enable'), /current Environment/)
})
test('System Skill catalog rejects source aliases and mismatched frontmatter', async () => {
const paths = await fixture()
const document = JSON.parse(await readFile(join(paths.sourceRoot, 'catalog.json'), 'utf8'))
document.skills[0].source = '../operations'
await writeFile(join(paths.sourceRoot, 'catalog.json'), JSON.stringify(document))
await assert.rejects(readSystemSkillCatalog(paths.sourceRoot), /source is invalid/)
})
@@ -0,0 +1,248 @@
import assert from 'node:assert/strict'
import { request as httpRequest } from 'node:http'
import { mkdir, mkdtemp } from 'node:fs/promises'
import { tmpdir, userInfo } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import WebSocket from '../../control-plane/services/management/node_modules/ws/wrapper.mjs'
import { createManagementServer } from '../../control-plane/services/management/server.mjs'
import { TerminalSessionManager, terminalSessionInternals } from '../../control-plane/services/management/terminal/sessions.mjs'
const API = '/_dsh_platform/api/v1/'
function request(port, method, path, body) {
return new Promise((resolve, reject) => {
const encoded = body === undefined ? undefined : Buffer.from(JSON.stringify(body))
const outgoing = httpRequest({
host: '127.0.0.1', port, method, path,
headers: encoded === undefined ? undefined : { 'content-type': 'application/json', 'content-length': encoded.byteLength },
}, response => {
const chunks = []
response.on('data', chunk => chunks.push(chunk))
response.once('end', () => {
const text = Buffer.concat(chunks).toString('utf8')
resolve({ status: response.statusCode, body: text === '' ? undefined : JSON.parse(text) })
})
})
outgoing.once('error', reject)
outgoing.end(encoded)
})
}
function collector(url) {
const socket = new WebSocket(url)
let output = ''
let exit
const waiters = new Set()
socket.on('message', bytes => {
const value = JSON.parse(bytes.toString())
if (value.type === 'output') output += value.data
if (value.type === 'exit') exit = value
for (const waiter of waiters) waiter()
})
const waitFor = async predicate => {
for (let attempt = 0; attempt < 400; attempt += 1) {
if (predicate({ output, exit })) return { output, exit }
await new Promise(resolve => {
const timer = setTimeout(() => { waiters.delete(done); resolve() }, 25)
const done = () => { clearTimeout(timer); waiters.delete(done); resolve() }
waiters.add(done)
})
}
throw new Error(`terminal output did not reach expected state: ${output}`)
}
return { socket, waitFor, output: () => output }
}
async function fixture({ reconnectMs = 30_000 } = {}) {
const root = await mkdtemp(join(tmpdir(), 'dsh-terminal-'))
const workspace = join(root, 'workspace')
const dshHome = join(root, 'dsh')
await mkdir(workspace)
await mkdir(dshHome)
const reports = []
const terminalSessions = new TerminalSessionManager({
cwd: workspace,
dshHome,
reconnectMs,
report: async (message, fields) => { reports.push({ message, fields }) },
})
const logs = {
diagnostic: async () => {}, query: async () => [], on: () => {}, off: () => {},
}
const state = { read: async () => ({}), on: () => {}, off: () => {} }
const coordinator = { publicStatus: async () => ({}), hasActiveTask: () => false, state, on: () => {}, off: () => {} }
const server = createManagementServer({ coordinator, logs, terminalSessions })
await new Promise((resolve, reject) => {
server.once('error', reject)
server.listen(0, '127.0.0.1', resolve)
})
const port = server.address().port
return {
root, workspace, dshHome, reports, terminalSessions, server, port,
close: async () => {
await terminalSessions.shutdown()
await new Promise(resolve => server.close(resolve))
},
}
}
test('terminal HTTP and WebSocket lifecycle provides a real bounded PTY', async () => {
const value = await fixture()
try {
const created = await request(value.port, 'POST', `${API}terminal/sessions`, { cols: 92, rows: 31 })
assert.equal(created.status, 201)
assert.match(created.body.sessionId, terminalSessionInternals.SESSION_PATTERN)
const path = `${API}terminal/sessions/${created.body.sessionId}`
assert.equal((await request(value.port, 'GET', path)).body.status, 'running')
const first = collector(`ws://127.0.0.1:${value.port}${path}/stream`)
await new Promise((resolve, reject) => {
first.socket.once('open', resolve)
first.socket.once('error', reject)
})
first.socket.send(JSON.stringify({ type: 'resize', cols: 101, rows: 37 }))
first.socket.send(JSON.stringify({
type: 'input',
data: "printf '\\033[31mred\\033[0m\\n'; printf '中文✓\\n'; printf 'cwd=%s\\n' \"$PWD\"; printf 'home=%s\\n' \"$HOME\"; printf 'dsh=%s\\n' \"$DSH_HOME\"; printf 'uid=%s\\n' \"$(id -u)\"; printf 'gids=%s\\n' \"$(id -G)\"; printf 'path=%s\\n' \"$PATH\"; printf 'umask=%s\\n' \"$(umask)\"; stty size; printf 'command-complete\\n'\n",
}))
let initial
try {
initial = await first.waitFor(({ output }) => output.includes('\x1b[31mred\x1b[0m') && output.match(/command-complete/g)?.length >= 3)
} catch (error) {
error.message += `; status=${JSON.stringify((await request(value.port, 'GET', path)).body)} reports=${JSON.stringify(value.reports)}`
throw error
}
assert.match(initial.output, /\x1b\[31mred\x1b\[0m/)
assert.match(initial.output, /中文✓/)
assert.match(initial.output, new RegExp(`cwd=${value.workspace.replaceAll('/', '\\/')}`))
assert.match(initial.output, new RegExp(`home=${userInfo().homedir.replaceAll('/', '\\/')}`))
assert.match(initial.output, new RegExp(`dsh=${value.dshHome.replaceAll('/', '\\/')}`))
assert.match(initial.output, new RegExp(`uid=${String(process.getuid())}`))
for (const group of process.getgroups()) assert.match(initial.output, new RegExp(`gids=[^\\r\\n]*\\b${String(group)}\\b`))
assert.match(initial.output, /path=\S+/)
assert.match(initial.output, /umask=0002/)
assert.match(initial.output, /37 101/)
first.socket.send(JSON.stringify({ type: 'input', data: "read -p 'answer: ' value; printf 'interactive=%s\\n' \"$value\"\n" }))
await first.waitFor(({ output }) => output.includes('answer:'))
first.socket.send(JSON.stringify({ type: 'input', data: 'works\n' }))
await first.waitFor(({ output }) => output.includes('interactive=works'))
first.socket.send(JSON.stringify({ type: 'input', data: "printf 'long-start\\n'; head -c 300000 /dev/zero | tr '\\0' x; printf '\\nlong-tail\\n'\n" }))
await first.waitFor(({ output }) => output.length > 300_000 && output.match(/long-tail/g)?.length >= 2)
first.socket.send(JSON.stringify({ type: 'input', data: "printf 'cached-marker\\n'\n" }))
await first.waitFor(({ output }) => output.includes('cached-marker'))
first.socket.close()
await new Promise(resolve => first.socket.once('close', resolve))
const second = collector(`ws://127.0.0.1:${value.port}${path}/stream`)
await new Promise((resolve, reject) => {
second.socket.once('open', resolve)
second.socket.once('error', reject)
})
const replay = (await second.waitFor(({ output }) => output.includes('cached-marker'))).output
assert.match(replay, /long-tail/)
assert.match(replay, /cached-marker/)
assert.doesNotMatch(replay, /long-start/)
assert.ok(Buffer.byteLength(replay) <= 256 * 1024 + 1024)
second.socket.send(JSON.stringify({ type: 'input', data: 'exit 7\n' }))
const ended = await second.waitFor(result => result.exit !== undefined)
assert.deepEqual({ code: ended.exit.code, signal: ended.exit.signal }, { code: 7, signal: null })
assert.equal((await request(value.port, 'GET', path)).body.status, 'exited')
assert.equal((await request(value.port, 'DELETE', path)).body.closed, true)
second.socket.close()
const messages = value.reports.map(entry => entry.message)
for (const event of [
'terminal.session.created', 'terminal.session.connected', 'terminal.session.disconnected',
'terminal.session.reconnected', 'terminal.session.exited', 'terminal.session.closed',
]) assert.ok(messages.includes(event), `${event} was not reported`)
assert.doesNotMatch(JSON.stringify(value.reports), /cached-marker|interactive=works|command-complete/)
} finally {
await value.close()
}
})
test('terminal sessions accept a trusted per-session network environment', async () => {
const value = await fixture()
try {
const created = value.terminalSessions.create({}, {
HTTP_PROXY: 'http://127.0.0.1:17896',
NO_PROXY: 'localhost,.example.com',
})
const path = `${API}terminal/sessions/${created.sessionId}`
const connection = collector(`ws://127.0.0.1:${value.port}${path}/stream`)
await new Promise((resolve, reject) => {
connection.socket.once('open', resolve)
connection.socket.once('error', reject)
})
connection.socket.send(JSON.stringify({
type: 'input',
data: "printf 'proxy=%s\\nno_proxy=%s\\n' \"$HTTP_PROXY\" \"$NO_PROXY\"\n",
}))
const result = await connection.waitFor(({ output }) => output.includes('no_proxy=localhost,.example.com'))
assert.match(result.output, /proxy=http:\/\/127\.0\.0\.1:17896/)
connection.socket.close()
} finally {
await value.close()
}
})
test('terminal sessions enforce dimensions, message size, expiry, and exact IDs', async () => {
const value = await fixture({ reconnectMs: 80 })
try {
for (const body of [{ cols: 1, rows: 24 }, { cols: 501, rows: 24 }, { cols: 80, rows: 0 }, { cols: 80, rows: 201 }]) {
assert.equal((await request(value.port, 'POST', `${API}terminal/sessions`, body)).status, 400)
}
const created = (await request(value.port, 'POST', `${API}terminal/sessions`, {})).body
const path = `${API}terminal/sessions/${created.sessionId}`
const connection = collector(`ws://127.0.0.1:${value.port}${path}/stream`)
await new Promise((resolve, reject) => {
connection.socket.once('open', resolve)
connection.socket.once('error', reject)
})
connection.socket.send(JSON.stringify({ type: 'resize', cols: 1, rows: 20 }))
const closeCode = await new Promise(resolve => connection.socket.once('close', resolve))
assert.equal(closeCode, 1008)
let expiredStatus
for (let attempt = 0; attempt < 100; attempt += 1) {
expiredStatus = (await request(value.port, 'GET', path)).status
if (expiredStatus === 404) break
await new Promise(resolve => setTimeout(resolve, 20))
}
assert.equal(expiredStatus, 404)
const oversized = (await request(value.port, 'POST', `${API}terminal/sessions`, {})).body
const oversizedConnection = collector(`ws://127.0.0.1:${value.port}${API}terminal/sessions/${oversized.sessionId}/stream`)
await new Promise((resolve, reject) => {
oversizedConnection.socket.once('open', resolve)
oversizedConnection.socket.once('error', reject)
})
oversizedConnection.socket.send(JSON.stringify({ type: 'input', data: 'x'.repeat(64 * 1024 + 1) }))
const oversizedClose = await new Promise(resolve => oversizedConnection.socket.once('close', resolve))
assert.ok([1008, 1009].includes(oversizedClose))
assert.equal((await request(value.port, 'GET', `${API}terminal/sessions/not-a-uuid`)).status, 404)
} finally {
await value.close()
}
})
test('terminal sessions default to the Root maintenance home', () => {
const terminalSessions = new TerminalSessionManager()
assert.equal(terminalSessions.cwd, '/root')
})
test('terminal shutdown waits for every helper process to close', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-terminal-shutdown-'))
const workspace = join(root, 'workspace')
const dshHome = join(root, 'dsh')
await mkdir(workspace)
await mkdir(dshHome)
const terminalSessions = new TerminalSessionManager({ cwd: workspace, dshHome })
const created = terminalSessions.create()
const session = terminalSessions.sessions.get(created.sessionId)
assert.equal(session.child.exitCode, null)
await terminalSessions.shutdown()
assert.equal(terminalSessions.sessions.size, 0)
assert.equal(session.child.exitCode !== null || session.child.signalCode !== null, true)
})
@@ -0,0 +1,105 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import {
TotpFlowStore,
TotpRetryLimiter,
generateTotpSecret,
totpCode,
totpUri,
validTotpSecret,
verifyTotpCode,
} from '../../control-plane/services/access-manager/lib/totp.mjs'
test('generates interoperable TOTP secrets, codes, and enrollment URIs', () => {
const secret = generateTotpSecret(size => Buffer.alloc(size, 7))
assert.equal(secret.length, 32)
assert.equal(validTotpSecret(secret), true)
const code = totpCode(secret, { now: 59_000 })
assert.equal(code.length, 6)
assert.equal(verifyTotpCode(code, secret, { now: 59_000 }), true)
assert.equal(verifyTotpCode(code, secret, { now: 89_000 }), true)
assert.equal(verifyTotpCode('not-six-digits', secret, { now: 59_000 }), false)
assert.match(totpUri({ secret, username: '管理 员' }), /^otpauth:\/\/totp\/DSH%20Docker%3A%E7%AE%A1%E7%90%86%20%E5%91%98\?secret=/)
})
test('binds one-time TOTP enrollment and login challenges to account state and sessions', () => {
let now = 1_000
let fill = 1
const flows = new TotpFlowStore({
now: () => now,
random: size => Buffer.alloc(size, fill++),
enrollmentTtlMs: 100,
loginTtlMs: 100,
})
const account = { accountId: 'account-a', revision: 'revision-a' }
const enrollment = flows.createEnrollment(account, 'management-a')
assert.equal(flows.enrollment(enrollment.token, account, 'management-a')?.value.secret, enrollment.secret)
assert.equal(flows.enrollment(enrollment.token, account, 'management-a')?.value.confirmed, false)
const boundEnrollment = flows.enrollment(enrollment.token, account, 'management-a')
assert.equal(flows.confirmEnrollment(boundEnrollment.key), true)
assert.equal(flows.enrollment(enrollment.token, account, 'management-a')?.value.confirmed, true)
assert.equal(flows.enrollment(enrollment.token, account, 'management-b'), undefined)
assert.equal(flows.enrollment(enrollment.token, { ...account, revision: 'revision-b' }, 'management-a'), undefined)
assert.equal(flows.cancelEnrollment(enrollment.token, account, 'management-a'), true)
assert.equal(flows.confirmEnrollment(boundEnrollment.key), false)
assert.equal(flows.enrollment(enrollment.token, account, 'management-a'), undefined)
const disabling = flows.createDisableConfirmation(account, 'management-a')
assert.match(disabling.token, /^dshtd_/)
const boundDisable = flows.disableConfirmation(disabling.token, account, 'management-a')
assert.equal(boundDisable?.value.confirmed, false)
assert.equal(flows.confirmDisable(boundDisable.key), true)
assert.equal(flows.disableConfirmation(disabling.token, account, 'management-a')?.value.confirmed, true)
assert.equal(flows.disableConfirmation(disabling.token, account, 'management-b'), undefined)
assert.equal(flows.disableConfirmation(disabling.token, { ...account, revision: 'revision-b' }, 'management-a'), undefined)
assert.equal(flows.cancelDisableConfirmation(disabling.token, account, 'management-a'), true)
assert.equal(flows.disableConfirmation(disabling.token, account, 'management-a'), undefined)
const login = flows.createLogin(account, { origin: 'https://dsh.example', authenticationSource: 'browser:a' })
assert.equal(flows.login(login.token, account)?.value.origin, 'https://dsh.example')
now += 101
assert.equal(flows.login(login.token, account), undefined)
})
test('applies fixed TOTP retry and separate source and global daily windows', () => {
let now = 1_000
assert.equal(new TotpRetryLimiter().sourceDailyLimit, 25)
assert.equal(new TotpRetryLimiter().globalDailyLimit, 50)
const limiter = new TotpRetryLimiter({
now: () => now,
threshold: 3,
retryMs: 10_000,
sourceDailyLimit: 4,
globalDailyLimit: 6,
dailyWindowMs: 100_000,
})
assert.equal(limiter.fail('account', 'browser:a').kind, null)
assert.equal(limiter.fail('account', 'browser:a').kind, null)
assert.deepEqual(limiter.fail('account', 'browser:a'), { kind: 'retry', retryAfterSeconds: 10 })
assert.equal(limiter.clearDailyLimits('account').cleared, 2)
assert.deepEqual(limiter.retry('account', 'browser:a'), { kind: 'retry', retryAfterSeconds: 10 })
now += 10_000
assert.deepEqual(limiter.fail('account', 'browser:a'), { kind: 'retry', retryAfterSeconds: 10 })
now += 10_000
limiter.succeed('account', 'browser:a')
assert.deepEqual(limiter.retry('account', 'browser:a'), { kind: null, retryAfterSeconds: 0 })
for (let index = 0; index < 3; index += 1) limiter.fail('account', 'browser:b')
now += 10_000
assert.equal(limiter.fail('account', 'browser:b').kind, 'rate')
limiter.clearDailyLimits('account')
assert.equal(limiter.retry('account', 'browser:b').kind, 'retry')
now += 10_000
assert.equal(limiter.retry('account', 'browser:b').kind, null)
for (let index = 0; index < 3; index += 1) {
limiter.succeed('account', 'browser:a')
limiter.fail('account', 'browser:a')
limiter.succeed('account', 'browser:b')
limiter.fail('account', 'browser:b')
}
assert.equal(limiter.retry('account', 'browser:a').kind, 'rate')
assert.equal(limiter.clearDailyLimits('account', { globalOnly: true }).cleared, 1)
assert.equal(limiter.retry('account', 'browser:a').kind, null)
})
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,439 @@
import assert from 'node:assert/strict'
import { chmod, lstat, mkdir, mkdtemp, readFile, readlink, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { UserPluginInventory } from '../../control-plane/modules/plugin-manager/user-inventory.mjs'
import { UserPluginJournal, userPluginJournalInternals } from '../../control-plane/modules/plugin-manager/user-journal.mjs'
import { UserPluginSnapshots, userPluginSnapshotInternals } from '../../control-plane/modules/plugin-manager/user-snapshots.mjs'
import { UserPluginSelectionStore, userPluginStateInternals } from '../../control-plane/modules/plugin-manager/user-state.mjs'
import { UserPluginTransactionManager, userPluginTransactionInternals } from '../../control-plane/modules/plugin-manager/user-transaction.mjs'
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-user-plugin-transaction-'))
const dshHome = join(root, 'dsh')
const profileRoot = join(dshHome, 'profiles/web')
const stateRoot = join(root, 'platform/state/management')
const selectionPath = join(stateRoot, 'user-plugins.json')
const journalPath = join(stateRoot, 'user-plugin-transaction.json')
const snapshotsRoot = join(root, 'platform/store/snapshots/user-plugins')
await mkdir(join(profileRoot, 'node_modules'), { recursive: true })
await writeFile(join(profileRoot, 'package.json'), JSON.stringify({
name: 'dsh-profile-web',
dependencies: { alpha: '1.0.0', beta: '1.0.0', gamma: '1.0.0' },
dsh: { profile: { bundles: ['alpha', 'beta'] } },
}))
await writeFile(join(profileRoot, 'pnpm-lock.yaml'), 'lockfileVersion: 9\n')
for (const name of ['alpha', 'beta', 'gamma']) {
const installed = join(profileRoot, 'node_modules', name)
await mkdir(installed)
await writeFile(join(installed, 'package.json'), JSON.stringify({
name, version: '1.0.0', dsh: { bundle: { patch: './cordis.patch.yml' } },
}))
await writeFile(join(installed, 'cordis.patch.yml'), '[]\n')
}
const inventory = new UserPluginInventory({ dshHome, selectionPath })
const selectionStore = new UserPluginSelectionStore(selectionPath)
const journal = new UserPluginJournal(journalPath)
const snapshots = new UserPluginSnapshots({ root: snapshotsRoot, profileRoot })
return { root, dshHome, profileRoot, selectionPath, journal, snapshots, inventory, selectionStore }
}
function manager(value, overrides = {}) {
const calls = []
return {
calls,
value: new UserPluginTransactionManager({
inventory: value.inventory,
selectionStore: value.selectionStore,
snapshots: value.snapshots,
journal: value.journal,
pauseDsh: async () => { calls.push('pause') },
restartDsh: async () => { calls.push('restart') },
runPlugin: async details => { calls.push(['remove', details]) },
report: async message => { calls.push(['report', message]) },
...overrides,
}),
}
}
test('runs DSH plugin removal with writable user configuration directories', () => {
const previous = {
HOME: process.env.HOME,
npm_config_userconfig: process.env.npm_config_userconfig,
NPM_CONFIG_CACHE: process.env.NPM_CONFIG_CACHE,
PNPM_HOME: process.env.PNPM_HOME,
npm_config_prefix: process.env.npm_config_prefix,
}
process.env.HOME = '/root'
process.env.npm_config_userconfig = '/root/.npmrc'
process.env.NPM_CONFIG_CACHE = '/root/.npm'
process.env.PNPM_HOME = '/root/.local/share/pnpm'
process.env.npm_config_prefix = '/root/.local'
try {
const environment = userPluginTransactionInternals.pluginEnvironment('/data/dsh')
assert.equal(environment.HOME, '/home/node')
assert.equal(environment.XDG_CACHE_HOME, '/home/node/.cache')
assert.equal(environment.XDG_CONFIG_HOME, '/home/node/.config')
assert.equal(environment.XDG_DATA_HOME, '/home/node/.local/share')
assert.equal(environment.XDG_STATE_HOME, '/home/node/.local/state')
assert.equal(environment.DSH_HOME, '/data/dsh')
assert.equal(environment.npm_config_userconfig, undefined)
assert.equal(environment.NPM_CONFIG_CACHE, undefined)
assert.equal(environment.PNPM_HOME, undefined)
assert.equal(environment.npm_config_prefix, undefined)
} finally {
for (const [name, value] of Object.entries(previous)) {
if (value === undefined) delete process.env[name]
else process.env[name] = value
}
}
})
test('snapshots and restores the complete Web Profile with hidden files, modes, and symlinks', async () => {
const value = await fixture()
await writeFile(join(value.profileRoot, '.hidden'), 'hidden\n')
await chmod(join(value.profileRoot, '.hidden'), 0o640)
await symlink('package.json', join(value.profileRoot, 'manifest-link'))
await value.snapshots.create('snapshot-one')
await rm(join(value.profileRoot, '.hidden'))
await writeFile(join(value.profileRoot, 'package.json'), '{}\n')
await value.snapshots.restore('snapshot-one')
assert.equal(await readFile(join(value.profileRoot, '.hidden'), 'utf8'), 'hidden\n')
assert.equal((await lstat(join(value.profileRoot, '.hidden'))).mode & 0o777, 0o640)
assert.equal(await readlink(join(value.profileRoot, 'manifest-link')), 'package.json')
assert.match(await readFile(join(value.profileRoot, 'package.json'), 'utf8'), /dsh-profile-web/)
await writeFile(join(value.snapshots.path('snapshot-one'), 'profile.tar'), 'corrupt')
await assert.rejects(value.snapshots.inspect('snapshot-one'), /does not match/)
})
test('creates full Profile snapshots without compression overhead', async () => {
const value = await fixture()
await value.snapshots.create('snapshot-uncompressed')
assert.equal((await lstat(join(value.snapshots.path('snapshot-uncompressed'), 'profile.tar'))).isFile(), true)
await assert.rejects(lstat(join(value.snapshots.path('snapshot-uncompressed'), 'profile.tar.gz')), { code: 'ENOENT' })
})
test('atomically applies ordered enable and disable actions around one DSH pause', async () => {
const value = await fixture()
const before = await value.inventory.read()
const transaction = manager(value)
const result = await transaction.value.apply({
taskId: 'task-enable-disable',
revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }, { name: 'gamma', action: 'enable' }],
})
assert.equal(result.status, 'success')
const manifest = JSON.parse(await readFile(join(value.profileRoot, 'package.json'), 'utf8'))
assert.deepEqual(manifest.dsh.profile.bundles, ['beta', 'gamma'])
assert.deepEqual((await value.selectionStore.read()).disabled, [{ name: 'alpha', index: 0 }])
assert.deepEqual(result.inventory.plugins.map(plugin => [plugin.name, plugin.enabled]), [
['alpha', false], ['beta', true], ['gamma', true],
])
assert.equal((await value.journal.read()).phase, 'completed')
await assert.rejects(lstat(value.snapshots.path('task-enable-disable')), { code: 'ENOENT' })
assert.deepEqual(transaction.calls.filter(call => typeof call === 'string'), ['pause', 'restart'])
})
test('records every disabled plugin position from the original Bundle order', async () => {
const value = await fixture()
const before = await value.inventory.read()
const transaction = manager(value)
await transaction.value.apply({
taskId: 'task-disable-order', revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }, { name: 'beta', action: 'disable' }],
})
assert.deepEqual((await value.selectionStore.read()).disabled, [
{ name: 'alpha', index: 0 }, { name: 'beta', index: 1 },
])
})
test('restores the full Profile when an exact uninstall command fails before commit', async () => {
const value = await fixture()
const beforeBytes = await readFile(join(value.profileRoot, 'package.json'))
const before = await value.inventory.read()
const transaction = manager(value, {
runPlugin: async ({ name }) => {
await writeFile(join(value.profileRoot, 'package.json'), '{}\n')
throw new Error(`pnpm failed for ${name}`)
},
})
await assert.rejects(transaction.value.apply({
taskId: 'task-uninstall-failure',
revision: before.revision,
actions: [{ name: 'alpha', action: 'uninstall' }],
}), /pnpm failed/)
assert.deepEqual(await readFile(join(value.profileRoot, 'package.json')), beforeBytes)
assert.equal((await value.journal.read()).phase, 'failed')
assert.equal((await value.journal.read()).recoveryResult, 'success')
assert.deepEqual(transaction.calls.filter(call => typeof call === 'string'), ['pause', 'restart'])
})
test('uninstalls one exact package name without exposing package-manager arguments', async () => {
const value = await fixture()
const before = await value.inventory.read()
const removals = []
const transaction = manager(value, {
runPlugin: async details => {
removals.push(details)
const manifestPath = join(value.profileRoot, 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
delete manifest.dependencies[details.name]
manifest.dsh.profile.bundles = manifest.dsh.profile.bundles.filter(name => name !== details.name)
await writeFile(manifestPath, JSON.stringify(manifest))
await writeFile(join(value.profileRoot, 'pnpm-lock.yaml'), 'lockfileVersion: 9\npackages: {}\n')
await rm(join(value.profileRoot, 'node_modules', details.name), { recursive: true, force: true })
},
})
const result = await transaction.value.apply({
taskId: 'task-uninstall-success',
revision: before.revision,
actions: [{ name: 'alpha', action: 'uninstall' }],
})
assert.deepEqual(removals, [{ dshHome: value.dshHome, profile: 'web', name: 'alpha' }])
assert.equal(result.inventory.plugins.some(plugin => plugin.name === 'alpha'), false)
})
test('reapplies disabled Bundle selection after DSH plugin removal reconciles the Profile', async () => {
const value = await fixture()
const before = await value.inventory.read()
const transaction = manager(value, {
runPlugin: async details => {
const manifestPath = join(value.profileRoot, 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
delete manifest.dependencies[details.name]
manifest.dsh.profile.bundles = ['beta']
await writeFile(manifestPath, JSON.stringify(manifest))
await rm(join(value.profileRoot, 'node_modules', details.name), { recursive: true, force: true })
},
})
const result = await transaction.value.apply({
taskId: 'task-disable-and-uninstall',
revision: before.revision,
actions: [{ name: 'beta', action: 'disable' }, { name: 'alpha', action: 'uninstall' }],
})
const manifest = JSON.parse(await readFile(join(value.profileRoot, 'package.json'), 'utf8'))
assert.deepEqual(manifest.dsh.profile.bundles, [])
assert.equal(result.inventory.plugins.find(plugin => plugin.name === 'beta')?.enabled, false)
assert.equal(result.inventory.plugins.some(plugin => plugin.name === 'alpha'), false)
})
test('restarts unchanged DSH when the mandatory Profile snapshot cannot be created', async () => {
const value = await fixture()
const beforeBytes = await readFile(join(value.profileRoot, 'package.json'))
const before = await value.inventory.read()
const transaction = manager(value, {
snapshots: {
create: async () => { throw new Error('snapshot disk full') },
remove: async () => {},
},
})
await assert.rejects(transaction.value.apply({
taskId: 'task-snapshot-failure',
revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
}), /snapshot disk full/)
assert.deepEqual(await readFile(join(value.profileRoot, 'package.json')), beforeBytes)
assert.deepEqual(transaction.calls.filter(call => typeof call === 'string'), ['pause', 'restart'])
const journal = await value.journal.read()
assert.equal(journal.phase, 'failed')
assert.equal(journal.recoveryResult, 'success')
})
test('retains a committed plugin change when DSH still fails to restart', async () => {
const value = await fixture()
const before = await value.inventory.read()
const transaction = manager(value, { restartDsh: async () => { throw new Error('DSH remains broken') } })
const result = await transaction.value.apply({
taskId: 'task-restart-failure',
revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
})
assert.equal(result.status, 'success')
assert.equal(result.strategy, 'next-start')
assert.equal(result.activationError, 'DSH remains broken')
const manifest = JSON.parse(await readFile(join(value.profileRoot, 'package.json'), 'utf8'))
assert.deepEqual(manifest.dsh.profile.bundles, ['beta'])
const journal = await value.journal.read()
assert.equal(journal.phase, 'completed')
assert.equal(journal.recoveryResult, null)
await assert.rejects(lstat(value.snapshots.path('task-restart-failure')), { code: 'ENOENT' })
})
test('applies persistent plugin changes without touching DSH when it is unavailable', async () => {
const value = await fixture()
const before = await value.inventory.read()
const transaction = manager(value)
const result = await transaction.value.apply({
taskId: 'task-next-start',
revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
strategy: 'next-start',
})
assert.equal(result.status, 'success')
assert.equal(result.strategy, 'next-start')
assert.equal(result.activationError, null)
assert.deepEqual(transaction.calls.filter(call => typeof call === 'string'), [])
assert.deepEqual(JSON.parse(await readFile(join(value.profileRoot, 'package.json'), 'utf8')).dsh.profile.bundles, ['beta'])
assert.equal((await value.journal.read()).phase, 'completed')
})
test('recovers an interrupted pre-commit mutation from its persisted snapshot', async () => {
const value = await fixture()
const before = await value.inventory.read()
await value.journal.begin({
taskId: 'task-interrupted', revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
selection: await value.selectionStore.snapshot(),
})
await value.journal.transition('paused')
await value.snapshots.create('task-interrupted')
await value.journal.transition('snapshotted', { snapshotId: 'task-interrupted' })
await value.journal.transition('mutating')
await writeFile(join(value.profileRoot, 'package.json'), '{}\n')
const transaction = manager(value)
const recovered = await transaction.value.recover()
assert.equal(recovered.phase, 'failed')
assert.equal(recovered.recoveryResult, 'success')
assert.match(await readFile(join(value.profileRoot, 'package.json'), 'utf8'), /dsh-profile-web/)
await assert.rejects(lstat(value.selectionPath), { code: 'ENOENT' })
assert.deepEqual(transaction.calls.filter(call => typeof call === 'string'), ['pause', 'restart'])
})
test('restores an interrupted pre-commit Profile before Bootstrap starts DSH', async () => {
const value = await fixture()
const before = await value.inventory.read()
await value.journal.begin({
taskId: 'task-prestart-restore', revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
selection: await value.selectionStore.snapshot(),
})
await value.journal.transition('paused')
await value.snapshots.create('task-prestart-restore')
await value.journal.transition('snapshotted', { snapshotId: 'task-prestart-restore' })
await value.journal.transition('mutating')
await writeFile(join(value.profileRoot, 'package.json'), '{}\n')
const transaction = manager(value)
const recovered = await transaction.value.recoverBeforeDshStart()
assert.equal(recovered.phase, 'failed')
assert.equal(recovered.recoveryResult, 'success')
assert.match(await readFile(join(value.profileRoot, 'package.json'), 'utf8'), /dsh-profile-web/)
assert.deepEqual(transaction.calls, [])
})
test('lets Bootstrap start a committed Profile once and then finalizes the journal', async () => {
const value = await fixture()
const before = await value.inventory.read()
await value.journal.begin({
taskId: 'task-prestart-committed', revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
selection: await value.selectionStore.snapshot(),
})
await value.journal.transition('paused')
await value.snapshots.create('task-prestart-committed')
await value.journal.transition('snapshotted', { snapshotId: 'task-prestart-committed' })
await value.journal.transition('mutating')
await value.journal.transition('committed')
const transaction = manager(value)
const pending = await transaction.value.recoverBeforeDshStart()
assert.equal(pending.phase, 'restarting')
assert.deepEqual(transaction.calls, [])
const completed = await transaction.value.completeDshStartup({ healthy: true })
assert.equal(completed.phase, 'completed')
await assert.rejects(lstat(value.snapshots.path('task-prestart-committed')), { code: 'ENOENT' })
})
test('restores platform selection state when final Profile validation fails', async () => {
const value = await fixture()
await value.selectionStore.write({ schema: 1, disabled: [{ name: 'gamma', index: 2 }] })
const initial = await value.inventory.read()
let reads = 0
const inventory = Object.create(value.inventory)
inventory.read = async () => {
reads += 1
if (reads === 2) throw new Error('result validation failed')
return value.inventory.read()
}
const transaction = manager({ ...value, inventory })
await assert.rejects(transaction.value.apply({
taskId: 'task-selection-restore',
revision: initial.revision,
actions: [{ name: 'alpha', action: 'disable' }],
}), /result validation failed/)
assert.deepEqual((await value.selectionStore.read()).disabled, [{ name: 'gamma', index: 2 }])
const manifest = JSON.parse(await readFile(join(value.profileRoot, 'package.json'), 'utf8'))
assert.deepEqual(manifest.dsh.profile.bundles, ['alpha', 'beta'])
})
test('rejects stale revisions and reserved-name enablement before pausing DSH', async () => {
const value = await fixture()
const transaction = manager(value)
await assert.rejects(transaction.value.apply({
revision: `sha256:${'0'.repeat(64)}`,
actions: [{ name: 'alpha', action: 'disable' }],
}), error => error.code === 'REVISION_CONFLICT')
assert.deepEqual(transaction.calls, [])
const reserved = new UserPluginInventory({
dshHome: value.dshHome,
selectionPath: value.selectionPath,
systemPluginNames: async () => ['alpha'],
})
const reservedManager = manager({ ...value, inventory: reserved })
const current = await reserved.read()
await assert.rejects(reservedManager.value.apply({
revision: current.revision,
actions: [{ name: 'alpha', action: 'enable' }],
}), /cannot be enabled/)
assert.deepEqual(reservedManager.calls, [])
})
test('rejects extension fields in every persisted User Plugin state document', () => {
assert.throws(() => userPluginStateInternals.parse({ schema: 1, disabled: [], extra: true }), /invalid/)
assert.throws(() => userPluginSnapshotInternals.parseManifest({
schema: 1,
id: 'snapshot',
source: '/data/dsh/profiles/web',
createdAt: new Date(0).toISOString(),
archiveSha256: 'a'.repeat(64),
archiveSize: 1,
extra: true,
}), /invalid/)
assert.throws(() => userPluginJournalInternals.parse({
schema: 1,
taskId: 'task',
revision: `sha256:${'a'.repeat(64)}`,
actions: [{ name: 'plugin', action: 'disable' }],
selectionPresent: false,
previousDisabled: [],
phase: 'validated',
snapshotId: null,
error: null,
recoveryResult: null,
updatedAt: new Date(0).toISOString(),
extra: true,
}), /invalid/)
})
test('does not turn successful recovery into failure when snapshot cleanup fails', async () => {
const value = await fixture()
const before = await value.inventory.read()
const reports = []
const snapshots = {
...value.snapshots,
create: (...args) => value.snapshots.create(...args),
restore: (...args) => value.snapshots.restore(...args),
remove: async () => { throw new Error('cleanup failed') },
}
const transaction = manager(value, {
snapshots,
report: async message => { reports.push(message) },
})
const result = await transaction.value.apply({
taskId: 'task-cleanup-warning', revision: before.revision,
actions: [{ name: 'alpha', action: 'disable' }],
})
assert.equal(result.status, 'success')
assert.equal((await value.journal.read()).phase, 'completed')
assert.equal(reports.includes('user-plugin.snapshot.cleanup.failed'), true)
})
@@ -0,0 +1,183 @@
import assert from 'node:assert/strict'
import { mkdtemp, mkdir, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { markUserPluginRestartState, UserPluginInventory } from '../../control-plane/modules/plugin-manager/user-inventory.mjs'
async function fixture({ dependencies, bundles, packages = {}, selection } = {}) {
const root = await mkdtemp(join(tmpdir(), 'dsh-user-plugins-'))
const profile = join(root, 'dsh/profiles/web')
const selectionPath = join(root, 'platform/state/management/user-plugins.json')
await mkdir(join(profile, 'node_modules'), { recursive: true })
await writeFile(join(profile, 'package.json'), JSON.stringify({
name: 'dsh-profile-web',
dependencies: dependencies ?? {},
dsh: { profile: { bundles: bundles ?? [] } },
}))
await writeFile(join(profile, 'pnpm-lock.yaml'), 'lockfileVersion: 9\n')
for (const [name, metadata] of Object.entries(packages)) {
const destination = join(profile, 'node_modules', ...name.split('/'))
if (metadata === 'dangling') {
await mkdir(join(destination, '..'), { recursive: true })
await symlink(join(root, 'missing-package'), destination)
continue
}
await mkdir(destination, { recursive: true })
await writeFile(join(destination, 'package.json'), typeof metadata === 'string' ? metadata : JSON.stringify({
name,
version: '1.2.3',
...metadata,
}))
}
if (selection !== undefined) {
await mkdir(join(selectionPath, '..'), { recursive: true })
await writeFile(selectionPath, JSON.stringify(selection))
}
return { root, profile, selectionPath }
}
test('inventories only profile Bundle dependencies without importing their entrypoints', async () => {
const { root, selectionPath } = await fixture({
dependencies: {
'working-plugin': '^1.2.0',
'plain-library': '2.0.0',
'git-plugin': 'github:example/plugin#main',
'local-plugin': 'file:../local-plugin',
},
bundles: ['@deepseek-ai/dsh-base', 'working-plugin', 'git-plugin'],
packages: {
'working-plugin': { description: 'Adds useful workflow tools.', dsh: { bundle: { patch: './cordis.patch.yml' } }, main: './throw-if-imported.mjs' },
'plain-library': {},
'git-plugin': { dsh: { bundle: { patch: './plugin.patch.yml' } } },
'local-plugin': { dsh: { bundle: { patch: './plugin.patch.yml' } } },
},
selection: { schema: 1, disabled: [{ name: 'local-plugin', index: 2 }] },
})
const inventory = await new UserPluginInventory({ dshHome: join(root, 'dsh'), selectionPath }).read()
assert.match(inventory.revision, /^sha256:[a-f0-9]{64}$/)
assert.deepEqual(inventory.plugins.map(plugin => [plugin.name, plugin.source, plugin.enabled, plugin.previousIndex]), [
['working-plugin', 'registry', true, null],
['git-plugin', 'git', true, null],
['local-plugin', 'file', false, 2],
])
assert.equal(inventory.plugins[0].version, '1.2.3')
assert.equal(inventory.plugins[0].description, 'Adds useful workflow tools.')
assert.equal(inventory.plugins[1].description, null)
assert.equal(inventory.plugins[0].damaged, false)
})
test('marks only user plugins which differ from the state loaded by DSH', () => {
const plugin = Object.freeze({
name: 'alpha', spec: '1.0.0', version: '1.0.0', enabled: true,
damaged: false, metadataError: null, reservedNameConflict: false,
})
const loaded = Object.freeze({ schema: 1, profile: 'web', revision: 'sha256:loaded', plugins: Object.freeze([plugin]) })
const unchanged = markUserPluginRestartState({ ...loaded, revision: 'sha256:lockfile-only' }, loaded)
assert.equal(unchanged.restartRequired, false)
assert.equal(unchanged.plugins[0].pendingRestart, false)
const added = Object.freeze({ ...plugin, name: 'beta' })
const changed = markUserPluginRestartState({
...loaded,
revision: 'sha256:changed',
plugins: Object.freeze([{ ...plugin, version: '1.1.0' }, added]),
}, loaded)
assert.equal(changed.restartRequired, true)
assert.deepEqual(changed.plugins.map(value => [value.name, value.pendingRestart]), [['alpha', true], ['beta', true]])
const removed = markUserPluginRestartState({ ...loaded, revision: 'sha256:removed', plugins: Object.freeze([]) }, loaded)
assert.equal(removed.restartRequired, true)
})
test('keeps damaged and dangling dependency metadata visible for recovery', async () => {
const { root, selectionPath } = await fixture({
dependencies: { broken: 'https://example.invalid/broken.tgz', dangling: 'link:../dangling' },
bundles: ['broken', 'dangling'],
packages: { broken: '{', dangling: 'dangling' },
})
const inventory = await new UserPluginInventory({ dshHome: join(root, 'dsh'), selectionPath }).read()
assert.deepEqual(inventory.plugins.map(plugin => [plugin.name, plugin.source, plugin.enabled, plugin.damaged]), [
['broken', 'url', true, true],
['dangling', 'file', true, true],
])
assert.match(inventory.plugins[0].metadataError, /valid JSON/)
assert.match(inventory.plugins[1].metadataError, /missing/)
})
test('keeps an enabled dependency visible when its Bundle declaration is invalid', async () => {
const { root, selectionPath } = await fixture({
dependencies: { 'startup-breaking-plugin': '1.0.0' },
bundles: ['startup-breaking-plugin'],
packages: { 'startup-breaking-plugin': { dsh: { bundle: { patch: 42 } } } },
})
const inventory = await new UserPluginInventory({ dshHome: join(root, 'dsh'), selectionPath }).read()
assert.equal(inventory.plugins.length, 1)
assert.equal(inventory.plugins[0].name, 'startup-breaking-plugin')
assert.equal(inventory.plugins[0].enabled, true)
assert.equal(inventory.plugins[0].damaged, true)
assert.match(inventory.plugins[0].metadataError, /Bundle metadata/)
})
test('uses verified Environment names for reserved conflicts instead of namespace prefixes', async () => {
const { root, selectionPath } = await fixture({
dependencies: {
'@dsh-docker/fake-external': '1.0.0',
'@dsh-docker/settings-document-editor': '1.0.0',
},
bundles: ['@dsh-docker/fake-external', '@dsh-docker/settings-document-editor'],
packages: {
'@dsh-docker/fake-external': { dsh: { bundle: { patch: './cordis.patch.yml' } } },
'@dsh-docker/settings-document-editor': {},
},
})
const inventory = await new UserPluginInventory({
dshHome: join(root, 'dsh'),
selectionPath,
systemPluginNames: async () => ['@dsh-docker/settings-document-editor'],
}).read()
assert.deepEqual(inventory.plugins.map(plugin => [plugin.name, plugin.reservedNameConflict, plugin.enabled]), [
['@dsh-docker/fake-external', false, true],
['@dsh-docker/settings-document-editor', true, false],
])
})
test('revision covers exact manifest, lockfile, and disabled-order bytes', async () => {
const { root, profile, selectionPath } = await fixture({
dependencies: { plugin: '1.0.0' },
bundles: ['plugin'],
packages: { plugin: { dsh: { bundle: { patch: './cordis.patch.yml' } } } },
})
const manager = new UserPluginInventory({ dshHome: join(root, 'dsh'), selectionPath })
const first = await manager.read()
await writeFile(join(profile, 'pnpm-lock.yaml'), 'lockfileVersion: 9\n# exact byte changed\n')
const second = await manager.read()
await mkdir(join(selectionPath, '..'), { recursive: true })
await writeFile(selectionPath, '{"schema":1,"disabled":[]}\n')
const third = await manager.read()
await rm(selectionPath)
await writeFile(join(profile, 'pnpm-lock.yaml'), '')
const emptyLockfile = await manager.read()
await rm(join(profile, 'pnpm-lock.yaml'))
const missingLockfile = await manager.read()
assert.notEqual(first.revision, second.revision)
assert.notEqual(second.revision, third.revision)
assert.notEqual(emptyLockfile.revision, missingLockfile.revision)
})
test('rejects malformed authoritative profile and selection state', async () => {
const malformed = await fixture({ dependencies: { plugin: 123 } })
await assert.rejects(
new UserPluginInventory({ dshHome: join(malformed.root, 'dsh'), selectionPath: malformed.selectionPath }).read(),
/non-empty string spec/,
)
const state = await fixture({
dependencies: { plugin: '1.0.0' },
packages: { plugin: { dsh: { bundle: { patch: './cordis.patch.yml' } } } },
selection: { schema: 1, disabled: [{ name: '../unsafe', index: 0 }] },
})
await assert.rejects(
new UserPluginInventory({ dshHome: join(state.root, 'dsh'), selectionPath: state.selectionPath }).read(),
/disabled-order entry/,
)
})
@@ -0,0 +1,33 @@
import assert from 'node:assert/strict'
import { lstat, mkdtemp, symlink } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { prepareUserWritableRoot, prepareUserWritableRoots } from '../stage0/lib/user-roots.mjs'
test('prepares custom DSH and workspace mount roots for the supervised user', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-user-roots-'))
const dshHome = join(root, 'custom-dsh')
const workspace = join(root, 'custom-workspace')
const uid = process.getuid?.()
const gid = process.getgid?.()
assert.deepEqual(await prepareUserWritableRoots({ dshHome, defaultWorkspace: workspace, uid, gid }), [dshHome, workspace])
for (const path of [dshHome, workspace]) {
const metadata = await lstat(path)
assert.equal(metadata.isDirectory(), true)
if (uid !== undefined) assert.equal(metadata.uid, uid)
if (gid !== undefined) assert.equal(metadata.gid, gid)
}
})
test('deduplicates shared roots and rejects relative, root, and symbolic-link targets', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-user-root-validation-'))
assert.deepEqual(await prepareUserWritableRoots({ dshHome: root, defaultWorkspace: root }), [root])
await assert.rejects(prepareUserWritableRoot('relative'), /absolute path/)
await assert.rejects(prepareUserWritableRoot('/'), /filesystem root/)
const target = join(root, 'target')
const link = join(root, 'link')
await prepareUserWritableRoot(target)
await symlink(target, link)
await assert.rejects(prepareUserWritableRoot(link), /must be a directory/)
})
@@ -0,0 +1,72 @@
import assert from 'node:assert/strict'
import { chmod, lstat, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { UserSkillManager } from '../../control-plane/services/management/user-skills.mjs'
import { LocalApiClient } from '../../control-plane/modules/updater/lib/client.mjs'
import { createUserSkillServer, listenUserSkills } from '../stage0/lib/user-skill-server.mjs'
async function rootOwnedFixture() {
const root = await mkdtemp(join(tmpdir(), 'dsh-user-skill-server-'))
const dshHome = join(root, 'dsh')
const agentsHome = join(root, 'agents')
const skill = join(dshHome, 'skills', 'root-owned')
await mkdir(skill, { recursive: true })
await mkdir(join(agentsHome, 'skills'), { recursive: true })
await writeFile(join(skill, 'SKILL.md'), '---\nname: root-owned\ndescription: Root-owned fixture\n---\n')
await chmod(skill, 0o755)
await chmod(join(skill, 'SKILL.md'), 0o644)
const manager = new UserSkillManager({ dshHome, agentsHome })
const server = createUserSkillServer({ manager })
const socket = join(root, 'run', 'user-skills.sock')
await listenUserSkills(server, socket)
return { root, dshHome, manager, server, socket, skill }
}
test('privileged User Skill broker validates and configures root-owned entries', async t => {
const value = await rootOwnedFixture()
t.after(async () => {
await new Promise(resolve => value.server.close(resolve))
await rm(value.root, { recursive: true, force: true })
})
const client = new LocalApiClient(value.socket)
const initial = await value.manager.list()
const entry = initial.skills[0]
const disabled = await client.request('POST', '/v1/action', {
entryId: entry.entryId,
revision: initial.revision,
action: 'disable',
})
assert.equal(disabled.skills[0].enabled, false)
assert.equal((await lstat(join(value.dshHome, 'skills/.disabled/root-owned'))).isDirectory(), true)
await assert.rejects(client.request('POST', '/v1/action', {
entryId: entry.entryId,
revision: initial.revision,
action: 'delete',
}), error => error.statusCode === 409)
const deleted = await client.request('POST', '/v1/action', {
entryId: disabled.skills[0].entryId,
revision: disabled.revision,
action: 'delete',
})
assert.deepEqual(deleted.skills, [])
})
test('privileged User Skill broker exposes no arbitrary path operation', async t => {
const value = await rootOwnedFixture()
t.after(async () => {
await new Promise(resolve => value.server.close(resolve))
await rm(value.root, { recursive: true, force: true })
})
const client = new LocalApiClient(value.socket)
await assert.rejects(client.request('POST', '/v1/action', {
entryId: `sha256:${'a'.repeat(64)}`,
revision: `sha256:${'b'.repeat(64)}`,
action: 'delete',
path: '/root',
}), error => error.statusCode === 400)
assert.equal((await lstat(value.skill)).isDirectory(), true)
})
@@ -0,0 +1,149 @@
import assert from 'node:assert/strict'
import { lstat, mkdir, readFile, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import test from 'node:test'
import { prepareUserSkillRoots, UserSkillConflictError, UserSkillManager } from '../../control-plane/services/management/user-skills.mjs'
async function writeDirectorySkill(root, entry, name = entry, description = `${name} description`) {
const path = join(root, entry)
await mkdir(path, { recursive: true })
await writeFile(join(path, 'SKILL.md'), `---\nname: ${name}\ndescription: ${description}\n---\n\nUse ${name}.\n`)
return path
}
async function fixture() {
const root = await import('node:fs/promises').then(fs => fs.mkdtemp(join(tmpdir(), 'dsh-user-skills-')))
const dshHome = join(root, 'dsh')
const agentsHome = join(root, 'agents')
await mkdir(join(dshHome, 'skills'), { recursive: true })
await mkdir(join(agentsHome, 'skills'), { recursive: true })
return { root, dshHome, agentsHome, manager: new UserSkillManager({ dshHome, agentsHome }) }
}
test('prepares real user Skill roots before privileged tools create entries', async t => {
const root = await import('node:fs/promises').then(fs => fs.mkdtemp(join(tmpdir(), 'dsh-user-skill-roots-')))
t.after(() => rm(root, { recursive: true, force: true }))
const dshHome = join(root, 'dsh')
const agentsHome = join(root, 'agents')
const roots = await prepareUserSkillRoots({ dshHome, agentsHome })
assert.deepEqual(roots, [join(dshHome, 'skills'), join(agentsHome, 'skills')])
assert.equal((await lstat(roots[0])).isDirectory(), true)
assert.equal((await lstat(roots[1])).isDirectory(), true)
assert.equal((await lstat(roots[0])).mode & 0o2777, 0o2775)
assert.equal((await lstat(roots[1])).mode & 0o2777, 0o2775)
await rm(roots[0], { recursive: true })
await symlink(root, roots[0])
await assert.rejects(prepareUserSkillRoots({ dshHome, agentsHome }), /must be a directory/)
})
test('inventories native directory and flat user skills from both user roots', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
await writeDirectorySkill(join(value.dshHome, 'skills'), 'directory-entry', 'shared-name', 'Directory guidance')
await writeFile(join(value.agentsHome, 'skills/flat-entry.md'), '---\nname: shared-name\ndescription: Flat guidance\n---\n\nFlat body.\n')
await writeFile(join(value.dshHome, 'skills/notes.txt'), 'not a skill')
await mkdir(join(value.dshHome, 'skills/.system/ignored'), { recursive: true })
const inventory = await value.manager.list()
assert.match(inventory.revision, /^sha256:[0-9a-f]{64}$/)
assert.deepEqual(inventory.skills.map(skill => ({
source: skill.source, entryName: skill.entryName, name: skill.name,
kind: skill.kind, enabled: skill.enabled, description: skill.description,
})), [
{ source: 'user-agents', entryName: 'flat-entry.md', name: 'shared-name', kind: 'file', enabled: true, description: 'Flat guidance' },
{ source: 'user-dsh', entryName: 'directory-entry', name: 'shared-name', kind: 'directory', enabled: true, description: 'Directory guidance' },
])
})
test('keeps malformed user skills visible for disable and delete', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
await mkdir(join(value.dshHome, 'skills/broken'), { recursive: true })
await writeFile(join(value.dshHome, 'skills/broken/SKILL.md'), '---\nname: Broken_Name\ndescription: broken\n---\n')
const inventory = await value.manager.list()
assert.equal(inventory.skills.length, 1)
assert.equal(inventory.skills[0].damaged, true)
assert.match(inventory.skills[0].metadataError, /name is invalid/i)
const disabled = await value.manager.configure({
entryId: inventory.skills[0].entryId,
revision: inventory.revision,
action: 'disable',
})
assert.equal(disabled.skills[0].enabled, false)
const deleted = await value.manager.configure({
entryId: disabled.skills[0].entryId,
revision: disabled.revision,
action: 'delete',
})
assert.deepEqual(deleted.skills, [])
})
test('atomically disables and enables exact entries without confusing duplicate names', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
await writeDirectorySkill(join(value.dshHome, 'skills'), 'first-entry', 'duplicate-name')
await writeDirectorySkill(join(value.agentsHome, 'skills'), 'second-entry', 'duplicate-name')
const before = await value.manager.list()
const selected = before.skills.find(skill => skill.source === 'user-dsh')
const disabled = await value.manager.configure({ entryId: selected.entryId, revision: before.revision, action: 'disable' })
assert.equal(disabled.skills.find(skill => skill.source === 'user-dsh').enabled, false)
assert.equal(disabled.skills.find(skill => skill.source === 'user-agents').enabled, true)
await assert.rejects(lstat(join(value.dshHome, 'skills/first-entry')), error => error.code === 'ENOENT')
assert.equal((await lstat(join(value.dshHome, 'skills/.disabled/first-entry'))).isDirectory(), true)
const afterManagementRestart = await new UserSkillManager({ dshHome: value.dshHome, agentsHome: value.agentsHome }).list()
assert.equal(afterManagementRestart.skills.find(skill => skill.source === 'user-dsh').enabled, false)
const disabledEntry = disabled.skills.find(skill => skill.source === 'user-dsh')
const enabled = await value.manager.configure({ entryId: disabledEntry.entryId, revision: disabled.revision, action: 'enable' })
assert.equal(enabled.skills.find(skill => skill.source === 'user-dsh').enabled, true)
assert.match(await readFile(join(value.dshHome, 'skills/first-entry/SKILL.md'), 'utf8'), /duplicate-name/)
})
test('accepts a directory skill whose SKILL.md is a symlink like native discovery', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
const sharedDocument = join(value.root, 'shared-skill.md')
await writeFile(sharedDocument, '---\nname: linked-document\ndescription: Linked document\n---\n\nLinked body.\n')
await mkdir(join(value.dshHome, 'skills/linked-document'), { recursive: true })
await symlink(sharedDocument, join(value.dshHome, 'skills/linked-document/SKILL.md'))
const inventory = await value.manager.list()
assert.equal(inventory.skills[0].name, 'linked-document')
assert.equal(inventory.skills[0].damaged, false)
})
test('rejects stale revisions and destination conflicts', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
await writeDirectorySkill(join(value.dshHome, 'skills'), 'example')
const before = await value.manager.list()
await writeDirectorySkill(join(value.agentsHome, 'skills'), 'concurrent')
await assert.rejects(value.manager.configure({
entryId: before.skills[0].entryId, revision: before.revision, action: 'disable',
}), UserSkillConflictError)
const current = await value.manager.list()
const selected = current.skills.find(skill => skill.entryName === 'example')
await mkdir(join(value.dshHome, 'skills/.disabled/example'), { recursive: true })
await assert.rejects(value.manager.configure({
entryId: selected.entryId, revision: current.revision, action: 'disable',
}), UserSkillConflictError)
})
test('deletes a symlink entry without touching its external target', async t => {
const value = await fixture()
t.after(() => rm(value.root, { recursive: true, force: true }))
const external = await writeDirectorySkill(value.root, 'external-skill', 'linked-skill')
await symlink(external, join(value.dshHome, 'skills/linked-skill'), 'dir')
const before = await value.manager.list()
assert.equal(before.skills[0].symbolicLink, true)
const after = await value.manager.configure({
entryId: before.skills[0].entryId, revision: before.revision, action: 'delete',
})
assert.deepEqual(after.skills, [])
assert.match(await readFile(join(external, 'SKILL.md'), 'utf8'), /linked-skill/)
})
@@ -0,0 +1,198 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
const workflowUrl = new URL('../../../.github/workflows/dsh-upstream-update.yml', import.meta.url)
const validationUrl = new URL('../../../.github/workflows/dsh-candidate-validation.yml', import.meta.url)
const productionUrl = new URL('../../../.github/workflows/production-publish.yml', import.meta.url)
const notificationsUrl = new URL('../../../.github/workflows/workflow-notifications.yml', import.meta.url)
const dockerUrl = new URL('../../../.github/workflows/docker.yaml', import.meta.url)
const gotifyWorkflow = 'yjrszcq/github-workflows/.github/workflows/gotify-notify.yml@c4c7fe9e17854cd4962913ac2792513eab0be988'
test('upstream workflow discovers candidates without production credentials', async () => {
const workflow = await readFile(workflowUrl, 'utf8')
assert.match(workflow, /schedule:/)
assert.match(workflow, /workflow_dispatch:/)
assert.match(workflow, /contents: write/)
assert.match(workflow, /pull-requests: write/)
assert.match(workflow, /BASE_BRANCH: dev/)
assert.match(workflow, /ref: \$\{\{ env\.BASE_BRANCH \}\}/)
assert.match(workflow, /supported-target\.mjs" advance/)
assert.match(workflow, /trusted-platform/)
assert.match(workflow, /node "\$trusted_platform\/tools\/supported-target\.mjs"/)
assert.match(workflow, /jq -r 'if \(\.changed \| type\) == "boolean" then \.changed else error\("expected boolean changed"\) end'/)
assert.doesNotMatch(workflow, /jq -er '\.changed'/)
assert.match(workflow, /candidate_remote_sha="\$\(git ls-remote --heads origin/)
assert.match(workflow, /git switch --create "\$CANDIDATE_BRANCH" "\$base_sha"/)
assert.match(workflow, /git push --force-with-lease="refs\/heads\/\$CANDIDATE_BRANCH:\$candidate_remote_sha"/)
assert.match(workflow, /git push origin/)
assert.match(workflow, /chore\(dsh\): validate/)
assert.match(workflow, /gh pr create[\s\S]*--base "\$BASE_BRANCH"/)
assert.match(workflow, /gh pr edit "\$pr_number"[\s\S]*--base "\$BASE_BRANCH"/)
assert.doesNotMatch(workflow, /github\.event\.repository\.default_branch/)
assert.doesNotMatch(workflow, /DSH_RELEASE_PRIVATE_KEY|DSH_RECOVERY|DOCKER_TOKEN/)
})
test('upstream workflow calls only the pinned reusable Gotify interface', async () => {
const workflow = await readFile(workflowUrl, 'utf8')
assert.equal(workflow.split(gotifyWorkflow).length - 1, 2)
assert.match(workflow, /gotify_url: \$\{\{ secrets\.GOTIFY_URL \}\}/)
assert.match(workflow, /gotify_token: \$\{\{ secrets\.GOTIFY_TOKEN \}\}/)
assert.doesNotMatch(workflow, /secrets: inherit/)
})
test('candidate validation is secret-free and exercises the complete current Environment', async () => {
const workflow = await readFile(validationUrl, 'utf8')
assert.match(workflow, /workflow_call:/)
assert.match(workflow, /workflow_dispatch:/)
assert.match(workflow, /pull_request_target:/)
assert.doesNotMatch(workflow, /^ pull_request:/m)
assert.match(workflow, /github\.event_name != 'pull_request_target'/)
assert.match(workflow, /github\.event\.pull_request\.head\.ref != 'automation\/dsh-upstream-candidate'/)
assert.match(workflow, /persist-credentials: false/)
assert.match(workflow, /inputs\.ref \|\| github\.event\.pull_request\.head\.sha \|\| github\.sha/)
assert.match(workflow, /permissions:\n contents: read/)
assert.match(workflow, /supported-target\.mjs validate/)
assert.match(workflow, /dist\.integrity/)
assert.match(workflow, /npm test --prefix container\/control-plane\/services\/gateway/)
assert.match(workflow, /npm test --prefix container\/platform/)
assert.match(workflow, /cache: npm/)
assert.match(workflow, /cache-dependency-path:[\s\S]*container\/control-plane\/services\/management\/package-lock\.json[\s\S]*container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/)
assert.match(workflow, /container-smoke\.sh/)
assert.match(workflow, /devtools-smoke\.sh/)
assert.doesNotMatch(workflow, /secrets\.|DSH_RELEASE_PRIVATE_KEY|DSH_RECOVERY|DOCKER_TOKEN/)
})
test('standalone candidate results notify without exposing secrets to candidate code', async () => {
const workflow = await readFile(notificationsUrl, 'utf8')
assert.match(workflow, /workflow_run:/)
assert.match(workflow, /DSH Candidate Validation/)
assert.match(workflow, /github\.event\.workflow_run\.event == 'pull_request_target'/)
assert.match(workflow, /github\.event\.workflow_run\.event == 'workflow_dispatch'/)
assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/)
assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'failure'/)
assert.match(workflow, /github\.event\.workflow_run\.head_branch != 'automation\/dsh-upstream-candidate'/)
assert.match(workflow, /github\.event\.workflow_run\.html_url/)
assert.match(workflow, /DSH 候选版本验证通过/)
assert.match(workflow, /DSH 候选版本验证失败/)
assert.match(workflow, /手动发起的 DSH 候选版本兼容性验证通过/)
assert.match(workflow, /手动发起的 DSH 候选版本兼容性验证失败/)
assert.doesNotMatch(workflow, /actions\/checkout|\brun:/)
})
test('discovery run reports candidate status without duplicate result notifications', async () => {
const workflow = await readFile(workflowUrl, 'utf8')
assert.match(workflow, /uses: \.\/\.github\/workflows\/dsh-candidate-validation\.yml/)
assert.match(workflow, /statuses: write/)
assert.match(workflow, /gh pr comment "\$PR_NUMBER" \\\n+\s+--repo "\$GITHUB_REPOSITORY"/)
assert.match(workflow, /DSH candidate Runtime/)
assert.match(workflow, /notify-discovered:[\s\S]*发现 DSH 上游新版本/)
assert.match(workflow, /notify-result:[\s\S]*DSH 上游检查失败/)
assert.match(workflow, /候选版本验证通过/)
assert.match(workflow, /候选版本验证失败/)
assert.doesNotMatch(workflow, /notify-validation-passed:|notify-validation-failed:/)
})
test('production publication owns signing, advances an append-only channel, and releases only Environment versions', async () => {
const workflow = await readFile(productionUrl, 'utf8')
assert.match(workflow, /branches:\n - main/)
assert.match(workflow, /release\/supported-target\.json/)
assert.match(workflow, /release\/official-dsh-policy\.json/)
assert.match(workflow, /environment: production-release/)
assert.match(workflow, /if: github\.ref == 'refs\/heads\/main'/)
assert.match(workflow, /DSH_RELEASE_PRIVATE_KEY/)
assert.match(workflow, /prepare-release\.mjs/)
assert.match(workflow, /environment-release\.mjs/)
assert.match(workflow, /cache: npm/)
assert.match(workflow, /cache-dependency-path:[\s\S]*container\/control-plane\/services\/management\/package-lock\.json[\s\S]*container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/)
assert.match(workflow, /refs\/heads\/release-channel/)
assert.match(workflow, /sequence=1/)
assert.match(workflow, /current_sequence \+ 1/)
assert.match(workflow, /previous="\$channel\/targets\/\$current_sequence"/)
assert.match(workflow, /test -d "\$previous"/)
assert.match(workflow, /test -f "\$previous\/\$name"/)
assert.match(workflow, /cmp "\$channel\/\$name" "\$previous\/\$name"/)
assert.match(workflow, /release-channel\/targets\/\$\{TARGET_SEQUENCE\}/)
assert.match(workflow, /test ! -e "\$target"/)
assert.match(workflow, /tag="v\$\{ENVIRONMENT_VERSION\}"/)
assert.match(workflow, /--title "\$ENVIRONMENT_TAG"/)
assert.doesNotMatch(workflow, /--title "DSH Docker Environment/)
assert.match(workflow, /cmp "\$RUNNER_TEMP\/environment-release\.json"/)
assert.match(workflow, /--draft/)
assert.match(workflow, /--draft=false/)
assert.match(workflow, /--latest/)
assert.match(workflow, /--json isDraft/)
assert.match(workflow, /cp "\$RUNNER_TEMP\/environment-release\.json" "\$assets\/"/)
assert.match(workflow, /prune_environment_assets\(\)/)
assert.match(workflow, /gh release delete-asset "\$ENVIRONMENT_TAG" "\$name" --yes/)
assert.match(workflow, /test "\$name" != environment-release\.json/)
assert.doesNotMatch(workflow, /bootstrap\.manifest\.json bootstrap\.manifest\.sig\.json/)
assert.doesNotMatch(workflow, /\.artifacts\[\]\.url/)
assert.doesNotMatch(workflow, /environment-v\$\{ENVIRONMENT_VERSION\}\.tar\.gz/)
assert.doesNotMatch(workflow, /uses: \.\/\.github\/workflows\/docker\.yaml/)
assert.doesNotMatch(workflow, /environment: production-image|DOCKER_TOKEN/)
assert.equal(workflow.split(gotifyWorkflow).length - 1, 0)
assert.doesNotMatch(workflow, /platform-\$\{TARGET_SEQUENCE\}|DSH Platform \$\{TARGET_SEQUENCE\}/)
assert.doesNotMatch(workflow, /RECOVERY_PRIVATE|secrets: inherit/)
})
test('successful signed targets notify independently from image approval', async () => {
const workflow = await readFile(notificationsUrl, 'utf8')
assert.match(workflow, /workflow_run:/)
assert.match(workflow, /Publish Supported Platform Target/)
assert.match(workflow, /github\.event\.workflow_run\.name == 'Publish Supported Platform Target'/)
assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/)
assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'failure'/)
assert.match(workflow, /DSH 正式发布失败/)
assert.match(workflow, /production-image/)
assert.match(workflow, /actions\/workflows\/docker\.yaml/)
assert.equal(workflow.split(gotifyWorkflow).length - 1, 1)
assert.equal((workflow.match(/^ notify-result:/gm) ?? []).length, 1)
assert.doesNotMatch(workflow, /actions\/checkout|\brun:/)
})
test('Docker publication consumes one signed channel target and mirrors only standard images to GHCR', async () => {
const workflow = await readFile(dockerUrl, 'utf8')
assert.match(workflow, /workflow_run:/)
assert.match(workflow, /Publish Supported Platform Target/)
assert.match(workflow, /github\.event\.workflow_run\.conclusion == 'success'/)
assert.match(workflow, /github\.event\.workflow_run\.head_sha/)
assert.match(workflow, /environment: production-image/)
assert.match(workflow, /contents: read\n packages: write/)
assert.match(workflow, /git -C channel log --format=%H -- channel\.json/)
assert.match(workflow, /No signed release-channel target matches source commit/)
assert.match(workflow, /latestSupportedDsh/)
assert.match(workflow, /channel\/targets\/\$sequence/)
assert.match(workflow, /verify-image-release\.mjs/)
assert.equal((workflow.match(/SIGNED_IMAGE_INPUT=true/g) ?? []).length, 4)
assert.match(workflow, /PLATFORM_REVISION=\$\{\{ steps\.channel\.outputs\.source_commit \}\}/)
assert.match(workflow, /ENVIRONMENT_VERSION=\$\{\{ steps\.signed-target\.outputs\.environment_version \}\}/)
assert.match(workflow, /TARGET_SEQUENCE=\$\{\{ steps\.signed-target\.outputs\.sequence \}\}/)
assert.match(workflow, /cache: npm/)
assert.match(workflow, /cache-dependency-path:[\s\S]*source\/container\/control-plane\/services\/management\/package-lock\.json[\s\S]*source\/container\/environment\/resources\/plugins\/platform-management\/package\/package-lock\.json/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --prefix container\/control-plane\/services\/management/)
assert.match(workflow, /npm ci --omit=dev --ignore-scripts --no-audit --no-fund --legacy-peer-deps --prefix container\/environment\/resources\/plugins\/platform-management\/package/)
assert.match(workflow, /DOCKERHUB_IMAGE: szcq\/deepseek-harness/)
assert.match(workflow, /GHCR_IMAGE: ghcr\.io\/\$\{\{ github\.repository \}\}/)
assert.match(workflow, /\$\{GHCR_IMAGE\}:\$\{ENVIRONMENT_VERSION\}/)
assert.match(workflow, /\$\{GHCR_IMAGE\}:\$\{major\}\.\$\{minor\}/)
assert.match(workflow, /\$\{GHCR_IMAGE\}:dsh-\$\{DSH_VERSION\}/)
assert.match(workflow, /\$\{DOCKERHUB_IMAGE\}:\$\{DSH_VERSION\}-devtools/)
const versionedDevtools = workflow.indexOf('- name: Push versioned devtools image to Docker Hub')
const versionedStandard = workflow.indexOf('- name: Push versioned standard image to Docker Hub and GHCR')
const rollingTags = workflow.indexOf('- name: Promote Docker Hub rolling tags')
assert.ok(versionedDevtools >= 0)
assert.ok(versionedDevtools < versionedStandard)
assert.ok(versionedStandard < rollingTags)
const promotion = workflow.slice(rollingTags, workflow.indexOf('- name:', rollingTags + 1))
assert.ok(promotion.indexOf(':latest-devtools"') < promotion.indexOf(':latest"'))
assert.equal(workflow.split(gotifyWorkflow).length - 1, 1)
assert.match(workflow, /notify-result:[\s\S]*needs\.build\.result == 'success'[\s\S]*needs\.build\.result == 'failure'/)
assert.match(workflow, /DSH 镜像发布失败/)
assert.doesNotMatch(workflow, /\$\{GHCR_IMAGE\}:[^\n]*devtools/)
assert.doesNotMatch(workflow, /workflow_call:|gh release|DSH_RELEASE_PRIVATE_KEY|prepare-release\.mjs/)
})