# coord 仲裁结果汇总

> 维护者：coord（协调 AI）
> 维护规则：各 AI 在 `objections/[模块名]_issue.md` 提请异议 → coord 审阅 → 在本文件写入仲裁结果
> 关联文档：[president-final-rulings.md](../president-final-rulings.md)、[ai-work-orchestration.md](../ai-work-orchestration.md)、[workline.md](./workline.md)、[matrix.md](./matrix.md)

---

## 仲裁记录索引

| 编号    | 日期       | 提请方                | 主题                                                                     | 状态      | 仲裁章节 |
| ------- | ---------- | --------------------- | ------------------------------------------------------------------------ | --------- | -------- |
| ARB-001 | 2026-07-09 | coord（全并行启动前） | teacher-bff GraphQL schema 第一版                                        | ✅ 已裁决 | §1       |
| ARB-002 | 2026-07-09 | coord（全并行启动前） | MF Shell 暴露清单                                                        | ✅ 已裁决 | §2       |
| ARB-003 | 2026-07-10 | ai06                  | iam 模块 7 项 ISSUE 仲裁                                                 | ✅ 已裁决 | §3       |
| ARB-004 | 2026-07-10 | ai08                  | core-edu 模块 7 项 ISSUE 仲裁                                            | ✅ 已裁决 | §4       |
| ARB-005 | 2026-07-10 | ai09                  | content 模块 10 项 ISSUE 仲裁                                            | ✅ 已裁决 | §5       |
| ARB-006 | 2026-07-10 | coord（跨模块）       | events.proto 补全（跨 iam/core-edu/content）                             | ✅ 已裁决 | §6       |
| ARB-007 | 2026-07-10 | coord（跨模块）       | proto 契约补全汇总（iam.proto + core_edu.proto）                         | ✅ 已裁决 | §7       |
| ARB-008 | 2026-07-10 | ai10                  | msg 模块 15 项 ISSUE 仲裁                                                | ✅ 已裁决 | §10      |
| ARB-009 | 2026-07-10 | ai11                  | data-ana 模块 6 项 ISSUE 仲裁                                            | ✅ 已裁决 | §11      |
| ARB-010 | 2026-07-10 | ai12                  | ai 模块 9 项 ISSUE 仲裁                                                  | ✅ 已裁决 | §12      |
| ARB-011 | 2026-07-10 | coord（跨模块）       | events.proto 扩展补全（msg/data-ana/ai message）+ proto package 命名统一 | ✅ 已裁决 | §13      |
| ARB-012 | 2026-07-10 | coord（跨模块）       | analytics.proto + ai.proto 补全                                          | ✅ 已裁决 | §14      |
| ARB-013 | 2026-07-10 | coord（跨模块）       | Kafka topic 命名统一裁决（跨全模块）                                     | ✅ 已裁决 | §15      |
| ARB-014 | 2026-07-10 | ai01                  | api-gateway 模块 4 项内联 ISSUE 仲裁                                     | ✅ 已裁决 | §16      |
| ARB-015 | 2026-07-10 | ai02                  | push-gateway 模块 7 项 ISSUE 仲裁                                        | ✅ 已裁决 | §17      |
| ARB-016 | 2026-07-10 | ai03                  | teacher-bff 模块 3 项 ISSUE 仲裁                                         | ✅ 已裁决 | §18      |
| ARB-017 | 2026-07-10 | ai04                  | student-bff 模块 4 项新 ISSUE 仲裁                                       | ✅ 已裁决 | §19      |
| ARB-018 | 2026-07-10 | ai05                  | parent-bff 模块 10 项 ISSUE 仲裁                                         | ✅ 已裁决 | §20      |
| ARB-019 | 2026-07-10 | ai14                  | student-portal 模块 7 项 ISSUE 仲裁                                      | ✅ 已裁决 | §21      |
| ARB-020 | 2026-07-10 | ai15                  | parent-portal 模块 10 项 ISSUE 仲裁                                      | ✅ 已裁决 | §22      |
| ARB-021 | 2026-07-10 | ai16                  | admin-portal 模块 7 项 ISSUE 仲裁                                        | ✅ 已裁决 | §23      |
| ARB-022 | 2026-07-10 | ai01                  | api-gateway 模块 8 项 ISSUE 仲裁（v2 正式版）                            | ✅ 已裁决 | §24      |

---

## §1 ARB-001：teacher-bff GraphQL schema 第一版

### 1.1 背景

全并行启动前，需仲裁 teacher-bff GraphQL schema 第一版，作为 ai03（teacher-bff）和 ai13（teacher-portal）的共同契约。

数据源：ai03 的 [02-architecture-design.md §5](../../services/teacher-bff/docs/02-architecture-design.md#L503) 提供了目标态 schema（P4），但 P2 只需 Must Have 子集。

### 1.2 仲裁结论

**P2 第一版 schema 范围**（Must Have，对应 ai03 P2 工作量分级 Must Have 13 项）：

```graphql
# ============ P2 第一版 schema ============
# 存放位置：packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql
# 仲裁原则：仅包含 P2 可实现的 Query（iam 已就绪），Mutation 延后到 P3
# 修订（ARB-016 §18）：admin 命名空间 P2 预留 schema 占位（总裁 §5.1 + §7.3 裁决优先级 president > coord）
# 修订（ARB-016 §18）：schema 文件名统一为 <bff-name>.schema.graphql（总裁 §2.17）

scalar DateTime

enum DataScope {
  SELF
  CLASS
  GRADE
  SCHOOL
  SUBJECT
  ALL
}

enum ExamStatus {
  DRAFT
  PUBLISHED
  IN_PROGRESS
  GRADING
  SCORED
  ARCHIVED
}

enum SubmissionStatus {
  NOT_SUBMITTED
  SUBMITTED
  GRADED
}

type User {
  id: ID!
  email: String!
  name: String!
  roles: [String!]!
  dataScope: DataScope!
}

type ViewportItem {
  key: String!
  label: String!
  route: String!
  icon: String
  sortOrder: String!
  requiredPermission: String
}

type Class {
  id: ID!
  name: String!
  gradeId: String!
  studentCount: Int!
}

type DashboardStats {
  totalExams: Int!
  pendingGrading: Int!
  todayHomework: Int!
}

type DashboardData {
  user: User!
  classes: [Class!]!
  viewports: [ViewportItem!]!
  stats: DashboardStats!
}

# ============ Query（P2 仅读，无 Mutation） ============

type Query {
  # 仪表盘聚合（并行：iam.me + iam.viewports + iam.permissions + iam.classesByTeacher）
  dashboard: DashboardData!

  # 视口配置（导航）
  viewports: [ViewportItem!]!

  # 当前用户信息
  me: User!

  # 班级列表（按教师 dataScope 过滤，数据来自 iam gRPC，总裁 §3.5）
  classes: [Class!]!
  class(id: ID!): Class
}

# ============ P2 不包含（P3+ 扩展） ============
# - exams / homework / grades Query → P3（core-edu 就绪后）
# - classPerformance / studentWeakness / learningTrend → P4（data-ana 就绪后）
# - notifications → P5（msg 就绪后）
# - 所有 Mutation → P3+
# - Subscription → P6+ 评估

# ============ admin 命名空间（P2 预留 schema 占位，P6 实现） ============
# 总裁 §5.1：admin-portal 复用 teacher-bff，admin 命名空间 P2 预留 schema 占位
# P2 仅声明类型骨架，Resolver 返 null；P6 实现（ARB-021 ISSUE-005）
# 详见 ARB-021 §23.4 admin 命名空间 schema 清单
extend type Query {
  # adminUsers / adminRoles / adminPermissions / adminViewports
  # adminOrganization / adminClasses / adminTeachers / adminStudents
  # auditLogs / adminDashboard
  # （P6 实现，P2 仅占位）
}

extend type Mutation {
  # createUser / updateUser / deleteUser / toggleUserStatus
  # createRole / updateRolePermissions / updateViewport
  # （P6 实现，P2 仅占位）
}
```

### 1.3 关键裁决

| 裁决点            | 结论                                                                                     | 依据                                                                             |
| ----------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Schema 存放位置   | `packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql`                        | 总裁裁决 §2.17 SDL-first + 集中管理                                              |
| schema 文件名格式 | `<bff-name>.schema.graphql`（统一格式，对齐 student-bff/parent-bff）                     | 总裁裁决 §2.17 + ARB-016 §18.3                                                   |
| P2 Query 范围     | dashboard / viewports / me / classes / class（5 个）                                     | 仅依赖 iam（P2 就绪），classes 数据从 iam gRPC 获取（总裁 §3.5）                 |
| P2 Mutation 范围  | **无**（P2 纯读）                                                                        | Mutation 依赖 core-edu（P3），P2 无下游可写                                      |
| DataLoader        | dashboard 内 classes 列表用 DataLoader                                                   | N+1 防御（ai03 §5.1 第 4 条）                                                    |
| 复杂度限制        | depth ≤ 7，cost ≤ 1000                                                                   | ai03 §5.1 第 5 条                                                                |
| admin 命名空间    | **P2 预留** schema 占位（声明 admin Query/Mutation 类型骨架，Resolver 返 null），P6 实现 | 总裁裁决 §5.1 + §7.3（裁决优先级 president > coord，修正原 ARB-001 "P2 不包含"） |
| DataScope 枚举    | SELF / CLASS / GRADE / SCHOOL / SUBJECT / ALL（SUBJECT 替代 DISTRICT）                   | coord DataScope 6 级统一                                                         |
| 错误响应          | ActionState 信封（success/errors/data）                                                  | coord-final-decisions F9                                                         |
| 降级模式          | success=true + error=null + data 内 degraded 字段                                        | 总裁裁决 §3.4 方案 B                                                             |

> **修订记录**（ARB-016 §18，2026-07-10）：
>
> 1. admin 命名空间由 "P2 不包含" 修正为 "P2 预留 schema 占位"（总裁 §5.1 + §7.3 优先级 president > coord）
> 2. schema 文件名由 `teacher-bff.graphql` 修正为 `teacher-bff.schema.graphql`（统一 `<bff-name>.schema.graphql` 格式，总裁 §2.17）
> 3. classes 数据来源明确为 iam gRPC（总裁 §3.5，非 core-edu）

### 1.4 ai03 执行项

1. 在 `packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql` 创建 P2 第一版 schema 文件
2. teacher-bff 实现 Yoga GraphQL endpoint（`POST /graphql`）
3. 实现 5 个 Query Resolver（dashboard / viewports / me / classes / class）
4. dashboard Resolver 并行调用 iam（3 RPC）+ iam.classesByTeacher（1 RPC），用 DataLoader 防御 N+1（总裁 §3.5：classes 数据从 iam gRPC 获取）
5. 实现 ActionState 信封 + 降级模式（方案 B）
6. P2 预留 admin 命名空间 schema 占位（声明类型骨架，Resolver 返 null；P6 实现见 ARB-021 §23.4）

### 1.5 ai13 执行项

1. teacher-portal Shell 暴露 `GraphQLProvider`（urql client 单例）
2. 使用 `useGraphQLClient()` 从 packages/hooks 获取 client
3. P2 页面（dashboard / classes）通过 GraphQL query 拉取数据
4. **不调用 REST 端点**（除登录外，P2 起 all-in GraphQL）

---

## §2 ARB-002：MF Shell 暴露清单

### 2.1 背景

全并行启动前，需仲裁 teacher-portal 作为 MF Shell 暴露哪些模块给 Remote（student/parent/admin），作为 ai13 的实现依据。

数据源：ai13 的 [03-long-term-architecture.md §1.4](../../apps/teacher-portal/docs/03-long-term-architecture.md) 提供了 GraphQL client 单例设计。

### 2.2 仲裁结论

**P2 第一版 MF Shell 暴露清单**：

```typescript
// teacher-portal/next.config.js — NextFederationPlugin exposes
exposes: {
  // 1. AppShell（布局 + 导航 + 认证守卫）
  './AppShell': './src/components/AppShell.tsx',
  // 2. GraphQLProvider（urql client 单例，总裁 §2.17 方案 A）
  './GraphQLProvider': './src/app/providers.tsx',
  // 3. 共享 hooks
  './useAuth': './packages/hooks/src/use-auth.ts',
  './usePermission': './packages/hooks/src/use-permission.ts',
  './useGraphQLClient': './packages/hooks/src/use-graphql-client.ts',
  // 4. 共享 UI 组件
  './ErrorBoundary': './packages/ui-components/src/error-boundary.tsx',
  './Loading': './packages/ui-components/src/loading.tsx',
  './Empty': './packages/ui-components/src/empty.tsx',
  './RequirePermission': './packages/ui-components/src/require-permission.tsx',
}
```

**MF shared（singleton）配置**：

```typescript
shared: {
  react: { singleton: true, requiredVersion: '^18.3.0' },
  'react-dom': { singleton: true, requiredVersion: '^18.3.0' },
  urql: { singleton: true, requiredVersion: '^2.2.0' },
  graphql: { singleton: true, requiredVersion: '^16.8.0' },
  '@edu/ui-tokens': { singleton: true },
  '@edu/ui-components': { singleton: true },
  '@edu/hooks': { singleton: true },
}
```

### 2.3 关键裁决

| 裁决点              | 结论                                           | 依据                        |
| ------------------- | ---------------------------------------------- | --------------------------- |
| Shell 身份          | teacher-portal 是 MF Shell（非 Remote）        | 总裁裁决 §2.17 + ai13 §1.3  |
| P2 Remote 数量      | **0**（P2 暂无 Remote，仅配置 exposes/shared） | ai13 §1.3 绞杀者模式 step 3 |
| P3 首个 Remote      | student-portal                                 | ai13 §1.3 step 4            |
| GraphQL client 归属 | Shell 暴露 GraphQLProvider，Remote 复用        | 总裁 §2.17 方案 A           |
| MF shared singleton | react / react-dom / urql / graphql / @edu/*    | 避免多实例 + 缓存不一致     |
| AppShell 暴露       | 是（Remote 复用布局 + 导航 + 认证守卫）        | ai13 §1.3                   |
| feature flag        | `NEXT_PUBLIC_MF_ENABLED=false`（P2 默认关）    | ai13 §1.3 回退策略          |
| 登录页              | P2 不走 MF（Shell 独占 `/login`）              | 登录是认证前提，MF 依赖认证 |

### 2.4 ai13 执行项

1. teacher-portal `next.config.js` 添加 NextFederationPlugin（exposes + shared，**无 remotes**）
2. 创建 `src/app/providers.tsx`（GraphQLProvider 包裹）
3. AppShell 改造：从 REST `/api/v1/teacher/viewports` 切换为 GraphQL query `viewports`
4. P2 页面（dashboard / classes）全部用 GraphQL
5. feature flag `NEXT_PUBLIC_MF_ENABLED=false`（P2 默认单体路由）

### 2.5 ai03 执行项（联动）

1. teacher-bff 暴露 `POST /graphql` endpoint
2. 提供GraphQL playground（仅开发环境）

---

## §3 ARB-003：iam 模块 7 项 ISSUE 仲裁

### 3.1 背景

ai06 在 [iam_issue.md](./objections/iam_issue.md) §2 提请 7 项异议，涉及文档回写、events.proto 缺失、Topic 命名不一致、DataScope 枚举冲突、iam.proto 未补全、AI 身份署名错误、双入口策略冲突。coord 对照 [iam_contract.md](./contracts/iam_contract.md)（v1.0，已含双入口策略 + 12 RPC + REST 端点清单）逐条仲裁。

### 3.2 仲裁结论

| ISSUE | 标题                                                | 仲裁结论                                                                                       | 执行方                                                       |
| ----- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| 001   | 01/02 文档未回写 I1-I8 裁决                         | ✅ 支持 ai06 方案：3 个工作日内回写 01/02，删除全部过渡方案，对齐 contract.md v1.0             | ai06                                                         |
| 002   | events.proto 缺 UserEvent/RoleEvent/AuditEvent      | ✅ coord 批次 0 补全（见 §6 ARB-006 统一处理）                                                 | coord                                                        |
| 003   | Topic 命名三方不一致（edu.identity.* vs edu.iam.*） | ✅ 统一 `edu.iam.*` 域名 + 聚合 topic 风格                                                     | coord 修 004 + matrix.md                                     |
| 004   | DataScope 枚举三方不一致                            | ✅ 采用 president §3.2 P2.2 方案：ALL/SCHOOL/GRADE/CLASS/SUBJECT/SELF（SUBJECT 替代 DISTRICT） | coord 修 004 + ai06 修源码 + coord 修 ARB-001 GraphQL schema |
| 005   | iam.proto 仅 4 RPC，未补全至 12 RPC                 | ✅ coord 批次 0 补全（见 §7 ARB-007 统一处理）                                                 | coord                                                        |
| 006   | 01/02 文档 AI 身份署名错误                          | ✅ 与 ISSUE-001 一并回写，署名改为 ai06                                                        | ai06                                                         |
| 007   | contract.md §1.2 与双入口策略冲突                   | ✅ contract.md 已修正为双入口策略（REST + gRPC），ai06 回写 02 文档时对齐                      | ai06                                                         |

### 3.3 关键裁决

| 裁决点            | 结论                                                      | 依据                                                           |
| ----------------- | --------------------------------------------------------- | -------------------------------------------------------------- |
| Topic 域名        | `edu.iam.*`（服务名 iam，非 identity）                    | G16 规则 `edu.<domain>.<aggregate>.<action>`，domain=服务名    |
| Topic 粒度        | 聚合 topic（`edu.iam.user.events` 含多 action）           | 与 events.proto ClassEvent 模式一致，减少 topic 数量           |
| DataScope 枚举    | ALL/SCHOOL/GRADE/CLASS/SUBJECT/SELF（6 级）               | president §3.2 P2.2；SUBJECT 替代 DISTRICT（K12 学科级更实用） |
| 双入口策略        | REST `/iam/v1/*` 供 gateway 透传 + gRPC 50052 供 BFF 聚合 | president §2.16                                                |
| iam.proto 补全    | 12 RPC（contract.md §1.1 已定义）                         | coord-final-decisions §5.1 + president §6 批次 0               |
| events.proto 补全 | UserEvent/RoleEvent/AuditEvent + schema_version 字段      | coord-final-decisions §5.1 + president §5.5                    |
| 004 §7.2 修正     | `edu.identity.*` → `edu.iam.*`，改为聚合 topic 风格       | 与 matrix.md §4 / iam_contract.md §1.4 统一                    |

### 3.4 ai06 执行项

1. 回写 iam 01/02 文档（3 个工作日内）：
   - 删除全部过渡方案（P2 仅 REST / 自建 Outbox / PermissionGuard 待改造 / AuthMiddleware P2 不注册 / iam_parent_student_relations / 无 /v1 前缀 / HTTP 调用 iam）
   - 对齐 contract.md v1.0（12 RPC + 双入口 + REST `/iam/v1/*` + gRPC 50052）
   - 署名从 ai02 改为 ai06
   - 02 文档 §3.1.2 表名改为 `iam_student_guardians`（I6 裁决）
   - 02 文档 §8.1 决策点 5 改为"P2 即启用 gRPC 50052"（I1 裁决）
   - 02 文档 §8.1 决策点 4 改为"使用 shared-ts Outbox 工具包"（I2 裁决）
   - 02 文档 §8.1 决策点 9 改为"P2 即 DB 驱动 + Redis 缓存"（I3 裁决）
   - 02 文档 §1.1/§1.2/§8.1 决策点 10 改为"P2 即注册 AuthMiddleware"（I4 裁决）
   - 02 文档 §4.1 REST API 加 `/v1` 前缀（I7 裁决）
2. 修改源码 iam.schema.ts DataScope 枚举：DISTRICT → SUBJECT（ISSUE-004）
3. 实现源码 PermissionGuard DB 驱动 + Redis 缓存（I3 裁决）
4. 实现源码 AuthMiddleware 注册（I4 裁决）
5. 实现源码 RS256 密钥（I5 裁决，本地文件 IAM_PRIVATE_KEY_PATH / IAM_PUBLIC_KEY_PATH）
6. 实现源码 iam_student_guardians 表 + GetChildrenByParent RPC + GET /iam/v1/children（I6 裁决）

### 3.5 coord 执行项

1. 补全 iam.proto 至 12 RPC（ARB-007，批次 0）
2. 补全 events.proto UserEvent/RoleEvent/AuditEvent + schema_version（ARB-006，批次 0）
3. 修正 004 §7.2：`edu.identity.*` → `edu.iam.*`，改为聚合 topic 风格
4. 修正 004 §5.3 表：DataScope 枚举 DISTRICT → SUBJECT；行 505 语义命名与枚举表对齐
5. 修正 ARB-001 GraphQL schema DataScope 枚举：去掉 DISTRICT，加 SUBJECT
6. 修正 matrix.md §4：iam topic 已为 `edu.iam.*`（核查无需改）；补 DataScope 枚举说明

---

## §4 ARB-004：core-edu 模块 7 项 ISSUE 仲裁

### 4.1 背景

ai08 在 [core-edu_issue.md](./objections/core-edu_issue.md) 提请 7 项异议，涉及 proto 实际状态与仲裁声称不符、events.proto 未同步、状态命名跨模块不一致、class.transferred topic 不一致、RPC 数量统计口径冲突、7 项设计决策未仲裁、01 文档审计待核对项。coord 对照 [core-edu_contract.md](./contracts/core-edu_contract.md)（已更新为 P3 目标态 27 RPC）逐条仲裁。

### 4.2 仲裁结论

| ISSUE | 标题                                    | 仲裁结论                                                                                                              | 执行方                                        |
| ----- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| 001   | core_edu.proto 实际状态与仲裁声称不符   | ✅ coord 批次 0 补全至 5 Service 27 RPC（见 §7 ARB-007）                                                              | coord                                         |
| 002   | events.proto 未同步 topic 命名仲裁      | ✅ coord 批次 0 补全（见 §6 ARB-006：AttendanceEvent + schema_version + edu.teaching.* 注释）                         | coord                                         |
| 003   | 考试/作业状态命名跨模块不一致           | ✅ 采用 ai08 方案 A：统一用 `graded`（去掉 `SCORED`）；submissions 统一为 `not_submitted/submitted/graded`            | ai08 修源码 + coord 修 ARB-001 GraphQL schema |
| 004   | class.transferred 事件 topic 三处不一致 | ✅ 统一为 `edu.teaching.class.transferred`                                                                            | coord 修 matrix.md + ai08 修文档              |
| 005   | RPC 数量统计口径不一致                  | ✅ 统一为 P3 全量 27 RPC（ClassService 4 + ExamService 8 + HomeworkService 5 + GradeService 6 + AttendanceService 4） | coord 修 matrix.md + ai08 修文档              |
| 006   | 7 项设计决策待仲裁                      | ✅ 全部采用 ai08 倾向方案（见 §4.4）                                                                                  | ai08                                          |
| 007   | 01 文档审计表"待核对"项                 | ✅ 3 项纳入 P3 验收硬性标准                                                                                           | ai08                                          |

### 4.3 关键裁决

| 裁决点           | 结论                                                                                                                                            | 依据                                                                                      |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| proto 补全范围   | 5 Service 27 RPC（含 ClassService + AttendanceService + P3 新增 5 RPC + Exam/Homework/Grade message 补字段 + SubmitHomeworkRequest 补 answers） | ISSUE-001 建议                                                                            |
| Topic 命名       | 统一 `edu.teaching.<aggregate>.<action>`（含 class.transferred）                                                                                | coord-cross-review §3.1                                                                   |
| 聚合 topic       | core-edu 采用具体动作 topic（`edu.teaching.exam.created` 等独立 topic，非聚合）                                                                 | 与 iam 聚合 topic 不同：core-edu 事件量大，独立 topic 利于分区与消费隔离                  |
| ExamStatus       | draft/published/in_progress/grading/graded/archived/cancelled（小写）                                                                           | 统一为 graded，去掉 SCORED                                                                |
| SubmissionStatus | not_submitted/submitted/graded（exam + homework 一致）                                                                                          | 统一初始状态为 not_submitted                                                              |
| GraphQL 枚举映射 | DRAFT/PUBLISHED/IN_PROGRESS/GRADING/GRADED/ARCHIVED/CANCELLED；NOT_SUBMITTED/SUBMITTED/GRADED                                                   | 大写映射，去掉 SCORED                                                                     |
| RPC 统计口径     | 27 RPC（P3 全量）                                                                                                                               | ClassService 4 + ExamService 8 + HomeworkService 5 + GradeService 6 + AttendanceService 4 |

> **注**：core-edu topic 策略采用"具体动作 topic"（`edu.teaching.exam.created` 等），与 iam/content 的"聚合 topic"（`edu.iam.user.events` / `edu.content.knowledge_point.events`）不同。原因：core-edu 事件量大（12 个事件类型），独立 topic 利于 Kafka 分区与消费者隔离；iam/content 事件量小，聚合 topic 减少元数据压力。此为 coord 裁决的策略差异，非矛盾。

### 4.4 ISSUE-006 七项设计决策仲裁

| #   | 决策点              | 仲裁结论                                           | ai08 倾向 |
| --- | ------------------- | -------------------------------------------------- | --------- |
| 1   | classes 合并时机    | ✅ (a) P3 初期合并                                 | (a)       |
| 2   | room_id             | ✅ (b) 仅预留字段                                  | (b)       |
| 3   | scope 优先级        | ✅ (a) class > subject > school                    | (a)       |
| 4   | grace_period        | ✅ (b) 300 秒（schema 默认值改为 `.default(300)`） | (b)       |
| 5   | schema 校验         | ✅ (b) 仅文档约束（P3 不强制）                     | (b)       |
| 6   | exam.submitted 事件 | ✅ (b) 仅含 submission_id                          | (b)       |
| 7   | archived 考试       | ✅ (b) P3 仅软删除                                 | (b)       |

### 4.5 ai08 执行项

1. 修改 core-edu 01/02 文档：
   - 01 §L48 补"ClassService 也缺失"
   - 02 §4.2 对齐 27 RPC（补 ClassService 4 + AttendanceService 4 + P3 新增 5 RPC + message 字段）
   - 02 §5.1 TOPIC_MAP 对齐 `edu.teaching.*` 命名（具体动作 topic）
   - 02 §13.3 七项决策按 §4.4 仲裁结论更新（决策 #4 schema `.default(300)`）
   - class.transferred topic 统一为 `edu.teaching.class.transferred`
2. 修改源码 status 字段值：exam `graded`（非 `scored`）；submissions 统一 `not_submitted`
3. P3 实施时补齐 Dockerfile 多阶段 / ActionState traceId / 权限装饰器覆盖（ISSUE-007 验收标准）

### 4.6 coord 执行项

1. 补全 core_edu.proto 至 5 Service 27 RPC（ARB-007，批次 0）
2. 补全 events.proto AttendanceEvent + schema_version + edu.teaching.* 注释（ARB-006，批次 0）
3. 修正 coord-cross-review.md L312："✅ 已补全" → "⏳ 待 coord 补全（ARB-007）"
4. 修正 matrix.md §2：core-edu 22 RPC → 27 RPC
5. 修正 matrix.md §4：class.transferred topic 统一为 `edu.teaching.class.transferred`
6. 修正 ARB-001 GraphQL schema：ExamStatus 去掉 SCORED 加 CANCELLED；SubmissionStatus 去掉 IN_PROGRESS（如有）确认 NOT_SUBMITTED/SUBMITTED/GRADED
7. 修正 core-edu_contract.md §2.2：UserEvent topic 从 `edu.identity.user.*` 改为 `edu.iam.user.events`（与 iam ISSUE-003 仲裁一致，聚合 topic 风格）

---

## §5 ARB-005：content 模块 10 项 ISSUE 仲裁

### 5.1 背景

ai09 在 [content_issue.md](./objections/content_issue.md) 提请 10 项异议，涉及 REST 端点设计不一致、事件 topic 命名策略冲突、Textbook/Chapter 事件遗漏、RPC 数量三方不一致、core-edu 失效事件无定义、文档 push main 冲突、created_by 迁移风险、缓存/API 版本化缺失、schema 字段缺失、Sync Worker 链路。coord 对照 [content_contract.md](./contracts/content_contract.md)（v1.1，已更新为 21 RPC + 4 聚合 topic）逐条仲裁。

### 5.2 仲裁结论

| ISSUE | 标题                                     | 仲裁结论                                                                                                  | 执行方                                          |
| ----- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| 001   | REST 端点设计与实现不一致                | ✅ P4 重构时统一为 query 参数风格 + 补 DELETE prerequisite 端点；允许 API 路径变更（BFF 走 GraphQL 解耦） | ai09                                            |
| 002   | 事件 topic 命名策略冲突                  | ✅ 采用聚合 topic + action 字段策略（4 聚合 topic）                                                       | ai09 修文档 + coord 补 events.proto             |
| 003   | Textbook/Chapter 事件遗漏                | ✅ 补登记 edu.content.textbook.events + chapter.events                                                    | ai09 已在 contract.md 补 + coord 同步 matrix.md |
| 004   | gRPC RPC 数量三方不一致                  | ✅ 统一为 21 RPC（Textbook 5 + Chapter 5 + KG 4 + Question 7）                                            | ai09 修文档 + coord 修 matrix.md                |
| 005   | core-edu → content 失效事件 topic 无定义 | ✅ 删除 02 文档 §5.2 该条目；联动改用 gRPC 调用                                                           | ai09                                            |
| 006   | "直接 push main"与项目规则冲突           | ✅ 遵循总裁裁决（trunk-based，直接 push main，post-commit review）；措辞优化为"trunk-based development"   | ai09                                            |
| 007   | questions.created_by 迁移风险            | ✅ schema 用 `created_by varchar(32) NOT NULL DEFAULT 'system'`（历史数据回填 'system'）                  | ai09                                            |
| 008   | 缓存策略与 API 版本化缺失                | ✅ P4 补缓存策略小节 + API 版本化说明                                                                     | ai09                                            |
| 009   | knowledge-points schema 缺字段           | ✅ P4 迁移补齐 difficulty + metadata + created_at + updated_at                                            | ai09                                            |
| 010   | Sync Worker 链路 P4 不必要               | ✅ ES Sync Worker 标 P5；Neo4j Sync Worker 输入仅 Outbox 事件；P4 移除 safeCreateNode 同步写              | ai09                                            |

### 5.3 关键裁决

| 裁决点                   | 结论                                                                                     | 依据                                                             |
| ------------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| REST 端点风格            | query 参数（`GET /knowledge-points?chapterId=`）                                         | RESTful 规范 + 与 design doc 一致                                |
| 事件 topic 策略          | 聚合 topic + action 字段（4 topic：textbook/chapter/knowledge_point/question）           | 与 matrix.md / events.proto ClassEvent 模式一致；减少 topic 数量 |
| RPC 总数                 | 21（TextbookService 5 + ChapterService 5 + KnowledgeGraphService 4 + QuestionService 7） | contract.md 为契约唯一源                                         |
| content 与 core-edu 关系 | content 是上游（core-edu 调 content），不消费 core-edu 事件                              | ISSUE-005 建议                                                   |
| Git 工作流               | trunk-based development（直接 push main + post-commit review）                           | 总裁裁决覆盖 project_rules §8 分支开发规则                       |
| created_by 迁移          | `NOT NULL DEFAULT 'system'`（历史数据回填 + 新数据应用层校验）                           | ISSUE-007 方案二                                                 |
| 缓存策略                 | Redis 缓存教材树/章节树 + Outbox 事件触发失效                                            | 读多写少场景                                                     |
| API 版本化               | REST `/v1/` 前缀 + gRPC proto package version                                            | 破坏性变更隔离                                                   |
| Neo4j 同步               | P4 改为 Outbox 事件驱动异步同步（移除 safeCreateNode 同步写）                            | 禁止业务事务内同步双写                                           |

### 5.4 ai09 执行项

1. 修改 content 02 文档：
   - §4.1 REST 端点改 query 参数风格 + 补 DELETE prerequisite 端点
   - §5.1 TOPIC_MAP 改为 4 聚合 topic（textbook/chapter/knowledge_point/question events）
   - §5.2 删除 core-edu 失效事件条目
   - §4.2 gRPC RPC 对齐 21 RPC（补 Textbook Update/Delete + Chapter Update/Delete + Question Publish/Search）
   - §6 补"缓存策略"小节（Redis + Outbox 失效）
   - §4 补"API 版本化"说明（REST `/v1/` 前缀）
   - §1.1 图 ES Sync Worker 标 P5（虚线/灰显）；Neo4j Sync Worker 输入仅 Outbox 事件
   - 文档末尾措辞优化为"trunk-based development（直接 push main，post-commit review）"
2. 修改源码 schema：questions.created_by `NOT NULL DEFAULT 'system'`；knowledge_points 补 difficulty/metadata/created_at/updated_at
3. P4 任务 T6：重构 knowledge-points.service.ts 移除 safeCreateNode 同步写，改为发 Outbox 事件

### 5.5 coord 执行项

1. 补全 events.proto TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent + schema_version（ARB-006，批次 0）
2. 修正 matrix.md §2：content 18 RPC → 21 RPC
3. 修正 matrix.md §4：补登记 edu.content.textbook.events + chapter.events（共 4 聚合 topic）

---

## §6 ARB-006：events.proto 补全（跨 iam/core-edu/content）

### 6.1 背景

iam ISSUE-002、core-edu ISSUE-002、content ISSUE-002/003 共同指向 events.proto 不完整。当前 events.proto 仅定义 4 个 message（ClassEvent/ExamEvent/HomeworkEvent/GradeEvent），缺 iam 的 UserEvent/RoleEvent/AuditEvent、core-edu 的 AttendanceEvent、content 的 TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent，且所有 message 缺 schema_version 字段，文件头注释仍用旧 topic 命名。

### 6.2 仲裁结论

coord 在批次 0（P2 启动前）补全 events.proto：

| 新增 message        | 字段                                                                                                                                                                                   | 来源                         |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| UserEvent           | event_id/aggregate_id/event_type/occurred_at/user_id/email/name/roles/action(created/updated/deleted/role_changed)/schema_version/metadata                                             | iam 02 §5.2 + president §5.5 |
| RoleEvent           | event_id/aggregate_id/event_type/occurred_at/role_id/role_name/permissions/action(created/updated)/schema_version/metadata                                                             | iam 02 §5.2                  |
| AuditEvent          | event_id/aggregate_id/event_type/occurred_at/user_id/action(create/update/delete/login/logout/permission_change)/resource_type/resource_id/schema_version/metadata                     | president §5.5               |
| AttendanceEvent     | event_id/aggregate_id/event_type/occurred_at/attendance_id/student_id/class_id/schedule_id/status/action(recorded)/schema_version/metadata                                             | core-edu 02 §5.1             |
| TextbookEvent       | event_id/aggregate_id/event_type/occurred_at/textbook_id/title/subject_id/grade_id/version/action(created/updated/published/archived)/schema_version/metadata                          | content contract.md §1.4     |
| ChapterEvent        | event_id/aggregate_id/event_type/occurred_at/chapter_id/textbook_id/title/order/action(created/updated/deleted)/schema_version/metadata                                                | content contract.md §1.4     |
| KnowledgePointEvent | event_id/aggregate_id/event_type/occurred_at/kp_id/chapter_id/title/difficulty/action(created/updated/prerequisite_added/prerequisite_removed)/prerequisite_id/schema_version/metadata | content contract.md §1.4     |
| QuestionEvent       | event_id/aggregate_id/event_type/occurred_at/question_id/kp_id/type/difficulty/status/source/created_by/action(created/updated/published/deleted)/schema_version/metadata              | content contract.md §1.4     |

**同时**：

- 所有现有 message（ClassEvent/ExamEvent/HomeworkEvent/GradeEvent）补 `string schema_version = N;` 字段
- 文件头注释改为 `edu.teaching.*` 命名（core-edu 事件）+ `edu.iam.*` 命名（iam 事件）+ `edu.content.*` 命名（content 事件）

### 6.3 Topic 命名策略（跨模块统一）

| 服务     | Topic 策略               | 示例                                                                      | 原因                                    |
| -------- | ------------------------ | ------------------------------------------------------------------------- | --------------------------------------- |
| iam      | 聚合 topic + action 字段 | `edu.iam.user.events`（含 created/updated/deleted/role_changed）          | 事件量小，聚合减少 topic 数             |
| core-edu | 具体动作 topic           | `edu.teaching.exam.created`（每事件独立 topic）                           | 事件量大，独立 topic 利于分区与消费隔离 |
| content  | 聚合 topic + action 字段 | `edu.content.knowledge_point.events`（含 created/updated/prerequisite_*） | 事件量中等，聚合减少 topic 数           |
| msg      | 具体动作 topic           | `edu.notify.notification.created`                                         | 通知事件量大，独立 topic                |

> coord 裁决：允许跨服务采用不同 topic 粒度策略（聚合 vs 具体动作），以服务特征为准。所有 topic 命名统一遵循 `edu.<domain>.<aggregate>.<action>` 或 `edu.<domain>.<aggregate>.events` 格式。

---

## §7 ARB-007：proto 契约补全汇总（iam.proto + core_edu.proto）

### 7.1 背景

iam ISSUE-005 和 core-edu ISSUE-001 共同指向 proto 契约未补全。coord 作为 shared-proto 维护者，在批次 0 统一补全。

### 7.2 iam.proto 补全（12 RPC）

| Service    | RPC                     | 请求                           | 响应                         |
| ---------- | ----------------------- | ------------------------------ | ---------------------------- |
| IamService | Register                | RegisterRequest                | AuthResponse                 |
| IamService | Login                   | LoginRequest                   | AuthResponse                 |
| IamService | RefreshToken            | RefreshTokenRequest            | TokenPair                    |
| IamService | Logout                  | LogoutRequest                  | LogoutResponse               |
| IamService | GetUserInfo             | GetUserInfoRequest             | UserInfo                     |
| IamService | BatchGetUsers           | BatchGetUsersRequest           | BatchGetUsersResponse        |
| IamService | GetEffectivePermissions | GetEffectivePermissionsRequest | EffectivePermissionsResponse |
| IamService | GetEffectiveAccess      | GetEffectiveAccessRequest      | EffectiveAccessResponse      |
| IamService | GetEffectiveDataScope   | GetEffectiveDataScopeRequest   | DataScopeResponse            |
| IamService | GetViewports            | GetViewportsRequest            | ViewportsResponse            |
| IamService | GetPublicKey            | GetPublicKeyRequest            | PublicKeyResponse            |
| IamService | GetChildrenByParent     | GetChildrenByParentRequest     | ChildrenResponse             |

> 对齐 iam_contract.md §1.1 的 12 RPC 清单。新增 8 RPC（Logout/BatchGetUsers/GetEffectivePermissions/GetEffectiveAccess/GetEffectiveDataScope/GetViewports/GetPublicKey/GetChildrenByParent）。

### 7.3 core_edu.proto 补全（5 Service 27 RPC）

| Service           | RPC                                                                                                                  | 状态            |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- | --------------- |
| ClassService      | GetClass / GetClassesByTeacher / BatchGetClasses / ListStudentsByClass                                               | 新增 4 RPC      |
| ExamService       | CreateExam / GetExam / ListExamsByClass / UpdateExam / DeleteExam / **PublishExam** / **SubmitExam** / **GradeExam** | 已有 5 + 新增 3 |
| HomeworkService   | AssignHomework / GetHomework / ListHomeworkByClass / SubmitHomework / **GradeHomework**                              | 已有 4 + 新增 1 |
| GradeService      | RecordGrade / GetGrade / ListGradesByStudent / ListGradesByExam / ListGradesByHomework / **UpdateGrade**             | 已有 5 + 新增 1 |
| AttendanceService | **RecordAttendance** / **GetAttendance** / **ListAttendanceByStudent** / **ListAttendanceByClass**                   | 新增 4 RPC      |

**同时补全 message 字段**：

- Exam：补 subject_id / school_id / status_changed_at / status_changed_by / archived_at
- Homework：补 subject_id / grace_period / school_id
- Grade：补 total_score / school_id / idempotency_key
- SubmitHomeworkRequest：补 answers 字段

> 对齐 core-edu_contract.md §1.1 的 27 RPC 清单。

### 7.4 coord 执行项

1. 补全 iam.proto 至 12 RPC（含全部 message 定义）
2. 补全 core_edu.proto 至 5 Service 27 RPC（含 ClassService + AttendanceService + P3 新增 5 RPC + message 字段补全）
3. 补全 events.proto（ARB-006，7 个新 message + schema_version + 注释更新）
4. 运行 `buf lint` + `buf breaking` 确保零错误
5. 运行 `buf generate` 产出 TS gRPC 代码
6. 修正 coord-cross-review.md L312 状态
7. 更新 matrix.md §2 RPC 统计

---

## §10 ARB-008：msg 模块 15 项 ISSUE 仲裁

### 10.1 背景

ai10 在 [msg_issue.md](./objections/msg_issue.md) 提请 15 项异议（ISSUE-001~~005 已有仲裁核查 + ISSUE-006~~015 新发现），涉及 events.proto 字段缺失、proto 包名规则冲突、Kafka topic 三套约定、RPC 数量超预算、权限点不一致、降级方向矛盾、DLQ/幂等防线缺失、events.proto 缺 message、RPC 清单不一致、Kafka 发布事件不一致。

### 10.2 仲裁结论

| ISSUE   | 标题                                                           | 仲裁结论                                                                                                                           | 执行方       |
| ------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| 001~005 | 已有仲裁核查                                                   | ✅ 核查通过（001/002/003）；004 待 coord 同步 events.proto 注释（ARB-006 已覆盖）；005 待 coord 修正 004 §4.1 PushGW 方向          | coord        |
| 006     | events.proto GradeEvent 缺 class_id + 全部事件缺 student_ids[] | ✅ coord 补全：GradeEvent 补 class_id；Exam/Homework/GradeEvent 补 student_ids[]（fan-out 广播用）                                 | coord        |
| 007     | proto 包名规则冲突（project_rules §5 vs 实际）                 | ✅ 统一为 `next_edu_cloud.<domain>.v1`（与实际 proto 一致）；coord 更新 project_rules §5（见 §13 ARB-011）                         | coord        |
| 008     | Kafka topic 命名三套约定并存                                   | ✅ 统一裁决（见 §15 ARB-013）：msg 采用具体动作 topic（`edu.notify.notification.sent` 等，与 core-edu 策略一致）                   | coord        |
| 009     | RPC 数量超预算（17 vs 13）                                     | ✅ 采用方案 A：维持 13 RPC 预算，裁剪 4 RPC（BatchSendNotification/GetUnreadCount/BatchMarkAsRead/MarkAllAsRead 降级为 REST only） | ai10         |
| 010     | markAsRead 权限点不一致                                        | ✅ 以 02 文档 §6.1 为准：`MSG_NOTIFICATION_READ`（非 MANAGE）                                                                      | ai10         |
| 011     | DB→ES 降级方向与 ai-allocation 相反                            | ✅ 采用双向降级：ES 故障→DB LIKE；DB 故障→ES 只读（仅读操作可降级，写操作必须等 DB 恢复）                                          | ai10         |
| 012     | 缺 DLQ 与三层幂等防线                                          | ✅ 非阻塞，ai10 自行补充设计文档（§3.1 补 msg_idempotency 表 + §5.5 三层幂等 + §5 DLQ 设计）                                       | ai10         |
| 013     | events.proto 缺 4 类 message                                   | ✅ coord 补全（见 §13 ARB-011：MasteryEvent/NotificationEvent + UserEvent/RoleEvent 已在 ARB-006 覆盖）                            | coord        |
| 014     | msg_contract.md 与 02 文档 RPC 清单不一致                      | ✅ 待 ISSUE-009 仲裁后统一为 13 RPC，两文档对齐                                                                                    | ai10         |
| 015     | Kafka 发布事件不一致                                           | ✅ 待 ISSUE-008 仲裁后统一（见 §15 ARB-013）                                                                                       | ai10 + coord |

### 10.3 关键裁决

| 裁决点           | 结论                                                                                 | 依据                                                    |
| ---------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| msg RPC 总数     | 13（NotificationService 5 + PreferenceService 4 + TemplateService 4）                | 维持 ai-allocation 预算；裁剪 4 RPC 降级 REST           |
| Kafka topic 策略 | 具体动作 topic（`edu.notify.notification.sent` / `.read` / `.recalled` / `.failed`） | 与 core-edu 策略一致；事件量大，独立 topic 利于消费隔离 |
| markAsRead 权限  | `MSG_NOTIFICATION_READ`                                                              | 02 文档为准                                             |
| 降级策略         | 双向（ES 故障→DB LIKE；DB 故障→ES 只读）                                             | ai-allocation §5 + 02 文档双向覆盖                      |
| 三层幂等         | L1 Redis SETNX + L2 msg_idempotency 表 + L3 notifications.source_event_id 唯一索引   | known-issues 已记录                                     |
| DLQ              | 重试 3 次后投递 `edu.notify.dlq` + 告警                                              | known-issues 已记录                                     |
| proto package    | `next_edu_cloud.msg.v1`（保留现状）                                                  | 见 §13 ARB-011                                          |

### 10.4 ai10 执行项

1. 修改 msg 02 文档：
   - §4.2 RPC 裁剪至 13（移除 BatchSendNotification/GetUnreadCount/BatchMarkAsRead/MarkAllAsRead，降级 REST only）
   - §5.2 Kafka topic 改为具体动作 topic（`edu.notify.notification.sent` 等 4 个 per-event topic）
   - §3.1 补 msg_idempotency 表 schema
   - §5.5 改为三层幂等防线
   - §5 补 DLQ 设计（`edu.notify.dlq` + 重试 3 次 + 告警）
   - §3.2.2/§3.4 补双向降级策略（DB 故障→ES 只读）
   - §6.1 markAsRead 权限改为 `MSG_NOTIFICATION_READ`
2. 修改源码 notifications.controller.ts markAsRead 权限点
3. msg_contract.md §1.1 RPC 清单对齐 13 RPC + §1.4 topic 对齐具体动作 topic

### 10.5 coord 执行项

1. 补全 events.proto（ARB-011：NotificationEvent + MasteryEvent + GradeEvent 补 class_id + 全部事件补 student_ids[]）
2. 修正 004 §4.1 PushGW 方向表述为"Msg → push-gateway (gRPC)"
3. 修正 matrix.md §4：msg topic 改为 `edu.notify.notification.*` 具体动作 topic

---

## §11 ARB-009：data-ana 模块 6 项 ISSUE 仲裁

### 11.1 背景

ai11 在 [data-ana_issue.md](./objections/data-ana_issue.md) 提请 6 项异议，涉及 iam.proto 缺 GetEffectiveDataScope、events.proto 缺 AIUsageEvent、analytics.proto 未补全至 12 RPC、004 章节引用断裂、MasteryEvent topic 不一致、coord-cross-review §8.2 声明与实际不符。

### 11.2 仲裁结论

| ISSUE | 标题                                               | 仲裁结论                                                                                                 | 执行方                           |
| ----- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------- |
| 001   | iam.proto 缺 GetEffectiveDataScope RPC             | ✅ coord 批次 0 补全 iam.proto 12 RPC（ARB-007 已覆盖，含 GetEffectiveDataScope）                        | coord                            |
| 002   | events.proto 缺 AIUsageEvent message               | ✅ coord 补全（见 §13 ARB-011）                                                                          | coord                            |
| 003   | analytics.proto 仅 3 RPC，声称 12 RPC 未落实       | ✅ coord 批次 0 补全 analytics.proto 至 12 RPC（见 §14 ARB-012）                                         | coord                            |
| 004   | 004 章节引用断裂（coord 整改 #7/#8/#9/#10 未落实） | ✅ coord 补全 004 §7.2/§1.2/§4.1/§12.2 对应章节                                                          | coord                            |
| 005   | MasteryEvent topic 命名三处不一致                  | ✅ 统一为 `edu.insight.mastery.updated` + `edu.insight.warning.triggered`（domain=insight 智能洞察领域） | coord 修 matrix.md + ai11 已对齐 |
| 006   | coord-cross-review §8.2 声明与实际不符             | ✅ coord 更正 §8.2 状态为"待执行"，明确补全时间点                                                        | coord                            |

### 11.3 关键裁决

| 裁决点             | 结论                                                            | 依据                                                                  |
| ------------------ | --------------------------------------------------------------- | --------------------------------------------------------------------- |
| analytics.proto    | 12 RPC（4 端 Dashboard + Warning + Mastery + Server Streaming） | 02 文档 §4.2 已设计，coord 补全 proto                                 |
| MasteryEvent topic | `edu.insight.mastery.updated`                                   | 004 §7.2 命名规范 `edu.<domain>.<aggregate>.<action>`，domain=insight |
| WarningEvent topic | `edu.insight.warning.triggered`                                 | 同上                                                                  |
| 004 章节补全       | coord 补全 §7.2/§1.2/§4.1/§12.2 对应段落                        | coord-cross-review §6 整改 #7/#8/#9/#10                               |
| §8.2 声明更正      | "✅ 已完成" → "⏳ 待 coord 补全（ARB-007/012）"                 | 实际 proto 未补全                                                     |
| Python Outbox 豁免 | ✅ 确认（MasteryUpdated/WarningTriggered 派生数据豁免）         | coord-cross-review §3.3                                               |

### 11.4 ai11 执行项

1. data-ana 01/02 文档：将 004 §4.2/§11.4/§11.5/§15.3 引用从 coord-cross-review.md 回切到 004 对应章节（待 coord 补全后）
2. contract.md §1.4 topic 已对齐 `edu.insight.*`（核查通过）

### 11.5 coord 执行项

1. 补全 analytics.proto 至 12 RPC（ARB-012，批次 0）
2. 补全 events.proto AIUsageEvent + MasteryEvent（ARB-011，批次 0）
3. 补全 iam.proto GetEffectiveDataScope（ARB-007 已覆盖）
4. 补全 004 §7.2（补登 6 个 topic + CDC 命名规范）/§1.2（端口列）/§4.1（gRPC 启用阶段矩阵）/§12.2（派生数据事件 Outbox 豁免条款）
5. 更正 coord-cross-review.md §8.2 状态
6. 修正 matrix.md §4：data-ana topic 改为 `edu.insight.*`

---

## §12 ARB-010：ai 模块 9 项 ISSUE 仲裁

### 12.1 背景

ai12 在 [ai_issue.md](./objections/ai_issue.md) 提请 9 项异议，涉及 matrix.md 端口不同步、ai 用量事件 topic 三义、ai.proto 待补全、events.proto 缺 AIUsageEvent、contract 与设计文档矛盾、Temporal 决策点、iam GetEffectiveDataScope、proto package 命名、ActionState 整改。

### 12.2 仲裁结论

| ISSUE | 标题                                      | 仲裁结论                                                                                                                                                           | 执行方             |
| ----- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ |
| 01    | matrix.md 端口 50057 vs 50058 不同步      | ✅ 统一为 50058（port-allocation.md §7 为准）；coord 修 matrix.md                                                                                                  | coord              |
| 02    | ai 用量事件 topic 三义未决                | ✅ 统一为 `edu.ai.usage`（见 §15 ARB-013）                                                                                                                         | coord              |
| 03    | ai.proto 待补全                           | ✅ P5 目标 6 RPC（Chat/StreamChat/GenerateQuestion/StreamGenerateQuestion/OptimizeExpression/GenerateLessonPlan）；备课状态查询/确认用 HTTP 端点（见 §14 ARB-012） | coord 补 proto     |
| 04    | events.proto 缺 AIUsageEvent              | ✅ coord 补全（见 §13 ARB-011）                                                                                                                                    | coord              |
| 05    | contract 与设计文档矛盾                   | ✅ ai12 自纠重写 contract（端口 50058 / 补 HTTP 端点 / topic 待 §15 裁决后填 / 错误码对齐 02 §6.2 / 删除消费事件）                                                 | ai12               |
| 06    | 备课工作流 Temporal（P6 决策点）          | ✅ P5 用 BackgroundTasks + Redis；P6 由 coord 评估 Temporal 引入（roadmap 标注 P6 决策点）                                                                         | ai12 P5 + coord P6 |
| 07    | iam GetEffectiveDataScope 待 P4 补全      | ✅ coord 批次 0 补全 iam.proto 12 RPC（ARB-007 已覆盖）                                                                                                            | coord              |
| 08    | proto package 命名不符合 project_rules §5 | ✅ 统一为 `next_edu_cloud.<domain>.v1`（见 §13 ARB-011）                                                                                                           | coord              |
| 09    | 响应信封偏离 ActionState                  | ✅ P5 实施时整改：所有返回值改为 ActionState；degraded 移至 `error.details.degraded`                                                                               | ai12               |

### 12.3 关键裁决

| 裁决点        | 结论                                          | 依据                                      |
| ------------- | --------------------------------------------- | ----------------------------------------- |
| ai gRPC 端口  | 50058                                         | port-allocation.md §7 为准                |
| ai RPC 总数   | 6（P5 目标）                                  | 避免 RPC 膨胀；备课状态查询/确认用 HTTP   |
| ai 用量 topic | `edu.ai.usage`                                | 最简短，符合 `edu.<domain>.<action>` 约定 |
| proto package | `next_edu_cloud.ai.v1`（保留现状）            | 见 §13 ARB-011                            |
| Temporal      | P5 不引入（BackgroundTasks + Redis）；P6 评估 | 避免过早引入复杂度                        |
| ActionState   | P5 强制整改（degraded 移至 error.details）    | 004 §11.5                                 |

### 12.4 ai12 执行项

1. 重写 ai_contract.md 对齐设计文档（端口 50058 / 补 HTTP 端点 / topic `edu.ai.usage` / 错误码对齐 02 §6.2 / 删除消费事件或标注 P6+）
2. P5 实施时整改 ActionState（main.py 返回值改为 `{success, data, error:{code,message,details,traceId}}`；degraded 移至 `error.details.degraded`）
3. P5 备课工作流用 BackgroundTasks + Redis（02 文档 §2.4 状态机已设计）
4. 修正 01/02 文档引用：004 §7.2/§1.2 引用失实，改引 port-allocation.md + coord 仲裁

### 12.5 coord 执行项

1. 补全 ai.proto 至 6 RPC（ARB-012，批次 0）
2. 补全 events.proto AIUsageEvent（ARB-011，批次 0）
3. 修正 matrix.md §2/§8：ai gRPC 端口 50057 → 50058
4. 在 roadmap 标注 P6 决策点（Temporal 引入评估）
5. 在 known-issues §2.9 ai 分区记录 ActionState 整改约束

---

## §13 ARB-011：events.proto 扩展补全 + proto package 命名统一

### 13.1 背景

msg ISSUE-013、data-ana ISSUE-002、ai ISSUE-04 共同指向 events.proto 还缺 msg/data-ana/ai 相关 message（ARB-006 已覆盖 iam/core-edu/content 的 7 个 message）。msg ISSUE-007 + ai ISSUE-08 共同指向 proto package 命名规则冲突。

### 13.2 events.proto 扩展补全（在 ARB-006 基础上）

| 新增 message      | 字段                                                                                                                                                                          | 来源             |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| MasteryEvent      | event_id/aggregate_id/event_type/occurred_at/student_id/subject_id/mastery_score/action(updated)/schema_version/metadata                                                      | data-ana 02 文档 |
| WarningEvent      | event_id/aggregate_id/event_type/occurred_at/student_id/warning_type/severity/action(triggered)/schema_version/metadata                                                       | data-ana 02 文档 |
| NotificationEvent | event_id/aggregate_id/event_type/occurred_at/notification_id/user_id/channel/action(sent/read/recalled/failed)/schema_version/metadata                                        | msg 02 文档      |
| AIUsageEvent      | event_id/request_id/user_id/school_id/provider/model/operation/prompt_tokens/completion_tokens/total_tokens/latency_ms/success/degraded/action(usage)/schema_version/metadata | ai 02 文档 §3.3  |

**同时**：

- GradeEvent 补 `class_id` 字段
- ExamEvent/HomeworkEvent/GradeEvent 补 `student_ids[]` 字段（复数，fan-out 广播用）

> events.proto 最终包含 15 个 message：ClassEvent/ExamEvent/HomeworkEvent/GradeEvent（原有 4 + 补字段）+ UserEvent/RoleEvent/AuditEvent/AttendanceEvent/TextbookEvent/ChapterEvent/KnowledgePointEvent/QuestionEvent（ARB-006 新增 8）+ MasteryEvent/WarningEvent/NotificationEvent/AIUsageEvent（本节新增 4）= 4+8+4 = 16 个 message（含原有 4）。

### 13.3 proto package 命名统一

| 裁决点                | 结论                                             | 依据                                    |
| --------------------- | ------------------------------------------------ | --------------------------------------- |
| proto package 命名    | `next_edu_cloud.<domain>.v1`（保留现状）         | 所有 proto 文件已采用此格式，改动成本高 |
| project_rules §5 更新 | `edu.<domain>.v1` → `next_edu_cloud.<domain>.v1` | 与实际 proto 一致                       |

### 13.4 coord 执行项

1. 补全 events.proto 4 个新 message（MasteryEvent/WarningEvent/NotificationEvent/AIUsageEvent）
2. 补全 GradeEvent class_id + 全部事件 student_ids[] 字段
3. 更新 project_rules §5 包名规范为 `next_edu_cloud.<domain>.v1`（需人类审批，project_rules §15.7 敏感文件）
4. 运行 `buf lint` + `buf breaking` 确保零错误

---

## §14 ARB-012：analytics.proto + ai.proto 补全

### 14.1 背景

data-ana ISSUE-003 和 ai ISSUE-03 共同指向 proto 契约未补全。coord 作为 shared-proto 维护者，在批次 0 统一补全。

### 14.2 analytics.proto 补全（12 RPC）

| Service          | RPC                    | 说明                          |
| ---------------- | ---------------------- | ----------------------------- |
| AnalyticsService | GetClassPerformance    | 班级表现                      |
| AnalyticsService | GetStudentWeakness     | 学生薄弱点                    |
| AnalyticsService | GetLearningTrend       | 学习趋势                      |
| AnalyticsService | StreamClassPerformance | Server Streaming 班级实时表现 |
| AnalyticsService | GetStudentDashboard    | 学生仪表盘                    |
| AnalyticsService | GetTeacherDashboard    | 教师仪表盘                    |
| AnalyticsService | GetAdminDashboard      | 管理员仪表盘                  |
| AnalyticsService | GetParentDashboard     | 家长仪表盘                    |
| AnalyticsService | TriggerWarning         | 触发预警                      |
| AnalyticsService | GetWarnings            | 查询预警列表                  |
| AnalyticsService | UpdateMastery          | 更新掌握度                    |
| AnalyticsService | GetMasteryByStudent    | 查询学生掌握度                |

> 对齐 data-ana 02 文档 §4.2 的 12 RPC 清单（含 1 Server Streaming）。

### 14.3 ai.proto 补全（6 RPC）

| Service   | RPC                    | 说明         |
| --------- | ---------------------- | ------------ |
| AiService | Chat                   | 单轮对话     |
| AiService | StreamChat             | 流式对话     |
| AiService | GenerateQuestion       | 生成题目     |
| AiService | StreamGenerateQuestion | 流式生成题目 |
| AiService | OptimizeExpression     | 优化表达     |
| AiService | GenerateLessonPlan     | 生成教案     |

**同时扩展 message 字段**：

- GenerateQuestionRequest：补 grade / knowledge_point_ids / question_type / count
- ChatRequest：补 user_id / session_id / data_scope（可选）

**备课工作流状态查询/确认用 HTTP 端点**（非 gRPC）：

- `GET /ai/v1/lesson/preparation/{id}`：查询备课状态
- `POST /ai/v1/lesson/preparation/{id}/confirm`：确认入库

### 14.4 coord 执行项

1. 补全 analytics.proto 至 12 RPC（含 Server Streaming）
2. 补全 ai.proto 至 6 RPC + message 字段扩展
3. 运行 `buf lint` + `buf breaking` 确保零错误
4. 运行 `buf generate` 产出 TS/Go/Python gRPC 代码

---

## §15 ARB-013：Kafka topic 命名统一裁决（跨全模块）

### 15.1 背景

msg ISSUE-008/015、data-ana ISSUE-005、ai ISSUE-02 共同指向 Kafka topic 命名跨模块不一致。需 coord 统一裁定。

### 15.2 仲裁结论

**统一命名规则**：`edu.<domain>.<aggregate>.<action>` 或 `edu.<domain>.<aggregate>.events`

**Topic 粒度策略**（按服务特征区分，coord 裁决允许差异）：

| 服务     | Topic 策略               | Topic 清单                                                                                                                                                                                                                                                             | 原因                          |
| -------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
| iam      | 聚合 topic + action 字段 | `edu.iam.user.events` / `edu.iam.role.events` / `edu.iam.audit.created`                                                                                                                                                                                                | 事件量小，聚合减少 topic 数   |
| core-edu | 具体动作 topic           | `edu.teaching.exam.created` / `.updated` / `.deleted` / `.published` / `.submitted` / `edu.teaching.homework.assigned` / `.submitted` / `.graded` / `edu.teaching.grade.recorded` / `.updated` / `edu.teaching.attendance.recorded` / `edu.teaching.class.transferred` | 事件量大，独立 topic 利于分区 |
| content  | 聚合 topic + action 字段 | `edu.content.textbook.events` / `edu.content.chapter.events` / `edu.content.knowledge_point.events` / `edu.content.question.events`                                                                                                                                    | 事件量中等，聚合减少 topic 数 |
| msg      | 具体动作 topic           | `edu.notify.notification.sent` / `.read` / `.recalled` / `.failed`                                                                                                                                                                                                     | 通知事件量大，独立 topic      |
| data-ana | 具体动作 topic           | `edu.insight.mastery.updated` / `edu.insight.warning.triggered`                                                                                                                                                                                                        | 派生数据事件（Outbox 豁免）   |
| ai       | 具体动作 topic           | `edu.ai.usage`                                                                                                                                                                                                                                                         | 派生数据事件（Outbox 豁免）   |

### 15.3 域名映射

| 服务     | domain     | 依据                              |
| -------- | ---------- | --------------------------------- |
| iam      | `iam`      | 服务名                            |
| core-edu | `teaching` | 教学领域（非服务名 core_edu）     |
| content  | `content`  | 内容领域                          |
| msg      | `notify`   | 通知领域（非服务名 msg）          |
| data-ana | `insight`  | 智能洞察领域（非服务名 data_ana） |
| ai       | `ai`       | AI 领域                           |

### 15.4 matrix.md §4 同步更新

coord 修正 matrix.md §4 Kafka 事件矩阵，全部 topic 对齐上述清单。

### 15.5 各 AI 执行项

各 AI 检查自身 02 文档 TOPIC_MAP + contract.md §1.4，对齐本仲裁的 topic 命名。具体差异见各模块 ARB 章节。

---

## §16 ARB-014：api-gateway 模块 4 项内联 ISSUE 仲裁

### 16.1 背景

ai01 的 [api-gateway_issue.md](./objections/api-gateway_issue.md) 文件仅含标题未填写实质内容（文件截断，仅 2 行），但其 [api-gateway_contract.md](./contracts/api-gateway_contract.md) v2 内联了 4 项待仲裁 ISSUE（§1.2.2 注 3 + §2.4 + §3.1）。coord 提取 contract.md 中的内联 ISSUE 逐条仲裁。

### 16.2 仲裁结论

| ISSUE | 标题                              | 仲裁结论                                                                                                                   | 执行方         |
| ----- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------- |
| 001   | JWKS 拉取方式（gRPC vs HTTP）     | ✅ 已确认 HTTP JWKS（contract v2 §2.3 已执行：`GET /.well-known/jwks.json`，TTL 5min 缓存）                                | ai01（已完成） |
| 002   | shared-go 包接入                  | ✅ shared-go 包骨架已完成（contract §3.1 显示 ✅）；ai01 直接 import `packages/shared-go` 的 jwks/logger/tracer/env 4 模块 | ai01（已就绪） |
| 003   | API 版本化路由方案（双 /v1 前缀） | ✅ 采纳方案 A：前端调用 `/api/v1/<service>/v1/*`（双 /v1 前缀，Gateway 纯透传无路径重写）                                  | ai01           |
| 004   | zap vs slog 日志库选型            | ✅ 遵循 project_rules §12 使用 **zap**（project_rules 明确规定 Go 日志用 zap）                                             | ai01           |

### 16.3 关键裁决

| 裁决点            | 结论                                                            | 依据                                                                                             |
| ----------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| JWKS 拉取         | HTTP `GET /.well-known/jwks.json`（非 gRPC）                    | president §2.16 + contract v2 §2.3                                                               |
| Gateway gRPC 消费 | **无**（Gateway 不消费任何 gRPC，纯 HTTP 透传）                 | president §2.16 + B3 裁决（权限由下游 Controller 自校验）                                        |
| API 版本化        | 方案 A：`/api/v1/<service>/v1/*` 双前缀，Gateway 不做路径重写   | 纯透传最简，避免路径重写 bug；`/api/v1` 是 Gateway API 前缀，`/<service>/v1` 是服务内部 API 前缀 |
| Go 日志库         | zap（对齐 project_rules §12）                                   | project_rules 强制规定；Go 1.22 slog 为备选，需 project_rules 变更后评估                         |
| matrix.md §2 修正 | 移除 api-gateway 为 iam gRPC 消费方（contract §2.1 勘误已指出） | Gateway 不消费 gRPC                                                                              |

### 16.4 ISSUE-003 方案 A 路径规范

| 层级         | 路径格式                                              | 示例                                   |
| ------------ | ----------------------------------------------------- | -------------------------------------- |
| 前端调用     | `/api/v1/<service>/v1/<resource>`                     | `/api/v1/iam/v1/register`              |
| Gateway 透传 | 原样转发到 `<service>:<port>/<service>/v1/<resource>` | iam:3002`/iam/v1/register`             |
| 服务内部路由 | `/<service>/v1/<resource>`                            | iam Controller 注册 `/iam/v1/register` |

> **双 /v1 语义**：外层 `/api/v1` 是 Gateway 层 API 版本（全局），内层 `/v1` 是服务内部 API 版本（独立演进）。此设计允许 Gateway 和服务各自独立版本化。

### 16.5 ai01 执行项

1. P2.7 任务统一迁移路由至 `/api/v1/<service>/v1/*` 双前缀格式（当前 P1 代码为 `/api/v1/<service>/*` 单前缀）
2. 使用 zap 日志库（import `packages/shared-go/logger`）
3. ISSUE-001/002 已落地，无需额外动作
4. 补充 issue.md 文件内容（当前为空，后续如有新问题需按格式追加）

### 16.6 coord 执行项

1. 修正 matrix.md §2 gRPC 接口提供方矩阵：移除 api-gateway 为 iam gRPC 消费方
2. 确认 shared-go 4 模块骨架已就绪（contract §3.1 已标 ✅）

---

## §17 ARB-015：push-gateway 模块 7 项 ISSUE 仲裁

### 17.1 背景

ai02 在 [push-gateway_issue.md](./objections/push-gateway_issue.md) 提请 7 项异议，涉及 SSE 端点冲突、内部 API 鉴权命名、容量目标、端点路径、审计表设计、Redis /readyz 冲突、02 文档缺 ADR/NFR。coord 对照 [push-gateway_contract.md](./contracts/push-gateway_contract.md) v2 逐条仲裁。

### 17.2 仲裁结论

| ISSUE | 标题                                | 仲裁结论                                                                                                                  | 执行方                                 |
| ----- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| 001   | SSE 端点三方冲突                    | ✅ 采纳 ai02 建议：**不支持 SSE，仅 WebSocket**。移除 contract.md §1.2 的 `/sse` 端点 + matrix.md §5 SSE 行               | coord 修 contract + matrix + ai02 确认 |
| 002   | 内部 API 鉴权命名不一致             | ✅ 统一为 `X-Internal-Token` 头 + `INTERNAL_API_TOKEN` 环境变量（对齐总裁 §7.2）                                          | ai02 改代码 + coord 修 contract        |
| 003   | 容量目标 50k vs 10w+                | ✅ 统一为 **10w+**（对齐 02 文档 + pending-features 权威）                                                                | coord 修 modules/README §7             |
| 004   | /internal/send vs /internal/push    | ✅ 统一为 `/internal/push`（ai02 已自行修复，contract v2 已对齐）                                                         | ai02（已完成）                         |
| 005   | 审计表设计缺失                      | ✅ 方案 2：审计由 msg 服务维护（msg 已落库），push-gateway 保持无 DB 定位                                                 | ai10 确认审计字段 + ai02 无需引入 DB   |
| 006   | ISSUE-058 与 055 Redis /readyz 冲突 | ✅ **Redis 软失败**（仅告警 + `degraded: true` + 返 200，不返 503）；从 ISSUE-055 必需依赖列表中移除 push-gateway → Redis | coord 澄清两裁决优先级                 |
| 007   | 02 文档缺 ADR/NFR/容量/失败模式     | ✅ P5（批次 4）补全 02 文档 §14-§17 四章节（ADR/非功能性需求/失败模式/容量估算）                                          | ai02                                   |

### 17.3 关键裁决

| 裁决点        | 结论                                                  | 依据                                                                   |
| ------------- | ----------------------------------------------------- | ---------------------------------------------------------------------- |
| SSE 端点      | **不支持**，仅 WebSocket                              | 单一协议降低维护成本；SSE 单向下行不适合双向协议                       |
| 内部鉴权      | `X-Internal-Token` + `INTERNAL_API_TOKEN`（共享密钥） | 总裁 §7.2；mTLS P5 成本过高，K8s NetworkPolicy 已隔离                  |
| 容量目标      | 10w+ 连接/单实例                                      | pending-features 权威；Go goroutine-per-connection 约 2-3GB/10w 连接   |
| 审计表归属    | msg 服务维护（push-gateway 无 DB）                    | 保持 push-gateway 无 DB 定位，避免引入持久化层                         |
| Redis /readyz | **软失败**（仅告警不阻塞，返 200 + degraded）         | push-gateway 重启不解决 Redis 故障；Redis 故障时单实例仍能服务本地连接 |
| Kafka /readyz | 软失败（仅告警 + degraded）                           | ISSUE-055 裁决                                                         |
| 心跳协议      | RFC 6455 控制帧（Ping/Pong，30s 间隔）                | 02 文档 §10                                                            |

### 17.4 ISSUE-006 Redis 软失败裁决详情

**冲突**：

- ISSUE-055（president §3.3）：Redis 列为"必需依赖"，失败返 503
- ISSUE-058（president §4.3）：Redis /readyz "仅告警不阻塞，避免雪崩"

**coord 裁决**：以 ISSUE-058 为准（后裁决优先），Redis 对 push-gateway 为**软失败**。

**理由**：

1. push-gateway 重启不解决 Redis 故障（Redis 是跨实例广播依赖，非本地状态）
2. Redis 故障时单实例仍能服务本地连接（仅跨实例广播失效）
3. 重启会丢失本地连接表，加剧雪崩风险
4. ISSUE-055 的"必需依赖"列表应排除 push-gateway → Redis（Redis 故障不触发 Pod 重启）

**修正**：004 §7.2 / coord-cross-review 中 ISSUE-055 必需依赖列表，push-gateway → Redis 标注为"软失败（ISSUE-058 裁决覆盖）"。

### 17.5 ai02 执行项

1. 修改源码鉴权头：`X-Internal-Key` → `X-Internal-Token`；`INTERNAL_API_KEY` → `INTERNAL_API_TOKEN`（ISSUE-002）
2. 02 文档 §3.1 补 Hub 启动重建机制（SADD + EXPIRE 60s + 清空旧 instanceID 成员，ISSUE-058 回写）
3. 02 文档 §6.7 /readyz Redis 检查改为软失败（返 200 + degraded，不返 503，ISSUE-006）
4. 02 文档 §5.4 添加"设计决策记录：gRPC vs HTTP 协议选型"章节，标注"coord 已采纳 P1"（ISSUE-056 回写）
5. 02 文档 §5.1 topic 已对齐 `edu.notification.requested`（ISSUE-053 回写确认）
6. 02 文档补 §14-§17 四章节（ADR/NFR/失败模式/容量估算，P5 批次 4 补全，ISSUE-007）
7. 02 文档补 `push_gateway_redis_set_rebuild_total` 指标 + 60s 不一致窗口文档说明（ISSUE-058 回写）
8. ISSUE-001/003/004/005 由 coord 修文档，ai02 确认

### 17.6 coord 执行项

1. 修正 contract.md §1.2：移除 `/sse` 端点（ISSUE-001）
2. 修正 matrix.md §5：移除 push-gateway SSE 行（ISSUE-001）
3. 修正 modules/push-gateway/README.md §7：50k → 10w+（ISSUE-003）
4. 修正 contract.md §1.2：鉴权头统一为 `X-Internal-Token`（ISSUE-002，contract v2 已部分对齐，确认最终）
5. 修正 004 §7.2 / coord-cross-review：ISSUE-055 必需依赖列表中 push-gateway → Redis 标注"软失败"
6. ISSUE-005 协调 ai10 确认 msg 审计表覆盖 push-gateway 推送结果字段

---

## §18 ARB-016：teacher-bff 模块 3 项 ISSUE 仲裁

### 18.1 背景

ai03 在 [teacher-bff_issue.md](./objections/teacher-bff_issue.md) 提请 3 项异议，涉及 admin 命名空间 P2 预留与 ARB-001 冲突、dashboard classes 数据来源与调用链冲突、GraphQL schema 文件命名不一致。coord 对照 [teacher-bff_contract.md](./contracts/teacher-bff_contract.md) v2 逐条仲裁。

### 18.2 仲裁结论

| ISSUE | 标题                                              | 仲裁结论                                                                                                      | 执行方                           |
| ----- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| 001   | admin 命名空间 P2 预留与 ARB-001 "P2 不包含" 冲突 | ✅ 以总裁裁决为准（president > coord），修正 ARB-001 §1.3 为 "P2 预留 admin schema 命名空间占位"              | coord 修 ARB-001                 |
| 002   | P2 dashboard classes 数据来源与调用链冲突         | ✅ 采纳 president §3.5：P2 classes 数据从 iam gRPC 获取（GetViewports/GetEffectiveAccess），不调 classes 服务 | coord 修 ARB-001 + ai03 修文档   |
| 003   | GraphQL schema 文件命名不一致                     | ✅ 以总裁 §2.17 为准：统一为 `teacher-bff.schema.graphql`                                                     | coord 修 ARB-001 + ai03 创建文件 |

### 18.3 关键裁决

| 裁决点               | 结论                                                                                       | 依据                                                           |
| -------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------- |
| admin 命名空间 P2    | **P2 预留** schema 占位（声明 `admin` Query/Mutation 类型骨架，Resolver 返 null），P6 实现 | president §5.1 + §7.3（裁决优先级 president > coord）          |
| P2 classes 数据来源  | **iam gRPC**（GetViewports/GetEffectiveAccess 返回关联班级），不调 classes 服务            | president §3.5 + B2 裁决（classes P2 无 gRPC，禁止 REST 过渡） |
| P3+ classes 数据来源 | 切换为 `core-edu.ClassService.GetClassesByTeacher` RPC（core-edu gRPC 50053 就绪后）       | ARB-007 已补全 ClassService 4 RPC                              |
| schema 文件名        | `teacher-bff.schema.graphql`（统一 `<bff-name>.schema.graphql` 格式）                      | president §2.17                                                |
| 裁决优先级           | president > coord（ARB-001 修正为对齐总裁裁决）                                            | 总裁裁决覆盖 coord 仲裁                                        |

### 18.4 ISSUE-002 P2 dashboard 调用链修正

**原 ARB-001 §1.4 第 4 条**：

> dashboard Resolver 并行调用 iam（3 RPC）+ classes（1 RPC），用 DataLoader 防御 N+1

**修正为**：

> dashboard Resolver 并行调用 iam gRPC（GetUserInfo + GetViewports + GetEffectiveAccess），classes 列表从 iam 返回数据推导，P3 core-edu gRPC 就绪后切换为 `GetClassesByTeacher` RPC

**理由**：

1. classes P2 无 gRPC server（classes.proto 注释 "P3 起转 gRPC"）
2. B2 裁决禁止 REST 过渡
3. president §3.5 裁决 P2 班级列表数据来自 iam

### 18.5 ai03 执行项

1. 创建 `packages/shared-ts/contracts/graphql/teacher-bff.schema.graphql`（文件名用 `.schema.graphql`，ISSUE-003）
2. schema 中预留 `admin` 命名空间占位（`admin.*` Query/Mutation 类型骨架，Resolver 返 null，ISSUE-001）
3. dashboard Resolver P2 实现：调 iam gRPC 获取 classes 数据（不调 classes 服务，ISSUE-002）
4. P3+ 切换 dashboard classes 数据源为 `core-edu.ClassService.GetClassesByTeacher`

### 18.6 coord 执行项

1. 修正 ARB-001 §1.3：admin 命名空间改为 "P2 预留 schema 占位"
2. 修正 ARB-001 §1.3/§1.4：文件名改为 `teacher-bff.schema.graphql`
3. 修正 ARB-001 §1.4 第 4 条：dashboard classes 数据来源改为 iam gRPC（不调 classes 服务）
4. 修正 ARB-001 §1.2 GraphQL schema 代码块：DataScope 枚举去掉 DISTRICT 改 SUBJECT（ARB-003 ISSUE-004 已裁决，需同步 ARB-001）

---

## §19 ARB-017：student-bff 模块 4 项新 ISSUE 仲裁

### 19.1 背景

ai04 在 [student-bff_issue.md](./objections/student-bff_issue.md) §1 提请 4 项新异议（STU-001~004），涉及 01 文档与 B1/B2/B5 裁决冲突、02 引用不存在的 004 章节、02 §8.3 八项已裁决决策未更新、GraphQL schema 第一版未起草。coord 对照 [student-bff_contract.md](./contracts/student-bff_contract.md) v2 逐条仲裁。

### 19.2 仲裁结论

| ISSUE   | 标题                            | 仲裁结论                                                                                                        | 执行方 |
| ------- | ------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------ |
| STU-001 | 01 文档与 B1/B2/B5 裁决冲突     | ✅ 与 ISSUE-028 合并处理：01 文档随 02 文档一并回写（删除 REST 端点清单、改 GraphQL、错误码改 BFF_STUDENT_）    | ai04   |
| STU-002 | 02 引用不存在的 004 §11.4/§11.5 | ✅ coord 补全 004 §11.4（错误码前缀矩阵）+ §11.5（ActionState 信封规范）章节                                    | coord  |
| STU-003 | 02 §8.3 八项已裁决决策未更新    | ✅ 02 文档回写时删除已裁决项的"待仲裁"标注，改为"已裁决（见 coord-final-decisions §2 BX）"                      | ai04   |
| STU-004 | GraphQL schema 第一版未起草     | ✅ ai04 在批次 1 等待期产出 schema 草案，存放 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql` | ai04   |

### 19.3 关键裁决

| 裁决点               | 结论                                                       | 依据                                       |
| -------------------- | ---------------------------------------------------------- | ------------------------------------------ |
| 01 文档回写范围      | 01 + 02 一并回写（01 不作为历史快照保留，必须对齐裁决）    | ISSUE-028 + STU-001 合并                   |
| 004 §11.4/§11.5 补全 | coord 补全错误码前缀矩阵 + ActionState 信封规范章节        | 004 作为架构设计意图唯一源，不应有断裂引用 |
| schema 仲裁时机      | ai04 批次 1 等待期起草 → coord 批次 2 启动前仲裁第一版     | president §2.2                             |
| schema 文件名        | `student-bff.schema.graphql`（统一格式，对齐 teacher-bff） | president §2.17                            |
| 02 §8.3 已裁决项     | B1/B2/B3/B4/B5/B6/B7/B8 全部已裁决，删除"待仲裁"标注       | coord-final-decisions §2                   |

### 19.4 ISSUE-028 回写范围确认

ai04 须在批次 2 启动前完成 02 文档回写（president §3.4 裁决），回写范围：

1. **§4 API 设计**：21 个 REST 端点 → GraphQL Query/Mutation 清单
2. **§9.2 演进路线**：删除"REST→GraphQL 演进"（违反"不分阶段"原则）
3. **§9.3 通信协议演进**：删除"HTTP→gRPC 演进"（违反 B2）
4. **§3.1 下游通信**："HTTP fetch（当前阶段）" → "gRPC 调用下游（@grpc/grpc-js + @bufbuild/protobuf）"
5. **§3.3/§6 错误码**：`STUDENT_BFF_` → `BFF_STUDENT_`
6. **§8.3 未决决策**：8 项已裁决项标注"已裁决"，仅保留 #7/#10/#11/#12 合理设计决策
7. **01 文档**：同步回写（删除 REST 假设、对齐错误码前缀、删除已裁决项重复提请）

### 19.5 ai04 执行项

1. 批次 1 等待期产出 `student-bff.schema.graphql` 草案（ISSUE-STU-004）
2. 批次 2 启动前回写 01 + 02 文档（ISSUE-028 + STU-001/003，范围见 §19.4）
3. 02 文档引用源修正：004 §11.4/§11.5 → coord 补全后引用（或暂引 coord-final-decisions G14/G8）
4. 实现 DownstreamClient 回写 teacher-bff（B8 裁决）

### 19.6 coord 执行项

1. 补全 004 §11.4（错误码前缀矩阵：GW_/IAM_/CORE_EDU_/BFF_TEACHER_/BFF_STUDENT_/BFF_PARENT_/MSG_/PUSH_/DATA_ANA_/AI_）+ §11.5（ActionState 信封规范：`{success, data, error:{code,message,details,traceId}}` + degraded 放 error.details）
2. 批次 2 启动前仲裁 student-bff schema 第一版（president §2.2）

---

## §20 ARB-018：parent-bff 模块 10 项 ISSUE 仲裁

### 20.1 背景

ai05 在 [parent-bff_issue.md](./objections/parent-bff_issue.md) 提请 10 项异议，涉及 01 文档未同步、ChildGuard TTL 不一致、契约引用错误、004 依赖图未同步、parent-portal REST vs GraphQL 跨模块冲突、proto 包名缺失、Notification.childId 缺失、ClassService 缺失、责任方过时、02 缺 ADR/NFR。coord 对照 [parent-bff_contract.md](./contracts/parent-bff_contract.md) 逐条仲裁。

### 20.2 仲裁结论

| ISSUE | 标题                                                       | 仲裁结论                                                                                                                                                                              | 执行方                  |
| ----- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| 001   | 01 文档未同步 ai05 接手 + U3/U4/C1 仲裁                    | ✅ 01 作为阶段 1 历史快照保留原样，以 02 为准（02 已执行 U3/U4/C1）                                                                                                                   | ai05 标注 01 为历史快照 |
| 002   | 02 文档 ChildGuard TTL 三处不一致（60s/30s）               | ✅ 统一为 **30s**（§3.1.1 表格改为 30s，对齐 §9 #2 + §13 #7）                                                                                                                         | ai05 修文档勘误         |
| 003   | contract.md 引用 I3 → 应为 I6                              | ✅ 修正为 I6 裁决（coord-final-decisions §1 I6：家长-学生关联）                                                                                                                       | ai05 修 contract 引用   |
| 004   | 004 §4 + matrix.md §1 未同步 C6 仲裁（缺 DataAna + Msg）   | ✅ coord 补全 004 §4 服务依赖图 + matrix.md §1 依赖矩阵（加 PBFF → DataAna + PBFF → Msg）                                                                                             | coord                   |
| 005   | parent-portal 01 文档按 REST 消费 parent-bff（跨模块冲突） | ✅ coord 协调 ai15 将 parent-portal 01/02 改为 GraphQL 消费（`POST /api/v1/parent/v1/graphql`）                                                                                       | coord 协调 ai15         |
| 006   | proto 包名引用缺 next_edu_cloud 前缀                       | ✅ 统一补 `next_edu_cloud.` 前缀（ARB-011 已裁决，ai05 修 02 §3.3 DTO 映射表）                                                                                                        | ai05                    |
| 007   | GraphQL Notification.childId 在 msg.proto 缺失             | ✅ coord 协调 ai10 在 msg.proto Notification message 补 `string child_id = 9;`（可选，非家长通知为空）                                                                                | coord 协调 ai10         |
| 008   | core_edu.proto 缺 ClassService                             | ✅ coord 已在 ARB-007 补全 ClassService 4 RPC（GetClass/GetClassesByTeacher/BatchGetClasses/ListStudentsByClass）；02 §7.1 状态改 "✅ 已有"；Grade.score string→Float 转换规则补 §3.3 | ai05 修 02 §7.1 + §3.3  |
| 009   | ai-allocation iam 责任方 ai02 → ai06                       | ✅ 修正为 ai06（iam 现归属 ai06，ai-allocation §3.2 确认）                                                                                                                            | ai05 修 01/02 引用      |
| 010   | 02 缺 ADR/NFR/容量规划/威胁建模                            | ✅ P6 硬化阶段补全（当前不阻塞 P4 实施）                                                                                                                                              | ai05 P6 补全            |

### 20.3 关键裁决

| 裁决点                          | 结论                                                                             | 依据                                               |
| ------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------- |
| 01 文档定位                     | 历史快照保留原样，02 为权威源                                                    | 避免回写成本；01 标注"阶段 1 历史快照，以 02 为准" |
| ChildGuard TTL                  | 30s + 主动失效（统一三处）                                                       | §9 #2 + §13 #7 已调整，§3.1.1 表格勘误             |
| 契约引用                        | I6（非 I3），ISSUE-047 编号虚构，删除                                            | coord-final-decisions §1 I6                        |
| C6 依赖图同步                   | coord 补 004 §4 + matrix.md §1：PBFF → IAM + CoreEdu + DataAna + Msg             | C6 仲裁                                            |
| parent-portal 消费方式          | GraphQL（`POST /api/v1/parent/v1/graphql`），非 REST                             | U3 仲裁 + parent-bff 02 §4.1 不实现 REST           |
| proto 包名                      | `next_edu_cloud.<domain>.v1`（全引用补前缀）                                     | ARB-011 已裁决                                     |
| msg.proto Notification.child_id | 补 `string child_id = 9;`（可选字段）                                            | ISSUE-007 家长场景需按孩子过滤通知                 |
| ClassService 归属               | core-edu（ARB-007 已补全 4 RPC）                                                 | coord 批次 0 补全                                  |
| Grade.score 类型转换            | BFF response-mapper 做 `Number.parseFloat(score)`，失败抛 BFF_PARENT_BAD_GATEWAY | ai05 建议                                          |
| iam 责任方                      | ai06（非 ai02）                                                                  | ai-allocation §3.2                                 |

### 20.4 ISSUE-005 跨模块契约冲突处理

**冲突**：parent-portal（ai15）01 文档 §3.1 按 REST 消费 parent-bff，但 parent-bff 02 §4.1 明确"不实现 REST 业务端点"。

**coord 仲裁**：按 project_rules §14.4 跨模块变更顺序处理：

1. parent-bff 契约已定义（GraphQL `POST /api/v1/parent/v1/graphql`）
2. coord 协调 ai15 将 parent-portal 01/02 文档的 parent-bff 消费契约从 REST 改为 GraphQL
3. 同步 C4 仲裁：iam 路径 `/iam/permissions/effective`（非 `/iam/effective-permissions`）
4. parent-portal §3.1 标注 "BFF 对接：parent-bff（ai05 设计）"

### 20.5 ISSUE-007 msg.proto Notification 字段补全

coord 协调 ai10 在 msg.proto Notification message 补字段：

```proto
message Notification {
  string id = 1;
  string user_id = 2;
  string type = 3;
  string title = 4;
  string content = 5;
  string channel = 6;
  bool is_read = 7;
  int64 created_at = 8;
  string child_id = 9;  // 新增：关联孩子 ID（可选，非家长通知为空）
}
```

> parent-bff GraphQL `Notification.childId` 映射自此字段。ai10 在 msg 02 文档同步补字段说明。

### 20.6 ISSUE-008 ClassService + Grade.score 处理

**ClassService**：coord 已在 ARB-007 补全 core_edu.proto ClassService 4 RPC（GetClass/GetClassesByTeacher/BatchGetClasses/ListStudentsByClass）。parent-bff 02 §7.1 状态从 "❌ 待补" 改为 "✅ 已有"。

**Grade.score 类型转换**：parent-bff 02 §3.3 DTO 映射表补转换规则说明：

- `core_edu.v1.Grade.score`（string）→ GraphQL `Grade.score`（Float!）
- BFF response-mapper 执行 `Number.parseFloat(score)`
- 转换失败（NaN）抛 `BFF_PARENT_BAD_GATEWAY` + i18n key `error.bffParent.bad_gateway`

### 20.7 ai05 执行项

1. 02 §3.1.1 ChildGuard TTL 改为 30s（ISSUE-002 勘误）
2. 02 §3.3 DTO 映射表补 `next_edu_cloud.` 前缀（ISSUE-006）
3. 02 §3.3 补 Grade.score string→Float 转换规则（ISSUE-008）
4. 02 §7.1 ClassService.GetClass 状态改 "✅ 已有"（ISSUE-008，ARB-007 已补全）
5. contract.md §2.1 引用 I3 → I6 修正（ISSUE-003）
6. 01 §7.1/§7.3 + 02 §7.3 #1 责任方 ai02 → ai06（ISSUE-009）
7. 01 文档头部标注"阶段 1 历史快照，以 02 为准"（ISSUE-001）
8. P6 硬化阶段补 02 ADR/NFR/容量规划/威胁建模（ISSUE-010，非阻塞）

### 20.8 coord 执行项

1. 补全 004 §4 服务依赖图：加 `PBFF --> DataAna` + `PBFF --> Msg`（ISSUE-004，C6 仲裁同步）
2. 补全 matrix.md §1 服务依赖矩阵：加 `PBFF --> DataAna` + `PBFF --> Msg`（ISSUE-004）
3. 协调 ai10 在 msg.proto Notification 补 `child_id = 9` 字段（ISSUE-007）
4. 协调 ai15 将 parent-portal 01/02 改为 GraphQL 消费 parent-bff（ISSUE-005，跨模块变更）
5. 确认 ClassService 已在 ARB-007 补全（ISSUE-008 已覆盖）

---

## §21 ARB-019：student-portal 模块 7 项 ISSUE 仲裁

### 21.1 背景

ai14 在 [student-portal_issue.md](./objections/student-portal_issue.md) 提请 7 项异议，涉及 GraphQL endpoint 路径、schema 文件存放位置、考试防作弊策略、主观题粘贴策略、附件上传协议、实时事件命名、DataScope L0 强制执行层。coord 对照 [student-portal_contract.md](./contracts/student-portal_contract.md) v2 + [student-bff_contract.md](./contracts/student-bff_contract.md) v2 + ARB-001/ARB-002/ARB-014 逐条仲裁。

### 21.2 仲裁结论

| ISSUE  | 标题                                      | 仲裁结论                                                                                                              | 执行方                                        |
| ------ | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| 014-01 | GraphQL endpoint 路径不一致               | ✅ 统一为 `POST /api/v1/student/graphql`（对齐 matrix.md §5 + ARB-014 方案 A 双 /v1 前缀）                            | ai14 修 contract.md §2.3 路径 + ai01 确认路由 |
| 014-02 | student-bff GraphQL schema 存放位置不一致 | ✅ 统一为 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql`（对齐 president §2.17 + ARB-016/017）     | ai04 创建并维护                               |
| 014-03 | 考试作答页全屏策略与防作弊检测边界        | ✅ P3 不强制全屏 + visibilitychange 仅记录 + 多标签警告不阻止 + 走 student-bff GraphQL mutation `recordExamViolation` | ai14 + ai04                                   |
| 014-04 | 主观题粘贴策略（防作弊 vs 学生体验）      | ✅ 客观题禁止 + 主观题允许记录 + 作文题允许不记录；复用 recordExamViolation（type=PASTE）                             | ai14 + ai04                                   |
| 014-05 | 作业附件上传协议                          | ✅ 方案 A：api-gateway REST `POST /api/v1/student/upload` → 对象存储 → GraphQL mutation 提交 URL                      | ai01 路由 + ai04 mutation 接受 attachmentUrls |
| 014-06 | 考试延长/题目重排等实时事件命名           | ✅ ai08 发布 ExamExtended + ExamForceSubmitted；题目重排 P3 不实现 P4 评估                                            | ai08 发布 + ai10 推送                         |
| 014-07 | 学生端 DataScope L0 边界强制执行层        | ✅ 方案 A：student-bff Resolver 从 JWT x-user-id 提取 studentId，前端 query 不传 studentId                            | ai14 修 query 设计 + ai04 实现                |

### 21.3 关键裁决

| 裁决点           | 结论                                                                      | 依据                                          |
| ---------------- | ------------------------------------------------------------------------- | --------------------------------------------- |
| GraphQL endpoint | `POST /api/v1/student/graphql`（双 /v1 前缀，对齐 ARB-014 方案 A）        | matrix.md §5 + ARB-014 §16.4                  |
| schema 文件路径  | `packages/shared-ts/contracts/graphql/student-bff.schema.graphql`         | president §2.17 + ARB-017 §19.3               |
| 全屏策略         | P3 推荐不强制（提示"建议全屏作答"）；P4 基于教师反馈评估升级              | 防止误伤合法场景                              |
| 离开页面策略     | visibilitychange hidden 仅记录，累计 3 次警告教师端可见；不自动提交       | 误触发风险高                                  |
| 多标签检测       | BroadcastChannel 警告 + 记录，不阻止作答                                  | 合法场景如查词典                              |
| 防作弊事件上报   | student-bff GraphQL mutation `recordExamViolation(examId, type, payload)` | GraphQL 统一入口；不走 push-gateway           |
| 粘贴策略分层     | 客观题禁止 / 主观题允许记录 / 作文题允许不记录                            | 防作弊与学生体验平衡                          |
| 附件上传协议     | api-gateway REST + 对象存储 + GraphQL mutation 提交 URL                   | GraphQL 不适合大文件；REST + 对象存储业界通用 |
| 实时事件命名     | ExamExtended + ExamForceSubmitted（ai08 发布到 `edu.exam.events` topic）  | 事件命名规范 `<Aggregate>.<Action>`           |
| 题目重排         | P3 不实现（题目顺序固定），P4 评估实时重排需求                            | 降低 P3 复杂度                                |
| DataScope L0     | student-bff Resolver 层从 JWT 强制过滤（方案 A），前端不传 studentId      | 前端无法绕过；gRPC 层重新校验                 |

### 21.4 ISSUE-014-03 防作弊策略详情

**全屏 API**：P3 不强制（提示"建议全屏作答"），P4 评估是否升级为强制（基于教师反馈）

**visibilitychange 策略**：

- hidden 触发时仅记录（不自动提交）
- 累计 3 次警告后教师端可见（走 `recordExamViolation` mutation 上报）
- 避免误伤合法场景（如切到词典查询）

**多标签检测**：

- BroadcastChannel 检测到多标签时警告 + 记录
- 不阻止作答（避免误伤）

**事件上报链路**：

```
student-portal → POST /api/v1/student/graphql (recordExamViolation mutation)
              → student-bff Resolver
              → core-edu gRPC ExamService.RecordViolation（ai08 在 P3 补全 RPC）
              → 落库 + 教师端可见
```

### 21.5 ISSUE-014-05 附件上传协议详情

**方案 A（采纳）**：

1. 前端：`POST /api/v1/student/upload`（multipart/form-data）→ api-gateway 鉴权 → 对象存储（MinIO/OSS）→ 返回 signed URL
2. 前端：GraphQL mutation `submitHomework(input: { homeworkId, answers, attachmentUrls: [String!] })` 提交作业 + 附件 URL
3. student-bff Resolver 接收 attachmentUrls 字段，透传给 core-edu

**路由配置**：

- api-gateway：`/api/v1/student/upload` → `student-bff:3009/upload`（或直接到对象存储代理）
- 由 ai01（api-gateway）确认路由配置 + 大小限制（建议 20MB）+ 类型白名单（图片/PDF/文档）

### 21.6 ISSUE-014-06 实时事件命名详情

| 事件                  | 发布方           | topic             | 消费链路                                            | 阶段 |
| --------------------- | ---------------- | ----------------- | --------------------------------------------------- | ---- |
| ExamExtended          | ai08（core-edu） | `edu.exam.events` | msg 消费 → push-gateway → student-portal 更新倒计时 | P3   |
| ExamForceSubmitted    | ai08（core-edu） | `edu.exam.events` | msg 消费 → push-gateway → student-portal 触发提交   | P3   |
| ExamQuestionReordered | ai08（core-edu） | `edu.exam.events` | P3 不实现，P4 评估                                  | P4   |

### 21.7 ISSUE-014-07 DataScope L0 强制执行详情

**方案 A（采纳）**：student-bff Resolver 层从 JWT 提取 studentId，强制过滤

**ai14 修改 02-architecture-design.md §4.2**：

- 移除所有 query 的 `studentId` 参数（如 `myClasses(studentId: ID!)` → `myClasses`）
- 所有 query 改为无参或仅含分页/筛选参数
- 前端不传 studentId（无法绕过 L0 边界）

**ai04 实现**：

- 所有 student-bff Query Resolver 从 JWT `x-user-id` 提取 studentId
- 强制过滤（`WHERE student_id = :jwtStudentId`）
- 不接受前端传入的 studentId 参数（GraphQL schema 层不暴露）

### 21.8 ai14 执行项

1. 修 contract.md §2.3：统一路径为 `POST /api/v1/student/graphql`（ISSUE-014-01）
2. 02 §4.2 GraphQL query 定义：移除所有 `studentId` 参数（ISSUE-014-07）
3. 02 §14 防作弊策略：补全屏策略 + visibilitychange + 多标签 + 事件上报链路（ISSUE-014-03）
4. 02 §14 粘贴策略：补客观题/主观题/作文题分层（ISSUE-014-04）
5. 02 §16 实时事件：补 ExamExtended + ExamForceSubmitted 命名（ISSUE-014-06）
6. 02 §4.2 mutation 域：确认 recordExamViolation + recordPasteEvent 参数（依赖 ai04 补全）

### 21.9 ai04 执行项

1. 创建 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql`（ISSUE-014-02）
2. 所有 Query Resolver 从 JWT 提取 studentId，不接受前端参数（ISSUE-014-07）
3. P3 提供 `recordExamViolation(input: RecordExamViolationInput!): RecordExamViolationPayload!` mutation（ISSUE-014-03）
4. P3 提供 `recordPasteEvent` mutation 或复用 recordExamViolation（type=PASTE）（ISSUE-014-04）
5. submitHomework mutation 接受 `attachmentUrls: [String!]` 字段（ISSUE-014-05）

### 21.10 ai01 执行项

1. 确认路由 `/api/v1/student/*` → `student-bff:3009/*`（ISSUE-014-01）
2. 确认 `/api/v1/student/upload` 路由配置（大小限制 + 类型白名单）（ISSUE-014-05）

### 21.11 ai08 执行项

1. P3 发布 ExamExtended 事件到 `edu.exam.events` topic（ISSUE-014-06）
2. P3 发布 ExamForceSubmitted 事件到 `edu.exam.events` topic（ISSUE-014-06）
3. P3 补全 ExamService.RecordViolation RPC（防作弊违规落库）（ISSUE-014-03）

### 21.12 coord 执行项

1. 确认 matrix.md §5 路径前缀对齐 `/api/v1/student/*`（ISSUE-014-01）
2. 协调 ai08 补全 ExamService.RecordViolation RPC（ISSUE-014-03）

---

## §22 ARB-020：parent-portal 模块 10 项 ISSUE 仲裁

### 22.1 背景

ai15 在 [parent-portal_issue.md](./objections/parent-portal_issue.md) 提请 10 项异议，涉及 01/02 文档 REST 消费与 ARB-001 冲突、MF shared 配置缺 urql、switch-child 端点不一致、登录端点三方不一致、未决决策过时、contract §1.2 误标 HTTP 端点、MF 配置文件位置不一致、GraphQL 路径缺 v1、switchChild Mutation 未明确、iam GetChildrenByParent 缺失。coord 对照 [parent-portal_contract.md](./contracts/parent-portal_contract.md) + [parent-bff_contract.md](./contracts/parent-bff_contract.md) + ARB-001/ARB-002/ARB-018 逐条仲裁。

### 22.2 仲裁结论

| ISSUE | 标题                                            | 仲裁结论                                                                                                    | 执行方                         |
| ----- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------ |
| 001   | 01/02 文档 REST 消费 parent-bff 与 ARB-001 冲突 | ✅ 统一 GraphQL 消费（对齐 ARB-018 ISSUE-005 跨模块裁决）                                                   | ai15 修 01/02                  |
| 002   | MF shared 配置缺 urql/graphql/@edu/*            | ✅ 补全 7 项 singleton（react/react-dom/urql/graphql/@edu/ui-tokens/@edu/ui-components/@edu/hooks）         | ai15 修 02 §1.2                |
| 003   | switch-child 端点在 01/02 不一致                | ✅ GraphQL Mutation `switchChild(childId: ID!): SwitchChildPayload!`（走 GraphQL，对齐 ISSUE-001）          | ai15 修 01/02 + ai05 补 schema |
| 004   | 登录端点三方不一致                              | ✅ 统一为 `POST /api/v1/iam/login`（对齐 matrix.md §5）；登录走 REST，其余走 GraphQL                        | ai15 修 contract §2.3          |
| 005   | 02 §11.3 未决决策 #2 已由 ARB-001 裁决          | ✅ 移除未决项，改为"已裁决：见 ARB-001"                                                                     | ai15 修 02 §11.3               |
| 006   | contract §1.2 误标前端路由为 HTTP 端点          | ✅ §1.2 改为"无（parent-portal 是前端 Remote，不对外提供 HTTP API）"                                        | ai15 修 contract §1.2          |
| 007   | contract §1.6 MF 配置文件位置不一致             | ✅ 统一为 `apps/parent-portal/next.config.js`（对齐 02 + teacher-portal Shell）                             | ai15 修 contract §1.6          |
| 008   | contract §2.3 GraphQL 路径缺 v1                 | ✅ 统一为 `POST /api/v1/parent/graphql`（对齐 matrix.md §5）                                                | ai15 修 contract §2.3 + §2.4   |
| 009   | parent-bff GraphQL schema 是否含 switchChild    | ✅ parent-bff 提供 `switchChild` Mutation（后端记录选中子女用于审计），同时前端 Zustand + localStorage 缓存 | ai05 补 schema + ai15 前端实现 |
| 010   | iam GetChildrenByParent 缺失（P0 阻塞）         | ✅ ai06 P3 收尾前补全（I6 裁决）；补全前用 mock（固定 2 个孩子 student-001 + student-002）                  | ai06 补全 + ai15 mock          |

### 22.3 关键裁决

| 裁决点                  | 结论                                                                    | 依据                          |
| ----------------------- | ----------------------------------------------------------------------- | ----------------------------- |
| parent-portal 消费方式  | GraphQL（`POST /api/v1/parent/graphql`），非 REST                       | ARB-001 + ARB-018 ISSUE-005   |
| MF shared               | 7 项 singleton 全补齐（含 urql/graphql/@edu/*）                         | ARB-002 §2.2                  |
| switchChild 归属        | parent-bff GraphQL Mutation（后端审计）+ 前端 Zustand 缓存              | 双层记录，避免状态不一致      |
| 登录端点                | `POST /api/v1/iam/login`（REST），登录前无 JWT 不能走 GraphQL           | matrix.md §5 + ARB-014 方案 A |
| 前端路由分类            | 前端页面路由不进 contract §1.2 HTTP 端点表                              | parent-portal 是前端 Remote   |
| MF 配置文件             | `apps/parent-portal/next.config.js`（NextFederationPlugin）             | 对齐 teacher-portal Shell     |
| GraphQL 路径            | `POST /api/v1/parent/graphql`（双 /v1 前缀，对齐 ARB-014）              | ARB-014 + matrix.md §5        |
| iam GetChildrenByParent | ai06 P3 收尾前补全（I6 裁决，P0 阻塞）                                  | coord-final-decisions §1 I6   |
| mock 数据一致性         | parent-portal mock 与 parent-bff mock 一致（student-001 + student-002） | ChildGuard 越权校验依赖       |

### 22.4 ISSUE-003 switchChild 端点裁决详情

**裁决**：switchChild 走 GraphQL Mutation（对齐 ISSUE-001 GraphQL 消费方式）

**GraphQL schema**（ai05 补 parent-bff schema）：

```graphql
type SwitchChildPayload {
  childId: ID!
  childName: String!
  selectedAt: DateTime!
}

type Mutation {
  switchChild(childId: ID!): SwitchChildPayload!
}
```

**后端职责**（parent-bff）：

- 记录选中子女用于审计（写 Redis `parent:selected:{parentId}` TTL 30s）
- ChildGuard 校验基于 iam.GetChildrenByParent 返回列表

**前端职责**（parent-portal）：

- Zustand store 缓存当前选中子女（`selectedChildId`）
- localStorage 持久化（避免刷新丢失）
- 切换子女时同时调 mutation（后端审计）+ 更新 Zustand

### 22.5 ISSUE-009 switchChild Mutation 归属裁决

**裁决**：parent-bff 提供 `switchChild` Mutation（后端记录审计），同时前端 Zustand + localStorage 缓存

**理由**：

1. 纯前端方案无法记录审计日志（谁在何时切换了哪个子女）
2. 后端记录用于异常行为检测（频繁切换可能暗示越权尝试）
3. 前端缓存提升用户体验（刷新不丢失选中状态）
4. 双层记录：后端审计 + 前端缓存，Redis TTL 30s 与 ChildGuard 对齐

### 22.6 ISSUE-010 iam GetChildrenByParent P0 阻塞处理

**裁决**：ai06 在 P3 收尾前补全（I6 裁决），补全前用 mock

**mock 数据要求**：

- 返回固定 2 个孩子：`student-001`（李同学）+ `student-002`（李妹妹）
- 与 parent-bff mock 数据一致（ChildGuard 校验依赖）
- parent-portal 启动时校验 myChildren 返回的 user_id 与下游查询的 student_id 一致性

**补全时间点**：

- ai06 P3 收尾前（parent-portal P4 启动前）
- coord 在 workline.md §4 跟踪 ai06 进度

### 22.7 ai15 执行项

1. 01 §3.1 + 02 §4.1：REST → GraphQL 消费（ISSUE-001）
2. 02 §1.2 MF shared：补齐 7 项 singleton（ISSUE-002）
3. 01 §3.1 + 02 §2.2/§4.1：switch-child → GraphQL Mutation `switchChild`（ISSUE-003）
4. contract.md §2.3：登录端点改为 `POST /api/v1/iam/login`（ISSUE-004）
5. 02 §11.3 #2：移除未决项，标注"已裁决：见 ARB-001"（ISSUE-005）
6. contract.md §1.2：改为"无（前端 Remote，不对外提供 HTTP API）"（ISSUE-006）
7. contract.md §1.6：MF 配置文件改为 `apps/parent-portal/next.config.js`（ISSUE-007）
8. contract.md §2.3 + §2.4：GraphQL 路径改为 `POST /api/v1/parent/graphql`（ISSUE-008）
9. 前端实现 `useChildSwitcher` hook：调 mutation + Zustand + localStorage（ISSUE-009）
10. mock 数据与 parent-bff 一致（student-001 + student-002）（ISSUE-010）

### 22.8 ai05 执行项

1. parent-bff GraphQL schema 补 `switchChild(childId: ID!): SwitchChildPayload!` Mutation（ISSUE-003/009）
2. switchChild Resolver：写 Redis `parent:selected:{parentId}` TTL 30s + 审计记录

### 22.9 ai06 执行项

1. P3 收尾前补全 iam GetChildrenByParent RPC + iam_student_guardians 表（ISSUE-010，I6 裁决）

### 22.10 coord 执行项

1. 协调 ai05 补 switchChild Mutation schema（ISSUE-003/009）
2. 跟踪 ai06 GetChildrenByParent 补全进度（ISSUE-010，P0 阻塞）
3. 确认 matrix.md §5 路径前缀对齐 `/api/v1/parent/*`（ISSUE-008）

---

## §23 ARB-021：admin-portal 模块 7 项 ISSUE 仲裁

### 23.1 背景

ai16 在 [admin-portal_issue.md](./objections/admin-portal_issue.md) 提请 7 项异议，涉及 01/02 文档归属错误（ai07→ai16）、端口错误（3003→4003）、通信协议与 ARB-001/002 不一致、遗漏审计日志与学校设置、teacher-bff 缺 admin 命名空间 schema、推送策略与同类 portal 不一致、matrix.md §4 将 admin-portal 列为 Kafka 直消费方。coord 对照 [admin-portal_contract.md](./contracts/admin-portal_contract.md) + ARB-001/ARB-002 逐条仲裁。

### 23.2 仲裁结论

| ISSUE | 标题                                                   | 仲裁结论                                                                                                                  | 执行方                           |
| ----- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| 001   | 01/02 模块文档归属错误（ai07 → ai16）                  | ✅ 修正为 ai16；ai07 产出视为历史草稿                                                                                     | ai16 修 01/02 头部               |
| 002   | 01/02 端口错误（3003 → 4003）                          | ✅ 确认 admin-portal 端口 4003；同步更新 full-stack-runbook §2.1 补齐 4 个 portal 4000 段                                 | ai16 修 01/02 + coord 修 runbook |
| 003   | 01/02 通信协议与 ARB-001/002 不一致（REST → GraphQL）  | ✅ 统一 GraphQL（`POST /api/admin/graphql` → teacher-bff admin 命名空间）；删除 useApi/ApiClient                          | ai16 修 01/02 全文               |
| 004   | 01/02 遗漏审计日志与学校设置                           | ✅ 视口补齐为 11 个：dashboard/users/roles/permissions/viewports/organization/classes/teachers/students/audit-logs/system | ai16 修 01/02                    |
| 005   | teacher-bff 缺 admin 命名空间 GraphQL schema           | ✅ ai03 在 P6 启动前补齐 teacher-bff admin 命名空间 schema（参照 contract §2.4）                                          | ai03 补 schema                   |
| 006   | 01/02 推送策略与同类 portal 不一致（轮询 → WebSocket） | ✅ admin-portal 接入 push-gateway WebSocket（审计告警/异常登录/系统异常）；保留轮询仅用于监控指标                         | ai16 修 01/02                    |
| 007   | matrix.md §4 将 admin-portal 列为 Kafka 直消费方       | ✅ 修正为 teacher-bff（admin-portal 经 teacher-bff 间接消费，链路：iam → Kafka → teacher-bff → GraphQL → admin-portal）   | coord 修 matrix.md §4            |

### 23.3 关键裁决

| 裁决点                | 结论                                                                      | 依据                                |
| --------------------- | ------------------------------------------------------------------------- | ----------------------------------- |
| 模块归属              | ai16（非 ai07）；ai07 产出视为历史草稿                                    | ai-allocation §5                    |
| 端口                  | 4003（非 3003，3003 与 teacher-bff 冲突）                                 | matrix.md §1 + ai-allocation §5     |
| 通信协议              | GraphQL（`POST /api/admin/graphql`），非 REST                             | ARB-001 + ARB-002                   |
| GraphQL 端点路径      | `POST /api/admin/graphql`（对齐 contract §2.3，非双 /v1 前缀）            | admin 走 teacher-bff，非独立 BFF    |
| 视口数量              | 11 个（补齐审计日志 + 学校设置）                                          | ai-allocation §5 + contract §1.2    |
| admin 命名空间 schema | ai03 在 P6 启动前补齐 teacher-bff admin schema                            | ARB-001 §1.3 P6 新增 admin 命名空间 |
| 推送策略              | WebSocket（审计告警/异常登录/系统异常）+ 轮询（监控指标 60s / 统计 5min） | 同类 portal 一致 + 低频数据轮询合理 |
| Kafka 消费链路        | iam → Kafka → teacher-bff 消费 → GraphQL auditLogs Query → admin-portal   | 前端不直连 Kafka，经 BFF 聚合       |

### 23.4 ISSUE-005 teacher-bff admin 命名空间 schema 补全

**裁决**：ai03 在 P6 启动前补齐 teacher-bff admin 命名空间 GraphQL schema

**补全范围**（参照 admin-portal contract §2.4）：

```graphql
# teacher-bff.graphql admin 命名空间部分（ai03 在 P6 补齐）

type Query {
  # 用户管理
  adminUsers(filter: AdminUserFilter, page: PageInput): AdminUserConnection!
  adminUser(id: ID!): AdminUser

  # 角色权限
  adminRoles: [AdminRole!]!
  adminPermissions: [AdminPermissionGroup!]!

  # 视口配置
  adminViewports(scope: ViewportScope): [ViewportItem!]!

  # 组织管理
  adminOrganization(parentId: ID): [OrganizationNode!]!

  # 全局管理
  adminClasses(filter: ClassFilter): [Class!]!
  adminTeachers(filter: TeacherFilter): [Teacher!]!
  adminStudents(filter: StudentFilter): [Student!]!

  # 审计日志
  auditLogs(filter: AuditLogFilter, page: PageInput): AuditLogConnection!

  # 仪表盘
  adminDashboard: AdminDashboard!
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
  toggleUserStatus(id: ID!): User!

  createRole(input: CreateRoleInput!): AdminRole!
  updateRolePermissions(id: ID!, permissions: [String!]!): AdminRole!

  updateViewport(key: String!, input: UpdateViewportInput!): ViewportItem!
}
```

**存放位置**：`packages/shared-ts/contracts/graphql/teacher-bff.graphql`（admin 命名空间部分，对齐 ARB-001 §1.3 集中管理）

**就绪信号**：

- ai03 P6 启动前完成
- 作为 admin-portal P6 的前置就绪信号
- 更新 matrix.md §3 teacher-bff 行的 schema 文件状态

### 23.5 ISSUE-006 推送策略裁决详情

**裁决**：admin-portal 接入 push-gateway WebSocket + 保留轮询低频数据

**WebSocket 消费场景**：

- 审计告警（异常权限变更、敏感操作）
- 异常登录（非工作时间登录、异地登录）
- 系统异常（服务健康检查异常、资源告警）

**轮询保留场景**：

- 监控指标（60s 间隔，Prometheus 数据）
- 统计数据（5min 间隔，全校统计）

**实现**：

- `ws://push-gateway:8081/ws`（与同类 portal 一致）
- JWT 鉴权
- 事件类型：审计告警 / 异常登录 / 系统异常

### 23.6 ISSUE-007 Kafka 消费链路修正

**裁决**：matrix.md §4 该行消费方更正为 teacher-bff（admin-portal 经 teacher-bff 间接消费）

**实际链路**：

```
iam → Kafka edu.iam.audit.created → teacher-bff 消费
                                        ↓
                                  GraphQL auditLogs Query
                                        ↓
                                  admin-portal 消费
```

**修正范围**：

- matrix.md §4 第 111 行：`admin-portal` → `teacher-bff`
- 避免误导架构分层（前端不直连 Kafka）

### 23.7 GraphQL 端点路径说明

**admin-portal 路径**：`POST /api/admin/graphql`（非双 /v1 前缀）

**与 ARB-014 方案 A 的关系**：

- ARB-014 方案 A 适用于独立服务（iam/core-edu 等）：`/api/v1/<service>/v1/*`
- admin-portal 走 teacher-bff admin 命名空间：`POST /api/admin/graphql`（teacher-bff 已有 `/api/v1/teacher/*` 前缀，admin 命名空间作为 teacher-bff 子路径）
- 由 ai01 确认 api-gateway 路由：`/api/admin/*` → `teacher-bff:3003/admin/*`

### 23.8 ai16 执行项

1. 01/02 头部：ai07 → ai16；分支名更正（ISSUE-001）
2. 01 §1 + 02 §12.1：端口 3003 → 4003（ISSUE-002）
3. 01 §3.1 + 02 §1/§4：REST → GraphQL（useApi → useGraphQLClient）（ISSUE-003）
4. 01 §2.1/§L1 导航/§L2 路由表：补齐 11 个视口（含 audit-logs + system）（ISSUE-004）
5. 01 §3.3 + 02 §5：推送策略改为 WebSocket + 轮询低频数据（ISSUE-006）
6. 02 §11.3：移除已裁决的"GraphQL vs REST"未决项（ISSUE-003）

### 23.9 ai03 执行项

1. P6 启动前补齐 teacher-bff admin 命名空间 schema（参照 §23.4 清单）（ISSUE-005）
2. schema 存放 `packages/shared-ts/contracts/graphql/teacher-bff.graphql` admin 部分

### 23.10 coord 执行项

1. 修正 matrix.md §4 第 111 行：`admin-portal` → `teacher-bff`（ISSUE-007）—— ✅ 已执行（基础设施批次）
2. 同步 full-stack-runbook §2.1：补齐 4 个 portal 4000 段端口（ISSUE-002）—— ⏳ 文件不存在，SRE AI 创建时同步
3. 确认 ai03 admin 命名空间 schema 作为 admin-portal P6 前置就绪信号（ISSUE-005）—— ✅ 已确认
4. 协调 ai01 确认 `/api/admin/*` → `teacher-bff:3003/admin/*` 路由配置 —— 见 §24.4 ARB-022 ISSUE-003 裁决

---

## §24 ARB-022：api-gateway 模块 8 项 ISSUE 仲裁

### 24.1 背景

ai01 在 [api-gateway_issue.md](objections/api-gateway_issue.md) §1 正式提请 8 项 ISSUE（ISSUE-001~005/007/008/009，ISSUE-006 预留），涉及 matrix.md 契约修正、shared-go 接入、API 版本化路由方案、日志选型、Go 版本不一致、文档过时、错误码 GW_ 前缀 + ActionState 信封。

ARB-014 曾基于 v1 早期 issue.md（仅 2 行）从 contract.md v2 内联 4 项 ISSUE 做过初步仲裁；本次基于 ai01 正式提请的 v2 issue.md 重新仲裁，ARB-014 中与此冲突的部分以本节为准。

### 24.2 仲裁结论总览

| ISSUE     | 主题                                | 仲裁结论                                                           | 影响范围            | 严重度 |
| --------- | ----------------------------------- | ------------------------------------------------------------------ | ------------------- | ------ |
| ISSUE-001 | matrix.md gRPC 矩阵修正             | ✅ 确认（已执行）                                                  | 无（matrix 已修）   | 低     |
| ISSUE-002 | shared-go 接入方式                  | go.work 已含；ai01 go.mod 补 `github.com/edu-cloud/shared-go` 依赖 | ai01 P2.1           | 中     |
| ISSUE-003 | API 版本化路由方案（/v1 前缀位置）  | **采纳方案 A**（双 /v1 前缀）                                      | **全模块**          | **高** |
| ISSUE-004 | zap vs slog 选型                    | **shared-go/logger 用 zap**（现状保留）                            | ai01 + 所有 Go 服务 | 中     |
| ISSUE-005 | go.mod 与 Dockerfile 版本不一致     | 统一为 `go 1.22`（Dockerfile + go.mod + go.work）                  | ai01 + ai02         | 中     |
| ISSUE-007 | 01-understanding.md §6 审计表过时   | ai01 更新文档                                                      | ai01 文档           | 低     |
| ISSUE-008 | 01-understanding.md §7.1 死代码过时 | ai01 删除该行                                                      | ai01 文档           | 低     |
| ISSUE-009 | W1/W2 错误码 GW_ + ActionState      | P2.3 统一修复（ai01 已在 workline 列出）                           | ai01 P2.3           | 中     |

### 24.3 ISSUE-001 matrix.md gRPC 矩阵修正

**裁决**：✅ 已执行（基础设施批次）

- matrix.md §2 iam "消费方"列已移除 `api-gateway`（保留 `teacher-bff / student-bff / parent-bff`）
- matrix.md §7 Mock 策略表已修正为"硬编码 RS256 公钥（DEV_MODE）→ HTTP JWKS 端点"
- 依据：总裁 §2.16 裁决第 3 条"gateway 保持 HTTP 透传，不改为 gRPC 客户端"

**跨模块影响**：无（matrix.md 已修正，其他 AI 不受影响）

### 24.4 ISSUE-003 API 版本化路由方案（/v1 前缀位置）

**裁决**：**采纳方案 A（双 /v1 前缀）**

> ⚠️ **严重影响说明**：此裁决与总裁 §2.15 裁决第 4 条"避免双 v1"存在冲突。coord 经审查后认为方案 A 更符合实际架构现状，但需明确说明冲突原因与修正范围。

**路由方案**：

| 前端调用路径                 | Gateway 路由               | proxy 透传目标                       | 下游 Controller 路径                         |
| ---------------------------- | -------------------------- | ------------------------------------ | -------------------------------------------- |
| `/api/v1/iam/v1/auth/login`  | `/api/v1/iam/v1/*path`     | iam:3002 `/iam/v1/*path`             | `@Controller('v1/iam/auth')`                 |
| `/api/v1/teacher/v1/graphql` | `/api/v1/teacher/v1/*path` | teacher-bff:3003 `/teacher/v1/*path` | GraphQL `/graphql`（BFF 无 Controller 分层） |
| `/api/v1/student/v1/graphql` | `/api/v1/student/v1/*path` | student-bff:3009 `/student/v1/*path` | GraphQL `/graphql`                           |
| `/api/v1/parent/v1/graphql`  | `/api/v1/parent/v1/*path`  | parent-bff:3010 `/parent/v1/*path`   | GraphQL `/graphql`                           |
| `/api/v1/admin/v1/graphql`   | `/api/v1/admin/v1/*path`   | teacher-bff:3003 `/admin/v1/*path`   | GraphQL admin 命名空间                       |

**理由**：

1. **iam_contract.md §2.3 已明确** `GET /iam/v1/.well-known/jwks.json`（Controller 内含 /v1），若 Gateway 透传不含 /v1，则前端需调用 `/api/v1/iam/.well-known/jwks.json`（缺服务级 /v1），与 iam 实际 Controller 路径不一致
2. **api-gateway_contract.md §1.2.2 v2 已列方案 A**（双 /v1），且注明"方案 A，双 v1"
3. **matrix.md §5 已对齐方案 A**（`/api/v1/teacher/*` → 方案 A 下应为 `/api/v1/teacher/v1/*`）
4. **ARB-014 §16.4 已采纳方案 A**，ARB-019/020/021 前端 portal 仲裁均引用方案 A（`/api/v1/student/v1/graphql` 等）
5. **方案 B 的"避免双 v1"虽符合总裁裁决字面意思，但要求下游 Controller 不加 /v1 前缀**，与 iam_contract.md §2.3 实际路径 `/iam/v1/.well-known/jwks.json` 矛盾

**与总裁 §2.15 裁决的冲突说明**：

- 总裁 §2.15 第 4 条"避免双 v1"字面要求"Controller 加 /v1，Gateway 转发路径不含 /v1"
- 但总裁 §2.15 第 3 条"Gateway 透传时不改路径"与第 4 条存在内在矛盾：若 Controller 加 /v1，Gateway 透传时必然携带 /v1，前端调用必然双 /v1
- **coord 裁决**：以总裁 §2.15 第 3 条"Gateway 不改路径"为准，接受双 /v1（方案 A）；第 4 条"避免双 v1"在实际执行中无法同时满足第 3 条，故第 4 条不适用
- **提请总裁复核**：若总裁坚持"避免双 v1"，需修正 iam_contract.md §2.3 的 Controller 路径（移除 `/v1` 前缀），并同步修正所有服务的 Controller 路径设计

**matrix.md §5 修正**：

当前 matrix.md §5 路径为 `/api/v1/teacher/*`（单 /v1），需修正为 `/api/v1/teacher/v1/*`（双 /v1，方案 A）：

| 修正前              | 修正后                 |
| ------------------- | ---------------------- |
| `/api/v1/teacher/*` | `/api/v1/teacher/v1/*` |
| `/api/v1/student/*` | `/api/v1/student/v1/*` |
| `/api/v1/parent/*`  | `/api/v1/parent/v1/*`  |
| `/api/v1/iam/*`     | `/api/v1/iam/v1/*`     |

**跨模块影响**：

- **前端 4 个 portal（ai13/ai14/ai15/ai16）**：文档已统一为双 /v1（ARB-019/020/021 已采纳方案 A），无影响
- **BFF 层（ai03/ai04/ai05）**：GraphQL endpoint 路径 `/graphql` 不变，仅 Gateway 路由前缀变化，BFF 内部无影响
- **iam（ai06）**：Controller 路径已含 `/v1`（如 `/iam/v1/.well-known/jwks.json`），无影响
- **core-edu/content/msg/data-ana/ai**：Controller 需加 `/v1` 前缀（总裁 §2.15 第 1 条"各服务按自身节奏推进"），P3-P5 各服务启动时由对应 AI 落实

### 24.5 ISSUE-002 shared-go 接入方式

**裁决**：go.work 已含 `./packages/shared-go`（已执行）；ai01 go.mod 需补 `github.com/edu-cloud/shared-go` 依赖

**现状核查**：

- [go.work](../../../go.work) L3-6 已含 `./packages/shared-go`（ISSUE-002 部分已解决）
- [go.mod](../../../services/api-gateway/go.mod) 未含 `github.com/edu-cloud/shared-go`（待 ai01 P2.1 接入时补充）

**ai01 执行项**：

1. go.mod 增加 `require github.com/edu-cloud/shared-go v0.0.0`（go work replace 模式）
2. P2.1 任务接入 jwks/logger/tracer/env 4 模块
3. 若 shared-go 模块路径命名与预期不符，提请 coord 仲裁

**跨模块影响**：无（仅 ai01 自身依赖配置）

### 24.6 ISSUE-004 zap vs slog 选型

**裁决**：**shared-go/logger 用 zap**（现状保留，W3 裁决修正为 zap）

**现状核查**：

- [packages/shared-go/logger/logger.go](../../../packages/shared-go/logger/logger.go) 实际用 `go.uber.org/zap`（不是标准库 `log/slog`）
- 实现：生产 JSON Info 级 / 开发 console Debug 级 + OTel trace_id 关联

**与 W3 裁决的冲突说明**：

- W3 裁决原文"首次实现即用 slog"
- 但 shared-go/logger 已用 zap 实现，且 zap 在 Go 生态中性能与生态成熟度优于 slog
- **coord 裁决**：接受现状（zap），W3 裁决修正为"shared-go/logger 基于 zap 封装；ai01 通过 import shared-go/logger 间接使用 zap，不直接 import zap"

**ai01 执行项**：

1. P2.1 任务 import `github.com/edu-cloud/shared-go/logger`
2. 替换全部 `log.Printf` 为 `logger.FromContext(ctx).Info/Error/Warn`
3. 涉及文件：main.go L70/160/169/176、config.go L38/41、recovery.go L22、circuit-breaker.go L38、tracer.go L25/31/43/51/65/70

**跨模块影响**：

- **ai02（push-gateway）**：同样 import shared-go/logger，使用 zap，无影响
- **其他 Go 服务**：若后续有 Go 服务，统一通过 shared-go/logger 使用 zap

### 24.7 ISSUE-005 go.mod 与 Dockerfile Go 版本不一致

**裁决**：统一为 `go 1.22`（与 Dockerfile + 01-understanding.md §4 一致）

**版本对齐**：

| 文件                                                      | 当前                 | 修正后                       |
| --------------------------------------------------------- | -------------------- | ---------------------------- |
| [Dockerfile](../../../services/api-gateway/Dockerfile) L1 | `golang:1.22-alpine` | `golang:1.22-alpine`（不变） |
| [go.mod](../../../services/api-gateway/go.mod) L3         | `go 1.25.0`          | `go 1.22`                    |
| [go.work](../../../go.work) L1                            | `go 1.26.0`          | `go 1.22`                    |

**理由**：

- Dockerfile 1.22-alpine 是实际构建环境，必须以它为准
- 01-understanding.md §4 声明 Go 1.22
- go.mod 1.25.0 / go.work 1.26.0 是误升版本，回退到 1.22

**ai01 执行项**：

1. go.mod L3 改为 `go 1.22`
2. go.work L1 改为 `go 1.22`
3. 验证 `go build ./...` 通过

**跨模块影响**：

- **ai02（push-gateway）**：同样需对齐 go 1.22（若 push-gateway go.mod/go.work 版本不一致，ai02 同步修正）
- **其他服务**：TS/Python 服务无影响

### 24.8 ISSUE-007 01-understanding.md §6 审计表 metrics 行过时

**裁决**：ai01 更新文档

**ai01 执行项**：

1. 01-understanding.md §6 审计表 metrics 行：`❌ 无` → `⚠️ 端点已注册，缺 7 个业务指标`
2. 01-understanding.md §7.1 issue #1：更新为"已注册 /metrics，需补 7 个业务指标（见 workline P2.5）"

**跨模块影响**：无

### 24.9 ISSUE-008 01-understanding.md §7.1 issue #3 死代码引用过时

**裁决**：ai01 删除该行

**ai01 执行项**：

1. 01-understanding.md §7.1 issue #3 整行删除（死代码 `RequestIDMiddleware()` + `generateUUID()` 已修复）

**跨模块影响**：无

### 24.10 ISSUE-009 W1/W2 错误码 GW_ 前缀 + ActionState 信封

**裁决**：P2.3 任务统一修复（ai01 已在 workline 列出）

**修复范围**：

| 文件                      | 当前问题                                                              | 修复后                                                                                   |
| ------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| auth.go                   | 错误码 `UNAUTHORIZED`/`INVALID_TOKEN`/`INVALID_CLAIMS`（无 GW_ 前缀） | `GW_UNAUTHORIZED`/`GW_INVALID_TOKEN`/`GW_INVALID_CLAIMS`                                 |
| ratelimit.go L51-54       | `{"error":"rate_limited","retry_after":60}`（无信封）                 | `{"success":false,"error":{"code":"GW_RATE_LIMITED","message":"..."},"retry_after":60}`  |
| circuit-breaker.go L55-58 | `{"error":"circuit_open","retry_after":30}`（无信封）                 | `{"success":false,"error":{"code":"GW_CIRCUIT_OPEN","message":"..."},"retry_after":30}`  |
| recovery.go L24-27        | `{"error":"internal_error","request_id":"..."}`（无信封）             | `{"success":false,"error":{"code":"GW_INTERNAL_ERROR","message":"...","traceId":"..."}}` |

**ActionState 信封规范**：见 [004 §11.5](../004_architecture_impact_map.md) ActionState 信封规范（coord 基础设施批次已补充）

**ai01 执行项**：

1. P2.3 任务统一修复 4 个中间件文件
2. 错误码统一 `GW_` 前缀（对齐 contract.md §1.6 错误码清单）
3. 响应体统一 ActionState 信封（对齐 004 §11.5）

**跨模块影响**：无（仅 ai01 自身代码修复）

### 24.11 ai01 执行项汇总

| 任务                                                   | ISSUE         | 阶段 | 阻塞 |
| ------------------------------------------------------ | ------------- | ---- | ---- |
| go.mod 补 shared-go 依赖 + 接入 jwks/logger/tracer/env | ISSUE-002/004 | P2.1 | P2.1 |
| 替换 log.Printf 为 shared-go/logger                    | ISSUE-004     | P2.1 | P2.1 |
| go.mod/go.work 版本回退到 1.22                         | ISSUE-005     | P2.0 | P2.0 |
| 01-understanding.md §6/§7.1 文档更新                   | ISSUE-007/008 | P2.0 | —    |
| 错误码 GW_ + ActionState 信封统一修复                  | ISSUE-009     | P2.3 | P2.3 |
| API 版本化路由方案 A 落实（P1 代码迁移到 /v1 前缀）    | ISSUE-003     | P2.7 | P2.7 |

### 24.12 coord 执行项

1. ✅ matrix.md §2 移除 api-gateway 为 iam gRPC 消费方（基础设施批次已执行）
2. matrix.md §5 路径前缀修正为双 /v1（方案 A）—— **本节裁决后立即执行**
3. ✅ 004 §11.5 ActionState 信封规范已补充（基础设施批次已执行）
4. 协调 ai02 同步修正 push-gateway go.mod/go.work 版本到 1.22
5. ✅ 总裁已确认采纳方案 A（2026-07-10），§2.15 第 4 条"避免双 v1"不再适用

---

## §8 仲裁流程说明

### 8.1 提请异议

各 AI 在自己模块的 `objections/[模块名]_issue.md` 中追加异议条目，格式：

```markdown
### ISSUE-[编号]-[AI标识]：[标题]

- **提请方**：aiXX
- **日期**：YYYY-MM-DD
- **类型**：契约不明确 / 工作量超批 / 前置依赖缺失 / 编号冲突 / 其他
- **描述**：[详细描述问题]
- **建议方案**：[AI 的建议]
- **状态**：待 coord 仲裁 / 已裁决（见 coord.md §X）
```

### 8.2 coord 仲裁

coord 审阅各 `objections/[模块名]_issue.md` 后，在本文件（coord.md）追加仲裁章节：

```markdown
## §N ARB-XXX：[主题]

### N.1 背景

### N.2 仲裁结论

### N.3 关键裁决（表格）

### N.4 相关 AI 执行项
```

### 8.3 状态同步

- 仲裁完成后，coord 在对应 `objections/[模块名]_issue.md` 中更新状态为"已裁决（见 coord.md §N）"
- coord 在 [workline.md](./workline.md) §8 就绪信号跟踪表中更新进度

### 8.4 目录结构

```
issues/
├── coord.md              # 本文件（仲裁汇总）
├── workline.md           # 总工作安排
├── matrix.md             # 上下游对接总矩阵
├── objections/           # 各模块问题/异议
│   ├── [模块名]_issue.md
│   └── cross_issue.md    # 跨模块问题
├── worklines/            # 各模块工作排期
│   └── [模块名]_workline.md
└── contracts/            # 各模块对接契约
    └── [模块名]_contract.md
```

---

## §9 历史仲裁（已迁移）

以下仲裁已在此前完成，原始记录见 [coord-final-decisions.md](../coord-final-decisions.md) 和 [president-final-rulings.md](../president-final-rulings.md)：

- I1-I8：iam P2 契约（coord-final-decisions.md §1）
- F1-F9：BFF 设计裁决（coord-final-decisions.md §2）
- G1-G3：Gateway 裁决（coord-final-decisions.md §3）
- N1-N3：content 裁决（coord-final-decisions.md §4）
- 总裁裁决 70+ 项（president-final-rulings.md §1-§5）

本文件仅记录**新流程启动后**（2026-07-09 起）的仲裁。
