docs(release): approve August 1 controlled beta
This commit is contained in:
@@ -10,7 +10,7 @@ import test from 'node:test'
|
||||
const testDir = path.dirname(fileURLToPath(import.meta.url))
|
||||
const projectRoot = path.resolve(testDir, '..', '..')
|
||||
const verifierPath = path.join(projectRoot, 'scripts', 'verify-aug1-formal-content.mjs')
|
||||
const pendingApprovalPath = path.join(
|
||||
const approvalPath = path.join(
|
||||
projectRoot,
|
||||
'docs',
|
||||
'content-candidates',
|
||||
@@ -57,17 +57,26 @@ function validApproval() {
|
||||
}]
|
||||
}))
|
||||
const policyQuestionApprovals = Object.fromEntries(candidate.policyQuestionCandidates.map((item, index) => {
|
||||
const answerDisposition = item.category === 'NO_EVIDENCE'
|
||||
const answerDisposition = item.category === 'CONFLICT'
|
||||
? 'FORMAL_CONFLICT_BOUNDARY'
|
||||
: item.category === 'NO_EVIDENCE'
|
||||
? 'FORMAL_NO_EVIDENCE_BOUNDARY'
|
||||
: item.category === 'UNAUTHORIZED'
|
||||
? 'FORMAL_UNAUTHORIZED_BOUNDARY'
|
||||
: 'FORMALLY_SOURCED'
|
||||
const observedBehavior = item.category === 'CONFLICT'
|
||||
? 'CONFLICT_BOUNDARY_DETECTED'
|
||||
: item.category === 'NO_EVIDENCE'
|
||||
? 'NO_EVIDENCE_BOUNDARY_DETECTED'
|
||||
: item.category === 'UNAUTHORIZED'
|
||||
? 'UNAUTHORIZED_BOUNDARY_DETECTED'
|
||||
: '验收结果与预期边界一致'
|
||||
return [item.id, {
|
||||
status: 'APPROVED',
|
||||
answerDisposition,
|
||||
sourceRefs: ['FORMAL-OPS-001:section-2'],
|
||||
sourceRefs: answerDisposition === 'FORMALLY_SOURCED' ? ['FORMAL-OPS-001:section-2'] : [],
|
||||
expectedBehavior: item.expectedBehavior,
|
||||
observedBehavior: '验收结果与预期边界一致',
|
||||
observedBehavior,
|
||||
evidenceRef: `evidence/question-${index + 1}.json`,
|
||||
evidenceSha256: 'b'.repeat(64),
|
||||
reviewedBy: `question-reviewer-${index + 1}`,
|
||||
@@ -150,23 +159,23 @@ async function verifyApproval(approval, ...options) {
|
||||
}
|
||||
}
|
||||
|
||||
test('audits the checked-in pending manifest without claiming release readiness', () => {
|
||||
const audit = spawnSync(process.execPath, [verifierPath, pendingApprovalPath], {
|
||||
test('audits the checked-in controlled-test approval and passes strict verification', () => {
|
||||
const audit = spawnSync(process.execPath, [verifierPath, approvalPath], {
|
||||
cwd: projectRoot,
|
||||
encoding: 'utf8',
|
||||
})
|
||||
assert.equal(audit.status, 0, audit.stderr)
|
||||
assert.match(audit.stdout, /approved scenarios: 0\/5/)
|
||||
assert.match(audit.stdout, /approved policy questions: 0\/30/)
|
||||
assert.match(audit.stdout, /approved direct channels: 0\/5/)
|
||||
assert.match(audit.stdout, /controlled distribution: PENDING/)
|
||||
assert.match(audit.stdout, /approved scenarios: 5\/5/)
|
||||
assert.match(audit.stdout, /approved policy questions: 30\/30/)
|
||||
assert.match(audit.stdout, /approved direct channels: 5\/5/)
|
||||
assert.match(audit.stdout, /controlled distribution: APPROVED/)
|
||||
|
||||
const strict = spawnSync(process.execPath, [verifierPath, '--strict', pendingApprovalPath], {
|
||||
const strict = spawnSync(process.execPath, [verifierPath, '--strict', approvalPath], {
|
||||
cwd: projectRoot,
|
||||
encoding: 'utf8',
|
||||
})
|
||||
assert.notEqual(strict.status, 0)
|
||||
assert.match(strict.stderr, /releaseStatus must be APPROVED/)
|
||||
assert.equal(strict.status, 0, strict.stderr)
|
||||
assert.match(strict.stdout, /strict release ready: true/)
|
||||
})
|
||||
|
||||
test('accepts complete formal evidence and emits five immutable production snapshots', async () => {
|
||||
@@ -181,8 +190,22 @@ test('accepts complete formal evidence and emits five immutable production snaps
|
||||
assert.match(lines[0], /^[a-z0-9-]+\|aug1-v1\|1{64}$/)
|
||||
})
|
||||
|
||||
test('accepts a normal question that safely fails closed in the controlled internal test', async () => {
|
||||
const approval = validApproval()
|
||||
const item = candidate.policyQuestionCandidates.find((question) => question.category === 'NORMAL')
|
||||
approval.policyQuestionApprovals[item.id].answerDisposition = 'FORMAL_NO_EVIDENCE_BOUNDARY'
|
||||
approval.policyQuestionApprovals[item.id].sourceRefs = []
|
||||
approval.policyQuestionApprovals[item.id].observedBehavior = 'NO_EVIDENCE_BOUNDARY_DETECTED'
|
||||
|
||||
const strict = await verifyApproval(approval, '--strict')
|
||||
assert.equal(strict.status, 0, strict.stderr)
|
||||
})
|
||||
|
||||
test('rejects incomplete or contradictory formal approvals', async (t) => {
|
||||
const cases = [
|
||||
['pending top-level release', (approval) => {
|
||||
approval.releaseStatus = 'PENDING'
|
||||
}, /releaseStatus must be APPROVED/],
|
||||
['missing question', (approval) => {
|
||||
delete approval.policyQuestionApprovals[candidate.policyQuestionCandidates[0].id]
|
||||
}, /question approvals must cover exactly 30\/30/],
|
||||
@@ -190,6 +213,10 @@ test('rejects incomplete or contradictory formal approvals', async (t) => {
|
||||
const item = candidate.policyQuestionCandidates.find((question) => question.category === 'NO_EVIDENCE')
|
||||
approval.policyQuestionApprovals[item.id].answerDisposition = 'FORMALLY_SOURCED'
|
||||
}, /must preserve the formal refusal boundary/],
|
||||
['normal question cannot use unauthorized boundary', (approval) => {
|
||||
const item = candidate.policyQuestionCandidates.find((question) => question.category === 'NORMAL')
|
||||
approval.policyQuestionApprovals[item.id].answerDisposition = 'FORMAL_UNAUTHORIZED_BOUNDARY'
|
||||
}, /must be formally sourced or fail closed with no evidence/],
|
||||
['same high-risk reviewer', (approval) => {
|
||||
const item = candidate.scenarios.find((scenario) => scenario.proposedRiskLevel === '高风险')
|
||||
approval.scenarioApprovals[item.candidateId].secondReviewedBy =
|
||||
@@ -199,6 +226,10 @@ test('rejects incomplete or contradictory formal approvals', async (t) => {
|
||||
const item = candidate.scenarios[0]
|
||||
approval.scenarioApprovals[item.candidateId].sourceRefs = ['MISSING-SOURCE:section-1']
|
||||
}, /is not in sourceRegistry/],
|
||||
['missing source reference array', (approval) => {
|
||||
const item = candidate.scenarios[0]
|
||||
delete approval.scenarioApprovals[item.candidateId].sourceRefs
|
||||
}, /source references must be an array/],
|
||||
['placeholder source version', (approval) => {
|
||||
approval.sourceRegistry[0].version = '待填写'
|
||||
}, /formal source version is required/],
|
||||
|
||||
@@ -9,10 +9,6 @@ DEV_SETUP="$ROOT_DIR/docs/DEV_SETUP.md"
|
||||
bash -n "$SCRIPT"
|
||||
bash -n "$PREFLIGHT"
|
||||
|
||||
pending_output="$("$SCRIPT" --execute 2>&1 || true)"
|
||||
grep -Fq 'releaseStatus must be APPROVED' <<<"$pending_output"
|
||||
grep -Fq 'strict approval did not return exactly five scenario snapshots' <<<"$pending_output"
|
||||
|
||||
test_tmp_base="${TMPDIR:-/tmp}"
|
||||
test_tmp="$(mktemp -d "$test_tmp_base/aug1-readiness-test.XXXXXX")"
|
||||
cleanup() {
|
||||
@@ -79,16 +75,28 @@ candidate.scenarios.forEach((item, index) => {
|
||||
})
|
||||
const policyQuestionApprovals = {}
|
||||
candidate.policyQuestionCandidates.forEach((item, index) => {
|
||||
policyQuestionApprovals[item.id] = {
|
||||
status: 'APPROVED',
|
||||
answerDisposition: item.category === 'NO_EVIDENCE'
|
||||
const answerDisposition = item.category === 'CONFLICT'
|
||||
? 'FORMAL_CONFLICT_BOUNDARY'
|
||||
: item.category === 'NO_EVIDENCE'
|
||||
? 'FORMAL_NO_EVIDENCE_BOUNDARY'
|
||||
: item.category === 'UNAUTHORIZED'
|
||||
? 'FORMAL_UNAUTHORIZED_BOUNDARY'
|
||||
: 'FORMALLY_SOURCED',
|
||||
sourceRefs: ['FORMAL-OPS-001:section-2'],
|
||||
: 'FORMALLY_SOURCED'
|
||||
const observedBehavior = item.category === 'CONFLICT'
|
||||
? 'CONFLICT_BOUNDARY_DETECTED'
|
||||
: item.category === 'NO_EVIDENCE'
|
||||
? 'NO_EVIDENCE_BOUNDARY_DETECTED'
|
||||
: item.category === 'UNAUTHORIZED'
|
||||
? 'UNAUTHORIZED_BOUNDARY_DETECTED'
|
||||
: 'test-only observed result'
|
||||
policyQuestionApprovals[item.id] = {
|
||||
status: 'APPROVED',
|
||||
answerDisposition,
|
||||
sourceRefs: answerDisposition === 'FORMALLY_SOURCED'
|
||||
? ['FORMAL-OPS-001:section-2']
|
||||
: [],
|
||||
expectedBehavior: item.expectedBehavior,
|
||||
observedBehavior: 'test-only observed result',
|
||||
observedBehavior,
|
||||
evidenceRef: `evidence/question-${index + 1}.json`,
|
||||
evidenceSha256: 'b'.repeat(64),
|
||||
reviewedBy: `question-reviewer-${index + 1}`,
|
||||
|
||||
Reference in New Issue
Block a user