fix(ai-first-config): 收口当前 PR 审查遗留项

- 新增 anyOf 对称运行时回归测试,覆盖组合关键字拒绝分支

- 更新 Game Abstractions README 的配置系统链接显示名,避免暴露原始路径

- 精简 active tracking 的批次级验证细节并补充恢复指针

- 清理 trace 中重复日期标题,消除 MD024 风险
This commit is contained in:
gewuyou 2026-04-30 15:03:47 +08:00
parent 85f7c1707e
commit 040bcb99e4
4 changed files with 57 additions and 22 deletions

View File

@ -278,4 +278,4 @@ public sealed class ContinueGameCommandHandler
- 最常见。公共层依赖 abstractions应用层或引擎层依赖 runtime
For configuration-specific adoption decisions, treat `GFramework.Game` and
[`docs/zh-CN/game/config-system.md`](../docs/zh-CN/game/config-system.md) as the authoritative next step.
[配置系统](../docs/zh-CN/game/config-system.md) as the authoritative next step.

View File

@ -324,6 +324,60 @@ public sealed class YamlConfigLoaderAllOfTests
});
}
/// <summary>
/// 验证运行时会显式拒绝当前共享子集尚未支持的 <c>anyOf</c>。
/// </summary>
[Test]
public void LoadAsync_Should_Throw_When_Object_Schema_Declares_Unsupported_AnyOf()
{
CreateConfigFile(
"monster/slime.yaml",
BuildMonsterConfigYaml(
"""
itemCount: 3
"""));
CreateSchemaFile(
"schemas/monster.schema.json",
BuildMonsterSchema(
DefaultRewardPropertiesJson,
"""
[
{
"type": "object",
"required": ["itemCount"],
"properties": {
"itemCount": { "type": "integer" }
}
}
]
""",
"""
"anyOf": [
{
"type": "object",
"required": ["bonus"],
"properties": {
"bonus": { "type": "integer" }
}
}
]
"""));
var loader = CreateMonsterRewardLoader();
var registry = CreateRegistry();
var exception = Assert.ThrowsAsync<ConfigLoadException>(() => loader.LoadAsync(registry));
Assert.Multiple(() =>
{
Assert.That(exception, Is.Not.Null);
Assert.That(exception!.Diagnostic.FailureKind, Is.EqualTo(ConfigLoadFailureKind.SchemaUnsupported));
Assert.That(exception.Diagnostic.DisplayPath, Is.EqualTo("reward"));
Assert.That(exception.Message, Does.Contain("unsupported combinator keyword 'anyOf'"));
Assert.That(registry.Count, Is.EqualTo(0));
});
}
/// <summary>
/// 验证运行时接受显式声明的 <c>additionalProperties: false</c>
/// 因为这与当前闭合对象字段集语义保持一致。

View File

@ -85,21 +85,8 @@
- `2026-04-17` 之前的详细实现记录与定向验证命令已归档到历史 tracking / trace
- active 跟踪文件只保留当前恢复点、当前状态和下一步,不再重复堆积已完成阶段的完整历史
- `2026-04-20` 当前恢复点验证:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 262 --format json`:通过(`CodeRabbit outside-diff comments: 1 declared, 1 parsed``CodeRabbit nitpick comments: 2 declared, 2 parsed`
- `bun run test``tools/gframework-config-tool`通过122 tests包含条件分支坏形状回归
- `dotnet test GFramework.SourceGenerators.Tests/GFramework.SourceGenerators.Tests.csproj -c Release --filter "FullyQualifiedName~SchemaConfigGeneratorTests"`:通过
- `dotnet test GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release --filter "FullyQualifiedName~YamlConfigLoaderIfThenElseTests"`通过8 tests新增 `else without if` 运行时回归)
- `dotnet build GFramework.sln -c Release`:通过(存在仓库既有 analyzer warning无新增错误
- `2026-04-30` Tooling lane 收口验证:
- `dotnet build GFramework.sln -c Release`通过0 Warnings, 0 Errors本轮仅改 ai-plan 文件,确认没有伴随未验证的代码漂移)
- `2026-04-30` Tooling / Docs reader-facing 收口:
- `git diff --check -- docs/zh-CN/game/config-tool.md docs/zh-CN/game/config-system.md tools/gframework-config-tool/README.md ai-plan/public/ai-first-config-system/todos/ai-first-config-system-tracking.md ai-plan/public/ai-first-config-system/traces/ai-first-config-system-trace.md`:通过
- 已补齐工具能力边界、`additionalProperties: false` / `oneOf` / `anyOf` 说明、工具与 Runtime 契约关系,以及复杂 shape 的 raw YAML 回退路径
- `2026-04-30` Tooling parser 边界收紧:
- `bun run test``tools/gframework-config-tool`通过4 test files
- 已让工具侧对 `additionalProperties` 的共享边界与 Runtime / Generator 对齐,只接受 `additionalProperties: false`
- 已让数组 `items` / `contains` 子 schema 必须显式声明 object-shaped 且带 `type`,避免 tuple-array 或缺失类型的坏形状被工具侧宽松吞掉
- 最近验证摘要:`2026-04-30` 已完成 Tooling / Docs reader-facing 收口与工具 parser 边界收紧,详细命令、批次背景与验证结果保留在 trace 的 `2026-04-30` 分阶段记录中
- PR review 跟进指针:当前分支的 latest review follow-up 与后续本地核验结论以 `ai-first-config-system-trace.md` 为准active tracking 不再重复展开逐条命令历史
## 下一步

View File

@ -136,8 +136,6 @@
2. 不再重复评估 `oneOf` / `anyOf` 的 object-focused 子集,除非未来主线明确接受联合形状生成
3. 若后续关键字需要新诊断编号或文档边界说明,继续保持 Runtime / Generator / Tooling 同步收口
## 2026-04-30
### 阶段Tooling lane 收口整理AI-FIRST-CONFIG-RP-003
- 已把 Tooling / Docs 后续动作从 active 入口的主线叙述中剥离,改成 backlog 文件里的非阻塞并行 lane
@ -165,8 +163,6 @@
2. 若另开 Tooling / Docs batch先读取 `ai-first-config-system-csharp-experience-next.md` 的并行 lane再把结果摘要写回 active tracking / trace
3. 继续保持 active 入口精简,不在默认恢复文件中追加 UI 细节、治理台账或面向读者的文档草稿
## 2026-04-30
### 阶段Tooling / Docs reader-facing 边界补齐AI-FIRST-CONFIG-RP-003
- 已在 `config-tool.md``config-system.md``tools/gframework-config-tool/README.md` 明确 reader-facing 能力边界
@ -190,8 +186,6 @@
1. Tooling / Docs 后续若继续推进,优先补真实采用示例,而不是重复扩写边界清单
2. 主线代码批次继续以 Runtime / Generator / Tooling 三端共享关键字收口为中心
## 2026-04-30
### 阶段Tooling parser 坏形状拒绝收紧AI-FIRST-CONFIG-RP-003
- 已在 `tools/gframework-config-tool/src/configValidation.js` 收紧工具侧 schema parser 边界