Archlens Rev 0.3.0 · next
Archlens source on GitHub

A-000 Cover sheet · Living architecture docs for Claude Code and AI coding agents

Architecture docs that stay in sync with your code.

Archlens keeps your architecture docs in step with your code. It writes a small handbook, or adopts the docs you already have where they live. It gives your coding agent a map of the whole project in a few hundred tokens, and teaches you the codebase while you work. It runs as a Claude Code plugin and as a portable Agent Skill for Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, and other agents.

Detail 1: code and page, coupled Real files from examples/order-service

Sourceorder_service.pylines 20–38

def submit_order(connection, request_key, sku, quantity):
    if not isinstance(request_key, str) or not request_key.strip():
        raise ValueError("request_key must be a non-empty string")
    if not isinstance(sku, str) or not sku.strip():
        raise ValueError("sku must be a non-empty string")
    if type(quantity) is not int or quantity <= 0:
        raise ValueError("quantity must be a positive integer")
    with connection:
        connection.execute(
            "INSERT INTO orders (request_key, sku, quantity) VALUES (?, ?, ?) "
            "ON CONFLICT(request_key) DO NOTHING",
            (request_key, sku, quantity),
        )
        order_id, existing_sku, existing_quantity = connection.execute(
            "SELECT id, sku, quantity FROM orders WHERE request_key = ?", (request_key,)
        ).fetchone()
        if (existing_sku, existing_quantity) != (sku, quantity):
            raise RequestConflict("request_key already identifies different order data")
    return order_id

Pagedocs/architecture/runtime/submit-order.mdFLOW-001

What happens when the caller submits an order?

The library validates the input before it starts a write. It creates an order or finds the order with the same request key. It rejects a repeated key whose SKU or quantity differs.

Rule orderConditionResultSide effect
1Empty or non-string keyValueErrorNone
2Empty or non-string SKUValueErrorNone
3Quantity is not a positive integerValueErrorNone
4Existing key has different dataRequestConflictTransaction rolls back
5New key or matching repeated keyOrder IDNew record commits, or existing record remains

Page maploaded at session start1,131 bytes

## Architecture handbook (Archlens)
Pages live in `docs/architecture/` (6 pages, 0 stale). Use them to find the right code fast and to learn why it is built this way. Pages summarize; source is authoritative: confirm names, limits, and behavior in the linked source before you answer or change code. STALE means evidence the page cites changed after the last doc sync. After an architectural change, update the affected pages.

- `README.md` Understand the order example: The library stores an order and returns its ID. [covers order_service.py]
- `context.md` What are the main parts?: The caller runs in the same process as the order library. [covers order_service.py]
- `runtime/submit-order.md` What happens when the caller submits an order?: The library validates the input before it starts a write. [covers order_service.py]
- `data.md` Where does order data go?: The caller supplies the input. [covers order_service.py]
- `glossary.md` Glossary: These are local project definitions, not an official STE vocabulary.
- `decisions/ADR-001.md` ADR-001: Identify repeated submissions with a request key [covers order_service.py]
≤ 3,000 bytes · default contextBudget
1,131 B

Page text, map lines, byte counts, and the Stop hook and commit gate messages are real output of archlens.py (next release) on the order example. The quantity limit is a hypothetical edit, simulated in your browser.

A-101The problem

Docs go stale a week after they are written. Agents start from zero every session.

Nothing says which architecture page drifted, and nothing tells a coding agent where to look, so it explores the repository again. Archlens answers both with one small handbook, or the docs you already have, and a baseline for every page.

Schedule of problems

MarkWhat goes wrong todayWhat Archlens doesMeasured
P1Docs go stale a week after they are writtenFingerprints the exact functions and line ranges each page cites, in Python and C-family languages, and flags the page when that code changes, even after a commitChecks 50,000 files in 0.20 s
P2Moved code breaks every #L120 linkRewrites links whose cited code only moved, or whose file was renamed. No model, no tokensAutomatic after each Claude turn
P3Agents re-explore the repository every sessionLoads a compact page map at session start, or writes it into AGENTS.md408 tokens for this repo; capped at 3,000 bytes
P4Context files bloat every turnOne model-visible description; everything else loads only when used178 bytes in every session
P5AI wikis invent plausible detailsEvery claim links to source, tests, or decisions. Unknowns stay unknown. A checker catches dead links, moved anchors, and vanished symbols0.04 wrong claims per answer in the benchmark
P6You ship code you do not understand/archlens:learn answers questions, gives a tour, quizzes you, and explains your branchInline, so you can ask follow-ups
P7The docs you already have drifted long ago Adopts them where they live: maps them, fixes statements the code contradicts with minimal edits, and adds pages only for real gapsTrial: 16 docs mapped, 3 real errors fixed, 5.8 min
P8Checkers bury real errors in noise Style heuristics become one info note per page that never fails --strict. Errors sort firstTrial: 407 warnings down to 4
Detail 2: what setup draws, or adopts

