| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- #!/usr/bin/env node
- const fs = require('fs');
- const os = require('os');
- const path = require('path');
- const { spawnSync } = require('child_process');
- const { buildStatusSummary, findOutputEvidence, hasLiveProof } = require('./optimization-status-audit');
- function main() {
- const root = path.resolve(__dirname, '..');
- const summary = buildStatusSummary(root);
- assert(summary.items.length >= 10, 'status audit should cover the optimization plan requirements');
- assert(summary.counts.passed >= 1, 'status audit should report passed items');
- assert(summary.counts.ready_not_proven >= 1, 'status audit should report ready_not_proven items');
- assert(summary.counts.blocked_by_external_data >= 1, 'status audit should report external-data blockers');
- assert(summary.complete === false, 'status audit should not mark the long-term goal complete without live/customer proof');
- assert(hasRequirement(summary, '视频 A/B 严格验收'), 'status audit should track video A/B proof');
- assert(hasRequirement(summary, '客户选中率 30%/40%/50% 和人工补号量减少 50%'), 'status audit should track customer effect proof');
- assert(hasId(summary, 'video-ab-proof'), 'status audit should expose stable id for video A/B proof');
- assert(hasId(summary, 'intake-readiness'), 'status audit should expose stable id for intake readiness proof gate');
- assert(hasId(summary, 'business-proof-progress'), 'status audit should expose stable id for business proof progress sync');
- assert(hasId(summary, 'business-proof-next-actions'), 'status audit should expose stable id for business proof next actions');
- assert(hasId(summary, 'latest-form-index'), 'status audit should expose stable id for latest form index');
- assert(hasId(summary, 'optimization-completion'), 'status audit should expose stable id for optimization completion audit');
- assert(hasId(summary, 'customer-effect-proof'), 'status audit should expose stable id for customer effect proof');
- assert(summary.items.every(item => item.id && item.title), 'status audit items should expose id and title for software-side consumption');
- const handoff = getItem(summary, 'optimization-handoff');
- const round = getItem(summary, 'round-deposition');
- const evidence = getItem(summary, 'evidence-index');
- const latestFormIndex = getItem(summary, 'latest-form-index');
- const completion = getItem(summary, 'optimization-completion');
- assert(handoff.next.includes('round:refresh'), 'handoff status next should prefer ordered round refresh');
- assert(round.next.includes('round:refresh') && !round.next.includes('再刷新 evidence:index'), 'round deposition next should not instruct stale manual refresh order');
- assert(evidence.next.includes('round:refresh'), 'evidence index status next should prefer ordered round refresh');
- assert(latestFormIndex.next.includes('round:refresh'), 'latest form index status next should prefer ordered round refresh');
- assert(completion.next.includes('round:refresh') && completion.next.includes('optimization:completion'), 'completion status next should expose round refresh and single audit commands');
- assertOldClosableLiveProofIsDetected();
- const outputDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-optimization-status-'));
- const run = spawnSync(process.execPath, [path.join(root, 'scripts', 'optimization-status-audit.js'), '--output', outputDir], {
- cwd: root,
- encoding: 'utf8'
- });
- assert(run.status === 0, `optimization:status --output should pass: ${run.stderr || run.stdout}`);
- assert(fs.existsSync(path.join(outputDir, 'optimization-status-summary.json')), 'status audit should write summary to --output directory');
- assert(fs.existsSync(path.join(outputDir, 'optimization-status-report.md')), 'status audit should write report to --output directory');
- const written = JSON.parse(fs.readFileSync(path.join(outputDir, 'optimization-status-summary.json'), 'utf8'));
- assert(written.complete === false, 'written status should preserve incomplete long-term proof boundary');
- console.log('optimization status smoke ok');
- }
- function hasRequirement(summary, text) {
- return summary.items.some(item => item.requirement === text);
- }
- function hasId(summary, id) {
- return summary.items.some(item => item.id === id);
- }
- function getItem(summary, id) {
- const item = summary.items.find(entry => entry.id === id);
- if (!item) throw new Error(`missing status item ${id}`);
- return item;
- }
- function assertOldClosableLiveProofIsDetected() {
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-status-live-proof-'));
- const outputs = path.join(tempRoot, 'outputs');
- fs.mkdirSync(outputs, { recursive: true });
- for (let index = 0; index < 90; index += 1) {
- const dir = path.join(outputs, `newer-${String(index).padStart(2, '0')}`);
- fs.mkdirSync(dir, { recursive: true });
- }
- const liveDir = path.join(outputs, 'older-closable-live');
- fs.mkdirSync(liveDir, { recursive: true });
- fs.writeFileSync(path.join(liveDir, 'aggregate-summary.json'), JSON.stringify({
- manifest: { liveEnabled: true },
- acceptance: {
- overallPass: true,
- failedGateCount: 0,
- tokenLeak: false
- },
- failureCount: 0
- }, null, 2), 'utf8');
- assert(hasLiveProof(findOutputEvidence(tempRoot)), 'status audit should detect closable live proof outside a recent-directory window');
- }
- function assert(condition, message) {
- if (!condition) throw new Error(message);
- }
- if (require.main === module) main();
|