// Package content loads the Markdown source of truth in content/ into documents // that both renderers (Mode A static pages, Mode B corpus) read. // // The schema is frozen; see docs/content-schema.md. This package does not // re-implement the validator (tools/validate_content.py is the gate). It does // enforce the invariants the renderer needs, and it fails loudly rather than // rendering a broken page. package content import ( "fmt" "os" "path" "path/filepath" "sort" "strconv" "strings" "gitea.lab.audasmedia.com.au/sam/ai-resume/internal/stage" "gopkg.in/yaml.v3" ) // Confidence values. These are displayed on the page and are never promoted. const ( ConfidenceDelivered = "delivered" ConfidenceRunning = "running" ConfidenceInProgress = "in-progress" ConfidenceAbandoned = "abandoned" ConfidenceHistoric = "historic" ) // Area is one of the six top-level navigation areas. Structure lives in code // (it comes from reference/content-map.md, not from the content tree); the // documents that fill it live in content/. type Area struct { Key string Title string Role string Blurb string } // Areas is the fixed navigation order from reference/content-map.md. var Areas = []Area{ {Key: "ai", Title: "AI & Agentic Systems", Role: "AI / LLM Engineer", Blurb: "Harnesses, subagents and skills, memory, model routing and cost, retrieval, voice, guardrails, agent observability."}, {Key: "platform", Title: "Platform & Infrastructure", Role: "Platform / DevOps Engineer", Blurb: "Declarative hosts, packaging, a fifty-container Docker estate, networking, storage and restore-tested backups, observability."}, {Key: "edge", Title: "Edge & Devices", Role: "Edge / IoT Engineer", Blurb: "Twenty-node fleet on constrained devices, custom radio, solar power, deep sleep, sensors and actuation — and the failures."}, {Key: "products", Title: "Products", Role: "", Blurb: "Three active businesses, built and run rather than advised on."}, {Key: "history", Title: "History", Role: "", Blurb: "2000–2014: agencies, clients, engagements, and the code that survives from them."}, {Key: "about", Title: "About", Role: "", Blurb: "The narrative, the non-IT work that came first, education, and how to get in touch."}, } // Positioning is the site's single line of introduction. const ( Positioning = "Twenty-five years shipping software. Now building agent systems, the platforms under them, and the hardware at the edge." SupportLine = "…and it all runs unattended." Location = "Melbourne" ) // AreaByKey returns the area with the given key. func AreaByKey(key string) (Area, bool) { for _, a := range Areas { if a.Key == key { return a, true } } return Area{}, false } // Metric is one approved chip on a page, e.g. {label: "edge nodes", value: 20}. type Metric struct { Label string `yaml:"label"` Value any `yaml:"value"` } // String renders the chip value with its label: "20 edge nodes". func (m Metric) String() string { return fmt.Sprintf("%v %s", m.Value, m.Label) } // Artefact is a drill-down link. Every URL must resolve to a file in this // repository; nothing external is allowed. type Artefact struct { Type string `yaml:"type"` // repo | image | video | doc Label string `yaml:"label"` URL string `yaml:"url"` } // Document is one Markdown file plus its front-matter. type Document struct { ID string `yaml:"id"` Area string `yaml:"area"` Level int `yaml:"level"` Title string `yaml:"title"` Claim string `yaml:"claim"` Confidence string `yaml:"confidence"` Period string `yaml:"period"` Tech []string `yaml:"tech"` Metrics []Metric `yaml:"metrics"` Artefacts []Artefact `yaml:"artefacts"` Public bool `yaml:"public"` LastVerified string `yaml:"last_verified"` Tags []string `yaml:"tags"` // Derived by Load. Path string `yaml:"-"` // path relative to the content root, e.g. edge/edge-fleet.md URL string `yaml:"-"` // canonical page URL, e.g. /edge/edge-fleet/ HTML string `yaml:"-"` // rendered body Plain string `yaml:"-"` // body reduced to text, for the search index bodyRaw string // Markdown body, rendered by the markdown renderer // Backlinks are the documents that reference this one as an artefact. Backlinks []*Document `yaml:"-"` } // ResolvedArtefact is an Artefact with its target resolved. type ResolvedArtefact struct { Artefact Target *Document // non-nil when the artefact is an L3/L2 document File string // absolute path on disk Rel string // path relative to the content root, e.g. assets/x.svg Href string // site URL: a page URL for documents, /assets/... for files Kind string // Fragment kind: text | code | diagram | image | video | links } // Set is every loaded document, indexed. type Set struct { Root string Docs []*Document byID map[string]*Document byRel map[string]*Document } // ByID returns the document with the given id. func (s *Set) ByID(id string) (*Document, bool) { d, ok := s.byID[id] return d, ok } // ByRel returns the document at the given content-relative path. func (s *Set) ByRel(rel string) (*Document, bool) { d, ok := s.byRel[rel] return d, ok } // InArea returns the public documents for an area, ordered L1, L2, L3. func (s *Set) InArea(key string) []*Document { var out []*Document for _, d := range s.Docs { if d.Area == key { out = append(out, d) } } sort.SliceStable(out, func(i, j int) bool { if out[i].Level != out[j].Level { return out[i].Level < out[j].Level } return out[i].Title < out[j].Title }) return out } // AreaLanding returns the L1 document for an area. func (s *Set) AreaLanding(key string) (*Document, bool) { for _, d := range s.InArea(key) { if d.Level == 1 { return d, true } } return nil, false } // Load reads every Markdown file under root. Documents with public: false are // loaded (so links to them still resolve) but are not published. func Load(root string) (*Set, error) { info, err := os.Stat(root) if err != nil { return nil, fmt.Errorf("content root %q: %w", root, err) } if !info.IsDir() { return nil, fmt.Errorf("content root %q is not a directory", root) } s := &Set{Root: root, byID: map[string]*Document{}, byRel: map[string]*Document{}} err = filepath.WalkDir(root, func(p string, e os.DirEntry, err error) error { if err != nil { return err } name := e.Name() if e.IsDir() { if p != root && (strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_")) { return filepath.SkipDir } return nil } if !strings.HasSuffix(name, ".md") || strings.HasPrefix(name, ".") { return nil } rel, rerr := filepath.Rel(root, p) if rerr != nil { return rerr } rel = filepath.ToSlash(rel) raw, rerr := os.ReadFile(p) if rerr != nil { return rerr } doc, derr := parse(rel, p, raw) if derr != nil { return derr } if prev, dup := s.byID[doc.ID]; dup { return fmt.Errorf("%s: duplicate id %q (already used by %s)", rel, doc.ID, prev.Path) } doc.URL = PageURL(doc) s.Docs = append(s.Docs, doc) s.byID[doc.ID] = doc s.byRel[rel] = doc return nil }) if err != nil { return nil, err } if len(s.Docs) == 0 { return nil, fmt.Errorf("content root %q contains no documents", root) } sort.SliceStable(s.Docs, func(i, j int) bool { if s.Docs[i].Area != s.Docs[j].Area { return areaOrder(s.Docs[i].Area) < areaOrder(s.Docs[j].Area) } if s.Docs[i].Level != s.Docs[j].Level { return s.Docs[i].Level < s.Docs[j].Level } return s.Docs[i].ID < s.Docs[j].ID }) for _, d := range s.Docs { for _, a := range d.Artefacts { ra, rerr := s.Resolve(d, a) if rerr != nil { return nil, rerr } if ra.Target != nil && ra.Target.ID != d.ID { ra.Target.Backlinks = append(ra.Target.Backlinks, d) } } } return s, nil } func areaOrder(key string) int { for i, a := range Areas { if a.Key == key { return i } } return len(Areas) } func parse(rel, abs string, raw []byte) (*Document, error) { fm, body, err := splitFrontMatter(string(raw)) if err != nil { return nil, fmt.Errorf("%s: %w", rel, err) } var d Document dec := yaml.NewDecoder(strings.NewReader(fm)) dec.KnownFields(true) // unknown front-matter fields are a schema violation if err := dec.Decode(&d); err != nil { return nil, fmt.Errorf("%s: front-matter: %w", rel, err) } d.Path = rel d.bodyRaw = body if err := d.check(rel); err != nil { return nil, err } return &d, nil } // BodyMarkdown returns the raw Markdown body (everything after the front-matter). func (d *Document) BodyMarkdown() string { return d.bodyRaw } func (d *Document) check(rel string) error { switch { case d.ID == "": return fmt.Errorf("%s: id is required", rel) case d.Title == "": return fmt.Errorf("%s: title is required", rel) case d.Claim == "": return fmt.Errorf("%s: claim is required", rel) } if _, ok := AreaByKey(d.Area); !ok { return fmt.Errorf("%s: unknown area %q", rel, d.Area) } if d.Level < 1 || d.Level > 3 { return fmt.Errorf("%s: level must be 1, 2 or 3, got %d", rel, d.Level) } switch d.Confidence { case ConfidenceDelivered, ConfidenceRunning, ConfidenceInProgress, ConfidenceAbandoned, ConfidenceHistoric: default: return fmt.Errorf("%s: unknown confidence %q", rel, d.Confidence) } if d.LastVerified == "" { return fmt.Errorf("%s: last_verified is required", rel) } stem := strings.TrimSuffix(path.Base(rel), ".md") if stem != d.ID { return fmt.Errorf("%s: id %q must equal the file name %q", rel, d.ID, stem) } for _, a := range d.Artefacts { if a.URL == "" || a.Label == "" { return fmt.Errorf("%s: artefact %q needs both label and url", rel, a.Label) } if strings.Contains(a.URL, "://") { return fmt.Errorf("%s: artefact %q uses an external URL; create an in-repo stub instead", rel, a.URL) } } return nil } func splitFrontMatter(src string) (fm, body string, err error) { src = strings.ReplaceAll(src, "\r\n", "\n") if !strings.HasPrefix(src, "---\n") { return "", "", fmt.Errorf("missing front-matter block on line 1") } rest := src[len("---\n"):] for _, delim := range []string{"\n---\n", "\n...\n"} { if i := strings.Index(rest, delim); i >= 0 { return rest[:i], rest[i+len(delim):], nil } } return "", "", fmt.Errorf("unterminated front-matter block") } // PageURL is the canonical URL for a document. Depth maps onto the URL path so // the drill-down is legible: /edge/ · /edge/edge-fleet/ · /edge/a/edge-zigbee/. func PageURL(d *Document) string { switch d.Level { case 1: return "/" + d.Area + "/" case 2: return "/" + d.Area + "/" + d.ID + "/" default: return "/" + d.Area + "/a/" + d.ID + "/" } } // Resolve maps an artefact reference onto a file, a site URL and a stage // fragment kind. Paths may be repository-relative ("content/edge/l3/x.md") or // document-relative ("./l3/x.md", "l3/x.md"). func (s *Set) Resolve(from *Document, a Artefact) (ResolvedArtefact, error) { rel := a.URL var target string switch { case strings.HasPrefix(rel, "content/"): target = strings.TrimPrefix(rel, "content/") case strings.HasPrefix(rel, "/") || strings.HasPrefix(rel, "../"): return ResolvedArtefact{}, fmt.Errorf("%s: artefact %q must not be root-absolute or escape the repo", from.Path, rel) default: target = path.Join(path.Dir(from.Path), rel) } target = path.Clean(target) out := ResolvedArtefact{Artefact: a, Rel: target} abs := filepath.Join(s.Root, filepath.FromSlash(target)) st, err := os.Stat(abs) if err != nil { return out, fmt.Errorf("%s: artefact %q does not resolve to a file (%s)", from.Path, a.URL, target) } if st.IsDir() { return out, fmt.Errorf("%s: artefact %q resolves to a directory", from.Path, a.URL) } out.File = abs if strings.HasSuffix(target, ".md") { doc, ok := s.byRel[target] if !ok { return out, fmt.Errorf("%s: artefact %q is not a loaded document", from.Path, a.URL) } out.Target = doc out.Href = doc.URL out.Kind = stage.KindText return out, nil } out.Href = "/assets/" + strings.TrimPrefix(target, "assets/") out.Kind = KindForFile(target) return out, nil } var codeExtensions = map[string]string{ ".go": "go", ".js": "javascript", ".mjs": "javascript", ".ts": "typescript", ".nix": "nix", ".php": "php", ".as": "actionscript", ".hpp": "cpp", ".h": "cpp", ".c": "c", ".cpp": "cpp", ".py": "python", ".sh": "bash", ".yaml": "yaml", ".yml": "yaml", ".json": "json", ".css": "css", ".sql": "sql", ".templ": "templ", } // KindForFile maps a file extension onto a stage fragment kind. func KindForFile(name string) string { ext := strings.ToLower(path.Ext(name)) if lang, ok := codeExtensions[ext]; ok && lang != "" { return stage.KindCode } switch ext { case ".svg": return stage.KindDiagram case ".png", ".jpg", ".jpeg", ".webp", ".gif", ".avif": return stage.KindImage case ".mp4", ".webm", ".mov": return stage.KindVideo case ".md": return stage.KindText } return stage.KindLinks } // LanguageFor returns the chroma language for a file, if it is code. func LanguageFor(name string) string { return codeExtensions[strings.ToLower(path.Ext(name))] } // Truncate shortens s to at most n runes, on a word boundary where possible. func Truncate(s string, n int) string { s = strings.TrimSpace(s) if len([]rune(s)) <= n { return s } r := []rune(s)[:n] if i := strings.LastIndex(string(r), " "); i > n/2 { return strings.TrimSpace(string(r)[:i]) + "…" } return strings.TrimSpace(string(r)) + "…" } // MetricValue renders a metric value for display. func MetricValue(v any) string { switch t := v.(type) { case nil: return "" case string: return t case int: return strconv.Itoa(t) case bool: return strconv.FormatBool(t) default: return fmt.Sprint(t) } }