The AntOS Wiki

System specification — for human contributors and AI assistants working on the AntOS codebase. Status: DESIGN + partial implementation (terminal face exists as wiki.lua; system library and ImGui face are specified here and not yet built).


1. What it is

The wiki is AntOS's on-device documentation system. Pages are markdown-lite text files stored inside the DBFS at D:/wiki/*.md. That single storage decision does most of the work:

  • Versioned & deployed like code — seeded from init.zip (a docs/ folder, sibling to scripts/), updated by the same pipeline.
  • Backed up for free — the D: → D!: shadow backup replicates the corpus continuously; a doc update is captured by the next backup cycle.
  • Editable in place — FTP a page to D:/wiki/, it's live.
  • Searchable for free — DBFS files are rows in sys.db, so full-corpus search is a SQL query, not an indexing subsystem.

Two principles are non-negotiable:

  1. Content never executes. Pages may embed live system values only through a fixed provider registry (§4). There is no eval, no template language, no scripting in pages. Doc bundles may someday arrive over the network; a page must never be a payload.
  2. Docs that can query the system cannot lie about it. Prefer a live {{backup.last}} over prose that says "check with the backup command". (Motivating incident: a code comment referenced dbfs_autopair() for a year; the function never existed. Live values make that class of drift structurally impossible.)

2. Architecture

Three layers plus faces:

                 ┌──────────────────────────────────────────┐
                 │            D:/wiki/*.md  (DBFS)           │  storage
                 └──────┬───────────────────────────┬───────┘
                        │                           │
              ┌─────────▼─────────┐        (SQL over DBFS tables)
              │     sys_wiki      │  C system library:
              │  load / expand /  │  page model, provider registry,
              │  search / render  │  search, ImGui window
              └───┬───────────┬───┘
                  │           │
        ┌─────────▼──┐   ┌────▼────────┐
        │  lib_wiki  │   │ ImGui window │  faces
        │ Luau bind  │   │ (sys_wiki)   │
        └───┬────────┘   └─────────────┘
            │
   ┌────────▼───────────────────┐
   │         wiki.lua           │  script: terminal renderer today,
   │ open / search / update     │  window opener when sys_wiki lands
   └────────────────────────────┘
   (help.lua is a SEPARATE, pre-existing tool: the COMMAND reference,
    listing script usage from their os.arguments specs. Complementary —
    and already half of roadmap item 2.)
  • sys_wiki (C) — owns the page model. Loads a page, parses front-matter, runs the provider expansion pass, serves search queries, and renders the ImGui window (clickable [[links]], back/forward history, search box). One expansion implementation, shared by every face.
  • lib_wiki (Luau binding) — exposes the page model to scripts: wiki.open(), wiki.get(), wiki.search(), wiki.topics(). Terminal faces render the expanded text themselves; they never re-implement expansion.
  • wiki.lua — user entry point: open the window, search from the console, fetch/check doc bundles.
  • help.lua — NOT part of the wiki: the pre-existing command reference (script usage from os.arguments specs). It stays as-is; roadmap item 2 formalises the relationship by generating cmd-* wiki pages from the same specs.

3. Page format

Docs are organised as bundles: each bundle is a directory under D:/wiki/ — D:/wiki/<bundle>/ — containing one .md file per topic plus its own index.md (bundle front page + metadata). The bundle name is the directory name is the zip basename (lowercase, [a-z0-9_-]).

A page is addressed as bundle/topic. Bare topic in links and commands resolves within the current bundle first, then across installed bundles (antos preferred). The wiki front page enumerates installed bundles; antos/index is home.

Front-matter

Pages open with a --- block of key: value lines:

key where meaning
title any page display name (search ranks it above body text)
tags any page comma-separated search keywords
version index.md integer, monotonically increasing per bundle
bundle index.md URL of this bundle's zip (for updates)
bundles index.md optional name=url list: URL overrides for
cross-bundle links to non-default hosts

Markup (deliberately small)

  • # Heading, ## Subheading
  • - item bullets
  • `code spans`
  • [[topic]] — link within the same bundle
  • [[bundle/topic]] — cross-bundle link. If the bundle is installed, it opens locally; if not, the wiki offers to FETCH it — URL resolved per §6. This is deliberate federation: bundles may reference each other without pre-coordination.
  • {{provider.name}} — live value insertion (§4)
  • Everything else is plain text. Resist the wiki-engine gravity well: no tables, no images, no nesting, until a real page needs them.

4. Providers — the only dynamic mechanism

A provider is a named, zero-argument, registered function returning a string. Pages reference them as {{name}}. The registry is code; pages are content. To add a capability, you add a provider in source — never anything in a page.

  • C providers register via sys_wiki_register_provider(name, fn) at subsystem init (e.g. sys_storage registers backup.*).
  • Every invocation is failure-guarded; a missing or erroring provider renders as ?, never kills a page.
  • Providers must be read-only and fast (called at render time, possibly from the ImGui task). No I/O heavier than a status struct read; no locks held across calls into other subsystems' slow paths.
  • A future {{sql:...}} mechanism, if added, is a provider that takes an argument, constrained to SELECT with a row cap — it is not page-side SQL.

Baseline registry (implemented in wiki.lua today, moves to sys_wiki): time.now, time.iso, time.uptime, heap.free, backup.state, backup.last, backup.total, backup.sizes.


5. Search

Because DBFS files are sys.db rows, search is a query against the docs directory's content — no crawler, no index build, always current.

Semantics (what callers may rely on):

  • Case-insensitive substring match across title, tags, body.
  • Ranking: title hit > tag hit > body hit; ties by topic name.
  • Results: { topic, title, snippet } — snippet is the first matching line, trimmed, with the match position marked.
  • Implementation detail (sys_wiki-private): SQL LIKE over the DBFS content tables scoped to the wiki/ directory. If SQLite FTS5 is compiled in, sys_wiki may upgrade transparently; the semantics above are the contract either way.

6. Bundles

A bundle zip contains its pages at the zip root and extracts into D:/wiki/<bundlename>/ — bundles never touch each other's directories.

URL convention. A bundle referenced by bare name resolves to https://ant64.com/downloads/wiki/<name>.zip — the default registry. A full URL (given explicitly, from bundle: front-matter, or from a bundles: override entry) wins over the convention. This is what lets [[foo/topic]] in any page be fetchable with zero configuration when foo lives at the default host.

The update flow (wiki update [name|url], or all installed bundles when bare):

  1. Resolve URL: explicit → as given; bare name → default convention; installed bundle → its index.md bundle: field, falling back to the convention.
  2. Download to a temp file (curl, https preferred, size cap).
  3. Read the downloaded bundle's index.md version: before applying; apply only if strictly newer than installed (force flag available).
  4. zip.unpack into D:/wiki/<name>/. Bundle files overwrite local files of the same name — the bundle is authoritative for the pages it ships. Local pages the bundle does not ship survive in place.
  5. Delete temp. The next shadow backup captures the update automatically.

Step 3 makes "check for updates" and "update" the same code path: the check reports up to date (v3) or applies and reports v3 → v4.

Trust model: bundles are content-only by construction (§1 principle 1), so a malicious bundle can at worst display wrong text. Still: https, size caps, and never auto-fetch without a user command.


7. API sketches (implementation contract)

sys_wiki (C)

void  sys_wiki_init(void);
void  sys_wiki_register_provider(const char* name, sys_wiki_provider_fn fn);
/* Load + front-matter + provider expansion. Returned buffer is heap
 * (PSRAM), caller frees. meta fields empty-string when absent. */
char* sys_wiki_get(const char* topic, sys_wiki_meta_t* meta);
int   sys_wiki_search(const char* query,
                      sys_wiki_hit_t* hits, int max_hits);
int   sys_wiki_topics(sys_wiki_topic_t* out, int max);
void  sys_wiki_window_open(const char* topic);   /* ImGui face */
bool  sys_wiki_window_visible(void);

Memory: page buffers and window state in PSRAM (house rule: new allocations prefer PSRAM; SRAM only where a subsystem requires it). ImGui window follows the existing sys_imgui window conventions (registered page, remote-context safe — glyphs used by docs are covered by the netimgui atlas warm-up).

lib_wiki (Luau)

wiki.open([topic])          -- open/focus the ImGui window
wiki.get(topic)             -- -> expanded_text, meta_table | nil
wiki.search(q [, max])      -- -> { {topic=, title=, snippet=}, ... }
wiki.topics()               -- -> { {topic=, title=}, ... }
wiki.update([name_or_url] [,force])  -- one bundle, or ALL installed when nil
wiki.bundles()              -- -> { {name=, version=, url=}, ... }
wiki.resolve(name)          -- -> url (override map / bundle: / default convention)

wiki.lua (script surface)

wiki                  open the ImGui wiki window (front page)
wiki <topic>          open the window at a topic (`bundle/topic` or bare)
wiki search <words>   search from the console, list hits
wiki update [url]     check for / apply a newer bundle

wiki renders in the terminal today (headless/telnet friendly) and gains the window when sys_wiki lands. help remains the command-usage reference.


8. Current state & migration

piece status
format + seed pages DONE — docs/ bundle: index, format, drives, backup
terminal face DONE — wiki.lua (self-contained: own expansion + providers)
sys_wiki / ImGui not started — this spec is the contract
lib_wiki not started
wiki.lua not started
search not started (needs sys_wiki's DBFS query)
bundle version check partial — wiki.lua fetches/applies, no version gate

Migration note: wiki.lua's provider registry and expansion are the reference implementation. When sys_wiki lands, wiki.lua shrinks to render-only over wiki.get() — one expansion pass, identical output on every face. Until then, wiki.lua is authoritative for format behavior.

9. Roadmap (in value order)

  1. sys_wiki + lib_wiki + wiki.lua per §7 (the ImGui face with clickable links is the headline).
  2. Auto-generated command reference: walk D:/scripts/*.lua, extract each os.arguments spec (name/desc/long/params), emit cmd-<name> pages. Single source of truth — the reference cannot drift from the parser, a property this codebase has painfully earned an appreciation of.
  3. Search UI in the window; wiki search console listing.
  4. Bundle version gating + update notification (a gossip broadcast when a peer has a newer bundle is a natural Ant64 flourish).
  5. {{sql:}} provider (SELECT-only, row-capped) when a page needs a table.

Important: The Ant64 family of home computers are at early design/prototype stage, everything you see here is subject to change.