From 00307ca6ee0ffcead45304266d640db6d007d36f Mon Sep 17 00:00:00 2001 From: stone Date: Wed, 5 Aug 2026 21:56:53 +0800 Subject: [PATCH 1/2] docs: pin OpenViking evidence and guard admission --- PLAN.md | 2 +- README.md | 17 +-- STATUS.md | 9 +- ...18-context-engine-implementation-design.md | 18 +-- ...repo-state-review-and-course-correction.md | 4 +- ...6-07-31-openviking-blueprint-evaluation.md | 48 ++++---- ...08-02-five-public-repositories-evidence.md | 53 +++++---- tests/unit/test_openviking_governance.py | 103 ++++++++++++++++++ 8 files changed, 184 insertions(+), 70 deletions(-) diff --git a/PLAN.md b/PLAN.md index db381784..e9b10691 100644 --- a/PLAN.md +++ b/PLAN.md @@ -135,4 +135,4 @@ M6 之后坚持 **one connector per milestone**,不把两个新权限模型压 ## 8. 致谢与参照 -设计吸收了对五个固定公开开源项目 **Dify、RAGFlow、MaxKB、Onyx、OpenViking** 的架构研究,仅学习可观察行为、Interface 形状、测试 oracle 与产品工作流。OpenViking 的白名单仅限 context filesystem/L0–L2 tiering、session→candidate UX、observable trajectory 与 agent exposure;它不证明多租户授权或安全,不作为 Runtime foundation,且任何 copy+patch 都被禁止。固定版本与一手链接见 `docs/research/2026-08-02-five-public-repositories-evidence.md`。安全与多租户协议由 ContextEngine 根据自身 requirement 与 threat model 独立设计;仓库外研究不是公开 authority 或 provenance。 +设计吸收了对四个已准入固定公开开源项目 **Dify、RAGFlow、MaxKB、Onyx** 的架构研究,仅学习可观察行为、Interface 形状、测试 oracle 与产品工作流。版本化后继基线 `docs/research/2026-08-02-five-public-repositories-evidence.md` 另含 OpenViking 候选包;#205 保持 open 时,本 PLAN 不把 OpenViking 引作 authority。候选白名单仅限 context filesystem/L0–L2 tiering、session→candidate UX、observable trajectory 与 agent exposure;它不证明多租户授权或安全,不作为 Runtime foundation,且任何 copy+patch 都被禁止。安全与多租户协议由 ContextEngine 根据自身 requirement 与 threat model 独立设计;仓库外研究不是公开 authority 或 provenance。 diff --git a/README.md b/README.md index ac917a92..c241bf2d 100644 --- a/README.md +++ b/README.md @@ -598,18 +598,19 @@ masquerade as a passing one. | [Implementation Design](./docs/design/2026-07-18-context-engine-implementation-design.md) | The integrated implementation authority and milestone boundaries | | [Threat Model](./docs/security/context-engine-threat-model.md) | Assets, trust boundaries, threats, hard oracles | | [Program PRD](./docs/agents/prd-contextengine-implementation.md) · [Epic Tech Spec](./docs/specs/2026-07-19-context-engine-implementation-epic.md) | Requirements, 100 user stories, contract shapes, work packages | -| [Prior-art evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md) | Strengths, limits, clean-room breakdown, and evidence gaps of five fixed public repositories | +| [Prior-art evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md) | Versioned successor for four admitted fixed repositories plus the non-authoritative OpenViking candidate packet | | [D0 Baseline Candidate](./DESIGN-BASELINE.md) | Current candidate state and unclosed evidence gates | ## Prior art -The design draws on architectural study of five fixed public open-source projects — -**Dify**, **RAGFlow**, **MaxKB**, **Onyx**, and conditionally admitted -**OpenViking** — limited strictly to observable -behavior, interface shape, test oracles, and product workflows. **No OpenViking -code was copied; other reuse remains governed per exact source region by -ADR-0074.** Pinned versions and first-party links are recorded in the -[evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md). +The design draws on architectural study of four admitted fixed public +open-source projects — **Dify**, **RAGFlow**, **MaxKB**, and **Onyx** — limited +strictly to observable behavior, interface shape, test oracles, and product +workflows. The versioned +[evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md) +also carries an OpenViking candidate packet, but this README does not cite +OpenViking as authority while issue #205 remains open. **No OpenViking code was +copied; other reuse remains governed per exact source region by ADR-0074.** ContextEngine's security and multi-tenancy protocols are designed independently from its own requirements and threat model. Research from outside this diff --git a/STATUS.md b/STATUS.md index 0564cca9..a4a45f4e 100644 --- a/STATUS.md +++ b/STATUS.md @@ -72,7 +72,7 @@ designed, and deliberately not active: | Session-derived Learning intake | ADR-0100 accepts only a future consented, minimized, provenance-bound candidate path; raw tape reads/storage, extractor model egress, candidate carrier, governed Memory artifact, release bridge, and Runtime serving remain `NOT_ACTIVE` | | Deployment/plugin productization | ADR-0101 bounds any future plugin to static composition at accepted ports, but defers generic categories/manifest/loader until a second implementation or measured drift; tenant code, hot loading, marketplace, and plugin-created service remain `NOT_ACTIVE` | | MCP ingress | Only the maintainer's spawn-per-session local stdio `context_resolve` tool is active; remote/shared HTTP, multi-user/tenant, private/group, `Continue`, `OpenCitation`, generation, effects, resources/prompts, and MCP egress-grant handling remain `NOT_ACTIVE` | -| OpenViking public-reference admission | The versioned five-repository baseline, permalink audit, legal dossier, and upstream license-metadata question are prepared in #205; maintainer/legal sign-off and the maintainer doc-steward decision remain pending. This activates no code reuse, dependency, Runtime carrier, or security claim. | +| OpenViking public-reference admission | The versioned successor baseline, permalink audit, legal dossier, and upstream license-metadata question are prepared in #205, but the OpenViking packet is not authority while #205 remains open; maintainer/legal sign-off and the maintainer doc-steward decision remain pending. This activates no code reuse, dependency, Runtime carrier, or security claim. | | Worker dead-letter transition / operator requeue | ADR-0060 adds bounded reclaim only; generation four is left untouched after expiry | | Provider polling, delete execution beyond ADR-0057 | See the File Provider ADRs for exact boundaries | | Streaming delivery | Explicit V1 non-goal — placeholder + edit instead | @@ -602,8 +602,8 @@ yet in M0 scope and are explicitly recorded as `not-evaluated`, so the report emits only an `m0SecurityDecision` — a passing security gate is never reported as an overall release or promotion PASS. -Beyond the pinned-commit evidence for Dify, RAGFlow, MaxKB, Onyx, and the -conditionally admitted OpenViking claim families in the +Beyond the pinned-commit evidence for the four admitted repositories Dify, +RAGFlow, MaxKB, and Onyx in the [versioned five-repository baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md), the dynamic evidence that exists today is the `compose.yaml`-pinned PostgreSQL + pgvector harness and RLS evidence for the @@ -611,3 +611,6 @@ first Organization-owned representative table. Dynamic evidence for the complete domain schema, ActorContext, filtered ANN, and Feishu capability is still outstanding — which is why this evidence slice is not described as a complete product authorization capability. + +The same versioned baseline carries an OpenViking candidate packet, but this +STATUS does not cite OpenViking as authority while issue #205 remains open. diff --git a/docs/design/2026-07-18-context-engine-implementation-design.md b/docs/design/2026-07-18-context-engine-implementation-design.md index c9f9a87b..513c79f1 100644 --- a/docs/design/2026-07-18-context-engine-implementation-design.md +++ b/docs/design/2026-07-18-context-engine-implementation-design.md @@ -29,14 +29,16 @@ reproducible report/digest is recorded. ### 0.1 Public provenance and independent design ownership -Public prior-art claims are allowlisted to Dify, RAGFlow, MaxKB, Onyx, and -conditionally admitted OpenViking at the fixed revisions recorded in -`docs/research/2026-08-02-five-public-repositories-evidence.md`. Those projects -provide observable patterns for product orchestration, document compilation, -knowledge operations, connectors, checkpointing, retrieval, and test layering. -They do not establish ContextEngine's security guarantees. OpenViking is -further restricted to the baseline's four behavioral claim families; it is no -Runtime foundation and supplies no code or dependency. +Public prior-art claims are allowlisted to Dify, RAGFlow, MaxKB, and Onyx at +the fixed revisions recorded in +`docs/research/2026-08-02-five-public-repositories-evidence.md`. Those four +projects provide observable patterns for product orchestration, document +compilation, knowledge operations, connectors, checkpointing, retrieval, and +test layering. They do not establish ContextEngine's security guarantees. The +same versioned baseline carries an OpenViking candidate packet, but this design +does not cite OpenViking as authority while issue #205 remains open; no +OpenViking code or dependency is admitted, and it cannot serve as a Runtime +foundation. ContextEngine independently owns the tenant model, AuthorizationKernel, AuthorizedProjection type flow, SourceAclEvidence semantics, WorkerLease, diff --git a/docs/design/2026-07-26-repo-state-review-and-course-correction.md b/docs/design/2026-07-26-repo-state-review-and-course-correction.md index aeea34cc..76707fa1 100644 --- a/docs/design/2026-07-26-repo-state-review-and-course-correction.md +++ b/docs/design/2026-07-26-repo-state-review-and-course-correction.md @@ -88,8 +88,8 @@ status: review record; decision boundaries owned by ADR-0061..ADR-0064 - **以创始论题为准绳:分叉。** 四支柱现状——真实检索:占位符;结构化 DB/API 族:路线图与领域模型零出现;adapter 群:一个 provider 且 seam 为名义;深度清洗:仅确定性 Markdown 编译。 -- 与四个公开参考仓(见 - `docs/research/2026-07-19-four-public-repositories-evidence.md`)呈镜像: +- 与四个已准入公开参考仓(见版本化后继基线 + `docs/research/2026-08-02-five-public-repositories-evidence.md`)呈镜像: 证据基线显示它们集体薄弱的授权/撤销/租户隔离恰是本仓已建成者;它们各自 擅长的摄取与检索广度恰是本仓未建者。此镜像可成为差异化,但必须出自 自觉选择——本次评审即为该选择补办手续(ADR-0061)。 diff --git a/docs/research/2026-07-31-openviking-blueprint-evaluation.md b/docs/research/2026-07-31-openviking-blueprint-evaluation.md index 6dfa2c60..3872679b 100644 --- a/docs/research/2026-07-31-openviking-blueprint-evaluation.md +++ b/docs/research/2026-07-31-openviking-blueprint-evaluation.md @@ -1,4 +1,4 @@ -> **Room-A 研究产物 — 维护者本地研究,非公开 provenance;第五仓准入已由维护者于 2026-07-31 有条件批准(D9)。66/66 上游 evidence links 已固定到 `49b1820…`,版本化候选五仓基线与 legal dossier 已于 2026-08-02 准备;maintainer/legal sign-off 仍由 #205 关闭。其余开放问题决定(D8/D10)见 [`five-repository-implementation-blueprint.md`](./2026-07-31-five-repository-implementation-blueprint.md) §5;正文推荐项保留评估时刻的状态。** +> **Room-A 研究产物 — 维护者本地研究,非公开 provenance;第五仓准入已由维护者于 2026-07-31 有条件批准(D9)。上游 evidence permalinks 已逐项固定到 `49b1820…` 的精确文件/行区间,版本化候选五仓基线与 legal dossier 已于 2026-08-02 准备;maintainer/legal sign-off 仍由 #205 关闭。其余开放问题决定(D8/D10)见 [`five-repository-implementation-blueprint.md`](./2026-07-31-five-repository-implementation-blueprint.md) §5;正文推荐项保留评估时刻的状态。** # 1. 固定 commit、许可证核验与证据基线状态 @@ -13,12 +13,12 @@ | 上游区域 | 固定证据 | 2026-07-31 核验结论 | ContextEngine 处置 | |---|---|---|---| -| 仓库根与 Python 主项目 | 根 [`LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/LICENSE) 是 GNU AGPL v3;[`pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/pyproject.toml) 自报 `AGPL-3.0`;[`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md) 也称 Main Project 为 AGPLv3 | **AGPLv3 区域**。除经单独许可证覆盖的路径外,`openviking/`、`openviking_cli/`、`web-studio/`、`bot/`、主项目测试与文档所描述的实现均按 AGPL 边界处理 | 严格 clean-room:仅行为规格、接口形状与测试 oracle;零源码复制、零派生实现、零主项目运行时依赖 | -| `crates/` 父目录 | [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE) 是 Apache License 2.0;README 称 `crates/ov_cli` 为 Apache-2.0 | 父目录给出 Apache-2.0 证据,但不能覆盖子项目 manifest 的相反声明 | 逐文件、逐 manifest 核验后才可能 copy+patch;不能把整个 `crates/` 当作已清洁素材池 | -| `crates/ov_cli` | [`crates/ov_cli/Cargo.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli/Cargo.toml) 自报 `MIT`,与 [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE) 和 [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md) 的 Apache-2.0 声明冲突 | **许可证边界未消歧,当前不可复制**。不能任选对项目更方便的一种许可证解释 | 需要上游/maintainer/legal 明确适用许可证、精确 source path 和所需 notice;在此之前只作 strategic-reference-only | -| `examples/` 父目录 | [`examples/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/LICENSE) 是 Apache License 2.0;README 称 examples 为 Apache-2.0 | 没有下层相反声明的具体文件,才有 Apache-2.0 初步依据;这不是对子树所有文件的无条件覆盖 | 每个候选需核对 manifest、SPDX、嵌套 LICENSE、依赖锁和实际 source path 后再登记 | -| `examples/openwebui-plugin` | [`pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/pyproject.toml) 自报 AGPL-3.0;[`tools.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/openviking_openwebui/tools.py) 带 AGPL-3.0 SPDX | 子项目明确为 **AGPL-3.0**,不得因父目录 `examples/LICENSE` 而误判为 Apache | clean-room only,禁止 copy+patch | -| 其他 examples | 例如 [`opencode-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/opencode-plugin/package.json) 自报 Apache-2.0,而 [`openclaw-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openclaw-plugin/package.json) 自报 MIT;[`claude-code-memory-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/claude-code-memory-plugin/package.json) 没有项目 license 字段 | examples 内存在多种或缺省声明,必须缩小到确切文件集合。依赖的 license 不是项目源码的 license | 当前无 copy+patch 提案;需要复用时另开 path-level 审批,不从本报告推定许可 | +| 仓库根与 Python 主项目 | 根 [`LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/LICENSE#L1-L12) 是 GNU AGPL v3;[`pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/pyproject.toml#L12-L20) 自报 `AGPL-3.0`;[`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L233-L240) 也称 Main Project 为 AGPLv3 | **AGPLv3 区域**。除经单独许可证覆盖的路径外,`openviking/`、`openviking_cli/`、`web-studio/`、`bot/`、主项目测试与文档所描述的实现均按 AGPL 边界处理 | 严格 clean-room:仅行为规格、接口形状与测试 oracle;零源码复制、零派生实现、零主项目运行时依赖 | +| `crates/` 父目录 | [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE#L1-L5) 是 Apache License 2.0;[`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L233-L240) 称 `crates/ov_cli` 为 Apache-2.0 | 父目录给出 Apache-2.0 证据,但不能覆盖子项目 manifest 的相反声明 | 逐文件、逐 manifest 核验后才可能 copy+patch;不能把整个 `crates/` 当作已清洁素材池 | +| `crates/ov_cli` | [`crates/ov_cli/Cargo.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli/Cargo.toml#L1-L8) 自报 `MIT`,与 [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE#L1-L5) 和 [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L233-L240) 的 Apache-2.0 声明冲突 | **许可证边界未消歧,当前不可复制**。不能任选对项目更方便的一种许可证解释 | 需要上游/maintainer/legal 明确适用许可证、精确 source path 和所需 notice;在此之前只作 strategic-reference-only | +| `examples/` 父目录 | [`examples/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/LICENSE#L1-L5) 是 Apache License 2.0;[`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L233-L240) 称 examples 为 Apache-2.0 | 没有下层相反声明的具体文件,才有 Apache-2.0 初步依据;这不是对子树所有文件的无条件覆盖 | 每个候选需核对 manifest、SPDX、嵌套 LICENSE、依赖锁和实际 source path 后再登记 | +| `examples/openwebui-plugin` | [`pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/pyproject.toml#L7-L12) 自报 AGPL-3.0;[`tools.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/openviking_openwebui/tools.py#L1-L3) 带 AGPL-3.0 SPDX | 子项目明确为 **AGPL-3.0**,不得因父目录 `examples/LICENSE` 而误判为 Apache | clean-room only,禁止 copy+patch | +| 其他 examples | 例如 [`opencode-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/opencode-plugin/package.json#L40-L47) 自报 Apache-2.0,而 [`openclaw-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openclaw-plugin/package.json#L56-L65) 自报 MIT;[`claude-code-memory-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/claude-code-memory-plugin/package.json#L1-L10) 没有项目 license 字段 | examples 内存在多种或缺省声明,必须缩小到确切文件集合。依赖的 license 不是项目源码的 license | 当前无 copy+patch 提案;需要复用时另开 path-level 审批,不从本报告推定许可 | AGPL 网络服务影响必须按工程红线理解:AGPLv3 第 13 节要求,若修改后的 AGPL 程序通过网络与用户交互,运营者须向这些用户提供获得该版本 Corresponding Source 的明确机会。ContextEngine 的 API/worker 是网络服务;复制、修改或依赖 OpenViking 主项目服务代码会把源码提供义务带到我们的网络交付面,并产生与 ADR-0074 受控复用政策不相容的风险。因此所有 AGPL 区域一律 clean-room,不能以“没有分发二进制”为由放宽。此结论是仓库工程治理边界,不代替法律意见。 @@ -38,15 +38,15 @@ OpenViking 的条件准入公开证据只存在于候选的 [`2026-08-02-five-pu | OpenViking 能力 | 上游固定证据 | ContextEngine 映射区域 | 复刻分类 | 结论 | |---|---|---|---|---| -| L0 abstract / L1 overview / L2 detail | [`context-layers.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/03-context-layers.md)、[`hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py) | Supply 编译的 Fragment/heading ancestry;Runtime AssemblyProfile、PackageBudget、Assembler | **clean-room Room-A spec** | 采用“信息密度逐级揭示”和逐 hop 预算;删除“层级/深度产生权限”的暗示 | -| `viking://` 虚拟文件系统、`ls/tree/glob/read` | [`viking-uri.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md)、[`filesystem.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/api/03-filesystem.md) | EffectiveScope、AuthorizationKernel、AuthorizedProjection、OpenCitation、Evidence Console | **clean-room Room-A spec** | 仅可做 post-authorization 的 browse UX 投影;不能暴露源 URI、目录存在性或 prefix 递归权限 | -| Session commit 后异步提取 memory | [`session.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/08-session.md)、[`session-memory-extraction-flow.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/design/session-memory-extraction-flow.md) | authorized-only Learning input、CurationCandidate/Annotation、CurationSnapshot、ReleaseCandidate/evaluate/promote | **clean-room Room-A spec** | 采用归档 intent、幂等队列、候选 diff;禁止模型直接 create/merge/delete active memory | -| 检索 trajectory / provenance | [`retrieval.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/07-retrieval.md)、[`test_provenance.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_provenance.py) | ContextRun、DecisionAudit、Package digest、Evidence Console | **clean-room Room-A spec** | 只保留 authorized-only lineage、预算与版本化 digest;拒绝 pre-auth path/query/score/count/thinking trace | -| Studio playground / Helper | [`observability.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/05-observability.md)、[`openviking-helper.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/14-openviking-helper.md) | ADR-0090 co-resident local Evidence Console | **clean-room Room-A spec** | 采用同进程、timeline、health、preview/confirm UX;必须经 HTTP seam、显式 browser auth 和 one-Control-operation-per-call | -| VikingBot 的 context/model/tools/channel 一体化 | [`vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md) | 外部 BotDelivery、ActionPlane;Engine Runtime | **do-not-take** | 与 ADR-0006 冲突;Engine 不生成答案、不拥有渠道或工具执行,只交付 ContextPackage | -| 同进程 `/mcp`、13 tools、coding-agent hooks | [`mcp_endpoint.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/mcp_endpoint.py)、[`mcp-integration.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md) | ADR-0017 sealed Runtime、OpenAPI/generated SDK、可选 thin MCP adapter | **clean-room Room-A spec** | 采用同认证、薄协议、hook 生命周期;不采用宽写面、目录直读、remember/forget 或旁路授权 | -| `crates/ov_cli` 和 examples 的客户端实现 | [`crates/ov_cli`](https://github.com/volcengine/OpenViking/tree/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli)、[`examples`](https://github.com/volcengine/OpenViking/tree/49b182045b42d34ad530948ad77d9d0226897da8/examples) | TS generated SDK、MCP/API exposure spikes、`third_party/` registry | **strategic-reference-only**(当前) | 许可证冲突且本仓已有 generated SDK authority;当前结论为 none,不提出 copy+patch | -| 完整 context layer / agent memory filesystem thesis | [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md) | ADR-0006、ADR-0061、Supply/Runtime/Learning 三环 | **strategic-reference-only** | 产品叙事相邻;我们以多租户授权真相和 audience-bound ContextPackage 为差异化核心 | +| L0 abstract / L1 overview / L2 detail | [`context-layers.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/03-context-layers.md#L1-L20)、[`hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py#L394-L551) | Supply 编译的 Fragment/heading ancestry;Runtime AssemblyProfile、PackageBudget、Assembler | **clean-room Room-A spec** | 采用“信息密度逐级揭示”和逐 hop 预算;删除“层级/深度产生权限”的暗示 | +| `viking://` 虚拟文件系统、`ls/tree/glob/read` | [`viking-uri.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md#L5-L35)、[`ls`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L3380-L3434)、[`tree`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L1822-L1875)、[`glob`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L1703-L1765)、[`read`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L3223-L3281) | EffectiveScope、AuthorizationKernel、AuthorizedProjection、OpenCitation、Evidence Console | **clean-room Room-A spec** | 仅可做 post-authorization 的 browse UX 投影;不能暴露源 URI、目录存在性或 prefix 递归权限 | +| Session commit 后异步提取 memory | [`session.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/08-session.md#L107-L122)、[`session-memory-extraction-flow.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/design/session-memory-extraction-flow.md#L45-L61) | authorized-only Learning input、CurationCandidate/Annotation、CurationSnapshot、ReleaseCandidate/evaluate/promote | **clean-room Room-A spec** | 采用归档 intent、幂等队列、候选 diff;禁止模型直接 create/merge/delete active memory | +| 检索 trajectory / provenance | [`retrieval.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/07-retrieval.md#L162-L186)、[`test_provenance.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_provenance.py#L17-L73) | ContextRun、DecisionAudit、Package digest、Evidence Console | **clean-room Room-A spec** | 只保留 authorized-only lineage、预算与版本化 digest;拒绝 pre-auth path/query/score/count/thinking trace | +| Studio playground / Helper | [`observability.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/05-observability.md#L168-L188)、[`openviking-helper.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/14-openviking-helper.md#L21-L53) | ADR-0090 co-resident local Evidence Console | **clean-room Room-A spec** | 采用同进程、timeline、health、preview/confirm UX;必须经 HTTP seam、显式 browser auth 和 one-Control-operation-per-call | +| VikingBot 的 context/model/tools/channel 一体化 | [`vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md#L1-L73) | 外部 BotDelivery、ActionPlane;Engine Runtime | **do-not-take** | 与 ADR-0006 冲突;Engine 不生成答案、不拥有渠道或工具执行,只交付 ContextPackage | +| 同进程 `/mcp`、13 tools、coding-agent hooks | [`mcp_endpoint.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/mcp_endpoint.py#L1029-L1048)、[`mcp-integration.md` process boundary](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md#L3-L13)、[`mcp-integration.md` tool list](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md#L130-L148)、[`Claude Code` hooks](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/02-claude-code.md#L63-L70)、[`Codex` hooks](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/04-codex.md#L47-L53)、[`Cursor` hooks](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/12-cursor.md#L39-L47) | ADR-0017 sealed Runtime、OpenAPI/generated SDK、可选 thin MCP adapter | **clean-room Room-A spec** | 采用同认证、薄协议、hook 生命周期;不采用宽写面、目录直读、remember/forget 或旁路授权 | +| `crates/ov_cli` 和 examples 的客户端实现 | [`crates/ov_cli/Cargo.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli/Cargo.toml#L1-L12)、[`opencode-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/opencode-plugin/package.json#L40-L47)、[`openclaw-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openclaw-plugin/package.json#L56-L65) | TS generated SDK、MCP/API exposure spikes、`third_party/` registry | **strategic-reference-only**(当前) | 许可证冲突且本仓已有 generated SDK authority;当前结论为 none,不提出 copy+patch | +| 完整 context layer / agent memory filesystem thesis | [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L32-L46) | ADR-0006、ADR-0061、Supply/Runtime/Learning 三环 | **strategic-reference-only** | 产品叙事相邻;我们以多租户授权真相和 audience-bound ContextPackage 为差异化核心 | # 3. 逐能力蓝图 @@ -54,7 +54,7 @@ OpenViking 的条件准入公开证据只存在于候选的 [`2026-08-02-five-pu ### 上游路径与可观察行为 -OpenViking 把内容写成 L0 摘要、L1 overview、L2 完整详情,并建议先读低成本层、按需深入;其固定描述与 token 量级见 [`docs/en/concepts/03-context-layers.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/03-context-layers.md)。层次检索先做全局 L0/L1 搜索,再以 priority queue 递归子目录;实现中有收敛轮次与并发边界,见 [`openviking/retrieve/hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py),rerank/回退行为由 [`tests/retrieve/test_hierarchical_retriever_rerank.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_hierarchical_retriever_rerank.py) 固定。上游的目录与层级只是检索结构,不提供可移植的多租户授权证明。 +OpenViking 把内容写成 L0 摘要、L1 overview、L2 完整详情,并建议先读低成本层、按需深入;其固定描述与 token 量级见 [`docs/en/concepts/03-context-layers.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/03-context-layers.md#L1-L20) 和 [token-budget guidance](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/03-context-layers.md#L163-L180)。层次检索先做全局 L0/L1 搜索,再以 priority queue 递归子目录;实现中有收敛轮次与并发边界,见 [`openviking/retrieve/hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py#L394-L551),rerank/回退行为由 [`hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py#L344-L392) 与 [`tests/retrieve/test_hierarchical_retriever_rerank.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_hierarchical_retriever_rerank.py#L249-L379) 固定。上游的目录与层级只是检索结构,不提供可移植的多租户授权证明。 ### 本仓 seam / authority @@ -129,7 +129,7 @@ class ProgressiveAssembler(Protocol): ### 上游路径与可观察行为 -OpenViking 使用 `viking:///`,区分 resources/user/agent 等 namespace,见 [`docs/en/concepts/04-viking-uri.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md) 与 [`openviking/core/namespace.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/core/namespace.py)。文件系统 API 暴露 `ls`、recursive listing、tree、glob、read 等行为,见 [`docs/en/api/03-filesystem.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/api/03-filesystem.md)、[`openviking/storage/viking_fs.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py) 和 [`openviking/service/fs_service.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/service/fs_service.py)。`node_limit`/`level_limit` 约束资源使用,但不等价于 ContextEngine 的 finite-target authorization。 +OpenViking 使用 `viking:///`,区分 resources/user/agent 等 namespace,见 [`docs/en/concepts/04-viking-uri.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md#L5-L35) 与 [`openviking/core/namespace.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/core/namespace.py#L13-L19)。文件系统 API 暴露 `ls`、recursive listing、tree、glob、read 等行为,见 [`ls`/recursive dispatch](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/service/fs_service.py#L84-L158)、[`tree`/`read`/`glob` service operations](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/service/fs_service.py#L434-L542) 和 [`read_file`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L3223-L3281)。[`node_limit`/`level_limit`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/storage/viking_fs.py#L1822-L1857) 约束资源使用,但不等价于 ContextEngine 的 finite-target authorization。 ### 本仓 seam / authority @@ -192,7 +192,7 @@ ContextRuntime.resolve(invocation, trusted_delivery, Acquire | OpenCitation) ### 上游路径与可观察行为 -OpenViking 的 `session.commit()` 同步归档消息,再异步生成摘要并提取 memory,最终写 `memory_diff.json`;阶段与输出见 [`docs/en/concepts/08-session.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/08-session.md) 和 [`docs/design/session-memory-extraction-flow.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/design/session-memory-extraction-flow.md)。实现的 session/archive/queue 路径见 [`openviking/session/session.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/session.py) 与 [`openviking/session/compressor_v2.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/compressor_v2.py),`memory_diff` 的 add/update/delete oracle 见 [`tests/session/memory/test_memory_diff.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/session/memory/test_memory_diff.py)。上游会把抽取结果 create/merge/delete 到用户 memory;这个激活路径不能移植。 +OpenViking 的 `session.commit()` 同步归档消息,再异步生成摘要并提取 memory,最终写 `memory_diff.json`;阶段与输出见 [`docs/en/concepts/08-session.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/08-session.md#L107-L122) 和 [`docs/design/session-memory-extraction-flow.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/design/session-memory-extraction-flow.md#L45-L61)。实现的 session/archive/queue 路径见 [`openviking/session/session.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/session.py#L1660-L1688) 和 its [phase-1 persistence/queue sequence](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/session.py#L1872-L2010);[`openviking/session/compressor_v2.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/compressor_v2.py#L224-L284) applies extraction results and [builds add/update/delete diffs](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/session/compressor_v2.py#L1083-L1229)。`memory_diff` 的 add/update/delete oracle 见 [`tests/session/memory/test_memory_diff.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/session/memory/test_memory_diff.py#L63-L170)。上游会把抽取结果 create/merge/delete 到用户 memory;这个激活路径不能移植。 ### 本仓 seam / authority @@ -262,7 +262,7 @@ ContextLearning.promote(evaluation_ref, release_operator_authority) -> ReleaseMa ### 上游路径与可观察行为 -OpenViking 的 retrieval result/provenance 可带 query、匹配 URI、level、score、searched directories、match reason 等,结构见 [`openviking_cli/retrieve/types.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking_cli/retrieve/types.py) 与 [`tests/retrieve/test_provenance.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_provenance.py);递归轨迹由 [`openviking/retrieve/hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py) 形成,汇总指标见 [`openviking/retrieve/retrieval_stats.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/retrieval_stats.py)。这些字段适合单机调试,但在多租户系统会泄露被拒绝资源的存在与相似度。 +OpenViking 的 retrieval result/provenance 可带 query、匹配 URI、level、score、searched directories、match reason 等,结构见 [`openviking_cli/retrieve/types.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking_cli/retrieve/types.py#L283-L313) 与 its [provenance serialization](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking_cli/retrieve/types.py#L350-L409),oracle 见 [`tests/retrieve/test_provenance.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/tests/retrieve/test_provenance.py#L17-L73);递归轨迹由 [`openviking/retrieve/hierarchical_retriever.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/hierarchical_retriever.py#L394-L551) 形成,汇总指标见 [`openviking/retrieve/retrieval_stats.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/retrieval_stats.py#L36-L69) 与 its [score aggregation](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/retrieve/retrieval_stats.py#L103-L125)。这些字段适合单机调试,但在多租户系统会泄露被拒绝资源的存在与相似度。 ### 本仓 seam / authority @@ -332,7 +332,7 @@ class RestrictedDecisionAudit: ### 上游路径与可观察行为 -OpenViking 在同一服务的 `/studio` 提供 Home、Resources、Retrieval、Sessions、Request Logs,见 [`docs/en/guides/05-observability.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/05-observability.md) 和 [`openviking/server/routers/console.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/routers/console.py)。Helper 检测 Claude Code/Codex/Cursor 等集成并展示 recall、prompt injection、capture、commit timeline,见 [`docs/en/agent-integrations/14-openviking-helper.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/14-openviking-helper.md)。VikingBot 把 context、model、tool 和 delivery 组合为 agent,见 [`docs/en/concepts/15-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md) 与 [`docs/en/guides/17-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/17-vikingbot.md)。最后一种一体化边界不适用于 ContextEngine。 +OpenViking 在同一服务的 `/studio` 提供 Home、Resources、Retrieval、Sessions、Request Logs,见 [`docs/en/guides/05-observability.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/05-observability.md#L168-L188) 和 [`openviking/server/routers/console.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/routers/console.py#L15-L60)。Helper 检测 Claude Code/Codex/Cursor 等集成并展示 recall、prompt injection、capture、commit timeline,见 [`docs/en/agent-integrations/14-openviking-helper.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/14-openviking-helper.md#L21-L53)。VikingBot 把 context、model、tool 和 delivery 组合为 agent,见 [`docs/en/concepts/15-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md#L1-L73) 与 [`docs/en/guides/17-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/17-vikingbot.md#L1-L5)。最后一种一体化边界不适用于 ContextEngine。 ### 本仓 seam / authority @@ -393,7 +393,7 @@ async def control_call( ### 上游路径与可观察行为 -OpenViking 把 `/mcp` 与 REST 同进程,以 streamable HTTP 暴露 13 个工具,包括 find/search/recall/read/list/remember/add_resource/watch/grep/glob/forget/health;工具表见 [`docs/en/guides/06-mcp-integration.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md),实现注册见 [`openviking/server/mcp_endpoint.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/mcp_endpoint.py)。Claude Code、Codex、Cursor 组合 hooks 与 MCP:prompt 前 recall/inject,response 后 capture,PreCompact/session end commit,见 [`claude-code.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/02-claude-code.md)、[`codex.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/04-codex.md)、[`cursor.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/12-cursor.md);通用 client 连接形状见 [`mcp-clients.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/06-mcp-clients.md)。 +OpenViking 把 `/mcp` 与 REST 同进程,以 streamable HTTP 暴露 13 个工具:find、search、recall、read、list、remember、add_resource、list_watches、cancel_watch、grep、glob、forget、health;进程边界与工具表见 [`docs/en/guides/06-mcp-integration.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md#L3-L13) 和 its [tool list](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/guides/06-mcp-integration.md#L130-L148),实现注册见 [`openviking/server/mcp_endpoint.py`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/openviking/server/mcp_endpoint.py#L1029-L1048)。Claude Code、Codex、Cursor 组合 hooks 与 MCP:prompt 前 recall/inject,response 后 capture,PreCompact/session end commit,见 [`claude-code.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/02-claude-code.md#L63-L70)、[`codex.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/04-codex.md#L47-L53)、[`cursor.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/12-cursor.md#L39-L47);通用 client 连接形状见 [`mcp-clients.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/agent-integrations/06-mcp-clients.md#L1-L13)。 ### 本仓 seam / authority @@ -461,7 +461,7 @@ async def resolve_context(tool_input: AcquireToolInput, transport: McpTransport) ### 上游路径与核验结果 -候选表面是 [`crates/ov_cli`](https://github.com/volcengine/OpenViking/tree/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli) 与 [`examples`](https://github.com/volcengine/OpenViking/tree/49b182045b42d34ad530948ad77d9d0226897da8/examples)。但是 `ov_cli` 的 [`Cargo.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli/Cargo.toml) 自报 MIT,和 [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE)/README 的 Apache 声明冲突;examples 内又有 [`openwebui-plugin/pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/pyproject.toml) 明确 AGPL、[`opencode-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/opencode-plugin/package.json) Apache、[`openclaw-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openclaw-plugin/package.json) MIT 等路径差异。 +候选表面包括 Rust CLI 与若干 examples;固定 manifest 表明 `ov_cli` 的 [`Cargo.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/ov_cli/Cargo.toml#L1-L12) 自报 MIT,和 [`crates/LICENSE`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/crates/LICENSE#L1-L5) 及 [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L233-L240) 的 Apache 声明冲突;examples 内又有 [`openwebui-plugin/pyproject.toml`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openwebui-plugin/pyproject.toml#L7-L12) 明确 AGPL、[`opencode-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/opencode-plugin/package.json#L40-L47) Apache、[`openclaw-plugin/package.json`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/examples/openclaw-plugin/package.json#L56-L65) MIT 等路径差异。 ### 本仓 seam / authority @@ -526,7 +526,7 @@ adapter 不得自己定义 tenant、authorization、filesystem 或 memory contra ### 上游路径与本仓 thesis -OpenViking 自称 agent 的 context database,把 memories/resources/skills 组织为可浏览的 virtual filesystem,以 tiered loading、recursive retrieval、session memory 和 observable trajectory 支撑 agent,见 [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md);VikingBot 进一步组合 context/model/tools/channel,见 [`docs/en/concepts/15-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md)。从这些固定材料可观察到 account/user/agent-local 的使用模型,但“缺乏与 ContextEngine 等价的 FORCE-RLS、多租户 audience authorization”只能表述为**在已核验路径中未见同等证据**,不能扩张为对上游全部安全能力的断言。 +OpenViking 自称 agent 的 context database,把 memories/resources/skills 组织为可浏览的 virtual filesystem,以 tiered loading、recursive retrieval、session memory 和 observable trajectory 支撑 agent,见 [`README.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/README.md#L32-L46);VikingBot 进一步组合 context/model/tools/channel,见 [`docs/en/concepts/15-vikingbot.md`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/15-vikingbot.md#L1-L73)。固定的 URI scope 表把 resources 和 agent 标为 account-global、user 标为 current-user 可见,见 [`Viking URI scopes`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md#L17-L31);agent 全局共享和 user 相对当前请求身份的语义另见 [`agent/user scope semantics`](https://github.com/volcengine/OpenViking/blob/49b182045b42d34ad530948ad77d9d0226897da8/docs/en/concepts/04-viking-uri.md#L104-L121)。从这些固定材料可观察到 account-global 与 current-user-local 的使用模型,但“缺乏与 ContextEngine 等价的 FORCE-RLS、多租户 audience authorization”只能表述为**在已核验路径中未见同等证据**,不能扩张为对上游全部安全能力的断言。 ### 本仓 seam / authority diff --git a/docs/research/2026-08-02-five-public-repositories-evidence.md b/docs/research/2026-08-02-five-public-repositories-evidence.md index 1d6ed6f2..bc5a0fd0 100644 --- a/docs/research/2026-08-02-five-public-repositories-evidence.md +++ b/docs/research/2026-08-02-five-public-repositories-evidence.md @@ -4,8 +4,9 @@ > > Date: 2026-08-02 > -> Status: candidate successor; prepared for maintainer legal decision in -> issue #205 +> Status: versioned successor and current public-reference aggregation entry; +> the OpenViking section remains a non-authoritative candidate pending issue +> #205 > > Supersedes: [`2026-07-19-four-public-repositories-evidence.md`](./2026-07-19-four-public-repositories-evidence.md) > as the current public-reference aggregation entry; the v1 report remains the @@ -13,35 +14,39 @@ ## 1. Scope and decision boundary -This candidate baseline records five fixed repository snapshots as public prior-art -evidence. They may support bounded claims about observable behavior, Interface -shapes, tests, and product workflows. They do not establish ContextEngine's -authorization, security, compliance, performance, or production-readiness -claims. - -| Repository | Fixed snapshot | Admitted evidence domain | -|---|---|---| -| Dify | [`120c38bad8d27cbe1e6a1d5522fd66f5caf6d0d5`](https://github.com/langgenius/dify/commit/120c38bad8d27cbe1e6a1d5522fd66f5caf6d0d5) | Product orchestration, workflow, Provider/Index seams, retrieval operations | -| RAGFlow | [`4391e03886b996201f3b8818f671b19eb24d0f7b`](https://github.com/infiniflow/ragflow/commit/4391e03886b996201f3b8818f671b19eb24d0f7b) | Document compilation, structured chunks, retrieval, hydration, differential tests | -| MaxKB | [`32b2d885e47ad04639abd7a18490bf5937f9c072`](https://github.com/1Panel-dev/MaxKB/commit/32b2d885e47ad04639abd7a18490bf5937f9c072) | Preview/confirm, knowledge operations, Hit Test, human curation workflow | -| Onyx | [`2fb3dd10493b3883870fa8adced5b1a0e114feff`](https://github.com/onyx-dot-app/onyx/commit/2fb3dd10493b3883870fa8adced5b1a0e114feff) | Connectors, checkpoints, staged indexing, retrieval composition, real-dependency test layering | -| OpenViking | [`49b182045b42d34ad530948ad77d9d0226897da8`](https://github.com/volcengine/OpenViking/commit/49b182045b42d34ad530948ad77d9d0226897da8) | Context filesystem and L0–L2 tiering, session-to-candidate UX, observable trajectory, agent exposure | +This versioned baseline succeeds the v1 aggregation entry. It records the four +admitted repository snapshots plus one fixed OpenViking candidate snapshot. +While issue #205 remains open, public prior-art claims may use only the first +four admitted rows; the OpenViking row and Section 3 are a non-authoritative +admission packet. None of the rows establishes ContextEngine's authorization, +security, compliance, performance, or production-readiness claims. + +| Repository | Fixed snapshot | Admission status | Evidence domain | +|---|---|---|---| +| Dify | [`120c38bad8d27cbe1e6a1d5522fd66f5caf6d0d5`](https://github.com/langgenius/dify/commit/120c38bad8d27cbe1e6a1d5522fd66f5caf6d0d5) | Admitted | Product orchestration, workflow, Provider/Index seams, retrieval operations | +| RAGFlow | [`4391e03886b996201f3b8818f671b19eb24d0f7b`](https://github.com/infiniflow/ragflow/commit/4391e03886b996201f3b8818f671b19eb24d0f7b) | Admitted | Document compilation, structured chunks, retrieval, hydration, differential tests | +| MaxKB | [`32b2d885e47ad04639abd7a18490bf5937f9c072`](https://github.com/1Panel-dev/MaxKB/commit/32b2d885e47ad04639abd7a18490bf5937f9c072) | Admitted | Preview/confirm, knowledge operations, Hit Test, human curation workflow | +| Onyx | [`2fb3dd10493b3883870fa8adced5b1a0e114feff`](https://github.com/onyx-dot-app/onyx/commit/2fb3dd10493b3883870fa8adced5b1a0e114feff) | Admitted | Connectors, checkpoints, staged indexing, retrieval composition, real-dependency test layering | +| OpenViking | [`49b182045b42d34ad530948ad77d9d0226897da8`](https://github.com/volcengine/OpenViking/commit/49b182045b42d34ad530948ad77d9d0226897da8) | Candidate; not public authority while #205 is open | Context filesystem and L0–L2 tiering, session-to-candidate UX, observable trajectory, agent exposure | The first four rows retain the claims, limitations, clean-room mappings, and pinned first-party links recorded in the [v1 baseline](./2026-07-19-four-public-repositories-evidence.md#2-证据纪律). -This successor does not expand those claims. Section 3 adds OpenViking using -only first-party material at its fixed snapshot. +This successor does not expand those claims. Section 3 prepares OpenViking for +a separate admission decision using only first-party material at its fixed +snapshot; it does not activate those claims while #205 is open. -OpenViking's admission is deliberately narrower than the original four: +The proposed OpenViking admission is deliberately narrower than the original +four: - **Whitelist:** context filesystem and information-density tiering, session-to-candidate workflow, observable retrieval trajectory, and agent exposure UX. - **Blacklist:** multi-tenant authorization or security proof, Runtime foundation, compliance proof, and every form of copy+patch. -- **No transitive authority:** the tracked Room-A evaluation is not public - provenance. Public claims must cite this baseline or the pinned upstream - sources linked below. +- **No transitive authority:** neither the tracked Room-A evaluation nor this + candidate section is public claim provenance while #205 remains open. If the + admission closes, public claims must cite this versioned baseline or the + pinned upstream sources linked below. ## 2. Evidence discipline @@ -62,7 +67,7 @@ baseline without a new reviewed version. The five repositories are not a common-corpus benchmark. Qualitative evidence domains must not be converted into a retrieval-quality ranking. -## 3. OpenViking conditional admission +## 3. OpenViking candidate packet (non-authoritative while #205 is open) ### 3.1 Context filesystem and information-density tiering @@ -197,8 +202,8 @@ Remaining evidence gaps are unchanged in kind: 3. Edition and path-specific license facts do not transfer across repository regions. 4. The maintainer legal decision for OpenViking behavior-observation-only reuse - remains the final authority gate; this PR must not merge before that decision - is recorded. + remains the final authority gate; neither this packet nor its public-document + attribution may become OpenViking authority before that decision is recorded. ## 6. Repository authority index diff --git a/tests/unit/test_openviking_governance.py b/tests/unit/test_openviking_governance.py index 5af79782..7c4bac43 100644 --- a/tests/unit/test_openviking_governance.py +++ b/tests/unit/test_openviking_governance.py @@ -6,12 +6,30 @@ REPOSITORY_ROOT = Path(__file__).resolve().parents[2] OPENVIKING_SHA = "49b182045b42d34ad530948ad77d9d0226897da8" BASELINE_PATH = "docs/research/2026-08-02-five-public-repositories-evidence.md" +PREDECESSOR_PATH = "docs/research/2026-07-19-four-public-repositories-evidence.md" ROOM_A_PATH = "docs/research/2026-07-31-openviking-blueprint-evaluation.md" DOSSIER_PATH = "docs/research/2026-08-02-openviking-legal-review-dossier.md" BLUEPRINT_PATH = "docs/research/2026-07-31-five-repository-implementation-blueprint.md" OPENVIKING_URL = re.compile( r"https://github\.com/volcengine/OpenViking/(?:blob|tree)/([^/)]+)/" ) +OPENVIKING_SOURCE_URL = re.compile( + r"https://github\.com/volcengine/OpenViking/(?:blob|tree)/" + rf"{OPENVIKING_SHA}/[^)]+" +) +EXACT_LINE_RANGE = re.compile(r"#L\d+-L\d+$") +UPSTREAM_CLAIM_BLOCK = re.compile( + r"^### 上游路径与(?:可观察行为|核验结果|本仓 thesis)\n\n" + r"(?P.*?)(?=\n\n### )", + re.MULTILINE | re.DOTALL, +) +EXPECTED_REPOSITORY_SNAPSHOTS = { + "langgenius/dify": "120c38bad8d27cbe1e6a1d5522fd66f5caf6d0d5", + "infiniflow/ragflow": "4391e03886b996201f3b8818f671b19eb24d0f7b", + "1Panel-dev/MaxKB": "32b2d885e47ad04639abd7a18490bf5937f9c072", + "onyx-dot-app/onyx": "2fb3dd10493b3883870fa8adced5b1a0e114feff", + "volcengine/OpenViking": OPENVIKING_SHA, +} def _read(path: str) -> str: @@ -55,6 +73,60 @@ def test_current_public_authority_uses_the_versioned_five_repository_baseline() assert ROOM_A_PATH not in document, path +def test_five_repository_baseline_is_an_explicit_versioned_successor() -> None: + baseline = _read(BASELINE_PATH) + + assert "> Version: 2.0.0" in baseline + predecessor_name = PREDECESSOR_PATH.rsplit("/", maxsplit=1)[1] + assert f"> Supersedes: [`{predecessor_name}`]" in baseline + for repository, snapshot in EXPECTED_REPOSITORY_SNAPSHOTS.items(): + assert f"https://github.com/{repository}/commit/{snapshot}" in baseline + + +def test_public_docs_keep_openviking_non_authoritative_until_issue_205_closes() -> None: + public_paths = ( + Path("README.md"), + Path("PLAN.md"), + Path("STATUS.md"), + *sorted(Path("docs/design").rglob("*.md")), + ) + boundary_terms = ( + "candidate", + "non-authoritative", + "not authority", + "does not cite openviking as authority", + "不把 openviking 引作 authority", + "候选", + "no openviking code", + "no code or dependency is admitted", + "not_active", + ) + forbidden_authority_phrases = ( + "conditionally admitted openviking", + "openviking claim families", + "draws on architectural study of five", + "allowlisted to dify, ragflow, maxkb, onyx, and openviking", + ) + + for path in public_paths: + document = _read(path.as_posix()) + normalized_document = _collapse_whitespace(document).lower() + assert ( + "https://github.com/volcengine/openviking" not in normalized_document + ), path + assert ROOM_A_PATH not in document, path + for phrase in forbidden_authority_phrases: + assert phrase not in normalized_document, (path, phrase) + + openviking_paragraphs = ( + _collapse_whitespace(paragraph).lower() + for paragraph in re.split(r"\n\s*\n", document) + if "openviking" in paragraph.lower() + ) + for paragraph in openviking_paragraphs: + assert any(term in paragraph for term in boundary_terms), (path, paragraph) + + def test_openviking_public_evidence_uses_only_the_admitted_snapshot() -> None: evidence_paths = ( BASELINE_PATH, @@ -68,6 +140,37 @@ def test_openviking_public_evidence_uses_only_the_admitted_snapshot() -> None: assert set(snapshots) == {OPENVIKING_SHA}, path +def test_room_a_claim_permalinks_pin_exact_source_regions() -> None: + room_a = _read(ROOM_A_PATH) + source_urls = OPENVIKING_SOURCE_URL.findall(room_a) + + assert source_urls + assert all(EXACT_LINE_RANGE.search(url) for url in source_urls) + + claim_blocks = UPSTREAM_CLAIM_BLOCK.findall(room_a) + assert len(claim_blocks) == 8 + for claim in claim_blocks: + claim_urls = OPENVIKING_SOURCE_URL.findall(claim) + assert claim_urls, claim + assert all(EXACT_LINE_RANGE.search(url) for url in claim_urls) + + capability_table = room_a.split( + "# 2. 能力盘点 → ContextEngine 区域映射表", maxsplit=1 + )[1].split("# 3. 逐能力蓝图", maxsplit=1)[0] + capability_rows = [ + line + for line in capability_table.splitlines() + if line.startswith("|") + and "OpenViking 能力" not in line + and not set(line.replace("|", "").strip()) <= {"-"} + ] + assert len(capability_rows) == 9 + for row in capability_rows: + row_urls = OPENVIKING_SOURCE_URL.findall(row) + assert row_urls, row + assert all(EXACT_LINE_RANGE.search(url) for url in row_urls) + + def test_openviking_copy_and_legal_authority_remain_closed() -> None: baseline = _read(BASELINE_PATH) dossier = _read(DOSSIER_PATH) From 064cfb902b8ac95a8879ceaf3cc3e56716a869c1 Mon Sep 17 00:00:00 2001 From: stone Date: Wed, 5 Aug 2026 23:36:33 +0800 Subject: [PATCH 2/2] test: close OpenViking governance review gaps --- CONTRIBUTING.md | 6 +- README.md | 2 +- README.zh-CN.md | 6 +- .../prd-contextengine-implementation.md | 2 +- ...on-authority-and-vertical-slice-roadmap.md | 14 +- ...08-02-five-public-repositories-evidence.md | 4 +- ...01\346\200\247\350\256\276\350\256\241.md" | 6 +- ...13\350\257\225\346\270\205\345\215\225.md" | 4 +- ...7-19-context-engine-implementation-epic.md | 6 +- tests/unit/test_openviking_governance.py | 174 ++++++++++++++++-- 10 files changed, 184 insertions(+), 40 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afaabd79..d3196394 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,8 +147,10 @@ first, or declined. ### Controlled third-party reuse -The design draws on architectural study of **Dify**, **RAGFlow**, **MaxKB**, -**Onyx**, and conditionally admitted **OpenViking**. Code reuse follows +The design draws on architectural study of the four admitted repositories +**Dify**, **RAGFlow**, **MaxKB**, and **Onyx**. The versioned evidence baseline +also carries an **OpenViking** candidate packet, but OpenViking is not public +authority while issue #205 remains open. Code reuse follows [ADR-0074](./docs/decisions/0074-adopt-controlled-third-party-code-reuse.md), per source region, never per product: Apache-2.0 regions (RAGFlow) and MIT regions (Onyx outside every `ee/` directory; separately-licensed SDK subtrees) diff --git a/README.md b/README.md index c241bf2d..6e65977e 100644 --- a/README.md +++ b/README.md @@ -598,7 +598,7 @@ masquerade as a passing one. | [Implementation Design](./docs/design/2026-07-18-context-engine-implementation-design.md) | The integrated implementation authority and milestone boundaries | | [Threat Model](./docs/security/context-engine-threat-model.md) | Assets, trust boundaries, threats, hard oracles | | [Program PRD](./docs/agents/prd-contextengine-implementation.md) · [Epic Tech Spec](./docs/specs/2026-07-19-context-engine-implementation-epic.md) | Requirements, 100 user stories, contract shapes, work packages | -| [Prior-art evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md) | Versioned successor for four admitted fixed repositories plus the non-authoritative OpenViking candidate packet | +| [Prior-art evidence baseline](./docs/research/2026-08-02-five-public-repositories-evidence.md) | Versioned successor for four admitted fixed repositories plus the OpenViking candidate packet, which is non-authoritative while issue #205 remains open | | [D0 Baseline Candidate](./DESIGN-BASELINE.md) | Current candidate state and unclosed evidence gates | ## Prior art diff --git a/README.zh-CN.md b/README.zh-CN.md index 0881cf54..f124e3f8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -299,10 +299,10 @@ IM 交付由 `BotDelivery` 这个受信深模块完成。它从 M2 起作为独 ## 参照与致谢 -设计吸收了对五个固定公开开源项目——**Dify**、**RAGFlow**、**MaxKB**、**Onyx**, -以及有条件准入的 **OpenViking**——的 +设计吸收了对四个已准入固定公开开源项目——**Dify**、**RAGFlow**、**MaxKB**、**Onyx**——的 架构研究,且严格限于可观察行为、interface 形状、测试 oracle 与产品工作流。 -**OpenViking 零代码复制;其他复用仍由 ADR-0074 按精确源码区域治理。** 固定版本与一手链接记录在 +版本化基线另含 **OpenViking** 候选包;#205 保持 open 时,本 README 不把 OpenViking +引作 authority。**OpenViking 零代码复制;其他复用仍由 ADR-0074 按精确源码区域治理。** 固定版本与一手链接记录在 [证据基线](./docs/research/2026-08-02-five-public-repositories-evidence.md)。 ContextEngine 的安全与多租户协议依据自身 requirement 与威胁模型独立设计。 diff --git a/docs/agents/prd-contextengine-implementation.md b/docs/agents/prd-contextengine-implementation.md index d5166b5f..69586e5a 100644 --- a/docs/agents/prd-contextengine-implementation.md +++ b/docs/agents/prd-contextengine-implementation.md @@ -36,7 +36,7 @@ ContextEngine 已经形成了较完整的产品定位、Domain Model、安全不 ### Public provenance and design ownership -- 公开 prior art 只允许引用五个固定版本的公开仓:Dify、RAGFlow、MaxKB、Onyx、OpenViking;证据索引统一见 `docs/research/2026-08-02-five-public-repositories-evidence.md`。OpenViking 只准入 context filesystem/L0–L2 tiering、session→candidate UX、observable trajectory 与 agent exposure 四类 claim,禁止作为多租户授权/安全证明、Runtime foundation 或任何 copy+patch 来源。 +- 公开 prior art 在 #205 保持 open 时只允许引用四个已准入固定版本的公开仓:Dify、RAGFlow、MaxKB、Onyx;证据索引统一见 `docs/research/2026-08-02-five-public-repositories-evidence.md`。该基线另含 OpenViking 候选包,但本 PRD 不把 OpenViking 引作 authority;候选范围只包括 context filesystem/L0–L2 tiering、session→candidate UX、observable trajectory 与 agent exposure 四类 claim,禁止作为多租户授权/安全证明、Runtime foundation 或任何 copy+patch 来源。 - 五仓只提供可观察的产品流程、Interface 形状、测试 oracle 与工程 pattern。ContextEngine 的 tenant model、AuthorizationKernel、SourceAclEvidence、WorkerLease、audience-bound delivery、ActionTicket、publication transaction 与 release authority 均是本项目根据自身威胁模型独立设计。 - 仓库之外的笔记、私有实现、本机路径或未署名综合结论不构成实现权威。任何探索性想法必须先改写成仓库内可独立审查的 requirement、threat、decision 或 evidence-gated hypothesis,才能进入 Design、ADR、PRD 或 Tech Spec。 - 不复制参考仓代码。公开设计不得通过删去来源名称来保留不可验证归因,也不得把 ContextEngine 自有协议描述成参考仓已经证明的能力。 diff --git a/docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md b/docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md index 82d57310..5e84fdbb 100644 --- a/docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md +++ b/docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md @@ -1,6 +1,6 @@ --- name: adr-0016-implementation-authority-and-vertical-slice-roadmap -version: "1.1.0" +version: "1.2.0" description: > Make the concise current implementation design authoritative and deliver the program as testable vertical slices with a separate launch gate. Use when @@ -31,11 +31,13 @@ assets, trust boundaries, threats, and hard oracles. These responsibilities are scoped, not a total precedence order; a contradiction blocks implementation until the owning documents are reconciled explicitly. `PLAN.md` plus the program PRD form the implementation-facing summary. -`docs/research/2026-07-19-four-public-repositories-evidence.md` fixes -the allowlisted public evidence behind reference-repository claims; it informs -design but does not override ContextEngine requirements, threat model, design, -or ADRs. Repository-external research inputs are neither public authority nor -public provenance. +`docs/research/2026-08-02-five-public-repositories-evidence.md` is the versioned +successor that fixes public evidence behind reference-repository claims. While +issue #205 remains open, only its Dify, RAGFlow, MaxKB, and Onyx rows are +admitted public authority; its OpenViking candidate packet is non-authoritative. +The baseline informs design but does not override ContextEngine requirements, +threat model, design, or ADRs. Repository-external research inputs are neither +public authority nor public provenance. D0 must record an immutable commit and digest for the publication-ready authority bundle after its allowlist and provenance scans pass. Implementation diff --git a/docs/research/2026-08-02-five-public-repositories-evidence.md b/docs/research/2026-08-02-five-public-repositories-evidence.md index bc5a0fd0..c311eeca 100644 --- a/docs/research/2026-08-02-five-public-repositories-evidence.md +++ b/docs/research/2026-08-02-five-public-repositories-evidence.md @@ -27,7 +27,7 @@ security, compliance, performance, or production-readiness claims. | RAGFlow | [`4391e03886b996201f3b8818f671b19eb24d0f7b`](https://github.com/infiniflow/ragflow/commit/4391e03886b996201f3b8818f671b19eb24d0f7b) | Admitted | Document compilation, structured chunks, retrieval, hydration, differential tests | | MaxKB | [`32b2d885e47ad04639abd7a18490bf5937f9c072`](https://github.com/1Panel-dev/MaxKB/commit/32b2d885e47ad04639abd7a18490bf5937f9c072) | Admitted | Preview/confirm, knowledge operations, Hit Test, human curation workflow | | Onyx | [`2fb3dd10493b3883870fa8adced5b1a0e114feff`](https://github.com/onyx-dot-app/onyx/commit/2fb3dd10493b3883870fa8adced5b1a0e114feff) | Admitted | Connectors, checkpoints, staged indexing, retrieval composition, real-dependency test layering | -| OpenViking | [`49b182045b42d34ad530948ad77d9d0226897da8`](https://github.com/volcengine/OpenViking/commit/49b182045b42d34ad530948ad77d9d0226897da8) | Candidate; not public authority while #205 is open | Context filesystem and L0–L2 tiering, session-to-candidate UX, observable trajectory, agent exposure | +| OpenViking | [`49b182045b42d34ad530948ad77d9d0226897da8`](https://github.com/volcengine/OpenViking/commit/49b182045b42d34ad530948ad77d9d0226897da8) | Candidate; not public authority while `#205` is open | Context filesystem and L0–L2 tiering, session-to-candidate UX, observable trajectory, agent exposure | The first four rows retain the claims, limitations, clean-room mappings, and pinned first-party links recorded in the [v1 baseline](./2026-07-19-four-public-repositories-evidence.md#2-证据纪律). @@ -67,7 +67,7 @@ baseline without a new reviewed version. The five repositories are not a common-corpus benchmark. Qualitative evidence domains must not be converted into a retrieval-quality ranking. -## 3. OpenViking candidate packet (non-authoritative while #205 is open) +## 3. OpenViking candidate packet (non-authoritative while `#205` is open) ### 3.1 Context filesystem and information-density tiering diff --git "a/docs/security/Test-Architecture-\344\270\216\345\217\257\351\252\214\350\257\201\346\200\247\350\256\276\350\256\241.md" "b/docs/security/Test-Architecture-\344\270\216\345\217\257\351\252\214\350\257\201\346\200\247\350\256\276\350\256\241.md" index 542db681..f55e6762 100644 --- "a/docs/security/Test-Architecture-\344\270\216\345\217\257\351\252\214\350\257\201\346\200\247\350\256\276\350\256\241.md" +++ "b/docs/security/Test-Architecture-\344\270\216\345\217\257\351\252\214\350\257\201\346\200\247\350\256\276\350\256\241.md" @@ -21,7 +21,7 @@ source: "context-engine-threat-model.md and ../research/2026-08-02-five-public-r ## Content -ContextEngine 的测试架构从自有威胁模型推导:租户隔离、授权前后类型边界、发布原子性、可重放工作租约、audience-bound delivery 以及 egress/effect 权限分离都是发布 veto,不由上游测试数量或 UI 交互间接证明。五个固定公开参考仓只提供可核验的工程形状;OpenViking 仅增加 context filesystem/tiering、session candidate、trajectory 与 agent exposure UX 的条件参考,不提供安全证明或 Runtime foundation。取舍边界见[Five Public Repositories Evidence Baseline](../research/2026-08-02-five-public-repositories-evidence.md)。这些证据不代表 ContextEngine 已经完成动态 Spike 或安全验证。 +ContextEngine 的测试架构从自有威胁模型推导:租户隔离、授权前后类型边界、发布原子性、可重放工作租约、audience-bound delivery 以及 egress/effect 权限分离都是发布 veto,不由上游测试数量或 UI 交互间接证明。四个已准入固定公开参考仓只提供可核验的工程形状;版本化基线另含 OpenViking 候选包,但 #205 保持 open 时,本设计不把 OpenViking 引作 authority。它不提供安全证明或 Runtime foundation。取舍边界见[Five Public Repositories Evidence Baseline](../research/2026-08-02-five-public-repositories-evidence.md)。这些证据不代表 ContextEngine 已经完成动态 Spike 或安全验证。 推荐接受两项代价:V1 的 security、RLS、composite FK、outbox 与 pgvector 集成测试默认启动真实 PostgreSQL 17 + pgvector,速度慢于纯 in-memory test;PGLite 最多承载不涉及 role、RLS、extension 和 connection-pool context 的快速 Adapter 反馈,不计入安全门禁。任何新 Adapter 必须通过共享 contract suite,接入速度会被 gate 限制。换来的确定性是:tenant isolation、outbox、RLS、retrieval filter 和 ContextPackage contract 不依赖某个调用点的自觉。 @@ -442,7 +442,7 @@ Flaky test 不能自动重跑后变绿;先记录原始失败,只有 typed ex | RAGFlow | parser/retrieval benchmark、rich document fixture | parser quality 与 tenant security 分开 gate;runtime parity 要 contract | | MaxKB | preview/confirm、Hit Test、direct return、human correction | 自动化 contract/golden/security release gate 由 ContextEngine 自建 | | Onyx | connector/checkpoint、分阶段索引与真实依赖测试分层 | missing tenant 不允许 default fallback;ACL semantics 必须单值明确 | -| OpenViking | context filesystem/L0–L2 tiering、session candidate、trajectory 与 agent exposure UX | 不证明多租户安全;不作为 Runtime foundation;禁止 copy+patch | +| OpenViking | #205 保持 open 时的 non-authoritative candidate packet:context filesystem/L0–L2 tiering、session candidate、trajectory 与 agent exposure UX | OpenViking is not public authority;不证明多租户安全;不作为 Runtime foundation;禁止 copy+patch | 这张表只记录固定版本中可回引的 observable behavior,不将上游的代码结构、安全保证或 edition 声明继承给 ContextEngine。具体 commit 与一手证据统一由[Five Public Repositories Evidence Baseline](../research/2026-08-02-five-public-repositories-evidence.md)管理。 @@ -500,4 +500,4 @@ Visible self-correction:早期设计把“多写一些 unit tests”当可测 *Updated 2026-07-20*: 依据 ADR-0019 将发布 catalog 固定为 15 个 canonical ID,归并重叠标签而不删除 case,并将 acceptance 口径收敛为 12 个顶层场景加历史 13–22 的派生/参数化证据。 -*Updated 2026-08-02*: 公开参考证据更新到版本化五仓基线;OpenViking 只提供四类条件行为输入,不扩张安全 claim 或 Runtime authority。 +*Updated 2026-08-02*: 公开参考证据更新到版本化五仓基线;#205 保持 open 时,本设计不把 OpenViking 引作 authority,候选包也不扩张 Runtime 安全 claim。 diff --git "a/docs/security/\345\256\211\345\205\250\350\264\237\345\220\221\346\265\213\350\257\225\346\270\205\345\215\225.md" "b/docs/security/\345\256\211\345\205\250\350\264\237\345\220\221\346\265\213\350\257\225\346\270\205\345\215\225.md" index fc37743f..9a9fb633 100644 --- "a/docs/security/\345\256\211\345\205\250\350\264\237\345\220\221\346\265\213\350\257\225\346\270\205\345\215\225.md" +++ "b/docs/security/\345\256\211\345\205\250\350\264\237\345\220\221\346\265\213\350\257\225\346\270\205\345\215\225.md" @@ -19,7 +19,7 @@ source: "context-engine-threat-model.md and ../research/2026-08-02-five-public-r ## Content -ContextEngine 的负向测试 catalog 从自有威胁模型与 release contract 推导,把租户越权、缺失上下文、证据泄漏、授权时序、工作者身份、audience drift、egress 与外部 effect 分离转成稳定 test IDs。[ADR-0019](../decisions/0019-security-catalog-normalization.md) 将发布权威归一为恰好 15 个稳定 ID;机器权威是 [`eval/catalogs/security-invariants.yaml`](../../eval/catalogs/security-invariants.yaml),由 [`eval/catalogs/security-catalog.schema.json`](../../eval/catalogs/security-catalog.schema.json) 和 `python3 scripts/validate_security_catalog.py` 校验。目录采用 JSON-compatible YAML,使校验器在 bootstrap 与 CI 中始终只依赖 Python 标准库并保持确定性,与应用依赖解耦。五个固定公开参考仓只提供工程形状;OpenViking 的条件准入不提供安全证明或 Runtime foundation。不继承任何上游安全保证,也不声称已运行上游渗透、故障注入或 ContextEngine 动态 Spike。一手证据和未取证边界见[Five Public Repositories Evidence Baseline](../research/2026-08-02-five-public-repositories-evidence.md)。 +ContextEngine 的负向测试 catalog 从自有威胁模型与 release contract 推导,把租户越权、缺失上下文、证据泄漏、授权时序、工作者身份、audience drift、egress 与外部 effect 分离转成稳定 test IDs。[ADR-0019](../decisions/0019-security-catalog-normalization.md) 将发布权威归一为恰好 15 个稳定 ID;机器权威是 [`eval/catalogs/security-invariants.yaml`](../../eval/catalogs/security-invariants.yaml),由 [`eval/catalogs/security-catalog.schema.json`](../../eval/catalogs/security-catalog.schema.json) 和 `python3 scripts/validate_security_catalog.py` 校验。目录采用 JSON-compatible YAML,使校验器在 bootstrap 与 CI 中始终只依赖 Python 标准库并保持确定性,与应用依赖解耦。四个已准入固定公开参考仓只提供工程形状;版本化基线另含 OpenViking 候选包,但 #205 保持 open 时,本清单不把 OpenViking 引作 authority。它不提供安全证明或 Runtime foundation。不继承任何上游安全保证,也不声称已运行上游渗透、故障注入或 ContextEngine 动态 Spike。一手证据和未取证边界见[Five Public Repositories Evidence Baseline](../research/2026-08-02-five-public-repositories-evidence.md)。 这里的“无 mock 能力声明”是证据门槛,不是禁止测试替身。deterministic fixture、fake、twin、spy 与 property generator 可以证明内部失败语义和“调用/bytes/effect = 0”;只有真实 PostgreSQL、真实 wire、真实 source sandbox 或真实外部依赖运行结果才能支持 live capability claim。 @@ -322,4 +322,4 @@ Flaky deterministic security/reliability case不能自动重跑变绿。所有 *Updated 2026-07-20*: 依据 ADR-0019 将发布目录归一为 15 个稳定 ID;保留被吸收标签的全部案例与 `CACHE-SCOPE-013` 条件扩展,并链接机器目录、schema 与 validator。 -*Updated 2026-08-02*: 公开参考证据更新到版本化五仓基线;OpenViking 的条件准入不提供任何安全证明。 +*Updated 2026-08-02*: 公开参考证据更新到版本化五仓基线;#205 保持 open 时,本清单不把 OpenViking 引作 authority,候选包也不提供任何安全证明。 diff --git a/docs/specs/2026-07-19-context-engine-implementation-epic.md b/docs/specs/2026-07-19-context-engine-implementation-epic.md index f70c1ac3..54e1eecf 100644 --- a/docs/specs/2026-07-19-context-engine-implementation-epic.md +++ b/docs/specs/2026-07-19-context-engine-implementation-epic.md @@ -140,8 +140,10 @@ dispute. ### 3.1 Public provenance closure The repository's public prior-art allowlist contains only Dify, RAGFlow, MaxKB, -Onyx, and conditionally admitted OpenViking at the revisions pinned by -`docs/research/2026-08-02-five-public-repositories-evidence.md`. These sources +and Onyx at the revisions pinned by +`docs/research/2026-08-02-five-public-repositories-evidence.md`. That baseline +also carries an OpenViking candidate packet, but OpenViking is not public +authority while issue #205 remains open. The four admitted sources may justify observable patterns, Interface shapes, test oracles, and product workflows. They do not prove ContextEngine's security properties. diff --git a/tests/unit/test_openviking_governance.py b/tests/unit/test_openviking_governance.py index 7c4bac43..4be347e5 100644 --- a/tests/unit/test_openviking_governance.py +++ b/tests/unit/test_openviking_governance.py @@ -3,9 +3,12 @@ import re from pathlib import Path +import pytest + REPOSITORY_ROOT = Path(__file__).resolve().parents[2] OPENVIKING_SHA = "49b182045b42d34ad530948ad77d9d0226897da8" BASELINE_PATH = "docs/research/2026-08-02-five-public-repositories-evidence.md" +BASELINE_NAME = BASELINE_PATH.rsplit("/", maxsplit=1)[1] PREDECESSOR_PATH = "docs/research/2026-07-19-four-public-repositories-evidence.md" ROOM_A_PATH = "docs/research/2026-07-31-openviking-blueprint-evaluation.md" DOSSIER_PATH = "docs/research/2026-08-02-openviking-legal-review-dossier.md" @@ -17,7 +20,7 @@ r"https://github\.com/volcengine/OpenViking/(?:blob|tree)/" rf"{OPENVIKING_SHA}/[^)]+" ) -EXACT_LINE_RANGE = re.compile(r"#L\d+-L\d+$") +EXACT_LINE_RANGE = re.compile(r"#L(?P\d+)-L(?P\d+)$") UPSTREAM_CLAIM_BLOCK = re.compile( r"^### 上游路径与(?:可观察行为|核验结果|本仓 thesis)\n\n" r"(?P.*?)(?=\n\n### )", @@ -30,6 +33,21 @@ "onyx-dot-app/onyx": "2fb3dd10493b3883870fa8adced5b1a0e114feff", "volcengine/OpenViking": OPENVIKING_SHA, } +EXPLICIT_NON_AUTHORITY_PATTERNS = ( + re.compile( + r"\bopenviking\b" + r"(?:(?!\bopenviking\b|[|。.!?;;]).){0,120}?" + r"\b(?:is|remains)\s+" + r"(?:a\s+)?(?:non-authoritative|not (?:public )?authorit(?:y|ative))\b" + ), + re.compile(r"\bdoes not cite\s+openviking\s+as\s+authority\b"), + re.compile(r"不把\s+openviking\s+引作\s+authority\b"), +) +AUTHORITY_TERM = re.compile(r"\bauthorit(?:y|ative)\b") +PRONOUN_AUTHORITY_CLAIM = re.compile( + r"\b(?:it|the candidate|this candidate)\b[^|。.!?;;]{0,120}" + r"\bauthorit(?:y|ative)\b" +) def _read(path: str) -> str: @@ -44,6 +62,38 @@ def _collapse_blockquote(value: str) -> str: return _collapse_whitespace(value.replace(">", "")) +def _has_exact_positive_line_range(url: str) -> bool: + match = EXACT_LINE_RANGE.search(url) + if match is None: + return False + start, end = (int(match.group(name)) for name in ("start", "end")) + return 0 < start <= end + + +def _assert_openviking_paragraph_is_non_authoritative( + paragraph: str, path: Path +) -> None: + normalized_paragraph = _collapse_whitespace(paragraph).lower() + assert "#205" in normalized_paragraph, (path, normalized_paragraph) + matched_boundary = any( + pattern.search(normalized_paragraph) + for pattern in EXPLICIT_NON_AUTHORITY_PATTERNS + ) + assert matched_boundary, (path, normalized_paragraph) + + for clause in re.split(r"[|。.!?;;]+", normalized_paragraph): + if "openviking" not in clause: + continue + residual = clause + for pattern in EXPLICIT_NON_AUTHORITY_PATTERNS: + residual = pattern.sub("", residual) + assert AUTHORITY_TERM.search(residual) is None, (path, normalized_paragraph) + assert PRONOUN_AUTHORITY_CLAIM.search(normalized_paragraph) is None, ( + path, + normalized_paragraph, + ) + + def _amendment_pair(dossier: str, number: int) -> tuple[str, str]: heading = f"### Pair {number} " section = dossier.split(heading, maxsplit=1)[1] @@ -65,6 +115,7 @@ def test_current_public_authority_uses_the_versioned_five_repository_baseline() "PLAN.md", "STATUS.md", "docs/design/2026-07-18-context-engine-implementation-design.md", + "docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md", ) for path in authority_paths: @@ -81,25 +132,55 @@ def test_five_repository_baseline_is_an_explicit_versioned_successor() -> None: assert f"> Supersedes: [`{predecessor_name}`]" in baseline for repository, snapshot in EXPECTED_REPOSITORY_SNAPSHOTS.items(): assert f"https://github.com/{repository}/commit/{snapshot}" in baseline + admitted_rows = { + "Dify": EXPECTED_REPOSITORY_SNAPSHOTS["langgenius/dify"], + "RAGFlow": EXPECTED_REPOSITORY_SNAPSHOTS["infiniflow/ragflow"], + "MaxKB": EXPECTED_REPOSITORY_SNAPSHOTS["1Panel-dev/MaxKB"], + "Onyx": EXPECTED_REPOSITORY_SNAPSHOTS["onyx-dot-app/onyx"], + } + for repository, snapshot in admitted_rows.items(): + row = next( + line + for line in baseline.splitlines() + if line.startswith(f"| {repository} |") + ) + cells = [cell.strip() for cell in row.strip("|").split("|")] + assert cells[0] == repository + assert f"[`{snapshot}`]" in cells[1] + assert cells[2] == "Admitted" + openviking_row = next( + line for line in baseline.splitlines() if line.startswith("| OpenViking |") + ) + openviking_cells = [ + cell.strip() for cell in openviking_row.strip("|").split("|") + ] + assert openviking_cells[2] == ( + "Candidate; not public authority while `#205` is open" + ) + assert ( + "## 3. OpenViking candidate packet " + "(non-authoritative while `#205` is open)" in baseline + ) def test_public_docs_keep_openviking_non_authoritative_until_issue_205_closes() -> None: - public_paths = ( + baseline_paths = ( + Path("CONTRIBUTING.md"), Path("README.md"), + Path("README.zh-CN.md"), Path("PLAN.md"), Path("STATUS.md"), - *sorted(Path("docs/design").rglob("*.md")), + Path("docs/agents/prd-contextengine-implementation.md"), + Path("docs/decisions/0016-implementation-authority-and-vertical-slice-roadmap.md"), + Path("docs/design/2026-07-18-context-engine-implementation-design.md"), + Path("docs/design/2026-07-26-repo-state-review-and-course-correction.md"), + Path("docs/security/Test-Architecture-与可验证性设计.md"), + Path("docs/security/安全负向测试清单.md"), + Path("docs/specs/2026-07-19-context-engine-implementation-epic.md"), ) - boundary_terms = ( - "candidate", - "non-authoritative", - "not authority", - "does not cite openviking as authority", - "不把 openviking 引作 authority", - "候选", - "no openviking code", - "no code or dependency is admitted", - "not_active", + public_paths = ( + *baseline_paths, + *sorted(Path("docs/design").rglob("*.md")), ) forbidden_authority_phrases = ( "conditionally admitted openviking", @@ -108,7 +189,10 @@ def test_public_docs_keep_openviking_non_authoritative_until_issue_205_closes() "allowlisted to dify, ragflow, maxkb, onyx, and openviking", ) - for path in public_paths: + for path in baseline_paths: + assert BASELINE_NAME in _read(path.as_posix()), path + + for path in dict.fromkeys(public_paths): document = _read(path.as_posix()) normalized_document = _collapse_whitespace(document).lower() assert ( @@ -124,7 +208,52 @@ def test_public_docs_keep_openviking_non_authoritative_until_issue_205_closes() if "openviking" in paragraph.lower() ) for paragraph in openviking_paragraphs: - assert any(term in paragraph for term in boundary_terms), (path, paragraph) + assert BASELINE_NAME in document, path + _assert_openviking_paragraph_is_non_authoritative(paragraph, path) + + +@pytest.mark.parametrize( + "paragraph", + ( + ( + "openviking is not authority while #205 is open. " + "openviking is authoritative." + ), + ( + "openviking remains non-authoritative while #205 is open. " + "we cite openviking as authority." + ), + ( + "openviking is authority but openviking is not authority " + "while #205 is open." + ), + ( + "openviking is not authority while #205 is open. " + "it is authoritative." + ), + ( + "openviking is not authority while #205 is open. " + "we cite openviking as public authority." + ), + ( + "openviking is not authority while #205 is open, but " + "openviking serves as authority." + ), + ( + "openviking is not authority while #205 is open. " + "openviking supplies authoritative evidence." + ), + "openviking is a candidate and remains not_active while #205 is open.", + "openviking is non-authoritative until the admission issue closes.", + ), +) +def test_openviking_paragraph_guard_rejects_incomplete_boundaries( + paragraph: str, +) -> None: + with pytest.raises(AssertionError): + _assert_openviking_paragraph_is_non_authoritative( + paragraph, Path("adversarial.md") + ) def test_openviking_public_evidence_uses_only_the_admitted_snapshot() -> None: @@ -145,14 +274,14 @@ def test_room_a_claim_permalinks_pin_exact_source_regions() -> None: source_urls = OPENVIKING_SOURCE_URL.findall(room_a) assert source_urls - assert all(EXACT_LINE_RANGE.search(url) for url in source_urls) + assert all(_has_exact_positive_line_range(url) for url in source_urls) claim_blocks = UPSTREAM_CLAIM_BLOCK.findall(room_a) assert len(claim_blocks) == 8 for claim in claim_blocks: claim_urls = OPENVIKING_SOURCE_URL.findall(claim) assert claim_urls, claim - assert all(EXACT_LINE_RANGE.search(url) for url in claim_urls) + assert all(_has_exact_positive_line_range(url) for url in claim_urls) capability_table = room_a.split( "# 2. 能力盘点 → ContextEngine 区域映射表", maxsplit=1 @@ -168,7 +297,16 @@ def test_room_a_claim_permalinks_pin_exact_source_regions() -> None: for row in capability_rows: row_urls = OPENVIKING_SOURCE_URL.findall(row) assert row_urls, row - assert all(EXACT_LINE_RANGE.search(url) for url in row_urls) + assert all(_has_exact_positive_line_range(url) for url in row_urls) + + +@pytest.mark.parametrize("line_range", ("#L0-L0", "#L20-L1", "#L1-L0")) +def test_exact_source_region_rejects_invalid_line_ranges(line_range: str) -> None: + assert not _has_exact_positive_line_range(f"https://example.test/file{line_range}") + + +def test_exact_source_region_accepts_ordered_positive_line_range() -> None: + assert _has_exact_positive_line_range("https://example.test/file#L1-L20") def test_openviking_copy_and_legal_authority_remain_closed() -> None: