docs: CLAUDE.md is a pointer to AGENTS.md - #283
Conversation
objectos had no CLAUDE.md, so Claude Code loaded no instructions at all
until a reader found AGENTS.md on their own. Add the pointer in the shape
the program fixes: it says where the truth lives and that the reader must
read it, and carries no rule, no hook roster and no digest of its own.
Nothing in the repository reads CLAUDE.md, so no gate adapts. AGENTS.md
already addresses every agent ("Claude Code, Codex, Cursor, etc."), which
is why the pointer keeps one instruction set rather than opening a second.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YKEjmbYNvYWJvWGSWx26zK
维护者速读改了什么 —— objectos 仓库根新增一个 5 行的 为什么改 —— 你 09-09 的指示「claude.md 是不是直接让他阅读 agents.md 即可,没必要维护两套。所有仓库都有类似的问题」,五仓计划(objectstack#17161)的第四仓。objectos 与其它仓相反:它原本根本没有 风险与代价(含回滚) —— 接近零:纯新增;仓内没有任何脚本或 workflow 读 席位意见 —— 通过。本席对照 diff 自读:5 行,形状与 objectstack/objectui 已落地的指针同构,措辞用 你要做的 —— 一个动作:人工合并本 draft PR。 skills 席,session Generated by Claude Code |
Fixes objectstack-ai/objectstack#17164
Program: objectstack-ai/objectstack#17161 —
CLAUDE.mdbecomes a pointer toAGENTS.mdin every repository, so there is one instruction set per repo, maintained once. objectos is the fourth of five repos; objectstack, hotcrm and objectui have landed.What this adds
objectos had no
CLAUDE.mdat all, so Claude Code loaded no instructions until a reader foundAGENTS.mdunaided. This adds the pointer in the program's fixed shape: it says where the truth lives and that the reader must read it, and carries no rule, no hook roster and no digest.CLAUDE.md, verbatim and complete — 5 lines:The second sentence is kept rather than dropped to objectui's three-line shape because
AGENTS.md:3already addresses every agent by name — "Guidance for AI agents (Claude Code, Codex, Cursor, etc.) working in this repository". A file that did not exist until this PR is exactly where a future session would start appending Claude-specific rules, and one line closes that. Wording followsAGENTS.md's own voice: "this repository", and ⛔ as it uses it.Measurements
Both re-verified in the worktree at this branch's tip. Neither is carried from the dispatch.
1. There was no prior
CLAUDE.mdAt the branch point
6505ac10, noCLAUDE.mdexisted anywhere in the tracked tree — not at the root, not in a subdirectory:So there was no pair to reduce and nothing to delete: the deliverable is the pointer's creation.
AGENTS.mdis 140 lines and is the repo's only instruction file. A.claude/directory does exist, holdinglaunch.jsononly — a run-configuration file, not instructions.After this PR:
CLAUDE.mdis 5 lines,AGENTS.mdis unchanged at 140 lines.2. Nothing reads
CLAUDE.md, so no gate adaptsThe program rule is that a gate reading
CLAUDE.mdas an instruction surface adapts to the pointer form in the same PR. No such gate exists here, measured two ways.Narrow population, the dispatch's own: every tracked
*.md,*.yml,*.yaml,*.mjs,*.js,*.ts,*.tsx,*.json, node_modules excluded — zero files nameCLAUDE.md. Broad population, every tracked file at any extension, case-insensitive onclaude— the only hits are prose about "Claude Code",claude.ailinks in docs content, and the.claude/directory path. Not one names the filenameCLAUDE.md.Positive control, same command, same population,
AGENTS.mdinstead: 30 tracked files name it,AGENTS.mditself among them. The grep can find an instruction filename when one is referenced; it found no reference to this one.At this branch's tip the reader-grep hits exactly one file —
CLAUDE.md, matching its own heading. Still zero readers.3. The new file is in no build input — measured, not read off the config
turbo.jsondeclaresbuild.inputsas["$TURBO_DEFAULT$", "$TURBO_ROOT$/content/docs/**"], andAGENTS.mdwarns in its own words that a wronginputsglob is not an error — "turbo exits 0, matches nothing". So the claim was measured rather than inferred, with the file present and then removed:CLAUDE.mdbuild1d6009513037543d1d6009513037543dtype-check59aafae9a3d555c859aafae9a3d555c8Identical. A hash that never moves is indistinguishable from a probe that cannot move, so the control
AGENTS.mdprescribes was run too — mutate a real input, then revert:buildtype-check1d6009513037543d59aafae9a3d555c8content/docs/build/agents.mdxmutatedfeff3b9d25464029d19d1f1257870c1b1d6009513037543d59aafae9a3d555c8The probe moves on a real input and comes back, so the unchanged reading above is a measurement. Both mutation legs restored via
git checkout HEAD -- path, proven by the restored blob matching the HEAD blob and bygit diff HEADbeing empty; no probe file is left behind.Consequence: the docs site this PR builds is byte-identical in inputs to what
mainbuilds, and every gate downstream of the build reads the same artifacts it reads onmain.What CI runs on this PR
ci.ymldeclares nopaths:filter, so both its PR jobs run on a root-level.mdaddition.translations.ymldoes filter —content/docs/**,apps/docs/lib/i18n.ts,.github/scripts/**,.github/workflows/translations.yml— and a rootCLAUDE.mdmatches none of them, so the Translations workflow is not triggered at all. Independently of the trigger,check-translation-ownership.mjs:53scopes its population to paths thatstartsWith('content/docs/')and carry a locale suffix, which this file does not.deploy-docsispushtomainonly.Every step of both PR jobs was run in the worktree at this tip, except the one with no local equivalent:
node-floor/ Self-testnode-floor/ Checkbuild/pnpm install --frozen-lockfilebuild/ Half-state sweeper self-testbuild/ Generated zh-Hant is currentbuild/turbo run type-check --continuebuild/turbo run buildbuild/ Locale surfacebuild/turbo run testbuild/ Package the Worker (--skipNextBuild)build/ Worker bundle fits the size budgetbuild/ smoke-check a local preview/docs,/zh-Hans/docs,/llms.txt,/sitemap.xmlanswered 200,/307build/ Upload the Worker bundleactions/upload-artifactstep with no local equivalent; left to CIObserved on this PR after the push: the head carries exactly two check runs —
Node floor(completed, success) andbuild(in progress at the time of writing). No Translations check appears, which confirms the path-filter reading above from the platform rather than from the file.No changeset: objectos has no
.changeset/directory and no changeset tooling, so neither a changeset nor askip-changesetlabel exists in this repo to add.Acceptance notes
Noted, not filed — an observation, not a defect:
ci.ymlcarries nopaths:filter, so a root-level documentation-only PR pays the fullbuildjob: install, Next build, Worker packaging, dry-run weigh-in and a preview boot. The measurement above shows the turbo hash does not move for such a change, so the compile itself is cache-eligible, but the packaging, weigh-in and preview steps are not turbo tasks and re-run unconditionally. This is a runner-cost observation with no correctness consequence, and the absence of filters is also what guarantees no docs change slips past the build — worth weighing rather than reflexively fixing. Reader who meets it: whoever next edits objectos.github/workflows/ci.yml.维护者速读(草稿)
改了什么 — 给 objectos 仓库根新增一个 5 行的
CLAUDE.md,内容只有一句话:真正的规则在AGENTS.md,请先读完它。没有删除、修改任何现有文件,AGENTS.md一个字节没动。为什么改 — 你 09-09 的指示:「claude.md 是不是直接让他阅读 agents.md 即可,没必要维护两套。所有仓库都有类似的问题」。objectos 的情况和其他仓库相反:它压根没有
CLAUDE.md,而 Claude Code 只自动加载CLAUDE.md。也就是说,在这个仓库里开一个 session,agent 默认读不到任何规则——140 行的AGENTS.md全靠它自己碰巧发现。这个指针把这条路补上,同时从第一天就把「只维护一套」写进文件里,免得以后有人往这里加规则。这是五个仓库计划里的第四个,前三个(objectstack、hotcrm、objectui)已合并。风险与代价(含回滚) — 风险接近于零:新增文件,无删除,仓库里没有任何脚本或 workflow 读
CLAUDE.md(已实测,并带正向对照)。已实测该文件不进入任何 turbo 构建输入,构建产物与main完全一致。已在本地跑完 CI 两个 PR job 的每一个步骤(唯一没跑的是 CI 专属的产物上传),全部退出 0。已知的代价写在计划卡上,不是本 PR 引入的:session 若跳过这个指针,在 hook 触发前就没有规则可依——hook 是这个方案的地板。回滚 = 删掉这一个文件,git revert一次即可,没有任何东西依赖它。席位意见 — (留空,待席位定稿)
你要做的 — 一个动作:人工合并本 draft PR。
Generated by Claude Code