Project context

Per-repo .werbos.md context: what werbos sees about your project before it sees your prompt. Mirrors Claude Code's CLAUDE.md pattern.

werbos reads a .werbos.md file from your project root before every chat session and prepends its contents to the system prompt under a # Project section. The file is for things the model can’t derive from the code: sibling-repo relationships, build/test commands, naming conventions, “don’t touch X” warnings, recent renames.

Same idea as Claude Code’s CLAUDE.md. Different filename, identical shape.

Discovery

When werbos chat or werbos serve boots, it walks parents from the working directory up to $HOME looking for .werbos.md. The nearest hit wins. Stops at $HOME (a global ~/.werbos.md works as a fallback for any project below it; it does not climb above home).

Files larger than 50 KB are skipped — keeps a runaway / committed-by- mistake file from blowing up every system prompt.

# Default: walk up from cwd
werbos chat

# Walk from a specific dir (the same path used by --workdir)
werbos chat --workdir /path/to/project

# Use a specific file regardless of location
werbos chat --project-context-file ./notes/project.md

# Disable entirely
werbos chat --no-project-context

The same flags work on werbos serve.

Bootstrap with werbos init

Stamp out a starter .werbos.md for the current directory:

werbos init                        # interactive, 3 questions
werbos init --yes                  # accept all defaults
werbos init --force                # overwrite an existing file
werbos init --dir /path/to/project # write somewhere other than cwd

werbos init auto-detects the project’s main language and likely build command from common manifests:

ManifestLanguageBuild hint
pyproject.toml / setup.pyPythonpytest -q
package.jsonTypeScript / JavaScriptnpm test
Cargo.tomlRustcargo test
go.modGogo test ./...
Makefile(lang unknown)make test
pom.xmlJava(no default)
GemfileRuby(no default)
mix.exsElixir(no default)

Then it asks three questions (project name, main language, build command) with the detected values prefilled. Answer with Enter to accept the default, or type a different value.

What to put in it

Things the model can’t see from the code itself:

  • Sibling repo relationships (“partyparrot is the wire protocol; pfm is the archive format; pitts is the agent loop”)
  • Build / test commands that aren’t obvious from pyproject.toml ("make integration needs SR8 reachable; pytest -q skips the slow network tests")
  • Naming conventions (“v5 means the TTT LoRA, not Llama 3.5”)
  • Don’t-touch warnings (“the salvage parser in pitts/backends/bellman.py:_salvage_text_tool_calls is the R2 defense; do not soften it”)
  • Recent renames or restructures the model would have stale knowledge of
  • Project-specific tool discipline (“we use uv, not pip”; “this project never imports requests, use stdlib urllib”)

The file is plain Markdown. The starter template includes empty sections for each of these so you can flesh them in over time.

Where the text lands

Inside the system prompt, between persona and memory:

# Persona
<persona text>

# Project        ← .werbos.md goes here
<project context>

# Memory
<text from memory store>

# Tools
<tool descriptions>

werbos chat prints a startup line like Project ctx: 412 chars when it loaded a file, or Project ctx: (none) when nothing was found.

Reload

Today the file is read once at session boot and cached for the lifetime of the chat. To pick up edits, end the chat (:q) and start a new one. A /reload-context slash command is queued — it will re-read .werbos.md mid-session.