mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-06 16:16:44 +08:00
fix(ai-first-config): 收口开放对象评审跟进
- 修复 Runtime、Generator 与 Tooling 中开放对象关键字校验的不可达 additionalProperties 分支 - 补充 Tooling 对 additionalProperties false 的正向回归测试 - 更新游戏配置接入文档与 ai-plan 跟踪,记录 PR #325 的核验结论和验证结果
This commit is contained in:
parent
cb6dd8a510
commit
f776d09f68
@ -966,13 +966,6 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(keywordName, "additionalProperties", StringComparison.Ordinal) &&
|
|
||||||
element.TryGetProperty("additionalProperties", out var additionalPropertiesElement) &&
|
|
||||||
additionalPropertiesElement.ValueKind == JsonValueKind.False)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
diagnostic = Diagnostic.Create(
|
diagnostic = Diagnostic.Create(
|
||||||
ConfigSchemaDiagnostics.UnsupportedOpenObjectKeyword,
|
ConfigSchemaDiagnostics.UnsupportedOpenObjectKeyword,
|
||||||
CreateFileLocation(filePath),
|
CreateFileLocation(filePath),
|
||||||
|
|||||||
@ -392,13 +392,6 @@ internal static partial class YamlConfigSchemaValidator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(keywordName, "additionalProperties", StringComparison.Ordinal) &&
|
|
||||||
element.TryGetProperty("additionalProperties", out var additionalPropertiesElement) &&
|
|
||||||
additionalPropertiesElement.ValueKind == JsonValueKind.False)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw ConfigLoadExceptionFactory.Create(
|
throw ConfigLoadExceptionFactory.Create(
|
||||||
ConfigLoadFailureKind.SchemaUnsupported,
|
ConfigLoadFailureKind.SchemaUnsupported,
|
||||||
tableName,
|
tableName,
|
||||||
|
|||||||
@ -93,6 +93,7 @@
|
|||||||
- active 跟踪文件只保留当前恢复点、当前状态和下一步,不再重复堆积已完成阶段的完整历史
|
- active 跟踪文件只保留当前恢复点、当前状态和下一步,不再重复堆积已完成阶段的完整历史
|
||||||
- 最近验证摘要:`2026-04-30` 已完成 Tooling / Docs reader-facing 收口与工具 parser 边界收紧,详细命令、批次背景与验证结果保留在 trace 的 `2026-04-30` 分阶段记录中
|
- 最近验证摘要:`2026-04-30` 已完成 Tooling / Docs reader-facing 收口与工具 parser 边界收紧,详细命令、批次背景与验证结果保留在 trace 的 `2026-04-30` 分阶段记录中
|
||||||
- 最近验证摘要:`2026-05-06` 已完成开放对象关键字边界收口;Runtime / Generator / Tooling 现统一拒绝 `patternProperties`、`propertyNames`、`unevaluatedProperties`,并保留 `additionalProperties: false` 作为唯一共享闭合对象入口;详细命令与批次背景保留在 trace 的 `2026-05-06` 记录中
|
- 最近验证摘要:`2026-05-06` 已完成开放对象关键字边界收口;Runtime / Generator / Tooling 现统一拒绝 `patternProperties`、`propertyNames`、`unevaluatedProperties`,并保留 `additionalProperties: false` 作为唯一共享闭合对象入口;详细命令与批次背景保留在 trace 的 `2026-05-06` 记录中
|
||||||
|
- 最近验证摘要:`2026-05-06` 已按 PR `#325` latest review follow-up 移除三端开放对象校验中的不可达 `additionalProperties: false` 放行分支,补齐 Tooling 正向回归,并同步拆分 reader-facing docs 对开放对象边界的表述;细节与验证命令保留在 trace 的 `2026-05-06` 追加记录中
|
||||||
- PR `#306` follow-up 摘要:已按 latest open review threads 补齐 Generator `anyOf` 对称回归、Tooling schema type 白名单、object-array 直系收集边界,以及 reader-facing docs 的显式 `additionalProperties: false` / adoption guidance 说明;细节和验证命令保留在 trace 的 `2026-04-30` 新增阶段记录中
|
- PR `#306` follow-up 摘要:已按 latest open review threads 补齐 Generator `anyOf` 对称回归、Tooling schema type 白名单、object-array 直系收集边界,以及 reader-facing docs 的显式 `additionalProperties: false` / adoption guidance 说明;细节和验证命令保留在 trace 的 `2026-04-30` 新增阶段记录中
|
||||||
- PR review 跟进指针:当前分支的 latest review follow-up 与后续本地核验结论以 `ai-first-config-system-trace.md` 为准,active tracking 不再重复展开逐条命令历史
|
- PR review 跟进指针:当前分支的 latest review follow-up 与后续本地核验结论以 `ai-first-config-system-trace.md` 为准,active tracking 不再重复展开逐条命令历史
|
||||||
|
|
||||||
|
|||||||
@ -280,3 +280,47 @@
|
|||||||
1. 继续盘点下一批不会改变生成类型形状、也不会重新打开对象形状的共享关键字
|
1. 继续盘点下一批不会改变生成类型形状、也不会重新打开对象形状的共享关键字
|
||||||
2. Tooling / Docs 如继续并发推进,优先补真实采用示例,不再重复扩写开放对象边界清单
|
2. Tooling / Docs 如继续并发推进,优先补真实采用示例,不再重复扩写开放对象边界清单
|
||||||
3. 若后续 batch 再触碰 schema contract,继续保持 Runtime / Generator / Tooling 三端同步失败语义与 reader-facing docs 一致
|
3. 若后续 batch 再触碰 schema contract,继续保持 Runtime / Generator / Tooling 三端同步失败语义与 reader-facing docs 一致
|
||||||
|
|
||||||
|
### 阶段:PR #325 latest review follow-up 收口(AI-FIRST-CONFIG-RP-003)
|
||||||
|
|
||||||
|
- 已使用 `gframework-pr-review` 抓取并复核 PR `#325` 的 latest review body、未解决 latest-head 线程、MegaLinter 摘要与测试报告
|
||||||
|
- 本轮按“仅修复本地仍成立项”收口 5 条 review 信号:
|
||||||
|
- Runtime / Generator / Tooling 三端均移除开放对象关键字校验中的不可达 `additionalProperties: false` 放行分支
|
||||||
|
- Tooling 测试补齐 `additionalProperties: false` 的正向回归,避免共享允许边界后续回退
|
||||||
|
- `docs/zh-CN/game/index.md` 将开放对象边界说明拆成并列语句,避免把 `patternProperties` / `propertyNames` / `unevaluatedProperties` 误读成 `additionalProperties` 的变体
|
||||||
|
- 本轮没有跟进 stale 信号:
|
||||||
|
- PR 当前 failed checks 为 `0`
|
||||||
|
- latest test report 为 `2280 passed / 0 failed`
|
||||||
|
- MegaLinter 仅保留 `dotnet-format` 摘要噪音,未提供需要额外修复的新代码格式差异
|
||||||
|
|
||||||
|
### 验证
|
||||||
|
|
||||||
|
- 2026-05-06:`python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --json-output /tmp/gframework-current-pr-review.json`
|
||||||
|
- 结果:通过
|
||||||
|
- 备注:确认 PR `#325` 仍有 3 条 CodeRabbit nitpick 与 2 条 Greptile open threads,需要本地核验
|
||||||
|
- 2026-05-06:`node --test ./test/*.test.js`(`tools/gframework-config-tool`)
|
||||||
|
- 结果:通过(134 tests)
|
||||||
|
- 备注:新增 `additionalProperties: false` 正向回归后,工具端继续显式接受唯一共享闭合对象入口
|
||||||
|
- 2026-05-06:`dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderAllOfTests"`
|
||||||
|
- 结果:通过(18 tests)
|
||||||
|
- 备注:运行时开放对象关键字回归保持通过,未引入额外诊断路径漂移
|
||||||
|
- 2026-05-06:`dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~SchemaConfigGeneratorTests"`
|
||||||
|
- 结果:通过(57 tests)
|
||||||
|
- 备注:生成器开放对象关键字诊断回归保持通过,移除不可达分支未影响既有诊断契约
|
||||||
|
- 2026-05-06:`dotnet build GFramework.Game/GFramework.Game.csproj -c Release`
|
||||||
|
- 结果:通过(0 warnings, 0 errors)
|
||||||
|
- 2026-05-06:`dotnet build GFramework.Game.SourceGenerators/GFramework.Game.SourceGenerators.csproj -c Release`
|
||||||
|
- 结果:通过(0 warnings, 0 errors)
|
||||||
|
- 2026-05-06:`python3 scripts/license-header.py --check`
|
||||||
|
- 结果:环境受限
|
||||||
|
- 备注:仓库脚本默认通过 `git ls-files` 枚举文件,在当前 WSL worktree 绑定下返回 `128`;已改为对受影响文件执行 targeted check 并通过
|
||||||
|
- 2026-05-06:`python3 scripts/license-header.py --check --paths GFramework.Game/Config/YamlConfigSchemaValidator.cs GFramework.Game.SourceGenerators/Config/SchemaConfigGenerator.cs tools/gframework-config-tool/src/configValidation.js tools/gframework-config-tool/test/configValidation.test.js`
|
||||||
|
- 结果:通过
|
||||||
|
- 2026-05-06:`git diff --check`
|
||||||
|
- 结果:通过
|
||||||
|
|
||||||
|
### 下一步
|
||||||
|
|
||||||
|
1. 执行本轮受影响 Tooling / Runtime / Generator 定向验证,并确认没有新增 warning 或格式漂移
|
||||||
|
2. 若验证通过,重新抓取 PR `#325` review 状态,区分哪些 open threads 会随推送自动折叠
|
||||||
|
3. 继续把 PR review follow-up 约束在“latest unresolved thread + 本地仍成立问题”,不回头追旧 summary 噪音
|
||||||
|
|||||||
@ -86,8 +86,7 @@ IStorage storage = new FileStorage("GameData", serializer);
|
|||||||
这条工作流的正式契约,以 `GFramework.Game` Runtime 和 `GFramework.Game.SourceGenerators` 当前共享支持的 schema
|
这条工作流的正式契约,以 `GFramework.Game` Runtime 和 `GFramework.Game.SourceGenerators` 当前共享支持的 schema
|
||||||
子集为准。`VS Code` 配置工具主要负责编辑期提示和表单辅助,不单独扩展运行时可接受的 schema 形状。
|
子集为准。`VS Code` 配置工具主要负责编辑期提示和表单辅助,不单独扩展运行时可接受的 schema 形状。
|
||||||
|
|
||||||
开始接入时,建议先把 schema 约束控制在共享子集内,并尽早确认像 `additionalProperties: false`(需显式设置为 `false`;省略或 `true` 视为非 `false`,`patternProperties` / `propertyNames` / `unevaluatedProperties` 也不属于共享子集)这类已收口的对象边界,以及
|
开始接入时,建议先把 schema 约束控制在共享子集内,并尽早确认像 `additionalProperties: false` 这类已收口的对象边界:它必须显式设置为 `false`,省略或 `true` 都视为非 `false`。`patternProperties` / `propertyNames` / `unevaluatedProperties` 当前也不属于共享子集。`oneOf` / `anyOf` 当前会被直接拒绝,而不是在工具里看起来“可以先写”。如果你的配置模型需要更深层的嵌套数组、联合分支或其他超出共享子集的复杂
|
||||||
`oneOf` / `anyOf` 当前会被直接拒绝,而不是在工具里看起来“可以先写”。如果你的配置模型需要更深层的嵌套数组、联合分支或其他超出共享子集的复杂
|
|
||||||
shape,优先回到 raw YAML 和 schema 设计本体处理,再决定是否拆分结构或调整约束方式。
|
shape,优先回到 raw YAML 和 schema 设计本体处理,再决定是否拆分结构或调整约束方式。
|
||||||
|
|
||||||
完整约定见:
|
完整约定见:
|
||||||
|
|||||||
@ -1285,10 +1285,6 @@ function validateUnsupportedOpenObjectKeyword(schemaNode, displayPath) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unsupportedKeyword === "additionalProperties" && schemaNode.additionalProperties === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Schema property '${displayPath}' uses unsupported '${unsupportedKeyword}' metadata. ` +
|
`Schema property '${displayPath}' uses unsupported '${unsupportedKeyword}' metadata. ` +
|
||||||
"The current config schema subset only accepts 'additionalProperties: false' and rejects keywords that reopen object shapes so fields remain closed and strongly typed.");
|
"The current config schema subset only accepts 'additionalProperties: false' and rejects keywords that reopen object shapes so fields remain closed and strongly typed.");
|
||||||
|
|||||||
@ -228,6 +228,23 @@ test("parseSchemaContent should reject unsupported additionalProperties forms",
|
|||||||
/unsupported 'additionalProperties' metadata/u);
|
/unsupported 'additionalProperties' metadata/u);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("parseSchemaContent should allow explicit additionalProperties false", () => {
|
||||||
|
assert.doesNotThrow(() => parseSchemaContent(`
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"reward": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"itemCount": { "type": "integer" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`));
|
||||||
|
});
|
||||||
|
|
||||||
test("parseSchemaContent should reject unsupported open-object keywords", () => {
|
test("parseSchemaContent should reject unsupported open-object keywords", () => {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => parseSchemaContent(`
|
() => parseSchemaContent(`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user