reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,287 @@
#!/usr/bin/env node
'use strict';
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const { contractHash } = require('./check_trace_runtime_conformance');
function parseArgs(argv) {
const args = {
caseDir: '',
entry: '',
contract: '',
out: '',
timeoutMs: 120000,
json: false,
markdown: false,
help: false,
};
for (let i = 2; i < argv.length; i++) {
const arg = argv[i];
if (arg === '--case-dir' || arg === '--case' || arg === '-d') args.caseDir = argv[++i] || '';
else if (arg === '--entry') args.entry = argv[++i] || '';
else if (arg === '--contract') args.contract = argv[++i] || '';
else if (arg === '--out') args.out = argv[++i] || '';
else if (arg === '--timeout-ms') args.timeoutMs = Number(argv[++i] || args.timeoutMs);
else if (arg === '--json') args.json = true;
else if (arg === '--markdown') args.markdown = true;
else if (arg === '--help' || arg === '-h') args.help = true;
else throw new Error(`未知参数:${arg}`);
}
if (!args.json && !args.markdown) args.markdown = true;
return args;
}
function usage() {
return `用法:
node scripts/run_trace_runtime_audit.js --case-dir case --entry case/result/final.js --markdown
node scripts/run_trace_runtime_audit.js --case-dir case --entry case/result/final.py --timeout-ms 180000 --json
说明:在强制 no-send 模式下运行项目审计入口。入口必须读取 WEB_JS_ENV_PATCHER_TRACE_AUDIT_OUT 并写出 observations;本脚本负责绑定 contractHash、runtimeSourceHash 和 probeVersion。`;
}
function exists(file) {
try { return fs.existsSync(file); } catch { return false; }
}
function stat(file) {
try { return fs.statSync(file); } catch { return null; }
}
function walk(root, out = []) {
if (!exists(root)) return out;
const st = stat(root);
if (!st) return out;
if (st.isFile()) {
out.push(root);
return out;
}
if (!st.isDirectory()) return out;
for (const name of fs.readdirSync(root)) walk(path.join(root, name), out);
return out;
}
function sha256(value) {
return crypto.createHash('sha256').update(value).digest('hex');
}
function runtimeSourceHash(resultDir) {
const entries = [];
for (const file of walk(resultDir)) {
const relative = (path.relative(resultDir, file) || '.').replace(/\\/g, '/');
if (/(^|\/)(node_modules|dist|build|coverage|tmp)(\/|$)/i.test(relative)) continue;
if (!/\.(js|mjs|cjs|ts|py|json)$/i.test(file)) continue;
entries.push([relative, sha256(fs.readFileSync(file))]);
}
entries.sort((a, b) => a[0].localeCompare(b[0]));
return sha256(JSON.stringify(entries));
}
function resolveCommand(entry) {
if (/\.py$/i.test(entry)) return { command: process.env.PYTHON || 'python', args: [entry, '--audit-only'] };
return { command: process.execPath, args: [entry, '--audit-only'] };
}
function normalizeObservations(raw) {
if (Array.isArray(raw)) return raw;
for (const key of ['observations', 'items', 'events', 'apis']) {
if (Array.isArray(raw && raw[key])) return raw[key];
}
return [];
}
function normalizeTimeline(raw, observations) {
const source = raw && (raw.timeline || raw.eventTimeline || raw.sequenceTimeline);
let entries = [];
if (Array.isArray(source)) {
entries = source;
} else if (source && Array.isArray(source.sequence)) {
entries = source.sequence;
}
let ordered = [];
let invalidEntries = 0;
if (entries.length) {
ordered = entries.map((item, index) => ({
id: String(item && typeof item === 'object'
? (item.contractId || item.id || item.key || '')
: item),
sequence: Number(item && typeof item === 'object'
? (typeof item.sequence !== 'undefined' ? item.sequence : (typeof item.seq !== 'undefined' ? item.seq : index))
: index),
})).filter(item => {
const valid = Boolean(item.id) && Number.isFinite(item.sequence);
if (!valid) invalidEntries += 1;
return valid;
}).sort((a, b) => a.sequence - b.sequence);
} else {
for (const observation of observations) {
const id = String(observation && (observation.id || observation.contractId || '') || '');
if (!id) continue;
const sequences = Array.isArray(observation.sequences)
? observation.sequences
: (typeof observation.sequence !== 'undefined' ? [observation.sequence] : []);
for (const sequence of sequences) {
ordered.push({ id, sequence: Number(sequence) || 0 });
}
}
ordered.sort((a, b) => a.sequence - b.sequence);
}
const sequence = [];
for (const item of ordered) {
if (sequence[sequence.length - 1] !== item.id) sequence.push(item.id);
}
const uniqueSequences = new Set(ordered.map(item => item.sequence));
const duplicateSequences = ordered.length - uniqueSequences.size;
return {
schemaVersion: 'trace-runtime-timeline/v1',
generatedFrom: entries.length ? 'runtime-event-timeline' : 'grouped-observations',
valid: invalidEntries === 0 && duplicateSequences === 0,
invalidEntries,
duplicateSequences,
eventCount: ordered.length,
collapsedCount: sequence.length,
truncated: false,
sequence,
sequenceSha256: sha256(JSON.stringify(sequence)),
};
}
function runAudit(args) {
const caseDir = path.resolve(args.caseDir || '.');
const resultDir = path.join(caseDir, 'result');
const entry = path.resolve(args.entry || path.join(resultDir, 'final.js'));
const contractPath = path.resolve(args.contract || path.join(caseDir, 'notes', 'trace-runtime-contract.json'));
const out = path.resolve(args.out || path.join(caseDir, 'tmp', 'node-trace-runtime-audit.json'));
if (!exists(entry)) throw new Error(`审计入口不存在:${entry}`);
if (!exists(contractPath)) throw new Error(`Trace runtime contract 不存在:${contractPath}`);
const contract = JSON.parse(fs.readFileSync(contractPath, 'utf8').replace(/^\uFEFF/, ''));
fs.mkdirSync(path.dirname(out), { recursive: true });
try { if (exists(out)) fs.rmSync(out); } catch {}
const command = resolveCommand(entry);
const env = {
...process.env,
WEB_JS_ENV_PATCHER_AUDIT_ONLY: '1',
WEB_JS_ENV_PATCHER_NO_NETWORK: '1',
WEB_JS_ENV_PATCHER_NETWORK_MODE: 'no-send',
WEB_JS_ENV_PATCHER_TRACE_CONTRACT: contractPath,
WEB_JS_ENV_PATCHER_TRACE_AUDIT_OUT: out,
};
const child = spawnSync(command.command, command.args, {
cwd: resultDir,
env,
encoding: 'utf8',
timeout: Number.isFinite(args.timeoutMs) && args.timeoutMs > 0 ? args.timeoutMs : 120000,
windowsHide: true,
});
const problems = [];
if (child.error) problems.push(`审计入口执行失败:${child.error.message}`);
if (child.status !== 0) problems.push(`审计入口退出码不是 0:${child.status}; stderr=${String(child.stderr || '').slice(0, 1000)}`);
if (!exists(out)) problems.push(`审计入口没有写出 ${out}`);
if (problems.length) {
return { clean: false, caseDir, entry, contractPath, out, command, problems, stdout: child.stdout || '', stderr: child.stderr || '' };
}
let raw;
try { raw = JSON.parse(fs.readFileSync(out, 'utf8').replace(/^\uFEFF/, '')); }
catch (err) {
return { clean: false, caseDir, entry, contractPath, out, command, problems: [`Node audit 无法解析:${err.message}`], stdout: child.stdout || '', stderr: child.stderr || '' };
}
const observations = normalizeObservations(raw);
if (!observations.length) problems.push('Node audit 没有 observations / items / events');
const hasNetworkAttempts = raw
&& (Object.prototype.hasOwnProperty.call(raw, 'networkAttempts')
|| Object.prototype.hasOwnProperty.call(raw, 'realNetworkRequests'));
if (!hasNetworkAttempts) problems.push('Node audit 必须显式记录 networkAttempts=0;缺失字段不能默认视为未访问网络');
const networkAttempts = Number(raw.networkAttempts || raw.realNetworkRequests || 0);
if (networkAttempts > 0) problems.push(`audit-only 阶段检测到 ${networkAttempts} 次真实网络尝试`);
const timeline = normalizeTimeline(raw, observations);
if (!timeline.valid) {
problems.push(`Node audit timeline 含无效项或重复 sequence:invalid=${timeline.invalidEntries},duplicate=${timeline.duplicateSequences}`);
}
if (contract.timeline && contract.timeline.required
&& timeline.generatedFrom !== 'runtime-event-timeline') {
problems.push('Trace contract 要求状态时间线,但审计入口没有输出原始 runtime event timeline;禁止从分组 observations 反推全局顺序');
}
const audit = {
schemaVersion: 'node-trace-runtime-audit/v3',
generatedBy: 'run_trace_runtime_audit.js',
generatedAt: new Date().toISOString(),
baselineId: contract.baselineId || raw.baselineId || '',
contractHash: contractHash(contract),
traceSourceHash: contract.traceSourceHash || '',
runtimeSourceHash: runtimeSourceHash(resultDir),
probeVersion: raw.probeVersion || 'runtime-audit/v3',
networkMode: 'no-send',
networkAttempts,
observations,
timeline,
runtimeMeta: raw.runtimeMeta || {},
};
fs.writeFileSync(out, `${JSON.stringify(audit, null, 2)}\n`, 'utf8');
return {
clean: problems.length === 0,
caseDir,
entry,
contractPath,
out,
command,
problems,
audit: {
observationCount: observations.length,
contractHash: audit.contractHash,
runtimeSourceHash: audit.runtimeSourceHash,
networkAttempts,
timelineEvents: timeline.eventCount,
timelineCollapsed: timeline.collapsedCount,
},
stdout: child.stdout || '',
stderr: child.stderr || '',
};
}
function renderMarkdown(result) {
const lines = [
'# Node Trace-runtime audit 执行结果',
'',
`- 入口:${result.entry}`,
`- contract:${result.contractPath}`,
`- audit:${result.out}`,
`- 是否通过:${result.clean ? '是' : '否'}`,
];
if (result.audit) {
lines.push(`- 观测项:${result.audit.observationCount}`);
lines.push(`- contractHash:${result.audit.contractHash}`);
lines.push(`- runtimeSourceHash:${result.audit.runtimeSourceHash}`);
lines.push(`- 真实网络尝试:${result.audit.networkAttempts}`);
lines.push(`- 状态时间线事件:${result.audit.timelineEvents}`);
lines.push(`- 状态时间线折叠项:${result.audit.timelineCollapsed}`);
}
if (result.problems.length) {
lines.push('', '## 问题');
for (const problem of result.problems) lines.push(`- ${problem}`);
}
return `${lines.join('\n')}\n`;
}
if (require.main === module) {
try {
const args = parseArgs(process.argv);
if (args.help) {
console.log(usage());
process.exit(0);
}
const result = runAudit(args);
if (args.json) console.log(JSON.stringify(result, null, 2));
if (args.markdown) process.stdout.write(renderMarkdown(result));
process.exit(result.clean ? 0 : 1);
} catch (err) {
console.error(err.message || String(err));
console.error(usage());
process.exit(1);
}
}
module.exports = { runAudit, runtimeSourceHash };