Files
khosra/docs/state.md
T
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

4.3 KiB

State

Verified against: 1c19727 on 2026-07-30 — update this line every change. If this file disagrees with the code, the code is right and this file is a bug.

Inventory

File Purpose LOC
go.mod module khosra; x/text, yaml.v3 direct 8
internal/content/content.go site root → bundles: os.Root open, walk, frontmatter split, key/lang derivation, NFC, collision drop 217
internal/content/content_test.go table-driven; symlink-escape evidence for the path guard 155

No HTTP yet. This repo holds engine source only — the site root is external and passed with -site (ADR-0011).

Dependencies: none.

Counters — the earn-it authority

Never anticipate a threshold. Increment when the code lands, then check whether the extraction is due this change.

Counter Now Extraction due at What it buys
Render transforms 0 3 Stage pipeline (ordered func(ctx,*Page) error)
Routing cases 0 2 Resolver extraction
Collection pages 0 1 Query primitive
Views / output formats 0 2 View layer (contract per theme-contract.md)
Effects 0 2 Effect runner + trigger wiring (change / schedule / demand)
Extensions 0 3 Extension registry + wire file (extensions.md)
Interface implementations 2 The interface itself
Non-stdlib dependencies 2 direct, 7 modules budget in scripts/budgets.env

Allowlisted, in use: goldmark is not yet imported. Allowlist: goldmark (markdown), golang.org/x/text (NFC, ADR-0015), gopkg.in/yaml.v3 (frontmatter, ADR-0020).

Latent items — known, deliberately unfixed

Do not fix these mid-feature. They become features when the human says so. An arc does not close with an untriaged item: at each arc boundary every row is fixed, scheduled into an arc, or accepted with a stated reason. A list nothing drains is a graveyard of known defects.

Item Why it waits Trigger to fix
No mechanical check that the counters are correct The coupling gate makes forgetting them impossible, which is the real failure mode; checking values needs code to count 3rd transform or 2nd route
No mechanical gate on the untrusted boundary (ADR-0003) Nothing untrusted exists yet The comment path, Arc 3 — a test that untrusted input reaches no shortcode or template evaluation

Open questions blocking Arc 1

None. Every decision the engine needs before Arc 1 and before the first deploy is recorded.

Every ADR in decisions.md is accepted; none is open or proposed.

Build queue

The prompt sequence to a Grav-level engine. Completed through 1. Update this line as each lands; a context refresh loses the conversation, not the plan.

  • 0 · ADRs: pagination shape (0028), parse-failure policy (0029), rename (0030), path guard (0031)
  • 1 · bundle loading: os.Root, frontmatter, key/lang, NFC, collisions, skip-loudly
  • 2 · serve a bundle at its permalink: -site, trailing-slash redirect, goldmark, reference theme
  • 3 · language variants: /bn/…, fallback chain, /en/… redirect (2nd routing case → resolver)
  • 4 · aliases
  • 5 · section index pages, paginated (first collection page → Query)
  • 6 · settings cascade (re-adopt from ideas/deferred-decisions.md)
  • 7 · declared content types (re-adopt)
  • 8 · template composition: per-type sets, block override, site templates/
  • 9 · tags: global namespace, tag listings (re-adopt)
  • 10 · sequences: series, sparse order, prev/next/archive
  • 11 · typography + Bengali numerals transforms
  • 12 · shortcodes (3rd transform → Stage pipeline)
  • 13 · image derivatives (first Effect)
  • 14 · feeds: primary, per-section, per-tag (2nd Effect → Effect runner)
  • 15 · sitemap, robots, OpenGraph/JSON-LD
  • 16 · in-process page cache with the validity record (re-adopt)
  • 17 · check command
  • 18 · new command
  • 19 · -dev: reveal drafts and future-dated, template reload
  • 20 · extras (re-adopt)
  • 21 · polled change detection + Dockerfile
  • 22 · complete the reference theme against the full contract

Arc retro log

One line per completed arc: what it cost, what it taught, what it made unnecessary.

  • (empty)