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(adocs/folder, sibling toscripts/), 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:
- 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.
- 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 referenceddbfs_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 fromos.argumentsspecs). It stays as-is; roadmap item 2 formalises the relationship by generatingcmd-*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- itembullets`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_storageregistersbackup.*). - 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
LIKEover the DBFS content tables scoped to thewiki/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):
- Resolve URL: explicit → as given; bare name → default convention;
installed bundle → its
index.mdbundle:field, falling back to the convention. - Download to a temp file (curl, https preferred, size cap).
- Read the downloaded bundle's
index.mdversion:before applying; apply only if strictly newer than installed (force flag available). zip.unpackintoD:/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.- 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)
- sys_wiki + lib_wiki + wiki.lua per §7 (the ImGui face with clickable links is the headline).
- Auto-generated command reference: walk
D:/scripts/*.lua, extract eachos.argumentsspec (name/desc/long/params), emitcmd-<name>pages. Single source of truth — the reference cannot drift from the parser, a property this codebase has painfully earned an appreciation of. - Search UI in the window;
wiki searchconsole listing. - Bundle version gating + update notification (a gossip broadcast when a peer has a newer bundle is a natural Ant64 flourish).
{{sql:}}provider (SELECT-only, row-capped) when a page needs a table.