The review package is the system of record.
Markdown is easy to store, copy, diff, and keep beside source code. Review history is usually different: comments, replies, decisions, and approvals live in a separate service. Open Markdown Review keeps a frozen revision and its review evidence together in one ordinary directory.
The folder can sit on a normal disk, in a Git repository, on a mounted network drive, or in a directory synchronized by another product. That storage layer transports files; it does not become an application server. VS Code and the browser reconstruct the same state from the same manifest, revision descriptors, blobs, and event files.
The HTML launcher contains client code and a minimal package binding. It does not contain a second copy of the documents or review state.
New actions create independent, content-addressed event files. Existing comments and decisions are never edited in place.
Folder access, synchronization, identity assurance, and organizational authorization are not silently invented by the protocol.
This is not an argument that every review should be file based. The design trades centralized identity, instant delivery, and server-side policy for portability, offline access, and inspectable evidence. That trade is useful only when it matches the review's assurance needs.
Frozen content plus an append-only event log.
Creation captures the selected Markdown and required resources into SHA-256-addressed blobs. A revision descriptor records exactly which bytes, renderer profile, diagrams, references, policy, and parent revisions belong to that snapshot. Later review actions append small JSON events.
review-folder/ ├── manifest.json ├── revisions/ │ └── revision_….json ├── blobs/sha256/ │ └── 3a/3a7f… ├── events/ │ ├── 19b2….json │ └── a46e….json ├── exports/ ├── .gitattributes └── Review-Architecture.html
Why separate event files?
A shared comments.json would turn every concurrent action into a read-modify-write
race. Here, comment.created, comment.replied,
thread.resolved, thread.reopened,
review.approved, review.rejected, and related events each have their
own immutable path. Clients validate exact bytes and fold the admitted event set into a
current view.
The extension and browser share one review toolbox.
Both clients render the frozen document, navigation, Mermaid diagrams, images, tables, anchored findings, replies, suggested edits, decisions, and participant stances. A comment card links to its highlighted source position; selecting the highlight returns to the discussion. Multi-document reviews can show findings for the current document or across the complete revision.
| Capability | VS Code | Portable browser | CLI |
|---|---|---|---|
| Create a review or revision | Graphical | Not exposed | Parameter driven |
| Render and navigate frozen content | Yes | Yes | Inspect/validate |
| Comment, reply, suggest, decide | Yes | Yes | Not a reviewer UI |
| Approve, reject, or withdraw | Yes | Yes | Not a reviewer UI |
| Produce audited PDF and inventory | Yes | Yes | Yes, through headless Chromium |
| Apply an accepted edit to source | Linked source workspace | Never | Explicit source path and digest |
New packages use an initiator-managed finding lifecycle. Reviewers may comment and reply while a thread is open; the manifest creator ID may decide, resolve, and reopen it. This is deterministic workflow behavior, not authenticated authorization—the base identity profile is self-asserted.
The HTML file is a door, not a copy of the review.
Each created package receives a review-named file such as
Review-Architecture.html. A participant can double-click it in a supported
Chrome or Edge browser. On first use, the browser asks the participant to choose that
same review folder and grant read/write access.
The generated file bundles the runtime dependencies needed for rendering, validation, Mermaid, styling, and PDF export. Its embedded binding contains only launcher version, review ID, title, and exact manifest digest. It refuses a different package and never stores a second document or event database.
The permission prompt is unavoidable. A double-clicked HTML file cannot silently access neighboring files or inherit a verified Windows identity. Remembered access is best effort. Safari and Firefox do not currently provide the required direct local-folder writer path and are not participant clients for this release.
Concurrent writing is safe by structure; delivery is eventual.
Two reviewers do not compete to overwrite one shared state file. They publish different content-addressed event files and converge by union after those files arrive. The active clients scan after the previous scan finishes—approximately every three seconds in the foreground and fifteen seconds when hidden—and surface newly admitted peer actions.
event A
A ∪ B
event B
This is not a WebSocket channel and it is not a global transaction. OneDrive, Syncthing, a mounted share, or another transport can add latency. Git-backed reviews change only after an external pull or merge. Disconnected clients cannot know that every other participant has synchronized, so an audit records the exact event set the exporting client actually observed.
The implementation keeps verified state and unchanged renderings in local caches, reads only new event filenames during normal refresh, limits adapter concurrency, and performs bounded integrity sweeps. Those optimizations reduce repeated I/O on slow storage without moving authority out of the shared folder.
The PDF is an offline archive of the observed review.
Export is not a browser printout of the current screen. The client verifies the selected
revision and observed event inventory, renders every frozen document, and writes a PDF
plus a machine-readable inventory under exports/.
Human-readable archive
- all documents in the revision;
- rendered Mermaid diagrams, tables, images, and sanitized HTML;
- challenged passages with comments and replies;
- suggested edits, decisions, resolution history, and participant stances;
- diagnostics and explicit incompleteness where applicable.
Machine-readable evidence
- review and revision identifiers;
- exact content and event digests;
- verified cutoff time and policy result;
- the PDF's own path, size, and digest;
- an
export.createdevent tying the archive to the package history.
The hash inventory proves which bytes were included. It does not prove who controlled a self-asserted actor ID, and it does not prove that a disconnected reviewer had already delivered another event. An authenticated organizational sign-off profile would require additional identity and signature rules.
A usable evaluation release, not a qualified assurance system.
Release 0.5.3 packages the protocol, clients, schemas, tests, and release artifacts as a regular GitHub release. Its own documentation deliberately stops short of calling it a professionally qualified pilot.
Actor IDs and display names are self-asserted. Events are unsigned; initiator controls are workflow consistency, not authentication.
Direct folder participation currently depends on Chrome/Edge File System Access behavior and local policy. Safari and Firefox are unsupported as writers.
SMB behavior and performance remain unqualified because no authorized test share was available. A mapped/native path is accepted by design, but this release makes no compatibility claim.
An export proves the exact local observation, not that all disconnected or delayed clients have synchronized.
The protocol does not configure sync, resolve provider-specific delivery failures, or automatically pull and push Git.
Those constraints make the current release appropriate for evaluation with non-critical material and for examining the protocol itself. Reviews that require authenticated identity, signed decisions, centrally enforced access, or proven global completeness need additional controls beyond this base profile.
Read the protocol and inspect the implementation.
The repository contains the wire specification, JSON Schemas, TypeScript implementation, VS Code extension, generated browser client, CLI, tests, and explicit release limitations. The code is available under the MIT License.
Current release: Open Markdown Review 0.5.3. Install the matching VSIX through Extensions: Install from VSIX, or follow the repository's build and CLI instructions.