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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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