feat: add org admin project onboarding foundation

This commit is contained in:
2026-07-10 00:25:00 +08:00
parent 2b7aa3294f
commit 34e07e229f
16 changed files with 1072 additions and 38 deletions
+11 -12
View File
@@ -6,14 +6,12 @@ import Spec.Prelude
ADR-0001 的核心:一个 project 对应一个**长生命周期**飞书项目群;群是协作空间,**不是锁
owner**(锁归 `AgentRun`,见 `Lock` / ADR-0002),不是临时处理 session。群可在无 Claude
处理时保持开启;教师离群/静音与项目权限、与 Claude 生命周期相互独立。本模块钉死
project↔group 的一对一绑定——likec4 画得出"project has group",画不出"恰好一个、且群
不持锁"。
project↔group 的**active**一对一绑定——likec4 画得出"project has group",画不出"恰好一个、
且群不持锁"。
**群失效态与绑定快照(`OPEN`, ADR-0001 Consequences):** 群解散/归档/不可达时,
`GroupBinding` 快照应变为 `none`(解绑、允许 rebind)还是保持 `some` 但指向失效 chat
(悬挂、待管理员干预)未决策。ADR-0001 已点名 "rebinding or group archival needs
explicit product rules";本模块只刻画健康态 1:1 不变式,不臆造失效态语义。实现遇到
群解散必须 surface,不得默认任一方。
**绑定历史(`PINNED`, ADR-0021):** active binding 严格 1:1;实现可以保留 archived
historical binding rows 供审计/纠错,但 `GroupBinding` 谓词只刻画当前 active 快照。
群解散/不可达的自动化处理仍为 `OPEN`;pilot 纠错由 org admin 显式归档绑定。
-/
namespace Spec.System
@@ -27,13 +25,14 @@ structure ProjectGroup where
group";chat 标识见 `Identifiers.ChatId`)。 -/
chat : I.ChatId
/-- 项目↔群绑定表(`PINNED` 每项目至多一个群, ADR-0001)。`ProjectId → Option ChatId` 的
结构本身即"一个 project 至多绑一个群"(由 `Option` 自带);良构补另一半——单射。 -/
/-- 项目↔active 群绑定表(`PINNED` 每项目至多一个 active 群, ADR-0001/0021)。
`ProjectId → Option ChatId` 的结构本身即"一个 project 至多绑一个 active 群"(由 `Option`
自带);良构补另一半——单射。 -/
def GroupBinding := I.ProjectId Option I.ChatId
/-- 绑定良构:**单射**——不同 project 不绑同一 chat(`PINNED` 1:1 的另一半, ADR-0001)。
"每 project 至多一个群"由 `Option` 结构自带;这条钉死"每群至多属于一个 project"。群
rebinding/archival 是生命周期事件(ADR-0001 Consequences),不在本快照不变式内。 -/
/-- Active 绑定良构:**单射**——不同 project 不绑同一 active chat(`PINNED` 1:1 的另一半,
ADR-0001/0021)。"每 project 至多一个群"由 `Option` 结构自带;这条钉死"每群至多属于一个
project"。archived historical bindings 不在本快照不变式内。 -/
def GroupBinding.WellFormed (b : GroupBinding I) : Prop :=
p₁ p₂ c, b p₁ = some c b p₂ = some c p₁ = p₂