# Single Context Priority 追踪

## 2026-05-07

### 阶段：启动并收敛实现方向（SINGLE-CONTEXT-PRIORITY-RP-001）

- 依据用户补充的运行时心智模型，确认当前 `Architecture` 更接近框架实例，`IArchitectureContext` 更接近功能入口，而不是需要并存运行的独立宿主
- 启动阶段已按仓库规则读取 `AGENTS.md`、`.ai/environment/tools.ai.yaml`、`ai-plan/public/README.md`，并在 `main` 上执行 `git pull --ff-only origin main` 后创建 `refactor/single-context-priority`
- 本轮实现决策：
  - `GameContext` 维持兼容 API，但内部收敛为单活动上下文模型；允许多个类型键指向同一上下文实例，不允许并存多个不同上下文实例
  - `MicrosoftDiContainer` 先做低风险修复：统一预冻结 `Get<T>()` / `Get(Type)` 的实例可见性规则，并把 CQRS 注册服务解析改为复用同一条实例收集路径
  - 若 `Contains<T>()` 的预冻结语义仍保持“是否已有注册”，则通过 XML 文档和测试显式记录，而不是隐含为“可立即解析”
- 本轮委托记录：
  - explorer `Noether`：梳理 `GameContext` 单活动上下文收敛的兼容风险、测试缺口和必须保留的 API 面
  - explorer `Boole`：梳理 `MicrosoftDiContainer` 预冻结查询、`Contains<T>()`、CQRS 注册依赖点的语义分叉

### 阶段：实现与验证完成（SINGLE-CONTEXT-PRIORITY-RP-001）

- 实现摘要：
  - `GameContext` 新增单活动上下文约束，`GetFirstArchitectureContext()` 改为显式返回当前活动上下文，不再依赖并发字典枚举顺序
  - `GameContext.GetByType(Type)`、`Get<T>()`、`TryGet<T>()` 增加对当前活动上下文的兼容匹配，保留按架构类型别名回查能力
  - `MicrosoftDiContainer.Get<T>()` / `Get(Type)` 的预冻结实例查询改为复用 `CollectRegisteredImplementationInstances(...)`
  - `ResolveCqrsRegistrationService()` 改为复用同一条注册阶段实例可见性路径，并把失败信息收敛为更明确的契约提示
  - `IIocContainer` XML 文档与 `docs/zh-CN/core/context.md`、`docs/zh-CN/core/rule.md`、`docs/zh-CN/source-generators/context-aware-generator.md` 已同步到“当前活动上下文 / 预冻结查询”语义
- 测试与验证：
  - `python3 scripts/license-header.py --check` 通过
  - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~GameContextTests|FullyQualifiedName~ContextProviderTests|FullyQualifiedName~ContextAwareTests|FullyQualifiedName~MicrosoftDiContainerTests|FullyQualifiedName~IocContainerLifetimeTests|FullyQualifiedName~ArchitectureInitializationPipelineTests"` 通过，`92/92` passed
  - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 通过，`0 warning / 0 error`

### 阶段：销毁闭环与文档收口完成（SINGLE-CONTEXT-PRIORITY-RP-002）

- 实现摘要：
  - `Architecture.DestroyAsync()` 新增 `finally` 解绑，确保销毁完成后自动从 `GameContext` 移除当前架构类型绑定
  - `ArchitectureLifecycleBehaviorTests` 新增销毁解绑、失败初始化后解绑、以及销毁后新 `ContextAwareBase` 实例不再回退到过期上下文的回归测试
  - `docs/zh-CN/source-generators/context-get-generator.md` 已把“多架构场景”改写为“自定义上下文来源”，收口对全局多架构并存的暗示
- 测试与验证：
  - `python3 scripts/license-header.py --check` 通过
  - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~ArchitectureLifecycleBehaviorTests|FullyQualifiedName~SyncArchitectureTests|FullyQualifiedName~AsyncArchitectureTests|FullyQualifiedName~ArchitectureInitializationPipelineTests|FullyQualifiedName~ContextAwareTests"` 通过，`32/32` passed
  - 首次并发执行 `dotnet test` 与 `dotnet build` 时出现 `bin/Release` 文件占用导致的 MSBuild copy 冲突；按仓库规则改为单独重跑直接命令后结果通过
  - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 单独重跑通过，`0 warning / 0 error`

### 当前下一步

1. 若后续要进一步彻底移除全局回退，可单独评估 `GameContext` 公开别名字典的收口策略与生成器默认 provider 的进一步简化空间

### 阶段：PR review 跟进修复（SINGLE-CONTEXT-PRIORITY-RP-003）

- Review 来源：
  - PR `#332`（`refactor/single-context-priority`）上的 CodeRabbit unresolved outside-diff / nitpick comments
  - PR `#332` 上 Greptile 的两个 latest-head open threads
- 本轮确认并接受的结论：
  - `Architecture.Destroy()` 与 `DestroyAsync()` 存在语义漂移，前者缺少 `GameContext.Unbind(GetType())` 清理，仍然会泄漏过期全局回退入口
  - `GameContext` 仅靠 `ConcurrentDictionary` + `_currentArchitectureContext` 的分离更新无法保证组合状态一致；`Bind` / `Unbind` / `Clear` 与读取路径需要统一同步边界
  - `GameContextProvider.GetContext()`、`ContextAwareBase.GetContext()`、`Architecture.DestroyAsync()` 等处的 XML 文档仍未完全反映最新生命周期语义
  - `RegisterCqrsHandlersFromAssemblies_Should_Resolve_Registration_Service_When_Registered_As_Instance` 需要从“仅不抛异常”加强为“确实注册了 handler”
- 本轮实现摘要：
  - 为 `GameContext` 新增统一临界区，保证别名字典与当前活动上下文指针的状态切换一致
  - 为 `Architecture.Destroy()` 增加 `finally` 解绑，和异步销毁路径对齐
  - 补充 `GameContextProvider`、`ContextAwareBase`、`Architecture`、`GameContext` 的 XML 文档说明
  - 新增同步 `Destroy()` 解绑回归测试，并加强 CQRS 注册断言
- 验证与环境备注：
  - `python3 scripts/license-header.py --check` 通过
  - `dotnet test GFramework.Core.Tests/GFramework.Core.Tests.csproj -c Release --filter "FullyQualifiedName~GameContextTests|FullyQualifiedName~ContextProviderTests|FullyQualifiedName~ContextAwareTests|FullyQualifiedName~ArchitectureLifecycleBehaviorTests|FullyQualifiedName~MicrosoftDiContainerTests"` 通过，`87/87` passed
  - `dotnet build GFramework.Core/GFramework.Core.csproj -c Release` 通过，`0 warning / 0 error`
  - 中途尝试把 `dotnet test` 与 `dotnet build` 并行执行时再次触发 `GFramework.Core.pdb` 占用重试；按仓库规则改为串行直跑后结果稳定通过
  - `System.Threading.Lock` 在 `net8.0` 目标下不可用，因此最终采用 `#if NET9_0_OR_GREATER` 条件锁声明，同时保留 `net8.0` 的 `object` 锁兼容实现
