Uh oh!
There was an error while loading. Please reload this page.
docs(skills): console-development.md 按 pages/system 现状重写,并同步 eval 的幽灵组件期望 (#3713) - #3729
Merged
Merged
Conversation
…lity and sync its eval (#3713) Five of the seven `pages/system/` files the guide taught do not exist, and a whole section documented `MetadataManagerPage` — deleted, zero hits repo-wide — including a route example and a `listComponent` extension point on a registry file (`config/metadataTypeRegistry.ts`) that never existed under `apps/console/src/`. - Directory tree rewritten to the six real `pages/system/` pages, plus a relocation table for everything that left `apps/console` in cccdf84. - New "Retired names" correction anchor: each dead symbol appears exactly once in the guide, immediately followed by its verdict and live replacement. - The registry chapter now documents the real engine — `packages/app-shell/src/views/metadata-admin/registry.ts`, `MetadataResourceConfig`, `registerMetadataResource()`, and the actual `MetadataResourceListPage` / `MetadataResourceEditPage` flows. - Routing section replaced with the real two-file split, the engine's canonical `metadata/:type…` routes, and the four `SystemObjectRedirect` legs (#3655's permissions leg is ruled but not yet on main, and is labelled as such). - Reference-assembly positioning added up front, citing cccdf84. - evals/console-development.json: expected_output no longer bakes in `MetadataManagerPage`; the phantom `MetadataTypeRegistry`, `MetadataDetailPage`, `pageSchemaFactory` and `registerWidgets` assertions are replaced with tokens that resolve to real code, and the dead API names move to `must_not_contain` so a stale answer now fails instead of passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
The latest updates on your projects. Learn more about Vercel for GitHub. |
yinlianghui
commented
Aug 8, 2026
CollaboratorAuthor
第十节「越界发现」单号补齐创建 PR 时 GitHub search API 速率限制未过,两单在 PR 开出后随即立完(均未认领,均已按关键词搜过本仓开放 issue、无同源单):
两单都只记录,本 PR 一行未改它们涉及的内容 —— 本 PR 文件面仍是 需要说明的边界:本 PR 已在 guide 顶部加了「先在 Generated by Claude Code Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 8, 2026 10:07
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 8, 2026
akarma-synetal pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 10, 2026
…ai#3735) (objectstack-ai#3864) `skills/objectui/**` 的指南是本仓 agent 写代码的直接输入,正文大量用反引号给出 仓内路径当坐标,而此前无任何门禁校验它们存在。`check-doc-links.mjs` 两头都不沾: 它的 SCAN_ROOTS 没有 skills 一行,而且它判的是 markdown 链接,反引号里的裸路径 本来也不在它眼里。代价付过两轮,两轮都靠人肉阅读发现 —— objectstack-ai#3713/PR objectstack-ai#3729 与 objectstack-ai#3730/PR objectstack-ai#3734(同一文件 13 个真实符号指向不存在的目录)。 这类缺陷贵得不成比例:符号通常是真的,只有坐标错了,所以没人拿到编译错误 —— agent 从 Read 拿到「文件不存在」,以为是自己搜得笨,再花一整圈重新定位指南声称已 经替它定位好的东西。它还天然复发:app-shell 抽取那批 commit 搬走代码时,没有任何 东西提醒指南跟着改。 ## 门禁 `scripts/check-skills-paths.mjs` —— 读 `skills/` 下每个 markdown,把正文反引号 span 里以五个顶层目录(apps/ packages/ examples/ scripts/ content/)开头、不含空格 的 token 逐个 existsSync。三条排除都是**规则**而不是豁免,因为它们都不是「某文件 存在」这个断言: - span 里含空白 —— 散文、命令行或类型,不是路径(PR objectstack-ai#3856 新加的自查命令行正好 是这个形状,凭此一条就出局,不需要任何名单条目); - 含 glob 元字符或占位段 —— 是形状不是位置,对它 existsSync 无意义; - 围栏代码块 —— 示例可以合法地写出读者「即将创建」的文件。 main@6422aa891 实测:18 个指南文件、91 个候选 span、其中 5 个是 pattern,86 条 路径断言里 85 条落地。 ## 豁免与它为什么不会烂掉 `scripts/skills-path-baseline.json` 只收「指南刻意声明其不存在」的路径,今天恰好 一条:console-development.md 的 Key contexts 一节存在的意义就是纠正那个反复出现的 错猜,原话是根本没有 `apps/console/src/context/` 这个目录。该条目是**双向**红的 棘轮 —— 路径哪天真出现在磁盘上,门禁红并点名(那句话已经变成假的);扫描不再命中 该条目,门禁也红(散文被改写了,条目成了死重)。条目按「文件 + token」定位,刻意 不含行号:指南散文一直在动(PR objectstack-ai#3856 刚搬过这一段),行号定位会在每次无关编辑后 陈旧。 反向验证(方向先判后跑,五个方向全部与预判一致):真实 skills 面绿(85/86 + 1 豁免);fixture 种死路径红并点名 file:line — token;豁免条目满足则绿;豁免路径出现 在磁盘上则红;豁免不再被命中则红。另有空判定护栏:扫到 0 个文件或 0 条断言即红 —— 「什么都没查到」不能算干净。 ## 接线 按同族三个门禁(control-bytes.yml、docs-links.yml、changeset-guard.yml)的挂法: 独立 workflow、无任何 paths 过滤、订阅 merge_group、`pnpm check:skills-paths`。 本门禁扫描面全是 markdown,而 ci.yml 的 push 触发器把 `'**/*.md'` 列进 paths-ignore、GitHub 又没有 per-job 路径过滤,放进 ci.yml 等于重建它要堵的洞 (objectstack-ai#3448 的原话)。ci-cd-pipeline.md 的 workflow 清单在两个方向上都被钉住,所以 新 workflow 连带一节文档与一行清单。 扫描面刻意不含 `content/docs/**`:扩面自带一批要清的红,check-doc-links 学过三遍 (objectstack-ai#3479/objectstack-ai#3490/objectstack-ai#3545),先量红再单独落地。五前缀名单同理 —— 补上本仓另外五个顶层 目录实测为 +2 候选、0 新红,便宜,但仍然是一个刻意的决定。 无 changeset:同族三个门禁脚本(check-control-bytes、check-i18n-call-site-keys、 check-changeset-presence)落地时都没带,且本改动不碰任何发版包 src/。 Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#3713
按 PM 裁决方向 1(按现状重写 + 同步 eval),吸收方向 3 的既定事实执行。两文件,无源码改动。
一、前提复核:issue 结论全部成立(
origin/main@0cf8f0f70)7 页面表逐条
find apps/console/src -name '{名}.tsx':SystemHubPage.tsx@deprecated判词MetadataManagerPage.tsxMetadataDetailPage.tsxAppManagementPage.tsxUserManagementPage.tsxRoleManagementPage.tsxPermissionManagementPage.tsxpages/system/现存 6 个,原 guide 一个都没提其中四个 —— 现已全部补入:ProfilePage/AuditLogPage/ApprovalsInboxPage/AiPendingActionsPage。零命中复核(
packages+apps,排除 node_modules):MetadataManagerPage0、MetadataDetailPage0、metadataTypeRegistry0、MetadataTypeConfig0、registerMetadataType0、getMetadataTypeConfig0、pageSchemaFactory0、listComponent0、MetadataListComponentProps0。即:88的listComponent扩展点与整个MetadataTypeConfig接口都是幽灵。一处与 PR #3699 正文不符的史实,以本次实测为准:#3699 说
cccdf84d7不是main的祖先(当时main仅 203 个 commit)。今天origin/main有 7517 个 commit,git merge-base --is-ancestor cccdf84d origin/main返回 ANCESTOR,git log -1能读到完整提交信息。故本 PR 放心引用它 ——apps/console/src/AppContent.tsx:110也已经在引。二、「How MetadataManagerPage works」按真实机制改写(先实测,未照抄派发单)
派发单指出真身在
packages/app-shell的 metadata-admin,要求先实测。实测结果比「registry 驱动」这句话更强,而且方向是反的:packages/app-shell/src/views/metadata-admin/registry.ts,类型MetadataResourceConfig,写入registerMetadataResource()(幂等 + 合并语义),读出getMetadataResource()/resolveResourceConfig()。/api/v1/meta/types返回的 JSONSchema 生成。一个类型完全不注册也能列/建/改 —— 注册项只是覆盖默认值。旧文那种「不注册就没有页面」的心智模型,会让 agent 去写一堆本来不必写的东西。ResourceListPage.tsx/ResourceEditPage.tsx逐行改写(含ListPage覆盖必须在其它 hook 之前短路这一实现约束、createSchema-> 服务端schema->defaultSchema的取值顺序、409 destructive_change重试?force=true)。builtinComponents.tsx里type:'permission'的真实注册项(EditPage: PermissionMatrixEditPage)。路由示例整节重写:两文件分工(
App.tsx外骨架 / app-shellDefaultAppContent应用内 /apps/console/src/AppContent.tsx的systemRoutesfragment)、引擎自己的metadata/:type…六条正规路由、以及SystemObjectRedirect的四条腿。三、#3655 permissions 腿:未落地,按「已裁 A 待落地」措辞写(避免抢跑)
动手前
git log origin/main实测:9961df297(#3673,四条重定向)已在 main;permissions 腿不在 ——apps/console/src/AppContent.tsx现仍只有 users / organizations / roles / positions 四行,:191-202的注释仍在解释为什么 permissions 故意缺席。故 guide 写作:即:陈述现状 + 记录已裁方向 + 给出自查指令,
sys_permission_set落地后这段只需删掉「not yet」那半句,不会与在途 PR 打架。四、参考装配定位(引 cccdf84)
开头新增引用块:cccdf84d7 把 shell / layout / home / 导航 / 整个 metadata admin 搬进
@object-ui/app-shell,designer 页搬进@object-ui/plugin-designer,apps/console只剩薄宿主。两条可执行推论:先在packages/app-shell找;第三方 fork 的是模板不是本 app。模板路径以实测为准:cccdf84d7 建的是
apps/console-starter,今天在examples/console-starter(apps/下只有console与site),故 guide 引后者。五、eval 同步(本单的牙)
先测量消费方式:全仓
scripts//.github//package.json/turbo.json对evals的引用 零命中 —— 本仓没有 eval runner,skills/objectui/README.md只说这个形状「so the prompts can be run as machine-checkable regression tests」。故校验方式是:逐字段人工核对 + 一个一次性核对脚本(写在 scratchpad,未进提交),规则见下。eval diff:
expected_outputregisterMetadataResource()覆盖:7,幽灵组件名被烤进期望答案must_containMetadataTypeRegistry,columns,formFields,SystemHubPageregisterMetadataResource,listColumns,createFields,metadata-admin,navigationMetadataTypeRegistry零命中;columns/formFields是幽灵接口的字段名;SystemHubPage是@deprecated面,不该作为正确答案的必要条件must_not_containnew standalone page,/system/objectsregisterMetadataType,pageSchemaFactorypromptmust_containpageSchemaFactory,registerWidgets,MetadataDetailPage,tabsComponentRegistry,SchemaRenderer,EditPage,registerMetadataResourceregisterWidgets连改前的 guide 里也不存在(真实文件名是registerObjectDetailWidgets.ts,不含该子串)—— 这条断言从来就无法从指南得到满足must_not_contain[]pageSchemaFactoryNavigationContext/ConsoleLayout/HomeLayout/UnifiedSidebar四个符号今天都真实存在,只是搬到了packages/app-shell。eval 断言的是答案里的符号名,不是路径,故该 eval 未被这次漂移污染 —— 如实不动为什么
MetadataManagerPage/MetadataDetailPage没进must_not_contain:一个正确答案完全可能顺口说一句「旧的MetadataDetailPage已删」,把它列成反模式会造成假红。改用正向断言把牙做足:照旧指南生成的答案会同时丢掉registerMetadataResource/EditPage(must_contain 未满足)并命中pageSchemaFactory(反模式),两条独立失败,已足够。这条取舍在此写明,免得下一个读者以为是漏了。六、纠错锚 + grep 计数(改前先量,#3656 措辞纪律)
新增「### Retired names — do not import these」小节,每个被删名字保留原名 + 紧跟判词与活体替代物。#3656 的教训是「措辞会改变 grep 结果,要先预测」—— 这里方向与 #3656相反:那次目标是 grep 归零,这次刻意不归零,而是收敛到「只在纠错锚里出现一次」,好让 grep 这些名字的 agent 一定落到判词上。
改前 / 改后计数(guide 内出现次数):
MetadataManagerPageMetadataDetailPageUserManagementPageRoleManagementPagePermissionManagementPagemetadataTypeRegistryMetadataTypeConfigregisterMetadataTypepageSchemaFactorylistComponentMetadataListComponentProps计数脚本的一处自身缺陷已修正并记录:
MetadataTypeConfig是getMetadataTypeConfig的子串,两者同在纠错锚同一行,裸计数会读成 2 —— 已在脚本里扣掉这层重叠,计的是「独立提及数」。七、逆向验证(先预测,后运行)
预测:把
origin/main的旧 guide + 旧 eval 放回去,核对脚本应转红,且红点必须落在(a) 旧 eval 的 must_contain 解析不到真实代码;(b) 纠错锚小节不存在;(c) 每个被删名字在锚外出现,次数应与上表「改前」列逐条相等;(d) 目录树名字集合 ≠ 真实文件集合。实测(
git show origin/main:取回两文件,apps/packages软链到本树):23 项 FAIL,逐条吻合:改后同一脚本:ALL CHECKS PASSED(87 项)。
八、门禁与 changeset 判断
node scripts/check-control-bytes.mjs->OK (scanned 3684 tracked text file(s); skipped 85 binary)grep -naP控制字符类 -> 无命中(退出码 1)JSON.parse(evals/console-development.json)-> OK;与其余 10 个 eval 文件的键集合逐一比对一致(skill_name,evals/id,prompt,expected_output,files,assertions/must_contain,must_not_contain),must_contain条数在 README 规定的 3–6 之间无 changeset,判断依据实测:
skills/下没有任何 package.json;根package.json是private: true且无files字段;39 包固定版本组里没有任何包把skills列进files。skills-lock.json只是把objectui指到本地路径供 skills CLI 消费,不参与 npm 发布。即 skills/ 不是发布面,本次改动对任何包产物零 delta。与 PR #3656(scripts/非发布包 -> 无 changeset)同一判据。九、围栏
apps/console任何源码、ROADMAP.md、content/docs/releases/。system的记录页 #3655 permissions 腿的文件面(AppContent.tsx/SystemHubPage.tsx)—— 与其在途 PR 零文件相交。十、越界发现(只报不改)
立单时命中 GitHub API 速率限制,单号待补(内容如下,PM 可代立或本 session 稍后补立):
apps/console/src/{context,hooks,components}/——apps/console/src/context/这个目录整个不存在,hooks/下只剩useBranding.ts,UnifiedSidebar.tsx在packages/app-shell/src/layout/。符号活着、路径全死,与本单同源(cccdf84)但属不同章节,故未在本 PR 中改。另:「Registered custom widgets」表列 6 个,registerObjectDetailWidgets.ts实注册 7 个(缺object-keys)。apps/console/src/schemas/objectDetailPageSchema.ts的buildObjectDetailPageSchema()全仓零调用者(唯一调用者正是被删的MetadataDetailPage),其 7 个 widget 仍由main.tsx注册。休眠代码,观察类(finding)。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Generated by Claude Code