Skip to content

feat(spec)!: view.zod.ts 子块收紧 —— 20 站点收 15 留 5(#4001 批 18) - #5070

Merged
xuyushun441-sys merged 5 commits into
mainfrom
claude/issue-4001-ui-batch18
Aug 4, 2026
Merged

feat(spec)!: view.zod.ts 子块收紧 —— 20 站点收 15 留 5(#4001 批 18)#5070
xuyushun441-sys merged 5 commits into
mainfrom
claude/issue-4001-ui-batch18

Conversation

@xuyushun441-sys

@xuyushun441-sys xuyushun441-sys commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Part of #4001 —— ui/ 波次批 18(packages/spec/src/ui/view.zod.ts,T1 必保)。

账面 20 个 strip 站点,收紧 15,留开 5。留开的每一个都是实测判定,不是没做完 —— 三处落锚(schema JSDoc + view-strictness-batch18.test.ts + 台账 ui 行)。

⚠️ 本批最有价值的一条:收了又退的 ListView.sort

sort 一度收紧成功,还带着本批最好的一条策展 —— direction → order(#4721SortNodeSchema 同一个二键元组定的别名;那边实测 {field, direction:'desc'} 解成 {field, order:'asc'},静默按相反方向排序)。

全量套件把它抓了回来:view-metadata-schema.test.ts 钉着 sort: [{ id, field, order }],注释写明那是「控制台按列排序 PUT 时 normalizeViewMetadata 落盘的确切形状」,而那个 id 是 objectui 逐行盖的 UI 行标识(components/src/custom/sort-builder.tsx:68 / :94,crypto.randomUUID())。收紧 = 控制台点一次排序就 422

机理(比这个站点本身值钱,且与本文件块注释所暗示的相反)

.strip() 不递归,和 .strict() 一样不递归。

ViewMetadataSchema 靠扁平成员上的 .strip() 放行 Studio 往返辅助键 —— 但那只重新打开顶层。任何在 ListViewSchema 内部被收紧的嵌套块仍经由该成员被解析,所以嵌套块里一个控制台盖的键无论成员姿态如何都会 422。块注释读起来像是救援能一路到底;它不能,现已就地改成实测描述,并在测试里钉住这条递归性质:

顶层 aux 键随行  -> ViewMetadataSchema.safeParse({...overlay, someStudioAuxKey:1}).success === true
嵌套已关块仍拒   -> ViewMetadataSchema.safeParse({...overlay, emptyState:{title:'x', notAnEmptyStateKey:1}}).success === false

为什么没有顺手声明 id

它是 React 列表键,不是协议。声明它等于把 UI 造物放进可授权面,并教 AI 作者去生成一个 UUID —— 正是本战役要杀的「声明即鼓励」。这是 ?? 兜底换了身 schema 外衣。故回退单个站点,终态是 #5074 的授权/wire 拆分下沉一层

同一机理向外追,抓到 main 上的现存 bug → #5114(已立案)

ViewFilterRuleSchema更早的批次收紧,而 filter-builder.tsx:228 盖同款 id。实测三条路径(含扁平 overlay)全被拒 —— 今天在控制台保存筛选条件就会 422。已如实标注「未跑真实 app 端到端复现」。

门测量(批 13-15 口径)

BFS 从 24 个 metadata-type root 加 ObjectStackSchema 出发,本文件每个目标 schema 解出 root-graph;阳性对照 ViewSchema/FormViewSchema/ViewItemSchema/PageSchema 可达,批 13 的 no-door 形状(touch/dnd)同一次运行里 UNREACHABLE。

⚠️ 仪器先修再信:lazySchema 返回 Proxy,承载点写 X.optional() 会解掉 Proxy,闭包里存的是真实例 —— 只比 Proxy 会把 ViewDataSchema 误判成不可达。靠它两个字面承载键交叉核对抓到的。

⚠️ #5056 复核:批 18 每个目标都是按 identityroot-graph,无一依赖 derived-clone 共享属性桥。运行里唯一的 derived-cloneListViewSchema —— 阳性对照而非目标,且经 ObjectListViewSchema 独立 identity 可达。

收紧的 15 个

ViewDataSchema 四个 provider 臂、UserFilterField.optionsGanttQuickFilter.optionsGanttConfig.tooltipFieldsListView.conditionalFormatting / .emptyStateFormFieldBase.keyFieldFormView.subformssubmitBehavior 四个臂。

策展锚定点名兄弟契约:option 上的 count跨层处方(objectui 每次渲染从快照算它)指向 showCount;object data source 上裸 name 刻意不设别名(它是 view ITEM 上的真键,按 finding 7 宁可不指路)。

submitBehavior 改成 discriminatedUnion('kind')(输入形状零变化)。朴素 union 的报错是 invalid_union 带四份子错误,#5014 实测渲染器压平成 "Invalid input";判别后顶层直接是 unrecognized_keys、路径就在 submitBehavior 上。副作用:check:variant-docs 因此首次看见这个一直可授权的词表 —— 判 governed(ui/forms.mdx 点名四个变体),非 exempt。

留开的 5 个(⛔ 别顺手收掉)

形状 依据
UserFiltersSchema 阻塞于能力声明 收紧会 422 掉 allowAddTab(#5073)
ViewItemSchema ×2 wire Studio 的 isPinned 往返落在这个成员(#5074)
ListView.sort wire 污染 控制台盖 UI 行 id(见上,#5114 同族)
FormFieldBaseSchema base,门已关 唯一消费者已 .strict() + ADR-0089 错误映射

批 6e 点名的验证做了:依赖真实存在 —— ObjectUserFiltersSchemaUserFiltersSchema.omit(...),.omit() 继承姿态,关基类会把钉从「drop」翻成「reject」。那个翻转是想要的(CLI lint 早就在报),只卡在 allowAddTab:saveMetaItem 校验后原样存原始 body,所以被 strip 的只是被丢弃的解析结果,渲染器仍读得到 —— 能力今天是工作的,收紧是删能力,不是把静默变响亮。

仪器纪律:六类断言先证红

破坏 结果
重开 ListView.emptyState 2 红
directionorder 别名 1 红(该站点后被回退)
discriminatedUnion 退回 union 首版没红 —— 抓到我自己断言的缺陷
UserFiltersSchema 2 红
ViewItemSchema 1 红
补 finding-7 错别名 nameobject 1 红

第 3 条:首版断言查「消息里有没有 delayMs」,而 union 子错误里也有,破坏后依然全绿;改成断言顶层 issue 的 codepath 后立刻红。断言查错误的载荷而非错误的形状,看起来在测、实际什么都没锁住。

台账闸门两向各证红(行内 4→5;表头 84→85),恢复绿。

台账(合并后重算)

#5069(批 16)冲突如期发生。取 main 整段 + 重贴批 18 三处编辑,批 16 条目逐条断言存活(widget no-door 行、i18n 5/6 split 行、AriaProps 散文、#5055/#5056、「批 16 is the eighth instance」)。

表头 75 strip of 198、可授权 35 of 75,从存活行重算:29+5+9+2+7+5+4+4+4+3+1+1+1 = 75。批 18 是第 9 例「两边都对、合并都错」—— 我的分支算 84、main 算 90,合并是 75,两边都没写过这个数。机理已记进散文:批 16 与批 18 为相反原因动了同两个数(16 改判 14 个它没碰的站点,18 关掉 15 个它碰的),合并值不可由任一 delta 推得。

验证(合并后 HEAD 4d7d39d,完整跑)

Test Files  303 passed (303)
     Tests  7720 passed (7720)

tsc --noEmit                     EXIT=0
check:generated                  ✓ All 8 generated artifacts are up to date
  spec-changes / upgrade-guide / skill-docs / skill-refs /
  react-blocks / authorable-surface / api-surface / docs   全 ✓

check:exported-any               EXIT=0
check:dual-source-exports        EXIT=0
check:empty-state                EXIT=0
check:variant-docs               EXIT=0   (20 unions — 9 governed / 11 exempt)
check:liveness                   EXIT=0
check:react-declaration-parity   EXIT=0
check:skill-examples             EXIT=0
check:strictness-ledger          EXIT=0   36 open file(s) / 234 strip site(s)

.changeset/pre.jsonmode=pre / tag=rc;⛔ content/docs/releases/ 零触碰;diff 面 5 文件。


🤖 Generated with Claude Code

https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9

…批 18)

ui/ wave batch 18 — the long tail of `ui/view.zod.ts`. The top level and the
form/page shapes closed in earlier waves; these are the sub-blocks that kept
the posture those were rescued from.

Closed (16 sites): ViewDataSchema's four provider arms, UserFilterField.options,
GanttQuickFilter.options, GanttConfig.tooltipFields, ListView.sort /
.conditionalFormatting / .emptyState, FormFieldBase.keyField, FormView.subforms,
and submitBehavior's four arms.

Reachability measured, not assumed: a BFS from all 24 metadata-type roots plus
ObjectStackSchema resolves every one `root-graph`, with ViewSchema/FormViewSchema/
ViewItemSchema/PageSchema positive and batch 13's no-door shapes UNREACHABLE in
the same run. The instrument needed fixing first — lazySchema returns a Proxy but
a carrier writes `X.optional()`, which resolves it, so comparing the Proxy alone
false-negatived ViewDataSchema.

submitBehavior became a discriminatedUnion on the `kind` literal it already
required: as a plain union of strict members the rejection is an invalid_union
whose prescription #5014 measured the renderers flattening away.

Left open, each measured and recorded in three places:
- UserFiltersSchema — closing would 422 `allowAddTab`, live in objectui's
  renderer and never declared in spec; saveMetaItem persists the ORIGINAL body,
  so the stripped key reaches the renderer and the capability works today.
- ViewItemSchema (x2) — wire: objectui's pin control PUTs {...storedItem,
  isPinned} onto this union member; closing would 422 pinning a saved view.
- FormFieldBaseSchema — a private base whose sole consumer already .strict()s it
  and carries the ADR-0089 strictVisibilityError map.

Ledger: ui/ 100 -> 84 strip, authorable 76 -> 60, both recomputed from surviving
rows. Also corrects a stale block comment claiming all four members of
ViewMetadataSchema strip-parse — member 2 has been strict since ViewSchema closed.

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 4, 2026 5:21am

Request Review

…dicts

Batch 16 found that the door-reachability BFS's `derived-clone` bridge can mark
a dead shape reachable off a few shared leaf properties, and that the error runs
one way — toward closing dead shapes.

Re-checked batch 18's verdicts against it: all sixteen closed shapes resolve
`root-graph` by IDENTITY (the schema's own instance, or the instance its
lazySchema Proxy resolves to, is literally in the closure), so none rests on
bridge evidence. The one `derived-clone` verdict in the run is `ListViewSchema`,
a positive control rather than a target, independently identity-reachable via
`ObjectListViewSchema`.

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
claude added 2 commits August 4, 2026 04:56
Ledger `ui/` section conflicted as expected — batch 16 (#5069) landed while
batch 18 was in flight and both edit it. Resolved by taking main's section
wholesale (so batch 16's `widget` no-door reclass, the `i18n` split row and the
AriaProps closure survive verbatim) and re-applying batch 18's three edits on
top.

Header and subtotal recomputed FROM THE SURVIVING ROWS, not carried from either
side: 29+4+9+2+7+5+4+4+4+3+1+1+1 = 74 strip, authorable 34 of 74. Batch 18 is
the ninth wrong-on-both-sides instance — it computed 84 against a tree where
batch 16's rows still existed, batch 16 computed 90 against one where view was
still 20, and the merge is neither. Recorded in the section's own prose, since
the two batches moved the same numbers for OPPOSITE reasons (16 reclassified 14
sites it never touched; 18 closed 16 it did).

check:strictness-ledger green on the merged tree: 36 open file(s) / 233 strip
site(s).

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
…row id

The full suite caught this: `view-metadata-schema.test.ts` pins
`sort: [{ id, field, order }]` as "the exact shape normalizeViewMetadata
persists on a console column-sort PUT", and objectui stamps that `id` per row
(components/src/custom/sort-builder.tsx:68/:94, crypto.randomUUID()). Closing
the sort entry made a console column-sort a 422.

The mechanism is the finding, and it governs every nested block in this file:
`.strip()` does NOT recurse, any more than `.strict()` does. ViewMetadataSchema
rescues Studio's round-trip keys by making its flattened members `.strip()`, but
that re-opens the TOP level only — a nested block closed inside ListViewSchema is
still reached through that member, so a console-stamped key inside it 422s
regardless of the member's own posture. The union's block comment read as though
the rescue reached all the way down; it does not, and it now says so.

`id` was deliberately NOT declared to silence the rejection. It is a React list
key, not protocol: declaring it would put a UI artifact on the authorable surface
and teach an AI author to emit a UUID. The end state is #5074's authoring/wire
split applied one level down.

Also adds the variant-docs entry my discriminatedUnion conversion made visible.
`FormView.submitBehavior`'s four variants were always authorable; as a plain
z.union the gate could not see them. GOVERNED (ui/forms.mdx names all four), not
exempt.

Ledger: ui/ 74 -> 75 strip, authorable 34 -> 35, recomputed from surviving rows.

Filed from this: #5114 — ViewFilterRuleSchema (closed by an EARLIER batch, live
on main) rejects the same class of console-stamped `id` on filter rows.

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation tests protocol:ui tooling labels Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

107 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@xuyushun441-sys xuyushun441-sys changed the title feat(spec)!: view.zod.ts 子块收紧 —— 20 站点收 16 留 4(#4001 批 18) feat(spec)!: view.zod.ts 子块收紧 —— 20 站点收 15 留 5(#4001 批 18) Aug 4, 2026
`ListView.sort` was reverted (the console stamps a UI row `id` into it), so the
changeset must not tell upgraders that `direction` now raises — it does not, and
a migration table that over-promises is the same "declared != enforced" defect
this campaign exists to remove, pointed at consumers.

15 closed, not 16. The `direction -> order` row is removed and `sort` is named
among the shapes deliberately left open, with the `.strip()`-does-not-recurse
reason.

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
@xuyushun441-sys
xuyushun441-sys marked this pull request as ready for review August 4, 2026 05:23
@xuyushun441-sys
xuyushun441-sys added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit 06df4fa Aug 4, 2026
25 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the claude/issue-4001-ui-batch18 branch August 4, 2026 05:44
xuyushun441-sys pushed a commit that referenced this pull request Aug 4, 2026
合并队列以 MERGE_CONFLICT 踢出后重做。冲突两处,双边全保留:

1. remaining-strip 表的相邻两行 —— 保留 批 17 的 `component.zod.ts`
   no gate 改判行,同时保留 批 18 的 `view.zod.ts` 5/50 行(20 收 15 留 5)。
   git 之所以冲突是两行相邻,不是同一行两改。
2. 小计段 —— 保留 批 18 的第九次实例叙述(它记录 批 16 与 批 18 为相反
   原因移动同两个数),把 批 17 作为第十次实例追加,再合成单一小计并从
   合并后存活行重算(不套用任何一方的 delta)。

从存活行重算(批 18 把 view 20 → 5,总数 90 → 75):

  存活行     = 29+5+9+2+7+5+4+4+4+3+1+1+1                  = 75
  no door    = touch 7 + animation 4 + dnd 4 + keyboard 4
             + offline 3 + sharing 1 + notification 1
             + widget 9 + i18n 5                           = 38
  no gate    = component 29 + chart 2                      = 31
  authorable = view 5 + app 1                              = 6
                                            6 + 38 + 31    = 75 ✓

批 18 关掉 15 个真门、批 17 测出 29 个根本没有门,叠加后 ui/ 只剩 6 个
authorable strip 站点,69/75(92%)不是本 ratchet 的工作。批 17 自身在同
一分支上把这行算错了三次(47/100 → 36/91 → 21/90 → 6/75),四次对各自的
树都正确、对合并都错误,已如实写下——十次全中。

os-regen 四步:merge(未 rebase)→ 从 origin/main 取回生成物(含
批 18 的 variant-docs.json,NOT_DRIVER_MANAGED 棘轮)→ install
--frozen-lockfile + 重建 spec + 整体重生成 → check:generated 8/8 全绿,
并断言十组兄弟条目共存(批 18 view 133 键 + submitBehavior variant-docs
条目 + view 参考页均存活)。

Part of #4001

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ehu85kbvMcrNTUJjwxvLJ9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:ui size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants