Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
006b669
fix(editor): refresh ID-bound resources and rebase variant buffers
StarryXYJ Oct 24, 2026
49e2713
feat(diagnostics): add opt-in CPU startup benchmarks
StarryXYJ Oct 24, 2026
1c53bc2
feat(editor): refine authoring panels and preserve editing state
StarryXYJ Oct 24, 2026
828bf9f
feat(diagnostics): compare fixed startup builds in alternating pairs
StarryXYJ Oct 25, 2026
4bb1dbc
perf(editor): prepare welcome page before first window layout
StarryXYJ Oct 25, 2026
9597a00
docs(editor): record startup experiments and rejected tuning
StarryXYJ Oct 25, 2026
a15140a
feat(diagnostics): correlate startup phases with runtime traces
StarryXYJ Oct 25, 2026
aec2783
perf: add contract-safe ReadyToRun desktop publish profiles
StarryXYJ Oct 25, 2026
e54b147
feat(diagnostics): profile native desktop startup stacks
StarryXYJ Oct 25, 2026
2ae47ee
perf(editor): overlap startup data preparation with platform setup
StarryXYJ Oct 25, 2026
42f8e0c
1
StarryXYJ Oct 25, 2026
e4df266
Simplify image variants inspector and infer dimension structure
StarryXYJ Oct 25, 2026
c61dcae
feat(editor): streamline localization editing and language management
StarryXYJ Oct 25, 2026
d4376d5
Refine variants inspector empty selection and localized dimensions
StarryXYJ Oct 25, 2026
c3ddda1
fix(editor): align localization columns and defer cell commits
StarryXYJ Oct 25, 2026
47dfcef
external agent adaption
StarryXYJ Oct 25, 2026
570617a
Add release packaging and expanded sample exports
StarryXYJ Oct 25, 2026
1496e0c
refactor(editor): publish committed Group author changes
StarryXYJ Oct 26, 2026
ce3f419
feat(editor): unify scene reference semantics and entry impact review
StarryXYJ Oct 26, 2026
0d44874
feat(editor): preserve entry move identities and archive detached inputs
StarryXYJ Oct 26, 2026
f99f855
refactor(runtime): simplify engine contracts and lifecycle
Oct 26, 2026
62deb3d
perf(editor): scope scene query leases and reuse bounded Group prefixes
StarryXYJ Oct 26, 2026
76753fc
refactor(runtime): move execution contracts into core
Oct 26, 2026
2a5c678
clean
Oct 26, 2026
7d5391d
feat(editor): complete Group presentation and input lifecycle coordin…
StarryXYJ Oct 26, 2026
669b586
refactor(runtime): decouple module options from player settings
Oct 26, 2026
e9e631b
Merge remote-tracking branch 'origin/dev' into dev
Oct 26, 2026
0c51c23
feat(audio): support developer-defined groups and track mixing
Oct 26, 2026
5a08d4f
refactor(editor): keep variable declarations solely in graph
Oct 26, 2026
caada23
bugfix
Oct 26, 2026
2a92fb6
fix(editor): parse language labels after filtering suggestions
Oct 26, 2026
1228f94
refactor(config): separate project sections from default settings
Oct 26, 2026
6218d5f
refactor(config): remove unused DTO paths and duplicate processing
Oct 26, 2026
b87297f
refactor(editor): remove embedded preview and clarify editing boundaries
Oct 26, 2026
3d37f50
refactor(config): generalize project edits and validate publishing
Oct 26, 2026
ac80aa5
refactor(config): use schema forms and explicit host projections
Oct 26, 2026
469a4ba
refactor(core): move scene and audio domains into optional builtins
Oct 26, 2026
7d48cfd
refactor(core): move content domains and select asset policies explic…
Oct 26, 2026
2abd70b
refactor(parameters): keep one entry schema and share effect validation
Oct 26, 2026
7da84d2
refactor(runtime): share dispatch cleanup and reuse seek snapshot
Oct 26, 2026
0c436b4
refactor(editor): share graph connection validation
Oct 26, 2026
137de6e
refactor(core): finish composition and native lifecycle verification
Oct 26, 2026
06695e0
refactor(compilation): reuse group validation output
Oct 26, 2026
a88f100
refactor(json): avoid redundant parsing at content boundaries
Oct 26, 2026
471934d
refactor(parameters): decode typed invocation fields during normaliza…
Oct 26, 2026
471b75e
refactor(export): prepare staged content once for both outputs
Oct 26, 2026
f92261b
refactor(io): share physical path checks across content tools
Oct 26, 2026
08de145
refactor(storage): share cancellable file replacement writes
Oct 26, 2026
5fe17e6
sample优化,可配置
Oct 26, 2026
c2f9eb7
feat(audio): reapply playback completion and editor fields on current…
StarryXYJ Oct 26, 2026
26a27ef
Simplify Group edits and refresh reference diagnostics automatically
StarryXYJ Oct 26, 2026
398f2cb
feat(visuals): seed default projects with shader assets and bindings
StarryXYJ Oct 26, 2026
f8d33f4
feat(rendering): bind live layer depth and leased shader textures
StarryXYJ Oct 26, 2026
882af07
feat(visuals): compile shader transitions and performance presets
StarryXYJ Oct 26, 2026
5586724
feat(visuals): deliver installer showcase and authoring documentation
StarryXYJ Oct 26, 2026
7cb7fe7
feat(editor): edit shader effect parameters in Inspector
Oct 27, 2026
0690d51
Add fixed shader vector inputs and hide built-in effect id
Oct 27, 2026
62aabe5
Preview effect shaders in entry inspector
Oct 27, 2026
f3c1965
feat(audio): add PCM mixer backend and effect authoring design
Oct 27, 2026
0818aab
Dock shader preview at inspector bottom
Oct 27, 2026
81a67e8
feat(visuals): sustain presets and await complete stop cleanup
Oct 27, 2026
799af93
feat(audio): add effect parameters and editor authoring
Oct 27, 2026
eb91ee1
Expand preset shader and transform inspector fields
Oct 27, 2026
84acffd
Use one scene target per shake and impact preset
Oct 27, 2026
f30f23c
align
Oct 27, 2026
35ee92e
group编辑器优化
Oct 27, 2026
abf9271
bugfix
Oct 27, 2026
cda2172
Make Sample game debugging a build-time capability
Oct 27, 2026
1ec644f
Support packaged PAK streams and host-owned media cache roots
Oct 27, 2026
0ef7946
Prepare portable media backends and device lifecycle adapters
Oct 27, 2026
1ae2ed1
Select complete MSVC toolsets for ARM64 native audio builds
Oct 27, 2026
ea4cc21
元数据优化
Oct 27, 2026
e12dc0f
Refine timeline panel layout and resizable sections
Oct 27, 2026
16ae052
Support NativeAOT engine backends with generated JSON contracts
Oct 27, 2026
08fc7a3
Fix recursive analysis for shader parameters and timelines
Oct 27, 2026
2f42071
Improve editor entry and timeline authoring
Oct 27, 2026
88c12e7
Fix reproducible local CI and sample contract regressions
StarryXYJ Oct 27, 2026
4cbf06c
Add locally validated NuGet bundles and Windows R2R release pipeline
StarryXYJ Oct 27, 2026
2f64e42
Reduce Windows release payload and verify compiled game content
StarryXYJ Oct 27, 2026
bea00e1
Stabilize cold atlas preparation test before first release
StarryXYJ Oct 27, 2026
7420401
Record successful first cloud prerelease
StarryXYJ Oct 27, 2026
a3ae72b
feat(assets): add dependency metadata and typed PAK contracts
StarryXYJ Oct 28, 2026
c734b9f
feat(release): share runtime and prepare Sample for AOT
StarryXYJ Oct 28, 2026
a7f0896
feat(content): address single graph resources and initialize chapter …
StarryXYJ Oct 28, 2026
f97bca7
feat(packaging): build independent story packages from resource closures
StarryXYJ Oct 28, 2026
5b2c1a7
feat(assets): export independent resource overrides and freeze effect…
StarryXYJ Oct 28, 2026
043638d
feat(editor): author story packages and resource override matrices
StarryXYJ Oct 28, 2026
2abb0c5
feat(packaging): finalize override saves and content delivery validation
StarryXYJ Oct 28, 2026
dcebf66
feat(editor): simplify resource patches and persist edits immediately
StarryXYJ Oct 28, 2026
30f8132
docs(packaging): defer streaming PAK and large-file support
StarryXYJ Oct 28, 2026
43c027d
Improve project settings and editor diagnostics
StarryXYJ Oct 28, 2026
c1e0442
gameUI
StarryXYJ Oct 29, 2026
63ec503
fix(samples): deploy fixture contracts before compiling content
Oct 29, 2026
ea5ce21
feat(sample): refine save cards audio controls and themed exit UI
Oct 29, 2026
431ac01
fix(samples): support Windows PowerShell path normalization
Oct 29, 2026
1391936
Improve sample save and screenshot responsiveness and control themes
Oct 29, 2026
86cc021
feat(packaging): organize desktop payload and default pak startup
Oct 29, 2026
f65a16c
feat(editor): select game app when creating projects
Oct 29, 2026
8808abe
Add dialogue history, transient voice replay, and read text colors
Oct 29, 2026
abeeabb
Fix history row interactions and read color confirmation localization
Oct 29, 2026
4c0b72b
pak opt
Oct 29, 2026
349047c
ci
Oct 29, 2026
049a89f
1
Oct 29, 2026
7ee7564
Refine sample exit confirmation typography and layout
Oct 29, 2026
1b8168a
Fix sample debug menu rendering and header contrast
Oct 29, 2026
028ef71
Preserve title foreground behind sample exit confirmation
Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
122 changes: 119 additions & 3 deletions .agents/agent-knowledge.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .agents/lessons/L-20260922-01-dotnet-build-sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ Codex 受限 workspace 中的 GalNet .NET/Avalonia 构建与测试。

