84 lines
3.0 KiB
TypeScript
84 lines
3.0 KiB
TypeScript
#!/usr/bin/env bun
|
|||
|
|
|
||
|
|
import fs from "node:fs"
|
||
|
|
import path from "node:path"
|
||
|
|
|
||
|
|
const ROOT = path.resolve(import.meta.dir, "..")
|
||
|
|
const CORE_ROOT = path.join(ROOT, "core")
|
||
|
|
const EXEMPT = new Set(["core/schemas/id-aliases.json"])
|
||
|
|
|
||
|
|
const P1_PATTERNS: { name: string; re: RegExp }[] = [
|
||
|
|
{ name: "ins24", re: /\bins24\b/ },
|
||
|
|
{ name: "private-ip-10", re: /\b10\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/ },
|
||
|
|
{ name: "private-ip-192", re: /\b192\.168\.\d{1,3}\.\d{1,3}\b/ },
|
||
|
|
{ name: "private-ip-172", re: /\b172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}\b/ },
|
||
|
|
{ name: "config-home", re: /~\/\.config\/octopus/ },
|
||
|
|
{ name: "dev-instance-host", re: /dev\.eightarms\.net/ },
|
||
|
|
{ name: "git-data-dirs", re: /\/data\/git-wikis|\/data\/git-worktrees/ },
|
||
|
|
{ name: "personal-identity", re: /\bzhusi\w*\b/ },
|
||
|
|
{ name: "org-owner-legacy", re: /\bfourbroad\b/ },
|
||
|
|
]
|
||
|
|
|
||
|
|
function listTextFiles(absDir: string, base = ""): string[] {
|
||
|
|
const out: string[] = []
|
||
|
|
for (const entry of fs.readdirSync(absDir, { withFileTypes: true })) {
|
||
|
|
const rel = base ? `${base}/${entry.name}` : entry.name
|
||
|
|
if (entry.isDirectory()) out.push(...listTextFiles(path.join(absDir, entry.name), rel))
|
||
|
|
else if (/\.(md|yaml|json|ts)$/.test(entry.name)) out.push(rel)
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
}
|
||
|
|
|
||
|
|
const files = listTextFiles(CORE_ROOT).map((f) => `core/${f}`)
|
||
|
|
|
||
|
|
const HISTORICAL_NS_RE = /https:\/\/eightarms\.net\/fourbroad\//
|
||
|
|
|
||
|
|
interface Mapping {
|
||
|
|
core: string
|
||
|
|
sync: string
|
||
|
|
}
|
||
|
|
const MANIFEST_PATH = path.join(ROOT, "core", "CORE-MANIFEST.json")
|
||
|
|
const byteLocked = new Set<string>()
|
||
|
|
if (fs.existsSync(MANIFEST_PATH)) {
|
||
|
|
const mappings = (JSON.parse(fs.readFileSync(MANIFEST_PATH, "utf8")) as { mappings: Mapping[] }).mappings
|
||
|
|
for (const m of mappings) {
|
||
|
|
if (m.sync !== "verbatim" && m.sync !== "verbatimDir") continue
|
||
|
|
const dir = m.core.endsWith("/") ? m.core : `${m.core}/`
|
||
|
|
if (m.sync === "verbatimDir") {
|
||
|
|
for (const f of listTextFiles(path.join(ROOT, dir))) byteLocked.add(`${dir}${f}`)
|
||
|
|
} else {
|
||
|
|
byteLocked.add(m.core)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
const hits: string[] = []
|
||
|
|
const deferred: string[] = []
|
||
|
|
for (const rel of files) {
|
||
|
|
if (EXEMPT.has(rel)) continue
|
||
|
|
const lines = fs.readFileSync(path.join(ROOT, rel), "utf8").split("\n")
|
||
|
|
lines.forEach((line, i) => {
|
||
|
|
for (const p of P1_PATTERNS) {
|
||
|
|
if (!p.re.test(line)) continue
|
||
|
|
if (p.name === "org-owner-legacy" && HISTORICAL_NS_RE.test(line)) continue
|
||
|
|
const entry = `${rel}:${i + 1} [${p.name}]`
|
||
|
|
if (byteLocked.has(rel))
|
||
|
|
deferred.push(`${entry} (byte-locked verbatim mirror — delink with dogfood side, Inc 6b)`)
|
||
|
|
else hits.push(entry)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
if (hits.length > 0) {
|
||
|
|
console.error(`check-core-p1: ${hits.length} P1 residual hit(s) in core/:`)
|
||
|
|
for (const h of hits) console.error(` ${h}`)
|
||
|
|
process.exit(1)
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(
|
||
|
|
`check-core-p1: OK — ${files.length} text files scanned, 0 P1 hits` +
|
||
|
|
(deferred.length > 0 ? `; ${deferred.length} hit(s) in byte-locked verbatim mirrors deferred to Inc 6b` : "") +
|
||
|
|
` (id-aliases.json exempt)`,
|
||
|
|
)
|
||
|
|
if (deferred.length > 0) for (const d of deferred) console.log(` deferred: ${d}`)
|