Skip to content

Context schema v1 ​

The manifest ​

.context/manifest.json is the only non-Markdown file in the context, and it is deliberately tiny:

json
{
  "protocol": "repository-context",
  "schemaVersion": 1,
  "layout": "standard"
}
FieldTypeMeaning
protocolstringThe contract this directory implements. Always "repository-context".
schemaVersionnumberThe layout contract this context follows. Currently always 1.
layoutstringThe named arrangement of directories. Currently always "standard".

There are no timestamps, no machine identifiers, no tool versions, no agent or model names. Every one of those would produce diff noise on each run and record something the repository does not need to know. What is here is what a reader — or a future version of the tool — genuinely needs.

protocol names the contract, not the tool ​

.context/ is a deliberately generic name, because the context belongs to the repository rather than to Syngraphe. The cost of a generic name is that another tool may claim the same path, so the manifest says which contract the directory implements. The value is "repository-context" — the protocol — not "syngraphe": any implementation of the protocol writes the same marker, and a directory carrying it is readable by all of them.

The field holds no version of its own. schemaVersion is the version, and a second one would only be something to keep in agreement.

Version handling ​

  • protocol: "repository-context" — this is a repository context.
  • Any other value — the directory belongs to something else. Syngraphe classifies it as unrelated, reports CTX003, and writes nothing. The schema is not even looked at: telling you to upgrade Syngraphe over a file it must not read would be the wrong advice.
  • No protocol at all — MANIFEST005, a warning, and the directory falls back to being recognised by its shape. Manifests written before the field existed keep working; add the line to make the identification exact.
  • schemaVersion: 1 — supported.
  • Any other number — MANIFEST003, and both init and check exit with code 3. The fix is to upgrade Syngraphe, never to edit the number down.
  • Not valid JSON, not an object, or no numeric schemaVersion — MANIFEST002, exit code 1.
  • An unrecognised layout — MANIFEST004, a warning: the layout is a name for an arrangement, and an unknown one is worth mentioning without being fatal.

The standard layout ​

text
.context/
├── manifest.json          # schema version and layout
├── index.md               # router into the context
├── truth/
│   ├── architecture.md    # current system architecture
│   └── conventions.md     # repository conventions
├── state/
│   └── current.md         # current focus, recent changes, next steps, blockers
├── decisions/
│   └── README.md          # significant decisions, one Markdown file each
└── history/
    └── README.md          # completed or superseded operational context

Those seven files are what init creates and what check expects. A missing one is CTX002, and re-running init recreates exactly what is absent without touching anything else.

Files you add — more documents under truth/, decision records, archived context — are yours. Syngraphe never removes, rewrites or reorders these additional files; it follows their local references and includes them in statistics. The explicit state archive command preserves state/current.md in history and resets that one file to its template.

How a .context/ directory is classified ​

Before doing anything, Syngraphe decides what it is looking at:

ClassificationCondition
absentNo .context path at all.
validManifest present, schema supported, all seven files present.
partialRecognisably a repository context (or an empty directory), some files missing.
unsupported schemaManifest parses, declares this protocol, schemaVersion is not 1.
invalid manifestManifest is not valid JSON, not an object, or has no numeric schemaVersion.
unrelatedThe manifest declares a different protocol — or there is no protocol to go by and the top level is not the standard layout: an unknown entry, a standard name of the wrong kind, or no standard document at all — or .context is not a directory at all.

Only absent and partial are written to. Unrelated aborts with an explanation and no assumptions; see adopting an existing repository.

The generated templates ​

They are intentionally almost empty — headings, no prose. Generated filler would be trusted by a reader who has no way to know a human never looked at it, and left in place far longer than it deserves.

index.md ​

md
# Repository Context

This directory contains the canonical shared context for this repository.

## Always relevant

- `truth/architecture.md` — current system architecture.
- `state/current.md` — current project state and active work.

## When relevant

- `truth/conventions.md` — repository conventions.
- `decisions/` — significant technical and architectural decisions.

## Historical

- `history/` — completed, historical, or superseded operational context.

The grouping is by how often a document is worth reading, which is the question a reader arriving at .context/ actually has.

truth/architecture.md ​

md
# Architecture

## Overview

## Major components

## Data flow

## External systems

## Important constraints

truth/conventions.md ​

md
# Conventions

## Repository conventions

## Development workflow

## Important rules

state/current.md ​

md
# Current State

## Current focus

## Recent relevant changes

## Next

## Blockers

decisions/README.md and history/README.md ​

Two short files explaining what belongs in each directory. They are excluded from the counts syngraphe status reports, so a directory with only its README shows as 0.

References between documents ​

syngraphe check verifies that local paths mentioned in context Markdown resolve:

  • Markdown links — [text](path) — resolve relative to the document, as Markdown requires, and are checked whatever they point at.
  • Inline code — `truth/architecture.md` — is prose, so only document references are checked: something ending in .md. It may resolve relative to the document, from the repository root, or from .context/ — the last because that is how index.md names its own siblings, and a note in history/ or a record in decisions/ means the same file by the same name.

A directory named in inline code — `.cursor/rules/`, `src/` — is not treated as a reference: prose mentions directories that need not exist here, and a missing context directory is already reported by the structure check. Anchors, external URLs and fenced code blocks are ignored. A reference that resolves no way at all is LINK001.

Nested contexts ​

Each scope has its own complete .context/ with the same schema and required files. Nested support adds no manifest fields and requires no migration. Select a directory with --scope or discover contexts with --all on reporting commands. See the monorepo guide.

Within a scope, inline-code document references additionally fall back to the Git root. Markdown links may reference parent or sibling context as long as they remain inside the Git tree.

Compatibility ​

The schema version is what a future Syngraphe reads to know whether it can act. That is why the manifest exists at all, and why the manifest is read before anything else happens: a v0.1 build meeting a future layout stops with a clear message instead of half-understanding it.

The two fields are read in that order — protocol first, schemaVersion second. Whose directory this is has to be settled before what version it is: a manifest belonging to another tool has no schema version Syngraphe is entitled to interpret.

Nothing else in the context is machine-parsed. The Markdown is for readers, and Syngraphe makes no claim about its structure beyond the file names above.

Syngraphe v0.4.1 · context schema v1 · GitHub · Donate