project-validator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Project Validator

项目验证工具

Project-wide lint for a Datex Studio branch. The branch is the source of truth: the validator enumerates the branch's configs via
dxs source explore configs
and bulk-exports them to a throwaway temp directory with
dxs source document build
(the CLI's offline-analysis path), then runs five cross-component checks against that temp export — checks that per-file validation cannot see in isolation. Returns a structured, read-only punch-list grouped by check type. Never modifies the branch, and never treats a local
src/
checkout as authoritative.
This is the project-level validator. It complements per-file validation:
component-validator
audits one component file end-to-end against its type-specific rule sheet; this skill audits the whole project (or a scope subset) for issues that only appear when you look across files — broken
objectType
references, OData queries that don't match the live schema, datasource query options that have drifted away from declared
outParams
, etc. The two skills are designed to be used together —
component-validator
after authoring each file,
project-validator
before merging a batch or shipping a release.
See also:
component-validator
— single-file audit against the per-type creator rule sheet. Use it after authoring or modifying any one component. This skill is the project-level counterpart.
See also:
component-wiring-check
— chases a specific cross-component reference contract. This skill is broader (5 categories across the whole project) but shallower (lint-grade, not deep wiring trace).
See also:
post-edit-verification
— quick post-write check on a single file. Different scope and lighter touch than this skill.
针对Datex Studio分支的项目级代码检查。分支是唯一可信来源:验证工具通过
dxs source explore configs
枚举分支的配置,并通过
dxs source document build
(CLI的离线分析路径)将其批量导出到临时目录,然后对该临时导出内容运行五项跨组件检查——这些检查是单文件验证无法独立完成的。返回按检查类型分组的结构化、只读问题清单。绝不会修改分支,也绝不会将本地
src/
检出目录视为可信来源。
这是项目级验证工具,是单文件验证的补充:
component-validator
针对单个组件文件,基于其类型特定规则表进行端到端审计;本工具则针对整个项目(或范围子集)检查那些只有跨文件查看才会发现的问题——损坏的
objectType
引用、与实时Schema不匹配的OData查询、与声明的
outParams
偏离的数据源查询选项等。这两个工具设计为配合使用:编写每个文件后使用
component-validator
,合并批次或发布版本前使用
project-validator
另见:
component-validator
—— 针对单文件,基于每类创建者规则表进行审计。在编写或修改任意单个组件后使用。本工具是其项目级对应工具。
另见:
component-wiring-check
—— 追踪特定的跨组件引用约定。本工具覆盖范围更广(整个项目的5类问题)但深度较浅(代码检查级别,而非深度连线追踪)。
另见:
post-edit-verification
—— 对单个文件进行快速编辑后检查。与本工具的范围和检查力度均不同。

Dependencies

依赖项

  • datex-studio-conventions
    defaults.md
    (description ≤100 chars, mandatory description),
    file-format.md
    (
    configurationTypeId
    table, suffix rules),
    naming-conventions.md
    (type-indicator rules). These are the rules the checks below enforce.
  • datex-studio-shared
    /
    datex-studio-runtime
    — branch-setup primitives and platform-runtime globals used when interpreting flow code (e.g. resolving
    $flow.inParams.<name>
    and
    $flow.outParams.<name>
    references).
  • component-validator
    — per-file companion. Sibling scope. When the project validator surfaces a file-local violation that a creator skill's rule sheet documents in detail, route the parent to
    component-validator
    for the deep audit.
  • schema-explorer
    — invoked for OData pre-flight (check 4). The project validator must not load raw schema documents into the parent context — always delegate the entity / property / navigation lookups to
    schema-explorer
    .
  • codebase-research
    — invoked when a finding needs grounded read-only inspection of supporting context (e.g. confirming an enum's allowed values by fetching the
    *-customType
    config from the branch). Optional, on demand.
  • datex-studio-conventions
    ——
    defaults.md
    (描述≤100字符,必填描述)、
    file-format.md
    configurationTypeId
    表、后缀规则)、
    naming-conventions.md
    (类型指示符规则)。以下检查均遵循这些规则。
  • datex-studio-shared
    /
    datex-studio-runtime
    —— 分支设置基础组件和平台运行时全局变量,用于解释流程代码(例如解析
    $flow.inParams.<name>
    $flow.outParams.<name>
    引用)。
  • component-validator
    —— 单文件配套工具。当项目验证工具发现某个文件本地违规,且创建者工具的规则表中有详细说明时,引导用户使用
    component-validator
    进行深度审计。
  • schema-explorer
    —— 在OData预检查(检查4)中调用。项目验证工具不得将原始Schema文档加载到父上下文——必须将实体/属性/导航查找委托给
    schema-explorer
  • codebase-research
    —— 当发现问题需要基于只读上下文进行验证时调用(例如通过从分支获取
    *-customType
    配置确认枚举的允许值)。可选,按需调用。

Mode

模式

This is a read-only project lint. Do NOT modify any files. Do NOT run commands that mutate branch state (no
upsert
, no
--fix
, no writes). The validator reports; the parent decides what to do with the findings, and routes fixes back to the matching creator/editor skill.
这是一个只读项目代码检查工具。请勿修改任何文件。请勿运行会改变分支状态的命令(无
upsert
、无
--fix
、无写入操作)。验证工具仅负责报告问题;由用户决定如何处理发现的问题,并将修复任务路由到对应的创建/编辑工具。

Workflow

工作流程

1. Resolve scope

1. 确定范围

The validator always runs against a branch (follow
datex-studio-shared/branch-setup.md
to establish the branch ID — never assume one). The caller additionally supplies one of:
  • all
    (default) — every owned config on the branch.
  • A check name —
    descriptions
    ,
    schema
    ,
    types
    ,
    metadata
    ,
    result-shapes
    . Run only that check across the project.
  • A scope subset — one or more config types (e.g.
    grid
    ,
    datasource
    ) or a name pattern. Apply all five checks (or the named check) within that subset only.
If the caller is ambiguous (e.g. just says "validate the project"), default to
all
owned configs on the branch and report the scope you chose in the output.
验证工具始终针对分支运行(遵循
datex-studio-shared/branch-setup.md
确定分支ID——切勿默认分支ID)。调用者还需提供以下选项之一:
  • all
    (默认)—— 分支上所有自有配置。
  • 检查名称 ——
    descriptions
    schema
    types
    metadata
    result-shapes
    。仅在项目中运行该指定检查。
  • 范围子集 —— 一个或多个配置类型(例如
    grid
    datasource
    )或名称模式。仅在该子集内运行所有五项检查(或指定检查)。
如果调用者表述模糊(例如仅说"验证项目"),默认针对分支上所有自有配置运行,并在输出中说明所选范围。

2. Enumerate and export the target configs (from the branch)

2. 枚举并导出目标配置(来自分支)

The branch is the source of truth — do not walk a local
src/
checkout. Acquire the configs via the CLI:
bash
undefined
分支是唯一可信来源——请勿遍历本地
src/
检出目录。通过CLI获取配置:
bash
undefined

List what's on the branch (optionally filter by type / owned-only / scope)

List what's on the branch (optionally filter by type / owned-only / scope)

dxs source explore configs --branch <branchId> --owned-only
dxs source explore configs --branch <branchId> --owned-only

Bulk-export every config to a THROWAWAY temp dir for offline analysis

Bulk-export every config to a THROWAWAY temp dir for offline analysis

dxs source document build --branch <branchId> --include-summaries -o "$TMP/dxs-validate"

`document build` writes one file per config under `$TMP/dxs-validate/<App>/<branchId>/local/<type>/<referenceName>.yaml`. That temp export is the only thing the checks read or grep — searching a temp file you just fetched is the sanctioned pattern; greping a persistent `src/` tree is not. Delete the temp dir when done.

Group the exported configs by type (the export is already organized into per-type folders, and each config carries its `configurationTypeId`):

- `footprintflow` — actions (`*-footprintFlow`)
- `flow` — functions (`*-flow`)
- `customtype` — interfaces / enums (`*-customType`)
- `footprintdatasource` — Footprint-tier OData datasources
- `datasource` — cloud-tier datasources (OData or flow-backed)
- `selector`, `storage`, `grid`, `form`, `editor`, `hub`, `backendtest`

A config whose type doesn't match the table is recorded as `unknown component type` and skipped (do not block the run on it).
dxs source document build --branch <branchId> --include-summaries -o "$TMP/dxs-validate"

`document build`会将每个配置写入`$TMP/dxs-validate/<App>/<branchId>/local/<type>/<referenceName>.yaml`路径下的单独文件。该临时导出内容是检查唯一读取或检索的对象——检索刚获取的临时文件是合规模式;检索持久化的`src/`目录则不允许。完成后删除临时目录。

按类型对导出的配置进行分组(导出内容已按类型文件夹组织,每个配置都带有`configurationTypeId`):

- `footprintflow` —— 动作(`*-footprintFlow`)
- `flow` —— 函数(`*-flow`)
- `customtype` —— 接口/枚举(`*-customType`)
- `footprintdatasource` —— Footprint层OData数据源
- `datasource` —— 云层数据源(OData或基于流程)
- `selector`, `storage`, `grid`, `form`, `editor`, `hub`, `backendtest`

类型与上表不匹配的配置会被记录为`unknown component type`并跳过(请勿因此阻止运行)。

3. Run the 5 checks

3. 运行5项检查

Run each check against the enumerated files. Order doesn't matter; do whichever is cheapest first. Collect findings as a structured list, never edit in-place.
针对枚举的文件运行每项检查。顺序无关紧要,可先运行成本最低的检查。将发现的问题收集为结构化列表,绝不就地编辑文件。

4. Report

4. 报告

Compose the punch-list per the Output format section below. Findings are grouped by check type. End with a one-line summary (
total files checked
,
passes
,
warnings
,
failures
). Do not propose fixes beyond a one-line pointer.
按照下方输出格式部分编写问题清单。发现的问题按检查类型分组。结尾添加一行摘要(
total files checked
passes
warnings
failures
)。除一行提示外,请勿提出修复方案。

The 5 Checks

5项检查

1. Description Validation (
descriptions
)

