Files
xinmi/scripts/wiki_seventh_recovery_review.cjs
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

198 lines
17 KiB
JavaScript

const assert = require('node:assert/strict')
const crypto = require('node:crypto')
const fs = require('node:fs')
const path = require('node:path')
const { sixthRecoveryScope, candidateSourceTreeHash } = require('./wiki_sixth_recovery_review.cjs')
const seventhRecoveryScope = Object.freeze({ ...sixthRecoveryScope })
const seventhPins = Object.freeze({
kind: 'wiki_source_name_correction_v1',
evidence_directory: 'acceptance/wiki-source-name-correction-private-20260921',
build_directory: 'acceptance/wiki-identity-repair-build-20260921',
baseline_release: 'public-20260921-113500',
baseline_image: 'sha256:c1755b2884652da1046da5e86b9cbc613435236ce98ea8b204b30d6981dda094',
baseline_published_at: '2026-09-21T03:41:42.894Z',
previous_release: 'public-20260921-040700',
previous_image: 'sha256:a3dbc9cecfca4d4143805a91a961e137da148ef3b8cc2211ba90cefb78207449',
previous_queued_at: '2026-09-20T20:28:12.142388+00:00',
checkpoint_fingerprint: '037c70fedd18d2fa1ec3d5017d290630b0fea0421e8b6224c425283cbed0e7c7',
previous_source_tree_hash: '7f09d5510b1d4d93f1b10d2697e536df96d7a0b93da3c75b6226d62e5af7b305',
previous_binary_sha256: '89ae673a89587a8d47b855f2a73b58afb2fdddc2d831aa710906316873cc42c2',
test_package: 'github.com/Tencent/WeKnora/internal/application/service',
})
const seventhRequiredTests = Object.freeze([
'TestWikiIdentityRepairPatchesOnlyRejectedNamesUnderExistingBudget',
'TestWikiIdentityRepairRejectsPartialOrUnsupportedPatchesWithoutMutation',
'TestWikiIdentityRepairNeverDeletesUnsupportedAliases',
'TestWikiIdentityRepairFailureKeepsOriginalErrorAndNeverRetriesProvider',
'TestWikiIdentityRepairCompletesWindowAndPreservesEarlierCheckpoint',
])
const seventhGraphDifference = Object.freeze({ path: 'internal/application/repository/retriever/legacygraph/repository.go',
source_sha256: '9ef94e82f4c3ea9e15ff8621d14be4a32309745ab4b4a98f8af5f3ce93987da4',
build_sha256: 'b3f5fb78a6f28b8a05af999976dd593e345a1a15262f01848e3c92f285fd2c19' })
const seventhPausedOperation = Object.freeze({ id: 4145, tenant_id: seventhRecoveryScope.tenant_id,
task_type: 'wiki:ingest', scope: 'knowledge_base', scope_id: seventhRecoveryScope.knowledge_base_id,
op: 'ingest', dedup_key: seventhRecoveryScope.knowledge_id, fail_count: 5,
payload: Object.freeze({ op: 'ingest', language: 'zh-CN', knowledge_id: seventhRecoveryScope.knowledge_id,
recovery_dead_letter_id: 10, recovery_attempt: 6, recovery_pending_op_id: 4145, recovery_budget_version: 1 }) })
const seventhReadProgress = Object.freeze({ stage: 'candidates', status: 'reading', version: 'wiki-full-read-v1',
source_runes: 227094, total_windows: 7, stage_complete: false, processed_runes: 32750,
completed_windows: 1, evidence_verified: false, source_windows_complete: false })
const sha = value => crypto.createHash('sha256').update(value).digest('hex')
const hash = (value, message) => assert.match(value || '', /^[a-f0-9]{64}$/, message)
function validateSeventhRecoveryReview(review, now = Date.now()) {
assert.equal(review?.max_attempt, 7, 'Seventh recovery requires its own review')
for (const [key, value] of Object.entries(seventhRecoveryScope)) assert.equal(review[key], value, `Seventh recovery scope mismatch: ${key}`)
for (const [key, value] of Object.entries({ previous_attempt: 6, previous_pending_op_id: 4145,
previous_error_code: 'EXTRACT_FAILED', budget_version: 1, public_gates_passed: true })) {
assert.equal(review[key], value, `Seventh recovery review mismatch: ${key}`)
}
assert.ok(Number.isSafeInteger(review.max_provider_requests) && review.max_provider_requests >= 1 && review.max_provider_requests <= 1000, 'Seventh recovery request limit must be 1..1000')
const start = Date.parse(review.budget_started_at), deadline = Date.parse(review.deadline_at)
assert.ok(Number.isFinite(start) && start <= now && deadline > start && deadline - start <= 120 * 60000, 'Seventh recovery needs a fixed duration of at most 120 minutes')
assert.match(review.fix_release || '', /^public-\d{8}-\d{6}$/)
assert.ok(review.fix_release > seventhPins.baseline_release, 'Seventh recovery requires the newly published source identity correction')
assert.match(review.api_image_id || '', /^sha256:[a-f0-9]{64}$/)
assert.ok(![seventhPins.baseline_image, seventhPins.previous_image].includes(review.api_image_id), 'Seventh recovery cannot use a pre-correction image')
const candidate = review.candidate_diagnostic
assert.equal(candidate?.kind, seventhPins.kind, 'Seventh recovery requires fresh source identity correction evidence')
assert.match(candidate.run_id || '', /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/)
for (const key of ['evidence_sha256', 'source_tree_hash', 'binary_sha256', 'build_manifest_sha256']) hash(candidate[key], `Missing correction ${key}`)
assert.notEqual(candidate.source_tree_hash, seventhPins.previous_source_tree_hash, 'Old replay source cannot prove the new correction')
assert.notEqual(candidate.binary_sha256, seventhPins.previous_binary_sha256, 'Old binary cannot prove the new correction')
assert.equal(candidate.semantic_reviewed, true, 'Source identity correction requires separate semantic review')
}
function validateSeventhRecovery(source, previous, review) {
validateSeventhRecoveryReview(review)
for (const [key, value] of Object.entries(seventhRecoveryScope)) {
assert.equal(source[key === 'dead_letter_id' ? 'id' : key], value, `Seventh recovery source mismatch: ${key}`)
}
for (const [key, value] of Object.entries({ attempt_number: 6, pending_op_id: 4145, recovery_status: 'stopped_budget',
error_code: 'EXTRACT_FAILED', span_status: 'failed', new_failures: 0, pending: false, pending_finalize: 0 })) {
assert.equal(previous?.[key], value, `Seventh recovery predecessor mismatch: ${key}`)
}
assert.equal(Date.parse(previous.queued_at), Date.parse(seventhPins.previous_queued_at), 'Preceding receipt time changed')
const budget = previous.recovery_budget
for (const [key, value] of Object.entries({ ...seventhRecoveryScope, attempt_number: 6, pending_op_id: 4145,
status: 'stopped_budget', stop_reason: 'phase_failed', last_phase: 'wiki_candidate_slug', reserved_provider_requests: 3,
reviewed_release: seventhPins.previous_release, reviewed_api_image: seventhPins.previous_image })) {
assert.equal(budget?.[key], value, `Seventh recovery preceding budget mismatch: ${key}`)
}
assert.equal(typeof budget.paused_payload, 'string', 'Preceding paused operation is missing')
const paused = JSON.parse(budget.paused_payload)
assert.ok(Array.isArray(paused) && paused.length === 1, 'Expected exactly one preceding paused operation')
for (const [key, value] of Object.entries(seventhPausedOperation)) {
if (key === 'payload') {
for (const [field, expected] of Object.entries(value)) assert.equal(paused[0]?.payload?.[field], expected, `Preceding paused payload changed: ${field}`)
} else assert.equal(paused[0]?.[key], value, `Preceding paused operation changed: ${key}`)
}
const progress = previous.read_progress?.candidates
assert.equal(Object.keys(progress || {}).length, Object.keys(seventhReadProgress).length, 'Preceding source reading checkpoint changed')
for (const [key, value] of Object.entries(seventhReadProgress)) assert.equal(progress?.[key], value, `Preceding source reading checkpoint changed: ${key}`)
}
function validateSeventhCorrectionEvidence(review, bytes, sourceTreeHash, binarySHA, testBytes, semanticBytes, buildManifestBytes, frozenBinarySHA) {
validateSeventhRecoveryReview(review)
const candidate = review.candidate_diagnostic
assert.equal(sha(bytes), candidate.evidence_sha256, 'Correction evidence changed after review')
const evidence = JSON.parse(bytes)
for (const key of ['kind', 'run_id', 'source_tree_hash', 'binary_sha256', 'build_manifest_sha256']) assert.equal(evidence[key], candidate[key], `Correction evidence mismatch: ${key}`)
assert.equal(sourceTreeHash, evidence.source_tree_hash, 'Current source differs from the tested correction')
assert.equal(binarySHA, evidence.binary_sha256, 'Running binary differs from the tested correction build')
assert.equal(frozenBinarySHA, evidence.binary_sha256, 'Frozen binary differs from the reviewed correction build')
assert.equal(sha(buildManifestBytes), evidence.build_manifest_sha256, 'Frozen build manifest changed after review')
const build = JSON.parse(buildManifestBytes)
for (const key of ['source_tree_hash', 'binary_sha256', 'fix_release', 'api_image_id', 'regression_tests_sha256']) assert.equal(build[key], evidence[key], `Frozen build mismatch: ${key}`)
assert.equal(build.source_kind, 'frozen_published_candidate', 'Recovery requires the tested frozen source')
for (const [key, value] of Object.entries(seventhGraphDifference)) assert.equal(build.baseline_graph_difference?.[key], value, `Unreviewed frozen source difference: ${key}`)
for (const [key, value] of Object.entries({ status: 'passed', model_calls: 0, production_writes: 0, prior_evidence_preserved: true,
fix_release: review.fix_release, api_image_id: review.api_image_id })) assert.equal(evidence[key], value, `Correction evidence mismatch: ${key}`)
const start = Date.parse(evidence.started_at), end = Date.parse(evidence.completed_at), published = Date.parse(review.published_at)
assert.ok(start > Date.parse(seventhPins.baseline_published_at) && end >= start && published > end && published <= Date.now(), 'Correction tests must be fresh and precede publication')
assert.equal(sha(testBytes), evidence.regression_tests_sha256, 'Correction regression output changed')
assert.equal(sha(semanticBytes), evidence.semantic_review_sha256, 'Correction semantic review changed')
const events = String(testBytes).trim().split('\n').map(line => JSON.parse(line))
assert.ok(events.length > 0, 'Correction test output is empty')
for (const event of events) {
assert.ok(typeof event.Package === 'string' && event.Package.startsWith('github.com/Tencent/WeKnora/'), 'Correction test package changed')
assert.ok(Date.parse(event.Time) >= start && Date.parse(event.Time) <= end, 'Correction test event is outside the fresh run')
assert.notEqual(event.Action, 'fail', 'Correction regression failed')
}
for (const name of seventhRequiredTests) {
const runs = events.filter(event => event.Package === seventhPins.test_package && event.Test === name && event.Action === 'run')
const ends = events.filter(event => event.Package === seventhPins.test_package && event.Test === name && ['pass', 'skip', 'fail'].includes(event.Action))
assert.ok(runs.length === 1 && ends.length === 1 && ends[0].Action === 'pass' && Date.parse(ends[0].Time) >= Date.parse(runs[0].Time), `Fresh correction regression did not pass: ${name}`)
}
assert.ok(events.some(event => event.Package === seventhPins.test_package && !event.Test && event.Action === 'pass'), 'Correction package did not pass')
const semantic = JSON.parse(semanticBytes)
for (const key of ['kind', 'run_id', 'source_tree_hash', 'binary_sha256', 'regression_tests_sha256']) assert.equal(semantic[key], evidence[key], `Semantic review mismatch: ${key}`)
for (const key of ['approved', 'candidate_count_preserved', 'aliases_not_removed', 'no_extra_retry', 'prior_evidence_preserved']) assert.equal(semantic[key], true, `Semantic review did not confirm ${key}`)
assert.ok(typeof semantic.reviewed_by === 'string' && semantic.reviewed_by.trim().length > 0, 'Semantic reviewer is required')
assert.ok(typeof semantic.notes === 'string' && semantic.notes.trim().length >= 20, 'Concrete semantic review notes are required')
assert.ok(Date.parse(semantic.reviewed_at) >= end && Date.parse(semantic.reviewed_at) < published, 'Semantic review must follow tests and precede publication')
return evidence
}
function verifySeventhBuildFiles(runtimeDirectory) {
const buildDirectory = path.join(runtimeDirectory, seventhPins.build_directory)
const buildManifestBytes = fs.readFileSync(path.join(buildDirectory, 'build-manifest.json'))
const build = JSON.parse(buildManifestBytes)
const sourceManifest = fs.readFileSync(path.join(buildDirectory, 'source-manifest.json'))
assert.equal(sha(sourceManifest), build.source_manifest_sha256, 'Frozen source manifest changed')
const files = JSON.parse(sourceManifest)
assert.ok(Array.isArray(files) && files.length > 0, 'Frozen source manifest is empty')
const seen = new Set()
for (const file of files) {
assert.ok(typeof file.path === 'string' && !path.isAbsolute(file.path) && !file.path.split('/').includes('..') && !seen.has(file.path), 'Invalid frozen source path')
seen.add(file.path)
const frozen = path.join(buildDirectory, 'source', file.path)
const live = path.join(runtimeDirectory, 'src', file.path)
assert.ok(fs.lstatSync(frozen).isFile() && fs.lstatSync(live).isFile(), 'Frozen source cannot contain symlinks')
assert.equal(sha(fs.readFileSync(frozen)), file.build_sha256, 'Frozen build source changed')
assert.equal(sha(fs.readFileSync(live)), file.source_sha256, 'Tested live source changed')
if (file.path === seventhGraphDifference.path) {
for (const [key, value] of Object.entries(seventhGraphDifference)) assert.equal(file[key], value, `Unreviewed graph difference: ${key}`)
} else assert.equal(file.source_sha256, file.build_sha256, 'Unreviewed live/build source difference')
}
assert.ok(seen.has(seventhGraphDifference.path), 'Frozen graph difference missing')
for (const file of ['go.mod', 'go.sum', 'internal/application/service/wiki_source_identity_repair.go', 'internal/application/service/wiki_source_identity_repair_test.go', 'internal/application/service/wiki_structured_output.go']) assert.ok(seen.has(file), 'Correction source is missing from the build manifest')
return { buildManifestBytes, sourceTreeHash: candidateSourceTreeHash(path.join(buildDirectory, 'source')),
frozenBinarySHA: sha(fs.readFileSync(path.join(buildDirectory, 'WeKnora'))) }
}
function seventhRecoveryEnqueueSQL(review, table, literal) {
validateSeventhRecoveryReview(review)
assert.equal(table, 'wiki_dead_letter_recoveries')
return `AND d.id=10 AND d.tenant_id=10059 AND d.fail_count=6
AND ${review.max_provider_requests} BETWEEN 1 AND 1000
AND ${literal(review.budget_started_at)}::timestamptz<=now()
AND ${literal(review.deadline_at)}::timestamptz>${literal(review.budget_started_at)}::timestamptz
AND ${literal(review.deadline_at)}::timestamptz<=${literal(review.budget_started_at)}::timestamptz+interval '120 minutes'
AND EXISTS (SELECT 1 FROM ${table} p JOIN wiki_recovery_budgets b
ON b.tenant_id=p.tenant_id AND b.dead_letter_id=p.dead_letter_id AND b.attempt_number=p.attempt_number AND b.pending_op_id=p.pending_op_id
WHERE p.tenant_id=d.tenant_id AND p.dead_letter_id=d.id AND p.attempt_number=6 AND p.pending_op_id=4145
AND p.queued_at=${literal(seventhPins.previous_queued_at)}::timestamptz
AND p.knowledge_id=d.related_id AND p.knowledge_base_id=d.scope_id AND p.model_id=k.wiki_config->>'synthesis_model_id'
AND b.status='stopped_budget' AND b.stop_reason='phase_failed' AND b.last_phase='wiki_candidate_slug' AND b.reserved_provider_requests=3
AND b.knowledge_id=d.related_id AND b.knowledge_base_id=d.scope_id AND b.model_id=k.wiki_config->>'synthesis_model_id'
AND b.embedding_model_id=k.embedding_model_id AND b.source_fingerprint=${literal(review.source_fingerprint)} AND b.model_fingerprint=${literal(review.model_fingerprint)}
AND b.reviewed_release=${literal(seventhPins.previous_release)} AND b.reviewed_api_image=${literal(seventhPins.previous_image)}
AND jsonb_typeof(b.paused_payload::jsonb)='array' AND jsonb_array_length(b.paused_payload::jsonb)=1
AND b.paused_payload::jsonb @> ${literal(JSON.stringify([seventhPausedOperation]))}::jsonb
AND NOT EXISTS (SELECT 1 FROM task_dead_letters failure WHERE failure.tenant_id=p.tenant_id AND failure.task_type='wiki:ingest'
AND failure.scope_id=p.knowledge_base_id AND failure.related_id=p.knowledge_id AND failure.id>p.dead_letter_highwater)
AND (SELECT span.status='failed' AND span.error_code='EXTRACT_FAILED' FROM knowledge_processing_spans span
WHERE span.knowledge_id=p.knowledge_id AND span.name='postprocess.wiki' AND span.started_at>=p.queued_at
ORDER BY span.started_at DESC,span.id DESC LIMIT 1)
AND (SELECT checkpoint.fingerprint=${literal(seventhPins.checkpoint_fingerprint)} AND checkpoint.payload::jsonb=${literal(JSON.stringify(seventhReadProgress))}::jsonb
FROM wiki_ingest_checkpoints checkpoint WHERE checkpoint.tenant_id=p.tenant_id AND checkpoint.knowledge_base_id=p.knowledge_base_id
AND checkpoint.knowledge_id=p.knowledge_id AND checkpoint.stage='read_progress' AND checkpoint.item_key='candidates' AND checkpoint.updated_at>=p.queued_at
ORDER BY checkpoint.updated_at DESC,checkpoint.fingerprint LIMIT 1))
AND NOT EXISTS (SELECT 1 FROM ${table} later WHERE later.tenant_id=d.tenant_id AND later.dead_letter_id=d.id AND later.attempt_number>6)`
}
module.exports = { seventhRecoveryScope, seventhPins, seventhRequiredTests, seventhPausedOperation, seventhReadProgress, seventhGraphDifference,
validateSeventhRecoveryReview, validateSeventhRecovery, validateSeventhCorrectionEvidence, verifySeventhBuildFiles, seventhRecoveryEnqueueSQL }