Wiki engine
Static wiki engine designed for AI-collaborative knowledge bases. Compiles markdown sources into themed HTML, clean markdown twins, talk pages, and machine-readable corpus files; defines a per-page edit contract with sign-off-tracked provenance.
The 1Context wiki engine is a static wiki engine for AI-collaborative knowledge bases. It compiles markdown source files into the surfaces a wiki needs — themed HTML, machine-readable corpus files, sibling discussion pages, and an auto-generated provenance log — from a single authoring step. It is part of the broader 1Context system and was extracted from a BookStack theme module into a standalone engine in April 2026.
The engine belongs to the static-build category of wiki software, alongside Quartz, Foam, MkDocs, and Obsidian Publish. What distinguishes it from those peers is that AI agents are treated as first-class readers and authors rather than incidental ones. Every page is fetchable as both themed HTML and clean markdown. Machine-readable corpus files following the llms.txt convention are emitted automatically. Every page may carry a sibling discussion file in an LKML-flavored Wikipedia-talk format. Every modification is governed by an explicit sign-off contract, and the resulting provenance is recorded by the engine in a per-page history file rather than in author-maintained frontmatter.
The engine is at version 0.3.0 (pre-1.0; breaking changes expected) as of April 2026. It powers the 1Context wiki itself, including this article: the page describing the engine is rendered by the engine that is the article's subject — a self-bootstrap pattern common to language compilers and one that converts any drift between documented behavior and actual behavior into a build-time bug rather than a documentation lag.
History
Origins as a BookStack module
The engine began life as a theme module for BookStack, a self-hosted PHP wiki, in the early months of 2026. The module added 1Context-specific surfaces — clean markdown twins, agent-discovery files, themed page chrome — to a stock BookStack installation, on the working assumption that BookStack itself would supply storage, editing, and authentication for the long term.
That assumption shifted as the module grew. By April 2026, the
load-bearing work consisted of the rendering pipeline, the theme,
the talk-page parser, and the agent-surface generator — none of
which depended meaningfully on BookStack's PHP backend. The
remaining BookStack-specific code (functions.php, views/,
bookstack-module.json) was a smaller surface than the engine
itself, and BookStack's role was reframed: rather than the
foundation, it became one possible storage backend among several,
accessible through a planned BookStackAdapter (see
§ Storage adapters).
Extraction and bootstrap
In April 2026 the engine code was migrated into a dedicated
wiki-engine/ directory at the repository root, the BookStack
module artifacts were removed, and the engine was renamed to
reflect its new standalone scope. Three numbered releases punctuated
the transition:
| Version | Date | Notable change |
|---|---|---|
| 0.1.0 | April 2026 | Initial scope-marker release; engine code still in css/, preview/js/, tools/. |
| 0.2.0 | April 2026 | Engine code migrated to wiki-engine/; theme, JS, and tooling relocated under one root. |
| 0.2.1 | April 2026 | Markdown-to-HTML renderer scaffold landed (renderPage(), frontmatter validator, TOC builder, page template). |
| 0.3.0 | April 2026 | "Bootstrap" milestone: this article was rendered through the engine for the first time, replacing a hand-authored HTML version. |
The 0.3.0 release is structurally important. From v0.3.0 onward,
any drift between the engine's design statements (in this article)
and its actual behavior is, by construction, a real bug rather than
a documentation lag — a property the project shares with
self-hosting language compilers such as those described in
bootstrapping (compilers).
The deployed page's HTML carries
<meta name="generator" content="1Context wiki-engine">, making
the bootstrap externally verifiable.
Versions are tracked in the engine's CHANGELOG.md; pre-1.0 releases are expected to make breaking changes.
Design
Static-first
The engine compiles the wiki at build time and deploys the result to a static host (currently Cloudflare Pages). This places it in the static-build category of wiki software, alongside Hugo, Quartz, Foam, and MkDocs.
The static-first decision was made not for ideological reasons but because it makes the load-bearing engine work — rendering, talk-page parsing, agent-surface generation, discovery-file emission — shippable without first solving the harder problems characteristic of runtime-editable wikis like MediaWiki, Confluence, and Notion: authentication, conflict resolution, real-time push, and continuous server operations. Git provides collaboration history, audit, rollback, and offline editing as an effect of source-of-truth being plain files in version control. A planned runtime-editable layer is described in § Future development; it is intended to layer on top of the static system rather than replace it.
Engine and content separation
The codebase observes a Hugo-style separation between the engine and the content of any particular wiki built on top of it. Material that two different 1Context-style wikis would share belongs in the engine; material specific to a particular wiki belongs in the content directory. The boundary is documented in the engine's SCOPE.md and is enforced by directory layout rather than by code.
Engine (wiki-engine/) |
Content (preview/public/, eventually content/) |
|---|---|
| Renderer (markdown → HTML) | Page sources (.md with frontmatter) |
| Theme (CSS) and chrome (interactive JS) | Talk pages (.talk.md) |
| HTML page templates | Static assets (images, embedded media) |
| Build tools (discovery generator, link-graph validator, audience-tier filter, deploy scripts) | Site-specific configuration (deployment URLs, branding overrides, audience policy) |
| Storage adapters | Page prose itself |
| Schemas (frontmatter, talk-page format, manifest) |
The boundary scales: the engine grows when capabilities are added that all wikis would want; the content directory grows when a particular wiki adds pages, talk discussions, or assets.
Storage adapters
The renderer reads page content through a small Adapter interface
and does not assume markdown-on-disk indefinitely. Adapters return
content in a normalized shape ({ slug, frontmatter, body }); the
renderer is unaware of the underlying storage mechanism.
The default adapter, StaticMarkdownAdapter, reads .md files
from a local directory. Several other adapters are planned but not
yet implemented:
PuterDBAdapter— backed by Puter's key-value store, allowing a 1Context wiki to operate without checked-in markdown files, with the database as source of truth.BookStackAdapter— backed by a BookStack instance's REST API, restoring the original BookStack-module use case as one option among several rather than as a hard dependency.GitAdapter— backed by a remote git repository's working tree, useful for read-only mirrors of a remote source.MemoryAdapter— used for testing; holds adapter state in process memory.
The adapter pattern is a textbook adapter design pattern application: the renderer programs against the abstract interface, and the choice of concrete adapter is a deployment-time decision rather than a code-time decision.
Authoring model
A page in a 1Context wiki is a single markdown file with YAML frontmatter, addressed by a kebab-case slug. The engine compiles each authored source into multiple surfaces (see § Output surfaces) and extends standard CommonMark with a small vocabulary of structured directives (see § Directives) for patterns that bare markdown does not express well. Provenance and history are not written by the author; they are maintained by the engine itself under the rules of an explicit edit contract (see § Edit contract).
Page source
Each page lives at content/pages/{slug}.md (currently
preview/public/{slug}.md). The file consists of YAML frontmatter
delimited by --- followed by a markdown body. The page template
emits the H1 and subtitle from the title and summary
frontmatter fields, so the body of an authored page begins directly
with the lead paragraph rather than with a top-level heading.
A minimal page is small:
---
title: Hello world
slug: hello-world
section: project
access: public
summary: My first 1Context page.
last_updated: 2026-04-21
---
Lead paragraph here. The body starts directly, not at an H1.
## A section heading
Some content. The TOC entry, the slug anchor, the copy-as-markdown
button, and this section's appearance in the wiki-wide corpus all
happen without further authoring.
Frontmatter
Every page-level setting that varies across pages is expressible in
frontmatter, so an authoring agent does not need to leave the
source file to change how the page behaves. Reader-side preferences
(theme, font size, layout) live in the customizer and persist in
localStorage; frontmatter only sets per-page defaults that the
customizer respects when a reader has expressed no preference of
their own.
The validator at
wiki-engine/src/renderer/frontmatter.mjs
enforces the schema. Typos in known enum fields fail the build with
a clear message; unknown fields pass through silently for
forward-compatibility with future engine versions and per-site
plugins.
The schema is grouped by purpose. Identity fields are required; everything else is optional with sensible defaults.
Identity
| Field | Type | Notes |
|---|---|---|
title |
string | Rendered as <h1> and <title>. |
slug |
string | Kebab-case, ≤60 chars, alphanumeric start. |
section |
enum | project · reference · ops · api · product |
access |
enum | public · shared · private |
Access control
| Field | Type | Notes |
|---|---|---|
shared_with |
string list | Required when access: shared. |
requires_auth |
boolean | Override; default derived from access. |
Display defaults
These values express a recommended presentation that the reader's customizer respects when no per-reader preference has been set. The engine never overrides a reader who has expressed an explicit choice in localStorage.
| Field | Type | Default | Values |
|---|---|---|---|
theme_default |
enum | auto |
light · dark · auto |
article_width |
enum | m |
s · m · l |
font_size |
enum | m |
s · m · l |
border_radius |
enum | rounded |
rounded · square |
links_style |
enum | underline |
underline · color |
cover_image |
enum | show |
show · hide |
article_style |
enum | full |
full · pics · text |
Structural toggles
The engine assumes every chrome feature should appear on every page; toggles let a particular page suppress one selectively.
| Field | Type | Default | Effect when false |
|---|---|---|---|
toc_enabled |
boolean | true |
Hides the TOC sidebar. |
talk_enabled |
boolean | true |
Hides the Talk button. |
agent_view_enabled |
boolean | true |
Hides the Agent toggle. |
copy_buttons_enabled |
boolean | true |
Hides the per-section copy buttons. |
footer_enabled |
boolean | true |
Suppresses the site footer. |
search_indexed |
boolean | true |
Excludes the page from site search. |
noindex |
boolean | false |
Emits <meta robots="noindex,nofollow">. |
Lifecycle
Status, supersession, and deprecation are first-class so the
reader sees an inline banner without an author having to
hand-author one. The engine emits the banner automatically when
status differs from published or when deprecation_notice is
set.
| Field | Type | Notes |
|---|---|---|
last_updated |
ISO date | Last meaningful authoring change. |
version |
integer | Bumped on substantive revisions. |
status |
enum | draft · published · archived · superseded (default published). |
superseded_by |
slug | Required when status: superseded. |
expires_at |
ISO date | Optional auto-archive trigger. |
deprecation_notice |
string | Overrides the auto-generated banner copy. |
Discoverability
| Field | Type | Notes |
|---|---|---|
summary |
string | Page subtitle and OpenGraph description. |
tags |
string list | Free-form taxonomy. |
keywords |
string list | Emitted as <meta name="keywords">. |
language |
IETF tag | Emitted as <html lang="…"> (default en). |
Content metadata
| Field | Type | Notes |
|---|---|---|
canonical_url |
string | |
md_url |
string | Overrides the default /{slug}.md. |
alternate_formats |
object | Extra format pointers (e.g. mcp_handle). |
related |
string list | Programmatic relations beyond :::see-also. |
parent |
slug | Parent page for breadcrumb-style lineage. |
source_type |
enum | authored · imported |
Directives
The engine extends standard CommonMark
with a small vocabulary of block-level directives, all using
Pandoc fenced-div
syntax: an opening line :::name args, body content, and a closing
::: on its own line.
| Directive | Purpose |
|---|---|
:::infobox |
Wraps a fast-facts sidebar in <aside class="infobox">. Body is full markdown. |
:::main-article slug |
Emits a Wikipedia-style hatnote pointing at a canonical sub-article. The slug becomes the link target; the human-readable title is derived from the slug. The block has no body. |
:::see-also |
Wraps a related-pages list at the bottom of an article in an H2-plus-list block. |
:::audience tier |
Wraps a section for the planned audience-tier build pipeline. Tier is internal, public, or both. |
The vocabulary is deliberately small. Adding a directive is treated
as a wiki-policy change rather than an unannounced code change: a
[PROPOSAL] topic on the engine's
talk page precedes implementation,
so the surface area stays small enough for an authoring agent to
keep in working memory.
Edit contract
Provenance is the engine's responsibility, not the authoring
agent's. Frontmatter does not contain author, model identifier, or
revision-history fields; those would couple the source file to a
particular edit, requiring agents to remember to update them and
allowing them to lie if they did not. Instead the engine maintains
a per-page sibling file at pages/{slug}.history.md, append-only,
that records every edit and every render: who made the change, when,
what changed, and why.
The trail is enforced by a contract on the edit, not on the source file. Every edit must be signed off by the editing agent. A sign-off carries an identity (agent name plus model version, or human email), an ISO-8601 UTC timestamp, and a one-line edit message describing the change.
In static-build mode (the configuration shipped today) sign-off is
derived from git commit metadata plus a Signed-off-by: trailer
following the
Linux kernel convention.
The render pipeline reads git log for each touched source file
and appends a [HISTORY] topic to that page's history file. Commits
without a sign-off trailer fail the pre-commit hook.
In runtime mode (planned, see § Future development) the write API
requires a sign_off field on every modification request, and
unsigned writes are rejected at the edge before any state changes.
History files are reachable two ways: as raw markdown at
/{slug}.history.md for agents and external systems, and themed
via the existing talk-page renderer at
/talk.html?page={slug}&track=history. The same parser and UI
conventions apply; provenance is structurally just another talk
discussion that the engine authors automatically.
Output surfaces
For every authored markdown source the engine emits the following per-page surfaces:
| Surface | URL | Notes |
|---|---|---|
| Themed HTML | /{slug} |
Human-readable Reader view. |
| Markdown twin | /{slug}.md |
Agent fetch target; frontmatter preserved. |
| Talk surface | /{slug}.talk.md, /talk.html?page={slug} |
Present when a .talk.md sibling file exists. |
| History surface | /{slug}.history.md, /talk.html?page={slug}&track=history |
Auto-maintained per the edit contract. |
| Index entry | inside /docs-index.json |
Page metadata as structured fields. |
| Corpus entry | inside /llms-full.txt |
Body folded into the wiki-wide corpus with llms.txt-style separators. |
For the wiki as a whole the engine emits three corpus-wide files:
| File | Purpose |
|---|---|
/llms.txt |
Curated index following the llms.txt convention, suitable as a single-fetch overview for a language model. |
/llms-full.txt |
Concatenated authored content, formatted for machine consumption. |
/docs-index.json |
Array of every page's frontmatter, suitable as a search or routing index. |
Engine-managed surfaces
In addition to the per-page and corpus outputs, the engine emits a number of derived surfaces automatically. These do not require authoring; they are functions of the markdown body, the frontmatter, or the page set as a whole:
- The H1 and subtitle, derived from
titleandsummary. - A table-of-contents nav from H2/H3 headings, with stable slug anchors.
- Header chrome (brand mark, search input, tier badge derived from
access). - Reader / Agent / Talk view toggles in the header.
- Per-section "copy as markdown" buttons next to each H2 and H3.
- A mobile-hardened layout (off-canvas TOC drawer, scroll-direction-reveal header, safe-area insets, touch-action containment).
- A theme system (light, dark, or system-auto) with a no-flash bootstrap script.
- A status banner when
statusdiffers frompublishedordeprecation_noticeis set. - A footer banner identifying the wiki as "1Context by Haptica".
- A favicon.
- A
<link rel="alternate" type="text/markdown">element pointing at the markdown twin. - OpenGraph and
<meta name="keywords">tags derived from frontmatter. - The
<html lang="…">attribute fromlanguage. data-*attributes carrying the page's display defaults so the customizer respects page-level recommendations.- An append to
.history.mdon every render or edit.
Future development
The engine is currently a pure static-build system: source files become HTML at compile time, the deployed wiki is a CDN-served bundle, and edits propagate through git. A runtime-editable layer is planned, designed to layer onto the static path rather than replace it.
The wider wiki-software ecosystem distinguishes between two coherent design points:
| Design point | Examples | Edit path |
|---|---|---|
| Static-build | Hugo, Quartz, Foam, MkDocs, this engine today | Source files become HTML at build time; edits go through version control. |
| Runtime-editable | MediaWiki, Confluence, Notion, Obsidian Publish | Source lives in a database; the server renders on demand; edits go through HTTP APIs and propagate live. |
The engine occupies the static-build position today and is designed so the runtime layer can land incrementally rather than as a fork. The planned runtime additions are:
- A small write API through which authenticated users can post to talk pages or edit articles from a browser, with the server appending to the underlying source file and triggering a rebuild.
- A change-notification stream (Server-Sent Events or WebSocket) so connected clients see updates without polling.
- A sync agent, separable from the engine core, that mirrors a remote adapter into a user's local file tree in a Dropbox-like fashion, supporting users who prefer a local editor.
- Real-time multi-cursor editing, layered over the write API as either a conflict-free replicated data type or operational-transformation system, if demand warrants the additional complexity.
The Adapter interface is the seam that makes layered evolution
possible. StaticMarkdownAdapter operates against the filesystem;
a future PuterDBAdapter would operate against Puter's KV store; a
hypothetical HybridAdapter could read from disk while writing
through the API. Because the renderer is adapter-agnostic, the
static path continues to function as runtime capabilities light up
incrementally.
The order in which the runtime pieces land — and the choice of backend they target — are open coordination questions tracked on the talk page.
Status
The engine is at version 0.3.0 (April 2026). Work is tracked
publicly on the engine's
talk page, where each roadmap item
carries a [TODO] topic that contributors claim, discuss, and
resolve via [DECIDED] replies, following the
1Context talk-page conventions.
Headline roadmap items, ordered by their internal P-numbers:
| ID | Item | State |
|---|---|---|
| P1 | Markdown → HTML renderer pipeline | Renderer scaffold landed in v0.2.1; build wiring pending. |
| P2 | Engine code migrated into wiki-engine/ |
Complete in v0.2.0. |
| P3 | Storage-adapter interface | Not started. |
| P4 | Content folder split | Not started. |
| P5 | Audience-tier pipeline (build-time filter, link-graph CI) | Not started. |
| P6 | Command-line interface (wiki-engine init/build/dev/deploy) |
Not started. |
| P7 | Engine repo extraction (publish as standalone npm package) | Not started. |
Additional design proposals not yet given P-numbers, all documented
on the talk page: auto-generated .history.md plus sign-off
enforcement (declared in v0.3.0 spec, implementation pending),
link-integrity validation, asset handling, authoring error UX, and
discoverability and search.
See also
- 1Context project — parent overview of the system the engine is part of
- Agent UX (AX) — agent-surface design philosophy the engine implements
- Talk page conventions — discussion-page format and editorial rules
References
- SCOPE.md — engine vs content boundary
- ROADMAP.md — numbered priorities
- CHANGELOG.md — release history
- docs/architecture.md — layered model and key types