Project Knowledge 解释一份代码在当前项目里扮演什么角色,以及项目希望它守住什么契约。它不解析
函数调用,也不判断 Finding;它包含两类知识:Repository / Component / FileRole 等结构知识,以及
spec / case / link / rule / doc 等作者声明的 Biz Knowledge。前者决定代码如何组织,后者说明代码
为什么这样工作。
Repository
├─ Component(repocli 提供的工程边界)
│ └─ File ─▶ FileRole[]
│ ├─ source / test
│ ├─ entrypoint / handler
│ └─ manifest / lock / version
└─ Authored Biz Knowledge
└─ spec / case / link / rule / doc
| 对象 | 语义 |
|---|---|
Repository |
本次被评审的 Git snapshot,也是解析 Component 的入口 |
Component |
repocli 从被评审快照识别的工程操作边界 |
FileRole |
文件在所属 Component 中可组合的稳定职责 |
| Authored Biz Knowledge | 作者声明的业务契约、场景、关系和说明,通过 Language 绑定到代码身份 |
| Project Clue | Project 事实面向一个 Unit 的上下文投影,不是独立事实源 |
Component 是静态项目边界,Unit 是当前 diff 动态形成的行为评审边界。一个 Component 可以产生多个 Unit;一个 Unit 通常只消费所属 Component 的项目事实,不能因为同在 Repository 就传播全部上下文。
FileRole 不是互斥枚举,也不表示证据强度。main.go 可以是 source + entrypoint,a_test.go
可以是 source + test;同一个 lockfile 对依赖变化可能关键,对业务状态流转则可能只是背景。
DiffReport.Inspect(before) 从已捕获的比较两侧提供 Layout,CCR 按文件路径查询工程 Component。
查询不重新读取工作区;删除文件使用旧侧归属,其余文件使用新侧归属。文件角色仍由 CCR 投影,
不再根据 语言角色规则的 manifest 标记自行发现 Component。当前语言角色规则为:
| 语言角色 | manifest | source | 补充角色与项目文件 |
|---|---|---|---|
| Python | pyproject.toml / setup.py |
.py / .pyi |
test_*.py、*_test.py、conftest.py 为 test;__main__.py 为 entrypoint;uv.lock 为 lock |
| Go | go.mod |
.go |
*_test.go 为 test;CodeGraph 标记的 Go main / init 声明所在文件为 entrypoint;go.sum 为 lock;Component 根 VERSION 为 version |
| TypeScript | package.json |
.ts/.tsx/.js/.jsx/.mjs/.cjs |
*.test.* / *.spec.* 为 test;main.* 为 entrypoint;tsconfig*.json 为 manifest;常见包管理器 lockfile 为 lock |
Component 采用 repocli 的工程粒度:根项目下可有多个组件,非根 manifest 组件内的嵌套 manifest
不自动形成新组件;Makefile-only 边界也由 repocli 提供。同目录多语言 manifest 共享一个工程身份,
Component 主要语言是元数据,文件角色按文件自身判断。未知文件可有明确归属,同时保留 unknown 角色。
CodeGraph.LockfileTag 提供通用锁文件分类,CCR 不另维护锁文件名称列表。
Repository 布局必须面向 workspace、range target 或 commit target 对应的同一 snapshot。 不能用当前 checkout 的 manifest 判断旧 commit 的 Component,否则 diff、源码和项目知识会来自不同时间点。
Project 只回答文件是什么,Runner 再决定本次 Unit Review 如何消费它:
Change ─▶ Component / FileRole
├─ source ───────────────▶ Unit target
│ └─ entrypoint / handler / test ─▶ project Clue
├─ manifest / lock ─────▶ Component context
└─ version ─────────────▶ no Unit Review
source是当前 Unit formation 的 target;- 发生变化的
manifest / lock只向同 Component Unit 提供项目 Clue,单独变化时不启动 agent loop; - Component 根
VERSION是发布元数据,保留角色用于观测,但不成为 target 或业务上下文; entrypoint / handler与 source 组合,提示 Review 关注初始化、生命周期、输入契约、鉴权和响应语义;test当前只记录职责,不在分类阶段直接决定跳过。是否独立形成 Unit、并入源码 Unit 或采用轻量 Review,应由 formation / review policy 决定;- 用户显式 include 可以提升文件为 target;未被 Component 认领的文件继续使用全局扩展名与路径规则。
CCR 组合 CodeGraph 内置规则与自身的 TagRule 扩展,通过 DiffRequest.TagRules 交给 repocli;
repocli 在捕获 Change 时保存 Tags。CodeGraph 提供匹配机制,CCR 维护分类约定并选择评审范围。
CCR 默认不为 generated、test_fixture、dependency、build_output、cache、minified、test、review_data、tooling
材料启动独立评审。CCR 将选择策略通过
repocli.UnitOptions.Exclude 传入,repocli 在 Change 进入 Fragment / Unit 之前执行排除;
原始 Diff 保留用于上下文,排除文件不生成 Fragment 或 Unit。Scan 使用同一套
TagMatcher 分类规则和 CCR 排除策略。manifest 标签本身不排除文件,普通 manifest/lock 仍按 Component
提供上下文;位于依赖或构建产物目录中的 manifest/lock 则受对应类别的排除策略约束。
在已捕获的文件中,用户显式 exclude 优先于 include;include 可覆盖默认类别和路径排除,二进制文件始终跳过。
可继续使用 --exclude '**/*.pb.go,**/kitex_gen/**' 或 .casecodereview/rule.json 的
exclude glob 数组补充规则,无需重复配置上述默认类别。review --preview / scan --preview
可检查实际选择;排除的 Change 保留在已捕获 diff 中,供相关上下文按需读取。
这层分离使 FileRole 可以被 Review 1、Review 2 或未来其它 Reviewer 复用,而不把当前 admission 策略固化进项目知识。
捕获后的选择只消费已有 Tags。Scan 在读取文件正文前使用同一规则集分类和选择;排除项仅保留路径 供 preview 解释原因,不探测二进制或统计行数。入选文件完成二进制和 token 预算筛选后才进入工具 DiffMap。用户显式 include/exclude 保留 现有 glob 接口,默认分类使用正则规则,大小写约定由每条规则明确表达。Project 的 Component 查找和 角色补充分析与 Graph、源码工具、仓库契约共用捕获快照;评审中后续工作区编辑或 HEAD 移动不改变它们。
用户 exclude 优先于 include;显式 include 可以覆盖默认路径排除,二进制仍不进入评审。
普通 HTML 继续作为候选,trace 报告等项目特有产物由项目 rule.json 的 exclude 声明,
例如 doctor-trace*.html,避免把正常 HTML 源码一并排除。
源码事实、仓库角色和评审策略分别归属不同组件:CodeGraph 提供 decorator、call、symbol、span 和语言入口,repocli
据此提供仓库角色,CCR 解释角色对 Review 的意义。例如 Python 中已关联声明的 app.get 等 route
decorator 可提供 handler 提示,main.py 中名为 FastAPI 的调用可提供 entrypoint 提示。
这些是名称与结构约定,不证明实际绑定到某个框架;routers/、routes.py、handlers/ 等路径名本身不提供 handler 提示。
同样,Language 识别注释、装饰器、symbol-id / fqn 和 relation,负责把 spec / case / link / rule / doc
绑定到具体代码;Project Knowledge 负责这些声明表达的契约和业务场景。知识分类不要求把现有实现
强行搬进 internal/project:结构分类仍由该包负责,作者契约仍可由 spec-case、配置与 Unit Clue
各自承载,最终在 Project Knowledge 视角下统一投影给 Review。
Project Clue 在 Unit scope 最终确定后挂载:source 自身的 entrypoint / handler 角色形成 self/project
Clue;同 Component 中变化的 manifest / lock 形成 project/project Clue。这样 Project 负责稳定事实,
Unit 负责当前行为范围,prompt 排版仍由各 Review 阶段决定。
FileRole 不能直接等同于 target/context/excluded。角色是可复用事实,admission 是当前 Reviewer 的
策略;把两者混在一起,会让新增 Review 视角时被迫修改 Project 模型。
Repository 可以包含多个语言和多个 Component。项目上下文按 repocli 的工程归属,只在明确 Component 内传播;Repository 级 README、docs 或规则未来可以作为 Repository Knowledge,但不能借“同仓”默认 注入所有 Unit。
无法识别 manifest、文件角色或语言语义时保持 unknown,交给全局规则降级。Project Knowledge 的价值 来自减少无意义 loop 和补充可靠先验,不来自用目录名或扩展名制造看似丰富的猜测。
新语言的工程发现与通用角色进入 repocli;语言声明和入口语义进入 CodeGraph;CCR 只补充角色到 Review 的投影。 跨仓测试覆盖 nested component、polyglot、unknown、role composition 及历史快照,Language 继续消费 CodeGraph 的解析结果。
kernel.md— Project Knowledge 在 CCR Kernel 中的位置unit-model.md— Project 事实如何参与 Unit formation 与 Clue 组织language.md— decorator、call、symbol 等源码事实的 ownerunit_review.md— Project Clue 进入 Review 1 后如何被消费