/archlens:setup new or a project without docs

docs/architecture/
  README.md              Reading path, coverage table, and known gaps
  context.md             Users, boundaries, and external systems
  runtime/               Important flows: branches, failures, and recovery
  data.md                Ownership, lifecycle, and retention
  decisions/ADR-*.md     Why the design is this way, with alternatives
  glossary.md            One term per concept
  map.json               Which code each page covers
  .archlens-state.json   Freshness baseline written by sync

/archlens:setup adopt the default when docs exist

docs/architecture/map.json
  ../ARCHITECTURE.md     An existing doc, mapped where it lives
                         Statements the code contradicts: minimal edits
  your ADR folder        New decisions use its folder and numbering
  runtime/*.md           New pages only for real gaps

Archlens starts small: context, main units, and one important journey, then grows by risk. Pages use Mermaid diagrams, short sentences, and plain words.

When a project already has architecture docs, setup adopts them. Nothing moves or gets copied. Mapped docs get the same link and reference checks and freshness tracking, and they appear in the agent’s page map. setup new writes a separate handbook instead.

Detail 3: the Detail 1 edit, from a terminal

examples/order-service

$ python3 archlens.py status --root .
Archlens status: PASS
1 fresh, 4 stale, 1 review, 0 unsynced.
STALE docs/architecture/README.md [INDEX] evidence-changed order_service.py#L20-L38 (submit_order); review: modified order_service.py
STALE docs/architecture/context.md [CONTEXT] evidence-changed order_service.py#L20-L38 (submit_order); review: modified order_service.py
STALE docs/architecture/runtime/submit-order.md [FLOW-001] evidence-changed order_service.py#L20-L38 (submit_order); review: modified order_service.py
STALE docs/architecture/data.md [DATA] evidence-changed order_service.py#L20-L38 (submit_order); review: modified order_service.py
REVIEW docs/architecture/decisions/ADR-001.md [ADR-001] review: modified order_service.py
$ python3 archlens.py cite --root . order_service.py submit_order \
--from docs/architecture/runtime/submit-order.md
Archlens cite: PASS
[submit_order](../../../order_service.py#L20-L38)

Real output of the next release on the order example, after the lines 25–26 edit. The status notes are trimmed.

Pages cite evidence, often a line range such as order_service.py#L20-L38. sync records a baseline of the function around each range. Python uses its syntax tree. JavaScript, TypeScript, Go, Rust, Java, C#, C/C++, Swift, PHP, Dart, and other C-family languages use a comment- and string-aware brace reader . It is a heuristic, not a parser. Comments and formatting do not count, and a moved function is followed.

A range inside a larger function tracks only its own lines. One changed rule in a 40-line function no longer flags every citation inside it.

Cited evidence that changed makes a page stale. A whole-file link to code goes stale only when the file’s declared names change; body edits mark it for review, as ADR-001 shows. An edit to a linked Markdown document marks review; deleting a linked file marks stale. Comment-only edits never make a page stale.

Links follow the code with no model. Moved code, files Git reports as renamed, and citations shifted by a new comment inside a function are rewritten. When a cited function disappears, status suggests a likely rename, such as symbol-removed memory.py#L14-L19 (authorized) now `is_authorized`?

cite prints a link-ready range for a symbol, so pages cite exact lines. check warns when a range cuts off a function’s first or last code line by one or two lines.

A stale flag means “check this page”. It does not prove the prose is wrong.

A-201The loop

Detecting drift costs no tokens. Rewriting prose happens only where it drifted.

Archlens separates two jobs. A local script compares the code each page cites with the baseline recorded at its last sync, and rewrites links whose code only moved: no model, no tokens. An agent then reviews only the stale pages, edits what changed, and syncs the pages it verified. By default that happens once per commit, so the docs land in the same commit as the code.

Detail 4: the freshness loop Hover or focus a callout
The Archlens freshness loop Session start loads the page map with stale flags. The agent works and edits covered code. The Stop hook flags stale pages when a turn ends, and the commit gate holds a commit that would leave pages stale. Update reviews them in an isolated task. Sync records the new baseline, code and docs commit together, and the next session starts from there. ≤ 3,000 B Session start Hook prints the page map with stale flags Agent works Opened files name their page once Commit gate Stop hook flags pages; a commit waits once Update Isolated task reviews only the stale pages Sync Records each reviewed page’s new baseline page map + stale flags turn end · git commit commit | auto verified pages code + docs commit next session local script · no model tokens agent work · uses tokens 1 2 3 4 5 The Archlens freshness loop, vertical layout: session start, agent works, commit gate, update, sync, then code and docs commit together and the loop returns to session start. ≤ 3,000 B Session startHook prints the page mapwith stale flags Agent worksOpened files nametheir page once Commit gateStop hook flags pages;a commit waits once UpdateIsolated task reviewsonly the stale pages SyncRecords each reviewedpage’s new baseline map + stale flags turn end · commit commit | auto verified pages code + docs commit · next session local script · no tokens agent work · uses tokens 1 2 3 4 5

Keyed notes

  1. Session start. In a project with a handbook, a SessionStart hook prints the page map: one line per page, with stale flags. The budget is 3,000 bytes by default; this repository’s map is 1,630 bytes, about 408 tokens. Summaries come from a page’s “Summary” section when it has one. Projects without a handbook get nothing.
  2. Agent works. The map says where to look. When the agent reads or edits a documented file, a hook names that file’s page, once per page per session. Pages summarize; source is authoritative.
  3. Stop hook and commit gate. When a turn ends, a local script compares cited evidence with its baseline. Code that only moved, or a file Git reports as renamed, gets its links rewritten. Code that changed makes the page stale, and you see one line per new set of stale pages. 276 ms on a 50,000-file repository. Before Claude runs git commit, a PreToolUse hook holds the commit once if it would leave pages stale.
  4. Update. With "autoUpdate": "commit" (the new default), the held commit runs the update first, in an isolated task. With "auto", it runs at the end of every turn. It fixes stale pages first, confirms review pages, and changes only prose the change made wrong.
  5. Sync. sync records the reviewed pages’ new baseline and refreshes the context file. It trusts the caller, so only pages someone checked against current source get synced. Then the commit runs again, and code and docs land together.

When docs update

autoUpdateAfter each turnWhen Claude runs git commitModel tokens
offNothingNothingNone
remindOne message per new set of stale pagesNothingNone
commit (default)One messageHolds the commit once, runs the isolated update, then commits code and docs togetherOne update per commit that leaves pages stale
autoRuns the isolated updateSame as commitOne update per turn that leaves pages stale

In every mode except off, the hooks first rewrite line links whose cited code only moved. Commits you make yourself in a terminal are not held: the turn-end message and the archlens-stale pre-push hook catch them. You add nothing to CLAUDE.md. The hooks are deterministic and cost no context until a page is actually stale. Other agents get the same rule through the AGENTS.md block.

No churn while code is still changing

Three turns that each change cited code, then one commit.

auto

  1. turn
  2. update
  3. turn
  4. update
  5. turn
  6. update
  7. commit

commit

  1. turn
  2. turn
  3. turn
  4. held once
  5. update
  6. commit

Where the loop runs

WhereDetects driftRewrites proseSetup
Claude Code pluginStop hook after each turn; commit gate before each agent commitautoUpdate: "commit" (default) or "auto" runs the isolated updateInstall the plugin
Any agent that reads AGENTS.mdThe map block tells the agent to run the status check before relying on a page, and to update stale pages before it commits codeAsk the agent to run the Archlens update operationcontextFile
Git, any editor or agentpre-push hookDeveloper or agentpre-commit
CIPull request checkOptional agent jobWorkflow, see I-601

Six commands

CommandWhat it doesChanges files?
/archlens:setupAdopts existing docs in place (adopt, the default when docs exist) or writes a small handbook (new), then records the baselineDocs only
/archlens:updateFixes stale pages first, confirms review pages, then syncs themDocs only
/archlens:checkAudits evidence, links, anchors, diagrams, stale references, freshness, and ranges that cut a function short. Errors first; style is one info note per pageNo
/archlens:explainTraces one flow with a diagram and a source-linked step tableNo
/archlens:decideDrafts a decision record with options, tradeoffs, and a review triggerDocs only
/archlens:learnTutors you: questions, tour, quiz, or changesNo

Five run in an isolated task, so exploration never fills your conversation. learn runs inline so you can keep asking. In other agents, ask for the same operations by name. For page authors, archlens.py cite prints link-ready line ranges (Detail 3).

What loads, and when

update descriptionEvery Claude session

178 B

Page mapSession start, only with a handbook

1,630 B in this repository · ≤ 3,000 budget

File pointerAfter reading a documented file

one line per page per session

Stop hookAfter each turn

nothing, unless cited evidence changed

Commit gateBefore Claude runs git commit

nothing, unless the commit leaves pages stale

learnInline, for follow-ups

≤ 2,200 B cold load

Other commandsInside an isolated task

≤ 5,000 B · setup ≤ 10,500 B

Solid lines are measured; dashed lines are limits that CI enforces. Byte counts are not exact tokens (roughly bytes/4). Source reads and outputs are extra.

A-301Evidence

Answers at least as good. About a third cheaper.

72 real Claude Code sessions (Sonnet; Read, Grep, and Glob only) answered eight architecture questions about this repository, three times each, under three conditions. A separate model graded every answer blind against a fixed key. Raw answers, grades, and usage are in the repository.

31%

fewer input tokens

no handbook24,952 archlens17,253

26%

fewer turns

no handbook4.2 archlens3.1

32%

lower cost per answer

no handbook$0.022 archlens$0.015

27%

less time per answer

no handbook9.6 s archlens7.0 s

Key-fact recall, with 95% confidence intervals

The intervals overlap. With 24 answers per condition, differences below about 8 points are noise.

no handbook86% (79–94)
handbook only84% (76–92)
archlens89% (82–95)

Per condition, mean per answer

ConditionKey-fact recall (95% CI)Wrong claims / answerInput tokensUncached inputOutputTurnsCostTime
no-handbook86% (79%–94%)0.1224,9524,1848614.2$0.0229.6 s
handbook84% (76%–92%)023,7783,4938583.9$0.0209.3 s
archlens89% (82%–95%)0.0417,2532,5796513.1$0.0157.0 s

The archlens sessions also had the file-pointer hook, which names a file’s page when the agent opens it. The first grading used an answer key written before the review tier existed; the corrected key re-graded every stored answer without re-running a session. Grades moved by up to 4 points per condition, which shows the size of judge noise.

Recall per question
Questionno-handbookhandbookarchlens
config-order100%100%100%
hook-safety100%100%78%
isolation83%92%75%
json-map92%67%100%
other-agents58%75%100%
portable-sync92%75%100%
staleness67%67%60%
summary-limit100%100%100%

Drift detection at scale

199 ms

status on a synthetic repository of 50,000 files and 300 pages, after changing 25 files. Every page cites a line-range anchor, so the time includes anchor checks. Median of three runs, Apple Silicon laptop, Python 3.9.6.

first implementation4.1 s
sorted prefix ranges0.20 s

The first version scanned every file for every page. Sorted prefix ranges made it fast enough for a hook after every turn.

Speed on all three synthetic repositories
Synthetic reposyncstatuscontextStop hookcheckMap bytesState file
1,000 files, 20 pages61 ms49 ms49 ms81 ms10 ms2,06936,215
10,000 files, 100 pages82 ms75 ms88 ms109 ms26 ms3,000357,086
50,000 files, 300 pages228 ms199 ms216 ms276 ms59 ms2,9821,828,468

The map stays inside its 3,000-byte budget at 300 pages. It keeps each page’s summary before its coverage list, fills them in reading order while they fit, and lists how many pages it left out only when even titles do not fit. A 22-page adopted handbook keeps every summary in 2,979 bytes.

Limits of this evidence

  1. One small repository, about 100 files. Agents can search it quickly without help, so savings on large repositories are likely larger, but they are not measured here.
  2. 24 answers per condition. Differences in recall below about 8 points are noise.
  3. The judge is a model. It is blind to the condition, but it can be strict or lenient.
  4. Questions are about architecture and rationale. This does not measure coding tasks.
  5. The final run cost $1.36 for 72 answers, plus about $0.30 for each grading pass. Rerun it before you rely on it.
python tools/benchmark.py
python tools/model_benchmark.py --questions benchmarks/questions/archlens.json --reps 3
python tools/model_benchmark.py --report benchmarks/results/model-sonnet.json
python tools/render_charts.py

Method, raw results, and questions: docs/benchmarks.md. The model benchmark spends real usage; start with --reps 1.

A-302Real-project trial

One real monorepo. A rule changed, tested, and committed with its docs in 4.6 minutes.

We tried Archlens on a 50,000-line FastAPI + React/TypeScript monorepo with about 6,000 lines of existing docs. Claude Code ran headless on Opus. This is one trial on one repository, not a general benchmark.

4.6min

change, test, and commit

$1.25 for the whole task. One commit with code, test, and docs.

5.8min

adopt-mode setup

$1.53. 16 existing docs mapped in place; 3 real errors fixed.

4

warnings on the existing docs

old checker407 now4

2

citations flagged by one change

before6 now2

Every measured run

TaskTimeCostWhat happened
Change one rule, run tests, and commit4.6 min$1.25The commit was held once and the isolated update ran. One commit landed with code, test, and docs
Setup, adopt mode5.8 min$1.53Mapped 16 existing docs in place and fixed 3 real errors in them: a missing plan node in a graph diagram, a threshold rule, and a broken ADR anchor
Setup that wrote new pagesabout 10 min$2.77Wrote 6 source-linked pages. The runtime page’s sampled claims matched the code. Found a real bug, below
Update after two real code changes93 s$0.40Fixed both drifted claims, including one the checker had only marked review, and added the missing source link
One /archlens:learn answer45 s$0.32Runs inline, so you can ask follow-ups
Detail 5: checker output on the existing docs

old checker

407 semicolon warnings. 1 real broken anchor buried among them.

now

4 warnings, plus one style note per page that never fails --strict.

What the trial changed

  • Style heuristics became one info note per page. Findings sort errors first.
  • Git-ignored paths, never-tracked names such as the MCP method tools/list, and paths in accepted decision records are no longer reported as stale references.
  • After the precision changes, the same code change flags 2 citations instead of 6. A comment-only edit no longer makes the glossary stale.
  • Editing a linked Markdown document marks pages for review, not stale. A docs fix that flagged 5 pages stale now gives 0 stale, 5 review.
  • check warns when a line range cuts off a function’s first or last code line by one or two lines. It found 1 real case, a test citation that dropped the finally: slot release, and no false positives.

Limits of this trial

  1. One trial on one repository. It is not a general benchmark, and your times and costs will differ.
  2. Times and costs are from Claude Code headless on Opus.
  3. The runtime page was checked by sampling its claims, not line by line.
  4. The repository is not named here. The 72-session benchmark on A-301 is the published, rerunnable measurement.

S-401Field survey

How other tools stay current, and what they cost.

Reviewed on 8 November 2026 from each project’s own documentation and files. Vendor claims are as published, not verified by the Archlens project.

From published docs and filesnot measured answer quality

ToolHow it stays currentAlways-loaded costAccuracy safeguardsAgents
ArchlensLocal fingerprints of cited functions (Python and C-family), line ranges, and covered files. Hooks flag drift and hold an agent's commit until stale pages are updated; pre-commit or CI elsewhere. An isolated task rewrites178 B description, plus a map of at most 3 KB only where a handbook existsEvidence links, symbol-level drift, moved-anchor and renamed-file detection, stale prose references, "unknown" rule. Existing docs adopted with the same checksClaude plugin with hooks; portable skill; AGENTS.md block
OpenWikiClaims tied to line-range evidence; clean updates skip model work. Manual run or scheduled CI PRA managed AGENTS.md block; size not statedGrounded claims with versioned evidenceRuns through the host agent's session or its own provider
repowisePer-commit incremental index; path, symbol, and command drift checksUp to 10 MCP toolsSymbol findings need proof from GitMCP clients
Fiberplane driftDoc anchors to file#Symbol with a normalized AST hash; CI fails when staleNear zeroSymbol-level, ignores reformattingSkill; detection only
SwimmDocs coupled to code snippets and tokens; auto-sync check on PRsNot statedElement-level couplingIDE and MCP; commercial
deepwiki-skillModel-driven --updateAbout 526 B descriptions; 3.7 KB skill plus up to 70 KB references per taskLine citations, Mermaid validationSkill hosts
claude-code-auto-memoryStarts an updater agent at turn end whenever files changedAbout 784 B descriptions plus managed CLAUDE.md sectionsNone statedClaude Code
DeepWikiHosted regenerationMCP tools, on demandCode links; users report stale and wrong pagesWeb and MCP
Aider repo map, CodeGraph, SerenaRecomputed from codeSymbol maps or MCP toolsDeterministic, but no rationale or design historyVaries

Source table: docs/benchmarks.md, section 1.

The model benchmark on A-301 compares Archlens with no handbook, not with these tools.

What no reviewed tool combines

A hard always-loaded budget enforced in CI, model-free drift detection on cited symbols, published answer-quality benchmarks including a failed run, and a built-in tutor for the human (/archlens:learn).

Where others are ahead

OpenWiki and repowise have far larger communities. Code-graph tools answer “who calls this” questions that a handbook does not. Swimm couples individual tokens, not just functions and line ranges.

A-501Learn

Understand the code, not just ship it.

/archlens:learn is a patient tutor. It answers from handbook pages first, reads source to confirm or fill a gap, cites both, and labels inference and unknowns. It runs inline, so you can ask follow-ups.

Four modes

/archlens:learn how are duplicate orders prevented?
Answers from the handbook first, with source links, in at most 150 words. Then one real trace or snippet.
/archlens:learn tour
Walks the reading path one stop per turn and waits before the next.
/archlens:learn quiz data flow
One question at a time about real behavior here. Grades each answer against evidence. Stops after five with a score and the pages to reread.
/archlens:learn changes
Explains what the current branch changes, which flow or data it affects, and why it matters.

While a long task runs, Claude Code’s /btw can answer from the page map already in context. In the real-project trial (A-302), one tutor answer took 45 seconds and $0.32.

Detail 6: a quiz on the order example

Illustration · scripted in this page, not a live model

you/archlens:learn quiz data flow

archlens

Question 1 of 3

A caller submits request key request-1 twice, both times with SKU BOOK and quantity 2. What does the second call return?

  1. A new order ID
  2. The same order ID as the first call
  3. It raises RequestConflict
  4. It raises ValueError
Show the graded answer

B. The insert uses ON CONFLICT(request_key) DO NOTHING, then reads the row for that key. The data matches, so the function returns the existing ID. See runtime/submit-order.md, rule 5.

I-601Install

Three lines in Claude Code. One line everywhere else.

No API key, Node installation, or server is required for the Claude Code plugin. Python 3.9+ on PATH as python3 enables the hooks and checks (the macOS system Python works); the commands still run without it. Your agent’s normal subscription or API usage still applies.

Claude Code plugin

Run these inside Claude Code. Choose user scope when asked, so Archlens works in every project.

/plugin marketplace add tushar-mahalya/archlens
/plugin install archlens@archlens
/archlens:setup

That is all. If the project already has architecture docs, setup adopts them where they live (/archlens:setup adopt, the default then). Otherwise, or with /archlens:setup new, it writes a handbook under docs/architecture/. It records a freshness baseline. From then on the docs update once per commit, in the same commit as the code. You add nothing to CLAUDE.md.

From a terminal, the install equivalent is claude plugin marketplace add tushar-mahalya/archlens then claude plugin install archlens@archlens --scope user. Choose either the native plugin or the portable skill for Claude Code, not both.

Codex, Cursor, Copilot, Gemini CLI, and others

The portable Agent Skill installs with skills.sh. In the project directory, with Node.js 22.20+ and Git:

npx skills@1.7.6 add tushar-mahalya/archlens --skill archlens --agent codex --copy --yes

Replace codex with cursor, github-copilot, gemini-cli, opencode, roo, or devin, or add --global for a user-level installation. Then ask your agent:

Use the Archlens skill to set up architecture documentation for this project.

Setup offers to write the page map into AGENTS.md, which these agents read every session. To write it yourself, set { "contextFile": "AGENTS.md" } in .archlens.json and run:

python <skill-dir>/scripts/archlens.py context --root . --write

Every sync refreshes the block. The written block has no stale flags, because freshness changes between commits; it tells the agent to run the status check before relying on a page, and to update stale pages before it commits code, in the same commit. Portable hosts do not necessarily provide Claude’s isolated, manual-only behavior. The skills CLI has its own telemetry; set DISABLE_TELEMETRY=1 to opt out. See installation for adapters and caveats.

Git hooks with pre-commit

Works with any editor or agent. Add Archlens to .pre-commit-config.yaml:

repos:
  - repo: https://github.com/tushar-mahalya/archlens
    rev: v0.3.0
    hooks:
      - id: archlens-check   # links, anchors, diagrams, stale references
      - id: archlens-stale   # on pre-push: fail while cited code changed

Install both stages:

pre-commit install --hook-type pre-commit --hook-type pre-push

archlens-check runs on every commit and fails on structural errors. archlens-stale runs on pre-push and fails while covered source changed after the last sync. rev: v0.3.0 pins the last release; items marked N on this site are not in it yet.

CI check on pull requests

This GitHub Actions job fails a pull request whose code changes leave pages stale. Copy archlens.py into your repository first, for example as tools/archlens.py, or check out the Archlens repository in the job.

name: architecture-docs
on: pull_request
permissions:
  contents: read
jobs:
  freshness:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with:
          python-version: "3.13"
      - run: python tools/archlens.py check --root . --summary
      - run: python tools/archlens.py status --root . --fail-on-stale

To rewrite stale pages in CI, run your coding agent’s headless mode with the Archlens update operation and open a pull request for human review. Never let an automated job mark pages reviewed or decisions accepted.

Trust and limits

  • A stale flag means “check this page”. It does not prove the prose is wrong.
  • Code shows what happens, not why a person chose it. Decisions stay proposed until a human accepts them.
  • Python and C-family files get symbol-level fingerprints. The C-family brace reader is a heuristic, not a parser. Other files use normalized line-range text.
  • The benchmark covers one small repository. The real-project trial (A-302) is one trial on one larger repository. Coding-task results are not measured yet.
  • Archlens has no server, no telemetry, and no network calls. Your agent’s provider policy still applies.
  • The writing style is STE-inspired, not certified ASD-STE100.

Q-701Questions

Questions people ask before they install.

Short answers. Each one points to the sheet with the details.

What is Archlens?

Archlens is a Claude Code plugin and a portable Agent Skill that keeps architecture docs in sync with your code. It writes a small, source-linked handbook or adopts the docs you already have. A local script flags pages whose cited code changed, and an isolated task updates them, by default in the same commit as the code. It also gives your coding agent a page map of the project in a few hundred tokens.

How is Archlens different from DeepWiki or OpenWiki?

DeepWiki regenerates a hosted wiki and serves it through the web and MCP. OpenWiki ties claims to line-range evidence and updates through a manual run or a scheduled CI pull request. Archlens keeps the docs in your repository, detects drift on the exact functions and line ranges each page cites with a local script and no model, and updates only the stale pages. Its always-loaded map has a byte budget that CI enforces. The field survey (S-401) compares more tools; vendor claims there are as published.

Which coding agents does it support?

Claude Code gets the native plugin with hooks. Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Roo, Devin, and other agents get the portable Agent Skill through skills.sh, and any agent that reads AGENTS.md can get the page map. The pre-commit hooks and the CI check work with any editor or agent.

Does it need a server, an API key, or send telemetry?

No. Archlens has no server, no telemetry, and makes no network calls. The Claude Code plugin needs no API key or Node installation; Python 3.9+ enables the hooks and checks. Your agent’s normal subscription or API usage and provider policy still apply. The skills CLI that installs the portable skill has its own telemetry; set DISABLE_TELEMETRY=1 to opt out.

What does keeping docs current cost?

Detecting drift costs no model tokens, because it is a local script. By default, prose is rewritten once per commit that leaves pages stale. In the real-project trial (A-302), an update after two real code changes took 93 seconds and $0.40 on Opus, and a whole change, test, and commit task with its docs took 4.6 minutes and $1.25. That is one trial on one repository.

Does it work with the docs I already have?

Yes. In a project with architecture docs, /archlens:setup adopt, the default then, maps them where they live, fixes statements the code contradicts with minimal edits, adds pages only for real gaps, and uses your decision-record folder and numbering. Mapped docs get the same checks and freshness tracking as new pages.

How do I install it?

In Claude Code, run /plugin marketplace add tushar-mahalya/archlens, then /plugin install archlens@archlens, then /archlens:setup. For other agents, run npx skills@1.7.6 add tushar-mahalya/archlens --skill archlens --agent codex --copy --yes in the project, and replace codex with your agent.

Free, MIT-licensed, and built in the open.

If Archlens keeps your docs honest, star the repository so other developers can find it. Bug reports and ideas are welcome.