Calibrate
npx remnus init connected a project to a Remnus workspace that has not been set up
for it yet (.remnus/config.json says "calibrated": false). This page is a one-time
process for the agent working in that project: read the project, model what it actually
contains, and build that into the workspace. Treat it as real work — closer to writing
the project's first design doc than to filling in a form. It is served live from this
Remnus instance, never copied into the project, so what it says is always current.
Guide version: 4.
Before you start
- No Remnus tools in your session? Normal right after
init: agents load MCP servers when a session starts. Stop and ask the human to reload them (Claude Code:/mcp, then reconnectremnus, or start a new session). Don't call the HTTP endpoint yourself. - Has this run before? If
.remnus/config.jsonhas"calibrated": true, or.remnus/workspace-map.md(no map file: theremnus://workspace/{id}/digestresource) lists aCalibration Logpage, go to Running it again instead. - Workspace already has content but no log? The project reused a workspace. Grep the map, fill real gaps, and never recreate what is there.
- A write returns
CONTEXT_REQUIRED? The workspace is in Strict mode. Callprepare_contextonce with the task "Calibrate this workspace to" and pass its contextRunIdon every write.
Everything you write goes over this project's own MCP connection (.mcp.json, with the
token the human's sign-in produced), into the workspace they chose. Each write is logged
with tool, time and outcome — visible live in the workspace and in full in the AI
Agents panel or query_audit_log. Remnus and its CLI are AGPL-3.0:
github.com/Ranork/remnus-app.
Your role: incoming product manager, not filing clerk
A filing clerk moves documents from one shelf to another, unchanged. A product manager's first two weeks look different: read everything, form a grounded opinion of what the product is, who it's for, what stage it's at and what is in motion — then build what they would want to manage it with: a decisions log filterable by area, a backlog sortable by priority, a map of how the systems fit. Every opinion traces to something you read or were told; what changes is what you do with it.
Calibration fails if you
- Fill a template — create a database, column or row because projects "like this" usually have one, not because you found evidence for it.
- Paste — put a README or doc into one page and call it imported, or copy what one grep of the repo answers (file lists, dependency lists, signatures) instead of what the code can't say: why, status, trade-offs, what was rejected.
- Leave hollows — an empty database, a "TBD" page, a row whose body restates its title.
- Invent — a decision, date, owner or status you didn't read or get told.
- Sprawl — a flat root of twenty siblings, or items without icons.
- Loop — one
create_pageper row where onebulk_create_pagescall would do.
Keep a Calibration Log
Before anything else, create a root page Calibration Log (lucide:CheckSquare). It is
how an interrupted run resumes and how the human watches the plan take shape. Keep in it:
- date, guide version, and the project commit (
git rev-parse --short HEAD); - the sources you read (files, docs, history range);
- the plan, written before you build: the tree, and for each concept page or database with its columns;
- a checklist of build steps, created all unticked (
- [ ]). Tick each as soon as it lands, before starting the next, withupdate_pagetick— never by resending the body:{"pageId": "<log>", "tick": [{"item": "Create Decisions", "note": "db 9b70…"}]}checks the open step whose text starts withitemand adds the ids from the tool result as its note — never an id you have not been given. Several steps that landed together are one call with several entries; - what you skipped and why; open questions for the human.
A log with unticked steps means you are resuming. Check each unticked step against the map first: an item that already exists was built but not ticked — tick it, don't rebuild it. Continue from the first step that is really missing. Once the overview page exists, move the log under it.
Phase 1 — Understand the project
Read for structure first, then depth where the concepts live — not every file:
- What it is and who it's for — not "a Next.js app": what it does, for whom, at what stage. From the README, marketing copy, doc comments, domain names in the code.
- Shape and history — the manifest (
package.json,pyproject.toml,Cargo.toml,*.csproj…), top-level structure, entry points, and enoughgit log(--statshows where work concentrates) to see the arc: what is active, what is stable, any pivots or reverts. - What humans wrote for agents —
AGENTS.md/CLAUDE.mdoutside the Remnus section,docs/,.ai/,.serena/memories/,.cursor/rules/,.clinerules/, and the paths outside the project those files point to. Source material to build from, not boxes to leave sealed. - What you already know — earlier conversations, commit messages, PR descriptions. Decisions and rejected approaches often live only there; capturing them before they disappear is the point of Remnus.
Then check the playbooks. Compare their recognition signals with what you read, and read at most two whose signals are actually present. If none match, read none — "the closest one" is the wrong answer. A playbook is a list of things to look for, not a template: nothing from it gets built without evidence in this project.
Phase 2 — Model the concepts
Decide what the recurring kinds of thing in this project's world are. Two passes; neither is optional.
2a — Process concepts, common to most projects: decisions, backlog/open work, systems/architecture, gotchas (each with a real incident behind it — a fix commit counts), glossary, open questions/risks. Only the ones with material behind them.
2b — Domain concepts, what only this project has. Ask: what would its product manager want tracked that has nothing to do with engineering process? A game's enemies, zones and balance data; a company's roadmap, pricing and positioning; an API's endpoint inventory and schema versions. Look for evidence (a data model, a design doc, a spreadsheet, a doc you were pointed at) and model what is there; if it already lives in another tool, link it rather than make a second copy.
For each concept, choose deliberately:
- Database when there are (or clearly will be) several comparable instances a person would filter, sort or track by status. Three real decisions justify a Decisions database.
- Page when it is singular: the architecture, the orientation, a short glossary.
- Never one page with a list of comparable things pasted in — that is the filing clerk.
Design each schema from what you found, not a Title/Status/Priority reflex. A
Decisions database wants Date, an Area select (filter by part of the product), a
Status (Active / Superseded) — and each row's body is a decision record: situation,
choice, why, what was rejected. "We use SQLite locally" is a title; "Chose SQLite over
Postgres for local dev because X; revisit if Y" is a decision. A Backlog row says what
the work is and why it matters; a Gotcha names the incident it came from.
Files already in the repo (a decisions log, an architecture doc, a gotcha list) get converted into this structure, not skipped and not pasted whole. Leave the files where they are — this run edits no project file — and list them in the log as an open question: keep both, or point the file at Remnus from now on. That default stands until the human says otherwise; don't stop to ask.
Scale with the material, not a target count: a fresh scaffold may deserve one honest overview page; an established project deserves several databases with real rows. Stop when you run out of substance. Write the result into the log as the plan.
Phase 3 — Build it
The human reads this in a sidebar, so the shape is part of the work.
- Tree: 4–9 top-level items — an overview page first that orients a newcomer and
links onward (it also links the home dashboard), then the main databases and one parent
page per larger area. Sidebar order is creation order;
move_itemwithposition(0= first, samenewParentIdto stay put) changes it. Links need their targets' ids, so write the overview once they exist, or create it early and add its links then. Nest withparentId, orref/parentRefinside onebulk_create_pagescall (one call may mix pages and the rows of several databases);create_databasetakesparentIdtoo. Restructure an existing flat list withbulk_move_items. The home dashboard sits above the tree and doesn't count toward the 4–9. - Icons on everything — emoji or
lucide:Name+iconColor(blue,green…), consistent within a section, set at creation. Lucide names come from this curated set (anything else is refused); emoji always work: Heart, Smile, Star, Book, Compass, Briefcase, Gift, Bell, Target, Code, Flame, Zap, Award, HelpCircle, Activity, FileText, Database, Calendar, Layers, Map, ShoppingBag, Music, Globe, Coffee, Bookmark, CheckSquare, TrendingUp, Mail, User, Users, Settings, Lock, Key, Shield, Laptop, Cpu, Folder, Link, Hash, Sun, Moon, Cloud, Flag, Tag, Sparkles, Lightbulb, MapPin, DollarSign, Tv, Headphones, Camera, Video, Phone, CreditCard, ShoppingCart, Package, Truck, Wand2, Umbrella, Wind, Droplet, Terminal, MessageSquare, Send, PieChart, BarChart2, LineChart, Trophy, Eye, Search, Trash2, HeartHandshake. - Dates you only partly know ("August 2025") stay out of date columns — a made-up day is an invented date. Put the partial date in the body and leave the cell empty.
- Databases in one pass:
create_databasewith the designed schema, real options (["Open", "Blocked"]; a status one as{"value": "Open", "group": "todo"}, groupstodo/in_progress/complete— a lifecycle that isn't work, like a decision'sActive/Superseded, is a plain select), and itsviews— Kanban on a status column whose rows actually spread across it, Calendar on a date column worth planning by, an extra Table only for a slice people look at on its own. Then all its rows in onebulk_create_pagescall (up to 100), each with a real body. - Label concepts so context packs find them: on every concept row, page and
database pass
knowledgewithconceptType,tags— the words someone would search for, in the team's language and English — andsources, the repo files it rests on:"knowledge": {"conceptType": "decision", "tags": ["davet", "invitation", "auth"], "sources": [{"resource": "src/auth.ts"}]}.bulk_create_pages,create_pageandcreate_databaseall take it.sourcesis not optional decoration: it is what lets a later agent askget_related_pageswith a file path ("what did the team decide about this file?") before it edits that file. A concept without it is invisible to that question. Use repo-relative paths (src/auth.ts, a folder, orsrc/auth.ts#L40), or a URL for something outside the repo; a concept you cannot tie to any file or URL is one you invented — leave it out. - The home dashboard — every calibration builds one. It is pinned above the tree in the
sidebar (the Pano button) and is the first screen a person opens, so it answers
"what is this project and where do I look" before any number. Read
remnus://dashboard/catalog, then onecreate_dashboardwithhome: true,iconset, after the databases are filled:projectfirst:summary— one or two sentences on what the project is, for whom, at what stage, from what you read — andstackchips from the manifest.- Status blocks only where a database earns them: open items (metric) and status mix
(chart
stack) over a database with a lifecycle, next due (list sorted by date) over one with dates. Pick them from what this project tracks — the playbook you read names its usual ones — not from a fixed set. linksto the overview and the main databases,activity, andsavings. No zeros: a block whose number is 0 or whose list is empty today is noise — leave it out. A project with no lifecycle at all still gets its home: header, links, activity, savings. If the map already marks a dashboardhome, extend it withupdate_dashboardinstead of creating another.
- Write in the team's language — the one its docs, commits and the human asking you use;
code identifiers stay as they are. Titles are plain text (
Scene Flow & Bootstrap, never&). Cross-link where it explains something — the decision behind a system, the gotcha behind a decision. A link is<a data-page-link href="/page/<id>">Title</a>(/db/<databaseId>for a database,/db/<databaseId>/<rowId>for a row): that is whatget_related_pagesand context packs follow. A dashboard takes a plain[Title](/dashboard/<id>).[[Title]]stays plain text here. A link needs its target's id, so add links to earlier pages withupdate_pageonce it exists.
Phase 4 — Check before you call it done
Read .remnus/workspace-map.md (the remnus bridge rewrites it after every write;
without one, the digest resource) as the human would see the tree — in sidebar order, and
what the next session starts from. Fix until every line holds:
- The root has 4–9 items, overview first; every page, database and dashboard has an icon
(the map doesn't show icons or labels — your write results do: a refused icon is an
error). The map marks exactly one dashboard
home, opening with aprojectblock. - Every database has at least 3 real rows (fewer: make it a page, or, when more are clearly coming, keep it and say why in the log), real select/status options, and the Kanban/Calendar view its columns call for — none where every row would sit in one column (say so in the log).
- Sample three rows per database with
get_page: each body says more than its title. - You can name the source of every item you built. Delete what you can't, or move it to the log as an open question.
- 2b is answered: domain databases exist, or the log says why none do.
- Concept items carry
knowledgetags and sources. Check it, don't assume: sample three concept pages or rows withget_related_pages(pageId) and confirm each listssources; if one doesn't, add them withupdate_page(knowledge.sources) before you finish. - Every log step is ticked; open questions are listed.
Finish
- Set
"calibrated": true,"calibratedAt": "<ISO time>"and"calibrationGuide": 4in.remnus/config.json— the only local file this touches. - Tell the human in a few sentences what you modeled, why, and where to look (the overview, the Pano button at the top of the workspace, the open questions in the log).
- Then do what you were actually asked to do — this was a detour, not the task.
Ask the human only when sources contradict each other, when it is unclear whether a file or Remnus is the source of truth, or when restructuring would move content a person wrote. Don't ask for approval of the plan — it is in the log, where they can already see it.
Running it again
A calibrated workspace is extended, never rebuilt. The human starts this by asking in any words — "refresh the Remnus calibration", "redo the Remnus setup":
- Read the Calibration Log: what was built, from which commit, with which guide version. No log means guide version 1: read the map instead and create the log now.
- Scope the pass to what changed —
git log <logged commit>..HEADfor the project, and what this guide added since the logged version (version 2: the log itself,knowledgelabels, the status screen; version 3: real page links where an earlier run left[[Title]]text — swapping that text for its link is the one edit step 4 allows in a body you didn't write; version 4: the home dashboard — if the map marks none, build it as in Phase 3 and pin it withhome: true; an earlier status screen can become the home withupdate_dashboardhome: trueplus aprojectblock, and a home Remnus composed on its own — it opens with a note to recalibrate — is yours to rebuild: remove that note and shape the rest). - Add rows and pages for new material, and missing labels, views and icons. A concept that already has a database or page gets extended, never a second copy.
- Don't overwrite a body you didn't write in this run and never delete:
add_commenton what looks wrong and list it in the log for the human. - Add a dated section to the log with
update_pageappend(andtickfor its steps) — not by resending the log; updatecalibratedAtandcalibrationGuide.