Skip to content

Latest commit

 

History

History
291 lines (227 loc) · 13.4 KB

WIKI.md

File metadata and controls

291 lines (227 loc) · 13.4 KB

The Wiki

Repowise builds a wiki for your repository at index time: a page per source file, per selected public symbol, per subsystem, per dependency cycle, per infrastructure file and per API surface, plus a repository overview and an onboarding collection. It is refreshed incrementally on every commit, and it is what get_answer, search_codebase, the CLI and the local dashboard read from.

Almost all of it is rendered from your code's structure with no model in the loop. A provider key adds prose to the subsystem layer and the top-level narrative pages. It does not switch the layer on: a repository indexed with no key gets a complete wiki, not a placeholder.

Quick start

repowise init                      # builds the wiki as part of indexing
repowise init --no-prose           # keyless and free, guaranteed no spend
repowise update                    # re-renders only what your commits touched
repowise generate                  # fill in the subsystem prose later
repowise restyle reference         # re-render every page in a different voice
repowise serve                     # browse it at localhost:3000
repowise export --format markdown  # write it out as files

What gets generated

Pages are produced in ordered levels, most local first, so a page that quotes another is generated after it.

Level Page type One per Written by
0 api_contract API spec (OpenAPI, proto, GraphQL) or FastAPI / ASP.NET route module structure
1 symbol_spotlight selected public symbol structure
2 file_page eligible source file structure
3 scc_page dependency cycle structure
4 module_page subsystem in the concept tree model, structure when keyless
5 flow_page operation walked end to end (3 to 6 per repo) model, structure when keyless
6 repo_overview repository model, structure when keyless
7 infra_page Dockerfile, Makefile, Terraform file or container entrypoint script structure
8 onboarding slot model, structure when keyless

The onboarding slots are Project Overview, Getting Started, Key Concepts, How It Works, Active Landscape and Glossary. Project Overview is not generated separately, the repository overview is tagged into that slot, and Glossary is rendered from mined terms with no model in every run, keyed or not.

A flow page follows one operation, such as a CLI command, a route handler or an MCP tool, from the function that starts it through the calls that carry it. The operations and their steps are traced from the call graph, so a keyed and a keyless index pick the same ones; a model explains each step, and a keyless run lists the steps with their line spans. Every step is cited as path:start-end, and an edit to any step's file marks the page stale.

Layers are grouping rows in the docs tree, built from provenance stamped on their members, not pages of their own. The repository overview carries the system map, a tiered diagram of who uses the system, the ways in, the server, the engine and the data store. Structure picks its boxes and arrows; a configured model only names them.

Which pages exist

By default there is no page budget. Every page type below the concept tree is rendered from structure and costs no tokens, and the concept partition covers every production file, so rationing it would stop it being a map of the repository. Each bucket takes every candidate that clears its eligibility floor.

The one exception is opt-in and owner-chosen. max_file_pages bounds the file bucket, highest importance first, for repositories large enough that the tail costs more in bytes and retrieval noise than it pays back. Unset lets a size policy decide, 0 means one page per eligible file however many that is, and a positive value is a hard cap. It does not reduce model spend, because file pages are rendered from structure either way.

Selection does not depend on whether a key is present: a keyed and a keyless index of the same commit agree about which files have pages.

What a model writes

Four page types are model-written when a provider is configured: module_page, flow_page, repo_overview and onboarding. These pages explain how the codebase fits together above the file level. Everything else is rendered from the parse, the import graph and git history, and no model ever sees it.

A model-written page is not prompted with raw source. It is prompted with assembled material: parsed structure and signatures, what the subject imports and what imports it, ownership and churn signals, the significant commits from its history with merges, dependency bumps and lint-only commits filtered out, and cross-references to the pages it should link to. The result explains why instead of restating what.

Keyless runs

repowise init never requires a key. Without one it renders the whole wiki from structure and exits 0. Ask for it explicitly with --no-prose, which is what free-tier, CI and air-gapped runs want.

What you give up is the subsystem prose, and semantic search until an embedder is configured. Full-text and symbol search work either way. File pages, symbol pages, hotspots, ownership, dead code, the dependency graph, code health and decision archaeology are identical.

Two facts on every page

Each page records two separate facts:

  • provider_name answers has a model written this page yet. It is what the docs tree's "not written yet" marker and the reader's upgrade affordance read. A page rendered from structure carries no model_name.
  • confidence answers how far should a reader trust the statements. A structure-rendered page is 1.0, because everything on it is extracted from the code. A model-written page is 0.8: grounded in the assembled material and checked against it, but a summary of the code instead of an extraction. Nothing gates on the difference; it is reported.

The axis is trust, not completeness. A page can be thin and still be entirely true. A 0.3 marks a page that was meant to carry prose and lost it to a provider outage, the one state a reader cannot infer from the page itself. A keyless run produces 1.0 pages throughout, because an index built without a key is that shape by design.

Adding prose later

Upgrading is in place and incremental. Neither command re-indexes: the graph and git metadata are rehydrated from SQL, and only the per-file parse and the generation you asked for run.

repowise generate                        # every subsystem page still unwritten
repowise generate --path src/api         # under a path prefix or glob
repowise generate --stale                # pages whose code changed since writing
repowise generate --all                  # rewrite the prose everywhere
repowise update --full                   # the whole wiki at once

generate writes the model-written pages and only those. Naming a structural page with --page is an actionable error instead of a silent LLM re-render, because those pages refresh on repowise update for free. Run it bare on a terminal and it prints the wiki's state, defaults to the unwritten pages, and ends at the normal cost confirmation.

What update re-renders

repowise update does not rebuild the wiki. It finds the files changed since the last sync, walks the dependency graph for the pages those changes affect, and re-renders only those, typically a handful per commit.

Two mechanisms decide what is stale:

  • Model-written pages compare a hash of the rendered prompt against the stored one. Same prompt and same model means the prior page is reused verbatim, with no tokens spent.
  • Structure-rendered pages fold the subject's own hash together with a fingerprint of the renderer: the template source, the resolved style and the output language. Comparing the stored key against a freshly computed one turns a released template change into exactly one regeneration.

So a new Repowise release that edits a template re-renders every page of that type once. That is intended, not drift.

Cycle, API-contract and infra pages follow the rebuilt graph on every update: a new cycle or newly selected file gets its page, a changed infra file is re-rendered, and a page selection no longer picks is removed. A deleted file's page stays as a tombstone for 30 days, a renamed file's as a redirect.

--cascade-budget N caps how many pages a single update may regenerate from cascading changes. It is adaptive when unset, which is what you want except on a very large refactor commit.

Pages also carry a freshness status of fresh, stale, expired or unknown. Expiry by age takes priority, then a source-hash mismatch marks a page stale.

Styles

A style controls the voice and density of the prose without changing the structural markdown. Headings and sections stay the same, so search, the table of contents and cross-links keep working across a style change.

Style Best for What it reads like
comprehensive The default. Humans and AI. Full, narrative documentation.
caveman AI agents, token budgets. Token-condensed fragments, ~70% smaller.
reference Library consumers. API-manual: signature-dense, minimal narrative.
tutorial New contributors. Guided, beginner-friendly walkthroughs.

List the available styles and the repo's current one:

repowise wiki-styles

Choosing and switching

At init (full mode), pick a style with a flag or the interactive prompt:

repowise init --wiki-style caveman

The choice is saved to .repowise/config.yaml as wiki_style:, so update keeps regenerated pages in the same style.

Switching re-renders every page in the new voice. Use the dedicated command: it reuses the existing index and git data, so nothing is re-resolved or re-blamed.

repowise restyle reference

In the web app, Settings > Documentation style does the same, and an individual page can be regenerated in a one-off style from its Regenerate control.

Editing wiki_style in config.yaml by hand and running repowise update will not regenerate existing pages, that path only re-scores health. Use repowise restyle to apply a style change.

Custom styles

Define your own under .repowise/styles/<name>/style.yaml:

# .repowise/styles/terse/style.yaml
description: Ultra-terse internal style
onboarding_condenses: true        # also condense the onboarding pages
style_version: 1                  # bump when you edit this file to force regen
system_note: |
  Write for senior engineers who know the domain. Be extremely concise.
user_directive: |
  Write in TERSE style.
  - Keep every required ## heading; bodies are short fragments.
  - No filler, no restating the heading, no closing summary.
  - Keep code identifiers and paths verbatim.

Then apply it:

repowise restyle terse

A style may also ship per-page-type Jinja templates in .repowise/styles/<name>/templates/, using the same filenames as the built-ins (file_page.j2 and so on). They override the built-in template for the page types you supply; anything you leave out falls back to the default.

Guard rails: style names must match [a-z0-9][a-z0-9_-]*, directive and note text are length-bounded, and a style with neither a directive nor a note is ignored. Built-in style names always take precedence over a custom directory of the same name.

Output language

language in .repowise/config.yaml, or init --language <code>, sets the natural language of the wiki. It reaches both the model-written prose and the headings and fixed sentences of the structure-rendered pages, for the languages that have a label catalog. A supported language without one keeps English headings on those pages while the model-written prose is still translated, and an unknown code falls back to English with a warning.

Code, file paths and symbol names are never translated, in any language.

Changing the language later does not retranslate existing pages. Re-run init --force --language <code> to rebuild the wiki in the new language.

Where the wiki shows up

  • Agents: get_answer retrieves and quotes from it, search_codebase ranks it, get_context pulls the page for a file or symbol. Hybrid retrieval merges SQLite full-text and vector results through Reciprocal Rank Fusion, biased by PageRank, then expands one to two hops along the imports and projected-calls graph for flow-shaped questions. Full-text works with no embedder; semantic search needs one configured. A module page's agent digest (the questions it answers, its concept index, public API and git signals) is stored beside the page body, indexed with it, and returned by get_context as digest_md with include=["full_doc"].
  • CLI: repowise ask, repowise search, repowise context.
  • Dashboard: repowise serve, then the Docs tab.
  • Files: repowise export --format markdown|html|json, written to .repowise/export by default.

Related

  • INTELLIGENCE_LAYERS.md for how this layer sits next to graph, git, decisions and code health.
  • CONFIG.md for wiki_style, language, max_file_pages and the rest of the generation settings.
  • CLI_REFERENCE.md for init, update, generate, restyle, wiki-styles and export in full.
  • AUTO_SYNC.md for keeping the wiki fresh automatically on every commit.