Skip to content

[cli/lint] 作者时规则的命令覆盖漂移是系统性的:23/26 条手工接线规则只跑部分命令,9 条 error 级有门禁盲区(os build 会发布 os lint 拒绝的流) #4409

Description

@os-zhuang

现象

逐条统计 CLI 三个作者时命令(os validate / os build(compile.ts)/ os lint)源码里手工接线的 26 条规则,各自跑在哪些命令上:

覆盖 条数
三个命令都跑 3
只跑 1–2 个 23

其中 9 条能报 error(即门禁级)的分布:

规则 来源 validate build lint 盲区
validateStackExpressions @objectstack/lint · lint
validateFilterTokens · lint
validateDashboardActionRefs · lint
validateResponsiveStyles · lint
lintAutonumberFormats CLI 本地 · lint
lintViewRefs CLI 本地 · lint
validateListViewMode @objectstack/lint · · build
validateViewContainers · · build
validateApprovalApprovers · · build + validate

最后三行是最危险的方向:os build 是三个命令里最弱的门,会发布 os validateos lint 拒绝的东西。

实测(不是 grep 推断)

app-todo 里植入一个 CEL 语法坏掉的 expression approver({ type: 'expression', value: 'record.owner ==' },命中门禁级 approval-expression-invalid):

os lint      EXIT=1   ✗ approval-expression-invalid
os validate  EXIT=0
os build     EXIT=0   ← 构建照常产出

一个审批人表达式解析不了的流,构建、发布一路绿灯——只有 os lint 拦得住,而 CI 通常跑的恰恰是另外两个。

完整 26 条矩阵(validate / build / lint)
validateApprovalApprovers      · · ✓   1/3
validateCapabilityReferences   ✓ · ✓   2/3
validateDashboardActionRefs    ✓ ✓ ·   2/3
validateFilterTokens           ✓ ✓ ·   2/3
validateFlowTriggerReadiness   ✓ · ·   1/3
validateJsxPages               ✓ · ·   1/3
validateListViewMode           ✓ · ·   1/3
validateOrgAxisRedLines        ✓ ✓ ✓   全
validatePageSourceStyling      ✓ · ·   1/3
validateReactPageProps         ✓ · ·   1/3
validateReactPages             ✓ · ·   1/3
validateRecordTitle            · · ✓   1/3
validateResponsiveStyles       ✓ ✓ ·   2/3
validateSecurityPosture        ✓ ✓ ✓   全
validateSeedReplaySafety       · · ✓   1/3
validateSeedStateMachine       · · ✓   1/3
validateSemanticRoles          · · ✓   1/3
validateStackExpressions       ✓ ✓ ·   2/3
validateViewContainers         ✓ · ·   1/3
validateVisibilityPredicates   ✓ ✓ ·   2/3
validateWidgetBindings         ✓ ✓ ✓   全 (另跑 os doctor,已记录的例外)
lintAutonumberFormats          ✓ ✓ ·   2/3
lintFlowPatterns               ✓ ✓ ·   2/3
lintLivenessProperties         ✓ ✓ ·   2/3
lintUniqueDeclarations         ✓ ✓ ·   2/3
lintViewRefs                   ✓ ✓ ·   2/3

统计口径:按命令源码里的直接调用;经 validateReferenceIntegrity 套件进入三命令的规则不在此列(那部分 #4402 已守住)。severity 按源码中 severity: 'error' 是否出现判定,个别属条件分支;approval 一条已实测,其余属"可报 error"。

这不是新型缺陷,是同一型的第四次

  1. lint: no reference-integrity or option-key validation for app metadata #3583 §5 D5REFERENCE_INTEGRITY_RULES,起因就是"同一个 stack,跑哪个命令就被哪个子集检查";
  2. os validate runs none of the flow authoring lints, so a build-failing flow passes validate #3782(validate.ts 3e3 注释自己记录):四条 authoring lints 曾只在 build 跑,其中两条 gating,validate 报干净、build 拒绝;
  3. [lint/cli] validateReadonlyFlowWrites 仍未接入 os lint —— 一条 gating error 只在 validate/compile 跑 #4384 / fix(lint,cli): os lint 不再放行另外两个命令拒绝的 flow #4394:validateReadonlyFlowWrites 只在 validate+build,lint 放行 build 拒绝的 stack;
  4. 本 issue:剩下的 23 条,含 9 条 error 级。

每次都修了"那一例",失败模式留着。#4402 的接线守卫也拦不住这 23 条——它只过滤 REFERENCE_INTEGRITY_RULES 现有成员名,suite 之外的规则被手工接进两个命令,它一声不吭。

建议

不变量:任何能报 error 的规则必须三个命令都跑。 advisory 规则可以按成本做命令级取舍(如 react 系列要加载 ~9MB TypeScript,os lint 保持轻量是正当理由)——但那必须是写下来的决定,不是没人接线的默认。

落地形态(#4384 讨论中的"家族 + 组合层"方向):

  1. 每条规则(或按家族)显式声明跑在哪些命令上,写成数据、带理由;三个命令消费同一 registry;
  2. 守卫从"点名单条"升级为棘轮:一份"仍允许 CLI 直接调用"的清单,每项带理由,新增必须显式编辑——FLOW_WRITE_NODE_TYPES_DEFERRED / TEST_DEBT 的同款纪律;
  3. 分批迁移:
    • P1:build 瞎的 3 条 gating(validateListViewModevalidateViewContainersvalidateApprovalApprovers)——能发布坏构建的方向;
    • P2:lint 瞎的 6 条 gating——预检说谎的方向;
    • P3:advisory 17 条——逐条写下命令范围与理由,进棘轮清单。

版本

main @ 27f907252。发现自 #4384 的收尾评估。相关:#4394#4402#3583#3782

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions