developer-guide/principles/index.md

2.8 KiB

id title description tags lang
principles Principles The four rules that shape f451's design, and why they exist.
architecture
principles
en

Principles

Four rules recur throughout the codebase. They are not style preferences — each one closes off a class of bugs or design mistakes that the project has already made once.

Git is the source of truth, Postgres is only an index

Every space is a Git repository; every page is a Markdown file with frontmatter. Postgres holds the rendered content, the search vector, the knowledge-graph edges, sessions and encrypted provider tokens — nothing that can be derived from Git is allowed to live only in the database.

Important

Losing pg-data is recoverable: POST /admin/reindex or the drift job rebuilds the index from Git. Losing forgejo-data is not — that is the one thing backups exist for. If you find yourself adding a column that holds information not derivable from the Git content, stop and ask whether it belongs in Git instead.

Permissions come from the Git provider

f451 has no role system of its own. Whether someone can see a space or write to it is decided by their permissions on the underlying repository. Writers always write with their own provider token — the API never commits under a service account. Without a linked provider account, every write attempt fails with 403; that is a precondition, not a bug.

This also shapes how "not found" behaves: a 404 deliberately means "doesn't exist, or you don't have access" — never distinguish the two. Doing so would let an unauthorized caller learn that a page exists, which is exactly the kind of existence oracle this design avoids.

Writing always goes through the review workflow

There is no route that writes directly to the published version — not for people, not for agents. The path is always: create a draft (a branch) → write → open a review (a pull request) → approve (merge) → reindex.

Draft routes carry a SHA contract: whoever writes names the baseSha of the version they started from. If the content has changed underneath them, they get a 409 back with the current state instead of a silent overwrite. See api for the routes that implement this.

Diagrams carry their own source

.drawio.svg and .excalidraw.svg files under <page folder>/_media/ are plain SVGs that also carry the diagram's source XML in a content attribute. One file is both the picture people see and the thing the diagram editor reopens. The SVG sanitizer keeps that attribute and the wrapping text elements deliberately — stripping either would make the diagram unreadable or unopenable.

Tip

These four rules are the first thing to check when a design choice looks surprising: it is very likely a direct consequence of one of them, not an arbitrary decision.