Documentation drifts from the code it describes. OpenWiki is a LangChain documentation agent that generates and maintains a Markdown knowledge base from evidence it can read: source, tests, schemas, deployment config, and repository history.
This cookbook runs OpenWiki on moonshotai/Kimi-K2.7-Code through the Nebius Token Factory OpenAI-compatible API, and sets up the controls that make generated documentation safe to merge.
What you will build
A documentation pipeline that covers two use cases:
- Enterprise repository documentation: architecture, domain concepts, API contracts, data flows, operations, and testing are generated under a repository’s
openwiki/directory and reviewed through an ordinary pull request. - A team or personal second brain: approved sources such as local repositories, Notion, Slack, Gmail, or custom MCP servers are ingested into a local knowledge base under
~/.openwiki/wiki.
OpenWiki writes a .claims/ record alongside each page, which is what makes the output reviewable. Every material statement is stored with the source it came from and a content hash of that source:
{
"statement": "The service is architecturally organized around three owned systems: event ingestion, rating/price-book, and the invoice HTTP API.",
"evidence": [
{ "resource": "repo://README.md", "version": "repo-file-v1:sha256:fb947d56f81d6d3a…" }
]
}
That gives a reviewer something to check against, and gives a later update a way to detect which pages went stale when the underlying file changed.
OpenWiki is also willing to say it does not know. On a service whose persistence layer is only a Protocol, the generated architecture page recorded the absence rather than inventing a database:
EventStoreis a protocol abstraction only. There is no concrete persistence implementation in the repository.
Prerequisites
- Node.js 22 or newer
- A Nebius Token Factory account with access to
moonshotai/Kimi-K2.7-Code - A Git repository you are authorized to process with a hosted model
- The API key in an environment variable or secret manager, never in a notebook cell, a workflow file, or a commit
Run the cookbook
-
Install OpenWiki:
npm install --global openwiki -
Point it at Token Factory. OpenWiki ships a built-in
nebiusprovider whose base URL is alreadyhttps://api.tokenfactory.nebius.com/v1, so the key and the model ID are the only settings you supply:export NEBIUS_API_KEY="your-token-factory-key" export OPENWIKI_PROVIDER="nebius" export OPENWIKI_MODEL_ID="moonshotai/Kimi-K2.7-Code"Set the full model ID explicitly rather than relying on the interactive preset. A model change is a change to how your documentation gets written, and it should be reviewable in a diff.
-
Write the documentation contract before the first run. OpenWiki treats
openwiki/INSTRUCTIONS.mdas a user-authored brief and preserves it across updates, so this is where scope, audience, and quality requirements live:# Documentation brief Audience: engineers, operators, security reviewers, and support. Data classification: internal. Accountable owner: platform-team. Document, where supported by repository evidence: 1. System purpose, capabilities, boundaries, dependencies, and owners. 2. Runtime architecture, deployment topology, and trust boundaries. 3. Domain terminology, business rules, entities, and lifecycle. 4. API contracts, authentication, authorization, errors, and consumers. 5. Data stores, schemas, retention, backup, and deletion. 6. Build, test, deploy, observability, rollback, and recovery. Ground important claims in source, tests, schemas, deployment configuration, or repository history. Mark unknowns explicitly.Put your real owner, service tier, and data classification in the brief. Do not ask the model to infer them.
-
Establish a hard read boundary. A repository-root
.openwikiignoreexcludes matching paths from agent reads, scans, and generated pages:.env .env.* !.env.example **/*.pem **/*.key **/secrets/** data/ exports/ dumps/ backups/ node_modules/ vendor/ dist/ build/ coverage/ openwiki/Ignore rules reduce exposure during a run. They do not remove sensitive data already sitting in a README, a fixture, or Git history.
-
Generate the knowledge base from the repository root:
openwiki code --init --print -
Keep it current after source changes, and wire the same contract into CI:
openwiki code --update --printon: workflow_dispatch: schedule: - cron: "0 6 * * 1" permissions: contents: write pull-requests: write jobs: update: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v5 with: fetch-depth: 0 - run: npm install --global openwiki - run: openwiki code --update --print env: NEBIUS_API_KEY: ${{ secrets.NEBIUS_API_KEY }} OPENWIKI_PROVIDER: nebius OPENWIKI_MODEL_ID: moonshotai/Kimi-K2.7-Code OPENWIKI_TELEMETRY_DISABLED: "1"Note what is deliberately absent: there is no
pull_requesttrigger. The job holds a Token Factory secret, so it must never run for an unreviewed fork. Use a full checkout so the agent can inspect history, have automation open a documentation pull request, and require CODEOWNERS review rather than merging automatically.
For a second brain
Personal mode writes to ~/.openwiki/wiki instead of the current repository:
openwiki personal --init
openwiki ingest all --print
openwiki personal --update
openwiki visualize "$HOME/.openwiki/wiki"
Connector ingestion is a data-governance decision. Use read-only, least-privilege identities, keep knowledge bases with different access policies separate, and do not ingest private messages, customer records, or regulated data without authorization. A connector’s source permissions do not carry over to the generated Markdown, so publish only to a destination with equivalent protection.
Verify the result
A successful --init leaves a populated openwiki/ tree. On a small service repository that looks like:
openwiki/architecture/overview.md
openwiki/concepts/domain.md
openwiki/concepts/pricing.md
openwiki/operations/deployment.md
openwiki/workflows/event-ingestion.md
openwiki/workflows/invoice-lifecycle.md
openwiki/testing/unit-tests.md
openwiki/.claims/…
Before merging the first result, check that it answers the questions a new on-call engineer would ask: what the system does and who owns each part, how a request or event flows through it, where data is stored and deleted, how trust boundaries are enforced, and how the service is deployed, observed, and rolled back.
Then read the pages critically. Generated documentation is a proposal until the service, security, and operations owners confirm it. Look for confident claims about topology, ownership, compliance, or data classification that the repository contains no evidence for; a .claims/ entry with no meaningful evidence is the sign to check.
Cost and time
An --init run is an agent loop rather than a single call. OpenWiki plans a page set, reads the repository, drafts each page, and then re-checks every claim against source, so the request count scales with the number of pages.
Measured on a small sample repository (8 files, 158 lines: a service with a Kafka consumer, a rating module, an HTTP surface, one test file, and a Helm values file), routed through a token-counting proxy in front of Token Factory:
| Model requests | 89 |
| Input tokens | 620,738 |
| Output tokens | 50,008 |
| Cost | $0.79 at the published $0.95 / $4.00 per million rates |
| Wall clock | 11.5 minutes |
| Pages produced | 8 of 9 planned |
That works out to roughly $0.10 per generated page. For your own estimate, multiply that by the number of pages your repository will justify rather than by its line count; a real service will plan more pages than this sample.
Wall-clock time is less predictable. A second run of the same repository averaged about 30 seconds per request against roughly 8 seconds in the first, purely from upstream load, so treat elapsed time as a range. Run one manual pilot on a low-risk repository to get your own per-page figure before scheduling recurring runs, and give the CI job both a timeout and a spend threshold.
Troubleshooting
- OpenWiki asks for provider setup: confirm all three variables are present in the same shell with
test -n "$NEBIUS_API_KEY" && echo set, thenecho "$OPENWIKI_PROVIDER"andecho "$OPENWIKI_MODEL_ID". Never echo the key itself. - The model is rejected: identifiers are case-sensitive and the catalog changes over time. Confirm
moonshotai/Kimi-K2.7-Codeis available to your account in the Token Factory catalog. - The wiki contains unsupported claims: tighten
openwiki/INSTRUCTIONS.md, make authoritative schemas and tests readable, and have the owner correct the page. Do not turn an assumption about topology or compliance into a documentation requirement. - A CI update produced sensitive or incorrect content: do not merge it. Rotate any disclosed credential, restrict the input path or connector, remove the content through your incident process, and preserve the workflow and review evidence.
Clean up
The cookbook creates no cloud resources. Remove the local install and the generated wiki if you were only trialling it:
npm uninstall --global openwiki
rm -rf openwiki
unset NEBIUS_API_KEY OPENWIKI_PROVIDER OPENWIKI_MODEL_ID
OpenWiki’s interactive setup can persist credentials to ~/.openwiki/.env; on a shared or managed machine, inject the key from your secret manager instead. If the key ever reached a shell history file, a workflow log, or a commit, rotate it in the Token Factory console rather than deleting the file and assuming it is gone.