spb/anomaly-atlas Public License
Systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io) — pre-registered, artifact-null-driven, fully reproducible. Live atlas: www.anomaly-atlas.io
Python 61.4%
JavaScript 28.7%
CSS 8.6%
Shell 0.7%
Makefile 0.5%
1// ============================================================================2// Project : anomaly-atlas3// File : web/lib/content.js4// Purpose : Content index over the synced research-repo snapshot (content/)5// Author : Simon-Pierre Boucher6// Contact : contact@spboucher.ai7// Data src : hfmarketdata.io (sole data source)8// Created : 2026-08-129// Modified : 2026-08-1210// Platform : macOS / Apple Silicon (arm64) — Node.js (deployed on MacLustr)11// License : All rights reserved (research code)12// ============================================================================13"use strict";1415const fs = require("fs");16const path = require("path");17const matter = require("gray-matter");1819const CONTENT_ROOT = path.join(__dirname, "..", "content");2021const TEXT_EXT = new Set([22 ".md", ".py", ".sh", ".toml", ".yaml", ".yml", ".cff", ".json",23 ".js", ".css", ".sql", ".txt", ".log",24]);2526/** Resolve a repo-relative path safely inside content/, or return null. */27function safeResolve(rel) {28 const abs = path.resolve(CONTENT_ROOT, rel);29 if (!abs.startsWith(CONTENT_ROOT + path.sep) && abs !== CONTENT_ROOT) return null;30 return abs;31}3233function exists(rel) {34 const abs = safeResolve(rel);35 return abs !== null && fs.existsSync(abs);36}3738function readText(rel) {39 const abs = safeResolve(rel);40 if (!abs || !fs.existsSync(abs) || !fs.statSync(abs).isFile()) return null;41 return fs.readFileSync(abs, "utf8");42}4344/** Read a markdown file, returning { data (front matter), content }. */45function readMarkdown(rel) {46 const raw = readText(rel);47 if (raw === null) return null;48 try {49 return matter(raw);50 } catch {51 return { data: {}, content: raw };52 }53}5455/** List a directory inside content/: [{name, rel, dir, size}] */56function listDir(rel) {57 const abs = safeResolve(rel || ".");58 if (!abs || !fs.existsSync(abs) || !fs.statSync(abs).isDirectory()) return null;59 return fs60 .readdirSync(abs)61 .filter((n) => !n.startsWith(".") && n !== "node_modules")62 .map((n) => {63 const st = fs.statSync(path.join(abs, n));64 return {65 name: n,66 rel: path.posix.join(rel || "", n),67 dir: st.isDirectory(),68 size: st.size,69 };70 })71 .sort((a, b) => (a.dir !== b.dir ? (a.dir ? -1 : 1) : a.name.localeCompare(b.name)));72}7374/** Recursively collect files under rel matching a predicate. */75function walk(rel, predicate, out = []) {76 const entries = listDir(rel);77 if (!entries) return out;78 for (const e of entries) {79 if (e.dir) walk(e.rel, predicate, out);80 else if (predicate(e)) out.push(e);81 }82 return out;83}8485function isTextFile(rel) {86 return TEXT_EXT.has(path.extname(rel).toLowerCase()) || path.basename(rel) === "Makefile";87}8889/** Parse research/LOG.md into entries [{title, body}] (## headings). */90function parseLogEntries() {91 const md = readMarkdown("research/LOG.md");92 if (!md) return [];93 const parts = md.content.split(/^## /m).slice(1);94 return parts.map((p) => {95 const nl = p.indexOf("\n");96 return { title: p.slice(0, nl).trim(), body: p.slice(nl + 1).replace(/^---\s*$/m, "").trim() };97 });98}99100/** Experiment cards: micro experiments + candidates. */101function listExperiments() {102 const out = [];103 for (const base of ["experiments/micro", "experiments"]) {104 const entries = listDir(base) || [];105 for (const e of entries) {106 if (!e.dir || e.name === "micro") continue;107 const readme = readMarkdown(path.posix.join(e.rel, "README.md"));108 const hasAnalysis = (readText(path.posix.join(e.rel, "analysis.md")) || "").length > 400;109 const runs = listResultRuns().filter((r) => r.experiment === e.name);110 let purpose = "";111 if (readme) {112 const line = readme.content.split("\n").find((l) => l.trim() && !l.startsWith("#"));113 purpose = line ? line.trim() : "";114 }115 out.push({116 id: e.name,117 rel: e.rel,118 purpose,119 status: runs.length > 0 && hasAnalysis ? "completed" : runs.length > 0 ? "has results" : "scaffolded",120 runs: runs.length,121 });122 }123 }124 return out;125}126127/** Result runs: results/<experiment>/<timestamp>/*.json */128function listResultRuns() {129 const out = [];130 for (const exp of listDir("results") || []) {131 if (!exp.dir) continue;132 for (const run of listDir(exp.rel) || []) {133 if (!run.dir) continue;134 const files = (listDir(run.rel) || []).filter((f) => !f.dir);135 out.push({ experiment: exp.name, timestamp: run.name, rel: run.rel, files });136 }137 }138 return out.sort((a, b) => b.timestamp.localeCompare(a.timestamp));139}140141/** Atlas findings: atlas/<anomaly_id>/<version>/finding.json (+ confidence.md). */142function listFindings() {143 const out = [];144 for (const anomaly of listDir("atlas") || []) {145 if (!anomaly.dir) continue;146 for (const ver of listDir(anomaly.rel) || []) {147 if (!ver.dir) continue;148 const finding = readJson(path.posix.join(ver.rel, "finding.json"));149 if (!finding) continue;150 out.push({151 id: anomaly.name,152 version: ver.name,153 rel: ver.rel,154 level: finding.confidence_level ?? 0,155 title: finding.title || anomaly.name,156 summary: finding.summary || "",157 negative: !!finding.negative_result,158 finding,159 });160 }161 }162 return out.sort((a, b) => b.level - a.level || a.id.localeCompare(b.id));163}164165function readJson(rel) {166 const raw = readText(rel);167 if (raw === null) return null;168 try {169 return JSON.parse(raw);170 } catch {171 return null;172 }173}174175/** Build info written by sync-content.sh (commit, counts, date). */176function buildInfo() {177 return readJson("build-info.json") || {};178}179180/** Site-wide stats for the home page. */181function stats() {182 const bib = readText("research/bibliography.md") || "";183 const sources = bib.split("\n").filter((l) => l.trim().startsWith("- ")).length;184 const gapsDoc = readText("research/research_gaps.md") || "";185 const gaps = (gapsDoc.match(/^#{2,3}\s+H\d{2}/gm) || []).length;186 const experiments = listExperiments();187 const notes = (listDir("research/notes") || []).filter((f) => f.name.endsWith(".md") && f.name !== "README.md").length;188 const findings = listFindings();189 return {190 sources,191 gaps,192 notes,193 experiments: experiments.length,194 experimentsDone: experiments.filter((e) => e.status === "completed").length,195 resultRuns: listResultRuns().length,196 logEntries: parseLogEntries().length,197 findings: findings.length,198 negatives: findings.filter((f) => f.negative).length,199 build: buildInfo(),200 };201}202203module.exports = {204 CONTENT_ROOT,205 safeResolve,206 exists,207 readText,208 readMarkdown,209 readJson,210 listDir,211 walk,212 isTextFile,213 parseLogEntries,214 listExperiments,215 listResultRuns,216 listFindings,217 buildInfo,218 stats,219};220