Conventions
This document defines how content and history are organized in Gitlas so that humans and AI agents produce consistent, predictable results.
Folder taxonomy
Top-level areas map to life domains. Keep the tree shallow and obvious.
work/ Professional context (projects, architecture, knowledge)
personal/ Private matters (finances, travel, health)
family/ Shared household (house, documents, insurance, planning)
templates/ Reusable page templates (do not store real content here)
attachments/ Binary files referenced by pages (images, PDFs, ...)
secrets/ Encrypted structured secrets (SOPS + age); values only
quartz/ Publishing configuration and themeNew subfolders are allowed when a clear category emerges. Prefer adding a subfolder over inventing deep nesting.
File naming
- Use lowercase
kebab-case:heat-pump.md,project-a.md. - No spaces, umlauts, or special characters in file names.
- Use ISO dates (
YYYY-MM-DD) and put the year last where a date matters:japan-2027.md,summer-vacation-2027.md. - One topic per file. Split large topics instead of growing one file forever.
Frontmatter schema
Every content page starts with YAML frontmatter. The base fields are required on all pages:
| Field | Type | Description |
|---|---|---|
title | string | Human-readable page title |
category | enum | work | personal | family |
tags | list of strings | Free-form tags for search and grouping |
created | date | Creation date (YYYY-MM-DD) |
updated | date | Last meaningful update (YYYY-MM-DD) |
status | enum | draft | active | planning | archived |
Specialized templates extend the base with extra fields (e.g. travel
adds period_start/period_end, insurance adds policy_number/
renewal_date). Extra fields are always additive; never remove a base field.
Templates
Pick the most specific template, then fill in the placeholders (<...>).
| Template | Use for |
|---|---|
templates/page.md | Generic page (default fallback) |
templates/travel.md | Trips and travel planning |
templates/maintenance-log.md | Assets with a service history |
templates/insurance.md | Insurance policies and contracts |
Templates live only in templates/ and must not contain real data.
Attachments
Binary files (images, PDFs, office documents) belong in attachments/ and are
marked as binary in .gitattributes. Reference an attachment from a page using
a relative link, e.g. [Policy PDF](../attachments/policy-2027.pdf).
Note: Git LFS is intentionally not enabled yet. Until it is, keep large binaries out of the repository. See below for how to enable it later.
Enabling Git LFS later (reference)
Introduce LFS once binary attachments actually grow, and only after the remote LFS story is sorted (see caveats). Steps:
# 1. Initialize LFS hooks for the clone
git lfs install --local
# 2. Track binary types (rewrites .gitattributes entries to filter=lfs)
git lfs track "*.png" "*.jpg" "*.jpeg" "*.gif" "*.webp" \
"*.pdf" "*.zip" "*.docx" "*.xlsx" "*.pptx" "*.odt" "*.ods"
# 3a. For NEW files: just add + commit as usual.
# 3b. To move files ALREADY in history into LFS (rewrites history, needs a
# force-push and coordination):
git lfs migrate import --include="*.png,*.pdf" --everythingRemote caveats (learned the hard way):
- Forgejo serves LFS over HTTPS. In a corporate network the LFS client must
trust the proxy/root CA, otherwise pushes fail with
x509: certificate signed by unknown authority. Point Git at the correct CA:git config http.sslCAInfo /path/to/corporate-ca.pem - The local bare repo used for dual-push is not an LFS server. Pin LFS
traffic to Forgejo so the bare push does not try (and fail) to upload objects:
git config lfs.url https://<forgejo-host>/<owner>/<repo>.git/info/lfs - If you see “does not support the Git LFS locking API”, disable lock
verification for that remote:
git config lfs.<remote-lfs-url>.locksverify false
Because LFS interacts with remote/infra configuration, treat enabling it as a deliberate, coordinated change rather than a routine commit.
Secrets (SOPS + age)
Secrets never live in normal pages. They belong exclusively in secrets/ as
structured files (.yaml / .json / .env) encrypted with
SOPS and age.
SOPS encrypts only the values; field names stay readable and greppable.
The human-readable page references the secret by file name.
Reference status: the current setup is a template.
.sops.yamlcontains placeholder recipients andsecrets/example.yamlholds fake values. No real key material or secret is stored yet.
Rules:
- Real secrets go only into
secrets/, never into content pages. - Files under
secrets/must be SOPS-encrypted before the first commit. - Keep one logical secret per file; name by topic (
wifi.yaml,insurance-haftpflicht.yaml).
Activate encryption (once real age keys exist):
# 1. Put the real age recipients (age1...) into .sops.yaml
# 2. Encrypt / edit a file
sops --encrypt --in-place secrets/wifi.yaml
sops secrets/wifi.yaml # edit decrypted, re-encrypts on saveKey revocation (on compromise)
Forward secrecy for new commits is straightforward; past ciphertext in Git history stays decryptable by the old key, so treat exposed secrets as burned.
- Remove the compromised recipient from
.sops.yaml. - Rotate every affected file’s data key and recipients:
find secrets -type f -exec sops updatekeys -y {} \; find secrets -type f -exec sops -r -i {} \; # rotate data keys - Rotate the real-world secrets (change passwords, reissue tokens) — anything the old key could read is considered exposed.
- Optionally rewrite Git history to purge old ciphertext.
Commit messages
Commit messages follow Conventional Commits and are written in English, in the imperative mood.
<type>(<scope>): <short summary>- type: one of
feat(new page or capability),docs(documentation),content(add/update knowledge content),fix(correction),refactor(restructure without changing meaning),chore(tooling, config, housekeeping). - scope (optional): the area or path, e.g.
family/insurance,templates. - summary: concise, lower-case, no trailing period, imperative (“add”, not “added”/“adds”).
Examples:
content(personal/travel): add japan 2027 trip page
feat(templates): add insurance template
docs: document frontmatter schema
fix(family/house): correct heat pump service date
chore: mark binary attachments in gitattributesFor AI-assisted changes on shared repositories, prefer the review workflow:
work on a topic/<name> branch and open a pull request instead of committing
directly to main.