/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { createHash } from 'node:crypto'; import { chmodSync, copyFileSync, existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from 'node:fs'; import { tmpdir } from 'node:os'; import { basename, dirname, join } from 'node:path'; import { describe, test } from 'node:test'; import { createSourceCandidate, controlledProcessEnvironment, parseSha512File, reproduceSourceCandidate, signSourceCandidate, sourceCandidateIdentity, validateArchiveEntries, validateGpgVerificationStatus, validatePackageVersions, verifySourceCandidate, } from './asf-source-release.mjs'; describe('ASF source release identity', () => { test('uses the incubating source distribution name for plain versions only', () => { assert.deepEqual(sourceCandidateIdentity('0.1.12'), { archiveName: 'apache-maka-0.1.12-incubating-src.tar.gz', rootDirectory: 'apache-maka-0.1.12-incubating', version: '0.1.12', }); assert.throws(() => sourceCandidateIdentity('0.1.12-incubating'), /Invalid release version/); }); }); describe('ASF source release verification', () => { test('validates checksum identity and archive boundaries', () => { const name = 'apache-maka-0.1.12-incubating-src.tar.gz'; assert.equal(parseSha512File(`${'a'.repeat(128)} ${name}\n`, name), 'a'.repeat(128)); assert.throws(() => parseSha512File(`${'a'.repeat(128)} another.tar.gz\n`, name), /expected/); const root = 'apache-maka-0.1.12-incubating'; assert.doesNotThrow(() => validateArchiveEntries( [ `${root}/`, `${root}/DISCLAIMER-WIP`, `${root}/LICENSE`, `${root}/NOTICE`, `${root}/package-lock.json`, `${root}/package.json`, `${root}/src/index.ts`, ], root, ), ); assert.throws( () => validateArchiveEntries( [ `${root}/DISCLAIMER-WIP`, `${root}/LICENSE`, `${root}/NOTICE`, `${root}/package-lock.json`, `${root}/package.json`, `${root}/.maka-shots/review.png`, `${root}/node_modules/dependency/index.js`, ], root, ), /Forbidden archive entry/, ); assert.throws( () => validateArchiveEntries( [ `${root}/DISCLAIMER-WIP`, `${root}/LICENSE`, `${root}/NOTICE`, `${root}/package-lock.json`, `${root}/package.json`, `${root}/fixtures/evil.bin`, `${root}/fixtures/EVIL.BIN`, ], root, ), /Cross-platform archive entry collision/, ); }); test('requires one current valid GPG signature status', () => { const fingerprint = 'A'.repeat(40); assert.deepEqual( validateGpgVerificationStatus( `[GNUPG:] GOODSIG ABCDEF0123456789 Release Test\n[GNUPG:] VALIDSIG ${fingerprint} 2026-08-20 1787193600 0 4 0 1 10 00 ${fingerprint}\n`, ), { fingerprint, hashAlgorithm: 10 }, ); for (const status of ['EXPKEYSIG', 'EXPSIG', 'KEYEXPIRED', 'KEYREVOKED', 'REVKEYSIG']) { assert.throws( () => validateGpgVerificationStatus( `[GNUPG:] ${status} ABCDEF0123456789 Release Test\n[GNUPG:] GOODSIG ABCDEF0123456789 Release Test\n[GNUPG:] VALIDSIG ${fingerprint} 2026-08-20 1787193600 0 4 0 1 10 00 ${fingerprint}\n`, ), new RegExp(status), ); } }); test('requires package and lockfile versions to share one identity', () => { const packageJson = { version: '0.1.12' }; const packageLock = { packages: { '': { version: '0.1.12' } }, version: '0.1.12' }; assert.doesNotThrow(() => validatePackageVersions({ packageJson, packageLock, source: 'fixture', version: '0.1.12' }), ); assert.throws( () => validatePackageVersions({ packageJson, packageLock: { ...packageLock, version: '9.9.9' }, source: 'fixture', version: '0.1.12', }), /package-lock\.json.*9\.9\.9/, ); }); test('rejects Category X dependencies from a nested package lockfile', async () => { const fixture = createFixtureCandidate({ 'tools/runtime/package.json': `${JSON.stringify({ name: 'runtime', private: true, license: 'Apache-2.0' })}\n`, 'tools/runtime/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, name: 'runtime', packages: { '': { name: 'runtime', license: 'Apache-2.0' }, 'node_modules/category-x-runtime': { version: '1.0.0', license: 'LGPL-3.0-or-later', }, }, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Category X.*category-x-runtime.*LGPL-3\.0-or-later/, ); } finally { fixture.cleanup(); } }); test('accepts a classified dependency from a nested package lockfile', async () => { const fixture = createFixtureCandidate({ 'tools/source/package.json': `${JSON.stringify({ dependencies: { 'source-helper': '1.0.0' }, name: 'source', private: true, })}\n`, 'tools/source/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, name: 'source', packages: { '': { name: 'source', license: 'Apache-2.0' }, 'node_modules/source-helper': { version: '1.0.0', license: 'MIT' }, }, })}\n`, }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('rejects an unclassified dependency from a nested package lockfile', async () => { const fixture = createFixtureCandidate({ 'tools/unknown/package.json': `${JSON.stringify({ name: 'unknown', private: true, license: 'Apache-2.0' })}\n`, 'tools/unknown/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, name: 'unknown', packages: { '': { name: 'unknown', license: 'Apache-2.0' }, 'node_modules/unknown-runtime': { version: '1.0.0' }, }, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify unknown-runtime@1\.0\.0.*tools\/unknown\/package-lock\.json/, ); } finally { fixture.cleanup(); } }); test('accepts an unlicensed private manifest without dependencies', async () => { const fixture = createFixtureCandidate({ 'tools/profile/package.json': `${JSON.stringify({ name: 'profile', private: true })}\n`, }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('rejects unlicensed private manifests whose dependencies lack lock provenance', async () => { const dependencyDeclarations = { bundleDependencies: ['runtime-helper'], bundledDependencies: ['runtime-helper'], dependencies: { 'runtime-helper': '1.0.0' }, devDependencies: { 'runtime-helper': '1.0.0' }, optionalDependencies: { 'runtime-helper': '1.0.0' }, peerDependencies: { 'runtime-helper': '1.0.0' }, }; for (const [field, declaration] of Object.entries(dependencyDeclarations)) { const fixture = createFixtureCandidate({ [`tools/${field}/package.json`]: `${JSON.stringify({ [field]: declaration, name: field, private: true, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), new RegExp( `Cannot safely classify.*${field}.*without (?:matching )?lock provenance`, 'u', ), ); } finally { fixture.cleanup(); } } }); test('does not accept arbitrary notice files as dependency license authority', async () => { const fixture = createFixtureCandidate({ 'tools/runtime/THIRD_PARTY_NOTICES.txt': 'Package: unknown-runtime@1.0.0\nSelected license: MIT\n', 'tools/runtime/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'runtime' }, 'node_modules/unknown-runtime': { version: '1.0.0' }, }, })}\n`, 'tools/runtime/package.json': `${JSON.stringify({ dependencies: { 'unknown-runtime': '1.0.0' }, license: 'Apache-2.0', name: 'runtime', private: true, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify unknown-runtime@1\.0\.0/, ); } finally { fixture.cleanup(); } }); test('uses the generated npm notice as the dependency license authority', async () => { const fixture = createFixtureCandidate({ 'apps/desktop/resources/licenses/npm/THIRD_PARTY_NOTICES.txt': 'Package: source-helper@1.0.0\nSelected license: MIT\n', 'tools/source/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'source' }, 'node_modules/source-helper': { version: '1.0.0' }, }, })}\n`, 'tools/source/package.json': `${JSON.stringify({ dependencies: { 'source-helper': '1.0.0' }, name: 'source', private: true, })}\n`, }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('does not let lock metadata override a Category X generated notice', async () => { const fixture = createFixtureCandidate({ 'apps/desktop/resources/licenses/npm/THIRD_PARTY_NOTICES.txt': 'Package: disguised-runtime@1.0.0\nSelected license: GPL-3.0-only\n', 'tools/runtime/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'runtime' }, 'node_modules/disguised-runtime': { license: 'MIT', version: '1.0.0' }, }, })}\n`, 'tools/runtime/package.json': `${JSON.stringify({ dependencies: { 'disguised-runtime': '1.0.0' }, license: 'Apache-2.0', name: 'runtime', private: true, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Category X.*disguised-runtime.*GPL-3\.0-only/, ); } finally { fixture.cleanup(); } }); test('rejects lock links without a candidate-owned workspace target', async () => { const fixture = createFixtureCandidate({ 'tools/runtime/package-lock.json': `${JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'runtime' }, 'node_modules/evil-runtime': { link: true, resolved: '../../evil-runtime' }, }, })}\n`, 'tools/runtime/package.json': `${JSON.stringify({ license: 'Apache-2.0', name: 'runtime' })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify workspace link.*evil-runtime/, ); } finally { fixture.cleanup(); } }); test('rejects Category X metadata on workspace package lock entries', async () => { const fixture = createFixtureCandidate({ 'packages/evil/package.json': `${JSON.stringify({ license: 'Apache-2.0', name: 'evil', version: '1.0.0', })}\n`, 'package-lock.json': `${JSON.stringify({ lockfileVersion: 3, name: 'maka', packages: { '': { name: 'maka', version: '0.1.12' }, 'packages/evil': { license: 'GPL-3.0-only', name: 'evil', version: '1.0.0' }, }, version: '0.1.12', })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Category X.*packages\/evil.*GPL-3\.0-only/, ); } finally { fixture.cleanup(); } }); test('binds licensed manifest dependencies to a package lock closure', async () => { const fixture = createFixtureCandidate({ 'tools/runtime/package.json': `${JSON.stringify({ dependencies: { 'unlocked-runtime': '1.0.0' }, license: 'Apache-2.0', name: 'runtime', private: true, })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify.*tools\/runtime\/package\.json.*without (?:matching )?lock provenance/, ); } finally { fixture.cleanup(); } }); test('rejects unsupported npm lockfile versions', async () => { const fixture = createFixtureCandidate({ 'tools/runtime/package-lock.json': `${JSON.stringify({ lockfileVersion: 99, packages: { '': { name: 'runtime' } }, })}\n`, 'tools/runtime/package.json': `${JSON.stringify({ license: 'Apache-2.0', name: 'runtime' })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Unsupported npm lockfile version 99/, ); } finally { fixture.cleanup(); } }); test('classifies dependencies from a nested npm shrinkwrap', async () => { const fixture = createFixtureCandidate({ 'tools/source/npm-shrinkwrap.json': `${JSON.stringify({ lockfileVersion: 3, packages: { '': { name: 'source' }, 'node_modules/source-helper': { license: 'MIT', version: '1.0.0' }, }, })}\n`, 'tools/source/package.json': `${JSON.stringify({ dependencies: { 'source-helper': '1.0.0' }, name: 'source', private: true, })}\n`, }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('rejects unsupported nested package manager lockfiles', async () => { for (const [name, contents] of [ ['pnpm-lock.yaml', 'lockfileVersion: 9\n'], ['yarn.lock', '# yarn lockfile v1\n'], ]) { const fixture = createFixtureCandidate({ [`tools/source/${name}`]: contents }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify unsupported package lockfile/, ); } finally { fixture.cleanup(); } } }); test('rejects Category X and unknown nested package manifest licenses', async () => { for (const [license, expected] of [ ['AGPL-3.0-only', /Category X/], ['LicenseRef-Unknown', /Cannot safely classify license/], ]) { const fixture = createFixtureCandidate({ 'tools/source/package.json': `${JSON.stringify({ license, name: 'source' })}\n`, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), expected, ); } finally { fixture.cleanup(); } } }); test('rejects compiled artifacts regardless of their file extension', async () => { const formats = new Map([ ['ELF', Buffer.from([0x7f, 0x45, 0x4c, 0x46])], ['Mach-O', Buffer.from([0xfe, 0xed, 0xfa, 0xcf])], ['Mach-O fat little-endian', Buffer.from([0xbe, 0xba, 0xfe, 0xca])], ['Mach-O fat64 little-endian', Buffer.from([0xbf, 0xba, 0xfe, 0xca])], ['PE', Buffer.from('MZ')], ['WASM', Buffer.from([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00])], ['ZIP/JAR', Buffer.from([0x50, 0x4b, 0x03, 0x04])], ['thin ar archive', Buffer.from('!\n')], ]); for (const [format, bytes] of formats) { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `fixtures/runtime.dat`: a claimed fixture.\n', 'fixtures/runtime.dat': bytes, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), new RegExp(`Compiled artifact.*fixtures/runtime\\.dat.*${format.replace('/', '\\/')}`), ); } finally { fixture.cleanup(); } } }); test('rejects ZIP payloads hidden behind an allowed source prefix', async () => { for (const bytes of [ Buffer.concat([Buffer.from('source preface\n'), Buffer.from([0x50, 0x4b, 0x03, 0x04])]), Buffer.concat([ Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), Buffer.from([0x50, 0x4b, 0x03, 0x04]), ]), ]) { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `fixtures/runtime.dat`: a claimed fixture.\n', 'fixtures/runtime.dat': bytes, }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /forbidden ZIP\/JAR content/, ); } finally { fixture.cleanup(); } } }); test('accepts an inventoried source image', async () => { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `fixtures/*.png`: test-generated source images.\n', 'fixtures/source.png': Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('accepts an inventoried non-text source fixture', async () => { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `fixtures/control.ts`: a raw control-character fixture.\n', 'fixtures/control.ts': Buffer.from([0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x78, 0x00]), }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('rejects unknown non-text release inputs', async () => { const fixture = createFixtureCandidate({ 'fixtures/unknown.bin': Buffer.from([0x01, 0x02]) }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify non-text release input.*fixtures\/unknown\.bin/, ); } finally { fixture.cleanup(); } }); test('rejects unknown binary paths even when their bytes are valid UTF-8', async () => { const fixture = createFixtureCandidate({ 'fixtures/unknown.bin': Buffer.from('printable but still an unknown binary input'), }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify non-text release input.*fixtures\/unknown\.bin/, ); } finally { fixture.cleanup(); } }); test('keeps provenance inventory entries inside their Markdown section', async () => { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n## Another section\n\n- `fixtures/unknown.bin`: outside the inventory.\n', 'fixtures/unknown.bin': Buffer.from([0x01, 0x02]), }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Cannot safely classify non-text release input.*fixtures\/unknown\.bin/, ); } finally { fixture.cleanup(); } }); test('rejects provenance patterns without a fixed path prefix', async () => { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `**`: overbroad inventory.\n', 'fixtures/unknown.bin': Buffer.from([0x01, 0x02]), }); try { await assert.rejects( () => verifySourceCandidate({ archivePath: fixture.archivePath }), /Unsafe source archive inventory pattern/, ); } finally { fixture.cleanup(); } }); test('allows a double-star inventory to match zero nested directories', async () => { const fixture = createFixtureCandidate({ 'docs/code-origin-audit.md': '### Source archive non-text inventory\n\n- `docs/images/**/*.png`: reviewed screenshots.\n', 'docs/images/root.png': Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), }); try { await assert.doesNotReject(() => verifySourceCandidate({ archivePath: fixture.archivePath })); } finally { fixture.cleanup(); } }); test('filters controlled environment names case-insensitively', async () => { await withEnvironmentVariables( { gIt_Prefix_Probe: 'prefix', mAkA_Exact_Probe: 'exact' }, () => { const environment = controlledProcessEnvironment({ excludedNames: ['MAKA_EXACT_PROBE'], excludedPrefixes: ['GIT_'], overrides: { GIT_CONFIG_NOSYSTEM: '1' }, }); const names = Object.keys(environment).map((name) => name.toUpperCase()); assert.equal(names.includes('MAKA_EXACT_PROBE'), false); assert.equal(names.includes('GIT_PREFIX_PROBE'), false); assert.equal(environment.GIT_CONFIG_NOSYSTEM, '1'); }, ); }); test('requires a signature before reading unauthenticated candidate metadata', async () => { const temporaryRoot = mkdtempSync(join(tmpdir(), 'maka-asf-auth-order-test-')); const identity = sourceCandidateIdentity('0.1.12'); const archivePath = join(temporaryRoot, identity.archiveName); try { writeFileSync(archivePath, 'not a tar archive\n'); const keysPath = join(temporaryRoot, 'KEYS'); writeFileSync(keysPath, ''); await assert.rejects( () => verifySourceCandidate({ archivePath, keysPath }), /Detached signature does not exist/, ); } finally { rmSync(temporaryRoot, { force: true, recursive: true }); } }); test('documents the checkout-only DeepSeek Harness toolchain build in the candidate', async () => { const temporaryRoot = mkdtempSync(join(tmpdir(), 'maka-asf-dsh-contract-test-')); const repositoryRoot = join(temporaryRoot, 'repository'); const outputDirectory = join(temporaryRoot, 'release'); const identity = sourceCandidateIdentity('0.1.12'); try { writeReleaseContents(repositoryRoot, { includeAttributes: true }); mkdirSync(join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain'), { recursive: true, }); mkdirSync(join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-profile'), { recursive: true, }); mkdirSync(join(repositoryRoot, 'scripts'), { recursive: true }); copyFileSync( join(import.meta.dirname, '../packages/eval/README.md'), join(repositoryRoot, 'packages/eval/README.md'), ); writeFileSync( join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain/package.json'), '{}\n', ); writeFileSync( join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain/package-lock.json'), '{}\n', ); writeFileSync( join(repositoryRoot, 'scripts/prepare-deepseek-harness-toolchain.mjs'), 'export {};\n', ); for (const name of ['package.json', 'cordis.patch.yml']) { copyFileSync( join(import.meta.dirname, `../packages/eval/harbor/deepseek-harness-profile/${name}`), join(repositoryRoot, `packages/eval/harbor/deepseek-harness-profile/${name}`), ); } git(repositoryRoot, ['init']); git(repositoryRoot, ['add', '.']); commitFixture(repositoryRoot, 'test DSH source archive contract'); const candidate = await createSourceCandidate({ outputDirectory, repositoryRoot, version: '0.1.12', }); const entries = execFileSync('tar', ['-tzf', candidate.archivePath], { encoding: 'utf8' }); const archivedReadme = execFileSync( 'tar', ['-xOzf', candidate.archivePath, `${identity.rootDirectory}/packages/eval/README.md`], { encoding: 'utf8' }, ); assert.doesNotMatch(entries, /deepseek-harness-toolchain\/package(?:-lock)?\.json/); assert.match(entries, /scripts\/prepare-deepseek-harness-toolchain\.mjs/); for (const name of ['package.json', 'cordis.patch.yml']) { const relativePath = `packages/eval/harbor/deepseek-harness-profile/${name}`; assert.deepEqual( execFileSync('tar', [ '-xOzf', candidate.archivePath, `${identity.rootDirectory}/${relativePath}`, ]), readFileSync(join(repositoryRoot, relativePath)), ); } assert.match(archivedReadme, /only from a complete Git checkout/u); assert.match(archivedReadme, /intentionally excluded from ASF source archives/u); } finally { rmSync(temporaryRoot, { force: true, recursive: true }); } }); test('creates reproducible candidates from committed files only', async () => { const temporaryRoot = mkdtempSync(join(tmpdir(), 'maka-asf-source-test-')); const repositoryRoot = join(temporaryRoot, 'repository'); const firstOutput = join(temporaryRoot, 'first'); const hostileOutput = join(temporaryRoot, 'hostile'); mkdirSync(repositoryRoot, { recursive: true }); try { writeReleaseContents(repositoryRoot, { includeAttributes: true }); writeFileSync(join(repositoryRoot, '.gitignore'), 'untracked.txt\n'); writeFileSync(join(repositoryRoot, 'README.md'), 'release fixture\n'.repeat(4096)); writeFileSync(join(repositoryRoot, 'untracked.txt'), 'must not be released\n'); mkdirSync(join(repositoryRoot, '.claude')); mkdirSync(join(repositoryRoot, '.maka-shots')); writeFileSync(join(repositoryRoot, '.claude/launch.json'), '{}\n'); writeFileSync(join(repositoryRoot, '.maka-shots/review.png'), 'review evidence\n'); writeFileSync(join(repositoryRoot, 'maka-proposal-zh-review.txt'), 'working notes\n'); mkdirSync(join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain'), { recursive: true, }); mkdirSync(join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-profile'), { recursive: true, }); writeFileSync( join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain/package-lock.json'), '{}\n', ); writeFileSync( join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain/package.json'), '{}\n', ); writeFileSync( join( repositoryRoot, 'packages/eval/harbor/deepseek-harness-toolchain/patch-subprocess-local.mjs', ), 'export {};\n', ); writeFileSync( join(repositoryRoot, 'packages/eval/harbor/deepseek-harness-profile/cordis.yml'), 'profile: maka-eval\n', ); git(repositoryRoot, ['init']); git(repositoryRoot, [ 'add', 'package.json', 'package-lock.json', 'DISCLAIMER-WIP', 'LICENSE', 'NOTICE', '.gitignore', '.gitattributes', 'README.md', '.claude/launch.json', '.maka-shots/review.png', 'maka-proposal-zh-review.txt', 'packages/eval/harbor/deepseek-harness-toolchain/package-lock.json', 'packages/eval/harbor/deepseek-harness-toolchain/package.json', 'packages/eval/harbor/deepseek-harness-toolchain/patch-subprocess-local.mjs', 'packages/eval/harbor/deepseek-harness-profile/cordis.yml', ]); git(repositoryRoot, [ '-c', 'user.name=ASF Release Test', '-c', 'user.email=release-test@example.invalid', 'commit', '-m', 'test fixture', ]); const first = await createSourceCandidate({ outputDirectory: firstOutput, repositoryRoot, version: '0.1.12', }); await assert.rejects( () => createSourceCandidate({ outputDirectory: firstOutput, repositoryRoot, version: '0.1.12', }), /Refusing to overwrite existing release output/, ); git(repositoryRoot, ['config', 'tar.umask', '0077']); writeFileSync(join(repositoryRoot, '.git/info/attributes'), 'README.md export-ignore\n'); const ambientTemplate = join(temporaryRoot, 'ambient-template'); mkdirSync(join(ambientTemplate, 'info'), { recursive: true }); writeFileSync(join(ambientTemplate, 'info/attributes'), 'README.md export-ignore\n'); const ambientRepository = join(temporaryRoot, 'ambient-repository'); git(temporaryRoot, ['clone', '--quiet', repositoryRoot, ambientRepository]); writeFileSync(join(ambientRepository, 'README.md'), 'ambient repository\n'); git(ambientRepository, ['add', 'README.md']); git(ambientRepository, [ '-c', 'user.name=ASF Release Test', '-c', 'user.email=release-test@example.invalid', 'commit', '-m', 'change ambient repository', ]); const hostile = await withEnvironmentVariables( { GIT_DIR: join(ambientRepository, '.git'), GIT_TEMPLATE_DIR: ambientTemplate, GZIP: '-l', }, () => createSourceCandidate({ outputDirectory: hostileOutput, repositoryRoot, version: '0.1.12', }), ); assert.deepEqual(readFileSync(first.archivePath), readFileSync(hostile.archivePath)); assert.equal(hostile.commit, first.commit); assert.deepEqual( readFileSync(`${first.archivePath}.sha512`), readFileSync(`${hostile.archivePath}.sha512`), ); await assert.doesNotReject(() => verifySourceCandidate({ archivePath: first.archivePath })); const entries = execFileSync('tar', ['-tzf', basename(first.archivePath)], { cwd: dirname(first.archivePath), encoding: 'utf8', }); assert.doesNotMatch(entries, /untracked\.txt/); assert.doesNotMatch(entries, /\.claude|\.maka-shots|maka-proposal-zh-review/); assert.doesNotMatch(entries, /deepseek-harness-toolchain\/package(?:-lock)?\.json/); assert.match(entries, /deepseek-harness-toolchain\/patch-subprocess-local\.mjs/); assert.match(entries, /deepseek-harness-profile\/cordis\.yml/); assert.match(entries, /README\.md/); const originalCompressedBytes = readFileSync(first.archivePath); rewriteArchiveCompression(first.archivePath, 1); assert.notDeepEqual(readFileSync(first.archivePath), originalCompressedBytes); await assert.doesNotReject(() => reproduceSourceCandidate({ archivePath: first.archivePath, repositoryRoot, revision: first.commit, }), ); writeFileSync(join(repositoryRoot, 'README.md'), 'different committed payload\n'); git(repositoryRoot, ['add', 'README.md']); commitFixture(repositoryRoot, 'change candidate payload'); await assert.rejects( () => reproduceSourceCandidate({ archivePath: first.archivePath, repositoryRoot, revision: 'HEAD', }), /Candidate source payload does not match/, ); const gpgHome = join(temporaryRoot, 'gnupg'); const keysPath = join(temporaryRoot, 'KEYS'); const fingerprint = generateSigningKey({ algorithm: 'rsa2048', gpgHome, identity: 'ASF Release Test ', signingSubkeyAlgorithm: 'rsa2048', usage: 'cert', }); writeFileSync(join(gpgHome, 'gpg.conf'), 'digest-algo SHA1\n'); await assert.doesNotReject(() => signSourceCandidate({ archivePath: first.archivePath, gpgHome, keyFingerprint: fingerprint, repositoryRoot, revision: first.commit, }), ); exportPublicKey({ fingerprint, gpgHome, keysPath }); await assert.doesNotReject(() => verifySourceCandidate({ archivePath: first.archivePath, keysPath }), ); rmSync(`${first.archivePath}.asc`); execFileSync( 'gpg', [ '--batch', '--homedir', gpgHome, '--digest-algo', 'SHA512', '--detach-sign', '--output', `${first.archivePath}.asc`, first.archivePath, ], { stdio: 'ignore' }, ); const checksum = readFileSync(`${first.archivePath}.sha512`); writeFileSync(`${first.archivePath}.sha512`, 'not a checksum\n'); await assert.rejects( () => verifySourceCandidate({ archivePath: first.archivePath, keysPath }), /ASCII-armored/, ); writeFileSync(`${first.archivePath}.sha512`, checksum); rmSync(`${first.archivePath}.asc`); execFileSync( 'gpg', [ '--batch', '--homedir', gpgHome, '--armor', '--digest-algo', 'SHA1', '--detach-sign', '--output', `${first.archivePath}.asc`, first.archivePath, ], { stdio: 'ignore' }, ); await assert.rejects( () => verifySourceCandidate({ archivePath: first.archivePath, keysPath }), /must use SHA-256, SHA-384, or SHA-512/, ); rmSync(`${first.archivePath}.asc`); // Keep the homedir short enough for GPG agent socket paths on macOS. const ed25519Home = join(temporaryRoot, 'ed'); const ed25519Fingerprint = generateSigningKey({ algorithm: 'ed25519', gpgHome: ed25519Home, identity: 'ASF Ed25519 Release Test ', }); await assert.rejects( () => signSourceCandidate({ archivePath: first.archivePath, gpgHome: ed25519Home, keyFingerprint: ed25519Fingerprint, repositoryRoot, revision: first.commit, }), /must be RSA with at least 2048 bits/, ); assert.equal(existsSync(`${first.archivePath}.asc`), false); const rsa1024Home = join(temporaryRoot, 'r'); const rsa1024Fingerprint = generateSigningKey({ algorithm: 'rsa2048', gpgHome: rsa1024Home, identity: 'ASF RSA-1024 Subkey Test ', signingSubkeyAlgorithm: 'rsa1024', usage: 'cert', }); await assert.rejects( () => signSourceCandidate({ archivePath: first.archivePath, gpgHome: rsa1024Home, keyFingerprint: rsa1024Fingerprint, repositoryRoot, revision: first.commit, }), /must be RSA with at least 2048 bits/, ); assert.equal(existsSync(`${first.archivePath}.asc`), false); } finally { rmSync(temporaryRoot, { force: true, recursive: true }); } }); test('does not let ambient tar options control archive verification', async () => { const temporaryRoot = mkdtempSync(join(tmpdir(), 'maka-asf-tar-options-test-')); const identity = sourceCandidateIdentity('0.1.12'); const sourceRoot = join(temporaryRoot, identity.rootDirectory); const archivePath = join(temporaryRoot, identity.archiveName); try { writeReleaseContents(sourceRoot); mkdirSync(join(sourceRoot, '.agents'), { recursive: true }); writeFileSync(join(sourceRoot, '.agents/secret.txt'), 'must not be released\n'); execFileSync('tar', ['-czf', archivePath, identity.rootDirectory], { cwd: temporaryRoot, stdio: 'ignore', }); const digest = createHash('sha512').update(readFileSync(archivePath)).digest('hex'); writeFileSync(`${archivePath}.sha512`, `${digest} ${identity.archiveName}\n`); for (const [name, value] of Object.entries({ GZIP: '-l', TAR_OPTIONS: `--exclude=${identity.rootDirectory}/.agents`, TAR_READER_OPTIONS: 'tar:hdrcharset=BOGUS', })) { await withEnvironmentVariables({ [name]: value }, () => assert.rejects(() => verifySourceCandidate({ archivePath }), /Forbidden archive entry/), ); } } finally { rmSync(temporaryRoot, { force: true, recursive: true }); } }); }); function git(repositoryRoot, arguments_) { execFileSync('git', arguments_, { cwd: repositoryRoot, stdio: 'ignore' }); } function writeReleaseContents(root, { includeAttributes = false } = {}) { mkdirSync(root, { recursive: true }); writeFileSync( join(root, 'package.json'), `${JSON.stringify({ license: 'Apache-2.0', name: 'maka', private: true, version: '0.1.12' }, null, 2)}\n`, ); writeFileSync( join(root, 'package-lock.json'), `${JSON.stringify({ lockfileVersion: 3, name: 'maka', packages: { '': { name: 'maka', version: '0.1.12' } }, version: '0.1.12' }, null, 2)}\n`, ); writeFileSync( join(root, 'DISCLAIMER-WIP'), 'Apache Maka is undergoing incubation at The Apache Software Foundation.\n', ); writeFileSync(join(root, 'LICENSE'), 'Apache License, Version 2.0\n'); writeFileSync(join(root, 'NOTICE'), 'Apache Maka\n'); if (includeAttributes) { copyFileSync(join(import.meta.dirname, '../.gitattributes'), join(root, '.gitattributes')); } } function createFixtureCandidate(files = {}) { const temporaryRoot = mkdtempSync(join(tmpdir(), 'maka-asf-candidate-test-')); const identity = sourceCandidateIdentity('0.1.12'); const sourceRoot = join(temporaryRoot, identity.rootDirectory); const archivePath = join(temporaryRoot, identity.archiveName); writeReleaseContents(sourceRoot); for (const [relativePath, contents] of Object.entries(files)) { const path = join(sourceRoot, relativePath); mkdirSync(dirname(path), { recursive: true }); writeFileSync(path, contents); } execFileSync('tar', ['-czf', archivePath, identity.rootDirectory], { cwd: temporaryRoot, stdio: 'ignore', }); const digest = createHash('sha512').update(readFileSync(archivePath)).digest('hex'); writeFileSync(`${archivePath}.sha512`, `${digest} ${identity.archiveName}\n`); return { archivePath, cleanup: () => rmSync(temporaryRoot, { force: true, recursive: true }), }; } function commitFixture(repositoryRoot, message) { git(repositoryRoot, [ '-c', 'user.name=ASF Release Test', '-c', 'user.email=release-test@example.invalid', 'commit', '-m', message, ]); } async function withEnvironmentVariables(values, callback) { const previous = new Map(Object.keys(values).map((name) => [name, process.env[name]])); Object.assign(process.env, values); try { return await callback(); } finally { for (const [name, value] of previous) { if (value === undefined) delete process.env[name]; else process.env[name] = value; } } } function rewriteArchiveCompression(archivePath, level) { const tarPath = archivePath.slice(0, -3); execFileSync('gzip', ['-d', archivePath], { stdio: 'ignore' }); execFileSync('gzip', ['-n', `-${level}`, tarPath], { stdio: 'ignore' }); const digest = createHash('sha512').update(readFileSync(archivePath)).digest('hex'); writeFileSync(`${archivePath}.sha512`, `${digest} ${basename(archivePath)}\n`); } function generateSigningKey({ algorithm, gpgHome, identity, signingSubkeyAlgorithm, usage = 'sign', }) { mkdirSync(gpgHome, { mode: 0o700 }); chmodSync(gpgHome, 0o700); execFileSync( 'gpg', [ '--batch', '--homedir', gpgHome, '--pinentry-mode', 'loopback', '--passphrase', '', '--quick-generate-key', identity, algorithm, usage, '1d', ], { stdio: 'ignore' }, ); const fingerprint = execFileSync( 'gpg', ['--batch', '--homedir', gpgHome, '--with-colons', '--fingerprint', '--list-secret-keys'], { encoding: 'utf8' }, ) .split(/\r?\n/) .find((line) => line.startsWith('fpr:')) ?.split(':')[9]; assert.match(fingerprint, /^[0-9A-F]{40}$/); if (signingSubkeyAlgorithm) { execFileSync( 'gpg', [ '--batch', '--homedir', gpgHome, '--pinentry-mode', 'loopback', '--passphrase', '', '--quick-add-key', fingerprint, signingSubkeyAlgorithm, 'sign', '1d', ], { stdio: 'ignore' }, ); } return fingerprint; } function exportPublicKey({ fingerprint, gpgHome, keysPath }) { execFileSync( 'gpg', ['--batch', '--homedir', gpgHome, '--armor', '--output', keysPath, '--export', fingerprint], { stdio: 'ignore' }, ); }