# PJ2026-010404 项目管理

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |

当前正文仍在规格治理草稿中；未定稿前不新增版本号，不为单次编辑追加 `待提交` 版本。

## 正文

## PJ2026-010404 项目管理需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-010404 |
| 短名 | 项目管理 |
| 层级 | L2 课题 |
| 状态 | 已生效 |
| 实现引用版本 | draft-2026-06-25-p0-project-management-mdtodo; draft-2026-06-25-p0-mdtodo-web-active-editing-hwpod-source; draft-2026-06-26-p1-mdtodo-web-operable; draft-2026-06-26-p0-mdtodo-web-rewrite |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |
| 上级规格 | [PJ2026-0104 客户端](PJ2026-0104-client.md) |
| 关联规格 | [PJ2026-010401 Web工作台](PJ2026-010401-web-workbench.md)、[PJ2026-010403 API契约](PJ2026-010403-api-contract.md)、[PJ2026-0102 Agent编排](PJ2026-0102-agent-orchestration.md)、[PJ2026-0105 用户管理](PJ2026-0105-user-management.md)、[PJ2026-0106 平台运维](PJ2026-0106-platform-ops.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版：正文只保留项目管理的稳定使命、范围、术语、系统边界、内部分工和原子需求。

## 2. 目的和范围

### 2.1 目的

项目管理负责 HWLAB 登录后的项目入口、项目 source、MDTODO 任务树、任务与 Workbench session 的公共 ID 关联，以及后续外部项目管理系统 adapter 的统一入口。

本课题的目标状态是：Cloud Web 提供 `/projects` 根导航和 `/projects/mdtodo` 页面；MDTODO 任务能一键启动 Workbench；两者通过公共 API、`projectId`、`taskRef`、`sessionId`、`traceId` 和 `launchContext` 关联，不通过组件嵌套、store import、iframe、私有服务 URL 或 Markdown 结构解析互相依赖。

`/projects/mdtodo` 的目标交互不只是只读投影。页面应支持 Web 配置 MDTODO Source、绑定 HWPOD workspace、按 Rxx 标准展示任务树、执行任务编辑 mutation，并通过受控 web-probe command 做交互式验收。Source/File 选择应收敛为顶部状态栏下拉，统计/诊断信息应进入 info/diagnostic 弹窗，主版面优先分配给任务树和编辑区。

`draft-2026-06-26-p1-mdtodo-web-operable` 的目标是把 MDTODO Web 从只读摘要收敛为可工作的任务面：File 下拉主标签必须是 `docs/MDTODO/` 下直接 Markdown 文件名；任务详情必须展示正文 Markdown 和可解析报告链接；报告链接必须在右侧预览并支持全屏；标题和正文编辑必须通过双击/inline editing 进入；Workbench launch 必须生成带任务上下文的首轮可执行内容，不能只创建空 session。

项目管理从 P0 起必须作为独立 `hwlab-project-management` 微服务交付。它不作为 `hwlab-cloud-api` 内部模块起步，也不并入既有 UniDesk `mdtodo`、UniDesk `project-manager`、HWLAB Workbench runtime、Cloud Web 或 user-billing 服务。

### 2.2 范围内

- Cloud Web `/projects` 根导航、项目列表、source 状态、能力摘要、blocker 和最近 Workbench link 展示。
- Cloud Web `/projects/mdtodo` 页面，展示 MDTODO source、Markdown 文件摘要、任务树、任务详情、状态、稳定 `taskRef`、链接摘要和 Workbench 启动入口。
- `/projects/mdtodo` 的 Source 配置弹窗、HWPOD source binding、Source/File 顶部下拉、metric info/diagnostic 弹窗、Rxx 任务树和主动编辑控件。
- `/projects/mdtodo` 的任务详情正文、Markdown report link 解析、右侧报告预览、全屏预览和 inline edit 操作。
- 独立 `hwlab-project-management` 微服务，包括 Project Management API、ProjectSource registry、MDTODO adapter 调度、DB read model、Workbench link 表、audit/outbox 和未来外部 PM adapter 扩展点。
- MDTODO adapter 对 Markdown TODO 文件的 Rxx heading 解析、文件锁、原子写入、重建投影、revision/fingerprint 并发保护和 parse error 表达。
- HWPOD-bound MDTODO source 对 `d601-f103-v2` 这类 HWPOD workspace 的 `docs/MDTODO/` 受控读写。
- `projectId`、`sourceId`、`taskRef`、`linkId`、`sessionId` 和 `traceId` 的稳定关联模型。
- Workbench launch intent，即项目管理页面通过公共 Workbench Launch API 创建或选择 session，并记录项目任务与 Workbench session 的关联。
- 项目管理页面的 web-probe observe/analyze 采样、分析、DOM 脱敏、自然同源 API 分组、Workbench launch 控制动作和 YAML-first 阈值。
- D601/v03 YAML-first 独立微服务部署所需的 serviceId、namespace、Secret sourceRef、DB migration、HWPOD node-ops adapter endpoint、OTel `service.name`、public route/proxy 和 health/readiness 声明。

### 2.3 范围外

- Workbench session、turn、run、command、trace/result 执行事实归 [Agent编排](PJ2026-0102-agent-orchestration.md) 和 Workbench 相关规格。
- 用户身份、role、capability、tenant/project visibility、API key 和额度归 [用户管理](PJ2026-0105-user-management.md)。
- Cloud API 的同源 path、错误 envelope、鉴权主体和 DTO 稳定性归 [API契约](PJ2026-010403-api-contract.md)。
- Cloud Web Workbench 的 session hydrate、timeline、trace renderer、composer 和状态投影归 [Web工作台](PJ2026-010401-web-workbench.md)。
- CI/CD、GitOps、FRP/Caddy、Secret 下发、public URL、OTel/Prometheus 和 rollout 归 [平台运维](PJ2026-0106-platform-ops.md)。
- P0 不直接部署 OpenProject、Plane、Vikunja、Redmine、Taiga、Huly、Leantime 或其他完整 PM 套件。
- P0 不把 Markdown TODO 权威数据迁移到数据库，不让 Workbench 解析 Markdown，也不让项目管理页面嵌入 Workbench。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| 项目管理 | HWLAB 登录后的项目、source、任务和 Workbench link 入口。 |
| `hwlab-project-management` | 独立项目管理微服务，拥有项目管理 API、source registry、MDTODO adapter 编排、DB 投影、Workbench link、audit/outbox 和外部 PM adapter 扩展点。 |
| ProjectSource | 项目任务来源，初始支持 `mdtodo`，后续可扩展到 `plane`、`vikunja`、`openproject` 等 adapter。 |
| ProjectRecord | HWLAB 项目摘要，包含 `projectId`、标题、默认 source、可见性和更新时间。 |
| MDTODO source | 指向一个受控 Markdown TODO 根目录或仓库视图的 ProjectSource。 |
| HWPOD-bound MDTODO source | `sourceKind=hwpod-workspace` 的 ProjectSource，绑定 `hwpodId`、`nodeId` 和 workspace 相对根，例如 `docs/MDTODO/`。 |
| Direct MDTODO file | HWPOD-bound source 根目录 `docs/MDTODO/` 的直接 `.md` 子文件；子目录内报告、日志和任务报告只能作为链接 target，不得注册为 MDTODO 文件。 |
| Rxx 任务树 | MDTODO 标准的 heading 任务树，使用 `R1`、`R1.1`、`R1.1.1` 等 id 表达父子关系，层级来自 Rxx id 前缀而不是 checkbox 缩进或 Markdown heading 数量。 |
| Markdown source-of-truth | MDTODO 的权威任务内容仍保存在 `.md` 文件中；DB 只保存可重建投影、link、audit/outbox。 |
| Document revision | 项目管理服务对单个 Markdown 文件内容、mtime、fingerprint 和 projection revision 的并发控制摘要。 |
| `taskRef` | 项目管理 API 返回的 opaque 任务引用，例如 `mdtodo:<sourceId>:<fileHash>#<taskId>`；只有项目管理服务和 adapter 能反解。 |
| ProjectTask | 从 source 投影出的任务 DTO，包含 `taskRef`、`projectId`、`sourceId`、title、status、父子关系、depth、linkCount 和更新时间。 |
| WorkbenchLaunchContext | 项目管理页面发给公共 Workbench Launch API 的脱敏上下文，包含 `sourceKind=project-management`、`projectId`、`taskRef`、title 摘要和 prompt template 标识。 |
| ReportPreview | 项目管理服务按 taskRef 和任务内 Markdown link 解析出的只读报告预览 DTO，包含链接标签、相对路径、内容摘要、Markdown 正文、fingerprint、mtime、大小限制诊断和全屏展示所需 metadata。 |
| ProjectWorkbenchLink | `projectId/taskRef/sessionId/traceId` 的稳定关联记录，用于从任务回到 Workbench session 或从 Workbench 元数据看到来源。 |
| PM DB 投影 | 项目管理服务维护的 `project_sources`、`mdtodo_documents`、`mdtodo_task_projection`、`project_workbench_links`、`project_audit_events` 等可重建表。 |
| Cloud API route/auth bridge | Cloud API 中只负责同源路由、AuthPrincipal、错误 envelope 和转发的桥接层；不拥有项目管理持久化或 Markdown 解析。 |
| 项目管理 web-probe | 针对 `/projects`、`/projects/mdtodo` 和 `/v1/project-management/*` 的 observe/analyze 采样与分析能力，只观察公共页面和同源 API，不提供私有后门。 |
| `project-mdtodo-summary` | web-probe observe collect 的项目管理阅读视图，只从采样 artifact 渲染 Source/File/Task/Revision/Workbench link 摘要，不访问业务 API 或驱动浏览器。 |

## 4. 系统边界和接口

本规格把项目管理作为客户端方向下的独立项目入口课题看待；本章只描述输入、输出和责任边界。

| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 硬件研发用户、平台管理员、需要从任务上下文启动 Workbench 的用户和自动化验收。 |
| 外部输入 | 浏览器导航、source/file/task 选择、任务状态修改请求、Workbench launch 请求、AuthPrincipal、项目可见性、Markdown source、HWPOD workspace source 配置和外部 PM adapter 事件。 |
| 受控资源 | `/projects`、`/projects/mdtodo`、`/v1/project-management/*`、`POST /v1/workbench/launches` 的项目上下文、MDTODO adapter、HWPOD node-ops workspace op、PM DB 投影、Workbench link、audit/outbox 和 web-probe artifact。 |
| 外部输出 | 项目列表、source 摘要、文件摘要、任务树、任务详情、taskRef、Workbench link 摘要、capability/blocker、错误诊断、observe/analyze 报告和部署健康。 |
| 用户接口 | Cloud Web 项目页面、同源 Project Management API、公共 Workbench Launch API、HWLAB CLI 同源 request 和 web-probe observe/analyze。 |
| 系统边界 | 项目管理负责项目/任务入口、source 投影和 Workbench link；不执行 Agent、不拥有 Workbench session lifecycle、不替代用户权限、不把 `.md` 转为 DB 权威，也不承担平台发布运维。 |

## 5. 内部分工与规格索引

| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-01040401 | 项目根导航 | 本规格 6.1 | `/projects` 一级入口、项目列表、source 状态、capability/blocker | 用户管理、Project Management API、平台入口 | 登录后项目入口、MDTODO 页面 |
| PJ2026-01040402 | MDTODO 页面 | 本规格 6.2 | `/projects/mdtodo` source/file/task/taskRef/link/launch 展示 | Project Management API、MDTODO adapter、API契约 | 用户任务阅读和 Workbench 启动 |
| PJ2026-01040403 | 独立微服务 | 本规格 6.3 | `hwlab-project-management` API、source registry、DB 投影、audit/outbox、adapter 编排 | 用户管理、平台运维、API契约 | Cloud Web、CLI、web-probe |
| PJ2026-01040404 | MDTODO adapter 与存储 | 本规格 6.4 | Markdown source-of-truth、解析、文件锁、原子写入、投影重建 | MDTODO `.md` source、mdtodo parser/CLI/service | ProjectTask DTO、DB 投影 |
| PJ2026-01040405 | Workbench Link | 本规格 6.5 | 公共 launch context、link 表、ID 关联和解耦边界 | Workbench Launch API、Agent编排 | 项目任务到 Workbench session |
| PJ2026-01040406 | 外部 PM adapter | 本规格 6.6 | Plane/Vikunja/OpenProject 等未来 adapter 接口和隔离边界 | 外部 PM 服务、用户管理 | 后续完整 PM 能力 |
| PJ2026-01040407 | 观测与验收 | 本规格 6.7 | web-probe observe/analyze、DOM 脱敏、YAML-first 阈值和 issue-ready evidence | 平台运维、公开入口、Cloud Web | D601/v03 原入口验收 |
| PJ2026-01040408 | YAML-first 运行配置 | 本规格 6.8 | 独立服务部署、Secret sourceRef、DB/OTel/health/public route 配置 | YAML运维、平台发布 | D601/v03 rollout |
| PJ2026-01040409 | MDTODO前端重写 | [PJ2026-01040409 MDTODO前端重写](PJ2026-01040409-mdtodo-web-rewrite.md) | 清除旧 MDTODO Web 前端并按有界三栏、Rxx 树、报告预览和主动编辑重新实现 | Project Management API、Web工作台、web-probe | D601/v03 MDTODO 原入口可用性 |

### 5.1 目标架构图

```mermaid
flowchart LR
  subgraph Browser[Cloud Web]
    Root[/projects/]
    Mdtodo[/projects/mdtodo/]
  end
  subgraph Edge[Cloud API same-origin]
    Bridge[route/auth bridge + HwlabErrorEnvelope]
    Launch[POST /v1/workbench/launches]
  end
  subgraph PM[hwlab-project-management]
    Api[Project Management API]
    Source[ProjectSource Registry]
    Projection[(PM DB read model)]
    Links[(ProjectWorkbenchLink)]
    Audit[(audit/outbox)]
    Adapter[MDTODO Adapter]
    HwpodAdapter[HWPOD Source Adapter]
  end
  subgraph Store[Task sources]
    Markdown[(.md source-of-truth)]
    HwpodWs[(d601-f103-v2 workspace docs/MDTODO)]
    External[Future PM adapters]
  end
  subgraph HWPOD[HWPOD node]
    Ops[workspace.ls/cat/apply-patch/write]
  end
  subgraph WB[Workbench]
    Session[(Session/read model)]
    Trace[(Trace/result projection)]
  end
  Root --> Bridge
  Mdtodo --> Bridge
  Bridge --> Api
  Api --> Source
  Api --> Projection
  Api --> Links
  Api --> Audit
  Api --> Adapter
  Source --> HwpodAdapter
  Adapter --> Markdown
  Adapter --> HwpodAdapter
  HwpodAdapter --> Ops
  Ops --> HwpodWs
  Api -.future adapter.-> External
  Mdtodo --> Launch
  Launch --> Session
  Launch --> Links
  Session --> Trace
```

### 5.2 数据流图

```mermaid
flowchart TD
  MD[Markdown TODO file] --> Parse[MDTODO adapter parse]
  Parse --> Rxx[Rxx task tree R1/R1.1/R1.1.1]
  Rxx --> Rev[MdtodoDocumentRevision]
  Rxx --> Task[MdtodoTaskProjection]
  Task --> Api[GET /v1/project-management/mdtodo/tasks]
  Api --> UI[/projects/mdtodo task tree]
  UI --> Detail[GET task detail with body + links]
  Detail --> Preview[GET report preview]
  UI --> Intent[WorkbenchLaunchContext + initial task prompt]
  Intent --> Launch[POST /v1/workbench/launches]
  Launch --> Sess[Workbench sessionId]
  Sess --> Link[ProjectWorkbenchLink]
  Link --> LinkApi[GET /v1/project-management/workbench-links]
  LinkApi --> UI
```

MDTODO `.md` 文件是任务正文的 source-of-truth。PM DB 投影只用于导航、检索、权限投影、Workbench link 和审计，可从 source 重建。写入路径必须是 Web mutation 到项目管理服务，再到 adapter 文件锁和原子写入，最后重建投影；前端不得直接 PUT raw Markdown，DB 投影不得绕过 adapter 反写文件。

### 5.3 Workbench 启动时序

```mermaid
sequenceDiagram
  participant U as 用户
  participant P as /projects/mdtodo
  participant PM as Project Management API
  participant W as Workbench Launch API
  participant R as Workbench Read Model
  U->>P: 选择 source/file/task
  P->>PM: GET /v1/project-management/mdtodo/tasks
  PM-->>P: ProjectTask DTO with taskRef
  U->>P: 点击在 Workbench 执行
  P->>W: POST /v1/workbench/launches {projectId, taskRef, launchContext}
  W->>R: create/select session with project metadata
  W->>PM: record ProjectWorkbenchLink
  W-->>P: sessionId, workbenchUrl, linkId
  P->>PM: GET workbench-links by taskRef
  P->>U: router.push(workbenchUrl)
  U->>R: /workbench/sessions/{sessionId}
  R-->>U: session/messages/trace projection
```

Workbench 接收 `launchContext` 元数据，但不反解 `taskRef`、不读取 Markdown、不 import MDTODO 页面或 adapter。项目管理页面只拿到 `sessionId` 和 `workbenchUrl`，随后让 Workbench 自己按 session authority hydrate。

### 5.4 web-probe observe/analyze 流程

```mermaid
flowchart LR
  Start[observe start --target-path /projects/mdtodo] --> Page[Project Management page]
  Page --> Dom[DOM/testId/ARIA passive samples]
  Page --> Net[Natural same-origin network]
  Cmd[observe command select/launch/screenshot/mark] --> Page
  Dom --> Art[(JSONL artifacts)]
  Net --> Art
  Cmd --> Art
  Art --> Analyze[observe analyze page-kind project-management-mdtodo]
  Analyze --> Report[analysis/report.md + report.json]
```

项目管理验收优先使用 `observe start`、`observe command` 和 `observe analyze`。`web-probe script` 只作为短 API matrix、截图补证或 observe command 尚未覆盖时的过渡手段，不能作为原入口 closeout 的唯一证据。

### 5.5 HWPOD Source 配置与编辑写回时序

```mermaid
sequenceDiagram
  participant U as 用户
  participant P as /projects/mdtodo
  participant PM as hwlab-project-management
  participant H as HWPOD Source Adapter
  participant N as hwpod-node node-ops
  participant F as docs/MDTODO/*.md
  U->>P: 打开 Source 配置弹窗
  P->>PM: POST /v1/project-management/mdtodo/sources {hwpodId,nodeId,root}
  PM->>H: normalize + allowlist docs/MDTODO/
  H->>N: workspace.ls / workspace.cat probe
  N->>F: 受控 workspace op
  F-->>N: 文件摘要
  N-->>H: redacted result
  H-->>PM: source probe status
  PM-->>P: sourceId + capability + blocker 可空
  U->>P: 编辑 R1.1 title/status/body
  P->>PM: PATCH taskRef with expected revision
  PM->>H: lock document + mutate Rxx block
  H->>N: workspace.apply-patch/write
  N->>F: 原子写回
  H->>PM: new fingerprint
  PM->>PM: rebuild projection + audit/outbox
  PM-->>P: updated task + document revision
```

HWPOD-bound source 只能访问配置过的 workspace 相对根，例如 `docs/MDTODO/`。路径归一化必须拒绝 `..`、绝对路径、Secret 文件、未声明扩展名和非 allowlist 根；Web 不得展示任意文件浏览器，也不得直接调用 HWPOD node 私有接口。

### 5.6 web-probe 交互式 command 控制流

```mermaid
flowchart TD
  Start[observe start /projects/mdtodo] --> Goto[command gotoProjectMdtodo]
  Goto --> Config[command configureMdtodoHwpodSource]
  Config --> Probe[command probeMdtodoSource]
  Probe --> File[command selectMdtodoFile]
  File --> Tree[command expand/select Rxx task]
  Tree --> Mutate[command edit/toggle/add/reindex]
  Mutate --> Launch[command launchWorkbenchFromMdtodo]
  Launch --> Collect[collect --view project-mdtodo-summary]
  Collect --> Analyze[observe analyze]
```

上述 command 必须通过页面 UI 或正式同源 API 表达用户动作，进入 `control.jsonl`。同类动作出现第二次时必须沉淀为 repo-owned command；一次性 `script` 只能作为探索、短 smoke、截图或 API matrix 补证。

## 6. 原子需求

### 6.1 CLIENT-PM-REQ-001 项目根导航

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-001 | 项目根导航 | PJ2026-01040401 项目根导航 | [Web工作台](PJ2026-010401-web-workbench.md)、[用户管理](PJ2026-0105-user-management.md)、[平台运维](PJ2026-0106-platform-ops.md) |

项目管理应提供 Cloud Web 登录后一级“项目”导航和 `/projects` 根页面，使用户可以看到可见项目、source 状态、最近任务、最近 Workbench session link、capability 和 blocker。

项目根导航不得嵌入 Workbench，也不得以 Workbench session、workspace snapshot 或 localStorage 作为项目可见性 authority。项目列表和 source 状态只能来自同源 Project Management API 和当前 AuthPrincipal；未登录、无权限、source 不可用和 adapter parse 失败必须显示结构化 blocker。

### 6.2 CLIENT-PM-REQ-002 MDTODO 页面

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-002 | MDTODO页面 | PJ2026-01040402 MDTODO 页面 | [API契约](PJ2026-010403-api-contract.md)、[用户管理](PJ2026-0105-user-management.md) |

项目管理应提供 `/projects/mdtodo` 页面，使用户可以选择 MDTODO source、Markdown 文件摘要和任务树，查看任务 title、status、父子关系、link 摘要、capability/blocker 和稳定 `taskRef`。

页面必须通过同源 `/v1/project-management/*` API 获取 DTO，不得直接访问 UniDesk microservice proxy、hostPath、SSH、Kubernetes、数据库、未声明内部 service URL 或 Markdown 文件系统。页面默认不得展示 host path、Secret、token、完整 raw Markdown、provider payload、DB DSN 或大段 stdout/stderr。

页面布局应把 Source 和 File 选择压缩到顶部状态栏的两个下拉菜单；Source 配置由弹窗承载；Source/Files/Tasks/Links 等 metric 摘要进入 info/diagnostic 弹窗，不作为常驻大卡片占用主版面。任务树和详情/编辑区是主工作面，窄屏下也必须保持下拉、任务树、编辑控件和主要 action 可达且不重叠。

File 下拉主标签必须显示文件名或 source root 下的直接相对路径，例如 `20260609_频率判断_用户反馈.md`。Markdown 文档内部标题只能作为 secondary label、tooltip 或详情字段，不得覆盖文件名成为主选择值。文件列表必须只来自配置 root 的 direct `.md` children；`details/**`、`*_Task_Report.md`、`*_log_*.md` 等报告文件只能作为任务链接 target，不得进入 File 下拉或 source 文件计数。

MDTODO 页面必须按 Rxx heading 标准组织任务树，至少支持 `R1`、`R1.1`、`R1.1.1` 的父子关系、展开/折叠、搜索、跳转、状态筛选和选中高亮。树 authority 来自项目管理 projection 中的 Rxx id 和 parentTaskRef，不得从 checkbox 缩进、DOM 缩进或标题级别临时推断。

MDTODO 页面不得把 source 级全量任务列表作为首屏依赖。首屏应读取 source 摘要、file 摘要和默认 selected file 或 selected subtree 的有界任务窗口；文件切换、展开 Rxx 分支、搜索和状态过滤再按 cursor/offset 或 parentTaskRef 请求后续窗口。对于 `constart-71freq-mdtodo` 这类大 source，`/projects/mdtodo` 必须能在不下载全部任务投影的情况下识别 source、列出文件并进入可交互状态。

MDTODO 页面可以提供任务状态和内容写入入口，但写入必须进入项目管理服务，再由 MDTODO adapter 使用文件锁和原子写入修改 `.md`，随后重建投影。前端不得直接上传或覆盖 raw Markdown。主动操作范围至少包括标题/正文或 raw block 编辑、`open/in_progress/completed` 状态切换、添加根任务、添加子任务、延续 sibling、删除任务、保存文本块、刷新文件、reindex 和 Workbench launch。

任务详情必须在默认阅读态展示正文 Markdown、解析后的 report/task links、link target 存在性和最近更新时间。标题、正文和文本块修改必须采用双击进入 inline edit 的交互；独立常驻 Title input 或 Replace body textarea 只能作为诊断或过渡开发面，不得成为目标 UX。任务内 Markdown 报告链接点击后应在右侧预览栏渲染，支持全屏预览；渲染必须使用成熟 Markdown 渲染器并经过 HTML sanitization。

### 6.3 CLIENT-PM-REQ-003 独立项目管理微服务

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-003 | 独立微服务 | PJ2026-01040403 独立微服务 | [API契约](PJ2026-010403-api-contract.md)、[用户管理](PJ2026-0105-user-management.md)、[平台运维](PJ2026-0106-platform-ops.md) |

项目管理后端必须作为独立 `hwlab-project-management` 微服务交付。该服务拥有 Project Management API、ProjectSource registry、MDTODO adapter 编排、PM DB read model、ProjectWorkbenchLink、audit/outbox、health/readiness、OTel `service.name` 和未来外部 PM adapter 扩展点。

Cloud API 只保留同源 route/proxy/auth bridge：负责 AuthPrincipal、route policy、错误 envelope、trace context 和转发，不拥有项目/任务持久化、Markdown 解析、外部 PM sync、Workbench link 表或 adapter 状态。即使 P0 只有只读 MDTODO 和 launch Workbench，也不得把实现先落到 `hwlab-cloud-api` 内部模块后再迁移。

`hwlab-project-management` 作为独立微服务时必须显式声明 HWPOD node-ops adapter endpoint，使 `sourceKind=hwpod-workspace` 的 probe、reindex、read 和 write 能通过受控 HWPOD 服务路由执行。该 endpoint 应由 node/lane YAML 注入为 `HWLAB_PROJECT_MANAGEMENT_HWPOD_NODE_OPS_URL` 或等价受控配置，目标是 Cloud API 正式 `/v1/hwpod-node-ops` route/auth bridge 或同等 HWPOD 服务入口；不得隐式依赖 Cloud API 同进程 handler、Kubernetes service 直连、D601 SSH 或手工脚本来补齐 HWPOD workspace 读写能力。

新增或重构的项目管理源码文件头部必须标注 `SPEC: PJ2026-010404 项目管理 draft-2026-06-25-p0-mdtodo-web-active-editing-hwpod-source`，并简述文件职责；若文件只实现旧只读投影，也应同时引用 `draft-2026-06-25-p0-project-management-mdtodo`。

### 6.4 CLIENT-PM-REQ-004 MDTODO adapter 与存储策略

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-004 | MDTODO存储 | PJ2026-01040404 MDTODO adapter 与存储 | 项目管理独立微服务、平台运维 |

MDTODO 的权威存储应保持为 `.md` 文件。项目管理 DB 只保存可重建投影、Workbench link、audit/outbox 和 source sync 状态，不成为 Markdown 任务正文的唯一真实来源。

MDTODO adapter 应兼容 VSCode 插件的 Rxx heading 语义：任务标题以 `## R1`、`### R1.1`、`#### R1.1.1` 或等价 heading 起始；状态 marker 至少支持 `[completed]`、`[in_progress]` 和历史 `[Processing]`、`[Finished]` 的读侧兼容；parentTaskRef 来自 Rxx id 前缀。checkbox list parser 只能作为显式 legacy mode，不能和 Rxx 标准任务树混成同一个 authority。

HWPOD source discovery 必须按配置 root direct child 枚举 MDTODO 文件。递归发现、按文件内容猜测 `details/**` 报告、或把 task report 当作 document candidate 都属于错误文件范围。reindex 应清理旧投影中的 stale report documents，使 File count、File 下拉和 task projection 与 direct-file 规则一致。

PM DB 至少应能表达 `project_sources`、`mdtodo_documents`、`mdtodo_task_projection`、`project_workbench_links`、`project_audit_events` 或等价结构。`project_sources` 对 HWPOD source 保存 `sourceKind`、`hwpodId`、`nodeId`、workspace 相对根、能力开关和配置 revision；`mdtodo_documents` 记录 fileRef、fingerprint、mtime、lastIndexedAt、parseError 和 revision；`mdtodo_task_projection` 记录 `taskRef`、rxxId、title、status、parentTaskRef、depth、linkCount、updatedAt 和 source fingerprint；link 表记录 `projectId/taskRef/sessionId/traceId`。

任务投影读取 API 必须支持 fileRef、parentTaskRef、status/search 和 cursor/offset+limit 的受控窗口。服务端应对缺省 limit 使用 YAML 或代码常量声明的保守默认值，并对客户端传入 limit 套用最大上限；source 级全量导出只能作为显式管理/调试能力，不能作为普通 Web 页面、web-probe collect/analyze 或默认 CLI 输出的依赖。

所有写操作必须携带 expected document revision 或 fingerprint。revision 不匹配时返回 409/conflict 和脱敏诊断，不覆盖远端修改。删除任务必须明确影响范围，写入 audit，并在响应中返回新的 document revision 和 projection status。

任务详情 API 应返回 full task body、raw task block、parsed links、resolved report target metadata、fileRef、document fingerprint 和可写状态。报告预览 API 应按 taskRef 和 link id/path 读取同一 source root 内允许的报告文件，返回 Markdown 内容、fingerprint、mtime、byteCount 和 truncated/blocked 诊断；路径解析必须拒绝越权、绝对路径和 Secret 文件。

只有当多人实时协同编辑成为主需求、任务查询和权限规则复杂到 Markdown 投影无法支撑、外部 PM adapter 已经成为主写入源，并且具备可靠 Markdown export/import、审计、冲突解决和离线恢复方案时，才重新评估 DB 作为权威存储。

### 6.5 CLIENT-PM-REQ-005 Workbench Link 与解耦

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-005 | Workbench联动 | PJ2026-01040405 Workbench Link | [Web工作台](PJ2026-010401-web-workbench.md)、[API契约](PJ2026-010403-api-contract.md)、[Agent编排](PJ2026-0102-agent-orchestration.md) |

项目管理页面应通过公共 Workbench Launch API 启动 Workbench。请求只能携带 `projectId`、`taskRef`、`launchContext`、prompt template 或等价脱敏元数据；响应返回 `sessionId`、`workbenchUrl`、可选 `traceId/linkId` 和错误诊断。

Workbench 与项目管理必须互相解耦。项目管理页面不得 import `useWorkbenchStore`、`CodeWorkbenchView`、Workbench reducer、Trace renderer 私有模块或 session 内部状态；Workbench 模块不得 import MDTODO 页面、MDTODO adapter、Markdown parser 或 Project Management DB。两者不得通过 iframe、嵌套容器、localStorage、私有 service URL、数据库 join 或解析对方 ID 内部结构关联。

Workbench 可以保存和展示脱敏 `launchContext` 元数据，但 session、turn、message、trace 和 final response 的 authority 仍来自 Workbench durable projection。项目管理页面返回后通过 `GET /v1/project-management/workbench-links?taskRef=...` 读取 link 摘要，不从 Workbench 私有 store 反查。

MDTODO 发起的 Workbench launch 必须产生可观察的工作上下文。成功响应后的目标 session 至少应包含首轮用户消息、initial prompt、task context projection 或等价可执行 turn，使 `web-probe observe collect --view turn-summary` 能看到非空任务上下文；只创建空 session 并跳转属于 launch 失败。

### 6.6 CLIENT-PM-REQ-006 外部 PM adapter 边界

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-006 | 外部PM适配 | PJ2026-01040406 外部 PM adapter | 项目管理独立微服务、用户管理 |

项目管理应预留外部 PM adapter 边界，但 P0 不直接引入完整外部套件。Plane 可作为未来 work item 平台优先候选，Vikunja 可作为任务/todo 后端优先候选，OpenProject/Redmine/Taiga/Huly/Leantime 仅作为后续 adapter 评估对象。

外部 PM adapter 必须通过 ProjectSource 和 ProjectTask DTO 进入项目管理服务，不得替换 HWLAB 项目管理 API，也不得让 Cloud Web 直接调用外部系统 UI/API 成为第二入口。外部服务的授权、同步、冲突、审计和脱敏策略必须先落入项目管理服务边界，再暴露给 Web 和 CLI。

### 6.7 CLIENT-PM-REQ-007 web-probe observe/analyze

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-007 | 观测验收 | PJ2026-01040407 观测与验收 | [Web工作台](PJ2026-010401-web-workbench.md)、[平台运维](PJ2026-0106-platform-ops.md) |

项目管理页面必须支持 web-probe observe/analyze 原入口验收。`web-probe observe start --target-path /projects/mdtodo` 应能在 selected Web origin 采样项目管理页面，并通过 `observe analyze` 输出 issue-ready evidence：observer id、stateDir、report SHA、screenshot SHA、page-kind 摘要、DOM 摘要、自然同源 API timing 和 findings。

采样器应优先观察自然页面行为：`/auth/session`、`/v1/project-management/navigation`、`/v1/project-management/projects`、`/v1/project-management/mdtodo/sources`、`/v1/project-management/mdtodo/files`、`/v1/project-management/mdtodo/tasks`、`/v1/project-management/workbench-links` 和 `POST /v1/workbench/launches`。`script` 只允许作为短 API matrix、截图或 observe command 缺口补证；阶段 closeout 不得仅凭 script 通过。

项目管理页面应提供稳定 `data-testid` 或 ARIA 语义，覆盖项目导航、source 列表、file 列表、任务树、任务详情、selected task、Workbench launch 按钮、link 摘要、capability/blocker、empty/error/loading 状态。采样结果只保存 count、status、opaque id、hash/preview 和脱敏摘要，不保存 raw Markdown、host path、Secret、完整 prompt 或 provider payload。

`observe command` 应支持 MDTODO 交互式验收动作，包括 `gotoProjectMdtodo`、`openMdtodoSourceConfig`、`configureMdtodoHwpodSource`、`probeMdtodoSource`、`selectMdtodoSource`、`selectMdtodoFile`、`expandMdtodoTask`、`selectMdtodoTask`、`editMdtodoTaskTitle`、`editMdtodoTaskBody`、`toggleMdtodoTaskStatus`、`addMdtodoRootTask`、`addMdtodoSubTask`、`continueMdtodoTask`、`deleteMdtodoTask`、`reindexMdtodoSource`、`launchWorkbenchFromMdtodo`、`screenshot` 和 `mark`。动作必须通过页面 UI 或正式公共 API 触发，进入 `control.jsonl`，并在 `observe analyze` 中关联动作前后的 DOM/API/link 投影变化；不得调用私有 service URL、localStorage、Kubernetes、数据库或测试后门。

web-probe 必须提供 `observe collect --view project-mdtodo-summary` 或等价第一层阅读视图。该视图只读取 `samples.jsonl`、`control.jsonl`、network/resource timing 和已有 analysis，输出 sourceId、fileRef、taskRef、revision before/after、mutation 结果、Workbench link/session/trace 摘要和慢路径 findings，不访问业务 API，不驱动浏览器，不构成第二事实源。

项目管理 analyzer 必须把 source 级全量 task 拉取、超过受控 limit 的响应、`/v1/project-management/mdtodo/tasks` 慢路径和 `status=0`/requestfailed 单独归类为 `mdtodo-task-window-*` 或等价 finding。修复方向应是 API/window/UI 的职责收敛，而不是把 web-probe script 超时时间调大、在脚本中直连 service、或用 Kubernetes/DB/SSH 补齐统计。

项目管理 analyzer 应输出 `project-management-*`、`mdtodo-*` 和 `workbench-launch-*` 前缀 findings，避免在非 Workbench 页面误报 Workbench session/trace 专属 finding。

`draft-2026-06-26-p1-mdtodo-web-operable` 后，analyzer 还必须覆盖以下红/黄项：File 列表出现非 direct child `.md`；File 下拉主 label 不是文件名；选中任务正文不可见；任务 report link 不可点击或预览为空；`launchWorkbenchFromMdtodo` 后 Workbench session `turns=0`、`MSG=0` 或 `TRACE=0`；control/observer 的 source/file/task count 长时间分歧。上述 finding 的修复方向必须是 API/UI/launch 契约收敛，不是增大脚本超时或绕过页面访问内部服务。

### 6.8 CLIENT-PM-REQ-008 YAML-first 运行配置

| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| CLIENT-PM-REQ-008 | YAML运行配置 | PJ2026-01040408 YAML-first 运行配置 | [YAML运维](PJ2026-010603-yaml-first-ops.md)、[平台运维](PJ2026-0106-platform-ops.md) |

`hwlab-project-management` 的运行面配置必须走 YAML-first。D601/v03 部署应在 node/lane YAML 中声明 serviceId、namespace、image/source truth、Service/Deployment、DB migration/read model、Secret sourceRef、targetKey、OTel `service.name`、health/readiness、NetworkPolicy、Cloud API route/proxy 和 public exposure 关联。

HWPOD-bound MDTODO source 依赖的 node-ops adapter URL 必须同样来自 YAML-first 运行配置，并进入 `hwlab-project-management` Deployment env。D601/v03 的目标值应指向同 namespace 内 Cloud API `/v1/hwpod-node-ops` 正式入口，避免项目管理微服务因缺少 adapter env 只能创建 Source 配置却无法 probe/reindex 或写回 HWPOD workspace。该配置属于服务依赖声明，不属于 Secret；输出和 issue 证据只披露 env 名、目标 service/path 摘要和是否存在。

项目管理 web-probe target、readiness selector、自然请求 path group、DOM redaction allowlist、project command allowlist、loading/API 阈值和 slow path budget 也必须由受控 YAML 配置进入运行面，不得写在 probe 脚本、Cloud Web、项目管理服务或一次性 shell 中作为隐藏默认。

D601/v03 的 HWPOD-bound MDTODO 验收应允许把 Source 配置到 `hwpodId=d601-f103-v2`、`nodeId=node-d601-f103-v2`、`mdtodoRootRef=docs/MDTODO/`。示例文件 `docs/MDTODO/hwlab-v03-mdtodo-web-sample.md` 应覆盖 `R1`、`R1.1`、`R1.1.1`、`R2`、`[in_progress]`、`[completed]` 和普通 text block，用于原入口 observe command 验收。

Secret、DB DSN、provider token、session token、API key、host path 和 raw Markdown 内容不得出现在默认 CLI 输出、probe 报告、日志或错误 envelope 中。输出只披露对象名、key 名、sourceRef、presence、fingerprint、hash、字节数和 `valuesRedacted=true` 摘要。

## 7. 过程控制

本规格的阶段活动由架构治理 issue [#2123](https://github.com/pikasTech/HWLAB/issues/2123) 拆分跟踪：

| 阶段 | 跟踪 issue | 完成口径 |
| --- | --- | --- |
| P0 SPEC 先行 | [#2133](https://github.com/pikasTech/HWLAB/issues/2133) | 本规格与客户端/Web/API 交叉引用合并到 UniDesk master。 |
| P1 独立项目管理微服务 | [#2134](https://github.com/pikasTech/HWLAB/issues/2134) | D601/v03 有独立 `hwlab-project-management` 服务、API、DB 投影和 health/readiness。 |
| P2 项目根导航与 MDTODO 页面 | [#2135](https://github.com/pikasTech/HWLAB/issues/2135) | `/projects` 与 `/projects/mdtodo` 可通过同源 API 展示项目、source、file、task 和 blocker。 |
| P3 Workbench Launch 与 Link 投影 | [#2136](https://github.com/pikasTech/HWLAB/issues/2136) | 任务一键启动 Workbench，`projectId/taskRef/sessionId/traceId` link 可双向读取且模块解耦。 |
| P4 web-probe observe/analyze 项目管理支持 | [#2137](https://github.com/pikasTech/HWLAB/issues/2137) | observe/analyze 输出项目管理 page-kind evidence，script 仅为补证。 |
| P5 D601 YAML-first 部署与原入口验收 | [#2138](https://github.com/pikasTech/HWLAB/issues/2138) | D601/v03 selected origin 原入口通过 observe/analyze 完成 `/projects/mdtodo` 到 Workbench launch 验收。 |
| #2155 P0 增量 SPEC | [#2156](https://github.com/pikasTech/HWLAB/issues/2156) | HWPOD Source 配置、Rxx 主动编辑、web-probe command 验收和 D601 `docs/MDTODO/` 样例要求合并到 UniDesk master。 |
| #2206 P1 可工作 MDTODO Web | [#2206](https://github.com/pikasTech/HWLAB/issues/2206) | File 范围/标签、任务正文、报告预览、inline edit、Workbench 非空 launch 和 web-probe 红黄灯在 D601/v03 原入口收敛。 |

P0 SPEC 完成前不得进入项目管理代码实现。每个阶段独立 PR 跟踪；PR 合并后必须把 PR、commit、observe/analyze 报告或原入口证据回写到对应阶段 issue 和 [#2123](https://github.com/pikasTech/HWLAB/issues/2123)。
