Download scripts/verify-space.mjs from mnemoverse/agent-memory-evaluation-map: direct link, hf CLI and curl.
- Browser
- Download file 14.9 kB
-
https://huggingface.co/spaces/mnemoverse/agent-memory-evaluation-map/resolve/main/scripts/verify-space.mjs
- Command line
-
hf download hf://spaces/mnemoverse/agent-memory-evaluation-map/scripts/verify-space.mjs
-
curl -L -o verify-space.mjs https://huggingface.co/spaces/mnemoverse/agent-memory-evaluation-map/resolve/main/scripts/verify-space.mjs
14.9 kB
| import { readFile, access } from "node:fs/promises"; | |
| import { dirname, join, resolve } from "node:path"; | |
| import { fileURLToPath } from "node:url"; | |
| const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); | |
| const errors = []; | |
| const notices = []; | |
| const requiredArtifactFields = [ | |
| "id", | |
| "title", | |
| "artifact_type", | |
| "primary_url", | |
| "authors", | |
| "mnemoverse_authored", | |
| "summary", | |
| "memory_scope", | |
| "evaluation_targets", | |
| "memory_unit", | |
| "time_model", | |
| "conflict_update_model", | |
| "outcome_level", | |
| "evidence_status", | |
| "code_url", | |
| "project_url", | |
| "dataset_url", | |
| "license", | |
| "limitations", | |
| "sources", | |
| "verified_at" | |
| ]; | |
| function fail(message) { | |
| errors.push(message); | |
| } | |
| function assert(condition, message) { | |
| if (!condition) fail(message); | |
| } | |
| async function read(relativePath) { | |
| return readFile(join(root, relativePath), "utf8"); | |
| } | |
| async function exists(relativePath) { | |
| try { | |
| await access(join(root, relativePath)); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| function parseFrontMatter(readme) { | |
| const match = readme.match(/^---\n([\s\S]*?)\n---\n/); | |
| assert(match, "README.md must start with YAML front matter"); | |
| if (!match) return new Map(); | |
| const fields = new Map(); | |
| for (const line of match[1].split("\n")) { | |
| const field = line.match(/^([A-Za-z][A-Za-z0-9_-]*):(?:\s*(.*))?$/); | |
| if (field) fields.set(field[1], (field[2] || "").trim()); | |
| } | |
| return fields; | |
| } | |
| function localReferences(indexHtml) { | |
| return [...indexHtml.matchAll(/(?:href|src)="([^"]+)"/g)] | |
| .map(match => match[1]) | |
| .filter(value => !value.startsWith("#") && !value.startsWith("http") && !value.startsWith("data:")); | |
| } | |
| function publicUrls(manifest) { | |
| const urls = []; | |
| for (const artifact of manifest.artifacts || []) { | |
| for (const key of ["primary_url", "code_url", "project_url", "dataset_url"]) { | |
| if (artifact[key]) urls.push(artifact[key]); | |
| } | |
| urls.push(...(artifact.sources || [])); | |
| } | |
| return [...new Set(urls)]; | |
| } | |
| async function checkUrl(url) { | |
| const controller = new AbortController(); | |
| const timer = setTimeout(() => controller.abort(), 15000); | |
| try { | |
| let response = await fetch(url, { method: "HEAD", redirect: "follow", signal: controller.signal }); | |
| if (response.status === 405 || response.status === 403) { | |
| response = await fetch(url, { method: "GET", redirect: "follow", signal: controller.signal }); | |
| } | |
| assert(response.ok, `Public URL returned ${response.status}: ${url}`); | |
| } catch (error) { | |
| fail(`Public URL check failed for ${url}: ${error.message}`); | |
| } finally { | |
| clearTimeout(timer); | |
| } | |
| } | |
| function normalizeText(value) { | |
| return String(value).replace(/\s+/g, " ").trim(); | |
| } | |
| function validDate(value) { | |
| if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return false; | |
| const parsed = new Date(`${value}T00:00:00Z`); | |
| return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value; | |
| } | |
| async function fetchSource(url, format = "json") { | |
| const controller = new AbortController(); | |
| const timer = setTimeout(() => controller.abort(), 15000); | |
| try { | |
| const response = await fetch(url, { | |
| headers: { Accept: format === "json" ? "application/json" : "text/html", "User-Agent": "mnemoverse-space-preflight" }, | |
| redirect: "follow", | |
| signal: controller.signal | |
| }); | |
| assert(response.ok, `Metadata URL returned ${response.status}: ${url}`); | |
| if (!response.ok) return null; | |
| return format === "json" ? await response.json() : await response.text(); | |
| } catch (error) { | |
| fail(`Metadata check failed for ${url}: ${error.message}`); | |
| return null; | |
| } finally { | |
| clearTimeout(timer); | |
| } | |
| } | |
| function decodeHtml(value) { | |
| return value.replace(/&#(x[0-9a-f]+|\d+);/gi, (_, code) => String.fromCodePoint(code[0].toLowerCase() === "x" ? parseInt(code.slice(1), 16) : Number(code))) | |
| .replaceAll(""", '"').replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&"); | |
| } | |
| async function checkPrimaryMetadata(artifact) { | |
| const paperId = artifact.id.split(":", 2)[1]; | |
| const metadataUrl = artifact.metadata_source || `https://huggingface.co/api/papers/${paperId}`; | |
| let metadata; | |
| if (artifact.metadata_source) { | |
| const html = await fetchSource(metadataUrl, "html"); | |
| if (html) { | |
| const title = html.match(/<meta name="citation_title" content="([^"]+)"\s*\/?\s*>/i)?.[1]; | |
| const authors = [...html.matchAll(/<meta name="citation_author" content="([^"]+)"\s*\/?\s*>/gi)].map(match => { | |
| const name = decodeHtml(match[1]); | |
| const comma = name.indexOf(","); | |
| return comma < 0 ? name : `${name.slice(comma + 1).trim()} ${name.slice(0, comma).trim()}`; | |
| }); | |
| assert(title && authors.length, `${artifact.id} pinned arXiv citation metadata was not found`); | |
| metadata = { title: decodeHtml(title || ""), authors }; | |
| } | |
| } else { | |
| metadata = await fetchSource(metadataUrl); | |
| } | |
| if (metadata) { | |
| assert(normalizeText(artifact.title) === normalizeText(metadata.title), `${artifact.id} title differs from ${metadataUrl}`); | |
| const apiAuthors = (metadata.authors || []).map(author => normalizeText(typeof author === "string" ? author : author.name)); | |
| const manifestAuthors = (artifact.authors || []).map(normalizeText); | |
| assert(JSON.stringify(manifestAuthors) === JSON.stringify(apiAuthors), `${artifact.id} authors differ from ${metadataUrl}`); | |
| } | |
| if (!artifact.code_url) return; | |
| const codeUrl = new URL(artifact.code_url); | |
| if (codeUrl.hostname !== "github.com") return; | |
| const [owner, repository] = codeUrl.pathname.split("/").filter(Boolean); | |
| if (!owner || !repository) { | |
| fail(`${artifact.id} has an unparseable GitHub code repository URL`); | |
| return; | |
| } | |
| const repositoryMetadata = await fetchSource(`https://api.github.com/repos/${owner}/${repository}`); | |
| if (!repositoryMetadata) return; | |
| const observedSpdx = repositoryMetadata.license?.spdx_id || "unknown"; | |
| const declaredSpdx = artifact.license.startsWith("MIT") | |
| ? "MIT" | |
| : artifact.license.startsWith("Apache-2.0") | |
| ? "Apache-2.0" | |
| : "unknown"; | |
| assert(observedSpdx === declaredSpdx, `${artifact.id} code-repository license differs: manifest ${declaredSpdx}, GitHub ${observedSpdx}`); | |
| } | |
| const [readme, indexHtml, appJs, manifestText, schemaText, licenseText, sources, deploymentChecklist] = await Promise.all([ | |
| read("README.md"), | |
| read("index.html"), | |
| read("app.js"), | |
| read("data/artifacts.json"), | |
| read("data/schema.json"), | |
| read("LICENSE"), | |
| read("SOURCES.md"), | |
| read("DEPLOYMENT-CHECKLIST.md") | |
| ]); | |
| let manifest; | |
| let schema; | |
| try { | |
| manifest = JSON.parse(manifestText); | |
| } catch (error) { | |
| fail(`data/artifacts.json is not valid JSON: ${error.message}`); | |
| manifest = {}; | |
| } | |
| try { | |
| schema = JSON.parse(schemaText); | |
| } catch (error) { | |
| fail(`data/schema.json is not valid JSON: ${error.message}`); | |
| schema = {}; | |
| } | |
| const frontMatter = parseFrontMatter(readme); | |
| assert(frontMatter.get("sdk") === "static", "README.md must declare sdk: static"); | |
| assert(frontMatter.get("app_file") === "index.html", "README.md must declare app_file: index.html"); | |
| assert(frontMatter.get("license") === "mit", "README.md must declare license: mit"); | |
| assert((frontMatter.get("short_description") || "").length <= 60, "README.md short_description must fit the current 60-character Space limit"); | |
| assert(await exists(frontMatter.get("app_file") || "__missing__"), "Configured app_file does not exist"); | |
| assert(!frontMatter.has("app_build_command"), "Vanilla Static Space must not declare an unnecessary build command"); | |
| const upstreamLicenseBoundary = "The MIT license covers original files in this Space. Linked papers, repositories, datasets, and project pages remain under their own licenses and terms; links and factual summaries do not relicense upstream works."; | |
| assert(licenseText.startsWith("MIT License\n"), "LICENSE must contain the standard MIT grant"); | |
| assert(licenseText.includes("Copyright (c) 2026 Mnemoverse"), "LICENSE must name Mnemoverse and the 2026 copyright year"); | |
| assert(licenseText.includes("Permission is hereby granted, free of charge"), "LICENSE must contain the MIT permission grant"); | |
| assert(licenseText.includes('THE SOFTWARE IS PROVIDED "AS IS"'), "LICENSE must contain the MIT warranty disclaimer"); | |
| assert(readme.includes(upstreamLicenseBoundary), "README.md must preserve the upstream-license boundary"); | |
| assert(sources.includes(upstreamLicenseBoundary), "SOURCES.md must preserve the upstream-license boundary"); | |
| for (const reference of localReferences(indexHtml)) { | |
| const cleanReference = reference.split(/[?#]/, 1)[0]; | |
| assert(await exists(cleanReference), `Missing local application reference: ${reference}`); | |
| } | |
| assert(appJs.includes('fetch("data/artifacts.json")'), "app.js must load the versioned local manifest"); | |
| assert(!appJs.includes("new Date()"), "Recipe exports must not contain a runtime timestamp"); | |
| assert(appJs.includes("evidence_verified_at: state.manifest.verified_at"), "Recipe exports must record the evidence verification date"); | |
| assert(appJs.includes('history.replaceState(null, "", "#evidence")'), "Skip navigation must preserve the evidence fragment"); | |
| assert(appJs.includes("elements.evidence.focus()"), "Skip navigation must move keyboard focus to the evidence section"); | |
| assert(indexHtml.includes('http-equiv="Content-Security-Policy"'), "index.html must declare a Content Security Policy"); | |
| assert(indexHtml.includes("object-src 'none'"), "Content Security Policy must block object embedding"); | |
| assert(/^\d+\.\d+\.\d+$/.test(manifest.manifest_version || ""), "manifest_version must be semantic x.y.z"); | |
| assert(validDate(manifest.verified_at), "manifest verified_at must be a valid YYYY-MM-DD calendar date"); | |
| assert(Array.isArray(manifest.targets) && manifest.targets.length === 8, "Manifest must define the reviewed eight evaluation targets"); | |
| const expectedArtifactIds = ["paper:2603.08965", "paper:2410.10813", "paper:2501.13956", "paper:2407.04363", "paper:2507.03724", "paper:2602.05665", "paper:2608.15008"]; | |
| assert(JSON.stringify((manifest.artifacts || []).map(artifact => artifact.id).sort()) === JSON.stringify([...expectedArtifactIds].sort()), "Manifest must contain exactly the seven source-reviewed artifacts"); | |
| assert(manifest.verified_at === (manifest.artifacts || []).map(artifact => artifact.verified_at).sort().at(-1), "manifest verified_at must equal the latest artifact source-check date"); | |
| const targetIds = new Set(); | |
| for (const target of manifest.targets || []) { | |
| assert(target && typeof target.id === "string", "Every target must have a string id"); | |
| assert(!targetIds.has(target.id), `Duplicate target id: ${target.id}`); | |
| targetIds.add(target.id); | |
| assert(appJs.includes(`${target.id}: [`), `app.js has no recipe prompts for target: ${target.id}`); | |
| } | |
| const artifactIds = new Set(); | |
| for (const artifact of manifest.artifacts || []) { | |
| const label = artifact?.id || "<missing id>"; | |
| for (const field of requiredArtifactFields) { | |
| assert(Object.hasOwn(artifact, field), `${label} is missing required field: ${field}`); | |
| } | |
| assert(/^paper:\d{4}\.\d{5}$/.test(label), `Unexpected artifact id format: ${label}`); | |
| assert(!artifactIds.has(label), `Duplicate artifact id: ${label}`); | |
| artifactIds.add(label); | |
| assert(validDate(artifact.verified_at) && artifact.verified_at <= manifest.verified_at, `${label} verification date must be valid and no later than the latest manifest source check`); | |
| const fieldSchemas = schema.$defs?.artifact?.properties || {}; | |
| for (const field of Object.keys(artifact)) { | |
| assert(Object.hasOwn(fieldSchemas, field), `${label} has an undeclared field: ${field}`); | |
| } | |
| for (const [field, definition] of Object.entries(fieldSchemas)) { | |
| if (definition.enum) assert(definition.enum.includes(artifact[field]), `${label} ${field} must be one of: ${definition.enum.join(", ")}`); | |
| } | |
| if (artifact.metadata_source) { | |
| assert(new RegExp(`^https://arxiv\\.org/abs/${label.slice(6).replace(".", "\\.")}v[1-9][0-9]*$`).test(artifact.metadata_source), `${label} metadata_source must pin the same arXiv paper`); | |
| assert(artifact.sources.includes(artifact.metadata_source), `${label} metadata_source must be in sources`); | |
| } | |
| assert(Array.isArray(artifact.authors) && artifact.authors.length > 0, `${label} must name at least one author`); | |
| assert(Array.isArray(artifact.limitations) && artifact.limitations.length > 0, `${label} must state at least one limitation`); | |
| for (const targetId of artifact.evaluation_targets || []) { | |
| assert(targetIds.has(targetId), `${label} references undefined target: ${targetId}`); | |
| } | |
| } | |
| const urls = publicUrls(manifest); | |
| for (const url of urls) { | |
| let parsed; | |
| try { | |
| parsed = new URL(url); | |
| } catch { | |
| fail(`Malformed public URL: ${url}`); | |
| continue; | |
| } | |
| assert(parsed.protocol === "https:", `Public evidence URL must use HTTPS: ${url}`); | |
| } | |
| const graphMemorySurvey = (manifest.artifacts || []).find(artifact => artifact.id === "paper:2602.05665"); | |
| assert(graphMemorySurvey?.code_url === null, "Awesome-GraphMemory is a curated resource repository, not implementation code"); | |
| assert(graphMemorySurvey?.project_url === "https://github.com/DEEP-PolyU/Awesome-GraphMemory", "Graph-memory survey must expose its curated repository as a project link"); | |
| assert(schema.$schema === "https://json-schema.org/draft/2020-12/schema", "Schema must use JSON Schema 2020-12"); | |
| assert(schema.$id === "https://huggingface.co/spaces/mnemoverse/agent-memory-evaluation-map/raw/main/data/schema.json", "Schema $id must match the planned Space path"); | |
| const publicPayload = `${readme}\n${indexHtml}\n${appJs}\n${manifestText}\n${schemaText}\n${sources}\n${deploymentChecklist}`.toLocaleLowerCase(); | |
| for (const forbidden of ["internal-only", "confidential", "do not publish", "room atom"]) { | |
| assert(!publicPayload.includes(forbidden), `Deployable app payload contains blocked phrase: ${forbidden}`); | |
| } | |
| if (process.argv.includes("--check-urls")) { | |
| notices.push(`Checking ${urls.length} unique public URLs…`); | |
| for (const url of urls) await checkUrl(url); | |
| notices.push(`Checking titles/authors against each declared metadata source and code-repository SPDX identifiers…`); | |
| for (const artifact of manifest.artifacts || []) await checkPrimaryMetadata(artifact); | |
| } else { | |
| notices.push(`Skipped ${urls.length} live URL checks; add --check-urls to enable them.`); | |
| } | |
| for (const notice of notices) console.log(`NOTICE: ${notice}`); | |
| if (errors.length) { | |
| for (const error of errors) console.error(`ERROR: ${error}`); | |
| console.error(`Preflight failed with ${errors.length} error(s).`); | |
| process.exit(1); | |
| } | |
| console.log(`PASS: Static Space package is internally consistent (${manifest.artifacts.length} artifacts, ${manifest.targets.length} targets, manifest ${manifest.manifest_version}).`); | |