- `features/F-20260922-01-entry-instance-runtime/phase-plan.md`
- 成功验证命令:`dotnet build test/GeneralTest/GeneralTest.csproj --no-restore -m:1 -v:minimal -p:UseSharedCompilation=false`

## 2026-10-26 补充:还原也应限制 MSBuild 并发

F-20261026-01 的 R4a 隔离还原使用默认 dotnet restore 调度时没有输出诊断即退出 1,并遗留 380 个同一父进程启动的 MSBuild /nodemode:1 /nodeReuse:true worker。具体退出根因尚未确认,不把它归因于业务代码。通过进程父 ID、命令行和启动时间确认归属后,只清理本次遗留 worker;保留用户 Editor 与其他进程。相同 locked/artifacts 参数加 --disable-parallel -m:1 /nr:false 后还原成功。还原与构建均优先使用串行、不复用节点的验证参数;命令返回 running session 时须等待实际结束,不能把一次等待超时视为结束后启动下一构建。
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@
两次 Presentation 全回归各出现一次 DisposeAsync NullReferenceException,分别发生在不同测试,产品断言均通过。Avalonia 12.0.5 的 HeadlessUnitTestSession.StartNew 在 Task.Run 回调里用闭包 task 构造会话,而外部 task 赋值尚可能未完成;DisposeAsync 等待此引用时会空引用。源码:https://github.com/AvaloniaUI/Avalonia/blob/12.0.5/src/Headless/Avalonia.Headless/HeadlessUnitTestSession.cs。

