Skip to content

Commit 4cdc5ac

Browse files
authored
Add portable knowledge onboarding and autonomous feature discovery (#323)
Portable initialization can now register a reviewed Git source and discover features without a packaged repository adapter. Documentation establishes the baseline; committed production code, tests and entry/contract units extend it. Independent model review and bounded residual scans preserve unknowns, existing IDs and frozen catalog denominators. Evidence bundles carry verified source spans into foundation and depth extraction. Add a single canonical knowledge store with hash-bound, read-only mirrors and explicit foundation/final publication receipts. Final publication replays source and native approvals, verifies the reviewed production inventory and coverage policy, checks retrieval, and stages the snapshot before replacing canonical files. Unaccepted catalogs and changed previews cannot proceed. Incremental updates prepare a new pinned batch and keep old approvals historical. SDK, MCP, Direct and Strict share resumable knowledge context sessions with a 24k-to-64k cumulative budget, actual injected-content records, and pinned, host-authorized cross-repository access. Existing adapters and the legacy two-page/6,000-character SDK interface retain their behavior. GLM-5.3 extraction and independent Codex review share a host-wide concurrency cap of 13; full native traces stay outside Git. Validation includes real SHA-1/SHA-256 Git sources, no-origin and multi-language libraries, long-file entries, nested tests, interrupted/failed discovery, exact native-fixture replay, partial/final gates, mirror isolation, cross-repository authorization, cache tampering, real thread/process dispatch limits, and retrieval truncation. Both hosted CI runs pass at `57ca043105112d1e887696402b7c6d11252d3f13`, including the complete repository tests, CLI, doctor JSON, clean wheel, documentation, all 97 SPEC pages and knowledge linters. The 16 real Git initialization tests also pass locally. This change makes no new claim about feature-discovery recall, upstream test execution, actual subscription charges, or GLM PR-review accuracy. The initialization workflow and operating commands are documented in `doc/architecture/portable-kb.md`.
1 parent beb098e commit 4cdc5ac

69 files changed

Lines changed: 5783 additions & 618 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎doc/architecture/SPEC/app/run_service.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
# app/run_service.py —— 规范
22

3-
<!-- verified-against: 2026-09-30 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`RunService` is the durable application boundary shared by the embedded
66
Strict SDK and MCP transport. It owns policy-checked reserve/start, a queue
77
drained by `STRICT_MAX_WORKERS` workers (default 1), isolated child launch, startup/orphan reconciliation,
88
readiness, bounded status/result polling, and repository-scoped knowledge
99
reads. Construction and polling require no CLI or MCP module import.
1010

11+
Knowledge reads resolve repository slices from the same frozen view's registry,
12+
with legacy adapters retained as fallback. Search/read always pass the view's
13+
manifest verifier. Child launch forwards the host-only
14+
`ALLOWED_KNOWLEDGE_REPOSITORIES`; tool input cannot grant cross-repository access.
15+
Strict adaptive document tools share the run's `KnowledgeContextService` ledger;
16+
legacy standalone document endpoints retain their per-call read windows.
17+
1118
Reservation and run ID containment go directly through `RunReservation`,
1219
not the workflow `Copilot` facade. `Copilot` remains for playbook readiness
1320
and workflow execution; it does not mediate the service's reserve or poll

‎doc/architecture/SPEC/config.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# config.py —— 规范
22

3-
<!-- verified-against: 2026-10-04 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`LOC ~658 · 配置 · refactor-status: oversized`
66

@@ -26,6 +26,11 @@ worker 数 `strict_max_workers`(`STRICT_MAX_WORKERS`,默认 1,启动时校
2626
以带标记的 JSON 评论贴到该锁定的 mailbox issue,供另一台主机上的 reviewbot 摄取)。
2727

2828
## 公开契约
29+
30+
`allowed_knowledge_repositories`(`ALLOWED_KNOWLEDGE_REPOSITORIES`,默认空 tuple)是
31+
运行主机授权读取的跨仓库 ID。它不进入模型工具的权限参数;授权仍须与固定快照中的
32+
confirmed 依赖及源码/目录 pin 一同验证,空配置只允许当前仓库。
33+
2934
带全部可调项的 `Settings`;`reviewer` / `intent`(回退到 `agent_model`);
3035
`repo_path(name)`;`model_for(mode)`;`tier_target(role)` → `ResolvedTarget`;
3136
`expansion_env()`;`knowledge_runtime_repos`;`allowed_repo_roots`

‎doc/architecture/SPEC/direct_routing.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# direct_routing.py —— 规范
22

3-
<!-- verified-against: 2026-10-02 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`LOC ~880 · Direct 模式完整策略包与仓库中立的知识路由 · refactor-status: stable`
66

77
## 职责
88
Direct 模式的知识路由**机制**。模块中不出现任何被服务仓库的名字:每个仓库的
9-
owner/model 路由表是知识数据 `knowledge/repos/<repo>/_routes.yaml`,仓库别名
10-
来自 `adapters/<repo>/manifest.yaml` 的 `repo.full_name`/`repo.aliases`。
9+
owner/model 路由表是知识数据 `knowledge/repos/<repo>/_routes.yaml`,仓库身份和别名
10+
优先来自同一固定视图的 `_repositories.yaml`,旧 adapter 别名保持兼容。
1111
公开面由 `contract.py` 再导出。
1212

1313
## 公开契约
@@ -39,7 +39,9 @@ Direct policy bundle)、`direct_knowledge_routes`、
3939
为模块级 `__getattr__` 惰性别名。
4040
- **路由选择按数据而非仓库名**:仓库有非空 `_routes.yaml` → title/body owner
4141
路由 + 模型路由 + scope fallback;否则有 adapter → changed-file 路由;否则
42-
`unsupported_exact_router`。`_routes.yaml` 引用的页面不存在时 fail-closed。
42+
`unsupported_exact_router`。已注册但未生成 owner routes 的仓库返回显式
43+
`description_unrouted`,仍可检索自己的说明知识;不得借用其他仓库路由。
44+
`_routes.yaml` 引用的页面不存在时 fail-closed。
4345
- `repo` 必填:空值抛 `ValueError`,不再默认某个仓库;形似路径的仓库名直接
4446
视为不支持。
4547
- **changed files 校验选择、绝不静默替换选择**:title/body 选 owner,
@@ -71,7 +73,9 @@ stdlib + PyYAML + `.adapters`(AdapterError / AdapterRegistry / RepoAdapter)+
7173
## 扩展点
7274
新 owner 路由/模型规则 → 改对应仓库的 `_routes.yaml`(schema_version 1:
7375
`owners[{owner, path, signals, scope_prefixes}]`、可选 `models{dir, page}`);
74-
新仓库 → 提供 adapter 与 `_routes.yaml`,不改 `src/`。
76+
新仓库 → 提供固定视图 registry 与 `_routes.yaml`,不要求打包 adapter、不改 `src/`。
77+
已有 adapter 仓库继续兼容。自适应 SDK 通过统一会话对本模块选出的规则/导航再计量;
78+
旧 bundle 的 6,000 字符相关背景预算保持不变。
7579

7680
## 测试
7781
`test_knowledge_view_routing.py`(150 个真实 vllm-omni PR 的黄金路由输出、

‎doc/architecture/SPEC/engine/agent_runtime.md‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
# engine/agent_runtime/ —— 规范
22

3-
<!-- verified-against: 2026-10-04 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`LOC ~1690(7 个文件) · 引擎(受治理的 agent 运行时) · refactor-status: ok`
66

77
## 职责
88

9+
含 `_repositories.yaml` 的固定快照默认采用 `knowledge_context_profile="adaptive"`;
10+
旧快照默认 legacy,也可显式选择。`doc_search` / `doc_read` / `doc_related`、规则与
11+
`doc_context_briefing` 共用 run 私有累计会话,`doc_context_expand` 必须给原因且保留
12+
源码/输出留白。实际注入正文和哈希写 trace,runner直接注入已围栏的 `model_content`。
13+
跨仓库 target 只选择已确认依赖,授权由 Settings 固定传入;模型工具不能授予权限。
14+
15+
916
开启 `profile_briefing_enabled` 且证据包含 `pr_diff` 时,runner 使用既有 diff parser 提取
1017
路径,通过 `doc_related` 在首个模型调用前注入同一有界知识背景。内容放入 untrusted
1118
围栏并转义标签;`review_knowledge_context` 记录命中页面、状态和正文长度。

‎doc/architecture/SPEC/kb_service.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@
55
`知识服务核心:仓库配置、账本、outbox、CLI · refactor-status: new`
66

77
## 职责
8+
- 通用接入:`git_source` 固定任意 Git 来源,`repo_spec` 保存经明确接受的范围;
9+
`portable_init` 创建本地受审工作区,`portable_commands` 提供 onboard、register、
10+
目录接受、发布和增量批次准备,不伪造已合并 PR。见 [通用知识库流程](../portable-kb.md)。
11+
- 功能发现:文档轮、源码轮、独立评审、最多两轮残留补查;共享完整库存和入口/契约单元,
12+
单项最多三次修正,失败保持未知。`evidence_bundle` 将固定哈希行段传给后续阶段。
13+
- 存储与接受:`knowledge_store` 单一主存储加只读镜像;`portable_publication` 区分 foundation
14+
与 final,默认只激活真实最终回执,显式 partial 仍为未完成。最终复核完整生产库存、
15+
七维分别 >90%、每功能认可和 ≥85% 结构覆盖,原生认可由 `native_depth_audit` 重放。
16+
- `source_links` 为 GitHub、GitLab 和本地 `repo://` 源码生成固定版本引用;原 GitHub 引用
17+
与历史认可正文保持一致。通用知识 pin 支持 SHA‑1/SHA‑256。
818
- `config`:解析 adapter `knowledge_lifecycle`(未知键、非法模式/触发器、缺失审计插件、
919
知识目录与 adapter 不一致、私有上游配 `auto_merge`、`auto_merge` 无校准集均抛
1020
`LifecycleConfigError`);`load_registry` 返回按仓库名的注册表,`general` 由服务配置。
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# knowledge_context.py —— 规范
2+
3+
<!-- verified-against: 2026-10-06 -->
4+
5+
## 职责与公开契约
6+
7+
`KnowledgeContextService` 是 SDK、MCP 与 Strict 共用的、固定快照的知识上下文服务。
8+
`ContextBudget` 声明模型窗口与留白;`ContextError` 拒绝身份、权限或预算不一致。
9+
`open_session` / `status` / `expand` 管理会话;`related` / `search` / `read` / `inject`
10+
返回同一累计预算下的实际正文和引用。服务不调用模型、不改知识页、不宣称评审准确率。
11+
12+
## 身份与权限
13+
14+
会话身份绑定快照树哈希、仓库 ID、知识切片、源码 pin、目录和政策哈希、PR 源码 pin、
15+
review ID、计量器及预算配置。已验证快照每次读取复核 manifest;开发目录绑定真实文件
16+
内容摘要。恢复复用固定根,不能悄悄切到当前 active。来源 pin 支持完整 SHA-1 / SHA-256。
17+
18+
仓库从固定视图的 `_repositories.yaml` 解析,旧目录只保留精确切片兼容,未知版本不猜测。
19+
跨仓库读取同时要求主机 `allowed_repositories` 授权与当前仓库中 `status: confirmed`
20+
的依赖;目标源码和目录哈希必须匹配。工具参数只能选择目标,不能授予权限;所有目标
21+
共享同一个累计预算。
22+
23+
## 预算与正文
24+
25+
默认初始 24,000、最高 64,000;模型上下文默认配置 131,072,源码留白 32,000、输出
26+
留白 8,192,还可预留其他 prompt。可用上限取知识上限和模型剩余窗口的较小值。
27+
扩大必须给出原因,不能占用留白。这些是主机配置,不能冒称探测到 served model 窗口。
28+
29+
默认以 UTF-8 字节数作保守计量上界,`token_accounting` 明示此单位;主机可传稳定 ID
30+
的 tokenizer。`actual_provider_usage` 保持 unknown。计量包括正文、来源字段、JSON
31+
转义与 untrusted 围栏。仅 `model_content` 用于注入;`documents` 是不带额外正文的引用。
32+
片段截断清空完整已注入维度及对应 basis/mode/validation 标签;可用维度仍可补读。
33+
34+
SQLite 运行账本必须位于知识树之外。事务串行记账,精确来源单元去重,重复请求幂等;
35+
扩大后允许继续未交付片段。缓存命中复核请求收据、正文摘要、计量和源文件;这属于完整性
36+
检查,不是针对可任意改写整个主机账本的签名。搜索与阅读重叠片段不保证全局语义去重。
37+
38+
## 接入与验证
39+
40+
新版 SDK 显式 `plan_adaptive` / 会话接口使用本服务;旧 `plan` 保留两页、6,000 字符契约。
41+
MCP 暴露同一 open/read/search/related/expand;Strict 在注册表快照默认 adaptive,旧树
42+
默认 legacy。规则与 briefing 经 `inject`,只接收真实文档 ID,不接收任意宿主散文。
43+
44+
`test_knowledge_context.py`、`test_knowledge_retrieval.py` 验证累计预算、并发、恢复、
45+
留白、跨仓库权限、缓存篡改、实际注入标签以及 SDK/Strict 的固定快照接入。

‎doc/architecture/SPEC/knowledge_docs.md‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# knowledge_docs.py —— 规范
22

3-
<!-- verified-against: 2026-10-04 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`LOC ~280 · 供 Direct 与 Agent 共用的只读知识检索 · refactor-status: ok`
66

@@ -33,7 +33,8 @@ stdlib 与 `knowledge_service.lifecycle` 的页面/完整深读正文解析;
3333
结构化接口卡不进入背景。确定性优先级为固定来源路径、生产入口、源码 glob,再结合
3434
功能 ID/标题和正文词命中;相同 feature 去重,完整深读优先于基础功能页。
3535
最多返回两页、每页 3,000 字符、总计 6,000 字符;优先完整 facet,超长单 facet 仍提供
36-
截断片段并标 `more_available`。返回来源 pin、命中路径、已有/缺失 facet,不验证 PR head。
36+
截断片段并标 `partial` 与 `more_available`,不把截断 facet 列入 `included_facets`。
37+
返回来源 pin、命中路径、已有/缺失 facet,不验证 PR head。
3738
`available_facets` 表示页内可用维度,`included_facets` 表示本次正文实际注入的维度;
3839
`not_injected_facets` 是已有但因预算未注入的维度,调用方可用原有有界读取补读。
3940
`facet_basis` 与 `included_facet_basis` 分别对应已有及已注入维度的认可依据。
@@ -59,3 +60,12 @@ stdlib 与 `knowledge_service.lifecycle` 的页面/完整深读正文解析;
5960

6061
## 2026-09-28 退役规则不再提供
6162
`read`/`search` 经 `visible_text` 去掉退役规则后再返回。
63+
64+
## 自适应调用边界(2026-10-06)
65+
66+
旧默认仍是两页、6,000 字符。`related` 允许显式覆盖 `max_documents`、
67+
`max_page_chars`、`max_content_chars` 与 `max_changed_files`;自适应服务可取消改变文件
68+
列表的前缀限制。可选上限是 100 页、每页 65,536 字符、总 262,144 字符,最终实际交付
69+
仍由 `KnowledgeContextService` 累计预算裁剪。这些是字符限制,不是模型实际 token 用量。
70+
纯解析缓存按原文内容寻址,所有命中仍先验证固定快照的真实字节;不缓存路径读取以绕过
71+
完整性检查。此读取器没有累计补读账本;累计预算由显式会话服务负责。

‎doc/architecture/SPEC/knowledge_service.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# knowledge_service/ — provider curation components
22

3-
<!-- verified-against: 2026-10-04 -->
3+
<!-- verified-against: 2026-10-06 -->
4+
5+
Pinned source identities and depth markers accept full SHA-1 or SHA-256 Git
6+
commits. Evidence bodies, stored hashes and native approval semantics remain
7+
unchanged; accepting a wider object identity never renews an old approval.
48

59
The provider owns knowledge curation beneath the public SDK v1 facade.
610
`KnowledgeCurator` composes four domain components over one explicit work

‎doc/architecture/SPEC/knowledge_service/lifecycle.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# knowledge_service/lifecycle.py —— 规范
22

3-
<!-- verified-against: 2026-10-04 -->
3+
<!-- verified-against: 2026-10-06 -->
4+
5+
深度区块的固定源码身份支持完整 SHA-1 或 SHA-256;旧区块正文、哈希及证明语义保持不变。
46

57
深度验证入口缺失证书的当前检测器为 `static-test-association-v2`;解析、证书工厂和
68
检索形状校验共用 `DEPTH_ABSENCE_DETECTOR`,算法升级不复用旧检测器身份。

‎doc/architecture/SPEC/knowledge_service/pinned_claims.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# knowledge_service/pinned_claims.py —— 规范
22

3-
<!-- verified-against: 2026-09-30 -->
3+
<!-- verified-against: 2026-10-06 -->
44

55
`LOC ~200 · 在钉住的上游 SHA 上核验规则声明与代码证据(kb init §9.1) · refactor-status: new`
66

77
## 职责
88
- `PinnedObserver(repo_dir, repository, pin, pull=)`:在本地 git 仓库(bare 或非 bare)上实现
99
`facts.Observer`,`head()` 固定返回钉住的 SHA;`top_level` / `path_exists` / `file_text` 读 git
1010
对象,`pull(n)` 默认走 `gh api repos/{repo}/pulls/{n}`(可注入;任何查询失败——没有 `gh`、网络错误、非对象回答——都归一为 `FactsError`,原有的 `FactsError` 原样抛出)。另加协议之外的
11-
`is_ancestor(sha)`:`sha` 是钉点或其祖先(非 40 位 SHA、镜像中不存在的对象、非 commit 对象为 False;候选对象损坏(`cat-file --batch-check` 同样输出 missing 但 stderr 报解包错误),或 git 读不到钉点历史(`merge-base` 此时也以 1 退出、只在 stderr 报 `Could not read`)时抛 `FactsError`,不把读失败当成"合入在钉点之后")。钉点必须是 40 位
11+
`is_ancestor(sha)`:`sha` 是钉点或其祖先(非完整 40/64 位 SHA、镜像中不存在的对象、非 commit 对象为 False;候选对象损坏(`cat-file --batch-check` 同样输出 missing 但 stderr 报解包错误),或 git 读不到钉点历史(`merge-base` 此时也以 1 退出、只在 stderr 报 `Could not read`)时抛 `FactsError`,不把读失败当成"合入在钉点之后")。钉点必须是完整 40/64 位
1212
且在仓库中存在的提交,否则构造即抛 `FactsError`。
1313
- `check_rules(rule_texts, observer)`:对每条(活跃)规则用 `facts.claims_in` 抽取声明,按
1414
`facts.observe` 在钉点观测;每条声明必须成立,`^[PR #N]` 还必须已合并进钉点历史

0 commit comments

Comments
 (0)