2026-09-09 12:19:16 +08:00
|
|
|
import assert from 'node:assert/strict'
|
|
|
|
|
import { readFileSync } from 'node:fs'
|
2026-10-03 03:21:14 +08:00
|
|
|
import { execFileSync } from 'node:child_process'
|
2026-09-09 12:19:16 +08:00
|
|
|
import test from 'node:test'
|
|
|
|
|
|
2026-10-03 03:21:14 +08:00
|
|
|
const source = readFileSync(new URL('./agents-index-contract.ps1', import.meta.url), 'utf8').replaceAll('\r\n', '\n')
|
|
|
|
|
const registry = readFileSync(new URL('../../docs/独立任务协作登记.md', import.meta.url), 'utf8')
|
2026-10-14 00:07:12 +08:00
|
|
|
const currentGroup = registry.match(/^## 2026-10-04 用户确认的三个独立执行对话(当前派工)\r?\n[\s\S]*?(?=^## |$(?![\s\S]))/m)?.[0]
|
|
|
|
|
assert.ok(currentGroup, 'mutations must target their own authorized group')
|
2026-10-03 03:21:14 +08:00
|
|
|
const contract = source.split('# BEGIN CURRENT TEST REGISTRY CONTRACT\n')[1]?.split('# END CURRENT TEST REGISTRY CONTRACT')[0]
|
|
|
|
|
assert.ok(contract, 'test exercises the production PowerShell registry validator')
|
|
|
|
|
function failures(text) {
|
|
|
|
|
const encoded = Buffer.from(text).toString('base64')
|
|
|
|
|
const command = `$ErrorActionPreference='Stop'
|
|
|
|
|
$script:failures=[System.Collections.Generic.List[string]]::new();$script:checked=0
|
|
|
|
|
function Add-Failure([string]$message){$script:failures.Add($message)}
|
|
|
|
|
function Assert-Contains([string]$text,[string]$needle,[string]$scope){if(-not $text.Contains($needle)){Add-Failure $scope}}
|
|
|
|
|
function Assert-NotContains([string]$text,[string]$needle,[string]$scope){if($text.Contains($needle)){Add-Failure $scope}}
|
|
|
|
|
${contract}
|
|
|
|
|
Assert-TestTaskRegistry ([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('${encoded}')))
|
|
|
|
|
ConvertTo-Json -InputObject @($script:failures) -Compress`
|
2026-10-14 00:07:12 +08:00
|
|
|
// Large registries exceed Windows command-line limits; the generated harness is passed over stdin.
|
|
|
|
|
return JSON.parse(execFileSync('pwsh', ['-NoProfile', '-NonInteractive', '-Command',
|
|
|
|
|
'$registryHarness = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String([Console]::In.ReadToEnd())); & ([ScriptBlock]::Create($registryHarness))'],
|
|
|
|
|
{ encoding: 'utf8', input: Buffer.from(command).toString('base64') }))
|
2026-10-03 03:21:14 +08:00
|
|
|
}
|
|
|
|
|
test('actual explicitly authorized TEST registry passes the production validator', () => {
|
|
|
|
|
assert.deepEqual(failures(registry), [])
|
2026-09-09 12:19:16 +08:00
|
|
|
})
|
2026-10-03 03:21:14 +08:00
|
|
|
for (const [name, mutate] of [
|
2026-10-05 12:07:02 +08:00
|
|
|
['missing creation authorization', s => s.replace('用户明确选择“按这 3 个独立对话创建”', '安排任务')],
|
|
|
|
|
['wrong controller', s => s.replace('所属唯一总控仍为 `退税报关` / `01a0d0da-130f-7d43-97b5-9c76abc1b5f1`', 'task_id=unknown')],
|
2026-10-03 12:15:12 +08:00
|
|
|
['wrong project', s => s.replace('`c64729ff-6710-43c6-8ef2-d84e9666cc1e`', 'projectId=wrong')],
|
2026-10-03 03:21:14 +08:00
|
|
|
['wrong workspace', s => s.replace('`C:/Users/BY-OY/Desktop/code/chongchong-global`', '`C:/Users/BY-OY/Desktop/code/chongchong-global-dev`')],
|
2026-10-05 12:07:02 +08:00
|
|
|
['duplicate task', s => s.replace('01a10686-cae9-7943-b976-27e78ad92723', '01a10686-c55c-75a3-9639-655b50cbce6c')],
|
|
|
|
|
['unregistered replacement', s => s.replace('01a10686-cae9-7943-b976-27e78ad92723', '00000000-0000-0000-0000-000000000000')],
|
2026-10-03 03:21:14 +08:00
|
|
|
['obsolete empty status', s => s + '\n当前无登记任务'],
|
|
|
|
|
['foreign project identity', s => s + '\n6f874ec3-d3b2-49bd-8625-327f4d685f98'],
|
|
|
|
|
['retired controller', s => s + '\n01a0194a-259c-7171-8967-074731a27618'],
|
2026-10-14 00:07:12 +08:00
|
|
|
]) test(`production validator rejects ${name}`, () =>
|
|
|
|
|
assert.ok(failures(registry.replace(currentGroup, mutate(currentGroup))).length > 0))
|