Files
khosra/docs/surface.md
T
Claude Opus 5andbdeshi 7796b0d919 make context a budget the harness enforces
Adopts ideas/token-conservation.md, parked 2026-07-28, plus the disciplines
the human added: read the compressed form first, discover by mechanism,
shrink output at the source, never pay twice for the same bytes.

docs/context-economy.md owns all of it and leads with a floor, because
every cheap failure mode is also a token saving — skipping the owning doc,
guessing a signature, reporting from a diff, thinning a test — and each has
already cost this repo a defect. Frugality is for presentation and
discovery, never for the artifact or the evidence.

Mechanical, not remembered:

- scripts/surface.sh generates docs/surface.md — every top-level
  declaration with its line, 261 lines standing for 3757 of source. The
  pre-commit hook regenerates and stages it, so it cannot be stale, and
  verify.sh compares independently for a clone that never set
  core.hooksPath. The hook refuses a commit with unstaged .go changes,
  since what it generated describes the working tree, not the commit.
- verify.sh --quiet: 48 lines of gate output become 1. The hook uses it.
- CLAUDE_LOC_MAX=150, the only budget billed per turn rather than per read.

Both new gates were watched failing before being kept: a doctored
surface.md, and CLAUDE_LOC_MAX temporarily set to 5.

state.md's inventory loses its LOC column. It had already drifted on six
files (content.go 381→450, render.go 447→454, web.go 206→217, check
216→223, watch 129→137, chrome 105→110) which is what a number written in
two places does; the generated file owns sizes now, the table owns purpose.
The subagent question is recorded there as the one open decision, with the
case for and against written out in the idea file.
2026-08-01 02:16:11 +06:00

15 KiB

Surface

Generated by scripts/surface.sh — do not edit. Regenerate with make surface.

Every top-level declaration in the engine, with its line. Read this before opening a source file: it answers "where does X live" and "what is in this package" without the bodies. What each file is for lives in state.md; why it is that way lives in decisions.md.

cmd/khosra — 256 lines

check.go 45 · main.go 150 · new.go 42 · wire.go 19

  • check.go:16 func runCheck(args []string)
  • main.go:23 func main()
  • main.go:44 func runServe()
  • main.go:108 func rebuilder(fsys fs.FS, cache string, reveal bool, live *atomic.Pointer[content.Site]) func() int
  • main.go:133 func defaultCache() string
  • main.go:143 func fatal(msg string, err error)
  • new.go:12 func runNew(args []string)
  • wire.go:15 func extenders(partial render.Partial) []goldmark.Extender

internal/content — 1042 lines + 537 test

