提交gitea知识库方案
This commit is contained in:
@@ -0,0 +1,435 @@
|
||||
---
|
||||
title: Gitea知识库 v1.1 产品需求文档 PRD
|
||||
date: 2026-08-10
|
||||
type: PRD
|
||||
status: review-ready
|
||||
content_status: discussion
|
||||
owner: Verlit
|
||||
last_updated_at: 2026-08-10
|
||||
last_updated_by: Codex
|
||||
hash: sha256:f2abc96b306a2314d8abf6beef982b56a6bd5dd2147bee1adbc025305d0c9536
|
||||
hash_scope: Markdown 正文(从一级标题开始至文件末尾)的 UTF-8 SHA-256
|
||||
belongs_to:
|
||||
- "[[3-业务线/Gitea知识库/_context|Gitea知识库]]"
|
||||
depends_knowledge:
|
||||
- "[[3-业务线/Gitea知识库/公司共享 Context 项目仓库发布方案 v1|公司共享 Context 项目仓库发布方案 v1]]"
|
||||
- "[[3-业务线/Gitea知识库/公司共享 Context MCP-first 身份与审计方案 v1.1|公司共享 Context MCP-first 身份与审计方案 v1.1]]"
|
||||
- "[[3-业务线/Gitea知识库/v1.1-技术栈与详细实施设计|v1.1 技术栈与详细实施设计]]"
|
||||
- "[[3-业务线/Gitea知识库/v1-验收与止损矩阵|v1.1 验收与止损矩阵]]"
|
||||
---
|
||||
|
||||
# Gitea知识库 v1.1 产品需求文档 PRD
|
||||
|
||||
## 1. 文档结论
|
||||
|
||||
本 PRD 已具备进入 C1 代码开发评审的业务与工程完整度,但不代表已经授权开发、部署或连接真实环境。当前仍处于 `C0 本地工程设计构建`;下一阶段必须由 Verlit 明确宣布后才开始。
|
||||
|
||||
方案没有方向性缺陷,也没有偏离原 v1。原 v1 的“一项目一私仓、单向明确发布、发布网关唯一写 `main`、不可变 release、唯一 `main/current`、内容状态与事务状态分离、可恢复和可止损”保持不变;v1.1 只补充 MCP 唯一用户入口、飞书身份、内部权限数据库、Gitea 二次复核、受控本地来源、Agent 无关适配和强制审计。
|
||||
|
||||
本轮闭合了三项此前不够明确的实现问题:
|
||||
|
||||
1. MCP OAuth 由成熟 OAuth/OIDC Authorization Server 承担协议和令牌生命周期,飞书作为员工身份来源;不在业务服务内从零自研完整授权服务器。
|
||||
2. 飞书登录不等于 Gitea 授权;v1.1 试点通过受控预配置绑定飞书稳定 ID 与 Gitea 数字用户 ID,未绑定即拒绝。
|
||||
3. 中文检索首期采用 PostgreSQL `pg_trgm`+元数据过滤,不把面向英文分词的原生 FTS 当成中文主检索。
|
||||
|
||||
仍未确定的内容属于环境和治理参数,见第 17 节;它们不要求重写 PRD,但会在对应阶段形成硬门。
|
||||
|
||||
## 2. 产品定义
|
||||
|
||||
### 2.1 产品一句话
|
||||
|
||||
面向全员 Agent 工作方式,以飞书员工身份登录,通过统一远程 MCP 安全读取和发布项目级共享 Context,并由内部授权与 Gitea 仓库权限共同限制访问,所有人、Agent 和服务行为均可追溯。
|
||||
|
||||
### 2.2 战略位置
|
||||
|
||||
本业务线是“企业内部 AI 系统(先知识库、后 Agent)”的共享 Context 与权限治理底座。当前版本先证明知识库内容可被可靠发布、准确读取、即时撤权、完整审计;Skill Registry、正式审批和更多内容来源只在真实试点证明需要后进入后续版本。
|
||||
|
||||
### 2.3 产品入口
|
||||
|
||||
- 唯一用户业务入口:Agent Host 中配置的远程 MCP。
|
||||
- 首批 Agent adapter:Codex、Claude Code;其他 Agent 只需满足同一 adapter contract。
|
||||
- 允许的浏览器页面:飞书/OAuth 授权页及协议回调,不是业务 Web 页面。
|
||||
- 不建设:独立企业管理后台、权限页面、发布驾驶舱、审计 Web 页面。
|
||||
|
||||
## 3. 目标与非目标
|
||||
|
||||
### 3.1 v1.1 目标
|
||||
|
||||
- 每位员工使用自己的飞书身份完成 MCP OAuth,不使用共享账号。
|
||||
- 通过 `ProjectGrant ∩ Gitea live permission` 实现双层项目权限。
|
||||
- Agent 只能读取已授权项目唯一 `current`,不能默认读取 Git 历史、构建区或其他项目。
|
||||
- 用户可明确选择本地 Markdown/受控附件,经 Local Source Gate、构建、检查、diff 和一次性确认后发布。
|
||||
- `discussion` 和 `confirmed` 复用同一发布链,仅规则和所需权限不同。
|
||||
- 每次调用自动记录 human、agent、service 三主体以及请求、授权、结果和关联链。
|
||||
- 发布完成以 Git、release、current、检索索引和 MCP readback 一致为准。
|
||||
- 支持撤权、失败重试、过期请求、并发冲突和恢复发布。
|
||||
|
||||
### 3.2 非目标
|
||||
|
||||
- 不建设自定义业务 Web/移动页面。
|
||||
- 不让 Agent、LLM 或用户参数直接决定身份、角色和权限。
|
||||
- 不开放任意 SQL、Shell、Git、Gitea Admin、部署、迁移、备份、密钥或审计写删工具。
|
||||
- 不接入个人全部工作区,不递归扫描未选择目录。
|
||||
- 不在当前版本建设 Skill Registry、skill 审核表或 skill 发布流程。
|
||||
- 不做跨项目统一大库、跨项目检索后再由模型过滤。
|
||||
- 不把向量库、Elasticsearch、Kafka、Redis、Kubernetes 或微服务作为首期前置。
|
||||
|
||||
## 4. 角色与责任
|
||||
|
||||
| 角色 | 说明 | 允许行为 | 禁止行为 |
|
||||
|---|---|---|---|
|
||||
| 普通成员 | 已绑定飞书和 Gitea 的项目成员 | 读取、搜索授权项目;提交允许级别的构建请求 | 直接写 Git、修改权限、读取历史或其他项目 |
|
||||
| Publisher | 获得项目发布动作的成员 | 在检查和确认后提交 discussion/confirmed 发布 | 绕过网关、force push、修改审计 |
|
||||
| 治理人员 | 维护用户绑定、ProjectGrant、项目配置和例外 | 受控预配置、撤权、审批配置变更 | 通过普通 MCP 自行扩大权限 |
|
||||
| 审计人员 | 查看授权范围内的脱敏审计 | 查询、追踪、验证事件链 | 修改或删除审计事件 |
|
||||
| Agent Host | Codex、Claude Code 或兼容 Agent | 调用标准 MCP、展示确认、传递明确选择的内容 | 自报身份、扫描工作区、持有发布 Git 凭据 |
|
||||
| `contextd serve` | MCP resource server | 身份、授权、工具路由、读、请求入队、审计 | Gitea 写入、迁移、部署 |
|
||||
| `contextd worker` | 内部可靠任务执行者 | 构建、Git 写入、export、readback | 面向用户开放、Gitea Admin |
|
||||
|
||||
## 5. 系统边界与技术基线
|
||||
|
||||
```text
|
||||
飞书用户
|
||||
→ Codex / Claude Code / Other Agent
|
||||
→ Verlit Agent Compatibility Layer
|
||||
→ OAuth Authorization Server ↔ 飞书 OAuth
|
||||
→ Reverse Proxy → contextd serve (/mcp)
|
||||
→ PostgreSQL Identity/AuthZ/Release/Outbox/Audit/Search
|
||||
→ contextd worker → Gitea 私仓 → immutable release/current
|
||||
→ MCP readback → Agent
|
||||
```
|
||||
|
||||
| 能力 | 技术基线 |
|
||||
|---|---|
|
||||
| 服务端 | Go 1.26.x,官方 Go MCP SDK v1.7.x,`net/http` |
|
||||
| MCP | Streamable HTTP;目标 2026-07-28,兼容 2025-11-25 |
|
||||
| OAuth | 成熟 OAuth/OIDC Authorization Server+飞书身份联邦;Authorization Code+PKCE |
|
||||
| 数据库 | PostgreSQL 18.x,`pgx/v5`、`sqlc`、`goose` |
|
||||
| 可靠任务 | PostgreSQL transactional outbox,独立 `worker` 运行角色 |
|
||||
| 仓库 | Gitea 1.26.x 支持分支;每项目一私仓;受保护 `main` |
|
||||
| Git | 系统 Git CLI、临时 worktree、非 force push、CAS/`base_current` |
|
||||
| 内容 | `goldmark` AST+JSON Schema 2020-12+确定性 builder |
|
||||
| 中文检索 | PostgreSQL `pg_trgm`+标题/标签/路径/正文元数据过滤 |
|
||||
| 审计 | PostgreSQL 独立 schema/角色、append-only、hash chain、每日 checkpoint |
|
||||
| 观测 | OpenTelemetry;正文、token、绝对路径不进入日志或 trace |
|
||||
| 制品 | OCI 镜像、固定 digest、SBOM;首期不要求 Kubernetes |
|
||||
|
||||
## 6. 端到端闭环总览
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
G[治理预配置] --> L[飞书 OAuth 登录]
|
||||
L --> B{绑定与状态有效?}
|
||||
B -- 否 --> D[拒绝并审计]
|
||||
B -- 是 --> T[MCP 会话]
|
||||
T --> A[双层授权]
|
||||
A --> R[读取 / 搜索 current]
|
||||
A --> S[本地明确选择]
|
||||
S --> V[构建 / 校验 / diff]
|
||||
V --> C[人类一次性确认]
|
||||
C --> Q[发布请求 + outbox]
|
||||
Q --> W[worker Git/CAS]
|
||||
W --> E[immutable release + current + index]
|
||||
E --> K[MCP readback]
|
||||
K --> Z[完成回执]
|
||||
Z --> R
|
||||
Q -. every step .-> U[三主体审计]
|
||||
W -- 失败 --> F[failed / retry / recovery release]
|
||||
F --> Q
|
||||
X[撤权/停用] --> D
|
||||
```
|
||||
|
||||
闭环定义:一次发布只有在 `release record completed ∩ Gitea commit 可读 ∩ immutable release 校验通过 ∩ current 指向该 release ∩ search index 同版本 ∩ MCP readback hash 一致 ∩ completed 审计已落盘` 时完成。任何一项失败都不得返回成功。
|
||||
|
||||
## 7. 每一步调用、功能与输出
|
||||
|
||||
下表是 Canvas 的文字真源。`A1` 为普通读,`A2` 为受控构建,`A3` 为 discussion 发布,`A4` 为 confirmed/恢复发布。
|
||||
|
||||
| 步骤 | 谁发起 | 调用内容 | 实现功能 | 成功输出 | 失败/审计 |
|
||||
|---|---|---|---|---|---|
|
||||
| S00 治理预配置 | 治理人员/运维 | 受控 migration/import;`user_identities`、`feishu_bindings`、`gitea_bindings`、`projects`、`project_grants` | 建立飞书稳定 ID、Gitea 数字 ID、项目和动作授权映射 | 版本化配置记录、导入报告、审计关联 ID | 冲突或重复即整批拒绝;不暴露普通 MCP 写工具 |
|
||||
| S01 发现资源 | Agent Host | `POST /mcp`;`/.well-known/oauth-protected-resource` | 发现 MCP resource 与授权服务器 | PRM、授权服务器地址、resource/audience | Origin/Host/protocol 不合法即拒绝并记 `request_denied` |
|
||||
| S02 飞书 OAuth | Agent adapter | Authorization Code+PKCE → 授权服务器 → 飞书 authorize/token/user info | 验证真实飞书员工身份,抵抗 code/token 截获 | 飞书 claims、内部 subject 候选 | state/PKCE/tenant/redirect 不一致即失败;不落飞书明文 token |
|
||||
| S03 绑定激活 | Identity federation adapter | 查询 `FeishuBinding`、`GiteaBinding`、`UserIdentity` | 仅激活唯一预配置的飞书—内部—Gitea 映射 | active internal `user_id` | 未配置进入 `binding_pending`;冲突/停用进入 denied;均审计 |
|
||||
| S04 MCP 凭据 | Authorization Server | token/refresh/revoke;`AgentSession` | 为当前人和 Agent client 创建短期会话 | access token、session、scope、expiry | token 不进入业务日志;会话可即时撤销 |
|
||||
| S05 身份自查 | 用户/Agent | `get_my_identity`、`get_my_project_roles` | 展示本人身份、绑定状态和可用角色,不接受参数冒充 | 脱敏 identity/role 摘要 | 只返回 token subject;记录 human/agent/service |
|
||||
| S06 列出项目 | 用户/Agent | `list_authorized_projects` | 先查 ProjectGrant,再实时查 Gitea permission | 两层均允许的项目列表 | Gitea 不可用、任一层拒绝即 fail closed |
|
||||
| S07 读取 current | 用户/Agent | `get_current_manifest`、`read_artifact`、`verify_release_hash` | 读取唯一 current 的 manifest、正文和校验信息 | project/release/content status/hash/content | 禁止 history/build/private source;每个 project 再鉴权 |
|
||||
| S08 搜索 current | 用户/Agent | `search_current` → ProjectGrant/Gitea → `pg_trgm` | 仅在已授权项目 current 内进行中文搜索 | 带 project/release/hash 的命中片段 | 先过滤项目再查询;不做跨项目结果后过滤 |
|
||||
| S09 本地选择 | 用户+adapter | Local Source Gate;允许根、真实路径、类型、大小、secret/PII 预检 | 只读取用户明确选择的本地 Markdown/附件 | 文件数、相对 label、size/hash 预览 | 越界、符号链接、控制文件、秘密/PII 命中即本地阻断 |
|
||||
| S10 人类确认来源 | 用户+框架确认服务 | 展示选择清单 → 签发 selection confirmation | 确认上传范围,不把 Agent 的自然语言当授权 | 一次性确认、Selection Manifest | 用户取消或 manifest 变化即废弃;不上传未选内容 |
|
||||
| S11 分块传输 | Agent adapter | `create_selection`、`append_selection_content` | 将选中内容以固定 chunk 送入隔离临时区 | selection ID、完整度、server-computed hash | 缺块、乱序、超时、hash 不符即废弃整个 selection |
|
||||
| S12 构建预览 | 用户/Agent | `build_preview` → deterministic builder | 规范化 Markdown、收集附件、改写链接、生成 manifest | candidate artifact、candidate hash、构建报告 | 不由 LLM 决定确定性结果;同输入同版本 hash 相同 |
|
||||
| S13 完整校验 | 用户/Agent | `validate_release_request` → schema/link/path/secret/PII/policy scanner | 拦截结构、路径、凭据、隐私和规则问题 | validation report、policy version、blocking findings | blocking finding 不得继续;例外必须引用受控记录 |
|
||||
| S14 差异预览 | 用户/Agent | `preview_release_diff` → current reader | 把 candidate 与 `base_current` 比较 | 文件/章节/附件变化、candidate hash、base_current | current 已变化则标 stale,要求重新构建 |
|
||||
| S15 发布确认 | 真实用户+框架确认服务 | 固定展示 project/action/hash/base/diff → `confirmation_id` | 给 A3/A4 生成与精确请求 hash 绑定的一次性授权 | 5 分钟内有效的 confirmation ID | 不能复用、转让或跨 hash;Agent 原生 prompt 不是最终真源 |
|
||||
| S16 提交发布 | Publisher/Agent | `submit_discussion_release` 或 `submit_confirmed_release` | 创建幂等发布记录并提交 outbox | release ID、queued 状态、correlation ID | 请求、release、outbox、审计同一事务;失败不入队 |
|
||||
| S17 网关复核 | `contextd serve` | token/user/binding/session/grant/policy/Gitea/confirmation 全链检查 | 在写动作前再次执行双层权限和确认校验 | allowed decision+policy evidence | 任一条件失败即 denied;不以工具参数覆盖主体 |
|
||||
| S18 Worker 领取 | `contextd worker` | `FOR UPDATE SKIP LOCKED` claim outbox;idempotency key | 可靠领取一次发布任务,允许安全重试 | processing 状态、attempt、worker identity | 重复事件返回同一 release;审计 worker 主体 |
|
||||
| S19 Git/CAS 发布 | worker | 临时 worktree、Gitea read/write credential、Git commit/push | 再验 `base_current`,生成完整新 `current/`,单 commit 非 force push | commit SHA、release manifest | non-fast-forward → `STALE_BASE`;token 不进命令行/日志 |
|
||||
| S20 导出与切换 | worker | immutable export、checksum、原子 current pointer | 从 commit 生成不可变 release,并原子切换唯一 current | release path、current version、checksums | 校验失败不切 current;旧 release 保留供恢复 |
|
||||
| S21 激活检索 | worker | 构建 `pg_trgm` search document/index | 让搜索版本与 current 保持一致 | `project_id+release_id` index active | 索引失败则发布不 completed;不得搜索旧/半成品索引 |
|
||||
| S22 MCP 读回 | worker/internal reader | `get_current_manifest`、`read_artifact` 等同业务读取链 | 用用户将使用的路径验证结果,不只检查磁盘 | readback release/hash/content status | Git/current/MCP 任一不一致即 failed,不能伪成功 |
|
||||
| S23 完成回执 | serve/worker | 更新 `release_records`、写 completed audit、`get_release_status` | 对用户给出可验证发布结果 | release ID、commit、current/hash、readback、timestamps | completed 审计无法落盘则不返回 completed |
|
||||
| S24 后续消费 | 用户/Agent | S07/S08 | 后续会话只消费唯一 current,闭合“发布→读取” | 与 S23 相同 release/hash | 若不一致触发完整性告警,停止扩散 |
|
||||
| S25 审计查询 | 本人/审计人员 | `list_my_actions`、`trace_release`、`trace_correlation`、`verify_audit_event` | 查询脱敏行为、追踪发布全链并验证 hash chain | human/agent/service、decision、result、correlation | 查询也需授权并被审计;无审计写删工具 |
|
||||
| S26 撤权/离职 | 治理人员/身份事件 | 受控更新 binding/grant/session;OAuth revoke | 使飞书、Gitea、内部权限或会话任一撤销立即生效 | revoked version、session invalidation、审计 | 下一次调用 fail closed;不等待 access token 自然到期 |
|
||||
| S27 失败与重试 | 系统/Publisher | `get_release_status`、幂等重试、`cancel_precommit_release` | 区分可重试、需重建、需人工处置的失败 | stable error code、attempt、next action | 已产生 commit 后不可“删除历史式回滚” |
|
||||
| S28 恢复发布 | Publisher+确认人 | 从已知良好 release 新建 A4 release | 通过新 commit 恢复 current,保留完整历史 | 新 release/commit/current、恢复原因 | 仍需双层权限、完整检查和一次性确认 |
|
||||
|
||||
## 8. 功能需求
|
||||
|
||||
### FR-01 身份与会话
|
||||
|
||||
- 每位用户必须独立 OAuth;同一 Agent Host 上不同用户的 token、session、审计主体不得串用。
|
||||
- 飞书身份键至少包含 `tenant_key+open_id`,在权限允许时保留租户内稳定 `user_id`;邮箱、手机号、姓名不作为主键。
|
||||
- MCP resource server 不直接信任 Feishu token;由授权服务器完成联邦并签发 MCP 资源令牌。
|
||||
- 未预配置 GiteaBinding 的用户只能看到绑定待处理状态,不可列出项目。
|
||||
- access token、refresh/session、binding 和 grant 均可撤销;每次调用重新检查权限版本。
|
||||
|
||||
### FR-02 双层授权
|
||||
|
||||
- 第一层:内部 `ProjectGrant` 决定项目、角色、动作、有效期和 sensitivity policy。
|
||||
- 第二层:Gitea 当前仓库权限决定该 Gitea 账户是否仍可读取项目。
|
||||
- 有效权限是两层交集;禁止用并集、兜底角色或 Agent 声明放宽。
|
||||
- 首期不缓存 Gitea 的 allow 结果;Gitea 超时或错误时 fail closed。
|
||||
- A3/A4 另需一次性精确确认;确认不替代双层授权。
|
||||
|
||||
### FR-03 读取与搜索
|
||||
|
||||
- 只允许读取 `main/current` 对应的不可变 release。
|
||||
- 响应必须带 `project_id`、`release_id`、`content_status`、manifest/hash,便于 Agent 判断来源。
|
||||
- 搜索必须在 SQL 查询前确定授权项目集合,并以 project/release 作为强过滤条件。
|
||||
- 不返回构建临时区、私人来源、Git 历史、其他分支或未发布 candidate。
|
||||
|
||||
### FR-04 Local Source Gate
|
||||
|
||||
- 允许根由企业/框架配置,正文和 Agent 无权更改。
|
||||
- 用户必须明确选择文件或章节;目录选择仅枚举该选择范围,禁止默认扫描整个工作区。
|
||||
- 解析真实路径后拒绝工作区外路径、符号链接逃逸、`.git`、凭据目录、隐藏控制文件和不允许的二进制。
|
||||
- 本地先做 secret/PII 预检,服务端收到后再次做完整策略检查;客户端通过不等于服务端放行。
|
||||
- 只传相对 source label,不传个人绝对路径;正文不进入普通日志、trace 或审计详情。
|
||||
|
||||
### FR-05 构建与验证
|
||||
|
||||
- builder 输入为 Selection Manifest+内容+固定 builder/policy/schema version。
|
||||
- 同输入和相同版本必须得到同 candidate hash。
|
||||
- validation 至少覆盖 schema、Markdown 结构、内部链接、附件引用、路径、凭据、PII、控制文件、大小和内容状态。
|
||||
- blocking finding 无法通过 Agent 解释绕过;例外必须是受控配置并进入审计。
|
||||
|
||||
### FR-06 发布
|
||||
|
||||
- `discussion` 与 `confirmed` 使用同一 pipeline;confirmed 需要更高权限/确认,但不复制另一套写入逻辑。
|
||||
- 提交必须引用 `candidate_hash+base_current+confirmation_id+idempotency_key`。
|
||||
- 只有 project-scoped publish gateway credential 可以非 force push 受保护 `main`。
|
||||
- current 必须通过完整目录构建后原子切换,不能在服务目录逐文件修改。
|
||||
|
||||
### FR-07 审计
|
||||
|
||||
- 每次工具调用产生 `request_received → allowed/denied → completed/failed` 事件链。
|
||||
- 每个事件至少记录 human、agent、service、session、tool、action、project、request hash、policy、authorization、confirmation、result、correlation。
|
||||
- `request_received` 无法持久化时拒绝业务调用。
|
||||
- 普通运行身份无 `audit_events` update/delete;查询只走脱敏 view。
|
||||
- 事件使用 canonical JSON hash chain,每日生成签名 checkpoint 并纳入备份。
|
||||
|
||||
### FR-08 失败、撤权和恢复
|
||||
|
||||
- 对外返回稳定错误码和下一步建议,不泄露其他项目、主体或内部路径。
|
||||
- 可重试错误保持相同 idempotency key;current 已变化返回 `STALE_BASE` 并要求重建。
|
||||
- 已完成 Git commit 不做历史删除式回滚;恢复必须创建新 release。
|
||||
- 撤权后下一次调用即失败,并可通过 correlation 追溯撤销主体和影响会话。
|
||||
|
||||
## 9. MCP 工具清单
|
||||
|
||||
| 分组 | 工具 | 风险等级 | 是否需人类确认 |
|
||||
|---|---|---:|---|
|
||||
| 身份/读取 | `get_my_identity`、`list_authorized_projects`、`get_my_project_roles`、`get_current_manifest`、`read_artifact`、`search_current`、`verify_release_hash` | A1 | 否;客户端可保留普通 tool prompt |
|
||||
| 选择/构建 | `create_selection`、`append_selection_content`、`build_preview`、`validate_release_request`、`preview_release_diff` | A2 | 来源上传前需要明确范围确认;不是发布确认 |
|
||||
| 发布 | `submit_discussion_release` | A3 | 是,一次性精确确认 |
|
||||
| 高等级发布/恢复 | `submit_confirmed_release` | A4 | 是,一次性精确确认+更高角色 |
|
||||
| 状态控制 | `get_release_status`、`cancel_precommit_release` | A1/A2 | 取消只允许 commit 前;记录审计 |
|
||||
| 审计查询 | `list_my_actions`、`get_action_detail`、`trace_release`、`trace_correlation`、`list_project_audit_events`、`verify_audit_event` | A1/A2 | 按审计角色和项目范围授权 |
|
||||
|
||||
以下能力绝不注册为普通 MCP tool:用户/Gitea 绑定写入、ProjectGrant 写入、数据库迁移、部署、备份/恢复、密钥管理、Gitea Admin、通用 Git、Shell/SQL、审计写入/删除、功能动作开关修改。
|
||||
|
||||
## 10. 数据与状态
|
||||
|
||||
### 10.1 核心数据对象
|
||||
|
||||
| 领域 | 对象 |
|
||||
|---|---|
|
||||
| 身份 | `UserIdentity`、`FeishuBinding`、`GiteaBinding`、`AgentSession`、`MCPToken/claims` |
|
||||
| 授权 | `Project`、`ProjectGrant`、`PolicyVersion`、`Confirmation` |
|
||||
| 来源与构建 | `Selection`、`SelectionChunk`、`Artifact`、`ValidationReport` |
|
||||
| 发布 | `ReleaseRecord`、`CurrentVersion`、`IdempotencyRecord`、`OutboxEvent` |
|
||||
| 搜索 | `CurrentSearchDocument(project_id, release_id, field, normalized_text)` |
|
||||
| 审计 | `AuditEvent`、`AuditCheckpoint`、`Correlation` |
|
||||
|
||||
### 10.2 状态机
|
||||
|
||||
```text
|
||||
selection: created → receiving → sealed → consumed | expired | rejected
|
||||
release: requested → queued → processing → committed → exported → indexed → readback_verified → completed
|
||||
↘ failed / stale_base / cancelled_before_commit
|
||||
binding: pending → active → suspended | revoked
|
||||
session: active → expired | revoked
|
||||
```
|
||||
|
||||
- 不认识的状态一律拒绝,不自动映射为成功。
|
||||
- `completed` 是最终一致性事实,不等同于“任务已入队”或“Git push 已返回成功”。
|
||||
- `content_status`(discussion/confirmed)与 `release status`(queued/completed/failed)保持两个字段。
|
||||
|
||||
## 11. 安全默认值
|
||||
|
||||
以下值作为 C1 合成环境的可执行默认值;G0 可按安全评审收紧或调整,但不得取消对应控制。
|
||||
|
||||
| 参数 | 默认值 |
|
||||
|---|---|
|
||||
| MCP access token | 15 分钟;issuer/audience/resource/scope/client 必验 |
|
||||
| AgentSession/refresh | 8 小时;撤权即时失效 |
|
||||
| 发布 confirmation | 5 分钟、一次性、绑定 user/session/tool/project/request hash |
|
||||
| Selection TTL | 30 分钟;完成立即清理,失败最长保留 30 分钟后清理 |
|
||||
| Markdown 单文件 | 2 MiB |
|
||||
| 允许附件 | `.png`、`.jpg`、`.jpeg`、`.webp`、`.pdf`;只作为受控附件,不自动执行 |
|
||||
| 附件单文件 | 5 MiB |
|
||||
| Bundle 总量 | 10 MiB、最多 100 个文件 |
|
||||
| MCP chunk | 256 KiB 原始内容;每块带序号和 hash |
|
||||
| 路径 | 仅中央配置允许根;拒绝 symlink/junction/reparse point 逃逸 |
|
||||
| Gitea allow cache | 关闭;每次项目访问实时复核 |
|
||||
| Idempotency | 同 key 24 小时内返回同一 release;payload hash 不同则冲突 |
|
||||
| 普通日志 | 不记录 token、正文、附件、绝对路径、完整 diff |
|
||||
| 审计试点保留建议 | 在线 365 天;checkpoint/备份 3 年,G0 结合制度确认 |
|
||||
| 试点恢复建议 | RPO 24 小时、RTO 8 小时;G0 可收紧 |
|
||||
|
||||
## 12. 非功能需求
|
||||
|
||||
### 12.1 性能与容量试点目标
|
||||
|
||||
- `get_my_identity`/项目列表:无外部故障时 p95 ≤ 2 秒。
|
||||
- current manifest/read:不含大正文传输时 p95 ≤ 2 秒。
|
||||
- 10 万个 current 文档以内的单项目中文搜索:p95 ≤ 3 秒;以合成和真实试点基准为准。
|
||||
- 10 MiB 以内发布从 queued 到 readback completed:p95 ≤ 60 秒,不以牺牲校验换取速度。
|
||||
- 单用户同时最多 3 个 receiving selection、1 个 processing release;每项目发布串行化。
|
||||
|
||||
### 12.2 可用性与一致性
|
||||
|
||||
- 试点目标月可用性 99.5%,不含已公告维护。
|
||||
- Gitea、数据库、授权服务器或审计写入不可用时,权限与发布 fail closed。
|
||||
- 读取可在 Git 暂时不可用时继续使用已校验的 current,但必须验证 manifest/hash;任何完整性异常立即停止读取。
|
||||
- 重启、worker 重复领取、网络超时不得产生两个 current 或重复 commit。
|
||||
|
||||
### 12.3 可观测性
|
||||
|
||||
- 公开指标:请求量、拒绝原因码、外部依赖延迟、outbox backlog、release 状态耗时、readback mismatch、撤权生效延迟。
|
||||
- trace 使用 correlation ID 串联 serve、DB、worker、Gitea、export、readback;不包含正文和秘密。
|
||||
- 审计是合规事实,普通日志和 trace 不能替代审计。
|
||||
|
||||
## 13. 异常与恢复矩阵
|
||||
|
||||
| 场景 | 系统行为 | 用户下一步 |
|
||||
|---|---|---|
|
||||
| 未预配置 Gitea 绑定 | `BINDING_PENDING`,不给项目列表 | 联系治理人员完成受控预配置 |
|
||||
| ProjectGrant 允许但 Gitea 拒绝 | `PERMISSION_DENIED_SECOND_LAYER` | 检查 Gitea 项目成员关系;不得自动放宽 |
|
||||
| Gitea 权限 API 超时 | `AUTHZ_DEPENDENCY_UNAVAILABLE`,fail closed | 稍后重试;审计保留依赖故障 |
|
||||
| Local Source Gate 命中 secret/PII | 本地阻断且不传正文 | 移除/脱敏后重新选择 |
|
||||
| 分块缺失/hash 不符 | selection rejected,全量清理 | 重新创建 selection |
|
||||
| validation blocking finding | 不生成可发布确认 | 修正文档或走受控例外评审 |
|
||||
| confirmation 过期/被用过 | `CONFIRMATION_INVALID` | 重新查看 diff 并确认 |
|
||||
| `base_current` 已变化 | `STALE_BASE` | 重新 build/validate/diff/confirm |
|
||||
| Git 已提交但 export/index/readback 失败 | release failed,保留 commit,不宣告 completed | 修复依赖后幂等续跑或发恢复 release |
|
||||
| completed 审计落盘失败 | 不返回 completed | 系统重试,治理人员排查 audit store |
|
||||
| 撤权/离职 | session/grant/binding version 失效 | 重新授权前任何访问均拒绝 |
|
||||
| current 完整性异常 | 停止读取和扩散,触发告警 | 从已知良好 release 发起恢复发布 |
|
||||
|
||||
## 14. 代码开发与实施拆解
|
||||
|
||||
### 14.1 C1 代码开发(需要 Verlit 另行授权)
|
||||
|
||||
| 阶段 | 实现内容 | 明细产物 | 退出条件 |
|
||||
|---|---|---|---|
|
||||
| C1-00 | Codex/Claude Code adapter contract | MCP 配置样例、fake OAuth、确认和 Local Source Gate 契约测试 | 两个 adapter 使用同一工具 schema;单个失败不降低核心控制 |
|
||||
| C1-01~03 | 工程、契约、领域、DB | Go module、contracts、migration、sqlc、测试夹具 | 离线 build/test,状态/约束/最小 DB role 通过 |
|
||||
| C1-04~06 | OAuth、绑定、双层授权、MCP、审计 | authorization server 集成、Feishu/Gitea fake、middleware、outbox | 冒充、未绑定、撤权、审计中断用例均 fail closed |
|
||||
| C1-07~08 | current 读取、中文搜索、Local Source Gate、build/validate | 第一/二批 MCP tools、`pg_trgm` benchmark、scanner | 跨项目、历史、越界路径、secret/PII、超限均阻断 |
|
||||
| C1-09~10 | release/export/readback、审计查询、OTel | 第三/四批 tools、worker、Git fake、完整性验证 | 并发、幂等、失败续跑、三主体审计通过 |
|
||||
| C1-11~12 | 安全/恢复测试与制品 | 测试报告、OCI、SBOM、checksum、运行手册 | M01~M10、开发态 T 用例通过;无秘密、无自动部署 |
|
||||
|
||||
### 14.2 G0~G5 真实实施(需要单独授权且先确认第 17 节)
|
||||
|
||||
1. G0:确认人、项目、OAuth/飞书/Gitea/服务器/审计/备份参数。
|
||||
2. G1:测试环境基础设施和合成用户/项目,不接真实内容。
|
||||
3. G2:导入真实绑定和 ProjectGrant,验证双层权限与撤权。
|
||||
4. G3:按“只读 → 构建 → discussion → confirmed/恢复”逐批开放工具。
|
||||
5. G4:安全、凭据轮换、备份和空环境恢复。
|
||||
6. G5:一个低敏感真实项目试点,以真实用户结果和止损矩阵决定是否扩展。
|
||||
|
||||
## 15. 验收标准
|
||||
|
||||
### 15.1 产品级必须通过
|
||||
|
||||
- 两名用户通过各自 OAuth 连接同一 MCP,身份、项目、token、session、审计不串用。
|
||||
- 未绑定、内部授权拒绝、Gitea 拒绝、Gitea 不可用、撤权五类场景全部 fail closed。
|
||||
- Agent 无法通过工具参数、prompt、伪造 username 或复用 confirmation 提升权限。
|
||||
- Local Source Gate 只能上传明确选择内容;越界、符号链接、secret/PII、超限和 hash 错误全部阻断。
|
||||
- discussion/confirmed 均经过 build、validation、diff、确认、CAS、Git、export、index、readback。
|
||||
- 并发发布不会产生两个 current;失败不会返回伪成功。
|
||||
- 发布回执、Gitea commit、immutable release、current、search、MCP readback 的 release/hash 完全一致。
|
||||
- human、agent、service 三主体链完整;审计事件可验证且普通角色无法修改删除。
|
||||
- 撤权后下一次调用拒绝;备份可在隔离环境恢复并使旧凭据失效。
|
||||
|
||||
### 15.2 止损信号
|
||||
|
||||
- 出现共享账号、共享 token、绕过 MCP 的业务写入口。
|
||||
- 出现内部授权或 Gitea 任一层被忽略。
|
||||
- Agent 能读取未选择本地内容、未授权项目、历史或构建区。
|
||||
- 出现两个 current、force push、Git 历史删除或无法恢复的备份。
|
||||
- 审计可被普通运行身份修改/删除,或关键动作在无 `request_received` 情况下执行。
|
||||
- 为兼容单个 Agent 而取消 OAuth、确认、Local Source Gate 或审计。
|
||||
|
||||
命中任一项即停止新增项目和扩大用户范围,先恢复到只读或 `forced_off`。
|
||||
|
||||
## 16. PRD 追溯矩阵
|
||||
|
||||
| 本 PRD 内容 | 上游依据 | 关系 |
|
||||
|---|---|---|
|
||||
| 一项目一私仓、唯一 current、发布状态与内容状态 | 原 v1 | 原样继承 |
|
||||
| MCP 唯一入口、飞书身份、双层权限、三主体审计 | v1.1 覆盖方案 | 差量补充 |
|
||||
| Agent adapter、Go/PostgreSQL/Gitea/outbox | 技术栈设计 | 实现选择 |
|
||||
| 成熟授权服务器 | MCP OAuth 安全边界 | 补齐实现责任,不改业务目标 |
|
||||
| 飞书—Gitea 预配置绑定 | 双层权限的安全开户流程 | 补齐未绑定/冒充路径 |
|
||||
| `pg_trgm` 中文检索 | “只搜索授权 current”的实现 | 修正中文检索技术选型 |
|
||||
| Skill Registry 后置 | 当前版本边界 | 明确不纳入 v1.1 |
|
||||
|
||||
## 17. 仍需确认的实施参数
|
||||
|
||||
这些不是架构问题,也不需要重新生成设计稿;它们按“开始哪一步、确认哪一项”处理。
|
||||
|
||||
| Gate | 最迟时间 | 必须提供/决定 | 没有时的处理 |
|
||||
|---|---|---|---|
|
||||
| DG-01 主栈 | C1-01 前 | 团队是否能长期维护 Go | 否则暂停并重新评审 TypeScript 主栈,不双栈混用 |
|
||||
| DG-02 OAuth AS | C1-04 前 | 可复用的成熟 OAuth/OIDC Authorization Server;若无,批准独立产品及责任人 | 不实现真实 token 签发,只保留 fake auth |
|
||||
| DG-03 Agent 版本 | C1-00 前 | Codex、Claude Code 支持版本与企业配置分发方式 | 只做通用 contract,不声明该 adapter 可用 |
|
||||
| DG-04 确认服务 | C1-05 前 | 签名算法、密钥托管、TTL、单次消费存储 | A3/A4 工具不注册 |
|
||||
| DG-05 Local Source Policy | C1-08 前 | 允许根、类型、大小、secret/PII 规则、临时保留 | 使用第 11 节合成测试默认值,不接真实文件 |
|
||||
| DG-06 飞书 | G0 前 | 自建 App、管理员、redirect domain、tenant、scope | 不连接飞书 |
|
||||
| DG-07 Gitea | G0 前 | 新建/复用、版本、管理员、权限 API、项目级服务凭据 | 不连接 Gitea |
|
||||
| DG-08 人和项目 | G2 前 | 试点项目、成员、Publisher、绑定清单、ProjectGrant、治理/审计责任人 | 不导入真实主体和内容 |
|
||||
| DG-09 环境 | G1 前 | Linux/容器、域名/TLS、PostgreSQL、反向代理、密钥与监控产品 | 不部署 |
|
||||
| DG-10 治理 | G1/G4 前 | 审计保留、脱敏、RPO/RTO、备份路径、事故联系人 | 不进入真实试点 |
|
||||
|
||||
## 18. 评审与下一步
|
||||
|
||||
### 18.1 当前可以确认的结论
|
||||
|
||||
- PRD、技术方案和闭环流程可以定稿为“review-ready”。
|
||||
- 当前没有必要重新改写原 v1,也不需要创建新的业务版本。
|
||||
- 不需要安装新的绘图或文档能力;本 vault 可直接承载 Markdown PRD 与 Obsidian Canvas。
|
||||
- 当前不部署、不运行、不连接飞书/Gitea/服务器、不创建代码仓库。
|
||||
|
||||
### 18.2 下一条授权应如何表述
|
||||
|
||||
若要进入代码阶段,可明确下达:
|
||||
|
||||
> 进入 Gitea 知识库 v1.1 的 C1 代码开发,只使用 fake Feishu/Gitea、合成身份和本地临时 PostgreSQL;先执行 C1-00~C1-03,不连接真实环境、不部署。
|
||||
|
||||
若要进入真实实施,必须在 C1 制品通过验收后,再按第 17 节补齐对应参数并单独授权 G0/G1,不能从“文档完成”直接跳到生产部署。
|
||||
Reference in New Issue
Block a user