Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
50f7163
docs(orgtrack-pm): freeze v1 contract, fixtures and phase-0 decisions
Neonforge98 Aug 5, 2026
f8b587d
refactor(agents): delete work-item-manager and dead automation paths
Neonforge98 Aug 5, 2026
64e168f
feat(pm): add work application service with FSM, audit and watermark
Neonforge98 Aug 5, 2026
0eaf930
feat(pm): converge UI write paths onto work.create and partial updates
Neonforge98 Aug 5, 2026
8994b7b
feat(pm): route agent-tool work item creation through work.create
Neonforge98 Aug 5, 2026
c9c76de
refactor(pm): convert manage_work_item standalone paths to atomic RMW
Neonforge98 Aug 5, 2026
f1ec6e7
feat(pm-cli): add org2-pm console binary with context and work commands
Neonforge98 Aug 5, 2026
8149d14
feat(pm-cli): wire idempotency dedup into mutation commands
Neonforge98 Aug 5, 2026
3cfe440
refactor(modes): converge divergent mode catalogs to a single source
Neonforge98 Aug 5, 2026
f662582
feat(pm): add portable routine spec domain with validated apply
Neonforge98 Aug 5, 2026
5e6b110
feat(pm): materialize routine runs into work graphs via routine.invoke
Neonforge98 Aug 5, 2026
dcbff52
feat(pm-cli): wire routine commands and durable run-status projection
Neonforge98 Aug 5, 2026
9f02f6d
feat(pm): convert legacy RoutineDefinitions into portable specs
Neonforge98 Aug 5, 2026
5ade99a
feat(pm): drive portable routines from the unified scheduler
Neonforge98 Aug 5, 2026
1f57ee7
refactor(automation): retire the cron execution path
Neonforge98 Aug 5, 2026
0b43bb7
feat(pm): make orchestrator completion an explicit audited policy
Neonforge98 Aug 5, 2026
5b9b005
feat(pm): add provider binding table and capability-profile registry
Neonforge98 Aug 5, 2026
d3a4fe9
feat(pm): add persistent product-mode axis to sessions
Neonforge98 Aug 5, 2026
b57bd44
refactor(ui): delete the dead workflow-drag signal
Neonforge98 Aug 5, 2026
fb28e24
chore(pm): finish the terminology sweep for retired PM identifiers
Neonforge98 Aug 5, 2026
f99635c
refactor(tools): consolidate work-item CRUD onto manage_work_item
Neonforge98 Aug 5, 2026
54e22b3
fix(app): thread product_mode through the remaining launch initializers
Neonforge98 Aug 5, 2026
2fa4aab
feat(pm): expose product mode end to end through the session aggregate
Neonforge98 Aug 5, 2026
92c1f12
feat(ui): add Project to the composer mode selector
Neonforge98 Aug 5, 2026
efeb258
feat(pm): gate the PM mutation tools on Project product mode
Neonforge98 Aug 5, 2026
c110215
fix(pm): close product-mode gating gaps across launch surfaces
Neonforge98 Aug 5, 2026
306a340
fix(ui): make the in-session mode pill reach Project mode
Neonforge98 Aug 5, 2026
ec3ae29
feat(pm): finish the Project session surface
Neonforge98 Aug 5, 2026
993bad1
fix(pm): scope the bootstrap root to a real local org or personal
Neonforge98 Aug 5, 2026
7c32109
fix(pm): keep git subprocesses out of the completion transaction
Neonforge98 Aug 5, 2026
a8a2266
fix(ux): land AI create flows in the launched session
Neonforge98 Aug 5, 2026
2f1ef0d
fix(ux): make the AI work-item filler an agent that has the tools
Neonforge98 Aug 5, 2026
9402844
fix(pm): stop linked sessions repurposing their draft for new items
Neonforge98 Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/architecture/managed-cloud-collaboration.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ detail views and ChatPanel. Lock release is serialized as explicit JSON

## Create with AI

Create with AI uses `builtin:work-item-manager` by default and follows one
durable-draft invariant:
Create with AI uses `builtin:os` by default (the Work Item Manager persona was
retired; `manage_work_item`/`manage_project` are ordinary built-in tools) and
follows one durable-draft invariant:

1. Before launch, the UI allocates a cloud-aware Work Item ID and writes one
draft in the selected Project or organization-scoped standalone store.
Expand Down
41 changes: 41 additions & 0 deletions docs/orgtrack-pm-protocol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Orgtrack PM Protocol — Phase 0 frozen artifacts