clock.go 12 · content.go 450 · doc.go 5 · extras.go 92 · settings.go 59 · site.go 424

  • clock.go:9 var now = time.Now
  • clock.go:12 func Now() time.Time { return now() }
  • content.go:20 const DefaultLang = "en"
  • content.go:27 type Bundle struct
  • content.go:70 func OpenSite(dir string) (fs.FS, error)
  • content.go:82 type Problem struct
  • content.go:94 func Scan(fsys fs.FS) ([]Bundle, error)
  • content.go:103 func ScanReport(fsys fs.FS) ([]Bundle, []Problem, error)
  • content.go:142 func Parse(name string, data []byte) (Bundle, error)
  • content.go:182 func (b Bundle) Published(at time.Time) bool
  • content.go:191 func (b Bundle) Assets() (string, bool)
  • content.go:201 func stringList(v any) []string
  • content.go:223 func asTime(v any) time.Time
  • content.go:239 func asInt(v any) int
  • content.go:252 func terms(v any) []string
  • content.go:276 func TagSlug(tag string) string
  • content.go:285 func Normalise(s string) string { return norm.NFC.String(s) }
  • content.go:291 func splitName(name string) (key, lang string, ok bool)
  • content.go:313 func isLangTag(s string) bool
  • content.go:331 func isPartial(base string) bool
  • content.go:343 func skipDir(base string) bool
  • content.go:351 func splitFrontmatter(data []byte) (front, body []byte)
  • content.go:366 func trimLeadingFence(data []byte, fence string) ([]byte, bool)
  • content.go:383 func dropCollisions(all []Bundle) ([]Bundle, []Problem)
  • content.go:405 const PerPage = 10
  • content.go:411 func URL(key, lang string) string
  • content.go:424 func TagURL(section, slug, lang string, page int) string
  • content.go:434 const DerivedPrefix = "/derived/"
  • content.go:437 func DerivedURL(name string) string { return DerivedPrefix + name }
  • content.go:440 const TagsSegment = "tags"
  • content.go:444 func PageURL(key, lang string, page int) string
  • extras.go:14 const ExtrasDir = "extras"
  • extras.go:17 type Entry struct
  • extras.go:33 func Extras(fsys fs.FS, b Bundle) []Entry
  • extras.go:67 func KindOf(name string) string
  • extras.go:86 func ExtrasURL(route, lang, entry string) string
  • settings.go:13 const SettingsFile = "site.yaml"
  • settings.go:20 type Settings struct
  • settings.go:33 func LoadSettings(fsys fs.FS) (Settings, error)
  • settings.go:54 func Absolute(base, path string) string
  • site.go:11 type Site struct
  • site.go:28 func NewSite(bundles []Bundle) *Site
  • site.go:45 func (s *Site) Reveal() { s.reveal = true }
  • site.go:52 func (s *Site) visible(b Bundle) bool
  • site.go:58 func (s *Site) Problems() []Problem { return s.problems }
  • site.go:61 func (s *Site) note(path, detail string)
  • site.go:72 func (s *Site) indexRoutes(bundles []Bundle)
  • site.go:111 func (s *Site) KeyFor(route string) (string, bool)
  • site.go:122 func (s *Site) RouteOf(key string) string
  • site.go:130 func sorted(set map[string]bool) []string
  • site.go:143 func (s *Site) indexAliases(bundles []Bundle)
  • site.go:175 func (s *Site) Alias(alias string) (string, bool)
  • site.go:184 func (s *Site) Lookup(key, lang string) (b Bundle, served string, ok bool)
  • site.go:202 func (s *Site) Variants(key string) []string
  • site.go:216 func (s *Site) HasLang(lang string) bool
  • site.go:226 func (s *Site) Len() int { return len(s.byKeyLang) }
  • site.go:232 type Query struct
  • site.go:243 func (s *Site) Run(q Query) []Bundle
  • site.go:268 func (s *Site) keys() []string
  • site.go:284 type Sequence struct
  • site.go:304 func (s *Site) Sequence(key, lang string) (Sequence, bool)
  • site.go:325 func (s *Site) parent(key string) (string, bool)
  • site.go:335 func (s *Site) has(key string) bool
  • site.go:344 func (s *Site) members(series, lang string) []Bundle
  • site.go:369 func (b Bundle) hasTag(slug string) bool
  • site.go:382 func (b Bundle) Section() string
  • site.go:394 func (s *Site) Everything() []Bundle
  • site.go:407 func (s *Site) Sections() []string

internal/ext/check — 223 lines + 147 test

