---
title: Commons publishing protocol v1
summary: The portable document contract for metadata, stable URLs, original files, and searchable publication.
owner: Platform
tags:
  - standards
  - publishing
---

# Commons publishing protocol v1

The protocol defines how a file becomes a discoverable company document.
It does not depend on a particular hosting provider or search engine.
The repository is the source of truth; the website is a generated artifact.

## Document bundle

```text
documents/
  a-stable-slug/
    document.json
    note.md
    images/diagram.png
```

Each immediate directory under `documents/` is one document. It contains a
metadata manifest, one UTF-8 `.md` or `.html` entrypoint, and optional assets.
The CLI imports into this layout. Authors can also create compliant bundles
without using the CLI.

```json
{
  "schema_version": 1,
  "slug": "a-stable-slug",
  "title": "A useful document",
  "summary": "Enough context to decide whether to open it.",
  "owner": "Platform",
  "tags": ["decisions"],
  "created": "2026-10-22",
  "updated": "2026-10-22",
  "status": "published",
  "entrypoint": "note.md"
}
```

## Required rules

- `schema_version` is the integer `1`.
- The directory name equals `slug`. Slugs contain lowercase ASCII letters,
  digits, and single separating hyphens. Keep slugs stable after publication.
- `title` and `owner` are non-empty strings of at most 200 characters.
  `summary` is non-empty text of at most 1,000 characters.
- `tags` is a list of up to 20 non-empty strings, each at most 40 characters.
- `created` and `updated` are ISO calendar dates: `YYYY-MM-DD`.
- `status` is `published` or `draft`.
- `entrypoint` names an existing `.md` or `.html` file inside the bundle.
  The root `index.html` filename is reserved for the generated reader; the
  importer renames an incoming `index.html` to `source.html`.
- Bundle paths remain inside the bundle. Symlinks and hidden files are
  rejected. Each source or attachment must be no larger than 25 MiB.
- Metadata is data. Builds never execute imported scripts or fetch remote
  resources to understand a document.

Protocol v1 uses exactly the manifest fields above and rejects unknown
fields so misspellings do not silently change publication behavior.

## Published addresses and machine interfaces

| Resource | Address |
| --- | --- |
| Library and search | `/` |
| Document reader | `/d/<slug>/` |
| Original source | `/d/<slug>/<entrypoint>` |
| Attachment | `/d/<slug>/<relative-path>` |
| Document metadata | `/d/<slug>/document.json` |
| Catalog without body text | `/catalog.json` |
| Browser full-text index | `/search-index.json` |

The configured site URL is `https://commons.vimaksh.in`. Reader pages and the
catalog expose stable URLs. Renaming the GitHub repository should not change
those public addresses. A withdrawn document is absent from the generated
site; an unknown path returns 404.

## Rendering and indexing

Markdown uses CommonMark with tables and strikethrough. Raw HTML inside
Markdown is escaped. Use a real `.html` document when you need a custom
interactive layout. Headings receive stable generated IDs for fragment links.

HTML source bytes are preserved and displayed in a sandboxed iframe.
The original remains available for download. Sandboxing is browser isolation
for the embedded document, not an assertion that arbitrary HTML is safe in
every context. Only company-authorized publishers should have repository
write access.

The search index includes title, summary, owner, tags, and readable body text.
It excludes script, style, template, and noscript bodies, and includes the
text of inactive HTML tabs. Drafts are excluded from all public outputs.
Search requires all query words as word prefixes and ranks title matches above tags, summary,
and body matches. Format and topic filters are applied before matching.

The initial implementation uses a static JSON index. It has no search server,
third-party search API, or analytics. This is intended for a small shared
library. Pagefind can replace that implementation when index size and query
latency justify it; the document bundle and public URL contract can stay the same.

## Publishing states

1. `commons add` imports a file locally.
2. `commons preview` builds and serves it on `127.0.0.1`.
3. `commons publish` validates, commits document changes, and pushes.
4. The hosting provider builds the committed state and publishes it.

A pushed commit is distinct from a completed deployment. Failed builds must
not replace the last valid site. Each author works in a separate Git checkout;
Git handles concurrent edits and conflicts. The CLI does not hide or resolve
those conflicts automatically.

## Compatibility

The CLI fails on an unsupported protocol version. Future additive or breaking
changes should have an explicit migration and compatibility policy. Preserve
historical experiment evidence separately from edits to a published narrative.
