FAQ
How is this different from JSONL with a label field?
JSONL labels need a schema you invent — and re-invent every time the workflow changes. MarkBack is text-first, lives next to the file it annotates, and lints without you writing a validator. The semantics of <<< are fixed by the spec; the semantics of your JSONL label field are whatever you wrote in a Python script three months ago.
JSONL is still better when you already have a strict schema and a pipeline that consumes it. MarkBack is better when you want to leave a comment now and figure out the consumer later.
Why not just write comments in markdown?
Markdown comments (HTML-style <!-- --> or just plain prose) aren't machine-extractable without a convention. <<< is one rule, not a convention, and mb --lint enforces it. A linted file is a contract: the <<< lines are guaranteed to be the feedback, and everything above them is the content.
Why a new format when Label Studio / doccano / Argilla exist?
Those are apps with their own database, UI, and import/export contracts. MarkBack is a file format. No server, fits in git, no migration cycle when the app changes versions or shuts down.
If you need a hosted UI for labeling teams, Label Studio is a great choice. If you need annotation that diffs cleanly in pull requests and survives a git blame, MarkBack is better. They're not the same product.
Can I use this for images / PDFs / audio?
Yes — via sidecar files. Put your content in report.pdf; put your feedback in report.pdf.mb:
@id report-001
@by alice@example.com
<<< approved; grade=B+The original file stays untouched. Many sidecars can share a parent directory; lint them together with mb --lint ./*.mb.
Why two packages — markback and markbackjs?
Same format, same lint rules. Two packages so you can reach for the runtime your workflow already uses:
pip install markback— Python lib + CLI (mb).npm install markbackjs— Node lib for JS/TS pipelines and the browser try-it editor.
Both are 0.2.x+ and ship from the same monorepo. The CLI is Python only today; the Node package is library-only (and the engine the browser editor uses).
What does the V1 → V2 path look like?
V1 files parse transparently in V2 with a W010 warning per V1 header:
@uri→@id@source→@file@prior→@input
mb --upgrade --apply --in-place *.mb rewrites a V1 tree to canonical V2 in place. Read the V1 Compatibility page for the detailed mapping.
Can I use MarkBack in VS Code?
Yes — v0.1 of the VS Code extension ships from the same monorepo. Highlight text in any file, right-click → MarkBack: Comment on Selection (or Cmd+Shift+M / Ctrl+Shift+M), and a .mb sidecar gets the feedback. Marketplace publication is post-launch; for now, build from source and press F5.
What's the deal with the name?
"MarkBack" reads as Mark + Back. You mark something. The feedback comes back to the file — in a sidecar, next to the work, in your repo. The whole point of the format is that comments don't drift away into a separate system.
Is there an API for extracting just the feedback?
Yes. From the CLI:
mb --list myfile.mb # human-readable
mb --list --json myfile.mb # JSONFrom Python:
from markback import parse_file
result = parse_file("myfile.mb")
for record in result.records:
print(record.feedback)From Node/TS:
import { parseString } from "markbackjs";
const result = parseString(text);
for (const record of result.records) console.log(record.feedback);