Skip to content

Commit f633439

Browse files
committed
fix: close release qualification portability gaps
1 parent 3494e55 commit f633439

2 files changed

Lines changed: 109 additions & 3 deletions

File tree

‎scripts/test-global-install-smoke.js‎

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,38 @@ const successfulTask = '隔离安装模板写入验证'
817817
const successfulTaskRoot = path.join(consumerActiveRoot, 'requirements', successfulTask)
818818
const successfulArtifact = path.join(successfulTaskRoot, '02-技术方案.md')
819819
fs.mkdirSync(successfulTaskRoot, { recursive: true })
820-
fs.writeFileSync(successfulArtifact, '# 隔离安装技术方案\n\n用于验证已安装正式写入器。\n', 'utf8')
820+
fs.writeFileSync(successfulArtifact, [
821+
'# 隔离安装技术方案',
822+
'',
823+
'## 目录导航',
824+
'',
825+
'- [现状分析](#0-现状分析)',
826+
'- [方案概述](#1-方案概述)',
827+
'- [核心设计](#2-核心设计)',
828+
'- [测试策略](#7-测试策略)',
829+
'- [风险与缓解](#9-风险与缓解)',
830+
'',
831+
'## §0 现状分析',
832+
'',
833+
'隔离 consumer 已安装唯一候选 tarball。',
834+
'',
835+
'## §1 方案概述',
836+
'',
837+
'通过正式 MCP 写入器确认 CP2,并验证模板绑定回读。',
838+
'',
839+
'## §2 核心设计',
840+
'',
841+
'产物沿用已安装技术方案模板的必需语义,并允许补充隔离验收内容。',
842+
'',
843+
'## §7 测试策略',
844+
'',
845+
'验证 CP 状态、模板绑定、摘要和 sessions.md 均由同一安装包产生。',
846+
'',
847+
'## §9 风险与缓解',
848+
'',
849+
'全部 HOME、prefix、cache 与 workspace 均隔离并在结束时精确清理。',
850+
''
851+
].join('\n'), 'utf8')
821852
const successfulResponses = runInstalledMcp(installedMemoryServer, [
822853
rpcRequest(1, 'initialize', {
823854
protocolVersion: '2024-11-05',
@@ -893,7 +924,9 @@ assert.strictEqual(
893924
'installed template was not restored after the negative probe'
894925
)
895926

896-
const installedPackageRoot = path.join(globalPrefix, 'node_modules', packageJson.name)
927+
const installedPackageRoot = process.platform === 'win32'
928+
? path.join(globalPrefix, 'node_modules', packageJson.name)
929+
: path.join(globalPrefix, 'lib', 'node_modules', packageJson.name)
897930
assert.strictEqual(fs.existsSync(path.join(installedPackageRoot, 'package.json')), true, 'installed package root missing')
898931
if (smokeOptions.tarball) {
899932
const installedAdmissionSuite = runCommand(process.execPath, [
@@ -1418,7 +1451,7 @@ runNpm(['uninstall', '-g', packageJson.name, '--prefix', globalPrefix], {
14181451
timeout: 180000
14191452
})
14201453
assert.strictEqual(fs.existsSync(binPath), false, 'global devcodex bin remained after npm uninstall')
1421-
assert.strictEqual(fs.existsSync(path.join(globalPrefix, 'node_modules', packageJson.name)), false, 'global package remained after npm uninstall')
1454+
assert.strictEqual(fs.existsSync(installedPackageRoot), false, 'global package remained after npm uninstall')
14221455

14231456
cleanupTempFixture()
14241457
assert.strictEqual(fs.existsSync(tmp), false, 'global install smoke temporary fixture must be removed before success')

‎scripts/test-workflow-completion-contract.js‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,79 @@ assert.strictEqual(taskAutoBlockProjection.automatic, false)
333333
assert.match(taskAutoBlockProjection.message, /不能自动续批/)
334334
assert.strictEqual(projectAutoCheckpointDecision({}).decisionDigest, null)
335335

336+
function invalidValidationControlIntent(overrides = {}, binding = null, options = {}) {
337+
const intent = { ...clone(tasklessAutoIntent), ...overrides }
338+
return !validateValidationControlIngressIntent(intent, binding, options).valid
339+
}
340+
341+
expectNegative('validation-control-intent-non-object', () => !validateValidationControlIngressIntent(null).valid)
342+
expectNegative('validation-control-intent-array', () => !validateValidationControlIngressIntent([]).valid)
343+
expectNegative('validation-control-intent-schema', () => invalidValidationControlIntent({
344+
schemaVersion: 'ValidationControlIngressIntentV0'
345+
}))
346+
expectNegative('validation-control-intent-required-field', () => invalidValidationControlIntent({ envelopeId: '' }))
347+
expectNegative('validation-control-intent-digest-shape', () => invalidValidationControlIntent({ envelopeDigest: 'invalid' }))
348+
expectNegative('validation-control-intent-mode', () => invalidValidationControlIntent({ executionMode: 'manual' }))
349+
expectNegative('validation-control-intent-action', () => invalidValidationControlIntent({ action: 'execute' }))
350+
expectNegative('validation-control-intent-authority-kind', () => invalidValidationControlIntent({ authorityKind: 'model' }))
351+
expectNegative('validation-control-intent-budget-digest-shape', () => invalidValidationControlIntent({
352+
requestedBudgetDigest: 'invalid'
353+
}))
354+
expectNegative('validation-control-intent-path-count-shape', () => invalidValidationControlIntent({
355+
declaredChangedPathCount: 0
356+
}))
357+
expectNegative('validation-control-intent-budget-digest-unexpected', () => invalidValidationControlIntent({
358+
action: 'none',
359+
authorityKind: 'none',
360+
requestedBudgetDigest: 'a'.repeat(64)
361+
}))
362+
expectNegative('validation-control-intent-path-count-unexpected', () => invalidValidationControlIntent({
363+
action: 'none',
364+
authorityKind: 'none',
365+
declaredChangedPathCount: 2
366+
}))
367+
expectNegative('validation-control-intent-confirm-authority', () => invalidValidationControlIntent({
368+
action: 'confirm-current-budget',
369+
authorityKind: 'none'
370+
}))
371+
expectNegative('validation-control-intent-auto-authority', () => invalidValidationControlIntent({ authorityKind: 'none' }))
372+
expectNegative('validation-control-intent-authority-unexpected', () => invalidValidationControlIntent({
373+
action: 'none',
374+
authorityKind: 'auto'
375+
}))
376+
expectNegative('validation-control-intent-revoke-flag', () => invalidValidationControlIntent({
377+
action: 'revoke',
378+
authorityKind: 'none'
379+
}))
380+
expectNegative('validation-control-intent-non-revoke-flag', () => invalidValidationControlIntent({
381+
revocationRequested: true
382+
}))
383+
expectNegative('validation-control-intent-ceiling', () => invalidValidationControlIntent({
384+
authorityCeiling: 'V2'
385+
}))
386+
expectNegative('validation-control-intent-time-order', () => invalidValidationControlIntent({
387+
expiresAt: tasklessAutoIntent.issuedAt
388+
}))
389+
expectNegative('validation-control-intent-root', () => invalidValidationControlIntent({ projectRootIdentity: null }))
390+
expectNegative('validation-control-intent-root-schema', () => invalidValidationControlIntent({
391+
projectRootIdentity: { ...validationRootIdentity, schemaVersion: 'ProjectRootIdentityV0' }
392+
}))
393+
expectNegative('validation-control-intent-digest', () => invalidValidationControlIntent({
394+
intentDigest: '0'.repeat(64)
395+
}))
396+
expectNegative('validation-control-intent-binding', () => invalidValidationControlIntent({}, {
397+
envelopeId: 'other-envelope',
398+
envelopeDigest: '0'.repeat(64),
399+
sourceMessageDigest: '1'.repeat(64),
400+
hostSessionDigest: '2'.repeat(64),
401+
contextEpoch: 'ctx-other',
402+
project: 'other',
403+
projectRootIdentity: { ...validationRootIdentity, digest: '3'.repeat(64) }
404+
}))
405+
expectNegative('validation-control-intent-expired', () => invalidValidationControlIntent({}, null, {
406+
now: Date.parse(tasklessAutoIntent.expiresAt) + 1
407+
}))
408+
336409
function invalidValidationControl(overrides = {}, binding = null, options = {}) {
337410
const receipt = { ...clone(confirmControl), ...overrides }
338411
return !validateValidationControlIngressReceipt(receipt, binding, options).valid

0 commit comments

Comments
 (0)