Skip to content

Workspace Contract

Assertions

WSP-001 - Managed note headers are strict and deterministic

Contract: A managed note header MUST be one first-line HTML comment containing compact key-sorted JSON with schema 1, optional 32-hex id, title, and canonical tags, followed by exactly one blank line. Unknown keys, invalid IDs, wrong schemas, multiline comments, or malformed separators MUST invalidate the file rather than guess intent. An absent header MUST mean a new local note.

Evidence:

WSP-002 - Canonicalization preserves user content

Contract: Body canonicalization MUST normalize CRLF and bare CR to LF and MUST preserve Unicode, trailing whitespace, Markdown, and embedded Joplin links. Tags MUST be lowercased, sorted, deduplicated, and stripped of empty values. Hashing MUST be deterministic and isolate body, title, tags, and parent components.

Evidence:

WSP-003 - Generated paths are portable and confined

Contract: Note and notebook names derived from remote titles MUST be safe on supported Windows and Linux filesystems, preserve usable Unicode, handle reserved names and case-insensitive sibling collisions, and remain inside the workspace. Filesystem scanning MUST NOT follow symlinks.

Evidence:

WSP-004 - Identity is independent of cosmetic paths

Contract: Note identity MUST live in the header ID and notebook identity MUST live in .joplin-folder.json; filenames and directory names are cosmetic. Pull MUST normalize title-derived paths. Nested and empty notebooks MUST be represented, and a new directory without metadata MAY become a notebook on push.

Evidence:

WSP-005 - Internal state is reserved, recoverable, and token-free

Contract: .joplin-sync MUST contain only tool-owned configuration, SQLite state, journals, backups, quarantine, conflicts, and downloaded resources and MUST be ignored by Git. The Joplin token MUST NOT be persisted there. State schema migration MUST be ordered; corrupt or newer unsupported state MUST fail explicitly.

Evidence:

WSP-006 - New and reconstructed notes never match by title alone

Contract: A local file without an ID MUST create a new remote note and be rewritten atomically with the assigned ID. A local file with an unknown ID MUST not be treated as new. After state loss, equal identified sides MAY be adopted as a base, while divergent sides MUST conflict. Title equality alone MUST NOT adopt an unrelated remote note.

Evidence: