Skip to content

Add collaborative LaTeX macro safety guard#393

Open
karollooool wants to merge 1 commit into
SCIBASE-AI:mainfrom
karollooool:codex/collab-latex-macro-safety
Open

Add collaborative LaTeX macro safety guard#393
karollooool wants to merge 1 commit into
SCIBASE-AI:mainfrom
karollooool:codex/collab-latex-macro-safety

Conversation

@karollooool
Copy link
Copy Markdown

/claim #12

Summary

Adds a self-contained collaborative LaTeX macro safety guard for the real-time collaborative research editor.

This slice validates synchronized Markdown/LaTeX editor packets before live preview or named-version export by checking:

  • conflicting collaborator macro definitions
  • unsafe macro commands such as raw HTML helpers, links, and image/resource includes
  • recursive macro expansion cycles that can hang live render/export
  • unapproved macro edits in shared named versions
  • raw active HTML and unapproved external render resources in Markdown/LaTeX blocks
  • locked-section render holds when risky macro packets affect controlled sections

Non-overlap

This targets collaborative LaTeX/KaTeX macro render safety. It does not implement a broad editor foundation, operation replay, offline conflict handling, notebook workbench/kernel lease, reference formatting or reference merge, authorship governance, freeze/recovery, discussion sidebar, autosave, round-trip fidelity, review decision gates, task dependency, equation/figure anchors, presence privacy/liveness, accessibility, manuscript evidence binding, embargo release, or notification visibility.

Safety

  • Synthetic fixtures only in collaborative-latex-macro-safety-guard/sample-data.js
  • No live users, private manuscripts, browser sessions, credentials, external services, wallet material, or payment data
  • Dependency-free evaluator/tests; ffmpeg is only optional for regenerating the committed demo video

Demo artifacts

  • collaborative-latex-macro-safety-guard/reports/demo.json
  • collaborative-latex-macro-safety-guard/reports/demo.md
  • collaborative-latex-macro-safety-guard/reports/demo.svg
  • collaborative-latex-macro-safety-guard/reports/demo.mp4

Validation

  • npm run check
  • npm test
  • npm run demo
  • npm run demo:video with FFMPEG_PATH pointing to a temporary ffmpeg-static binary outside the repo
  • ffmpeg -v error -i collaborative-latex-macro-safety-guard/reports/demo.mp4 -f null -
  • git diff --check
  • git diff --cached --check
  • rg -n "token|secret|password|private key|BEGIN|sk-|ghp_|github_pat|wallet|seed phrase" README.md collaborative-latex-macro-safety-guard -> no matches

AI-assisted with Codex; reviewed and locally verified before submission.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a self-contained “collaborative LaTeX macro safety guard” slice that evaluates collaborative Markdown/LaTeX macro packets for safety risks (unsafe macros, recursion, external resources, locked-section holds) and produces deterministic JSON/Markdown/SVG demo artifacts.

Changes:

  • Introduces a dependency-free evaluator (evaluateMacroPacket) and report renderers (Markdown/SVG) for collaborative macro safety gating.
  • Adds synthetic sample packets plus a demo script that generates deterministic report artifacts.
  • Adds a minimal Node-based test and an optional ffmpeg script to render a demo video card.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Links the new safety-guard module from the repo root README.
collaborative-latex-macro-safety-guard/index.js Core policy, packet evaluation checks, and Markdown/SVG report rendering.
collaborative-latex-macro-safety-guard/sample-data.js Synthetic “ready / blocked / needs_review” packets used by demo/tests.
collaborative-latex-macro-safety-guard/test.js Node assert-based tests covering evaluator decisions and renderers.
collaborative-latex-macro-safety-guard/demo.js Generates deterministic JSON/MD/SVG report artifacts into reports/.
collaborative-latex-macro-safety-guard/scripts/render-demo-video.js Optional ffmpeg-driven MP4 rendering for demo output.
collaborative-latex-macro-safety-guard/package.json Adds scripts (check, test, demo, demo:video) for the module.
collaborative-latex-macro-safety-guard/README.md Documents scope, requirement mapping, and how to run validation/demo.
collaborative-latex-macro-safety-guard/reports/demo.json Committed deterministic demo report output (JSON).
collaborative-latex-macro-safety-guard/reports/demo.md Committed deterministic demo report output (Markdown).
collaborative-latex-macro-safety-guard/reports/demo.svg Committed deterministic demo report output (SVG).
Comments suppressed due to low confidence (1)

collaborative-latex-macro-safety-guard/index.js:390

  • findMacroCycle() returns visited when the traversal exceeds maxDepth (i.e., no cycle found within the limit). Because callers treat any non-empty return as a cycle, this will raise RECURSIVE_MACRO_EXPANSION false positives for long-but-acyclic macro chains. Consider returning an empty array on depth exhaustion (or emitting a distinct "depth limit exceeded" warning/check code).
    if (visited.includes(nextName)) {
      return [...visited, nextName];
    }
    current = macroMap.get(nextName);
  }
  return visited;
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"\\url",
],
rawHtmlPattern: /<\s*(script|iframe|object|embed|link|meta|style)\b/i,
externalUrlPattern: /https?:\/\/([^)\s"']+)/gi,
Comment on lines +374 to +389
const visited = [];
let current = startMacro;
for (let depth = 0; depth <= maxDepth; depth += 1) {
visited.push(current.name);
const nextName = [...macroMap.keys()].find((name) =>
current.body.includes(name),
);
if (!nextName) {
return [];
}
if (visited.includes(nextName)) {
return [...visited, nextName];
}
current = macroMap.get(nextName);
}
return visited;
Comment on lines +322 to +325
function checkLockedSection(packet, addCheck, addIssue) {
const lockedBlocks = packet.blocks.filter((block) => block.locked);
const hasRenderRisk = packet.macros.some(
(macro) => !macro.approved || macro.body.includes("\\href"),
function escapeDrawtext(value) {
return String(value)
.replaceAll("\\", "\\\\")
.replaceAll(":", "\\:")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants