refactor(repo): 重构ai-plan目录语义

- 重命名 local-plan 为 ai-plan,并收口 public 与 private 的目录语义
- 更新 AGENTS、README 与 boot skill 的恢复文档路径和安全约束
- 迁移共享 tracking 与 trace 文件到 ai-plan/public,并补充治理说明文档
This commit is contained in:
gewuyou 2026-04-19 03:18:46 +08:00
parent ce10c1f462
commit 6ab32032bc
12 changed files with 329 additions and 35 deletions

View File

@ -1,6 +1,6 @@
--- ---
name: gframework-boot name: gframework-boot
description: Repository-specific boot workflow for the GFramework repo. Use when Codex needs to start or resume work in this repository from short prompts such as "boot", "continue", "read AGENTS", or "start the next step"; when the user expects Codex to first read AGENTS.md, .ai/environment/tools.ai.yaml, and local-plan tracking files; or when Codex should assess task complexity, decide whether explorer or worker subagents are warranted, and then proceed under the repository's workflow rules. description: Repository-specific boot workflow for the GFramework repo. Use when Codex needs to start or resume work in this repository from short prompts such as "boot", "continue", "read AGENTS", or "start the next step"; when the user expects Codex to first read AGENTS.md, .ai/environment/tools.ai.yaml, and public ai-plan tracking files; or when Codex should assess task complexity, decide whether explorer or worker subagents are warranted, and then proceed under the repository's workflow rules.
--- ---
# GFramework Boot # GFramework Boot
@ -14,38 +14,41 @@ Treat `AGENTS.md` as the source of truth. Use this skill to enforce a startup se
1. Read `AGENTS.md` before choosing tools, planning edits, or delegating work. 1. Read `AGENTS.md` before choosing tools, planning edits, or delegating work.
2. Read `.ai/environment/tools.ai.yaml` to confirm the preferred local toolchain. 2. Read `.ai/environment/tools.ai.yaml` to confirm the preferred local toolchain.
3. Inspect `local-plan/todos/` and `local-plan/traces/` before asking the user for missing context. 3. Inspect `ai-plan/public/todos/` and `ai-plan/public/traces/` before asking the user for missing context.
4. Classify the task state: 4. If `ai-plan/private/<branch-or-worktree>/` exists and is relevant, treat it as private recovery context for the current worktree only and do not assume it should be committed.
5. Classify the task state:
- `new`: no matching recovery document exists, or the user is clearly starting fresh work - `new`: no matching recovery document exists, or the user is clearly starting fresh work
- `resume`: a matching todo or trace exists and the user is continuing that thread - `resume`: a matching todo or trace exists and the user is continuing that thread
- `recovery`: prior work looks partial, interrupted, or ambiguous and the next safe recovery point must be reconstructed - `recovery`: prior work looks partial, interrupted, or ambiguous and the next safe recovery point must be reconstructed
5. Choose the best matching `local-plan` artifacts: 6. Choose the best matching `ai-plan` artifacts:
- Prefer path names or headings that match the user's task wording - Prefer path names or headings that match the user's task wording
- Break ties by most recently updated trace or todo - Break ties by most recently updated trace or todo
- If ambiguity would materially change implementation, summarize the candidates and ask one concise question - If ambiguity would materially change implementation, summarize the candidates and ask one concise question
6. Classify the task complexity before deciding on subagents: 7. Classify the task complexity before deciding on subagents:
- `simple`: one concern, one file or module, no parallel discovery required - `simple`: one concern, one file or module, no parallel discovery required
- `medium`: a small number of modules, some read-only exploration helpful, critical path still easy to keep local - `medium`: a small number of modules, some read-only exploration helpful, critical path still easy to keep local
- `complex`: cross-module design, migration, large refactor, or work likely to exceed one context window - `complex`: cross-module design, migration, large refactor, or work likely to exceed one context window
7. Apply the delegation policy from `AGENTS.md`: 8. Apply the delegation policy from `AGENTS.md`:
- Keep the critical path local - Keep the critical path local
- Use `explorer` with `gpt-5.1-codex-mini` for narrow read-only questions, tracing, inventory, and comparisons - Use `explorer` with `gpt-5.1-codex-mini` for narrow read-only questions, tracing, inventory, and comparisons
- Use `worker` with `gpt-5.4` only for bounded implementation tasks with explicit ownership - Use `worker` with `gpt-5.4` only for bounded implementation tasks with explicit ownership
- Do not delegate purely for ceremony; delegate only when it materially shortens the task or controls context growth - Do not delegate purely for ceremony; delegate only when it materially shortens the task or controls context growth
8. Before editing files, tell the user what you read, how you classified the task, whether subagents will be used, and the first implementation step. 9. Before editing files, tell the user what you read, how you classified the task, whether subagents will be used, and the first implementation step.
9. Proceed with execution, validation, and documentation updates required by `AGENTS.md`. 10. Proceed with execution, validation, and documentation updates required by `AGENTS.md`.
## Task Tracking ## Task Tracking
For multi-step, cross-module, or interruption-prone work, maintain the repository recovery artifacts instead of keeping state only in chat. For multi-step, cross-module, or interruption-prone work, maintain the repository recovery artifacts instead of keeping state only in chat.
- Update the active document under `local-plan/todos/` with completed work, validation results, risks, and the next recovery point. - Update the active public document under `ai-plan/public/todos/` with completed work, validation results, risks, and the next recovery point.
- Update the matching document under `local-plan/traces/` with key decisions, delegated scope, and the immediate next step. - Update the matching public trace under `ai-plan/public/traces/` with key decisions, delegated scope, and the immediate next step.
- Keep worktree-private scratch recovery files under `ai-plan/private/` and do not treat them as commit targets.
- Never write secrets, machine-specific paths, or other sensitive environment details into any `ai-plan/**` artifact.
- If the task is clearly complex and no recovery artifact exists yet, create one before substantive edits. - If the task is clearly complex and no recovery artifact exists yet, create one before substantive edits.
## Recovery Heuristics ## Recovery Heuristics
- If the user says `next step`, `continue`, `继续`, or similar resume language, search `local-plan/` first, then classify the task as `resume` or `recovery` based on artifact clarity and continuity. - If the user says `next step`, `continue`, `继续`, or similar resume language, search the relevant `ai-plan/` artifacts first, then classify the task as `resume` or `recovery` based on artifact clarity and continuity.
- If the current branch and the newest recovery documents describe the same feature area, prefer resuming that thread. - If the current branch and the newest recovery documents describe the same feature area, prefer resuming that thread.
- If the repository state suggests in-flight work but no recovery document matches, reconstruct the safest next step from code, tests, and Git state before asking the user for clarification. - If the repository state suggests in-flight work but no recovery document matches, reconstruct the safest next step from code, tests, and Git state before asking the user for clarification.
@ -53,8 +56,8 @@ For multi-step, cross-module, or interruption-prone work, maintain the repositor
- `boot` - `boot`
- `Use $gframework-boot and continue the current task` - `Use $gframework-boot and continue the current task`
- `Read AGENTS and local-plan, then start the next step` - `Read AGENTS and public ai-plan, then start the next step`
- `继续当前任务,先看 AGENTS.md 和 local-plan` - `继续当前任务,先看 AGENTS.md 和 public ai-plan`
## References ## References

View File

@ -4,14 +4,15 @@
- `AGENTS.md` - `AGENTS.md`
- `.ai/environment/tools.ai.yaml` - `.ai/environment/tools.ai.yaml`
- `local-plan/todos/` - `ai-plan/public/todos/`
- `local-plan/traces/` - `ai-plan/public/traces/`
## Local-Plan Selection Heuristics ## AI-Plan Selection Heuristics
- Match the user's wording against todo and trace file names first. - Match the user's wording against public todo and trace file names first.
- Prefer the newest matching trace when several candidates describe the same feature area. - Prefer the newest matching trace when several candidates describe the same feature area.
- If one file records a clearer recovery point than a newer but vague file, prefer the clearer recovery point. - If one file records a clearer recovery point than a newer but vague file, prefer the clearer recovery point.
- If a matching `ai-plan/private/<branch-or-worktree>/` directory exists, use it only as private context for the current worktree.
## Complexity Defaults ## Complexity Defaults
@ -28,4 +29,4 @@
Use a short update before execution: Use a short update before execution:
`Read AGENTS.md, the environment inventory, and the relevant local-plan artifacts. This looks like a <task-state> <complexity> task. I will <delegate-or-not> and start with <first-step>.` `Read AGENTS.md, the environment inventory, and the relevant public ai-plan artifacts. This looks like a <task-state> <complexity> task. I will <delegate-or-not> and start with <first-step>.`

10
.gitignore vendored
View File

@ -14,7 +14,15 @@ opencode.json
.omc/ .omc/
docs/.omc/ docs/.omc/
docs/.vitepress/cache/ docs/.vitepress/cache/
local-plan/ ai-plan/*
!ai-plan/README.md
!ai-plan/public/
ai-plan/public/*
!ai-plan/public/todos/
!ai-plan/public/traces/
!ai-plan/public/todos/*.md
!ai-plan/public/traces/*.md
ai-plan/private/
ai-libs/ ai-libs/
# tool # tool
.venv/ .venv/

View File

@ -44,7 +44,7 @@ All AI agents and contributors must follow these rules when writing, reviewing,
`按 boot 开始``先看 AGENTS``继续当前任务`. `按 boot 开始``先看 AGENTS``继续当前任务`.
- The boot skill is a startup convenience layer, not a replacement for this document. If the skill and `AGENTS.md` - The boot skill is a startup convenience layer, not a replacement for this document. If the skill and `AGENTS.md`
diverge, follow `AGENTS.md` first and update the skill in the same change. diverge, follow `AGENTS.md` first and update the skill in the same change.
- The boot skill MUST read `AGENTS.md``.ai/environment/tools.ai.yaml` and the relevant `local-plan/` artifacts before - The boot skill MUST read `AGENTS.md``.ai/environment/tools.ai.yaml` and the relevant `ai-plan/` artifacts before
substantive execution. substantive execution.
## Subagent Usage Rules ## Subagent Usage Rules
@ -329,17 +329,28 @@ bash scripts/validate-csharp-naming.sh
### Task Tracking ### Task Tracking
- `ai-plan/` is split by intent:
- `ai-plan/public/todos/`: repository-safe recovery documents that may be committed and shared across worktrees
- `ai-plan/public/traces/`: repository-safe execution traces that may be committed and shared across worktrees
- `ai-plan/private/`: worktree-private recovery artifacts; keep these untracked and scoped to the current worktree
- Contributors MUST keep committed `ai-plan/public/**` content safe to publish in Git history.
- Never write secrets, tokens, credentials, private keys, machine usernames, home-directory paths, hostnames, IP
addresses, proprietary URLs, or other sensitive environment details into any `ai-plan/**` file.
- Never record absolute file-system paths in `ai-plan/**`; use repository-relative paths, branch names, PR numbers, or
stable document identifiers instead.
- Use `ai-plan/public/**` only for durable, handoff-safe task state. Put temporary notes, local experiments, or
worktree-specific scratch recovery data under `ai-plan/private/`.
- When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under - When working from a tracked implementation plan, contributors MUST update the corresponding tracking document under
`local-plan/todos/` in the same change. `ai-plan/public/todos/` in the same change.
- Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended - Tracking updates MUST reflect completed work, newly discovered issues, validation results, and the next recommended
recovery point. recovery point.
- Completing code changes without updating the active tracking document is considered incomplete work. - Completing code changes without updating the active tracking document is considered incomplete work.
- For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery - For any multi-step refactor, migration, or cross-module task, contributors MUST create or adopt a dedicated recovery
document under `local-plan/todos/` before making substantive code changes. document under `ai-plan/public/todos/` before making substantive code changes.
- Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next - Recovery documents MUST record the current phase, the active recovery point identifier, known risks, and the next
recommended resume step so another contributor or subagent can continue the work safely. recommended resume step so another contributor or subagent can continue the work safely.
- Contributors MUST maintain a matching execution trace under `local-plan/traces/` for complex work. The trace should - Contributors MUST maintain a matching execution trace under `ai-plan/public/traces/` for complex work. The trace
record the current date, key decisions, validation milestones, and the immediate next step. should record the current date, key decisions, validation milestones, and the immediate next step.
- When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery - When a task spans multiple commits or is likely to exceed a single agent context window, update both the recovery
document and the trace at each meaningful milestone before pausing or handing work off. document and the trace at each meaningful milestone before pausing or handing work off.
- If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in - If subagents are used on a complex task, the main agent MUST capture the delegated scope and any accepted findings in

View File

@ -133,7 +133,7 @@ GFramework.sln
1. 先阅读对应模块目录下的 `README.md` 1. 先阅读对应模块目录下的 `README.md`
2. 如果改动影响采用路径、安装方式、公共 API 或目录结构,同时更新 `docs/zh-CN/` 2. 如果改动影响采用路径、安装方式、公共 API 或目录结构,同时更新 `docs/zh-CN/`
3. 对跨模块或多阶段任务,维护 `local-plan/todos/` 与 `local-plan/traces/` 3. 对跨模块或多阶段任务,维护 `ai-plan/public/todos/` 与 `ai-plan/public/traces/`
## 许可证 ## 许可证

33
ai-plan/README.md Normal file
View File

@ -0,0 +1,33 @@
# AI Plan
`ai-plan/` stores AI task recovery artifacts for this repository, but not every file under it has the same sharing rules.
## Directory Semantics
- `public/todos/`
- Repository-safe recovery documents.
- Use these for durable task state that another contributor or worktree may need to resume safely.
- These files may be committed.
- `public/traces/`
- Repository-safe execution traces that record decisions, validation milestones, and the immediate next step.
- These files may be committed.
- `private/`
- Worktree-private recovery space.
- Use this for temporary notes, local scratch recovery points, or state that only matters in the current worktree.
- Keep this directory untracked.
## Content Rules
- Never write secrets, tokens, credentials, private keys, hostnames, IP addresses, proprietary URLs, or other sensitive data.
- Never write absolute file-system paths, home-directory paths, or machine usernames.
- Use repository-relative paths, branch names, PR numbers, recovery-point IDs, and stable document identifiers instead.
- Keep committed `public/**` content concise, handoff-safe, and understandable without machine-local context.
## Naming
- Shared recovery documents should describe the task, for example:
- `public/todos/cqrs-rewrite-migration-tracking.md`
- `public/traces/cqrs-rewrite-migration-trace.md`
- Worktree-private files should live under a folder named for the current branch or worktree, for example:
- `private/feat-cqrs-optimization/`
- `private/gframework-cqrs/`

View File

@ -0,0 +1,50 @@
# AI-Plan 治理跟踪
## 目标
收口 `ai-plan/` 的目录语义与提交边界,避免不同 worktree 的恢复文件持续膨胀并污染仓库历史。
- 为 `ai-plan/` 建立明确的目录分层
- 区分“可提交共享状态”与“工作树私有状态”
- 明确禁止写入敏感数据、绝对路径和机器本地信息
- 让 `AGENTS.md` 与 boot skill 使用同一套目录语义
## 当前恢复点
- 恢复点编号:`AI-PLAN-GOV-RP-002`
- 当前阶段:`Phase 1`
- 当前焦点:
- 已将共享恢复文档迁移到 `ai-plan/public/todos/``ai-plan/public/traces/`
- 已保留 `ai-plan/private/` 作为工作树私有空间,并通过 `.gitignore` 保持未跟踪
- 已新增 `ai-plan/README.md`,明确目录语义、命名方式和敏感信息限制
- 已同步更新 `AGENTS.md``gframework-boot`,让启动流程和 tracking 规则使用新的目录语义
- 已将目录根名从 `local-plan/` 正式收口到 `ai-plan/`,避免“本地计划”和“可共享 AI 恢复文档”语义混淆
## 已完成
- `.gitignore` 现只允许 `ai-plan/README.md``ai-plan/public/**/*.md` 被纳入版本控制
- `AGENTS.md` 已补充:
- `public/**``private/` 的职责划分
- 禁止写入敏感数据、绝对路径、主机与账号信息
- 复杂任务应更新 `ai-plan/public/**`,而不是把 worktree 私有状态直接丢进 Git
- `.codex/skills/gframework-boot/SKILL.md` 与其 `references/startup-artifacts.md` 已切换到:
- 优先读取 `ai-plan/public/**`
- 按需读取 `ai-plan/private/<branch-or-worktree>/` 作为私有上下文
- 既有共享 tracking / trace 文件已迁移到 `ai-plan/public/`
## 验证
- `find ai-plan -maxdepth 3 -type f | sort`
- 结果:通过
- 备注:当前只剩 `ai-plan/README.md``ai-plan/public/**` 进入仓库可见范围
- `rg -n "ai-plan/public/|ai-plan/private/" AGENTS.md .codex/skills/gframework-boot/SKILL.md .codex/skills/gframework-boot/references/startup-artifacts.md ai-plan/README.md .gitignore`
- 结果:通过
- 备注:新目录语义已统一到仓库规则与 boot skill
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release`
- 结果:通过
- 备注:本轮规则与文档调整未引入构建问题
## 下一步
1. 若后续需要 worktree 级恢复文件,可在 `ai-plan/private/<branch-or-worktree>/` 下建立私有目录,但仍遵守“不写敏感数据、不写绝对路径”的约束
2. 若未来再新增 skill 或仓库规则引用 `ai-plan/`,统一按 `public/**``private/` 的语义扩展,不再恢复平铺结构

View File

@ -0,0 +1,67 @@
# CQRS Cache And Docs Hardening Tracking
## Goal
Address the current CQRS follow-up issues across runtime caches, tests, and user-facing setup/integration
documentation so the repository state matches the published onboarding path and the runtime remains safe for
collectible assemblies.
## Current Recovery Point
- Recovery point: `CQRS-CACHE-DOCS-HARDENING-RP-001`
- Current phase: `Phase 2`
- Active focus:
- validation completed for the targeted CQRS test project
- the repository can resume from documentation follow-up or broader solution validation if needed
## Planned Work
- [x] Create the matching execution trace under `ai-plan/public/traces/`.
- [x] Update `README.md` quick-install guidance to include CQRS runtime packages.
- [x] Update the related Chinese setup/integration docs with CQRS runtime + source-generator wiring and a minimal
working CQRS generator example.
- [x] Replace static `ConcurrentDictionary<Assembly, ...>` / `ConcurrentDictionary<Type, ...>` CQRS caches with
weak-key caches that do not permanently root collectible assemblies or handler/message types.
- [x] Document the weak-cache thread-safety assumptions and recomputation behavior in code comments/XML docs.
- [x] Expand CQRS tests to assert that cached metadata still results in successful registration in every container.
- [x] Adapt dispatcher cache tests to the new unload-aware cache structure.
- [x] Run targeted CQRS test validation and capture the results here and in the trace.
## Validation
Executed:
```bash
dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release
dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-restore
```
Results:
- `dotnet test ... -c Release`: passed, `62` tests passed.
- `dotnet test ... -c Release --no-restore`: passed, `62` tests passed.
- The first run exposed one nullable warning in `GFramework.Cqrs/Internal/WeakKeyCache.cs`; the follow-up fixed the
`WeakTypePairCache.TryGetValue(...)` null-flow and reran the full CQRS test project cleanly.
- The CQRS doc update intentionally did not rename handler examples from `GFramework.Cqrs.Cqrs.*` to
`GFramework.Cqrs.*`, because the current public handler base types still live under the double-`Cqrs` namespace.
Instead, the docs now explain the split between message namespaces and handler namespaces explicitly.
- A later follow-up added the missing `using GFramework.Cqrs.Command;` to the handler snippet so that the block can be
copied independently, documented the private dispatch-binding types in `CqrsDispatcher`, restored the explicit
`System.Runtime.CompilerServices` import in `WeakKeyCache.cs`, and removed the `WeakTypePairCache.GetOrAdd(...)`
closure allocation by routing the secondary-key factory through a stateful overload.
- A final documentation cleanup aligned the `WeakKeyCache<TKey, TValue>.GetOrAdd(...)` XML comments with the runtime
contract by stating that `valueFactory` must not return `null`.
## Known Risks
- `ConditionalWeakTable`-based caches trade deterministic retention for unload safety, so the implementation must make
the recomputation semantics explicit and keep hot-path lookups thread-safe.
- The source-generator docs already cover multiple generator families; adding CQRS guidance must stay aligned with the
actual runtime APIs and package split.
- The existing CQRS docs mix conceptual snippets and minimal examples; changes should improve correctness without
silently inventing APIs that the current packages do not expose.
## Recommended Resume Step
1. If broader regression confidence is needed, run solution-level CQRS/Core validation next.
2. If the public CQRS handler namespaces are flattened in a future refactor, update the docs again in the same change.

View File

@ -58,8 +58,8 @@
### Phase 0工作流基础 ### Phase 0工作流基础
- [x] 在 `local-plan/todos/` 建立本任务跟踪文档 - [x] 在 `ai-plan/public/todos/` 建立本任务跟踪文档
- [x] 在 `local-plan/traces/` 建立本任务追踪文档 - [x] 在 `ai-plan/public/traces/` 建立本任务追踪文档
- [x] 将恢复点 / trace / subagent 协作规范写入 `AGENTS.md` - [x] 将恢复点 / trace / subagent 协作规范写入 `AGENTS.md`
### Phase 1本地验证链路 ### Phase 1本地验证链路
@ -128,7 +128,7 @@
### Phase 8方向修正后的收敛 ### Phase 8方向修正后的收敛
- [x] 将 `local-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 的目标边界正式改写为: - [x] 将 `ai-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 的目标边界正式改写为:
- `GFramework.Core.Abstractions -> GFramework.Cqrs.Abstractions` - `GFramework.Core.Abstractions -> GFramework.Cqrs.Abstractions`
- `GFramework.Core -> GFramework.Cqrs` - `GFramework.Core -> GFramework.Cqrs`
- `Core` 默认集成 CQRS但不依赖其细节结构 - `Core` 默认集成 CQRS但不依赖其细节结构
@ -295,7 +295,7 @@
- `GFramework.Core/Services/Modules/CqrsRuntimeModule.cs` 已新增,并由 `ServiceModuleManager` 纳入 built-in modules确保默认架构启动路径继续自动具备 CQRS runtime 与 handler 注册能力。 - `GFramework.Core/Services/Modules/CqrsRuntimeModule.cs` 已新增,并由 `ServiceModuleManager` 纳入 built-in modules确保默认架构启动路径继续自动具备 CQRS runtime 与 handler 注册能力。
- `GFramework.Core.Tests/CqrsTestRuntime.cs` 已补充裸测试容器的 CQRS seam 注册辅助,以便不经过 `ServiceModuleManager` 的单元测试继续观察正式 runtime 行为。 - `GFramework.Core.Tests/CqrsTestRuntime.cs` 已补充裸测试容器的 CQRS seam 注册辅助,以便不经过 `ServiceModuleManager` 的单元测试继续观察正式 runtime 行为。
- `GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs` 中“Clear 后重新接入 handler”回归已适配 seam 方案:在裸容器 `Clear()` 后显式补回测试基础设施,再验证程序集去重状态重置。 - `GFramework.Core.Tests/Ioc/MicrosoftDiContainerTests.cs` 中“Clear 后重新接入 handler”回归已适配 seam 方案:在裸容器 `Clear()` 后显式补回测试基础设施,再验证程序集去重状态重置。
- `local-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 已新增,完成 Phase 5 的模块边界评估、依赖倒置方案与包拆分草案输出。 - `ai-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 已新增,完成 Phase 5 的模块边界评估、依赖倒置方案与包拆分草案输出。
- Phase 5 结论已收敛为“两阶段拆分”: - Phase 5 结论已收敛为“两阶段拆分”:
- 先做 `Core -> runtime abstraction` 的 seam 改造 - 先做 `Core -> runtime abstraction` 的 seam 改造
- 再拆 `GFramework.Cqrs.Abstractions` / `GFramework.Cqrs` 项目与 public runtime 类型归属 - 再拆 `GFramework.Cqrs.Abstractions` / `GFramework.Cqrs` 项目与 public runtime 类型归属
@ -468,9 +468,9 @@
若本轮中断,优先从以下顺序恢复: 若本轮中断,优先从以下顺序恢复:
1. 查看 `local-plan/traces/cqrs-rewrite-migration-trace.md` 1. 查看 `ai-plan/public/traces/cqrs-rewrite-migration-trace.md`
2. 确认当前恢复点 `CQRS-REWRITE-RP-015` 已对应到最新提交 2. 确认当前恢复点 `CQRS-REWRITE-RP-015` 已对应到最新提交
3. 优先继续执行 `local-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 中的 Phase 7 3. 优先继续执行 `ai-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` 中的 Phase 7
- 先决定是否正式支持旧 `GFramework.Core.Abstractions.Cqrs*` / `GFramework.Core.Cqrs.Extensions` public namespace 兼容,还是明确要求消费端迁到当前 `GFramework.Cqrs*` 路径 - 先决定是否正式支持旧 `GFramework.Core.Abstractions.Cqrs*` / `GFramework.Core.Cqrs.Extensions` public namespace 兼容,还是明确要求消费端迁到当前 `GFramework.Cqrs*` 路径
- 再评估 `CqrsCoroutineExtensions` 是否保留在 `GFramework.Core`,或连同所需协程辅助一起形成更小的可迁移边界 - 再评估 `CqrsCoroutineExtensions` 是否保留在 `GFramework.Core`,或连同所需协程辅助一起形成更小的可迁移边界
4. 在 runtime 项目真正承接实现后,再处理 source-generator、meta package 与消费端 transitive 依赖的迁移 4. 在 runtime 项目真正承接实现后,再处理 source-generator、meta package 与消费端 transitive 依赖的迁移
@ -659,7 +659,7 @@
- `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release` - `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release`
- 结果:通过 - 结果:通过
- 备注:存在既有 `MA0051``MA0158` analyzer warnings无新增构建错误 - 备注:存在既有 `MA0051``MA0158` analyzer warnings无新增构建错误
- `rg -n "ai-libs/Mediator|只读|第三方项目源码副本" AGENTS.md local-plan/todos/cqrs-rewrite-migration-tracking.md local-plan/traces/cqrs-rewrite-migration-trace.md` - `rg -n "ai-libs/Mediator|只读|第三方项目源码副本" AGENTS.md ai-plan/public/todos/cqrs-rewrite-migration-tracking.md ai-plan/public/traces/cqrs-rewrite-migration-trace.md`
- 结果:通过 - 结果:通过
- 备注:`AGENTS.md`、tracking 与 trace 均已命中新规则和本地参考路径说明 - 备注:`AGENTS.md`、tracking 与 trace 均已命中新规则和本地参考路径说明

View File

@ -0,0 +1,31 @@
# AI-Plan 治理追踪
## 2026-04-19
### 阶段目录语义收口RP-002
- 建立 `AI-PLAN-GOV-RP-002` 恢复点
- 用户指出当前 `ai-plan/` 存在三个治理问题:
- 缺少更细的目录分层,容易随着 worktree 增长持续膨胀
- 缺少“不得写入敏感数据、真实路径、机器信息”的明确约束
- 目录语义没有区分共享恢复信息与 worktree 私有状态
- 已据此完成以下收口:
- 将既有共享 tracking / trace 文件迁移到 `ai-plan/public/todos/``ai-plan/public/traces/`
- 新增 `ai-plan/private/` 作为工作树私有恢复空间,并通过 `.gitignore` 保持未跟踪
- 新增 `ai-plan/README.md` 作为目录语义与内容规范的单点说明
- 在 `AGENTS.md` 中补齐 public/private 职责边界,以及敏感信息与绝对路径禁写规则
- 在 `gframework-boot` 中同步新的读取顺序:优先 public按需读取当前 worktree 私有目录
### 验证
- `find ai-plan -maxdepth 3 -type f | sort`
- 结果:通过
- `rg -n "ai-plan/public/|ai-plan/private/" AGENTS.md .codex/skills/gframework-boot/SKILL.md .codex/skills/gframework-boot/references/startup-artifacts.md ai-plan/README.md .gitignore`
- 结果:通过
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release`
- 结果:通过
### 下一步
1. 后续若出现新的 worktree 私有恢复需求,直接在 `ai-plan/private/<branch-or-worktree>/` 下创建,不再向共享目录追加本地临时状态
2. 若将来需要进一步限制格式,可再为 `public/**``private/` 各自补一个模板文件,但本轮先把目录语义和安全边界固定下来

View File

@ -0,0 +1,90 @@
# CQRS Cache And Docs Hardening Trace
## 2026-04-17
### Stage: Discovery
- Read `AGENTS.md` and `.ai/environment/tools.ai.yaml` before selecting repository tools.
- Confirmed `README.md` quick-install guidance omits `GeWuYou.GFramework.Cqrs` and
`GeWuYou.GFramework.Cqrs.Abstractions` even though the module overview recommends CQRS as a first-class module.
- Confirmed `docs/zh-CN/source-generators/index.md` lists the split CQRS generator package but does not provide a
dedicated CQRS handler-registry section with package wiring, minimal usage, or compatibility notes.
- Confirmed `GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs` has a cross-container metadata-cache test that
only asserts reflection/attribute call counts and does not prove the second container still receives registrations.
- Confirmed `GFramework.Cqrs/Internal/CqrsDispatcher.cs` and
`GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs` currently use process-wide `ConcurrentDictionary<Type, ...>` /
`ConcurrentDictionary<Assembly, ...>` caches that strongly retain collectible types and assemblies.
- Reviewed `docs/zh-CN/getting-started/installation.md` as a related setup entry page; it also omits the CQRS runtime
packages from the installation snippets.
### Current Recovery Point
- `CQRS-CACHE-DOCS-HARDENING-RP-001`
### Immediate Next Step
1. Update the tracking document and then patch the docs, runtime caches, and tests in one pass.
### Stage: Implementation
- Updated `README.md` quick-install guidance to include:
- `GeWuYou.GFramework.Cqrs`
- `GeWuYou.GFramework.Cqrs.Abstractions`
- Updated `docs/zh-CN/getting-started/installation.md` to add CQRS runtime package rows and installation snippets, and
corrected the installation verification sample to the current `GFramework.Core.Architectures` /
`OnInitialize()` / `OnInit()` API shape.
- Updated `docs/zh-CN/core/cqrs.md` to add explicit CQRS package wiring and document the current namespace split
between message base types (`GFramework.Cqrs.*`) and handler base types (`GFramework.Cqrs.Cqrs.*`).
- Updated `docs/zh-CN/source-generators/index.md` to add a dedicated `CQRS Handler Registry 生成器` section covering:
- required runtime and generator packages
- a minimal working architecture example
- compatibility and migration notes for reflection fallback vs generated registries
- Added `GFramework.Cqrs/Internal/WeakKeyCache.cs` with unload-aware weak-key cache helpers built on
`ConditionalWeakTable`.
- Replaced the CQRS runtime's process-wide strong-reference type/assembly caches with weak-key caches in:
- `GFramework.Cqrs/Internal/CqrsDispatcher.cs`
- `GFramework.Cqrs/Internal/CqrsHandlerRegistrar.cs`
- Expanded `GFramework.Cqrs.Tests/Cqrs/CqrsHandlerRegistrarTests.cs` so the cross-container metadata-cache test now
proves both containers still resolve the expected handlers after the cache is reused.
- Updated `GFramework.Cqrs.Tests/Cqrs/CqrsDispatcherCacheTests.cs` to assert cache reuse through observable cached
entries instead of assuming `ConcurrentDictionary`-specific count semantics.
- Evaluated the suggestion to change handler doc examples from `using GFramework.Cqrs.Cqrs.Command;` to
`using GFramework.Cqrs.Command;`. The repository's actual handler base types still live under
`GFramework.Cqrs.Cqrs.*`, so the implementation kept the real API and clarified the namespace split in the docs
instead of documenting a non-existent namespace.
### Stage: Validation
- Ran:
- `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release`
- Result:
- passed, `62` tests passed
- The first validation run surfaced one nullable warning in `GFramework.Cqrs/Internal/WeakKeyCache.cs` because the
nested weak cache lookup did not prove the secondary cache was non-null to the compiler.
### Stage: Validation Follow-up
- Fixed `WeakTypePairCache<TValue>.TryGetValue(...)` to guard the nested weak cache reference explicitly.
- Re-ran:
- `dotnet test GFramework.Cqrs.Tests/GFramework.Cqrs.Tests.csproj -c Release --no-restore`
- Result:
- passed, `62` tests passed
### Immediate Next Step
1. Stop at `CQRS-CACHE-DOCS-HARDENING-RP-001` unless broader solution-level validation is requested.
### Stage: Minor Follow-up
- Updated `docs/zh-CN/core/cqrs.md` again so the standalone handler snippet now imports both:
- `GFramework.Cqrs.Command`
- `GFramework.Cqrs.Cqrs.Command`
- Added XML documentation to the private nested binding types in `GFramework.Cqrs/Internal/CqrsDispatcher.cs` so the
intent of the cached service-type/delegate bundles is explicit to future maintainers.
- Restored the explicit `using System.Runtime.CompilerServices;` directive at the top of
`GFramework.Cqrs/Internal/WeakKeyCache.cs` so `ConditionalWeakTable<,>` does not rely on ambient imports.
- Added a stateful `WeakKeyCache<TKey, TValue>.GetOrAdd<TState>(...)` overload and updated
`WeakTypePairCache<TValue>.GetOrAdd(...)` to use it, removing the captured lambda allocation from the secondary-key
lookup path.
- Updated both `WeakKeyCache<TKey, TValue>.GetOrAdd(...)` XML comments to state the full contract:
`valueFactory` itself must be non-null, and it must not produce a null cache value.

View File

@ -541,7 +541,7 @@
### 阶段CQRS 模块边界评估 ### 阶段CQRS 模块边界评估
- 建立 `CQRS-REWRITE-RP-010` 恢复点 - 建立 `CQRS-REWRITE-RP-010` 恢复点
- 已完成 Phase 5 的模块边界再评估,并新增 `local-plan/migration/CQRS_MODULE_SPLIT_PLAN.md` - 已完成 Phase 5 的模块边界再评估,并新增 `ai-plan/migration/CQRS_MODULE_SPLIT_PLAN.md`
- 本轮结论: - 本轮结论:
- 将 CQRS 拆为独立 abstractions/runtime 模块是成立的 - 将 CQRS 拆为独立 abstractions/runtime 模块是成立的
- 但当前不能直接做“搬项目”式拆分,必须先完成 `GFramework.Core -> CQRS runtime abstraction` 的依赖倒置 - 但当前不能直接做“搬项目”式拆分,必须先完成 `GFramework.Core -> CQRS runtime abstraction` 的依赖倒置
@ -1327,7 +1327,7 @@
- `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release` - `dotnet build GFramework.Cqrs/GFramework.Cqrs.csproj -c Release`
- 结果:通过 - 结果:通过
- 备注:存在既有 `MA0051``MA0158` analyzer warnings无新增构建错误 - 备注:存在既有 `MA0051``MA0158` analyzer warnings无新增构建错误
- `rg -n "ai-libs/|ai-libs/Mediator|只读|第三方源码参考区|第三方项目源码副本" AGENTS.md local-plan/todos/cqrs-rewrite-migration-tracking.md local-plan/traces/cqrs-rewrite-migration-trace.md` - `rg -n "ai-libs/|ai-libs/Mediator|只读|第三方源码参考区|第三方项目源码副本" AGENTS.md ai-plan/public/todos/cqrs-rewrite-migration-tracking.md ai-plan/public/traces/cqrs-rewrite-migration-trace.md`
- 结果:通过 - 结果:通过
- 备注:三处文档都已命中 `ai-libs` 只读规则与 `ai-libs/Mediator` 参考路径 - 备注:三处文档都已命中 `ai-libs` 只读规则与 `ai-libs/Mediator` 参考路径
@ -1380,7 +1380,7 @@
- PR 页面当前无 `Failed Tests`CTRF 测试报告显示 `2103 passed / 0 failed` - PR 页面当前无 `Failed Tests`CTRF 测试报告显示 `2103 passed / 0 failed`
- `Failed checks` 仅剩 `Title check` warning属于 GitHub PR 标题元数据问题,不是本地代码缺陷 - `Failed checks` 仅剩 `Title check` warning属于 GitHub PR 标题元数据问题,不是本地代码缺陷
- 已按 PR `#253` 的公开建议完成本地修正: - 已按 PR `#253` 的公开建议完成本地修正:
- `gframework-boot` 的恢复 heuristics 改为“先检索 `local-plan/`,再判定 `resume``recovery` - `gframework-boot` 的恢复 heuristics 改为“先检索 `ai-plan/`,再判定 `resume``recovery`
- `AGENTS.md``ai-libs/**` 观察写入 active plan/trace 的要求收窄到“多步/复杂任务或已有 active tracking document” - `AGENTS.md``ai-libs/**` 观察写入 active plan/trace 的要求收窄到“多步/复杂任务或已有 active tracking document”
- `Godot` 模板与 `IController` 文档注释中的旧 - `Godot` 模板与 `IController` 文档注释中的旧
`GFramework.SourceGenerators.Abstractions.Rule` 引用已收口到 `GFramework.SourceGenerators.Abstractions.Rule` 引用已收口到