check.go 215 · doc.go 8

  • check.go:15 type Finding struct
  • check.go:29 func Run(fsys fs.FS, bundles []content.Bundle, site *content.Site, problems []content.Problem) []Finding
  • check.go:52 func Fatal(found []Finding) bool
  • check.go:62 func inspect(fsys fs.FS, b content.Bundle, site *content.Site) []Finding
  • check.go:78 var figureCall = regexp.MustCompile((?m)^\s*\{\{<\s*figure\s+([^>]*)>\}\}\s*$)
  • check.go:81 var altArg = regexp.MustCompile(alt="[^"]+")
  • check.go:87 func checkFigures(b content.Bundle) []Finding
  • check.go:98 var internalLink = regexp.MustCompile(\]\((/[^)\s"]*))
  • check.go:104 func checkLinks(fsys fs.FS, b content.Bundle, site *content.Site) []Finding
  • check.go:121 func engineOwned(target string) bool
  • check.go:138 func resolves(fsys fs.FS, target string, from content.Bundle, site *content.Site) bool
  • check.go:164 func asset(fsys fs.FS, trimmed string, site *content.Site) bool
  • check.go:192 func mixedOrdering(bundles []content.Bundle, site *content.Site) []Finding

internal/ext/scaffold — 102 lines + 89 test

doc.go 8 · scaffold.go 94

  • scaffold.go:23 func New(siteDir, key, lang, title string) (string, error)
  • scaffold.go:69 func frontmatter(title string) string
  • scaffold.go:76 func titleFrom(key string) string
  • scaffold.go:85 func mkdirAll(root *os.Root, dir string) error

internal/ext/shortcodes — 569 lines + 417 test

doc.go 7 · images.go 250 · shortcodes.go 312

  • images.go:31 var widths = []int{480, 960, 1440}
  • images.go:38 func Derive(siteFS fs.FS, cacheDir string) (int, error)
  • images.go:76 func derive(data []byte, name, cacheDir string) (int, error)
  • images.go:103 func scale(src image.Image, width int) image.Image
  • images.go:115 func write(file string, img image.Image, source string) error
  • images.go:133 func encode(w *os.File, img image.Image, source string) error
  • images.go:149 var
  • images.go:159 func picture(origin render.Origin, file string) (render.Picture, bool)
  • images.go:214 func derivedName(data []byte, source string, width int) string
  • images.go:224 func lossless(source string) bool
  • images.go:234 func showable(name string) bool
  • images.go:244 func derivable(name string) bool
  • shortcodes.go:24 const
  • shortcodes.go:33 func New(partial render.Partial) goldmark.Extender
  • shortcodes.go:37 type extension struct
  • shortcodes.go:46 func (e extension) Extend(md goldmark.Markdown)
  • shortcodes.go:56 var nested = parser.NewContextKey()
  • shortcodes.go:64 type includes struct
  • shortcodes.go:68 func (in includes) Transform(doc *ast.Document, reader text.Reader, pc parser.Context)
  • shortcodes.go:88 func (in includes) convert(name string, pc parser.Context) ([]byte, error)
  • shortcodes.go:118 func pending(doc *ast.Document) []*node
  • shortcodes.go:136 var kind = ast.NewNodeKind("Shortcode")
  • shortcodes.go:139 type node struct
  • shortcodes.go:153 func (n *node) Kind() ast.NodeKind { return kind }
  • shortcodes.go:155 func (n *node) Dump(source []byte, level int) { ast.DumpHelper(n, source, level, nil, nil) }
  • shortcodes.go:158 type blocks struct{}
  • shortcodes.go:160 func (blocks) Trigger() []byte { return []byte{'{'} }
  • shortcodes.go:162 func (blocks) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State)
  • shortcodes.go:193 func gallery(pc parser.Context) []render.Picture
  • shortcodes.go:220 func (blocks) Continue(n ast.Node, reader text.Reader, pc parser.Context) parser.State
  • shortcodes.go:224 func (blocks) Close(n ast.Node, reader text.Reader, pc parser.Context) {}
  • shortcodes.go:226 func (blocks) CanInterruptParagraph() bool { return true }
  • shortcodes.go:228 func (blocks) CanAcceptIndentedLine() bool { return false }
  • shortcodes.go:231 type fragments struct
  • shortcodes.go:235 func (f fragments) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer)
  • shortcodes.go:243 func (f fragments) render(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error)
  • shortcodes.go:270 func parse(line string) (name string, args map[string]string, ok bool)
  • shortcodes.go:297 func argument(s string) (key, value, rest string, ok bool)

internal/ext/watch — 137 lines + 103 test

doc.go 8 · watch.go 129

  • watch.go:23 var
  • watch.go:29 type Changed func()
  • watch.go:35 func Watch(fsys fs.FS, stop <-chan struct{}, onChange Changed)
  • watch.go:75 func Fingerprint(fsys fs.FS) string
  • watch.go:94 func record(sum hash.Hash, p string, d fs.DirEntry, err error) error
  • watch.go:117 func dropping(name string) bool

internal/render — 694 lines + 359 test

chrome.go 110 · render.go 454 · view.go 130

  • chrome.go:19 var chrome = map[string]map[string]string{
  • chrome.go:33 var months = map[string][]string{
  • chrome.go:41 var digits = map[string][]rune{
  • chrome.go:47 var funcs = template.FuncMap{"t" text, "num" numerals, "day" day}
  • chrome.go:53 func text(lang, key string, args ...string) string
  • chrome.go:73 func numerals(lang string, n int) string
  • chrome.go:82 func day(lang string, t time.Time) string
  • chrome.go:98 func localiseDigits(lang, s string) string
  • render.go:24 var themeFS embed.FS
  • render.go:28 type Renderer struct
  • render.go:56 type Partial func(name string, data Fragment) ([]byte, error)
  • render.go:59 type Fragment struct
  • render.go:69 type Picture struct
  • render.go:86 type Origin struct
  • render.go:95 var originKey = parser.NewContextKey()
  • render.go:98 func OriginFrom(pc parser.Context) (Origin, bool)
  • render.go:105 func WithOrigin(pc parser.Context, origin Origin)
  • render.go:118 func New(siteFS fs.FS, settings content.Settings, extend func(Partial) []goldmark.Extender) (*Renderer, error)
  • render.go:160 func (r *Renderer) head(title, lang, canonical string) head
  • render.go:177 func (r *Renderer) absolute(path string) string
  • render.go:185 func (r *Renderer) Navigation(sections func() []string) { r.sections = sections }
  • render.go:189 func (r *Renderer) Reload() { r.reload = true }
  • render.go:193 func (r *Renderer) fresh() error
  • render.go:208 func (r *Renderer) Partial(name string, data Fragment) ([]byte, error)
  • render.go:226 func parseSet(siteFS fs.FS, names ...string) (*template.Template, error)
  • render.go:248 func readStyle(siteFS fs.FS) (template.CSS, error)
  • render.go:266 func (r *Renderer) Extras(b content.Bundle, served string, entries []content.Entry, selected *Selected) ([]byte, error)
  • render.go:290 func (r *Renderer) RenderText(kind string, data []byte) (template.HTML, error)
  • render.go:308 func (r *Renderer) Bundle(b content.Bundle, served string, variants []string, seq *content.Sequence) ([]byte, error)
  • render.go:345 func (r *Renderer) Listing(section, lang string, all []content.Bundle, page int) ([]byte, error)
  • render.go:367 func (r *Renderer) Tag(section, slug, lang string, all []content.Bundle, page int) ([]byte, error)
  • render.go:394 func (r *Renderer) sequence(seq *content.Sequence, lang string) *Sequence
  • render.go:421 func (r *Renderer) item(b content.Bundle, lang string) Item
  • render.go:426 func (r *Renderer) paginate(title, lang, canonical string, all []content.Bundle, page int, url func(int) string) (List, []content.Bundle)
  • render.go:448 func (r *Renderer) execute(set *template.Template, data any, what string) ([]byte, error)
  • view.go:16 type head struct
  • view.go:36 type Page struct
  • view.go:55 type Sequence struct
  • view.go:71 type Extras struct
  • view.go:82 type Selected struct
  • view.go:91 type List struct
  • view.go:105 type Group struct
  • view.go:111 type Item struct
  • view.go:122 type Alternate struct

internal/web — 734 lines + 1586 test

asset.go 58 · discover.go 71 · extras.go 93 · feed.go 125 · resolve.go 170 · web.go 217

  • asset.go:22 func serveAsset(w http.ResponseWriter, req *http.Request, site *content.Site, siteFS fs.FS, res resolution) bool
  • discover.go:14 const
  • discover.go:24 func serveRobots(w http.ResponseWriter, req *http.Request, siteFS fs.FS, base string)
  • discover.go:45 func serveSitemap(w http.ResponseWriter, req *http.Request, site *content.Site, base string)
  • discover.go:67 func xmlEscape(s string) string
  • extras.go:18 func serveExtras(w http.ResponseWriter, req *http.Request, site *content.Site, r *render.Renderer,
  • extras.go:69 func renderExtras(w http.ResponseWriter, r *render.Renderer, b content.Bundle, served string,
  • extras.go:85 func find(entries []content.Entry, want string) (content.Entry, bool)
  • feed.go:13 const feedFile = "feed.xml"
  • feed.go:17 const feedMax = 20
  • feed.go:24 type atom struct
  • feed.go:34 type atomLink struct
  • feed.go:40 type atomEntry struct
  • feed.go:52 func serveFeed(w http.ResponseWriter, req *http.Request, site *content.Site, res resolution, settings content.Settings) bool
  • feed.go:102 func dated(all []content.Bundle) []content.Bundle
  • feed.go:113 func feedTitle(settings content.Settings, res resolution) string
  • resolve.go:12 type resolution struct
  • resolve.go:40 func resolve(path string, site *content.Site) (resolution, bool)
  • resolve.go:102 func cutLang(key string, site *content.Site) (lang, rest, redirect string)
  • resolve.go:117 func cutExtras(key string) (bundle, entry string, ok bool)
  • resolve.go:131 func cutFeed(key string) (rest string, ok bool)
  • resolve.go:142 func cutTag(key string) (tag, section string, ok bool)
  • resolve.go:154 func cutPage(key string) (rest string, page int, ok bool)
  • web.go:19 type Current func() *content.Site
  • web.go:22 func Fixed(site *content.Site) Current { return func() *content.Site { return site } }
  • web.go:27 func Handler(current Current, r *render.Renderer, siteFS, derivedFS fs.FS, settings content.Settings) http.Handler
  • web.go:60 func serveStatic(sub fs.FS) http.Handler
  • web.go:76 func serveListing(w http.ResponseWriter, req *http.Request, site *content.Site, r *render.Renderer, res resolution) bool
  • web.go:100 func serveTags(w http.ResponseWriter, req *http.Request, site *content.Site, r *render.Renderer, res resolution) bool
  • web.go:125 func write(w http.ResponseWriter, out []byte, what string)
  • web.go:134 func writeAs(w http.ResponseWriter, contentType string, out []byte, what string)
  • web.go:142 func serve(w http.ResponseWriter, req *http.Request, site *content.Site, r *render.Renderer, siteFS fs.FS, settings content.Settings)
  • web.go:173 func serveBundle(w http.ResponseWriter, req *http.Request, site *content.Site, r *render.Renderer,