bdeshi eb9f408dd7 content: read a site root into bundles
Bundle loading with no HTTP: walk content/, split YAML frontmatter, derive an
NFC-normalised key and a language from the filename, and lift only title out of
frontmatter so every other key stays readable through Extra (ADR-0002).

Path safety is os.Root rather than a hand-rolled cleaner (ADR-0031). os.DirFS
documents that it does not prevent symlink escape; os.Root refuses any name
resolving outside the root, so the guard is a property of the type instead of a
check to remember at each call site. Test: a symlink to a file above the root
cannot be read. This clears the traversal item off the latent list.

A bundle that will not parse is logged and skipped, never fatal (ADR-0029), as
is a key claimed by two spellings of one variant (ADR-0021).

Bundle carries only Key, Lang, Path, Title, Body and Extra; Date, Slug, Draft
and Aliases arrive with the features that read them.
2026-08-01 02:23:34 +06:00
2026-07-30 00:34:18 +06:00
2026-08-01 02:23:34 +06:00
2026-08-01 02:23:34 +06:00

khosra

A flat-file personal publishing engine in Go. Point the binary at a directory of Markdown and it becomes an owned, networked home for fiction, webcomics, art, and essays, in English and Bengali. The site's content lives in its own repository, not this one (ADR-0011).

If you are a human: start at HARNESS.md — what the scaffolding is, how to use it, and what to decide.

If you are an agent: start at CLAUDE.md — the constitution and the read order. It is loaded for you automatically; this file is not a prerequisite and nothing here is a rule.

S
Description
A personal publishing engine
Readme
1.1 MiB
Languages
Go 89%
Shell 7%
HTML 2.3%
CSS 1%
Makefile 0.4%
Other 0.3%