docs: publish HoloLake system architecture baseline
This commit is contained in:
parent
75be096183
commit
ee9a85a5ca
138 changed files with 19347 additions and 71 deletions
111
language-world/reconstruction/tools/validate-reconstruction.mjs
Normal file
111
language-world/reconstruction/tools/validate-reconstruction.mjs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { createHash } from "node:crypto";
|
||||
import { readdir, readFile, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
const root = path.resolve(here, "..");
|
||||
const knowledgeRoot = path.resolve(root, "../..");
|
||||
const worldRoot = path.join(root, "world");
|
||||
const manifest = JSON.parse(await readFile(path.join(root, "selected-sources-manifest.json"), "utf8"));
|
||||
const errors = [];
|
||||
let linksChecked = 0;
|
||||
let jsonFilesChecked = 0;
|
||||
let sourceHashesChecked = 0;
|
||||
|
||||
async function filesUnder(directory) {
|
||||
const found = [];
|
||||
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
||||
if (entry.name === ".git") continue;
|
||||
const full = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) found.push(...await filesUnder(full));
|
||||
else found.push(full);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
for (const file of (await filesUnder(root)).filter((item) => item.endsWith(".json"))) {
|
||||
try {
|
||||
JSON.parse(await readFile(file, "utf8"));
|
||||
jsonFilesChecked += 1;
|
||||
} catch (error) {
|
||||
errors.push({ type: "INVALID_JSON", file, message: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
for (const source of manifest.sources) {
|
||||
const imported = path.join(root, source.imported_path);
|
||||
for (const [kind, file] of [["source", source.source_path], ["imported", imported]]) {
|
||||
try {
|
||||
const bytes = await readFile(file);
|
||||
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
||||
if (sha256 !== source.sha256) {
|
||||
errors.push({ type: "HASH_MISMATCH", id: source.id, kind, file });
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push({ type: "SOURCE_READ_FAILED", id: source.id, kind, file, message: error.message });
|
||||
}
|
||||
}
|
||||
sourceHashesChecked += 1;
|
||||
}
|
||||
|
||||
const markdownFiles = (await filesUnder(knowledgeRoot)).filter((item) => item.endsWith(".md"));
|
||||
for (const file of markdownFiles) {
|
||||
const text = await readFile(file, "utf8");
|
||||
const linkPattern = /\[[^\]]*]\(([^)]+)\)/g;
|
||||
for (const match of text.matchAll(linkPattern)) {
|
||||
let target = match[1].trim();
|
||||
if (!target || target.startsWith("#") || /^(https?:|mailto:)/.test(target)) continue;
|
||||
if (target.startsWith("<") && target.endsWith(">")) target = target.slice(1, -1);
|
||||
target = decodeURIComponent(target.split("#")[0]);
|
||||
const resolved = path.resolve(path.dirname(file), target);
|
||||
linksChecked += 1;
|
||||
try {
|
||||
await stat(resolved);
|
||||
} catch {
|
||||
errors.push({ type: "BROKEN_RELATIVE_LINK", file, target });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const source of manifest.sources) {
|
||||
if (/^domains\/(main|sub|zero|zero-sense)/.test(source.group) && source.privacy === "PRIVATE_FIFTH") {
|
||||
errors.push({ type: "PRIVATE_SOURCE_IN_PUBLIC_DOMAIN", id: source.id, group: source.group });
|
||||
}
|
||||
}
|
||||
|
||||
for (const domain of ["main", "sub", "zero", "zero-sense"]) {
|
||||
const file = path.join(worldRoot, "domains", domain, "INDEX.md");
|
||||
const text = await readFile(file, "utf8");
|
||||
if (text.includes("sources/domains/fifth") || text.includes("sources/supplemental/fd-mig-001")) {
|
||||
errors.push({ type: "PUBLIC_DOMAIN_LINKS_PRIVATE_FIFTH", file });
|
||||
}
|
||||
}
|
||||
|
||||
const routes = JSON.parse(await readFile(path.join(worldRoot, "routing/login-route-map.json"), "utf8"));
|
||||
const routeById = new Map(routes.routes.map((route) => [route.route_id, route]));
|
||||
const expected = {
|
||||
"GLW-LOGIN-BINGSHUO-FIFTH": ["光湖语言世界", "第五域", "永恒湖心系统", "心跳核心频道"],
|
||||
"GLW-LOGIN-ZHIZHI-FIFTH": ["光湖语言世界", "第五域", "永恒湖心系统", "爱之核心子系统", "明天见频道"]
|
||||
};
|
||||
for (const [routeId, steps] of Object.entries(expected)) {
|
||||
if (JSON.stringify(routeById.get(routeId)?.steps) !== JSON.stringify(steps)) {
|
||||
errors.push({ type: "CURRENT_ROUTE_MISMATCH", route_id: routeId });
|
||||
}
|
||||
}
|
||||
|
||||
console.log(JSON.stringify({
|
||||
schema: "guanghu.reconstruction-validation/v0.1",
|
||||
status: errors.length === 0 ? "PASS" : "FAIL",
|
||||
markdown_pages_checked: markdownFiles.length,
|
||||
relative_links_checked: linksChecked,
|
||||
json_files_checked: jsonFilesChecked,
|
||||
source_hash_pairs_checked: sourceHashesChecked,
|
||||
privacy_boundary_checked: true,
|
||||
current_routes_checked: Object.keys(expected).length,
|
||||
errors
|
||||
}, null, 2));
|
||||
|
||||
process.exitCode = errors.length === 0 ? 0 : 1;
|
||||
Loading…
Reference in a new issue