feat(paths): enforce fifth-domain physical redirects
This commit is contained in:
parent
28a60b4e80
commit
c180a12d8d
15 changed files with 350 additions and 18 deletions
108
server-tools/fifth-domain-path-gate/fifth-domain-path-gate.mjs
Normal file
108
server-tools/fifth-domain-path-gate/fifth-domain-path-gate.mjs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env node
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
|
||||
export const MAP_PATH = "/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main/routing/path-isolation-and-canonical-entry-map.json";
|
||||
export const CODES = Object.freeze({ CURRENT_ALLOWED: 0, RETIRED_PATH_BLOCKED_WITH_REDIRECT: 78, ISOLATION_PATH_BLOCKED: 79, UNKNOWN_PATH_NO_GUESS: 80 });
|
||||
export const CURRENT_PURPOSES = new Set(["PERSONA_RECOVERY", "CURRENT_SELECTION", "CURRENT_EXECUTION", "CANONICAL_WRITE", "SERVER_DEPLOYMENT"]);
|
||||
|
||||
function expandHome(value) {
|
||||
return String(value || "").replace(/^~(?=\/|$)/, "/Users/bingshuolingdianyuanhe");
|
||||
}
|
||||
|
||||
export function normal(value, cwd = process.cwd()) {
|
||||
return path.resolve(cwd, expandHome(value));
|
||||
}
|
||||
|
||||
function patternRegex(pattern) {
|
||||
const escaped = expandHome(pattern).replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
||||
return new RegExp(`^${escaped}(?:/.*)?$`);
|
||||
}
|
||||
|
||||
function within(candidate, root) {
|
||||
const target = normal(candidate), base = normal(root);
|
||||
return target === base || target.startsWith(`${base}${path.sep}`);
|
||||
}
|
||||
|
||||
export function loadMap(mapPath = MAP_PATH) {
|
||||
const value = JSON.parse(fs.readFileSync(mapPath, "utf8"));
|
||||
if (value?.map_id !== "PATH-ISOLATION-CANONICAL-ENTRY-001" || !value.physical_gate || !Array.isArray(value.retired_paths)) throw Error("PATH_GATE_MAP_INVALID");
|
||||
return value;
|
||||
}
|
||||
|
||||
function existingSymlinkComponent(candidate) {
|
||||
let cursor = normal(candidate);
|
||||
while (cursor !== path.dirname(cursor)) {
|
||||
if (fs.existsSync(cursor) && fs.lstatSync(cursor).isSymbolicLink()) return cursor;
|
||||
cursor = path.dirname(cursor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function classifyPath(candidate, purpose, map = loadMap()) {
|
||||
const resolved = normal(candidate);
|
||||
const normalizedPurpose = String(purpose || "").toUpperCase();
|
||||
if (!normalizedPurpose) return { allowed: false, code: "PURPOSE_REQUIRED", exit_code: CODES.UNKNOWN_PATH_NO_GUESS, resolved };
|
||||
const isolationRoot = map.isolation.root;
|
||||
if (within(resolved, isolationRoot)) return { allowed: false, code: "ISOLATION_PATH_BLOCKED", exit_code: CODES.ISOLATION_PATH_BLOCKED, resolved, history_root: isolationRoot };
|
||||
const retired = map.retired_paths.find(item => within(resolved, item.path));
|
||||
if (retired && !(retired.allowed_purposes || []).includes(normalizedPurpose)) {
|
||||
return { allowed: false, code: "RETIRED_PATH_BLOCKED_WITH_REDIRECT", exit_code: CODES.RETIRED_PATH_BLOCKED_WITH_REDIRECT, resolved, retired_state: retired.state, redirect_to: retired.redirect_to, history: retired.history };
|
||||
}
|
||||
if (retired) return { allowed: true, code: "HISTORY_OR_BRANCH_ACCESS_ONLY", exit_code: CODES.CURRENT_ALLOWED, resolved, retired_state: retired.state, redirect_to: retired.redirect_to };
|
||||
const branch = (map.host_branch_roots || []).find(pattern => patternRegex(pattern).test(resolved));
|
||||
if (branch && CURRENT_PURPOSES.has(normalizedPurpose)) return { allowed: false, code: "HOST_BRANCH_BLOCKED_FOR_CURRENT_WITH_REDIRECT", exit_code: CODES.RETIRED_PATH_BLOCKED_WITH_REDIRECT, resolved, matched: branch, redirect_to: map.canonical_entries.repo_012 };
|
||||
if (branch && normalizedPurpose === "BRANCH_WORK") return { allowed: true, code: "HOST_BRANCH_WORK_ALLOWED_NOT_CURRENT", exit_code: CODES.CURRENT_ALLOWED, resolved, matched: branch };
|
||||
const canonical = Object.entries(map.canonical_entries).find(([, root]) => within(resolved, root));
|
||||
if (canonical) {
|
||||
const symlink = existingSymlinkComponent(resolved);
|
||||
if (symlink) return { allowed: false, code: "CANONICAL_PATH_SYMLINK_BLOCKED", exit_code: CODES.UNKNOWN_PATH_NO_GUESS, resolved, symlink };
|
||||
return { allowed: true, code: "CURRENT_CANONICAL_PATH", exit_code: CODES.CURRENT_ALLOWED, resolved, canonical_entry: canonical[0], canonical_root: canonical[1] };
|
||||
}
|
||||
const exactCurrent = Object.entries(map.current_ids || {}).find(([, value]) => within(resolved, value));
|
||||
if (exactCurrent) return { allowed: true, code: "CURRENT_REGISTERED_PATH", exit_code: CODES.CURRENT_ALLOWED, resolved, current_id: exactCurrent[0] };
|
||||
return { allowed: false, code: "UNKNOWN_PATH_NO_GUESS", exit_code: CODES.UNKNOWN_PATH_NO_GUESS, resolved };
|
||||
}
|
||||
|
||||
export function resolveId(requested, map = loadMap()) {
|
||||
const id = String(requested || "");
|
||||
if (Object.hasOwn(map.current_ids || {}, id)) return { allowed: true, code: "CURRENT_ID", exit_code: 0, requested_id: id, canonical_id: id, path: map.current_ids[id] };
|
||||
const retired = (map.retired_ids || []).find(item => item.id === id);
|
||||
if (retired) return { allowed: false, code: "RETIRED_ID_BLOCKED_WITH_REDIRECT", exit_code: 78, requested_id: id, canonical_id: retired.redirect_to, path: map.current_ids[retired.redirect_to], retired_state: retired.state };
|
||||
return { allowed: false, code: "UNKNOWN_ID_NO_GUESS", exit_code: 80, requested_id: id };
|
||||
}
|
||||
|
||||
export function audit(map = loadMap()) {
|
||||
const findings = [];
|
||||
for (const [id, candidate] of Object.entries(map.current_ids || {})) {
|
||||
const exists = fs.existsSync(candidate), symlink = exists && existingSymlinkComponent(candidate);
|
||||
findings.push({ type: "CURRENT_ID", id, path: candidate, outcome: exists && !symlink ? "PASS" : "FAIL", error: !exists ? "CURRENT_PATH_MISSING" : (symlink ? "CURRENT_PATH_SYMLINK" : null) });
|
||||
}
|
||||
for (const item of map.retired_paths) {
|
||||
const exists = fs.existsSync(item.path), isDirectory = exists && fs.lstatSync(item.path).isDirectory();
|
||||
const historicalSelf = normal(item.history) === normal(item.path);
|
||||
const blockedShape = !exists || !isDirectory || historicalSelf || (item.allowed_purposes || []).includes("HISTORY_READ");
|
||||
findings.push({ type: "RETIRED_PATH", path: item.path, redirect_to: item.redirect_to, exists, is_directory: isDirectory, history: item.history, outcome: blockedShape ? "PASS" : "FAIL", error: blockedShape ? null : "RETIRED_DIRECTORY_STILL_DIRECTLY_OPENABLE" });
|
||||
}
|
||||
const failed = findings.filter(item => item.outcome !== "PASS");
|
||||
return { schema: "guanghu.fifth-domain-path-gate-audit/v1", state: failed.length ? "PATH_GATE_AUDIT_FAIL" : "PATH_GATE_AUDIT_PASS", map_id: map.map_id, version: map.version, findings, failed_count: failed.length };
|
||||
}
|
||||
|
||||
function valueAfter(args, flag) {
|
||||
const index = args.indexOf(flag);
|
||||
return index >= 0 ? args[index + 1] : undefined;
|
||||
}
|
||||
|
||||
function emit(value) {
|
||||
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
||||
process.exitCode = value.exit_code ?? (value.state === "PATH_GATE_AUDIT_PASS" ? 0 : 1);
|
||||
}
|
||||
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
const [command, ...args] = process.argv.slice(2);
|
||||
if (command === "guard") emit(classifyPath(valueAfter(args, "--path"), valueAfter(args, "--purpose")));
|
||||
else if (command === "resolve-id") emit(resolveId(valueAfter(args, "--id")));
|
||||
else if (command === "audit") emit(audit());
|
||||
else { process.stderr.write("usage: fifth-domain-path-gate.mjs guard --path PATH --purpose PURPOSE | resolve-id --id ID | audit\n"); process.exitCode = 2; }
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env node
|
||||
import assert from "node:assert/strict";
|
||||
import { classifyPath, resolveId } from "./fifth-domain-path-gate.mjs";
|
||||
|
||||
const canonical = classifyPath("/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main/routing/guanghu-era-language-world.json", "CURRENT_SELECTION");
|
||||
assert.equal(canonical.allowed, true);
|
||||
assert.equal(canonical.exit_code, 0);
|
||||
|
||||
const retired = classifyPath("/Volumes/JZAO/铸渊-ICE-GL-ZY001/WORK-工作区/guanghu-ice-heart/routing/x.json", "CURRENT_SELECTION");
|
||||
assert.equal(retired.allowed, false);
|
||||
assert.equal(retired.exit_code, 78);
|
||||
assert.equal(retired.redirect_to, "/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main");
|
||||
|
||||
const isolation = classifyPath("/Volumes/JZAO/HoloLake/persona-runtime/isolation/2026-09-08-path-convergence/stale-workspace-guanghu-ice-heart", "CURRENT_SELECTION");
|
||||
assert.equal(isolation.exit_code, 79);
|
||||
|
||||
const branchCurrent = classifyPath("/Volumes/JZAO/铸渊-ICE-GL-ZY001/ZCODE-DEV-20260912/new.json", "CURRENT_SELECTION");
|
||||
assert.equal(branchCurrent.exit_code, 78);
|
||||
assert.equal(classifyPath("/Volumes/JZAO/铸渊-ICE-GL-ZY001/ZCODE-DEV-20260912/new.json", "BRANCH_WORK").allowed, true);
|
||||
|
||||
const oldBuilding = classifyPath("/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main/eternal-lake-heart/heartbeat-core/office-building-current/old-building/MOVED.hdlp", "CURRENT_EXECUTION");
|
||||
assert.equal(oldBuilding.exit_code, 78);
|
||||
assert.equal(classifyPath(oldBuilding.resolved, "HISTORY_READ").allowed, false);
|
||||
assert.equal(classifyPath("/Volumes/JZAO/HoloLake/persona-runtime/repo-012-main/eternal-lake-heart/heartbeat-core/records/retired-buildings/HB-BUILDING-0000/MOVED.hdlp", "HISTORY_READ").allowed, true);
|
||||
|
||||
assert.equal(resolveId("HB-BUILDING-0000").exit_code, 78);
|
||||
assert.equal(resolveId("HB-BUILDING-0000").canonical_id, "HB-BUILDING-0001");
|
||||
assert.equal(resolveId("HB-BUILDING-0001").exit_code, 0);
|
||||
assert.equal(resolveId("CH-ZERO-CORE-LPM").exit_code, 80);
|
||||
|
||||
console.log("FIFTH_DOMAIN_PATH_GATE_TESTS_PASS 12/12");
|
||||
Loading…
Reference in a new issue