Skip to content

fix(lint): every exported rule id constant is reachable from a published barrel (#5648) - #5735

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-5648-rule-id-barrel-export
Aug 6, 2026
Merged

fix(lint): every exported rule id constant is reachable from a published barrel (#5648)#5735
os-zhuang merged 1 commit into
mainfrom
claude/issue-5648-rule-id-barrel-export

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #5648

前提核对

issue 的前提成立,且比它报的更广。origin/main (205e81b) 上:

  • packages/lint/src/validate-flow-trigger-readiness.ts:57 导出 FLOW_TRIGGER_UNKNOWN_EVENT,src/index.tssrc/runtime.ts 均无该名(grep -c = 0)。
  • package.json#exports 确实只开 ".""./runtime",tsup.config.ts 的 entry 也只有 src/index.tssrc/runtime.ts,index.ts没有任何 export *(全部逐名列出)。三者合起来印证 issue 的判断:没进 barrel 不是「不好取」,而是完全取不到,没有深路径可绕。

为什么这不是一行的事

规则把自己的 id 写进每条 finding 的 f.rule,而那个字符串就是 os lint --json / os validate 递到消费者手上的东西:Studio 的 finding 渲染、下游按规则过滤/抑制、以及被授权元数据里的 suppressWarnings 数组。规则文件为此导出同名常量,消费者本该比对常量而不是重敲 slug。

issue 建议的全量清查翻出另外六处同类漏项,散在五个规则文件,成因都远早于 #5648:

常量 定义处 修前 barrel 状态
FLOW_TRIGGER_UNKNOWN_EVENT validate-flow-trigger-readiness.ts:57 两个 barrel 均无(#5648 所报)
APPROVAL_APPROVER_TYPE_UNSUPPORTED validate-approval-approvers.ts:57 两个 barrel 均无
SECURITY_FLS_UNQUALIFIED_KEY validate-security-posture.ts:68 两个 barrel 均无
FIELD_GROUP_SHADOWED validate-semantic-roles.ts:23 两个 barrel 均无
WIDGET_LEGACY_ANALYTICS_SHAPE validate-widget-bindings.ts:86 两个 barrel 均无
WIDGET_LEGACY_ANALYTICS_UNRENDERABLE validate-widget-bindings.ts:87 两个 barrel 均无
REACT_CHART_DRILLDOWN_INVALID validate-react-page-props.ts:259 两个 barrel 均无

七个都是活的规则 id:各有发射点与单测(已逐个核对,非休眠代码)。其中 WIDGET_LEGACY_ANALYTICS_SHAPE 最能说明代价 —— 规则打给用户的提示原话是 Suppress with suppressWarnings: ['widget-legacy-analytics-shape'](validate-widget-bindings.ts:417),即它主动教消费者用这个 id,却不让消费者拿到承载它的常量

漏项之所以能一路静默:规则照常工作,而它自己的单测从规则文件直接 import 常量(不经 barrel),于是唯一会暴露的时刻是有人从包外去消费它。同一种一行漏项独立发生七次,不是「下次记牢」能解决的记性问题,而是缺一条判定 —— 所以按 issue 正文的建议走了 gate 化这一支。

改动

  1. 补七行导出(src/index.ts,各自插进所属模块已有的导出块,顺序与源文件一致)。
  2. 新增 src/rule-id-barrel-exports.test.ts —— 4 条用例,把「每个导出的规则 id 常量必须 barrel 可达」变成 packages/lint 测试面的门禁。
  3. changeset:"@objectstack/lint": patch(导出面变化即发布面变化)。

分层:为什么落测试面而不是 scripts/ 门禁

  • 这条不变量完全是包内的 —— 没有别处定义 lint 规则 id,repo 级门禁会为一条局部不变量增加一个全局步骤。
  • 它要真的 import barrel 才能核验「名字在」且「取值对」;vitest 天然给得到。换成 scripts/ 门禁要么自己写一个 ES 解析器(即再造一份易错的静态分析),要么先构建 dist 才能检查。
  • 反馈时机:落在包自己的测试里,新增规则的作者在新规则单测转绿的同一次 run 里就会看到漏项;scripts/ 门禁会把它挪到另一个 job。

门禁如何防两类假绿

1. 「规则文件根本没被枚举到」 —— 发现面是对 src/文件系统读取,不是手写规则文件清单,新规则文件一存在即被枚举。另加一条 covers the whole rule surface:对 id 条数(> 100)与覆盖文件数(> 30)压下限,使将来改坏提取式后**在空集上「全绿」**这条路走不通。同一用例还断言无重名常量 —— 两个文件导出同名,barrel 只可能再导出其一,却会替另一条规则作答。

2. 「barrel entry 根本没被 import」 —— 两个 entry 是静态列出的(全动态 import 无法可靠打包),但另有 barrel entries match the published exports mappackage.json#exportstsup.config.ts 各自独立推导出同一集合并三方比对。新增第三个 entry 若不登记就会红,而不是悄悄不被检查;同时也挡住「发布了但没构建」的 entry —— 否则门禁会拿一个根本不出货的文件去判定可达性,这本身就是假绿。

分类按取值形状,而非发射位置。 早先一版靠「定义旁边有 rule: NAME」来认规则 id,结果漏掉了经辅助函数参数发射的四个 REACT_CHART_* —— 恰好包含本次真实漏项之一(REACT_CHART_DRILLDOWN_INVALID)。形状是每个 id 都有的性质,与它怎么旅行无关。

悬空导出:诚实标注为「可见」而非主门禁。 反向用例(no barrel export names a rule id that no rule file defines)看着像能抓改名残留,实际抓不到 —— 因为 barrel 再导出一个源模块已不存在的名字根本过不了 tsc。这一点是实测过的,不是推断:临时往 barrel 加一行 FLOW_TRIGGER_RENAMED_GHOSTpnpm --filter @objectstack/lint typecheck

src/index.ts(59,3): error TS2305: Module '"./validate-flow-trigger-readiness.js"' has no exported member 'FLOW_TRIGGER_RENAMED_GHOST'.

所以该用例的真实价值是抓仍能解析但已漂移的情况(barrel 行指向的模块与定义处不一致、或规则 id 形状的字符串从不再发射它的地方导出),测试注释里就是这么写的,没有夸大成改名门禁。

全量清查表(131 个规则 id 常量 / 47 个规则文件)

runtime.ts 一列统一为「无」:该 entry 按设计只导出函数与类型(runRuntimeAuthoringRules 等),不承载任何规则 id 常量 —— 与 issue 表格里两个已导出常量在 runtime 侧同为「无」一致。故下表状态即 index.ts 状态,FIXED = 本 PR 补入。

authoring-rules.ts                       ok     EXPRESSION_INVALID
data-model-rules.ts                      ok     UNIQUE_DOUBLE_DECLARATION
                                         ok     UNIQUE_UNSCOPED_DECLARED_INDEX
                                         ok     UNIQUE_LEGACY_ORGANIZATION_COMPOSITE
lint-autonumber-formats.ts               ok     AUTONUMBER_UNKNOWN_FIELD
                                         ok     AUTONUMBER_OPTIONAL_FIELD
                                         ok     AUTONUMBER_SELF_REFERENCE
                                         ok     AUTONUMBER_LITERAL_TOKEN
lint-flow-patterns.ts                    ok     FLOW_TIME_RELATIVE_ANTIPATTERN
                                         ok     FLOW_DATE_EQUALITY_FILTER
                                         ok     FLOW_PHANTOM_AGGREGATION
                                         ok     FLOW_DOUBLE_BRACE_INTERP
                                         ok     FLOW_BARE_DOLLAR_REF
                                         ok     FLOW_APPROVAL_REVISE_DEAD_END
                                         ok     FLOW_APPROVAL_REVISE_UNMARKED_BACKEDGE
                                         ok     FLOW_APPROVAL_REVISE_DISABLED
                                         ok     FLOW_APPROVAL_REVISE_TARGET_NOT_SERVICE_OWNED
                                         ok     FLOW_RUNAS_UNSCOPED
                                         ok     FLOW_ERROR_LABEL_NOT_FAULT
                                         ok     FLOW_BRANCH_LABEL_UNMATCHED
                                         ok     FLOW_DECISION_UNCONDITIONAL_BRANCH
                                         ok     FLOW_DEFAULT_EDGE_WITH_CONDITION
                                         ok     FLOW_MULTIPLE_DEFAULT_EDGES
                                         ok     FLOW_INERT_NODE_CONDITION
                                         ok     FLOW_MULTI_WRITE_UNFILTERED
lint-liveness-properties.ts              ok     LIVENESS_DEAD_PROPERTY
                                         ok     LIVENESS_EXPERIMENTAL_PROPERTY
lint-view-refs.ts                        ok     VIEW_KEY_COLLISION
                                         ok     VIEW_REF_FORM_TARGET_MISSING
                                         ok     VIEW_REF_FORM_TARGET_KIND
validate-action-body-writes.ts           ok     ACTION_BODY_WRITE_UNKNOWN_FIELD
                                         ok     ACTION_RECORD_WRITE_DISCARDED
validate-action-locations.ts             ok     ACTION_NO_PLACEMENT
validate-action-name-refs.ts             ok     ACTION_NAME_UNDEFINED
validate-ai-agent-authoring.ts           ok     AGENT_AUTHORING_WITHDRAWN
validate-ai-surface-affinity.ts          ok     AI_SKILL_SURFACE_MISMATCH
validate-ai-tool-references.ts           ok     AI_SKILL_TOOL_UNRESOLVED
validate-approval-approvers.ts           ok     APPROVAL_APPROVER_NOT_MEMBERSHIP_TIER
                                         ok     APPROVAL_APPROVER_TYPE_DEPRECATED
                                         ok     APPROVAL_APPROVER_TYPE_UNKNOWN
                                         FIXED  APPROVAL_APPROVER_TYPE_UNSUPPORTED
                                         ok     APPROVAL_ESCALATION_REASSIGN_NO_TARGET
                                         ok     APPROVAL_APPROVERS_MAY_RESOLVE_EMPTY
                                         ok     APPROVAL_EXPRESSION_INVALID
                                         ok     APPROVAL_EXPRESSION_NO_EMPTY_POLICY
                                         ok     APPROVAL_DECISION_OUTPUTS_RESERVED
                                         ok     APPROVAL_APPROVER_CROSS_ORG_UNSUPPORTED
validate-capability-references.ts        ok     CAPABILITY_REFERENCE_UNKNOWN
validate-chart-bindings.ts               ok     CHART_DIMENSION_UNKNOWN
                                         ok     CHART_MEASURE_UNKNOWN
                                         ok     CHART_DATASET_UNKNOWN
                                         ok     CHART_AXIS_NOT_SELECTED
validate-dashboard-action-refs.ts        ok     DASHBOARD_ACTION_TARGET_UNDEFINED
                                         ok     DASHBOARD_ACTION_ROUTE_UNRESOLVED
validate-filter-tokens.ts                ok     FILTER_TOKEN_UNKNOWN
validate-flow-node-writes.ts             ok     FLOW_NODE_WRITE_UNKNOWN_FIELD
validate-flow-template-paths.ts          ok     FLOW_TEMPLATE_UNKNOWN_FIELD
                                         ok     FLOW_TEMPLATE_LOOKUP_TRAVERSAL
validate-flow-trigger-readiness.ts       ok     FLOW_TRIGGER_UNKNOWN_OBJECT
                                         ok     FLOW_DRAFT_STATUS_AMBIGUOUS
                                         FIXED  FLOW_TRIGGER_UNKNOWN_EVENT
                                         ok     FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID
validate-form-layout.ts                  ok     FORM_FIELD_UNKNOWN
                                         ok     FORM_COLSPAN_ABSOLUTE
validate-hook-body-writes.ts             ok     HOOK_BODY_WRITE_UNKNOWN_FIELD
validate-list-view-mode.ts               ok     LIST_VIEW_FILTERS_IN_VIEWS_MODE
validate-nav-access.ts                   ok     NAV_OBJECT_UNGRANTED
validate-nav-target-refs.ts              ok     NAV_TARGET_UNRESOLVED
validate-object-references.ts            ok     OBJECT_REFERENCE_UNKNOWN
                                         ok     OBJECT_REFERENCE_UNREGISTERED_PLATFORM
validate-org-axis-red-lines.ts           ok     ORG_AXIS_PERMISSION_INHERITANCE
                                         ok     ORG_AXIS_CROSS_ORG_BU_GRANT
validate-page-field-bindings.ts          ok     PAGE_FIELD_UNKNOWN
validate-page-source-styling.ts          ok     PAGE_SOURCE_CLASSNAME
validate-react-page-props.ts             ok     REACT_CHART_FIELD_UNKNOWN
                                         ok     REACT_CHART_AGGREGATE_INVALID
                                         ok     REACT_CHART_AXIS_UNKNOWN
                                         FIXED  REACT_CHART_DRILLDOWN_INVALID
                                         ok     REACT_BLOCK_NEEDS_RECORD_CONTEXT
validate-readonly-flow-writes.ts         ok     FLOW_UPDATE_READONLY_FIELD
                                         ok     FLOW_UPDATE_READONLY_WHEN_FIELD
validate-record-title.ts                 ok     TITLE_FORMAT_RETIRED
                                         ok     TITLE_UNRESOLVABLE
validate-responsive-styles.ts            ok     STYLE_NODE_MISSING_ID
                                         ok     STYLE_CLASSNAME_TAILWIND
                                         ok     STYLE_RESPONSIVE_NO_BASE
                                         ok     STYLE_UNKNOWN_CSS_PROPERTY
                                         ok     STYLE_UNKNOWN_TOKEN
validate-rls-predicate-enforceability.ts ok     RLS_PREDICATE_UNENFORCEABLE
                                         ok     RLS_PREDICATE_UNPARSEABLE
validate-rule-compilability.ts           ok     VALIDATION_RULE_REGEX_UNCOMPILABLE
                                         ok     VALIDATION_RULE_SCHEMA_UNCOMPILABLE
validate-rule-schema-formats.ts          ok     VALIDATION_RULE_SCHEMA_UNKNOWN_FORMAT
validate-searchable-fields.ts            ok     SEARCHABLE_FIELD_UNKNOWN
                                         ok     SEARCHABLE_FIELD_UNSEARCHABLE
validate-security-posture.ts             ok     SECURITY_OWD_UNSET
                                         ok     SECURITY_OWD_ALIAS
                                         ok     SECURITY_EXTERNAL_WIDER
                                         ok     SECURITY_WILDCARD_VAMA
                                         ok     SECURITY_ANCHOR_HIGH_PRIVILEGE
                                         ok     SECURITY_ROLE_WORD
                                         ok     SECURITY_BOOK_AUDIENCE_UNKNOWN_SET
                                         ok     SECURITY_PRIVATE_NO_READSCOPE
                                         ok     SECURITY_MASTER_DETAIL_UNGRANTED
                                         FIXED  SECURITY_FLS_UNQUALIFIED_KEY
                                         ok     SECURITY_GRANT_EXPIRED_AT_AUTHORING
                                         ok     SECURITY_DELEGATION_MISSING_REASON
validate-seed-replay-safety.ts           ok     SEED_INSERT_MODE_DUPLICATES_ON_REPLAY
validate-seed-state-machine.ts           ok     SEED_VALUE_OUTSIDE_STATE_MACHINE
validate-semantic-roles.ts               ok     FIELD_GROUP_UNDECLARED
                                         ok     FIELD_GROUP_EMPTY
                                         FIXED  FIELD_GROUP_SHADOWED
                                         ok     SEMANTIC_ROLE_FIELD_UNKNOWN
validate-sharing-rule-enforceability.ts  ok     SHARING_RULE_UNLOWERABLE_CONDITION
                                         ok     SHARING_RULE_RUNTIME_VARIABLE_CONDITION
validate-translatable-sections.ts        ok     TRANSLATION_SECTION_NAME_MISSING
validate-translation-references.ts       ok     TRANSLATION_TARGET_UNKNOWN
                                         ok     TRANSLATION_OPTION_KEY_UNKNOWN
validate-view-containers.ts              ok     VIEW_CONTAINER_SHAPE
validate-visibility-predicates.ts        ok     VISIBILITY_ALIAS_DEPRECATED
                                         ok     VISIBILITY_ROOT_MISLAYERED
validate-widget-bindings.ts              ok     WIDGET_DATASET_UNKNOWN
                                         ok     WIDGET_DIMENSION_UNKNOWN
                                         ok     WIDGET_MEASURE_UNKNOWN
                                         ok     CHART_FIELD_UNKNOWN
                                         ok     CHART_CONFIG_MISSING
                                         ok     TABLE_COUNT_ONLY
                                         ok     MEASURE_AGGREGATE_INCOHERENT
                                         FIXED  WIDGET_LEGACY_ANALYTICS_SHAPE
                                         FIXED  WIDGET_LEGACY_ANALYTICS_UNRENDERABLE
                                         ok     DASHBOARD_FILTER_FIELD_UNKNOWN

清查中被正确排除的唯一非规则 id 字符串常量:RELATED_LIST_TYPE = 'record:related_list'(validate-page-field-bindings.ts:183,page block 类型,:_ 都不是 id 拼法)。NULL_GUARD_HINT 是多行模板拼接,不是字面量常量,同样在外。

#5651 / #5663 / #5695 今天新增的常量:验证过,自带导出。 FLOW_TIME_RELATIVE_DESCRIPTOR_INVALID(#5651)与 FLOW_MULTI_WRITE_UNFILTERED(#5663)在 index.ts 中各命中 1 次;#5695 未新增常量(只改了 flow-runas-unscoped 的证据搜索范围)。即近期车道确实各自补了 barrel 行,本次七处均为更早的存量漏项。

反向验证(方向:红 —— 事前预判并命中)

事前预判:注掉本 PR 补的 FLOW_TRIGGER_UNKNOWN_EVENT 导出行 → 可达性用例转红并点名该常量;其余三条(entry 集合、发现面下限、反向孤儿)保持绿,因为它们都不依赖这一行。实测完全吻合:

 FAIL  src/rule-id-barrel-exports.test.ts > ... > every declared rule id constant is exported from a barrel, with its own value
AssertionError: expected { …(2) } to deeply equal { unreachable: [], mismatched: [] }
+   "unreachable": [
+     "FLOW_TRIGGER_UNKNOWN_EVENT ('flow-trigger-unknown-event') — validate-flow-trigger-readiness.ts:57",
+   ],
 Test Files  1 failed (1)
      Tests  1 failed | 3 passed (4)

恢复后 4/4 绿。

可达性实测(证明修复真的到消费者手上)

构建产物取值(ESM 与 CJS 双格式,并核对 .d.ts / .d.cts 类型面各命中 1 次 declare const):

OK    FLOW_TRIGGER_UNKNOWN_EVENT             esm="flow-trigger-unknown-event" cjs="flow-trigger-unknown-event"
OK    APPROVAL_APPROVER_TYPE_UNSUPPORTED     esm="approval-approver-type-unsupported" cjs=...
OK    SECURITY_FLS_UNQUALIFIED_KEY           esm="security-fls-unqualified-key" cjs=...
OK    FIELD_GROUP_SHADOWED                   esm="field-group-shadowed" cjs=...
OK    WIDGET_LEGACY_ANALYTICS_SHAPE          esm="widget-legacy-analytics-shape" cjs=...
OK    WIDGET_LEGACY_ANALYTICS_UNRENDERABLE   esm="widget-legacy-analytics-unrenderable" cjs=...
OK    REACT_CHART_DRILLDOWN_INVALID          esm="react-chart-drilldown-invalid" cjs=...
all reachable: true

验证

结果
pnpm --filter @objectstack/lint test Test Files 60 passed (60) / Tests 1383 passed, 4 skipped (1387)
新用例单跑 4 passed(逐条 verbose 列出)
pnpm --filter @objectstack/lint typecheck 绿
pnpm --filter @objectstack/lint build 绿(含 DTS)
消费半径 pnpm --filter @objectstack/cli test Test Files 83 passed (83) / Tests 825 passed (825)
node scripts/check-nul-bytes.mjs OK (scanned 5614 tracked text file(s)),并对改动文件另跑控制字符自扫,干净
eslint 改动文件 干净无输出

CLI 首跑曾出现 46 个文件红,原因是新 worktree 里 CLI 的工作区依赖未构建(Failed to resolve entry for package "@objectstack/types"),补 pnpm --workspace-concurrency=2 --filter '@objectstack/cli^...' build 后 83/83 全绿 —— 与本改动无关,记录在此以免误读。

范围

仅导出面,无行为变化:没有任何 f.rule 字符串被改动,原先对字面量比对的消费者继续可用;新增的只是「也可以 import 常量」这条路。未碰 content/docs/releases/

顺带说明一处未纳入本 PR 的工作区改动:构建依赖时 packages/spec/authorable-surface.base.jsongen:schema 自动重锚(baseRev 指向当前 merge base)。已 git checkout -- 还原,不进本 PR。该现象已有在案 issue,故未另开新单:#5358(--check 模式也会重写该文件)与变体 #5370


Generated by Claude Code

…hed barrel (#5648)

A rule writes its id into every finding's `f.rule`, and that string is what
`os lint --json` / `os validate` put in front of consumers — Studio's finding
renderer, downstream filtering, and `suppressWarnings: ['<rule-id>']` in
authored metadata. Rule files export a named constant for exactly that reason:
a consumer should compare against the constant, not retype the slug.

But `package.json#exports` opens only "." and "./runtime" (and `tsup.config.ts`
builds only those two entries), so a constant no barrel re-exports is not merely
inconvenient to reach — it is unreachable. There is no deep path to fall back
to, and the consumer's only remaining option is the literal the constant existed
to eliminate.

#5648 reported one (`FLOW_TRIGGER_UNKNOWN_EVENT`). The sweep it asked for found
SIX more, across five rule files and all predating it:
`APPROVAL_APPROVER_TYPE_UNSUPPORTED`, `SECURITY_FLS_UNQUALIFIED_KEY`,
`FIELD_GROUP_SHADOWED`, `WIDGET_LEGACY_ANALYTICS_SHAPE`,
`WIDGET_LEGACY_ANALYTICS_UNRENDERABLE`, `REACT_CHART_DRILLDOWN_INVALID`.
`WIDGET_LEGACY_ANALYTICS_SHAPE` shows the cost best: the rule's own message
tells the user to `Suppress with suppressWarnings: ['widget-legacy-analytics-shape']`
— it teaches the id while withholding the constant that carries it.

Nothing failed when a barrel line was forgotten: the rule kept working, and its
unit test imported the constant from the rule file directly rather than through
the barrel, so the omission surfaced only when someone consumed it from outside
the package. Seven independent omissions of one one-line kind is a missing
check, not a memory problem.

So the judgement moves into the package's own test surface
(`src/rule-id-barrel-exports.test.ts`): forgetting the barrel line now fails in
the same run the new rule's own tests go green. The invariant is package-local
— nothing outside defines lint rule ids — and it needs to actually IMPORT the
barrel to verify values, which vitest gives for free; a `scripts/` gate would
either reimplement an ES parser or have to build dist first, and would move the
feedback into another job.

Built against two shapes of false green:
- Discovery reads `src/` from the filesystem rather than a hand-kept list, so a
  new rule file is enumerated as soon as it exists, and a floor on the id count
  makes a future break in the extraction pattern fail loudly instead of passing
  over an empty set.
- The two entries are named statically (a fully dynamic import cannot be
  bundled reliably), but a separate case derives the same set independently from
  `package.json#exports` AND `tsup.config.ts` and compares — a third entry that
  is not registered fails rather than going silently unchecked.

Classification is by VALUE SHAPE, not emission site: an earlier draft matched
`rule: NAME` next to the definition and missed the four `REACT_CHART_*` ids,
which reach their finding through a helper argument — including one of the real
gaps.

Export surface only, no behavior change: no `f.rule` string moved, and
consumers already comparing literals keep working.

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 6, 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 6, 2026 2:48am

Request Review

@github-actions github-actions Bot added the size/m label Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

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

  • content/docs/automation/hook-bodies.mdx (via @objectstack/lint)
  • content/docs/permissions/authorization.mdx (via @objectstack/lint)
  • content/docs/releases/v17.mdx (via @objectstack/lint)

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.

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 size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FLOW_TRIGGER_UNKNOWN_EVENT 规则 id 常量没从 @objectstack/lint 导出 —— 消费者拿不到,只能对字面量

2 participants