`orgtrack/v1` WorkItem + Routine CLI 协议的 Phase 0 产出。本目录是协议 wire
contract 的 source of truth:schemas 与 golden fixtures 会被后续 Phase 3+ 的
conformance 测试直接消费;`decisions.md` 记录 Phase 0 冻结的全部命名与边界
决策,实现与之冲突时以本目录为准。

设计依据是《Orgtrack WorkItem + Routine CLI Protocol — 最终设计》rev 2
(2026-08-04 审计修订版,暂未入库)。

## 目录

```text
decisions.md Phase 0 冻结决策(mode/capability/provider id/hook 名/
manifest/CLI 载体/watermark/exit code)
parity-matrix.md 入口一致性矩阵(每个 phase 落地时填格)
schemas/ JSON Schema(draft-07)
common.schema.json 共享 $defs:ActorRef、SessionRef、状态枚举、
capability 词汇表
envelope.schema.json success/error CLI envelopes 与稳定错误码
execution-context.schema.json `org2 context` 返回的 ExecutionContext
work-item.schema.json WorkItem canonical shape
routine.schema.json portable Routine spec
routine-run.schema.json RoutineRun occurrence
fixtures/
success/ 每个 command family 的 success envelope golden fixture
errors/ 18 个稳定错误码各一份 golden fixture
```

## 约定

- fixtures 是 byte-level golden:conformance 测试比较真实 serialized bytes,
不允许隐藏 `$schema`、remote `$ref`、secret 或本地路径混入 wire payload;
- 未列入 `envelope.schema.json` 错误码枚举的 code 不得出现在任何实现中;
- schemas 修改需要同步更新 fixtures 与 `decisions.md`,三者不一致视为 CI 失败
(Phase 3 接入)。

## Phase 0 未尽项

- 现有 Routine/WorkItem 数据导出(migration fixture)需要开发机的
`projects.db`,推迟到 Phase 4 开工时以脚本完成,脚本与导出样本届时入库。
144 changes: 144 additions & 0 deletions docs/orgtrack-pm-protocol/decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Phase 0 冻结决策

本文件是 Phase 0 交付的决策冻结记录。实现阶段(Phase 1-8)与此冲突时,要么改
实现,要么先修订本文件并说明理由——不允许静默偏离。

## 1. Product mode 与 resolver precedence

Product mode enum:`build | plan | ask | project`(唯一 source of truth 是
ExecutionContext 的 `mode` 字段;禁止任何 `tracking_enabled` 类影子布尔)。

Mode resolver 固定顺序:

1. 从 WorkItem detail、Routine 或 RoutineRun 启动 → `project`;
2. 用户在当前 Session 明确选择的 mode;
3. 普通新 Session → `build`。

现状注意:mode 枚举目前有四处发散清单(Rust `AgentExecMode`、
`agent_list_modes`(返回 4 项且无 UI caller)、TS `AGENT_EXEC_MODES` picker、
`MODE_LABELS`)。Phase 3 收敛为单一 source 后才允许新增 `project`。

Plan mode 有"进入时快照、退出时恢复前一 mode"状态
(`restore_mode_before_plan_entry`):`Convert to Project` 必须失效该快照。

## 2. Mode × capability allowlist

Capability 词汇表(12 个,见 `common.schema.json#/definitions/capabilityId`):
`work.read|create|update|claim|transition|note|relate`、
`routine.read|apply|run|cancel|set_enabled`。`context` 读取不需要 capability。

| Mode | allowlist |
| ----------------------------------- | ------------------ |
| build / plan / ask / 其他 exec mode | (空——仅 context) |
| project | 全部 12 个 |

最终 capabilities = mode allowlist ∩ actor/org policy ∩ provider capabilities。
实现必须用现有 deny-delta 机制表达("modes never grant tools"):Build/Plan 等
显式 deny work/routine mutation surface,Project 不施加该 deny;授权本身只来自
actor/org policy。

术语隔离:本协议的 `runtimeExecutionMode` 对应现有 `AgentExecMode` wire
values;**不得**复用现有 Rust `ExecutionMode { Direct, WorkStation }` 类型名。
`review` 在三个域必须使用限定名:exec mode(`AgentExecMode::Review`)、agent
role(`AgentRole::Review`,orchestrator 状态机 key 的列)、orchestrator phase
(`OrchestratorPhase::Review`)。

## 3. 错误码 ↔ exit code

错误码枚举见 `envelope.schema.json`(18 个,含 `RESULT_SCHEMA_MISMATCH`)。

| exit | 错误码 |
| ---- | ------------------------------------------------------------------------------------------------------------ |
| 0 | success |
| 2 | INVALID_ARGUMENT / RESULT_SCHEMA_MISMATCH / DEPENDENCY_CYCLE |
| 3 | NOT_FOUND / CONTEXT_REQUIRED / ACTOR_REQUIRED |
| 4 | REVISION_CONFLICT / IDEMPOTENCY_CONFLICT / ALREADY_CLAIMED / ALREADY_EXISTS / NOT_READY / INVALID_TRANSITION |
| 5 | PROJECT_MODE_REQUIRED |
| 6 | PROVIDER_UNAVAILABLE / STORE_UNAVAILABLE |
| 7 | UNSUPPORTED_CAPABILITY |
| 8 | PERMISSION_DENIED / SCOPE_VIOLATION |

`PROJECT_MODE_REQUIRED`(5)与 `PERMISSION_DENIED`(8)分离:前者提示"需要用户
切换 mode",后者是"该 actor 无权执行"。claim 竞争时 `ALREADY_CLAIMED` 优先于
`REVISION_CONFLICT`。现有 `orgtrack check` 的 0/1/2 exit 语义属于该 binary 自身,
与本表无关。

## 4. CLI 载体与 crate 命名

- 用户侧 command 名为 `org2`;由**新的独立 console binary** 提供:crate
`orgtrack-pm-cli`,cargo bin name `org2-pm`(workspace 内唯一),distribution
安装到 PATH 并命名/别名为 `org2`;
- 现有 GUI binary(cargo package `org2`,release 下
`windows_subsystem = "windows"`,无 console)**不承载任何 CLI subcommand**;
- PM 协议 DTO crate 命名为 `orgtrack-pm-protocol`——注意 `orgtrack-protocol`
已被 session provenance wire contracts 占用(设计文档 §19 的建议名与之冲突,
以本条为准);同理后续 domain/application/store crates 使用 `orgtrack-pm-*`
前缀;
- 现有 `orgtrack` binary(外部会话历史索引)不变;`packages/orgtrack` npm
stub 在 Phase 1 删除。

## 5. Provider ID 命名空间

SessionRef.provider / ProviderBinding.provider 使用以下冻结 registry:

- `org2` —— 一切 ORG2 拥有/托管的 session(内部 canonical source
`orgii_rust_agents` / `orgii_cli_sessions` / `orgii_cloud_replay` 一律对外
呈现为 `org2`;底层 harness 记录在 SessionRef.metadata.nativeHarness);
- 外部 provider 使用 importer 端 canonical source id:`claude_code`、
`codex_app`、`cursor_ide`、`cursor_cli`、`opencode`、`cline`、`copilot`、
`kimi`、`qwen_code`、`droid`、`antigravity`、`zcode`、`warp`、`trae`、
`qoder`、`windsurf` 等(以 `orgtrack-core` source registry 为准);
- hook 端短名映射到 canonical id,不对外出现:`claude→claude_code`、
`codex→codex_app`、`cursor→cursor_ide`、`qwen→qwen_code`、其余同名直映;
- planning provider id:`linear`、`github`(现有 adapter registry id 不变)。

## 6. Session 生命周期 hook 命名

协议 canonical hook 名:`session.started`、`session.completed`、
`work.claimed`、`work.transitioned`、`routine.invoked`、`routine.completed`、
`artifact.produced`。

现状三套命名的映射(Phase 5 落地时接线,不新增第四套):

| 现状 | canonical |
| -------------------------------------------------------------------- | --------------------------------------------------- |
| WS wire `session.completed` / `session.failed` / `session.cancelled` | `session.completed`(payload 携带 terminal status) |
| Tauri 内部 `session-status-changed` | 内部信号,驱动 canonical hooks,不直接暴露 |
| agent 流 `session_start` / `session_end` | `session.started` / `session.completed` |

`session.started` 现状不存在,为新增。`session.completed` 默认只附加
SessionRef;orchestrator 场景的自动完成改写为显式默认 completion policy(走
canonical `work.transition`,带 attempt/session identity)。

## 7. Workspace manifest 与 env

- Manifest 文件:`.orgii/orgtrack.json`,最小 shape
`{ "version": 1, "scopeId": "...", "orgId": "..." }`;
- `is_initialized(workspace)` = 该文件存在且 `version` 受支持。`.orgii/` 目录
存在本身**不**代表已初始化(现状该目录树由 git-folder sync 等副作用创建);
- trusted local resolver 顺序:explicit CLI flags → `ORGII_*` env →
manifest。冻结 env 名:`ORGII_MODE`、`ORGII_ACTOR`、`ORGII_SCOPE`、
`ORGII_SESSION_REF`(沿用现有 `ORGII_` 前缀惯例;不新增 `ORG2_*`)。

## 8. 跨进程 wake(pm_change_seq)

