museum-documentation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMuseum Documentation
博物馆式文档
Documentation as hospitality. Code as curated collection.
The art of transforming technical systems into welcoming guided tours. Museum documentation positions the writer as a guide walking alongside readers through "why" questions before diving into implementation specifics.
This is Grove's elegant documentation style—meant for Wanderers of any experience level who want to understand the technologies, patterns, and decisions that make Grove what it is.
文档即待客之道,代码即精心策展的藏品。
将技术系统转化为亲切导览的艺术。博物馆式文档将作者定位为导览者,先陪读者探讨「为什么」的问题,再深入实现细节。
这是Grove的优雅文档风格——适用于所有想要了解Grove背后技术、模式和决策逻辑的Wanderer,无论其经验水平如何。
When to Activate
适用场景
- Creating documentation meant to be read by Wanderers, not developers
- Writing knowledge base articles that explain how systems work
- Documenting a codebase, feature, or system for curious visitors
- Creating "how it works" content for the help center
- Writing technical content that should feel inviting, not intimidating
- Building exhibits for future knowledge base sections
- Onboarding documentation that walks through architecture
Not for:
- API references (use grove-documentation)
- Technical specs (use grove-spec-writing)
- Quick-reference guides
- 为Wanderer(而非开发者)编写的文档
- 解释系统工作原理的知识库文章
- 为好奇的访客记录代码库、功能或系统
- 为帮助中心创作「工作原理」类内容
- 编写亲切而非生硬的技术内容
- 为未来的知识库板块打造「展品」
- 讲解架构的入职文档
不适用场景:
- API参考文档(请使用grove-documentation)
- 技术规格文档(请使用grove-spec-writing)
- 快速参考指南
Core Philosophy
核心理念
Documentation should function as hospitality.
When readers enter a codebase or system, they're visitors unfamiliar with its architecture and design decisions. Museum-style documentation positions the writer as a guide rather than a reference compiler, walking alongside readers through "why" questions before diving into implementation.
文档应发挥待客之道的作用。
当读者接触代码库或系统时,他们是不熟悉其架构和设计决策的访客。博物馆式文档将作者定位为导览者而非参考资料编纂者,先陪读者探讨「为什么」的问题,再深入实现细节。
The Museum Metaphor
博物馆隐喻
🌲 Welcome 🌲
╭─────────────────────╮
│ │
│ ╭─────────────╮ │
│ │ EXHIBIT A │ │
│ │ │ │
│ │ How Login │ │
│ │ Works │ │
│ │ │ │
│ ╰─────────────╯ │
│ │ │
│ ═════╪═════ │
│ │ │
│ ╭─────────────╮ │
│ │ EXHIBIT B │ │
│ ╰─────────────╯ │
│ │
╰─────────────────────╯
Walk through. Take your time.
Every exhibit tells a story.A museum doesn't hand you a catalog and wish you luck. It guides you through a curated experience, placing context before complexity, stories before specifications.
🌲 Welcome 🌲
╭─────────────────────╮
│ │
│ ╭─────────────╮ │
│ │ EXHIBIT A │ │
│ │ │ │
│ │ How Login │ │
│ │ Works │ │
│ │ │ │
│ ╰─────────────╯ │
│ │ │
│ ═════╪═════ │
│ │ │
│ ╭─────────────╮ │
│ │ EXHIBIT B │ │
│ ╰─────────────╯ │
│ │
╰─────────────────────╯
Walk through. Take your time.
Every exhibit tells a story.博物馆不会只给你一本目录就让你自行探索,它会引导你完成一段精心策划的体验,先讲背景再讲复杂细节,先讲故事再讲规格说明。
Key Principles
关键原则
Orient Before Explaining
先定位,再解释
Start exhibits by establishing context. Before showing code or architecture, tell readers:
- What they're looking at
- Why it exists
- Who benefits from it
Instead of:
The TokenRefreshMap stores active refresh operations keyed by user ID.
Write:
When someone's login expires, we need to refresh their credentials without logging them out. This map coordinates that process—preventing duplicate refresh attempts when multiple tabs are open.
展品开头先建立上下文。在展示代码或架构之前,告诉读者:
- 他们正在看什么
- 它存在的原因
- 谁能从中受益
反面示例:
TokenRefreshMap按用户ID存储正在进行的刷新操作。
正面示例:
当用户登录过期时,我们需要在不登出的情况下刷新其凭据。这个Map用于协调该流程——防止在多标签页打开时重复发起刷新请求。
Explain Reasoning Over Facts
解释原因,而非陈述事实
Code shows what. Documentation explains why.
Rather than stating that a Map stores token refresh operations, describe the coordination problem it solves. Connect the abstraction to the experience it creates.
代码展示「是什么」,文档解释「为什么」。
不要只说Map存储令牌刷新操作,而要描述它解决的协调问题,将抽象概念与它带来的用户体验联系起来。
Use Accessible Metaphors
使用易懂的隐喻
Connect technical concepts to familiar experiences:
| Technical Concept | Museum Metaphor |
|---|---|
| Database | A filing cabinet with organized drawers |
| Cache | A quick-lookup shelf by the door |
| Middleware | A security checkpoint you pass through |
| Queue | A line where requests wait their turn |
| Worker | A helpful assistant handling tasks in the background |
| Webhook | A doorbell that rings when something happens |
将技术概念与熟悉的体验联系起来:
| 技术概念 | 博物馆隐喻 |
|---|---|
| Database | 带有分类抽屉的文件柜 |
| Cache | 门口的快速查询货架 |
| Middleware | 你必须经过的安检口 |
| Queue | 请求排队等待的队伍 |
| Worker | 后台处理任务的贴心助手 |
| Webhook | 发生事件时响起的门铃 |
Show Real Code, Then Analyze
展示真实代码,再进行分析
Present actual code snippets followed by clear explanation of their significance:
typescript
const pending = this.refreshInProgress.get(userId);
if (pending) return pending;If a refresh is already happening for this person, we wait for that one instead of starting another. One kitchen, one cook.
先展示实际代码片段,再清晰解释其重要性:
typescript
const pending = this.refreshInProgress.get(userId);
if (pending) return pending;如果该用户的刷新操作已在进行中,我们会等待其完成,而不是启动新的操作。就像一个厨房只需要一个厨师。
Structural Framework
结构框架
Museum exhibits follow consistent anatomy:
博物馆展品遵循统一的结构:
1. Title with Tagline
1. 带标语的标题
markdown
undefinedmarkdown
undefinedThe Authentication Exhibit
认证展品
Where login happens. Where trust begins.
undefined登录发生之地,信任开启之处。
undefined2. "What You're Looking At" Section
2. 「你正在看什么」板块
Orient the reader immediately:
markdown
undefined立即为读者定位:
markdown
undefinedWhat You're Looking At
你正在看什么
This is where login happens. When someone proves they own an email
address, this code decides what they can access and how long that
access lasts.
You'll see OAuth flows, session management, and token refresh logic.
Nothing scary—just careful choreography.
undefined这里是登录功能的实现之处。当用户证明自己拥有某个邮箱地址时,这段代码会决定他们可以访问什么内容,以及访问权限的有效期。
你会看到OAuth流程、会话管理和令牌刷新逻辑。没什么可怕的——只是精心编排的流程而已。
undefined3. Organized Tour Structure
3. 结构化的导览流程
Use galleries, parts, or sections to organize the journey:
markdown
undefined使用展厅、部分或章节来组织导览:
markdown
undefinedThe Tour
导览路线
Gallery 1: The Front Door
展厅1:前门
How visitors arrive and prove who they are.
访客如何抵达并证明身份。
Gallery 2: The Memory Room
展厅2:记忆室
How we remember who's logged in.
我们如何记住已登录的用户。
Gallery 3: The Renewal Office
展厅3:续期办公室
How sessions stay fresh without interrupting work.
undefined会话如何在不打断工作的情况下保持有效。
undefined4. "Patterns Worth Stealing"
4. 「值得借鉴的模式」
Highlight transferable lessons:
markdown
undefined强调可迁移的经验:
markdown
undefinedPatterns Worth Stealing
值得借鉴的模式
The "already in progress" check. Before starting an expensive
operation, check if it's already running. Simple, but easy to forget.
Centralized error handling. All auth failures flow through one
function. One place to fix, one place to log.
undefined「已在进行中」检查:在启动昂贵的操作之前,先检查它是否已在运行。方法简单,但很容易被忽略。
集中式错误处理:所有认证失败都通过同一个函数处理。一处修复,一处记录。
undefined5. "Lessons Learned"
5. 「经验教训」
Offer honest reflection:
markdown
undefined提供真诚的反思:
markdown
undefinedLessons Learned
经验教训
We tried stateless JWTs first. Simpler, they said. Scalable, they
promised. But logout was impossible—tokens couldn't be revoked.
Session-based auth is older, but it works. Sometimes boring is right.
undefined我们最初尝试了无状态JWT。他们说更简单,更具可扩展性。但登出功能无法实现——令牌无法被撤销。
基于会话的认证技术更古老,但切实有效。有时候,保守的选择才是正确的。
undefined6. "Continue Your Tour"
6. 「继续你的导览」
Link to related exhibits:
markdown
undefined链接到相关展品:
markdown
undefinedContinue Your Tour
继续你的导览
- The Database Exhibit — Where sessions are stored
- The API Exhibit — How protected routes check access
- The Security Exhibit — Rate limiting and protection
undefined- 数据库展品 — 会话存储之地
- API展品 — 受保护路由如何检查访问权限
- 安全展品 — 速率限制与防护
undefined7. Meaningful Closing Signature
7. 有意义的结尾署名
markdown
---
*— Autumn, January 2026*Or a poetic one-liner:
markdown
---
*Trust is built one verified request at a time.*markdown
---
*—— Autumn,2026年1月*或者一句富有诗意的话:
markdown
---
*信任建立在每一次经过验证的请求之上。*Visual Elements
视觉元素
ASCII Flow Diagrams
ASCII流程图
Show processes and relationships:
Visitor Grove Google
│ │ │
│ "Log me in" │ │
│ ───────────────────────>│ │
│ │ "Who is this?" │
│ │ ────────────────────────>│
│ │ │
│ │ "It's autumn@..." │
│ │ <────────────────────────│
│ │ │
│ "Welcome back" │ │
│ <───────────────────────│ │
│ │ │展示流程和关系:
Visitor Grove Google
│ │ │
│ "Log me in" │ │
│ ───────────────────────>│ │
│ │ "Who is this?" │
│ │ ────────────────────────>│
│ │ │
│ │ "It's autumn@..." │
│ │ <────────────────────────│
│ │ │
│ "Welcome back" │ │
│ <───────────────────────│ │
│ │ │Tables for Quick Reference
快速参考表格
markdown
| File | What It Does | Why It Matters |
|------|--------------|----------------|
| `auth.ts` | Handles OAuth flow | The front door |
| `session.ts` | Manages login state | The memory |
| `middleware.ts` | Checks every request | The bouncer |markdown
| 文件 | 功能 | 重要性 |
|------|--------------|----------------|
| `auth.ts` | 处理OAuth流程 | 前门 |
| `session.ts` | 管理登录状态 | 记忆核心 |
| `middleware.ts` | 检查每一个请求 | 门卫 |Code Blocks with Context
带上下文的代码块
Never show code in isolation. Always explain before or after:
typescript
// Every request passes through this checkpoint
export async function authGuard(request: Request): Promise<Response | null> {
const session = await getSession(request);
if (!session) {
return redirect('/login');
}
return null; // Continue to the page
}If you're not logged in, you go to login. If you are, you continue. Simple checkpoint logic.
永远不要孤立展示代码。始终在前后附上解释:
typescript
// 每一个请求都要经过这个检查点
export async function authGuard(request: Request): Promise<Response | null> {
const session = await getSession(request);
if (!session) {
return redirect('/login');
}
return null; // 继续访问页面
}如果未登录,你会被转到登录页;如果已登录,你可以继续访问。简单的检查点逻辑。
Voice and Tone
语气与语调
Do
建议做法
- Write conversationally using "you" and "we" naturally
- Acknowledge imperfections ("We tried X first. It didn't work.")
- Include personal touches ("This took three attempts to get right.")
- Use short paragraphs (2-4 sentences)
- Vary sentence rhythm
- 使用自然的「你」和「我们」进行对话式写作
- 承认不完美之处(「我们最初尝试了X,但行不通。」)
- 加入个人化细节(「这个功能我们尝试了三次才做对。」)
- 使用短段落(2-4句话)
- 变换句子节奏
Avoid
避免做法
- Em-dashes (use periods, commas, or parentheses)
- Corporate jargon ("robust," "seamless," "leverage")
- Heavy transitions ("Furthermore," "Moreover," "Additionally")
- Passive voice when active is clearer
- Hedging language ("This may potentially help...")
- 使用破折号(改用句号、逗号或括号)
- 企业行话(「健壮的」、「无缝的」、「利用」)
- 生硬的过渡词(「此外」、「而且」、「另外」)
- 在主动语态更清晰时使用被动语态
- 含糊的措辞(「这可能潜在地帮助...」)
The Distinction
对比示例
Generic (avoid):
This module provides robust functionality for handling authentication flows in a seamless manner, leveraging industry-standard OAuth protocols.
Museum style (use):
This is where login happens. When someone proves they own an email address, this code decides what they can access.
通用风格(避免):
该模块提供了健壮的功能,可利用行业标准的OAuth协议无缝处理认证流程。
博物馆风格(推荐):
这里是登录功能的实现之处。当用户证明自己拥有某个邮箱地址时,这段代码会决定他们可以访问什么内容。
Organization Patterns
组织模式
Full Codebase: MUSEUM.md
完整代码库:MUSEUM.md
For documenting an entire codebase, create a central that serves as the entrance:
MUSEUM.mdmarkdown
undefined要记录整个代码库,创建一个中心文件作为入口:
MUSEUM.mdmarkdown
undefinedWelcome to the Grove Museum
欢迎来到Grove博物馆
A guided tour of how this forest grows.
一场关于这片「森林」如何生长的导览。
The Wings
展区
- The Architecture Wing — The big picture
- The Authentication Exhibit — Trust and identity
- The Database Galleries — Where data lives
undefined- 建筑展区 — 全景概览
- 认证展品 — 信任与身份
- 数据库展厅 — 数据存储之地
undefinedSingle Directory: EXHIBIT.md
单个目录:EXHIBIT.md
For a single complex feature or directory:
markdown
undefined对于单个复杂功能或目录:
markdown
undefinedThe Editor Exhibit
编辑器展品
Where words become posts.
This directory contains everything that powers the writing experience...
undefined文字变为帖子的地方。
这个目录包含了支撑写作体验的所有内容...
undefinedComplex Features: Gallery Structure
复杂功能:展厅结构
For multi-part systems, use galleries:
markdown
undefined对于多部分系统,使用展厅结构:
markdown
undefinedGallery 1: Data Layer
展厅1:数据层
How posts are stored and retrieved.
帖子如何存储和检索。
Gallery 2: API Endpoints
展厅2:API端点
The doors visitors knock on.
访客访问的入口。
Gallery 3: The Editor Component
展厅3:编辑器组件
Where the magic happens in the browser.
浏览器中的魔法发生之地。
Gallery 4: Security Considerations
展厅4:安全考量
Keeping things safe.
---确保一切安全。
---Validation Checklist
验证清单
Before finalizing any museum documentation:
在完成博物馆式文档之前,请检查以下内容:
Structure
结构
- Title includes tagline
- "What You're Looking At" orients the reader
- Organized into logical galleries/sections
- "Patterns Worth Stealing" highlights transferable lessons
- "Continue Your Tour" links to related content
- Meaningful closing (signature or poetic line)
- 标题包含标语
- 「你正在看什么」板块为读者定位
- 内容组织为逻辑清晰的展厅/章节
- 「值得借鉴的模式」板块突出可迁移经验
- 「继续你的导览」板块链接到相关内容
- 有意义的结尾(署名或诗意语句)
Visual Variety
视觉多样性
- At least one ASCII diagram or flow
- Tables where comparison helps
- Code blocks with explanatory context
- No walls of text longer than 4-5 paragraphs
- 至少包含一个ASCII图或流程图
- 在需要对比的地方使用表格
- 代码块带有解释性上下文
- 没有超过4-5段的大段文字
Voice (refer to grove-documentation)
语气(参考grove-documentation)
- No em-dashes
- No corporate jargon
- Direct tone explaining motivations
- Acknowledged imperfections where honest
- Clear connections between system parts
- 没有使用破折号
- 没有企业行话
- 直接解释动机的语气
- 坦诚承认不完美之处
- 清晰连接系统各部分
Reader Experience
读者体验
- A newcomer could follow the tour
- "Why" is answered before "how"
- Technical details are contextualized
- The path feels logical and navigable
- 新手可以跟随导览路线
- 先回答「为什么」,再回答「怎么做」
- 技术细节都有上下文支撑
- 路线逻辑清晰、易于导航
Integration with Other Skills
与其他技能的集成
Before Writing
写作前
- walking-through-the-grove — If the exhibit needs a name
- grove-documentation — Review voice guidelines, especially the "avoid" lists
- walking-through-the-grove — 如果展品需要命名
- grove-documentation — 查看语气指南,尤其是「避免」列表
While Writing
写作中
- grove-spec-writing — Borrow ASCII art techniques for diagrams
- grove-documentation — Check terminology (Wanderer, Rooted, etc.)
- GroveTerm components — When exhibits include Grove terminology in UI, use ,
GroveTerm, orGroveSwapfromGroveTextinstead of hardcoding terms. New visitors see standard terms by default; Grove Mode users see the nature-themed vocabulary. Use@autumnsgrove/groveengine/uisyntax in markdown content for auto-transformation via the rehype-groveterm plugin.[[term]]
- grove-spec-writing — 借鉴ASCII绘图技术制作图表
- grove-documentation — 检查术语(Wanderer、Rooted等)
- GroveTerm components — 当展品在UI中包含Grove术语时,使用中的
@autumnsgrove/groveengine/ui、GroveTerm或GroveSwap,而非硬编码术语。新访客默认看到标准术语;Grove模式用户看到自然主题的词汇。在Markdown内容中使用GroveText语法,通过rehype-groveterm插件自动转换。[[term]]
After Writing
写作后
- Read as a newcomer — Traverse the documentation as if you've never seen it
- Does the path feel logical? Would you want to explore further?
- 以新手视角阅读 — 像从未见过这份文档一样浏览它
- 路线逻辑清晰吗?你会想要进一步探索吗?
Example: A Complete Exhibit
示例:完整展品
markdown
undefinedmarkdown
undefinedThe Session Exhibit
会话展品
How Grove remembers who you are.
Grove如何记住你的身份。
What You're Looking At
你正在看什么
When you log in, Grove needs to remember you. Not forever—just long
enough for your visit. This exhibit shows how that memory works.
You'll see cookies, database tables, and the careful dance of
"who are you?" that happens with every page load.
当你登录时,Grove需要记住你。不是永远——只是在你访问期间。这个展品展示了这种「记忆」的工作原理。
你会看到Cookie、数据库表,以及每次页面加载时发生的「你是谁?」的精心互动。
Gallery 1: The Cookie Jar
展厅1:饼干罐
A session starts with a cookie. Not the chocolate chip kind—a small
piece of text your browser holds onto.
typescript
const SESSION_COOKIE = 'grove_session';
const SESSION_DURATION = 7 * 24 * 60 * 60 * 1000; // 7 daysSeven days. Long enough to be convenient, short enough to stay secure.
When you log in, we generate a random ID and store it in this cookie.
The ID itself means nothing—it's just a key to look you up.
会话从Cookie开始。不是巧克力饼干那种——是浏览器保存的一小段文本。
typescript
const SESSION_COOKIE = 'grove_session';
const SESSION_DURATION = 7 * 24 * 60 * 60 * 1000; // 7天7天。足够方便,又足够安全。
当你登录时,我们会生成一个随机ID并存储在这个Cookie中。这个ID本身没有意义——它只是用来查找你的密钥。
Gallery 2: The Memory Book
展厅2:记忆手册
The actual session data lives in the database:
| Column | What It Holds |
|---|---|
| The random key from the cookie |
| Who this session belongs to |
| When you logged in |
| When this session ends |
Every time you load a page, we look up your cookie's ID in this table.
If we find it (and it hasn't expired), you're still logged in.
实际的会话数据存储在数据库中:
| 列名 | 存储内容 |
|---|---|
| Cookie中的随机密钥 |
| 该会话所属的用户 |
| 登录时间 |
| 会话过期时间 |
每次你加载页面时,我们都会在这个表中查找你的Cookie ID。如果找到且未过期,你就保持登录状态。
Gallery 3: The Refresh Dance
展厅3:续期之舞
Sessions expire. But logging in every week is annoying.
So we do a quiet refresh: when your session is more than halfway
through its life, we extend it. You never notice. You just stay
logged in while you're active.
typescript
if (session.expiresAt < Date.now() + SESSION_DURATION / 2) {
await extendSession(session.id);
}Active visitors stay. Abandoned sessions expire.
会话会过期。但每周都登录很烦人。
所以我们会进行静默续期:当会话生命周期过半时,我们会延长它的有效期。你不会注意到,只是在活跃期间保持登录状态。
typescript
if (session.expiresAt < Date.now() + SESSION_DURATION / 2) {
await extendSession(session.id);
}活跃的访客会保持登录,闲置的会话会过期。
Patterns Worth Stealing
值得借鉴的模式
The "halfway refresh" pattern. Don't wait until expiration to
extend sessions. Extend them while the visitor is active.
Random IDs over sequential. Session IDs should be unpredictable.
Never use auto-incrementing numbers for security tokens.
「半周期续期」模式:不要等到过期才续期会话,在访客活跃时就延长它的有效期。
随机ID而非顺序ID:会话ID应该不可预测。永远不要使用自增数字作为安全令牌。
Lessons Learned
经验教训
We used to store session data in the cookie itself (JWTs). Simpler,
we thought. But then we couldn't revoke sessions—if someone's token
leaked, we had no way to invalidate it.
Database sessions are older technology. Sometimes older is wiser.
我们曾经在Cookie中存储会话数据(JWT)。我们认为这样更简单。但后来我们无法撤销会话——如果有人的令牌泄露,我们没有办法让它失效。
基于数据库的会话是更古老的技术。有时候,古老的技术更可靠。
Continue Your Tour
继续你的导览
- The Authentication Exhibit — How login happens
- The Security Exhibit — Rate limiting and protection
— Autumn, January 2026
---- 认证展品 — 登录如何实现
- 安全展品 — 速率限制与防护
—— Autumn,2026年1月
---The Underlying Purpose
底层目标
Museum documentation respects readers' time and intelligence while acknowledging that code is knowledge deserving careful stewardship.
Wanderers who read these exhibits should leave understanding not just what Grove does, but why it does it that way. They should feel like they've been welcomed into the workshop, not handed a manual.
Every codebase has stories. Museum documentation tells them.
博物馆式文档尊重读者的时间和智慧,同时承认代码是值得精心管理的知识。
阅读这些展品的Wanderer不仅应该了解Grove做什么,还应该了解它为什么这样做。他们应该感觉自己是被邀请进入工坊,而不是被塞了一本手册。
每个代码库都有故事。博物馆式文档讲述这些故事。