修复审核发现的并发与工作台边界
拒绝维护目标符号链接并补充回归测试 为 manifest 写入增加跨进程锁与并发不可变校验 实时同步 Supervisor manifest 到资源、任务和版本工作台 在 Agent DB 截断时关闭不完整依赖推导 补齐依赖图文本等价、焦点恢复和对比度门禁 同步更新产品、技术、运维与项目记忆文档
This commit is contained in:
@@ -4,11 +4,15 @@ import { spawnSync } from 'node:child_process';
|
||||
import {
|
||||
chmodSync,
|
||||
existsSync,
|
||||
lstatSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
statSync,
|
||||
symlinkSync,
|
||||
unlinkSync,
|
||||
writeFileSync,
|
||||
} from 'node:fs';
|
||||
import os from 'node:os';
|
||||
@@ -141,6 +145,60 @@ function validateRuntimePageLifecycle() {
|
||||
if (missingPage.status === 0 || existsSync(markerFile)) {
|
||||
fail('不存在的 --page-file 必须在创建 marker 前失败。');
|
||||
}
|
||||
|
||||
const linkedPageTarget = path.join(tempRoot, 'linked-page-target');
|
||||
mkdirSync(linkedPageTarget);
|
||||
symlinkSync(
|
||||
linkedPageTarget,
|
||||
runtimePageFile,
|
||||
process.platform === 'win32' ? 'junction' : 'dir',
|
||||
);
|
||||
const linkedPageEnable = runScript(
|
||||
onScript,
|
||||
['--page-file', sourcePageFile, 'linked page target'],
|
||||
env,
|
||||
);
|
||||
if (linkedPageEnable.status === 0) {
|
||||
fail('maintenance-on 必须拒绝指向目录的公告页符号链接。');
|
||||
}
|
||||
if (!lstatSync(runtimePageFile).isSymbolicLink()) {
|
||||
fail('拒绝公告页符号链接后不得替换链接本身。');
|
||||
}
|
||||
if (readdirSync(linkedPageTarget).length > 0) {
|
||||
fail('拒绝公告页符号链接后不得把临时文件移入链接目标目录。');
|
||||
}
|
||||
if (existsSync(markerFile)) {
|
||||
fail('公告页符号链接校验失败时不得创建维护 marker。');
|
||||
}
|
||||
unlinkSync(runtimePageFile);
|
||||
|
||||
const linkedMarkerTarget = path.join(tempRoot, 'linked-marker-target');
|
||||
mkdirSync(linkedMarkerTarget);
|
||||
symlinkSync(
|
||||
linkedMarkerTarget,
|
||||
markerFile,
|
||||
process.platform === 'win32' ? 'junction' : 'dir',
|
||||
);
|
||||
const linkedMarkerEnable = runScript(
|
||||
onScript,
|
||||
['linked marker target'],
|
||||
env,
|
||||
);
|
||||
if (linkedMarkerEnable.status === 0) {
|
||||
fail('maintenance-on 必须拒绝指向目录的 marker 符号链接。');
|
||||
}
|
||||
if (!lstatSync(markerFile).isSymbolicLink()) {
|
||||
fail('拒绝 marker 符号链接后不得替换链接本身。');
|
||||
}
|
||||
if (readdirSync(linkedMarkerTarget).length > 0) {
|
||||
fail('拒绝 marker 符号链接后不得把临时文件移入链接目标目录。');
|
||||
}
|
||||
if (
|
||||
linkedMarkerEnable.stdout.includes('已进入维护模式') ||
|
||||
linkedMarkerEnable.stderr.includes('已进入维护模式')
|
||||
) {
|
||||
fail('marker 符号链接校验失败时不得打印维护模式成功信息。');
|
||||
}
|
||||
} finally {
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@ replace_file_atomically() {
|
||||
local source_file="$1"
|
||||
local target_file="$2"
|
||||
|
||||
if [[ -d "${target_file}" && ! -L "${target_file}" ]]; then
|
||||
if [[ -L "${target_file}" ]]; then
|
||||
echo "[maintenance] 原子替换目标不能是符号链接: ${target_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -d "${target_file}" ]]; then
|
||||
echo "[maintenance] 原子替换目标不能是目录: ${target_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user