mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The root manifest carries the dsh family version. bump writes it with the members, because the workspace constraint requires them to match, and that constraint now accepts a prerelease segment: without both, release:dsh 0.0.2 left the root behind and 0.0.1-rc.1 could satisfy neither check. The Landlock workflow no longer passes --access public, which overrode the restricted publishConfig this repository just adopted for those packages. Vendored change detection reads build inputs when a package publishes build output, and vendor/cordis publishes the src its export map already pointed at: its lib/ is untracked, so a real source edit read as 'nothing changed' and the next publish would fail on a version whose bytes moved. The next version also takes the last published version as its baseline, so a re-sync that restores a lower upstream version cannot recompute a version already on the registry, and bump confirms the registry carries what the newest tag names. Tag prefixes are constructed rather than recovered from a full tag, which a hyphenated version defeated. Pack runs group per ref so concurrent pull requests stop displacing each other, the publish job carries the global group, and the unused id-token permission is gone. Every release script sits behind an entry guard, which is what lets the pure judgements carry tests: tag naming, publish order and cycle reporting, version arithmetic, payload policy, and the change judgement. The Agent Note moves to implemented and states what shipped: one probe command, the registry confirmation that now exists, and byte reproducibility recorded as assumed rather than measured.
109 lines
4.9 KiB
TypeScript
109 lines
4.9 KiB
TypeScript
/**
|
|
* Install packed tarballs into a throwaway consumer outside the repository and
|
|
* drive the installed executable with plain Node.
|
|
*
|
|
* Every tarball the installed tree needs comes from `--from`, so the only
|
|
* registry traffic is for external dependencies. That matters beyond hermetic
|
|
* verification: the harness packages declare the vendored framework as a peer,
|
|
* and those packages live in another release sequence that this credential-free
|
|
* job cannot fetch from a private registry — so a dsh verification passes the
|
|
* vendored family's pack output too, while publishing only its own
|
|
* ([rationale](../../.agents/notes/implemented/process/2026-08-10-npm-release-sequences.md)).
|
|
*
|
|
* What this proves is that `files` selected a complete payload and that the
|
|
* published dependency ranges resolve. A workspace link or a stale `lib/` in the
|
|
* checkout cannot stand in for a missing file here.
|
|
*/
|
|
|
|
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join, resolve } from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
import { parseArgs } from 'node:util'
|
|
import { releaseFamily } from './families.ts'
|
|
import { capture, isEntry } from './process.ts'
|
|
import { packedIdentity, readPublishOrder } from './tarball.ts'
|
|
|
|
/**
|
|
* Environment for the installed artifact: no host Node hooks, no host DeepSeek
|
|
* Harness home, and no ambient npm user agent that would confuse npm.
|
|
* @param consumerRoot - the throwaway consumer directory.
|
|
* @returns The child environment.
|
|
*/
|
|
function consumerEnvironment(consumerRoot: string): NodeJS.ProcessEnv {
|
|
const environment = { ...process.env }
|
|
delete environment.npm_config_user_agent
|
|
delete environment.NPM_CONFIG_USER_AGENT
|
|
delete environment.NODE_OPTIONS
|
|
delete environment.NODE_PATH
|
|
environment.DSH_HOME = resolve(consumerRoot, '.dsh')
|
|
environment.DSH_AGENTS_HOME = resolve(consumerRoot, '.agents')
|
|
environment.DSH_TELEMETRY_DISABLED = '1'
|
|
return environment
|
|
}
|
|
|
|
/**
|
|
* Every packed tarball in the given directories, as `file:` dependency entries.
|
|
* @param directories - absolute pack output directories.
|
|
* @returns Package name to tarball file URL, and the version each carries.
|
|
*/
|
|
function packedDependencies(directories: readonly string[]): Map<string, { url: string; version: string }> {
|
|
const dependencies = new Map<string, { url: string; version: string }>()
|
|
for (const directory of directories) {
|
|
for (const filename of readPublishOrder(directory)) {
|
|
const tarball = join(directory, filename)
|
|
const { name, version } = packedIdentity(tarball)
|
|
dependencies.set(name, { url: pathToFileURL(tarball).href, version })
|
|
}
|
|
}
|
|
return dependencies
|
|
}
|
|
|
|
/** Install every tarball under `--from` and drive the `--family` entry. */
|
|
function main(): void {
|
|
const { values } = parseArgs({
|
|
options: { family: { type: 'string' }, from: { type: 'string', multiple: true } },
|
|
allowPositionals: false,
|
|
})
|
|
if (values.family === undefined || values.from === undefined || values.from.length === 0) {
|
|
throw new Error('usage: verify-packed-install.ts --family <dsh|vendor> --from <packed directory> [--from ...]')
|
|
}
|
|
|
|
const family = releaseFamily(values.family)
|
|
const entry = family.installedEntry
|
|
if (entry === undefined) {
|
|
console.log(`release verify-packed-install: family ${family.id} publishes no executable, nothing to drive`)
|
|
return
|
|
}
|
|
|
|
const root = process.cwd()
|
|
const packed = packedDependencies(values.from.map(directory => resolve(root, directory)))
|
|
const expected = packed.get(entry.packageName)
|
|
if (expected === undefined) throw new Error(`${entry.packageName} is not among the packed tarballs`)
|
|
|
|
const consumerRoot = mkdtempSync(join(tmpdir(), `dsh-packed-${family.id}-`))
|
|
try {
|
|
writeFileSync(join(consumerRoot, 'package.json'), `${JSON.stringify({
|
|
name: `dsh-packed-install-${family.id}`,
|
|
version: '0.0.0',
|
|
private: true,
|
|
dependencies: Object.fromEntries([...packed].map(([name, entryPacked]) => [name, entryPacked.url])),
|
|
}, null, 2)}\n`)
|
|
|
|
const environment = consumerEnvironment(consumerRoot)
|
|
console.log(`release verify-packed-install: installing ${String(packed.size)} tarball(s) into ${consumerRoot}`)
|
|
capture('npm', ['install', '--no-audit', '--no-fund', '--package-lock=false'], { cwd: consumerRoot, env: environment })
|
|
|
|
const bin = join(consumerRoot, 'node_modules', ...entry.packageName.split('/'), entry.binPath)
|
|
const version = capture(process.execPath, [bin, '--version'], { cwd: consumerRoot, env: environment })
|
|
if (version !== expected.version) {
|
|
throw new Error(`installed ${entry.packageName} --version reported ${JSON.stringify(version)}, expected ${expected.version}`)
|
|
}
|
|
console.log(`release verify-packed-install: installed ${entry.packageName} reports ${version}`)
|
|
} finally {
|
|
rmSync(consumerRoot, { recursive: true, force: true })
|
|
}
|
|
}
|
|
|
|
if (isEntry(import.meta.url)) main()
|