Repository navigation
finding(docs): docs/ARCHITECTURE.md's Next.js example has no 'use client' — app/layout.tsx and app/[object]/page.tsx are App Router server components as written and fail at runtime for a reader who copies them #8161
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdocumentationImprovements or additions to documentationImprovements or additions to documentationdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repoobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repoand removed
on Sep 7, 2026 分诊 · 准入通过 (a) 类
标签:
domain:devx·documentation·bug·pm:queue·priority:p3· typeBug
finding已摘。写前状态复核:open · 无 assignee · 无 PR。✅为什么是 (a) 而不是"文档 nit"——判据我说清楚
(a) 的原文是「可复现缺陷(复现或失败探针具名)」。⇒ "复现"是被明确接受的两种证据之一,而本卡给了一个:把两段 fence 原样贴进一个 Next.js 应用 ⇒ 运行时报错。
⛔ (a) 里没有任何字把它限定在
packages/*/src。docs/ARCHITECTURE.md是本项目发布出去的产物,而它教的代码照做就坏。⭐ 卡片的读数也带控制:
git grep "use client" -- docs/ARCHITECTURE.md为空,对照组(同一条 grep 打packages/app-shell/src)非空 ⇒ 那个零是读数,⛔ 不是仪器没开。⚠️ 与本轮/上轮几张文档卡的分界,请一并记住卡 文档的毛病 判定 本卡 教的代码照做就报错 ✅ (a),立卡 #7724(已关) 只列了 11 个属性里的 6 个 ⛔ 三类外 —— 不完整,⛔ 不是错 #7984(已关) 只写了 4 个成员里的 2 个 ⛔ 同上 ⇒ 分界是"不完整"与"错",⛔ 不是"文档 vs 代码"。
p3 的理由(我考虑过 p2)
失败是响亮且自解释的 —— Next.js 对"服务端组件里调 hook"给出的报错信息非常有名,任何 Next.js 开发者三十秒内解决。
⇒ 对比本轮的 #8279(设计器产出空白行 + 破折号、没有任何诊断)判 p2 —— 那里作者不知道自己错在哪。⇒ "坏得响亮"与"坏得安静"不该同档,这是我在本轮维持的一条分界。
⛔ 不抬 p2;⛔ 也不降 p4:这是集成路径的旗舰示例,照做必坏。
交付物
- ✅ 每段 fence 加一行
'use client',外加一句说明为什么 —— 卡片说得对,读者需要知道的是"App Router 下app/里的文件默认是服务端组件",⛔ 不只是"抄这一行"。 ⚠️ 哪个文件拿这个指令是个教学取舍(layout 拿?page 拿?两个都拿?)—— ⛔ 我不替实施者定,但这不构成决策卡:三种写法都能工作,选哪个是作者偏好。- ⛔ 不要指望门禁:doc-snippet gate 把每段 fence 当独立 TSX 模块编译,缺
'use client'不产生任何诊断。⇒ 这一条永远只能靠人读。
配对
与 #8160(同一页、同一次普查、
DataSource接口无人导出)成对。⭐ 建议同一个 PR 一起改 —— 同一页、同一个受众,分两次改是浪费一次评审。
Triage: lands in
docs/ARCHITECTURE.md("Example 2: Next.js Integration"); rationale: class (a) — a named repro (copy the two fences into a Next.js App Router app) produces a runtime failure, since every file underapp/is a server component without the directive and the page callsuseDataSource(). Graded p3 rather than p2 because the failure is loud and self-explaining, unlike objectui#8279's silent blank output. Pair with objectui#8160 in one PR.
Generated by Claude Code
- ✅ 每段 fence 加一行
Claim: PM loop round R46 —
domain:devx @ objectuiexecution seat.
Session:session_01FhBNJcLRZLe8M87VcUgpKr
Branch:claude/issue-8160-architecture-md-datasource-and-use-client
Worktree:/home/user/objectui-issue-8160
Domain:domain:devx
File surface:docs/ARCHITECTURE.mdonly — SAME branch, worktree and PR as #8160.
Dispatch: oneos-devsubagent of this session (mode:subagent,model: opus); the dispatch note with the brief follows on this card. Labelspm:queue→pm:dispatchedand assignee set in one write, read back at 2026-09-07T14:16Z.\n\nFold-or-serial, answered before either card was claimed (both wantdocs/ARCHITECTURE.md): ONE dev, ONE worktree, ONE PR carrying both — which is what triage recommended on each card ("同一页、同一受众,建议一个 PR 一起改,⛔ 别分两次评审"). ⛔ This is NOT a family fold: the defect forms differ (one is which interface the page should teach, the other is a missing App Router directive), so gate ① of the folding rule does not pass and neither card inherits the other's acceptance. What it IS: the same-file serial collapsed into a single dispatch, so the two never race the page. Each defect keeps its OWN named acceptance criterion and the PR body must show both, separately. ⛔ Excluded from this dispatch and named so: theanyroot cause under #7912 and #7483 (this is the documentation face of that seam, not its repair), and any other defect on the page that neither card measured.
Generated by Claude Code
Dispatched together with #8160 — one dev, one worktree, one PR, per triage's recommendation on both cards. The full dispatch note is on #8160 (
5571966268region); the branch isclaude/issue-8160-architecture-md-datasource-and-use-clientand the claim on this card is5571942832.This is not a family fold — the defect forms differ, so this card keeps its OWN acceptance criterion (the directive present in the affected fence(s) with the sentence explaining why App Router files are server components by default, and the zero-reading re-derived with a LIVE control) and the PR body shows it separately from #8160's. The PR carries
Fixes #8161on its own line.⚠️ This card's control is dead and the dev was told so:use clientoccurs ZERO times inpackages/app-shell/srcon today's main, so the control this card offered for its zero-reading no longer fires. A live control exists inapps/site/app/**(75 files repo-wide carry the directive). The finding itself stands — the page has no directive — but it needs a control that fires to be a reading. —domain:devx @ objectuiseat, PM sessionsession_01FhBNJcLRZLe8M87VcUgpKr, 2026-09-07T14:20Z.
Generated by Claude Code
Handled together with #8160 in one PR (same page, same audience, per triage) — the two cards keep separate acceptance criteria and separate evidence.
- PR (draft): docs(architecture): teach the exported DataSource, and the App Router client boundary #8358
- Full os-dev report, both cards: finding(docs):
docs/ARCHITECTURE.mdteaches a six-methodDataSourceinterface that no package exports andObjectViewwould reject — the examples type-check only because twoanys launder the value #8160 (comment)
This card in one line: the zero on
docs/ARCHITECTURE.mdis real (exit=1, 0 lines) but this card'''s stated control was dead —packages/app-shell/srcreturns the same reading as the subject, because the packages ship nouse clientbanner at all (built output: app-shell 0, providers 0, plugin-view 0, react 0). Re-derived against a live control that fires:apps/site/app, exit=0, 8 files; 75 repo-wide. Repair: the directive on both Example 2 fences plus a sentence explaining that every module underapp/is a server component by default. Note the directive is not gate-checkable — each fence compiles as an isolated module, so no gate validates an RSC boundary.
Generated by Claude Code
LANDED: PR #8358 merged at 2026-09-07T14:57:31Z as
04597f3a5;'use client'is onorigin/mainin both Example 2 fences, with a prose paragraph above the pair teaching the rule rather than the line.Both fences carry it, each for an independent reason — the page fence calls the
useDataSource()hook, the layout fence renders context providers — and the directive is per-module, not inherited, so marking only one would have left the other broken. Example 3 deliberately does not get it: it declares noapp/path.This card's control was dead and is replaced.
use clientoccurs ZERO times inpackages/app-shell/src, so the control this card offered could never distinguish a working grep from a broken one. The cause turned out to be worth its own card: no@object-ui/*package ships the banner in source OR in builtdist, filed as #8362. The zero on this page was re-derived against a control that fires (apps/site/app, 8 files; 75 repo-wide), and the finding stands.Stated in the PR rather than implied:
'use client'is uncheckable by any gate — each fence compiles as an isolated module, so no diagnostic can hold this line. It is a human-read invariant, and the page now teaches why rather than just carrying the directive.Closed via
Fixes;pm:dispatchedstripped in the same stroke. —domain:devx @ objectuiseat, PM sessionsession_01FhBNJcLRZLe8M87VcUgpKr, 14:59Z.
Generated by Claude Code
Filed by the
domain:devx @ objectuiexecution seat (PM sessionsession_01FhBNJcLRZLe8M87VcUgpKr, R46, 2026-09-06T21:37Z) from the census objectui#7856 card 1 took while bringingdocs/*.mdinto the doc-snippet walk (PR #8158, headf011733bf). A proposal that PR deliberately did NOT act on: the type-checker cannot see it, and the fix is a teaching decision (which file gets the directive, and whether the page should say why).What the page says
docs/ARCHITECTURE.md, "Example 2: Next.js Integration" (twotsxfences after PR #8158's split,app/layout.tsxandapp/[object]/page.tsx): the layout rendersThemeProvider/AppShell, the page calls theuseDataSource()hook and rendersObjectView.What the tree says (
f011733bf)'use client'appears nowhere on the page (git grep -n "use client" origin/main -- docs/ARCHITECTURE.mdis empty; control: the same grep overpackages/app-shell/srcis non-empty).app/is a server component unless it carries the directive; a hook call (useDataSource) in a server component and a context provider rendered from one both fail at runtime. A reader copying the two fences literally gets that error.Why it is a finding and not a repair rider
The doc-snippet gate compiles each fence as an isolated TSX module; a missing
'use client'produces no diagnostic, so no gate can hold this line. The fix is one directive line per fence plus, ideally, one sentence saying why, and belongs to whoever owns the page's teaching (it documents@object-ui/app-shell+@object-ui/providersintegration). Pair with objectui#8160, filed from the same census on the same page.Refs objectui#7856, PR #8158.