# Agent Note: PR 到 Issue 的状态仅向前投射

Status: implemented
Archived: 2026-08-10

[English](2026-08-04-forward-only-pr-issue-status.md) | 中文

## 问题

Issue Project 状态表示工作所处阶段，同仓库内精确匹配的解决型关键字引用则建立权威的 PR（Pull Request）到 Issue 关系。若仅允许已处于 `Ready` 的 Issue 推进生命周期，即使实现已经明确开始，处于 `Inbox` 或 `Backlog` 的 Issue 仍会停留在原状态。只有 PR 元数据在其他方面均有效时才投射工作阶段，也会把政策合规性与可观察到的工作状态混为一谈。

## 决策

PR 事件和 PR 评审事件会把当前 PR 阶段投射到同仓库内由解决型关键字精确引用的每个 Issue。草稿 PR，或既没有评审请求也没有已提交评审的非草稿 PR，目标状态为 `In progress`。具备上述任一类评审活动的非草稿 PR，目标状态为 `In review`。

活跃状态依次为 `Inbox`、`Backlog`、`Ready`、`In progress` 和 `In review`。只有目标状态在该顺序中位于当前状态之后时，投射才会写入。投射不会把 Issue 状态向后移动，不会改动 `Done` 或 `No action`，也不会把没有 Project 状态的 Issue 加入 Project。生命周期路径独立于 PR 元数据校验；另行执行的必需 PR 政策检查继续强制落实标签、引用和优先级一致性。

这项投射刻意保持单向。它不会从 Issue 反查关联 PR，也不会添加定时对账任务。PR 事件是推进生命周期的来源。Issue 管理测试会验证纯函数实现的状态转换决策，并且该测试会在 `check-all`、`ci-primary` 和 `ci-static` 门禁中运行。

## 验证

`.github/issue-management/policy.test.mjs` 覆盖从所有更早活跃状态推进、区分草稿与评审状态、独立于元数据政策，以及防止状态倒退或改动终态。`scripts/run-gates.ts` 负责在顶层本地门禁模式和 CI 门禁模式中执行这项专项政策测试。

## 考虑过的替代方案

**仅允许从 `Ready` 状态推进。** 这种方案保留了人工前置条件，但解决型 PR 已经证明实现开始后，仍会让处于 `Inbox` 和 `Backlog` 的条目保持陈旧状态。

**增加双向或定时对账。** 由 Issue 事件反查 PR，或定期扫描 Project，可以修复更多历史遗留状态；但这会新增一条反向的权威状态更新路径，并增加周期性 API 工作量，超出所需的 PR 驱动生命周期范围。

**以完整的 PR 元数据作为投射前提。** 标签、引用和优先级仍须强制落实，但元数据缺陷并不能否定工作实际处于实现或评审阶段。

**PR 转为草稿或失去评审人时将状态向后移动。** 这会让临时的 PR 状态覆盖已经观察到的更靠后工作阶段，也会使状态所有权更复杂。因此，投射保持单调。

## 后果

- PR 事件会自动纠正由该 PR 解决但仍停留在 `Inbox`、`Backlog` 或 `Ready` 的 Issue。
- 若 Issue 创建于最后一个相关 PR 事件之后，则必须等待后续 PR 事件或人工更新状态，因为系统不会反向查找或定时扫描。
- 即使存在历史评审活动，草稿 PR 仍保持 `In progress`；只有非草稿 PR 才会以 `In review` 为目标状态。
- 终态以及顺序中更靠后的活跃状态不会倒退。
- 必需的政策检查仍会暴露 PR 元数据错误，而不会因此阻止生命周期投射。