Presentation 测试改用官方 GetOrStartForAssembly 配合 AvaloniaTestApplication 特性,由框架缓存会话,测试不逐项释放缓存 worker。默认 PerTest 隔离仍使每次 Dispatch 重新建立和释放应用 scope。测试必须自己关闭窗口并释放产品资源;不能捕获并吞掉任意产品异常或用成功重试掩盖断言失败。此调整避免反复创建/释放会话,不修改第三方源码,也不声称修复其内部启动竞态。

2026-10-26 引擎重构 R4a:Editor 隔离全回归中的 TimelineKeyDetailsBatchEditInterpolationTangentsUnitsAndPresetsThroughMountedControls 在 HeadlessUnitTestSession.DisposeAsync 发生一次空引用(调用点为测试 await using 收尾)。定向 1 项与完整 Editor 323 项重跑通过,未修改 Timeline 产品代码;原日志 r4a-editor-tests.log 与重跑日志 r4a-timeline-recheck.log/r4a-editor-recheck.log 保留。该现象与上述已知竞态的失败位置一致,不把一次成功重跑表述为框架问题已修复。

2026-10-26 R6/R8:Editor 全回归再次在 CharacterNestedListFieldUsesSemanticEditorAndRenameUpdatesStoredWirePath 的 DisposeAsync 复现相同空引用,319 项通过;该用例独立复核通过。R8 将 Editor 与剩余 Integration 的 StartNew/逐项 Dispose 改为官方 GetOrStartForAssembly,复用各自既有 application builder,保留每项 Dispatch、窗口关闭与产品资源释放。不捕获该空引用、不删除功能断言;完整复核结果见 feature R8。

R8 最终完整复核:Editor 320、Integration 128 项全部通过;缓存 worker 的改动保留了普通用例的完整执行,没有跳过或捕获框架失败。
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@

适用:异步准备资源后再呈现候选的字段、Timeline 或类似选择 lease。
禁止:无条件接受等待后的当前快照;只在预热后验证选择;仅因预期的后台准备推进结果版本而永久禁用本次选择。


GC4 后续(2026-10-26):托管选择器现在按查询局部作者依赖版本和资源代次检查准备请求,允许无关作者修改保留请求;写入方上下文另有版本,详见 [查询事实与写入上下文](L-20261026-03-query-result-and-write-context.md)。原始整作者快照身份是当时的保守实现,不是永久要求全局失效。

2026-10-28 远端 CI 跟进:首次远端运行 40559879643 在上述冷图集用例的初始 Select 失败。项目/条目创作会自动 QueuePreparation,测试若在插入条目之后才设置资源 Gate,先前启动的读取仍可在查询快照与选择之间完成。测试应在创建项目/服务之前安装 Gate,并断言显式释放前 PrepareAsync 未完成,不能用机器速度推断“冷启动”。
2 changes: 2 additions & 0 deletions .agents/lessons/L-20261024-01-required-string-defaults.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
证据:CustomActionTests.Contract_rejects_invalid_arguments_before_handler_creation 初轮缺 argument 的用例失败,调整 DTO 声明后通过;显式 null 也有拒绝回归。编译入口额外断言两个字段 IsRequired、AllowNull=false、DefaultValue=null。

适用范围:可接受空串但不接受缺省/null 的 DTO 字段。不要把 Required=true 等同于“即使有默认值也必须显式提供”,也不要为了局部字段语义修改全局 Normalize 的默认值规则。关联:docs/spec/entry-types.md、docs/manual/custom-actions.md。

复现补充:F-20261026-01 引擎重构 R3 自定义音频中,将 TrackId 从固定 bgm/vocal 改为 Required 时,保留空串属性初始化值同样导致省略参数仍通过。统一改为构造函数初始化,并对全部普通音频/语音 schema 断言 DefaultValue=null、缺省/null 拒绝;不要仅改 Required 标记。
15 changes: 15 additions & 0 deletions .agents/lessons/L-20261025-01-variant-buffer-structural-rebase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 资源结构重写必须覆盖已跟踪缓冲

状态:confirmed
日期:2026-10-25
来源:资源 ID、选择器缓存与文件移动同步修复

现象:移动 `.variants` 或其图片目录时,文件事务已计算新 folder,但打开过的描述文件由 ProjectContentSession 的 ManagedContent 写出;仅修改事务备份不能改变实际写出的缓冲内容。

根因:ProjectFileOperation 的非托管 Copies 会跳过 ManagedContent;ProjectContentSession 从保存版 EditorFileDocument.Data 写出文件。原 FileChange.Apply 只移动 Path,没有对工作版和保存版的 Data 分别重基。

正确做法:在结构变更的 Apply 内根据当前文档位置和当前 folder 重算路径,分别转换工作内容与最近保存内容;验证也覆盖两份转换后的文档。Undo/Redo 从当时的配置重算,不能恢复首次捕获的整份 JSON,否则会回退之后保存的 default 或 dimensions。

验证:ResourceIdentityTests.cs 中 OpenVariantBufferRebasesFolderAndPreservesSavedAndUnsavedChanges 的描述移动/图片目录移动两例均通过,覆盖打开的 Inspector、未保存 default、磁盘保存基线、Save 后 Undo/Redo。关联规范:docs/spec/editor-files.md。

适用:文件结构操作会重写内部关系,且文件可进入项目文本缓冲的场景。禁止仅改路径/磁盘备份或以未打开文件的测试替代缓冲生命周期验证。
9 changes: 9 additions & 0 deletions .agents/lessons/L-20261025-02-benchmark-restore-graph.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 条件引用必须匹配 restore 图

状态:candidate
来源:features/F-20261025-01-cpu-startup-benchmark

现象:Benchmark=true 的 Editor 编译通过,但启动在 Main 抛 FileNotFoundException: GalNet.Diagnostics;输出目录缺 DLL,deps/assets 也不含它。
已确认的直接原因:编译器看见了条件 ProjectReference,运行时依赖清单却来自不含该引用的还原结果。工作区存在普通模式构建,无法仅凭日志断言哪次 restore 覆盖了 assets。
正确做法:切换影响依赖图的属性时允许 restore,不能用 --no-restore 证明运行时成功。Benchmark 单独使用 bin/benchmark、obj/benchmark 和独立锁文件;固定路径 Content 也必须读取同模式产物。修改 BaseIntermediateOutputPath 时继续排除整个 obj/bin,避免把另一模式生成代码编入源码。
不要只凭编译成功交付条件依赖构建;实际启动并验证 trace。不要归因于尚未证实的其他进程。
8 changes: 8 additions & 0 deletions .agents/lessons/L-20261025-03-avalonia-benchmark-exitcode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Avalonia 生命周期结束后重申 benchmark 失败退出码

状态:confirmed
来源:features/F-20261025-01-cpu-startup-benchmark

现象:Sample 初始化失败时 trace 正确记录 Startup.Failed,Complete 中也设置 Environment.ExitCode=1,但关闭窗口后子进程仍返回 0。脚本通过检查 Ready 缺失才拒绝了该运行。
修正:StartupBenchmark 保留 Failed 状态,宿主在 StartWithClassicDesktopLifetime 返回后的 finally 中重申退出码。无效游戏内容的最终集成检查确认进程返回 1,失败 trace 保留,脚本不生成成功摘要。
规则:不要依赖窗口仍运行时设置的 Environment.ExitCode;桌面宿主可能在生命周期结束时覆盖它。脚本同时验证退出码和协议完成标记,不能仅以其中之一判断成功。
15 changes: 15 additions & 0 deletions .agents/lessons/L-20261025-04-character-name-key-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 姓名文本 key 不能替代角色身份

状态:confirmed
日期:2026-10-25
来源:features/F-20261023-01-editor-uiux/phase-ui-20261025.md

现象:若角色草稿和选择只按 DisplayNameKey 缓存,两个共享姓名文本的角色会互相取得草稿;删除一个角色后还可能选中另一个角色。

根因:CharacterCatalog 只校验角色 ID 唯一,允许多个角色使用同一 DisplayNameKey。GUI 新建默认生成不同姓名文本 key,不代表所有合法作者数据都具有该唯一性。

验证:源码 CharacterCatalog 的唯一约束与 CharactersSharingANameTextNeverShareDraftsOrAcquireADeletedCharactersSelection 回归共同覆盖;角色 ID 改名跟随与旧基线拒绝另有连续性回归。

正确做法:按角色 ID 与姓名文本 key 组合区分草稿。仅在会话中始终未出现共享的姓名文本 key 上允许推断 ID 改名;一旦出现共享,不凭文本 key 合并身份。重基缓存键时保留原声明基线,使外部修改后的提交仍接受冲突检查。

适用:角色表、引用选择、搜索投影与项目级草稿。禁止将文本 key、显示名或行号当作普遍唯一的作者对象身份。文本共享与作者对象身份是不同契约。
9 changes: 9 additions & 0 deletions .agents/lessons/L-20261025-05-paired-startup-baselines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# 启动优化使用固定二进制交错对照

状态:confirmed
来源:features/F-20261025-01-cpu-startup-benchmark/experiments.md

证据:同一个提前准备欢迎页的 exe 快照,在主题探测中作为基线 median 1907.65ms,在后续 Acrylic 探测中作为基线 median 1473.09ms;这段变化没有基线源码优化。前后顺序跑两批、或拿最后一次 smoke 与早期基线相比,会把缓存和机器负载漂移归功于代码。
做法:固定可运行快照和程序集 SHA256,两版各预热,再 AB/BA 配对交错,使用同一个 ready 定义;一次改变一个因素,边缘结果补反向验证,提前规定保留门槛。编译和重负载测试不与测量并行。
验证:提前准备欢迎页 20 对 median 1938.59→1834.01ms,14 对更快,行为检查通过后提交。主题与 Acrylic 探测未达门槛,逐字节恢复原 XAML。原始 trace 和 metadata 在 artifacts/benchmarks,结论保存在 feature 文档。
禁止:跨轮拼接绝对时间当作优化趋势;只凭单次最快值提交;更改 ready 定义后宣称启动变快。
18 changes: 18 additions & 0 deletions .agents/lessons/L-20261025-06-r2r-contract-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ReadyToRun 与严格契约字节身份

状态:confirmed

现象:ReadyToRun 发布会转换输入 IL 程序集;即使反射/schema 语义相同,发布 DLL 的 SHA256 也可能变化。

根因:本仓契约采用严格二进制身份,Core、Contracts.Builtins 及 GalNet.Project.Contracts 参与契约闭包;预编译是二进制重写,不能当作透明复制。

发现方式:F-20261025-01 的同源码 IL/R2R 发布对照,比较 SHA256 与 PE ManagedNativeHeaderDirectory;最终两个非 Benchmark 发布再次核对编译输入与发布输出,并实际加载 Editor 默认契约 45 项。

正确做法:PublishReadyToRun=true 时通过 PublishReadyToRunExclude 排除上述三个 DLL。必须验证实际部署字节与编译输入一致、native header 为空,并执行真实契约加载/宿主启动;其他程序集可正常 R2R。命名发布配置的 RID restore 使用隔离 bin/obj/lock,相关原则见 L-20261025-02。

适用范围:R2R 或其他会重写程序集的发布转换;新增契约闭包依赖需重新核对排除项。

禁止做法:为发布加速放宽严格契约哈希;仅检查编译通过或 schema 语义相同就宣称身份安全;把 Benchmark 与普通构建的契约哈希跨模式比较。

来源:features/F-20261025-01-cpu-startup-benchmark/runtime-profile.md。
正式操作:docs/manual/ready-to-run.md。
17 changes: 17 additions & 0 deletions .agents/lessons/L-20261025-07-traceevent-retained-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 保留 TraceEvent 迭代结果必须 Clone

状态:confirmed

现象:原生 ETL 内已收到 17 个 GalNet-CPU 标记,直接把 log.Events.Where(...).ToArray() 的事件保存后,却无法找到 Editor.RunAvalonia,或读取到后续事件的 payload。

根因:TraceEvent 迭代器复用事件对象。延后读取保留下来的引用,不能保证它仍对应当次事件。

发现方式:F-20261025-01 的 native-editor-02 无丢事件 trace;改成逐项 Clone 后,同一 ETL 成功对齐阶段并获取 383 个目标区间主线程 CPU 样本,重复分析及 Editor/Sample 实测通过。

正确做法:立即在 foreach 内消费并提取不可变字段;确实需要保存 TraceEvent(含 CallStack/EventIndex)供后续筛选时,先 Select(item => item.Clone())。当前 scripts/analyze-startup-native.cs 使用后一种方式。

适用范围:TraceEvent/TraceLog 迭代器事件的延后处理;scripts/analyze-startup-trace.cs 原有逐项消费方式不需要改成全量保留。

禁止做法:把 ToArray/ToList 当作事件快照;因延后读取失败就判定 provider 没发标记,或凭空补齐时间轴。

来源:features/F-20261025-01-cpu-startup-benchmark/parallel-native.md。
12 changes: 12 additions & 0 deletions .agents/lessons/L-20261025-08-localization-header-alignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 横向表格变窄时必须明确共用左边界

状态:confirmed
来源:features/F-20261023-01-editor-uiux/follow-up-localization-20261025.md

现象:本地化表格在所有语言显示时对齐,隐藏部分语言后表头与正文错位。真实挂载测试在隐藏中间语言后测得正文左边界 362 DIP、表头 483 DIP,相差 121 DIP。

根因:表头 Grid 指定 Width,但保持默认 HorizontalAlignment;内容宽度变得小于 ScrollViewer 视口时,表头居中,而 ListBox 显式靠左。宽表场景掩盖了差异,与单元格语言顺序无关。

修正:表头与正文都显式 HorizontalAlignment=Left,并使用同一组列宽。只验证语言数据或列数不能发现实际布局错位。

验证:I18nVisibleLanguageHeadersStayAlignedWhenTableBecomesNarrowerThanViewport 在修复前失败,修复后通过;覆盖横向滚动后隐藏中间列、仅剩源语言及恢复语言,直接比较真实表头/单元格的 X 与宽度。不要只测表格宽于视口的初始状态。
10 changes: 10 additions & 0 deletions .agents/lessons/L-20261025-09-textchanging-local-input.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 失焦提交仍需同步捕获本地输入

状态:confirmed
来源:features/F-20261023-01-editor-uiux/follow-up-localization-20261025.md

项目安装的 Avalonia 12.0.5 XML 文档明确:TextBox.TextChanged 在新文本渲染后异步发生;TextChanging 在 Text 属性更新后、渲染前同步发生。用 TextChanged 作为本地待提交模型的唯一入口,可能让紧随文字变更的 Escape 或 Save All 看到旧模型。

本地化表格改为 TextChanging 只同步单元格本地文字,不调用作者写入;失焦/Ctrl+Enter/Save All 才提交。保留 PreeditText 组合输入保护,提交失败仍保留输入,模型回填时按相等值过滤防止重入。已经送入历史的异步提交与后来新输入分开处理,Escape 只取消后者。

验证入口:I18nMountedTableCommitsOnBlurProtectsCompositionAndRetainsViewState 在 TextBox.Text 赋值后不等待渲染直接 Save All,检查保存值与焦点;另覆盖组字、Esc 和失焦提交。该挂载测试已通过;最终完整回归结果见本轮实施记录。
16 changes: 16 additions & 0 deletions .agents/lessons/L-20261025-10-empty-localization-references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 空本地化引用需要在作者索引、加载和解析边界保持一致

状态:confirmed
来源:2026-10-25 角色引用分析与空对话启动问题,用户明确要求空内容按空字符串处理;未创建独立 feature。

现象:作者索引已经忽略精确空字符串,但 GameLocalizationLoader.Require 把空 content 当成缺失 key,启动报 missing required localization key ''。同时 layer.show 的默认 transform={} 因字段声明为 JsonElement 而产生 field.opaque,阻止角色改 ID。

根因:作者引用覆盖分析与运行内容校验各自实现空值规则;没有引用的空结构也进入了无法遍历 schema 的兜底诊断。

正确做法:缺省、null、空串及纯空白引用不要求翻译;GameTextResolver 直接返回空字符串,不查询翻译来源。空 speaker 不查角色 catalog。作者索引跳过空对象/数组,未知字段和无 schema 类型只有存在非空值时才报告覆盖不完整;非空未知结构仍保留诊断。显式空译文是合法定义,不能当作缺译。

验证:LocalizationReferenceIndexTests 覆盖 layer.show 空 transform 与未知空字段;GameLocalizationLoadingTests 覆盖 dialogue.text、nvl.append 和 Choice 的空引用加载;GameTextResolverTests 验证空引用不调用来源;GameTextLocalizationTests 验证对话与 NVL 展示空文本。

适用范围:游戏本地化引用和引用分析中的空字段;不放宽角色声明的唯一身份、JSON 语法、必填字段或非空错误引用。禁止只在 UI 隐藏诊断、只修改索引却遗漏启动加载器,或把所有非空不透明字段都视为可安全重写。

关联文档:docs/spec/editor-game-localization.md、docs/spec/i18n.md。
15 changes: 15 additions & 0 deletions .agents/lessons/L-20261025-11-static-reference-warning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 静态引用扫描的正常警告不等于应用失败

状态:confirmed
日期:2026-10-25
来源:F-20261025-02-external-project-authoring / P2

现象:批量删除资源并在同一批次移除 UI JSON 引用后,ProjectApplyTests.ResourceDeletionRequiresRemainingJsonReferencesToBeUpdatedInTheSameBatch 仍返回失败。

根因:ProjectQueryService.References 始终附带 references.partial warning,说明自定义 C# 和运行表达式未被完整分析。以 diagnostics.Count != 0 判定失败,会把无剩余静态候选、但明确不完整的有效扫描也拒绝。

正确做法:应用成败按 Severity=error 和实际匹配引用判断;保留 warning,并明确 ReferencesComplete=false,不把零静态候选写成全局零引用。当前 ProjectApplyService 返回合并诊断并使用错误级别判定。

验证:修正后的 Editor.Shared 全部 417 项及最终批次/热重载 19 项通过;同批清除 UI 引用后资源删除成功,留下引用时拒绝。

适用:消费 References 或其他允许 partial/Complete=false 的查询结果。不要直接用诊断总数代替错误数量,也不要吞掉不完整性说明。
15 changes: 15 additions & 0 deletions .agents/lessons/L-20261026-01-baseline-restore-timestamps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 基线对照后恢复源码必须使增量构建失效

状态:confirmed
日期:2026-10-26
来源:F-20261015-02-editor-authoring-workspace / GC1

现象:隔离快照先成功编译新 AuthorChanges API,再替换旧服务源码重现一个基线失败。恢复备份的候选源码后,测试编译报告 UndoRedoHistory 没有 AuthorChanges;磁盘上的候选源码明明已有该成员。

根因:File.Copy 恢复了备份的旧时间戳,而基线 DLL 的生成时间更晚。MSBuild 增量检查复用了基线 DLL。源码字节恢复不等于构建图已经失效。

发现方式:gc1-baseline-character.trx 独立复现原有角色引用测试失败;随后 editor-final.log 出现 CS1061,核对恢复源码与 DLL 时序后确认不一致。对快照内候选文件显式 SetLastWriteTimeUtc 或执行 Rebuild 后才能继续验证。

正确做法:基线与候选优先使用独立源/输出目录。若复用快照进行对照,恢复候选后必须 Rebuild,或刷新所有被替换源码的时间戳并核对生成结果;验证最后核对主工作区与快照的源字节一致。不要修改主工作区源码来迎合旧 DLL。

适用:复制源码备份进行回归对照、测试旧实现、热切换隔离验证快照。不能把仅恢复文件或一次 no-build 成功当作当前候选证据。构建日志、首次失败和恢复方式留在阶段记录。
Loading
Loading