diff --git a/site/red-team-shadow-dossiers/server/server.mjs b/site/red-team-shadow-dossiers/server/server.mjs
index 1d4ccbe..1d56972 100644
--- a/site/red-team-shadow-dossiers/server/server.mjs
+++ b/site/red-team-shadow-dossiers/server/server.mjs
@@ -4,6 +4,7 @@ import path from "node:path";
import url from "node:url";
import { spawn } from "node:child_process";
+import MarkdownIt from "markdown-it";
import express from "express";
import multer from "multer";
@@ -17,8 +18,37 @@ const indexHtmlPath = path.join(distDir, "index.html");
const privateUploadToken = process.env.PRIVATE_UPLOAD_TOKEN || "";
const privateUploadMaxBytes = Number(process.env.PRIVATE_UPLOAD_MAX_BYTES || 25 * 1024 * 1024);
const privateUploadStyle = process.env.PRIVATE_UPLOAD_STYLE || "if.dave.v1.2";
+const privateUploadActionPack = String(process.env.PRIVATE_UPLOAD_ACTION_PACK || "")
+ .trim()
+ .toLowerCase();
const revoiceRepoRoot = path.resolve(projectRoot, "..", "..");
+function normalizeBaseUrl(value) {
+ return String(value || "")
+ .trim()
+ .replace(/\/+$/g, "");
+}
+
+function uniqBaseUrls(values) {
+ const out = [];
+ const seen = new Set();
+ for (const v of values || []) {
+ const base = normalizeBaseUrl(v);
+ if (!base) continue;
+ if (seen.has(base)) continue;
+ seen.add(base);
+ out.push(base);
+ }
+ return out;
+}
+
+function staticMirrorBaseUrls(primaryBaseUrl, publicBaseUrl) {
+ const env = String(process.env.STATIC_MIRROR_PUBLIC_BASE_URLS || "").trim();
+ const defaults = ["https://git.infrafabric.io"];
+ const configured = env ? env.split(",") : defaults;
+ return uniqBaseUrls([primaryBaseUrl, ...configured, publicBaseUrl]);
+}
+
function escapeHtml(value) {
return String(value || "")
.replaceAll("&", "&")
@@ -32,6 +62,613 @@ function ensureDir(dirPath) {
fs.mkdirSync(dirPath, { recursive: true });
}
+const markdown = new MarkdownIt({
+ html: false,
+ linkify: true,
+ breaks: false,
+});
+const defaultFence = markdown.renderer.rules.fence;
+markdown.renderer.rules.fence = (tokens, idx, options, env, self) => {
+ const token = tokens[idx];
+ const info = String(token.info || "")
+ .trim()
+ .split(/\s+/g)[0]
+ .toLowerCase();
+ if (info === "mermaid") {
+ return `
${escapeHtml(token.content)}\n`;
+ }
+ if (typeof defaultFence === "function") return defaultFence(tokens, idx, options, env, self);
+ return self.renderToken(tokens, idx, options);
+};
+
+function renderMarkdownPage({ title, html, topLinksHtml }) {
+ return [
+ "",
+ "",
+ "",
+ "",
+ "",
+ `${escapeHtml(title || "Shadow Dossier")}`,
+ "",
+ "",
+ topLinksHtml ? `${topLinksHtml}
` : "",
+ `${html}`,
+ "",
+ "",
+ ].join("");
+}
+
+function renderVerificationBadgeHtml(verification) {
+ const status = String(verification?.status || "").toLowerCase();
+ const label = String(verification?.label || "").trim();
+ const detail = String(verification?.detail || "").trim();
+
+ if (!status) return "";
+
+ const cls = status === "verified" ? "ok" : status === "warning" ? "warn" : "fail";
+ const safeLabel = escapeHtml(label || status.toUpperCase());
+ const safeDetail = escapeHtml(detail);
+ return `${safeLabel}${safeDetail ? ` ${safeDetail}` : ""}`;
+}
+
+async function computeVerificationStatus({ job, projectRoot, outputsDir, uploadsDir }) {
+ const expectedOutput = String(job?.outputSha256 || "").trim();
+ const expectedSource = String(job?.sourceSha256 || "").trim();
+ const warningsPresent = Boolean(job?.warnings && String(job.warnings).trim());
+ const status = String(job?.status || "").trim();
+
+ const outputPathRel = String(job?.outputPath || "").trim();
+ const outputAbs = outputPathRel ? path.resolve(projectRoot, outputPathRel) : "";
+
+ let outputOk = false;
+ if (expectedOutput && outputAbs && outputAbs.startsWith(outputsDir + path.sep) && fs.existsSync(outputAbs)) {
+ try {
+ const actual = await sha256File(outputAbs);
+ outputOk = actual === expectedOutput;
+ } catch {
+ outputOk = false;
+ }
+ }
+
+ const sourcePathRel = String(job?.sourcePath || "").trim();
+ const sourceAbs = sourcePathRel ? path.resolve(projectRoot, sourcePathRel) : "";
+ let sourceOk = false;
+ let sourceCheckKnown = false;
+ if (expectedSource && sourceAbs && sourceAbs.startsWith(uploadsDir + path.sep) && fs.existsSync(sourceAbs)) {
+ sourceCheckKnown = true;
+ try {
+ const actual = await sha256File(sourceAbs);
+ sourceOk = actual === expectedSource;
+ } catch {
+ sourceOk = false;
+ }
+ } else if (expectedSource) {
+ sourceCheckKnown = false;
+ }
+
+ if (!outputOk) {
+ return {
+ status: "fail",
+ label: "FAIL",
+ detail: "hash mismatch",
+ checks: { outputOk, sourceOk: sourceCheckKnown ? sourceOk : null, warningsPresent, jobStatus: status },
+ };
+ }
+
+ if (sourceCheckKnown && !sourceOk) {
+ return {
+ status: "fail",
+ label: "FAIL",
+ detail: "source mismatch",
+ checks: { outputOk, sourceOk, warningsPresent, jobStatus: status },
+ };
+ }
+
+ if (warningsPresent || status === "done_with_warnings" || !sourceCheckKnown) {
+ const detail = warningsPresent ? "warnings" : !sourceCheckKnown ? "source not locally verifiable" : "check details";
+ return {
+ status: "warning",
+ label: "WARNING",
+ detail,
+ checks: { outputOk, sourceOk: sourceCheckKnown ? sourceOk : null, warningsPresent, jobStatus: status },
+ };
+ }
+
+ return {
+ status: "verified",
+ label: "VERIFIED",
+ detail: "all checks passed",
+ checks: { outputOk, sourceOk, warningsPresent, jobStatus: status },
+ };
+}
+
+function renderTraceMarkdown({ shareId, job, publicBaseUrl, staticPublicBaseUrl }) {
+ const primaryBase = normalizeBaseUrl(staticPublicBaseUrl || publicBaseUrl);
+ const bases = staticMirrorBaseUrls(primaryBase, publicBaseUrl);
+ const mirrorBase = bases.find((b) => b !== primaryBase) || "";
+
+ const verificationStatus = String(job?._verification?.status || "").toUpperCase() || "UNKNOWN";
+ const verificationDetail = String(job?._verification?.detail || "").trim();
+ const verificationChecks = job?._verification?.checks || {};
+
+ const createdAt = job?.createdAt ? String(job.createdAt) : "";
+ const status = job?.status ? String(job.status) : "";
+ const warningsPresent = Boolean(job?.warnings && String(job.warnings).trim());
+
+ const dossierUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}`;
+ const traceUrl = `${primaryBase}/static/trace/${encodeURIComponent(shareId)}`;
+ const downloadUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}/download`;
+ const packUrl = `${primaryBase}/static/pack/${encodeURIComponent(shareId)}.md`;
+ const sourceUrl = job?.sourceSha256
+ ? `${primaryBase}/static/source/${job.sourceSha256}${path.extname(job.sourcePath || "").toLowerCase()}`
+ : "";
+
+ const directBase = primaryBase; // Caddy exposes /r/* on infrafabric.io and git.infrafabric.io too.
+ const directDossierUrl = `${directBase}/r/${encodeURIComponent(shareId)}`;
+ const directTraceUrl = `${directBase}/r/${encodeURIComponent(shareId)}/trace`;
+ const directDownloadUrl = `${directBase}/r/${encodeURIComponent(shareId)}/download`;
+ const directPackUrl = `${directBase}/r/${encodeURIComponent(shareId)}/pack.md`;
+
+ const lastResortBase = normalizeBaseUrl(publicBaseUrl);
+ const lastResortDossierUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}` : "";
+ const lastResortTraceUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}/trace` : "";
+ const lastResortDownloadUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}/download` : "";
+
+ const lines = [
+ "# IF.TTT trace (public evidence view)",
+ "",
+ "## Trace verification status",
+ "",
+ `**${verificationStatus}**${verificationDetail ? ` — ${verificationDetail}` : ""}`,
+ "",
+ "- Output hash check: " + (verificationChecks.outputOk ? "**PASS**" : "**FAIL**"),
+ "- Source hash check: " + (verificationChecks.sourceOk === true ? "**PASS**" : verificationChecks.sourceOk === false ? "**FAIL**" : "**UNKNOWN**"),
+ "- Quality warnings: " + (warningsPresent ? "**present**" : "none recorded"),
+ "",
+ "IF.TTT (Traceable, Transparent, Trustworthy) is InfraFabric’s chain-of-custody protocol: it binds the **source fingerprint** to the **generated output fingerprint**, so a skeptical reader can verify what was produced and from which input, without needing access to internal systems.",
+ "This page is intentionally scoped to **one dossier only** (no index, no directory listing).",
+ "",
+ "## What this trace proves",
+ "",
+ "- You can independently verify the downloaded dossier Markdown by hashing it and comparing to `Output sha256` below.",
+ "- You can independently verify the hosted source file (if present) by hashing it and comparing to `Source sha256` below.",
+ "- This page binds those two fingerprints together as a single public evidence record.",
+ "",
+ "## What this trace does not prove",
+ "",
+ "- It does not validate the truth of the source’s claims.",
+ "- It does not attest to correctness of any commentary or recommendations in the dossier.",
+ "- It does not expose internal prompts, intermediate steps, or private systems.",
+ "",
+ "## Links",
+ "",
+ `- Dossier (rendered): ${dossierUrl}`,
+ `- Dossier (download Markdown): ${downloadUrl}`,
+ `- Single-file pack (review + dossier + trace): ${packUrl}`,
+ sourceUrl ? `- Source (PDF): ${sourceUrl}` : null,
+ `- This trace page: ${traceUrl}`,
+ mirrorBase ? "" : null,
+ mirrorBase ? "## Mirror host (same paths)" : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? `- Dossier: ${mirrorBase}/static/dossier/${encodeURIComponent(shareId)}` : null,
+ mirrorBase ? `- Pack: ${mirrorBase}/static/pack/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- Trace: ${mirrorBase}/static/trace/${encodeURIComponent(shareId)}` : null,
+ mirrorBase && sourceUrl ? `- Source: ${mirrorBase}/static/source/${job.sourceSha256}${path.extname(job.sourcePath || "").toLowerCase()}` : null,
+ "",
+ "## Fallback links (direct)",
+ "",
+ `- Dossier: ${directDossierUrl}`,
+ `- Download: ${directDownloadUrl}`,
+ `- Pack: ${directPackUrl}`,
+ `- Trace: ${directTraceUrl}`,
+ lastResortBase && lastResortBase !== directBase ? "" : null,
+ lastResortBase && lastResortBase !== directBase ? "## Last resort (alternate host)" : null,
+ lastResortBase && lastResortBase !== directBase ? "" : null,
+ lastResortBase && lastResortBase !== directBase ? `- Dossier: ${lastResortDossierUrl}` : null,
+ lastResortBase && lastResortBase !== directBase ? `- Download: ${lastResortDownloadUrl}` : null,
+ lastResortBase && lastResortBase !== directBase ? `- Trace: ${lastResortTraceUrl}` : null,
+ "",
+ "## Generation context",
+ "",
+ createdAt ? `- Generated at (UTC): \`${createdAt}\`` : null,
+ status ? `- Status: \`${status}\`` : null,
+ `- Quality warnings: ${warningsPresent ? "present (see pack trace JSON)" : "none recorded"}`,
+ "",
+ "## Verifiability",
+ "",
+ `- Trace ID: \`${job.id || ""}\``,
+ `- Dossier: \`${job.originalFilename || ""}\``,
+ `- Output sha256: \`${job.outputSha256 || ""}\``,
+ `- Source sha256: \`${job.sourceSha256 || ""}\``,
+ `- Style: \`${job.style || ""}\``,
+ `- Source bytes: \`${String(job.sourceBytes ?? "")}\``,
+ "",
+ "## How to verify (locally)",
+ "",
+ "1) Download the dossier Markdown.",
+ "2) Compute its hash and compare to `Output sha256` above:",
+ "",
+ "```bash",
+ "sha256sum .md",
+ "```",
+ "",
+ sourceUrl ? "3) Optionally, download the source and verify its hash matches `Source sha256` above:" : null,
+ sourceUrl ? "" : null,
+ sourceUrl
+ ? "```bash\nsha256sum \n```"
+ : null,
+ ];
+
+ return lines.filter(Boolean).join("\n");
+}
+
+function renderReviewPackMarkdown({ shareId, job, publicBaseUrl, externalReviewUrl, staticSourceUrl, staticPublicBaseUrl }) {
+ const primaryBase = normalizeBaseUrl(staticPublicBaseUrl || publicBaseUrl);
+ const bases = staticMirrorBaseUrls(primaryBase, publicBaseUrl);
+ const mirrorBase = bases.find((b) => b !== primaryBase) || "";
+
+ const dossierUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}`;
+ const traceUrl = `${primaryBase}/static/trace/${encodeURIComponent(shareId)}`;
+ const downloadUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}/download`;
+ const packUrl = `${primaryBase}/static/pack/${encodeURIComponent(shareId)}.md`;
+
+ const directBase = primaryBase; // Caddy exposes /r/* on infrafabric.io and git.infrafabric.io too.
+ const directDossierUrl = `${directBase}/r/${encodeURIComponent(shareId)}`;
+ const directTraceUrl = `${directBase}/r/${encodeURIComponent(shareId)}/trace`;
+ const directDownloadUrl = `${directBase}/r/${encodeURIComponent(shareId)}/download`;
+ const directPackUrl = `${directBase}/r/${encodeURIComponent(shareId)}/pack.md`;
+
+ const lastResortBase = normalizeBaseUrl(publicBaseUrl);
+ const lastResortDossierUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}` : "";
+ const lastResortTraceUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}/trace` : "";
+ const lastResortDownloadUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}/download` : "";
+ const lastResortPackUrl = lastResortBase ? `${lastResortBase}/r/${encodeURIComponent(shareId)}/pack.md` : "";
+
+ const lines = [
+ "# InfraFabric External Review Pack — Shadow Dossier + IF.TTT trace",
+ "",
+ "Please review the dossier and the IF.TTT trace page. Provide constructive criticism and patch-style suggestions.",
+ "",
+ "## Assets",
+ "",
+ `- Dossier (rendered): ${dossierUrl}`,
+ `- Dossier (download Markdown): ${downloadUrl}`,
+ `- Single-file pack (review + dossier + trace): ${packUrl}`,
+ staticSourceUrl ? `- Source (download): ${staticSourceUrl}` : null,
+ `- IF.TTT trace page: ${traceUrl}`,
+ externalReviewUrl ? `- Feedback intake (login): ${externalReviewUrl}` : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? "## Alternate host mirror (same paths)" : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? `- Dossier (rendered): ${mirrorBase}/static/dossier/${encodeURIComponent(shareId)}` : null,
+ mirrorBase ? `- Dossier (download Markdown): ${mirrorBase}/static/dossier/${encodeURIComponent(shareId)}/download` : null,
+ mirrorBase ? `- Single-file pack: ${mirrorBase}/static/pack/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- IF.TTT trace page: ${mirrorBase}/static/trace/${encodeURIComponent(shareId)}` : null,
+ "",
+ "## Fallback links (direct)",
+ "",
+ "- These may be blocked by some scanners/LLM sandboxes; use only if the `infrafabric.io/static/*` links fail.",
+ "",
+ `- Dossier (rendered): ${directDossierUrl}`,
+ `- Dossier (download Markdown): ${directDownloadUrl}`,
+ `- Single-file pack (review + dossier + trace): ${directPackUrl}`,
+ `- IF.TTT trace page: ${directTraceUrl}`,
+ lastResortBase && lastResortBase !== directBase ? "" : null,
+ lastResortBase && lastResortBase !== directBase ? "## Last resort (alternate host)" : null,
+ lastResortBase && lastResortBase !== directBase ? "" : null,
+ lastResortBase && lastResortBase !== directBase ? `- Dossier (rendered): ${lastResortDossierUrl}` : null,
+ lastResortBase && lastResortBase !== directBase ? `- Dossier (download): ${lastResortDownloadUrl}` : null,
+ lastResortBase && lastResortBase !== directBase ? `- Pack: ${lastResortPackUrl}` : null,
+ lastResortBase && lastResortBase !== directBase ? `- Trace: ${lastResortTraceUrl}` : null,
+ "",
+ "## Response metadata (required)",
+ "",
+ "- `llm_name`: provider + model name/version (exact string)",
+ "- `probable_model`: if `llm_name` is ambiguous, your best guess",
+ "- `cutoff_date`: training data cutoff (YYYY-MM, or “unknown”)",
+ "- `response_date_utc`: current date/time in UTC",
+ "- `web_access_used`: `yes`/`no` (if yes, list URLs relied on)",
+ "",
+ "## Executive read (fast)",
+ "",
+ "- 5–10 bullets: what works / what doesn’t",
+ "- 3 bullets: who this will land with vs who will reject it",
+ "",
+ "## Scorecard (0–5 each)",
+ "",
+ "- Mirror integrity (section order, headings, high-signal numbers/dates, lists/tables)",
+ "- Layout fidelity (does it “feel” like the source?)",
+ "- Humor discipline (sharp without being template-y)",
+ "- Mermaid value (valid syntax; clarifies, not decorates)",
+ "- IF.TTT demo value (understandable + credible + worth clicking)",
+ "- Call-to-action stealth (curious about governance stack without feeling spammed)",
+ "",
+ "## Patch suggestions (actionable)",
+ "",
+ "Provide 5–15 patch suggestions. Use this format per item:",
+ "",
+ "- `target`: dossier / trace page / “generator rules” / site UX",
+ "- `problem`: 1 sentence",
+ "- `change`: proposed text or behavior (copy/pasteable if possible)",
+ "- `why`: 1 sentence",
+ "- `priority`: P0 / P1 / P2",
+ "- `confidence`: high / medium / low",
+ "",
+ "## Plan iteration (debug our plan)",
+ "",
+ "Propose a revised 5–8 step plan for improving the system. Prioritize steps that:",
+ "",
+ "- reduce repeatable/template patterns",
+ "- strengthen mirror fidelity (numbers/tables/caveats)",
+ "- make Mermaid + output correct-by-construction",
+ "- make IF.TTT feel like real chain-of-custody (not just “we printed a hash”)",
+ "",
+ "## Fact checking guidance (important)",
+ "",
+ "Default posture: don’t assume stats are true.",
+ "",
+ "- If you did not verify a number externally, refer to it as “the source claims …”",
+ "- If you did verify, cite URLs and state confirmed/disputed/unclear",
+ "- If a stat cannot be confirmed, recommend either: keep it attributed (“source claims”) or remove it from commentary",
+ "",
+ "## Notes",
+ "",
+ `- Dossier ID: \`${job.id || ""}\``,
+ `- Style: \`${job.style || ""}\``,
+ ]
+ .filter((line) => line !== null)
+ .join("\n");
+
+ return lines;
+}
+
+function renderSingleFilePackMarkdown({ shareId, job, publicBaseUrl, externalReviewUrl, staticSourceUrl, staticPublicBaseUrl, dossierMarkdown }) {
+ const primaryBase = normalizeBaseUrl(staticPublicBaseUrl || publicBaseUrl);
+ const bases = staticMirrorBaseUrls(primaryBase, publicBaseUrl);
+ const mirrorBase = bases.find((b) => b !== primaryBase) || "";
+
+ const dossierUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}`;
+ const traceUrl = `${primaryBase}/static/trace/${encodeURIComponent(shareId)}`;
+ const downloadUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}/download`;
+ const reviewUrl = `${primaryBase}/static/review/${encodeURIComponent(shareId)}.md`;
+ const packUrl = `${primaryBase}/static/pack/${encodeURIComponent(shareId)}.md`;
+
+ const jobSlim = {
+ id: job?.id || "",
+ status: job?.status || "",
+ createdAt: job?.createdAt || "",
+ originalFilename: job?.originalFilename || "",
+ style: job?.style || "",
+ sourceSha256: job?.sourceSha256 || "",
+ outputSha256: job?.outputSha256 || "",
+ warnings: job?.warnings || "",
+ };
+
+ const lines = [
+ "# InfraFabric External Review Pack — Single File",
+ "",
+ "This is a single-file bundle intended for review environments that cannot reliably fetch multiple URLs.",
+ "",
+ "## Links",
+ "",
+ `- Pack (this file): ${packUrl}`,
+ `- Review pack (links only): ${reviewUrl}`,
+ `- Dossier (rendered): ${dossierUrl}`,
+ `- Dossier (download Markdown): ${downloadUrl}`,
+ `- IF.TTT trace page: ${traceUrl}`,
+ staticSourceUrl ? `- Source (download): ${staticSourceUrl}` : null,
+ externalReviewUrl ? `- Feedback intake (login): ${externalReviewUrl}` : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? "## Alternate host mirror (same paths)" : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? `- Pack (this file): ${mirrorBase}/static/pack/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- Review pack: ${mirrorBase}/static/review/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- Dossier: ${mirrorBase}/static/dossier/${encodeURIComponent(shareId)}` : null,
+ mirrorBase ? `- Trace: ${mirrorBase}/static/trace/${encodeURIComponent(shareId)}` : null,
+ "",
+ "## Review instructions (portable)",
+ "",
+ "Hard rules:",
+ "1) 100% factual: every non-trivial claim must be tagged [SOURCE]/[DOSSIER]/[TRACE]/[INFERENCE]. If unverified, say “unverified” and stop.",
+ "2) Vendor-neutral: critique deployment conditions + org behaviors, not vendor intent/competence.",
+ "3) Mirror discipline: follow the dossier’s section order; do not invent a new structure.",
+ "",
+ "Deliverables:",
+ "A) 5–10 bullets: what works / what doesn’t (tag each)",
+ "B) Scorecard (0–5): mirror integrity, layout fidelity, humor discipline, mermaid value, IF.TTT demo value, CTA stealth",
+ "C) Section-by-section critique (mirror headings): what’s mirrored, what’s missing, what feels templated/repeated",
+ "D) Vendor-safe conclusion rewrite: success conditions / traps / questions-to-ask-vendor",
+ "E) Unified diff patches against `IF_DAVE_BIBLE_v1.3.md` (and patchset if needed)",
+ "",
+ "## IF.TTT trace (portable extract)",
+ "",
+ "```json",
+ JSON.stringify(jobSlim, null, 2),
+ "```",
+ "",
+ "## Shadow dossier (Markdown)",
+ "",
+ "```markdown",
+ String(dossierMarkdown || "").trim(),
+ "```",
+ "",
+ ];
+
+ return lines.filter((line) => line !== null && line !== undefined).join("\n");
+}
+
+function extractSection(markdownText, sectionMatcher) {
+ const text = String(markdownText || "");
+ if (!text.trim()) return "";
+ const lines = text.split("\n");
+ const headingRe = /^##\s+/;
+ let start = -1;
+ for (let i = 0; i < lines.length; i++) {
+ if (!headingRe.test(lines[i])) continue;
+ const title = lines[i].replace(/^##\s+/, "").trim();
+ if (sectionMatcher && sectionMatcher.test(title)) {
+ start = i;
+ break;
+ }
+ }
+ if (start === -1) return "";
+ let end = lines.length;
+ for (let i = start + 1; i < lines.length; i++) {
+ if (headingRe.test(lines[i])) {
+ end = i;
+ break;
+ }
+ }
+ return lines.slice(start, end).join("\n").trim();
+}
+
+function extractFirstMermaid(markdownText) {
+ const text = String(markdownText || "");
+ const m = text.match(/```mermaid\s+([\s\S]*?)```/m);
+ return m ? String(m[1] || "").trim() : "";
+}
+
+function extractHeroMermaid(dossierMarkdown) {
+ // Prefer the section that usually produces the most "hero" marketing loop for this dossier: audits.
+ const sec02 = extractSection(dossierMarkdown, /^02\b/);
+ const sec02Diagram = extractFirstMermaid(sec02);
+ if (sec02Diagram) return { label: "Audit theater loop", diagram: sec02Diagram };
+ const any = extractFirstMermaid(dossierMarkdown);
+ if (any) return { label: "Incentive loop (inferred)", diagram: any };
+ return { label: "", diagram: "" };
+}
+
+function renderMarketingPackMarkdown({ shareId, job, publicBaseUrl, staticPublicBaseUrl, staticSourceUrl, dossierMarkdown }) {
+ const primaryBase = normalizeBaseUrl(staticPublicBaseUrl || publicBaseUrl);
+ const bases = staticMirrorBaseUrls(primaryBase, publicBaseUrl);
+ const mirrorBase = bases.find((b) => b !== primaryBase) || "";
+
+ const marketingUrl = `${primaryBase}/static/marketing/${encodeURIComponent(shareId)}.md`;
+ const dossierUrl = `${primaryBase}/static/dossier/${encodeURIComponent(shareId)}`;
+ const traceUrl = `${primaryBase}/static/trace/${encodeURIComponent(shareId)}`;
+ const packUrl = `${primaryBase}/static/pack/${encodeURIComponent(shareId)}.md`;
+
+ const hero = extractHeroMermaid(dossierMarkdown);
+
+ const lines = [
+ "# InfraFabric Red Team — Marketing-safe excerpt",
+ "",
+ "This is a **marketing-safe surface** for sharing a Shadow Dossier without rewriting it into “features”.",
+ "",
+ "## One sentence (blessed)",
+ "",
+ "> InfraFabric shows why AI controls fail in practice and what must be true for them to hold.",
+ "",
+ "## Hero asset (blessed)",
+ "",
+ hero.diagram ? `### ${hero.label}` : "### (No diagram available)",
+ "",
+ hero.diagram ? "```mermaid" : null,
+ hero.diagram ? hero.diagram : null,
+ hero.diagram ? "```" : null,
+ "",
+ "## Allowed pulls (blessed)",
+ "",
+ "- Section titles",
+ "- “Dave Factor” blocks (verbatim)",
+ "- Mermaid diagrams (unchanged)",
+ "- Red Team Conclusion questions (verbatim)",
+ "",
+ "## Forbidden moves (do not do this)",
+ "",
+ "- Rewriting countermeasures as product capabilities",
+ "- Adding adjectives that imply guarantees (\"proven\", \"complete\", \"bulletproof\")",
+ "- Removing the “problem isn’t X” framing (it’s the vendor-safe contract)",
+ "- Inventing stats, timelines, or customer claims",
+ "",
+ "## CTAs (safe buttons)",
+ "",
+ "- Run this against your own rollout",
+ "- See the trace behind this critique",
+ "- Ask these questions internally",
+ "",
+ "## Links",
+ "",
+ `- Marketing excerpt (this file): ${marketingUrl}`,
+ `- Full dossier (rendered): ${dossierUrl}`,
+ `- Single-file pack (review + dossier + trace): ${packUrl}`,
+ `- IF.TTT trace: ${traceUrl}`,
+ staticSourceUrl ? `- Source (PDF): ${staticSourceUrl}` : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? "## Mirror host (same paths)" : null,
+ mirrorBase ? "" : null,
+ mirrorBase ? `- Marketing excerpt: ${mirrorBase}/static/marketing/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- Full dossier: ${mirrorBase}/static/dossier/${encodeURIComponent(shareId)}` : null,
+ mirrorBase ? `- Pack: ${mirrorBase}/static/pack/${encodeURIComponent(shareId)}.md` : null,
+ mirrorBase ? `- Trace: ${mirrorBase}/static/trace/${encodeURIComponent(shareId)}` : null,
+ ].filter((l) => l !== null);
+
+ return lines.join("\n");
+}
+
+function ensureStaticSourceFile({ job, uploadsDir, staticSourceDir, projectRoot }) {
+ if (!job?.sourcePath) return null;
+ if (!job?.sourceSha256) return null;
+
+ const ext = path.extname(String(job.sourcePath || "")).slice(0, 12).toLowerCase() || ".bin";
+ const fileName = `${job.sourceSha256}${ext}`;
+ const destAbs = path.join(staticSourceDir, fileName);
+ if (fs.existsSync(destAbs)) return { fileName, destAbs, urlPath: `/static/source/${fileName}` };
+
+ const srcAbs = path.resolve(projectRoot, job.sourcePath);
+ if (!srcAbs.startsWith(uploadsDir + path.sep)) return null;
+ if (!fs.existsSync(srcAbs)) return null;
+
+ ensureDir(staticSourceDir);
+ fs.copyFileSync(srcAbs, destAbs);
+ return { fileName, destAbs, urlPath: `/static/source/${fileName}` };
+}
+
+function buildExternalReviewUrl(baseUrl, sheetId) {
+ const base = String(baseUrl || "").trim();
+ const id = String(sheetId || "").trim();
+ if (!base || !id) return "";
+ try {
+ const u = new URL(base);
+ u.searchParams.set("sheet", id);
+ return u.toString();
+ } catch {
+ return base.includes("?") ? `${base}&sheet=${encodeURIComponent(id)}` : `${base}?sheet=${encodeURIComponent(id)}`;
+ }
+}
+
+function publicBaseFromRequest(req, fallbackHost) {
+ const host = req.get("host") || fallbackHost || "red-team.infrafabric.io";
+ const protocol = req.protocol || "https";
+ return `${protocol}://${host}`.replace(/\/+$/g, "");
+}
+
+function staticPublicBaseUrlForRequest(req, fallbackPublicBaseUrl) {
+ const explicit = String(process.env.STATIC_SOURCE_PUBLIC_BASE_URL || "").trim();
+ if (explicit) return explicit.replace(/\/+$/g, "");
+ return publicBaseFromRequest(req, fallbackPublicBaseUrl);
+}
+
function looksLikeUuid(value) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(String(value || ""));
}
@@ -55,6 +692,25 @@ function writeJob(jobsDir, job) {
fs.writeFileSync(p, JSON.stringify(job, null, 2) + "\n", "utf8");
}
+function shareJsonPath(sharesDir, shareId) {
+ return path.join(sharesDir, `${shareId}.json`);
+}
+
+function writeShare(sharesDir, shareId, data) {
+ const p = shareJsonPath(sharesDir, shareId);
+ fs.writeFileSync(p, JSON.stringify(data, null, 2) + "\n", "utf8");
+}
+
+function readShare(sharesDir, shareId) {
+ const p = shareJsonPath(sharesDir, shareId);
+ if (!fs.existsSync(p)) return null;
+ try {
+ return JSON.parse(fs.readFileSync(p, "utf8"));
+ } catch {
+ return null;
+ }
+}
+
async function sha256File(filePath) {
return await new Promise((resolve, reject) => {
const h = crypto.createHash("sha256");
@@ -104,9 +760,13 @@ async function generateShadowDossier({ inputPath, outputPath }) {
PYTHONPATH: path.join(revoiceRepoRoot, "src"),
};
+ const genArgs = ["-m", "revoice", "generate", "--style", privateUploadStyle];
+ if (["1", "true", "yes", "on"].includes(privateUploadActionPack)) genArgs.push("--action-pack");
+ genArgs.push("--input", inputPath, "--output", outputPath);
+
const gen = await runProcess(
"python3",
- ["-m", "revoice", "generate", "--style", privateUploadStyle, "--input", inputPath, "--output", outputPath],
+ genArgs,
{ cwd: revoiceRepoRoot, env: baseEnv }
);
if (gen.code !== 0) {
@@ -166,17 +826,26 @@ function generateRoastText(content) {
function main() {
const port = Number(process.env.PORT || 8080);
const app = express();
- const dataDir = path.join(projectRoot, "data");
+ app.set("trust proxy", true);
+ const configuredDataDir = String(process.env.RED_TEAM_DATA_DIR || "").trim();
+ const dataDir = configuredDataDir ? path.resolve(configuredDataDir) : path.join(projectRoot, "data");
const uploadsDir = path.join(dataDir, "uploads");
const outputsDir = path.join(dataDir, "outputs");
const jobsDir = path.join(dataDir, "jobs");
+ const sharesDir = path.join(dataDir, "shares");
+ const staticDir = path.join(dataDir, "static");
+ const staticSourceDir = path.join(staticDir, "source");
ensureDir(uploadsDir);
ensureDir(outputsDir);
ensureDir(jobsDir);
+ ensureDir(sharesDir);
+ ensureDir(staticDir);
+ ensureDir(staticSourceDir);
app.disable("x-powered-by");
app.use(express.json({ limit: "256kb" }));
+ app.use("/static", express.static(staticDir, { fallthrough: false, etag: true, maxAge: "30d" }));
app.get("/healthz", (_req, res) => {
res.status(200).json({ ok: true });
@@ -256,7 +925,16 @@ function main() {
const refresh = isDone || isError ? "" : "";
const downloadLink = isDone
- ? `Download shadow dossier
`
+ ? `Download Markdown
`
+ : "";
+ const viewLink = isDone
+ ? `View rendered dossier
`
+ : "";
+ const shareLinks = isDone && job.shareId
+ ? [
+ "Share links (no repo):
",
+ `Public view · Public download
`,
+ ].join("")
: "";
const sourceLink = job.sourcePath
@@ -285,8 +963,11 @@ function main() {
job.originalFilename ? `Source: ${escapeHtml(job.originalFilename)}
` : "",
job.sourceSha256 ? `Source sha256: ${escapeHtml(job.sourceSha256)}
` : "",
job.outputSha256 ? `Output sha256: ${escapeHtml(job.outputSha256)}
` : "",
+ job.shareId ? `Share ID: ${escapeHtml(job.shareId)}
` : "",
downloadLink,
+ viewLink,
sourceLink,
+ shareLinks,
warnings ? "Warnings
" + warnings : "",
isError ? "Error
" + error : "",
`Back to upload
`,
@@ -295,6 +976,209 @@ function main() {
);
});
+ app.get("/private/:token/view/:jobId", privateGuard, (req, res) => {
+ const jobId = String(req.params.jobId || "");
+ if (!looksLikeUuid(jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, jobId);
+ if (!job) return res.status(404).type("text/plain").send("Not found");
+ if (!job.outputPath) return res.status(409).type("text/plain").send("Not ready");
+
+ const abs = path.resolve(projectRoot, job.outputPath);
+ if (!abs.startsWith(outputsDir + path.sep)) return res.status(400).type("text/plain").send("Bad path");
+ if (!fs.existsSync(abs)) return res.status(404).type("text/plain").send("Not found");
+
+ const mdText = fs.readFileSync(abs, "utf8");
+ const html = markdown.render(mdText);
+
+ const token = req.params.token;
+ const topLinks = [
+ `Download Markdown`,
+ job.sourcePath ? `Download source` : "",
+ job.shareId ? `Share view` : "",
+ ]
+ .filter(Boolean)
+ .join(" · ");
+
+ res.status(200).type("text/html; charset=utf-8").send(renderMarkdownPage({ title: job.originalFilename || "Shadow dossier", html, topLinksHtml: topLinks }));
+ });
+
+ app.get("/r/:shareId/trace", async (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const verification = await computeVerificationStatus({ job, projectRoot, outputsDir, uploadsDir });
+ const jobForRender = { ...job, _verification: verification };
+
+ const publicBaseUrl = publicBaseFromRequest(req, "red-team.infrafabric.io");
+ const staticPublicBaseUrl = staticPublicBaseUrlForRequest(req, publicBaseUrl);
+ const md = renderTraceMarkdown({ shareId, job: jobForRender, publicBaseUrl, staticPublicBaseUrl });
+ const html = markdown.render(md);
+
+ const badge = renderVerificationBadgeHtml(verification);
+ const topLinks = [
+ badge,
+ `Back to dossier`,
+ `Download Markdown`,
+ job.sourcePath ? `Download source` : "",
+ `Review pack (MD)`,
+ ]
+ .filter(Boolean)
+ .join(" · ");
+
+ res
+ .status(200)
+ .type("text/html; charset=utf-8")
+ .send(renderMarkdownPage({ title: "IF.TTT trace", html, topLinksHtml: topLinks }));
+ });
+
+ app.get("/r/:shareId/source", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.sourcePath) return res.status(404).type("text/plain").send("Not found");
+
+ const staticFile = ensureStaticSourceFile({ job, uploadsDir, staticSourceDir, projectRoot });
+ if (!staticFile) return res.status(404).type("text/plain").send("Not found");
+ res.redirect(302, staticFile.urlPath);
+ });
+
+ app.get("/r/:shareId/review-pack.md", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const staticSource = ensureStaticSourceFile({ job, uploadsDir, staticSourceDir, projectRoot });
+ const externalReviewBaseUrl = String(process.env.EXTERNAL_REVIEW_BASE_URL || "https://emo-social.infrafabric.io/external-review.html");
+ const externalReviewUrl = buildExternalReviewUrl(externalReviewBaseUrl, share.reviewSheetId);
+ const publicBaseUrl = publicBaseFromRequest(req, "red-team.infrafabric.io");
+ const staticPublicBaseUrl = staticPublicBaseUrlForRequest(req, publicBaseUrl);
+ const staticSourceUrl = staticSource ? `${staticPublicBaseUrl}${staticSource.urlPath}` : "";
+
+ const md = renderReviewPackMarkdown({ shareId, job, publicBaseUrl, externalReviewUrl, staticSourceUrl, staticPublicBaseUrl });
+ const baseName = (job.originalFilename || "dossier").replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 60);
+ res
+ .status(200)
+ .type("text/markdown; charset=utf-8")
+ .send(md);
+ });
+
+ app.get("/r/:shareId/pack.md", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const abs = path.resolve(projectRoot, job.outputPath);
+ if (!abs.startsWith(outputsDir + path.sep)) return res.status(400).type("text/plain").send("Bad path");
+ if (!fs.existsSync(abs)) return res.status(404).type("text/plain").send("Not found");
+ const dossierMarkdown = fs.readFileSync(abs, "utf8");
+
+ const staticSource = ensureStaticSourceFile({ job, uploadsDir, staticSourceDir, projectRoot });
+ const externalReviewBaseUrl = String(process.env.EXTERNAL_REVIEW_BASE_URL || "https://emo-social.infrafabric.io/external-review.html");
+ const externalReviewUrl = buildExternalReviewUrl(externalReviewBaseUrl, share.reviewSheetId);
+ const publicBaseUrl = publicBaseFromRequest(req, "red-team.infrafabric.io");
+ const staticPublicBaseUrl = staticPublicBaseUrlForRequest(req, publicBaseUrl);
+ const staticSourceUrl = staticSource ? `${staticPublicBaseUrl}${staticSource.urlPath}` : "";
+
+ const md = renderSingleFilePackMarkdown({
+ shareId,
+ job,
+ publicBaseUrl,
+ externalReviewUrl,
+ staticSourceUrl,
+ staticPublicBaseUrl,
+ dossierMarkdown,
+ });
+
+ res.status(200).type("text/markdown; charset=utf-8").send(md);
+ });
+
+ app.get("/r/:shareId/marketing.md", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const abs = path.resolve(projectRoot, job.outputPath);
+ if (!abs.startsWith(outputsDir + path.sep)) return res.status(400).type("text/plain").send("Bad path");
+ if (!fs.existsSync(abs)) return res.status(404).type("text/plain").send("Not found");
+ const dossierMarkdown = fs.readFileSync(abs, "utf8");
+
+ const staticSource = ensureStaticSourceFile({ job, uploadsDir, staticSourceDir, projectRoot });
+ const publicBaseUrl = publicBaseFromRequest(req, "red-team.infrafabric.io");
+ const staticPublicBaseUrl = staticPublicBaseUrlForRequest(req, publicBaseUrl);
+ const staticSourceUrl = staticSource ? `${staticPublicBaseUrl}${staticSource.urlPath}` : "";
+
+ const md = renderMarketingPackMarkdown({
+ shareId,
+ job,
+ publicBaseUrl,
+ staticPublicBaseUrl,
+ staticSourceUrl,
+ dossierMarkdown,
+ });
+
+ res.status(200).type("text/markdown; charset=utf-8").send(md);
+ });
+
+ app.get("/r/:shareId", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const abs = path.resolve(projectRoot, job.outputPath);
+ if (!abs.startsWith(outputsDir + path.sep)) return res.status(400).type("text/plain").send("Bad path");
+ if (!fs.existsSync(abs)) return res.status(404).type("text/plain").send("Not found");
+
+ const mdText = fs.readFileSync(abs, "utf8");
+ const html = markdown.render(mdText);
+ const externalReviewBaseUrl = String(process.env.EXTERNAL_REVIEW_BASE_URL || "https://emo-social.infrafabric.io/external-review.html");
+ const externalReviewUrl = buildExternalReviewUrl(externalReviewBaseUrl, share.reviewSheetId);
+ const topLinks = [
+ `Download Markdown`,
+ job.sourcePath ? `Download source` : "",
+ `IF.TTT trace`,
+ `Review pack (MD)`,
+ `Marketing excerpt (MD)`,
+ externalReviewUrl ? `Feedback intake (login)` : "",
+ ]
+ .filter(Boolean)
+ .join(" · ");
+ res.status(200).type("text/html; charset=utf-8").send(renderMarkdownPage({ title: job.originalFilename || "Shadow dossier", html, topLinksHtml: topLinks }));
+ });
+
+ app.get("/r/:shareId/download", (req, res) => {
+ const shareId = String(req.params.shareId || "").trim();
+ if (!shareId) return res.status(404).type("text/plain").send("Not found");
+ const share = readShare(sharesDir, shareId);
+ if (!share?.jobId || !looksLikeUuid(share.jobId)) return res.status(404).type("text/plain").send("Not found");
+ const job = readJob(jobsDir, share.jobId);
+ if (!job?.outputPath) return res.status(404).type("text/plain").send("Not found");
+
+ const abs = path.resolve(projectRoot, job.outputPath);
+ if (!abs.startsWith(outputsDir + path.sep)) return res.status(400).type("text/plain").send("Bad path");
+ if (!fs.existsSync(abs)) return res.status(404).type("text/plain").send("Not found");
+
+ const baseName = (job.originalFilename || "dossier").replace(/[^A-Za-z0-9._-]+/g, "-").slice(0, 60);
+ res.download(abs, `${baseName}.shadow.dave.md`);
+ });
+
app.get("/private/:token/download/:jobId", privateGuard, (req, res) => {
const jobId = String(req.params.jobId || "");
if (!looksLikeUuid(jobId)) return res.status(404).type("text/plain").send("Not found");
@@ -328,8 +1212,9 @@ function main() {
if (!file?.path) return res.status(400).type("text/plain").send("Missing file");
const relSourcePath = path.relative(projectRoot, file.path);
- const relOutputPath = path.join("data", "outputs", `${jobId}.shadow.dave.md`);
- const absOutputPath = path.resolve(projectRoot, relOutputPath);
+ const absOutputPath = path.join(outputsDir, `${jobId}.shadow.dave.md`);
+ const relOutputPath = path.relative(projectRoot, absOutputPath);
+ const shareId = crypto.randomBytes(18).toString("base64url");
const now = new Date().toISOString();
const job = {
@@ -339,6 +1224,7 @@ function main() {
originalFilename: file.originalname || "",
sourcePath: relSourcePath,
outputPath: relOutputPath,
+ shareId,
style: privateUploadStyle,
sourceBytes: Number(file.size || 0),
sourceSha256: "",
@@ -357,6 +1243,7 @@ function main() {
}
writeJob(jobsDir, job);
+ writeShare(sharesDir, shareId, { shareId, jobId, createdAt: now });
void (async () => {
try {