1. 描述验证(
descriptions

Scans: every component file (all suffixes above).
Rule (from
datex-studio-conventions/defaults.md
and
file-format.md
):
  • description
    must not be
    null
    .
  • description
    must not be
    ""
    (empty string).
  • description
    must be ≤ 100 characters. This is a hard SQL column cap on the Footprint side — imports fail with a SQL truncation error when exceeded.
Severity:
  • null
    or
    ""
    description → fail.
  • > 100 chars
    description → fail (not a warning — imports break).
  • Description present and within cap → pass.
Output line:
[pass] i_awi_configuration-customType.json — "Allocation config interface" (35 chars)
[FAIL] my_action-footprintFlow.json — description is null
[FAIL] orders_grid-grid.json — description is 137 chars (cap is 100)
扫描范围: 所有组件文件(上述所有后缀)。
规则(来自
datex-studio-conventions/defaults.md
file-format.md
):
  • description
    不得为
    null
  • description
    不得为
    ""
    (空字符串)。
  • description
    必须**≤100字符**。这是Footprint端的SQL列硬限制——超过时导入会因SQL截断错误失败。
严重程度:
  • null
    ""
    描述 → 失败
  • 描述长度
    >100字符
    失败(不是警告——导入会中断)。
  • 描述存在且符合长度限制 → 通过
输出示例:
[pass] i_awi_configuration-customType.json — "Allocation config interface" (35 chars)
[FAIL] my_action-footprintFlow.json — description is null
[FAIL] orders_grid-grid.json — description is 137 chars (cap is 100)

2. Schema-Code Alignment (
schema
)

2. Schema-代码对齐(
schema

Scans: action files (
*-footprintFlow.json
) and function files (
*-flow.json
).
What it checks: the declared
inParams
/
outParams
JSON declaration vs. the embedded TypeScript code that lives at
nodes[0].stepConfig.executeCodeConfig.code
(per the pattern documented in
codebase-research
— flow code lives inside the JSON, not on top).
Procedure:
  1. Parse
    inParams[]
    and
    outParams[]
    from the JSON.
  2. Extract the embedded code string (and iterate
    nodes[*]
    for multi-step flows).
  3. Heuristic match each declared
    inParam.id
    against
    $flow.inParams.<id>
    references in the code.
  4. Heuristic match each declared
    outParam.id
    against
    $flow.outParams.<id>
    references in the code.
  5. Look for
    $flow.inParams.<name>
    or
    $flow.outParams.<name>
    references in code that have no matching declaration.
Severity:
  • Declared
    inParam
    not referenced in code → warning (may be deliberate — kept for back-compat, future use, or external wiring).
  • Declared
    outParam
    never assigned in code → warning.
  • Code references
    $flow.inParams.<name>
    /
    $flow.outParams.<name>
    that has no matching declaration → fail (runtime error or silent
    undefined
    ).
Caveat: this is a heuristic string match, not a TypeScript compiler. False positives are acceptable when surfaced as warnings — the caller decides whether each warning is real. Do not escalate a warning to a fail without source-code grounded evidence.
Output line:
[warn] plan_inventory_consumption_action — inParam 'unused_param' declared but not referenced in code
[FAIL] commit_allocation_plan_action — code references $flow.inParams.foo but 'foo' is not declared in inParams
扫描范围: 动作文件(
*-footprintFlow.json
)和函数文件(
*-flow.json
)。
检查内容: 声明的
inParams
/
outParams
JSON声明与位于
nodes[0].stepConfig.executeCodeConfig.code
的嵌入式TypeScript代码之间的一致性(遵循
codebase-research
中记录的模式——流程代码位于JSON内部,而非外部)。
步骤:
  1. 从JSON中解析
    inParams[]
    outParams[]
  2. 提取嵌入式代码字符串(多步骤流程需遍历
    nodes[*]
    )。
  3. 将每个声明的
    inParam.id
    与代码中的
    $flow.inParams.<id>
    引用进行启发式匹配。
  4. 将每个声明的
    outParam.id
    与代码中的
    $flow.outParams.<id>
    引用进行启发式匹配。
  5. 查找代码中引用的
    $flow.inParams.<name>
    $flow.outParams.<name>
    在声明中不存在的情况。
严重程度:
  • 声明的
    inParam
    未在代码中引用 → 警告(可能是故意保留——用于向后兼容、未来使用或外部连线)。
  • 声明的
    outParam
    从未在代码中赋值 → 警告
  • 代码引用的
    $flow.inParams.<name>
    /
    $flow.outParams.<name>
    在声明中不存在 → 失败(运行时错误或静默
    undefined
    )。
注意: 这是启发式字符串匹配,而非TypeScript编译器。将误报作为警告处理是可接受的——由调用者决定每个警告是否真实。在没有源代码证据的情况下,请勿将警告升级为失败。
输出示例:
[warn] plan_inventory_consumption_action — inParam 'unused_param' declared but not referenced in code
[FAIL] commit_allocation_plan_action — code references $flow.inParams.foo but 'foo' is not declared in inParams

3. Type Resolution (
types
)

3. 类型解析(
types

Scans: every component file. Looks for
"objectType": "<Package>.<TypeName>"
values anywhere in the JSON (commonly inside
inParams[*].objectType
,
outParams[*].objectType
,
objectTypeDef.properties[*].objectType
, and nested datasource shapes).
Rule: every referenced
<Package>.<TypeName>
must resolve to either:
  • A
    <TypeName>
    customType
    config owned by the current package on the branch (a
    customtype/<TypeName>-customType.*
    entry in the temp export, equivalently
    dxs source explore configs --branch <id> --type customtype --search <TypeName>
    ), or
  • A type owned by another package the project depends on (treat unknown packages as "out of scope, do not report" unless the caller explicitly asked to chase cross-package references).
Procedure:
  1. Determine the current package (read from one of the package's component files; cross-check via folder convention).
  2. Collect every
    objectType
    string across all scanned component files.
  3. For each in-package reference, verify a matching
    <TypeName>
    customType config exists on the branch (in the temp export's
    customtype/
    folder). Fast resolution shortcut: pull the branch's nomenclature registry once —
    dxs configuration nomenclature -b <branchId>
    returns a flat
    <Package>.<Type>
    catalog (with enum members in
    constantValues
    ) to membership-test every
    objectType
    against in one pass, instead of a per-type
    dxs source explore
    lookup. See ../datex-studio-shared/context-navigation.md#discovering-custom-types-and-enum-members.
  4. Report unresolved references.
Severity:
  • Reference to a type in the current package with no matching customType config on the branch → fail.
  • Reference whose package is unknown to the project → warning (may be a typo, may be a legitimate external package).
Output line:
[FAIL] orders_grid-grid.json — references `Allocations.i_unknown_type`, no i_unknown_type-customType.json found
[warn] import_orders_action-footprintFlow.json — references `ExternalPkg.i_thing`; ExternalPkg is unknown to this project
扫描范围: 所有组件文件。查找JSON中所有
"objectType": "<Package>.<TypeName>"
值(常见于
inParams[*].objectType
outParams[*].objectType
objectTypeDef.properties[*].objectType
和嵌套数据源结构中)。
规则: 每个引用的
<Package>.<TypeName>
必须解析为以下两者之一:
  • 当前包在分支上拥有的
    <TypeName>
    customType
    配置(临时导出中的
    customtype/<TypeName>-customType.*
    条目,等价于
    dxs source explore configs --branch <id> --type customtype --search <TypeName>
    ),
  • 项目依赖的其他包拥有的类型(除非调用者明确要求追踪跨包引用,否则将未知包视为"超出范围,不报告")。
步骤:
  1. 确定当前包(从包的某个组件文件中读取;通过文件夹约定交叉验证)。
  2. 收集所有扫描组件文件中的每个
    objectType
    字符串。
  3. 对于每个包内引用,验证分支上存在匹配的
    <TypeName>
    customType配置(在临时导出的
    customtype/
    文件夹中)。快速解析捷径: 一次性获取分支的命名注册表——
    dxs configuration nomenclature -b <branchId>
    返回一个扁平化的
    <Package>.<Type>
    目录(枚举成员包含在
    constantValues
    中),可一次性对所有
    objectType
    进行成员测试,而非逐个类型进行
    dxs source explore
    查找。参见../datex-studio-shared/context-navigation.md#discovering-custom-types-and-enum-members
  4. 报告未解析的引用。
严重程度:
  • 引用当前包中的类型,但分支上无匹配的customType配置 → 失败
  • 引用项目未知的包中的类型 → 警告(可能是拼写错误,也可能是合法的外部包)。
输出示例:
[FAIL] orders_grid-grid.json — references `Allocations.i_unknown_type`, no i_unknown_type-customType.json found
[warn] import_orders_action-footprintFlow.json — references `ExternalPkg.i_thing`; ExternalPkg is unknown to this project

4. OData Schema Pre-Flight (
metadata
)

4. OData Schema预检查(
metadata

Scans: OData datasource files —
*-footprintDatasource.json
, and
*-datasource.json
files whose
type
is
"oDataQuery"
. Skips flow-backed datasources.
Procedure:
  1. Resolve the connection. Each datasource references a connection (a connection ID or a connection name). Determine it from the file. If ambiguous, ask the caller which connection to validate against.
  2. Delegate to
    schema-explorer
    for every entity / property / navigation lookup. Do not load raw OData metadata documents into the parent context —
    schema-explorer
    returns concise structured answers and handles connection resolution and FootPrintApi special cases.
  3. For each OData datasource:
    • Confirm the
      entitySet
      in
      paths[0].entitySet
      exists in the OData schema.
    • Confirm every property in
      queryOptions.selects
      exists on the entity type.
    • Confirm every property referenced in
      queryOptions.filters
      (filter-expression operands) exists on the entity type.
    • Confirm every navigation property in
      queryOptions.expands
      exists on the entity type.
  4. Report mismatches.
Severity:
  • Missing entity set → fail.
  • Missing select/filter property → fail.
  • Missing navigation in expand → fail.
  • Schema lookup failed (connection unreachable, schema not loaded) → warning with a note that the check could not run for this file. Do not fail the entire run on a single unreachable connection — record the warning and continue.
Output line:
[FAIL] fpds_get_material-footprintDatasource.json — entitySet 'Materials' not found in schema (did you mean 'Material'?)
[FAIL] ds_orders_grid-datasource.json — selects: property 'CustomeName' not on entity 'Orders' (typo?)
[warn] ds_legacy_thing-datasource.json — could not reach connection 'LegacyProd'; check skipped
扫描范围: OData数据源文件——
*-footprintDatasource.json
,以及
type
"oDataQuery"
*-datasource.json
文件。跳过基于流程的数据源。
步骤:
  1. 解析连接。 每个数据源引用一个连接(连接ID或连接名称)。从文件中确定该连接。如果存在歧义,请询问调用者要针对哪个连接进行验证。
  2. 将所有实体/属性/导航查找委托给
    schema-explorer
    请勿将原始OData元数据文档加载到父上下文——
    schema-explorer
    返回简洁的结构化答案,并处理连接解析和FootPrintApi特殊情况。
  3. 针对每个OData数据源:
    • 确认
      paths[0].entitySet
      中的
      entitySet
      存在于OData Schema中。
    • 确认
      queryOptions.selects
      中的每个属性都存在于实体类型中。
    • 确认
      queryOptions.filters
      中引用的每个属性(过滤表达式操作数)都存在于实体类型中。
    • 确认
      queryOptions.expands
      中的每个导航属性都存在于实体类型中。
  4. 报告不匹配项。
严重程度:
  • 实体集不存在 → 失败
  • 选择/过滤属性不存在 → 失败
  • 展开中的导航属性不存在 → 失败
  • Schema查找失败(连接不可达、Schema未加载) → 警告,并注明该文件的检查无法运行。请勿因单个连接不可达而终止整个运行——记录警告并继续。
输出示例:
[FAIL] fpds_get_material-footprintDatasource.json — entitySet 'Materials' not found in schema (did you mean 'Material'?)
[FAIL] ds_orders_grid-datasource.json — selects: property 'CustomeName' not on entity 'Orders' (typo?)
[warn] ds_legacy_thing-datasource.json — could not reach connection 'LegacyProd'; check skipped

5. Result-Shape Sync (
result-shapes
)

5. 结果结构同步(
result-shapes

Scans: all datasource files (both
*-datasource.json
and
*-footprintDatasource.json
, both OData and flow-backed).
Rule: the datasource's query-side shape (
queryOptionsObjectTypeDef
) and its consumer-facing shape (
outParams[0].objectTypeDef
) must agree. Each property on one side should have a matching entry on the other with the same
id
and the same
type
. Drift between these two declarations is the canonical "datasource works in Studio preview but breaks consumers" failure mode.
Procedure:
  1. Read
    queryOptionsObjectTypeDef.properties[]
    from the file.
  2. Read
    outParams[0].objectTypeDef.properties[]
    from the file.
  3. Pair properties by
    id
    .
  4. Flag any property on one side without a counterpart on the other, or any
    id
    pair whose
    type
    differs.
Severity:
  • Property present on one side, missing on the other → fail.
  • Property pair with mismatched
    type
    fail.
  • Property pair with matching
    id
    and
    type
    but different ordering / metadata → nit.
Output line:
[FAIL] ds_open_orders-datasource.json — `queryOptionsObjectTypeDef.OrderId` is `int32`, `outParams[0].objectTypeDef.OrderId` is `string`
[FAIL] fpds_lots-footprintDatasource.json — `outParams[0].objectTypeDef` declares property `LotCode`, missing from `queryOptionsObjectTypeDef`
扫描范围: 所有数据源文件(
*-datasource.json
*-footprintDatasource.json
,包括OData和基于流程的数据源)。
规则: 数据源的查询端结构(
queryOptionsObjectTypeDef
)和面向消费者的结构(
outParams[0].objectTypeDef
)必须一致。一侧的每个属性在另一侧都应有匹配的条目,且
id
type
都相同。这两个声明之间的偏离是典型的"数据源在Studio预览中可用但会导致消费者出错"的故障模式。
步骤:
  1. 从文件中读取
    queryOptionsObjectTypeDef.properties[]
  2. 从文件中读取
    outParams[0].objectTypeDef.properties[]
  3. id
    配对属性。
  4. 标记一侧存在但另一侧不存在的属性,或
    id
    配对但
    type
    不同的情况。
严重程度:
  • 属性仅存在于一侧 → 失败
  • 属性配对但
    type
    不匹配 → 失败
  • 属性配对且
    id
    type
    匹配但顺序/元数据不同 → 细节问题
输出示例:
[FAIL] ds_open_orders-datasource.json — `queryOptionsObjectTypeDef.OrderId` is `int32`, `outParams[0].objectTypeDef.OrderId` is `string`
[FAIL] fpds_lots-footprintDatasource.json — `outParams[0].objectTypeDef` declares property `LotCode`, missing from `queryOptionsObjectTypeDef`

Output Format

输出格式

Group findings by check type, in the order of the five checks above. Within each group, list failures first, then warnings, then nits. Pass-lines are optional — include them when the caller asked for a verbose run, omit them when the run is the default lint summary. Always end with a one-line summary.
undefined
按上述5项检查的顺序,将发现的问题按检查类型分组。在每个组内,先列出失败项,再列出警告项,最后列出细节问题。通过项为可选——当调用者要求详细运行时包含,默认代码检查摘要时省略。结尾必须添加一行摘要。
undefined

1. Description Validation

1. Description Validation

[FAIL] my_action-footprintFlow.json — description is null [FAIL] orders_grid-grid.json — description is 137 chars (cap is 100) [pass] i_awi_configuration-customType.json — "Allocation config interface" (35 chars) ...
[FAIL] my_action-footprintFlow.json — description is null [FAIL] orders_grid-grid.json — description is 137 chars (cap is 100) [pass] i_awi_configuration-customType.json — "Allocation config interface" (35 chars) ...

2. Schema-Code Alignment

2. Schema-Code Alignment

[FAIL] commit_allocation_plan_action — code references $flow.inParams.foo but 'foo' is not declared in inParams [warn] plan_inventory_consumption_action — inParam 'unused_param' declared but not referenced
[FAIL] commit_allocation_plan_action — code references $flow.inParams.foo but 'foo' is not declared in inParams [warn] plan_inventory_consumption_action — inParam 'unused_param' declared but not referenced

3. Type Resolution

3. Type Resolution

[FAIL] orders_grid-grid.json — references
Allocations.i_unknown_type
, no i_unknown_type-customType.json found
[FAIL] orders_grid-grid.json — references
Allocations.i_unknown_type
, no i_unknown_type-customType.json found

4. OData Schema Pre-Flight

4. OData Schema Pre-Flight

[FAIL] fpds_get_material-footprintDatasource.json — entitySet 'Materials' not found (did you mean 'Material'?) [warn] ds_legacy_thing-datasource.json — could not reach connection 'LegacyProd'; check skipped
[FAIL] fpds_get_material-footprintDatasource.json — entitySet 'Materials' not found (did you mean 'Material'?) [warn] ds_legacy_thing-datasource.json — could not reach connection 'LegacyProd'; check skipped

5. Result-Shape Sync

5. Result-Shape Sync

[FAIL] ds_open_orders-datasource.json —
OrderId
type drift: query=int32, outParams=string
[FAIL] ds_open_orders-datasource.json —
OrderId
type drift: query=int32, outParams=string

Summary

Summary

files checked: 142 passes: 128 warnings: 7 failures: 7 scope: all

If a check ran with no findings, write `(no issues)` under that heading rather than omitting it — explicit emptiness is more legible than silent absence.
files checked: 142 passes: 128 warnings: 7 failures: 7 scope: all

如果某项检查未发现问题,请在该标题下写入`(no issues)`,而非省略——明确说明无问题比静默缺失更清晰。

Rules

规则

  • Read-only. Do not modify any files. Do not auto-fix. Do not run mutating
    dxs
    commands. The validator's job is to report; the parent (or the user) decides what to do.
  • Punch-list, not rewrite. Findings are one-line citations with file path and a brief evidence line. Do not include long code suggestions or proposed JSON. If a fix is non-obvious, name the matching creator skill that owns the fix (e.g. "route to
    datasource-creator
    "), not the fix itself.
  • Delegate OData schema to
    schema-explorer
    .
    Never load raw OData metadata into the parent context. This is the single biggest context-poisoning anti-pattern in Datex Studio work.
  • Heuristic checks may warn, not fail. Schema-code alignment in particular is a string-match lint, not a compiler. Use
    warning
    for "may be real" and
    fail
    only when the evidence is unambiguous.
  • Scope discipline. When the caller scopes to a check name, run only that check. When they scope to a subtree, walk only that subtree. Do not expand scope on your own initiative.
  • Don't speculate about intent. If a violation could be deliberate (a kept-around
    inParam
    for external wiring, an
    outParams
    declared wider than the query for a future-proofing reason), flag it as a warning with a note — not as a failure.
  • One run per invocation. Don't loop the validator until "clean." Surface the punch-list and let the parent decide whether to iterate.
  • Branch is the source of truth. Enumerate and export configs from the branch via
    dxs source explore configs
    /
    dxs source document build
    . Never read a local
    src/
    checkout as authoritative.
  • No writes to the branch, no fix patches. The only local artifact is the throwaway
    dxs source document build
    temp export, which the checks read and which you delete when done. The report itself is returned in the response body — no
    references/
    , log, or patch files.
  • 只读。 请勿修改任何文件。请勿自动修复。请勿运行会改变状态的
    dxs
    命令。验证工具的职责是报告问题;由用户(或调用者)决定如何处理。
  • 问题清单,而非重写。 发现的问题应为一行引用,包含文件路径和简短证据说明。请勿包含冗长的代码建议或JSON修改方案。如果修复方案不明确,请指明负责修复的创建者工具(例如"路由到
    datasource-creator
    "),而非直接给出修复内容。
  • 将OData Schema委托给
    schema-explorer
    切勿将原始OData元数据加载到父上下文。这是Datex Studio工作中最主要的上下文污染反模式。
  • 启发式检查可警告,不可直接判定失败。 尤其是Schema-代码对齐,这是字符串匹配式代码检查,而非编译器。对"可能真实"的问题使用
    warning
    ,仅在证据明确时使用
    fail
  • 范围约束。 当调用者指定检查名称时,仅运行该检查。当指定子树范围时,仅遍历该子树。请勿自行扩大范围。
  • 请勿推测意图。 如果违规可能是故意的(例如保留用于外部连线的
    inParam
    、为未来兼容而声明比查询更宽泛的
    outParams
    ),请将其标记为警告并附带说明——而非判定为失败。
  • 每次调用运行一次。 请勿循环运行验证工具直到"无问题"。展示问题清单,由用户决定是否迭代。
  • 分支是唯一可信来源。 通过
    dxs source explore configs
    /
    dxs source document build
    从分支枚举并导出配置。切勿将本地
    src/
    检出目录视为可信来源。
  • 不得写入分支,不得生成修复补丁。 唯一的本地产物是临时的
    dxs source document build
    导出内容,供检查读取,完成后删除。报告本身在响应体中返回——无需生成
    references/
    、日志或补丁文件。",