- `projects.db` 新增单行表 `pm_change_seq(id INTEGER PRIMARY KEY CHECK(id=1),
seq INTEGER NOT NULL)`;
- 每个 PM mutation 在同一 transaction 内 `seq = seq + 1`;
- 桌面 host 低频轮询(或 db 文件 watch 触发)读取 seq,变化时做增量
reconciliation;进程内 mutation 直接内存通知;
- readiness / RoutineRun 投影 / output 绑定在 mutation 事务内同步完成,CLI
写入不依赖 host 在线。

## 9. 列表分页与 list 返回形状

- list 类 data 形状固定为 `{ "items": [...] }`;
- `--cursor <token>` 请求下一页;`meta.nextCursor` 存在表示还有后续页;
- cursor 是 opaque token,实现可变,语义不进协议。

## 10. Claim 与既有锁的边界

- claim record 收编本地 `execution_lock`(CAS session 执行锁)职责;
- 云端 `orgii_acquire_work_item_lock` 保持为 human 协作**编辑锁**:编辑锁 ≠
工作 claim,两者并存但互不代理;Phase 2a 落地时在 service 层写清依赖关系
(持有编辑锁不阻止 claim,claim 不授予编辑权)。
15 changes: 15 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/actor-required.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "ACTOR_REQUIRED",
"message": "No actor resolved: pass --actor or set ORGII_ACTOR (actors are never inferred from OS username or git owner)",
"retryable": false,
"details": {
"missing": ["actor"]
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR03"
}
}
18 changes: 18 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/already-claimed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "ALREADY_CLAIMED",
"message": "WorkItem work_01K0000000000000000000WORK0 is claimed by agent codex_app:reviewer-1",
"retryable": false,
"details": {
"claimedBy": {
"kind": "agent",
"id": "codex_app:reviewer-1"
}
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR10"
}
}
16 changes: 16 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/already-exists.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "ALREADY_EXISTS",
"message": "Routine name 'interaction-impact-analysis' already exists in this scope",
"retryable": false,
"details": {
"resource": "Routine",
"name": "interaction-impact-analysis"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR06"
}
}
15 changes: 15 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/context-required.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "CONTEXT_REQUIRED",
"message": "No scope resolved: pass --scope, set ORGII_SCOPE, or run inside an initialized workspace (.orgii/orgtrack.json)",
"retryable": false,
"details": {
"missing": ["scopeId"]
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR02"
}
}
19 changes: 19 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/dependency-cycle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "DEPENDENCY_CYCLE",
"message": "Adding depends_on work_01K0000000000000000000ROOT0 would create a cycle",
"retryable": false,
"details": {
"cycle": [
"work_01K0000000000000000000WORK0",
"work_01K000000000000000000COLL0",
"work_01K0000000000000000000WORK0"
]
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR13"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "IDEMPOTENCY_CONFLICT",
"message": "Idempotency key 'session_abc:complete' was already used with a different canonical request body",
"retryable": false,
"details": {
"idempotencyKey": "session_abc:complete",
"operation": "work.transition"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR08"
}
}
16 changes: 16 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/invalid-argument.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "INVALID_ARGUMENT",
"message": "Unknown state 'done'; expected one of open|in_progress|blocked|completed|failed|cancelled",
"retryable": false,
"details": {
"field": "--to",
"value": "done"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR01"
}
}
16 changes: 16 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/invalid-transition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "INVALID_TRANSITION",
"message": "completed -> in_progress is not allowed; in_progress is only entered via work.claim or blocked -> in_progress",
"retryable": false,
"details": {
"from": "completed",
"to": "in_progress"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR11"
}
}
16 changes: 16 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/not-found.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "NOT_FOUND",
"message": "WorkItem work_01K000000000000000000GONE0 does not exist in scope project_01K0000000000000000000SCOPE",
"retryable": false,
"details": {
"resource": "WorkItem",
"id": "work_01K000000000000000000GONE0"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR05"
}
}
15 changes: 15 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/not-ready.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "NOT_READY",
"message": "WorkItem work_01K0000000000000000000WORK0 has 1 incomplete dependency",
"retryable": true,
"details": {
"incompleteDependencies": ["work_01K000000000000000000COLL0"]
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR09"
}
}
16 changes: 16 additions & 0 deletions docs/orgtrack-pm-protocol/fixtures/errors/permission-denied.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"apiVersion": "orgtrack/v1",
"ok": false,
"error": {
"code": "PERMISSION_DENIED",
"message": "Actor codex_app:reviewer-1 lacks capability routine.apply in this scope",
"retryable": false,
"details": {
"actor": "codex_app:reviewer-1",
"missingCapability": "routine.apply"
}
},
"meta": {
"requestId": "req_01K0000000000000000000ERR15"
}
}
Loading
Loading