Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"homepage": "https://github.com/PsychQuant/issue-driven-development",
"allowCrossMarketplaceDependenciesOn": [
"claude-plugins-official",
"parallel-ai-agents"
"parallel-ai-agents",
"codex-pro"
],
"plugins": [
{
Expand Down
3 changes: 3 additions & 0 deletions openspec/changes/codex-channel-dependency/.openspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema: spec-driven
created: 2026-07-18
created_by: che cheng <kiki830621@gmail.com>
45 changes: 45 additions & 0 deletions openspec/changes/codex-channel-dependency/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Design: codex-channel-dependency

## D1 — executable 歸 pai,前置區先解析(供兩用途)

現行 SKILL 的共通前置在 Tier 1 之前算 `CODEX_CALL=$CLAUDE_PLUGIN_ROOT/bin/codex-call`、Tier 1 才算 `PAI_DIR`。重排:**前置區先解析 `PAI_DIR`**(同一段 `sort -V` cache glob),再取 `PAI_CODEX_CALL="$PAI_DIR/bin/codex-call"` — 一次解析、engine 路徑與 codex-call 路徑兩用。`MIN_PAI="2.19.0"`(gate 理由更新:2.18.0 引擎會**靜默忽略** codexModel/codexEffort → canonical tier 治理斷鏈,寧 fail 不降級)。pai 缺席/過舊 → 既有 Tier 2 fail-fast 訊息路徑;此時 codex leg 無 executable → 沿用既有 fail-closed INFO finding(cross-model pass incomplete),不 abort 整個 verify。

## D2 — 治理歸 codex-pro:contract-pinned,非 value-pinned

```bash
CP_DIR=$(ls -d ~/.claude/plugins/cache/codex-pro/codex-pro/*/ 2>/dev/null | grep -E '/[0-9]+\.[0-9]+\.[0-9]+/$' | sort -V | tail -1)
MIN_CODEX_PRO="0.7.0" # defaults.json + profile-contract.md 起點
# gate 失敗 → abort:claude plugin install codex-pro@codex-pro(superpowers 同款 fail-fast)
# 解析(per codex-pro references/profile-contract.md §2):
# defaults.json 起底(model/effort/max_time)→ ~/.codex-pro/profile.yaml → ./.codex-pro/profile.yaml(per-field 高層蓋低層)
```

IDD **pin 契約不 pin 值**(contract §4):樹內不出現任何 model 字面。defaults.json 缺檔/parse 失敗 → **fail-fast**(#205 fail-loud 判準 — 靜默跑錯 model 比失敗糟)。profile.yaml 解析沿 contract 的扁平 YAML 假設(python3 單行,同 codex-pro 慣例、不依賴 PyYAML)。

## D3 — 依賴接線:superpowers 形狀逐項對齊

| #209 superpowers | 本案 codex-pro |
|---|---|
| `dependencies` @ claude-plugins-official | `dependencies` @ codex-pro(self-hosted marketplace)|
| root marketplace `allowCrossMarketplaceDependenciesOn` | 同 — 加 `codex-pro` |
| `check-plugin-presence.sh` 三參數 pre-flight | `check-plugin-presence.sh codex-pro codex-pro` 於 idd-verify Step 0.5 前 |
| 缺席 fail-fast + 一步安裝指令 | 同(無 soft fallback — 使用者裁決「要 hard,保證品質」)|

## D4 — canonical tier 傳參

Workflow args 增 `codexModel: $CODEX_MODEL, codexEffort: $CODEX_EFFORT`(pai 2.19.0 additive 契約)。`codexCallPath` 改傳 `$PAI_CODEX_CALL`。manual fan-out 的背景 codex 呼叫與 legacy 直呼段同步帶 `--model "$CODEX_MODEL" --effort "$CODEX_EFFORT" --max-time "$CODEX_MAX_TIME"`。

## D5 — drift-guard 重塑(single-pin 契約遷移)

`model-generation-sync` 的不變量從「pin 在 IDD codex-call」改為「**IDD 樹內零 pin,契約指向 codex-pro**」:

- assert `bin/codex-call` **不存在**(回歸 = 有人重新 vendor)
- assert SKILL 含 `MIN_CODEX_PRO="0.7.0"`、`defaults.json`、`codexModel`、`PAI_CODEX_CALL`、`MIN_PAI="2.19.0"`
- refute `--model gpt-5` / `gpt-5.5` hard-pin(維持);世代中立 prose(`gpt-5.x`)維持
- idd-route / references 斷言維持不動

## Alternatives considered

- **依賴 codex-pro 也提供 executable**:否 — codex-pro design D3 明文 executable 歸 pai;跨 plugin 職責不重排
- **PATH 解析 `command -v codex-call`**(codex-pro setup 的做法):否 — IDD 已有 PAI_DIR 精確解析,PATH 受安裝順序影響(本案動機之一就是 PATH 上撞到 IDD 自己的 vendored copy)
- **保留 vendored copy 當 fallback**:否 — 使用者裁決 superpowers 形狀;divergence audit 證明 fork 必然靜默落後
29 changes: 29 additions & 0 deletions openspec/changes/codex-channel-dependency/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Proposal: codex-channel-dependency

## Why

IDD vendor 一份 `bin/codex-call`(#147 時代 — 當時 pai 還不是依賴)。前提已被 #207/#219 推翻(pai 是 install-time hard dependency、vendored ensemble fork 已刪,codex-call 卻留下)。實證兩則:divergence audit(#264 comment)顯示 vendored copy 落後 pai 2.18.0 四個安全/正確性修正(exp NSNumber parse、umask 0o077、form-encoding、flock re-read);#251 在 vendored copy 重做了 codex-pro#3 五天前已做過的 model bump。使用者裁決(2026-07-18):「完全依賴,跟 superpowers 一樣」。

## What Changes

1. **刪除** `plugins/issue-driven-dev/bin/codex-call`(不留 fork — superpowers 形狀,#209 exemplar)
2. **executable 歸 pai**:codex-call 一律解析 `$PAI_DIR/bin/codex-call`(沿用既有 cache `sort -V` 解析);`MIN_PAI` 2.18.0 → **2.19.0**(codexModel/codexEffort args 起點,pai#22)
3. **治理歸 codex-pro**:新 governance 解析 — `MIN_CODEX_PRO=0.7.0` gate、讀 `references/defaults.json` 起底、疊 profile.yaml 兩層(per codex-pro `profile-contract.md` §2);解析失敗 fail-fast(不靜默 fallback)
4. **canonical tier 傳參**:Workflow args 加 `codexModel`/`codexEffort`(pai 2.19.0 契約);manual fan-out 與 SKILL 直呼處帶顯式 `--model`/`--effort`
5. **依賴接線**:`plugin.json` dependencies 加 `codex-pro@codex-pro`;root marketplace `allowCrossMarketplaceDependenciesOn` 加 `codex-pro`;Step 0.5 前 pre-flight `check-plugin-presence.sh codex-pro codex-pro`(缺席 fail-fast + 一步安裝指令)
6. **drift-guard 重塑**:`model-generation-sync` 的 single-pin 契約改指 codex-pro `defaults.json` — IDD 樹內零 model pin;`bin/codex-call` 不存在成為 assertion

## Non-Goals

- pai `bin/codex-call` 自身 default 的 bump(顯式傳參後無關;pai 另案)
- codex-pro producer skills 的 resolver 讀檔化(codex-pro#7 Residue)
- IDD_AGENT_MODEL(Claude dispatch model)機制 — 與 codex 治理正交,不動

## Impact

- Affected specs: `idd-verify`(ADDED requirement)
- Affected code: `skills/idd-verify/SKILL.md`、刪 `bin/codex-call`、`scripts/tests/model-generation-sync/test.sh`、`.claude-plugin/plugin.json`、root `marketplace.json`

## Refs

Issue #264(diagnosis + divergence audit);上游 codex-pro#7(0.7.0,已結案)、pai#22(2.19.0,已結案)
27 changes: 27 additions & 0 deletions openspec/changes/codex-channel-dependency/specs/idd-verify/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## ADDED Requirements

### Requirement: Codex channel is fully dependency-resolved

`idd-verify`'s codex channel SHALL contain no vendored executable and no model pin: the `codex-call` executable SHALL resolve from the installed `parallel-ai-agents` plugin cache (semver `sort -V`, gated `MIN_PAI` ≥ 2.19.0 — the `codexModel`/`codexEffort` contract floor), and model / effort / max-time governance SHALL resolve per `codex-pro`'s profile contract (gated `MIN_CODEX_PRO` ≥ 0.7.0): `references/defaults.json` as the base layer overlaid by the global then project `profile.yaml`. Resolved values SHALL be passed explicitly — as `codexModel` / `codexEffort` Workflow args on the canonical tier and as explicit `--model` / `--effort` flags on manual-fan-out invocations. A missing or too-old `codex-pro` installation, or an unreadable `defaults.json`, SHALL fail fast with a one-step install instruction and SHALL NOT silently fall back to any hardcoded model.

#### Scenario: no vendored executable in the tree

- **WHEN** the plugin tree is inspected
- **THEN** `plugins/issue-driven-dev/bin/codex-call` does not exist, and the SKILL resolves the executable from the pai plugin cache

#### Scenario: governance flows from codex-pro to the canonical tier

- **GIVEN** codex-pro 0.7.0+ installed with `defaults.json` model `gpt-5.6-sol` and no profile.yaml overrides
- **WHEN** the pai-ensemble canonical tier dispatches
- **THEN** the Workflow args include `codexModel: "gpt-5.6-sol"` and the codex leg runs that model

#### Scenario: project profile overrides the default

- **GIVEN** `./.codex-pro/profile.yaml` sets `effort: high`
- **WHEN** governance resolves
- **THEN** effort is `high` (project layer) while model still comes from `defaults.json`

#### Scenario: absent codex-pro fails fast

- **WHEN** codex-pro is not installed (or < 0.7.0)
- **THEN** idd-verify aborts before dispatch with the instruction `claude plugin install codex-pro@codex-pro`, and no ensemble runs on a guessed model
9 changes: 9 additions & 0 deletions openspec/changes/codex-channel-dependency/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## 1. Tests first (RED)

- [x] 1.1 (Req: Codex channel is fully dependency-resolved) Reshape scripts/tests/model-generation-sync/test.sh: single-pin 契約遷移 — assert `bin/codex-call` 不存在、SKILL 含 `MIN_CODEX_PRO="0.7.0"` / `defaults.json` / `codexModel` / `PAI_CODEX_CALL` / `MIN_PAI="2.19.0"` / 安裝指令 `claude plugin install codex-pro@codex-pro`;refute `--model gpt-5` hard-pin 維持;idd-route 斷言維持。Run: RED。

## 2. Implementation (GREEN)

- [x] 2.1 (Design D1 — executable 歸 pai,前置區先解析; D2 — 治理歸 codex-pro:contract-pinned; D4 — canonical tier 傳參) skills/idd-verify/SKILL.md: 前置區重排(PAI_DIR 先解析 + PAI_CODEX_CALL + codex-pro governance 解析 block + fail-fast);MIN_PAI 2.19.0 + gate 理由;Workflow args 加 codexModel/codexEffort、codexCallPath 改 PAI_CODEX_CALL;manual fan-out 與 legacy 直呼段帶顯式 --model/--effort/--max-time;Step 0 TaskCreate 清單補 governance pre-flight。
- [x] 2.2 (Design D3 — 依賴接線 superpowers 形狀) 刪 plugins/issue-driven-dev/bin/codex-call;plugin.json dependencies 加 codex-pro@codex-pro;root marketplace.json allowCrossMarketplaceDependenciesOn 加 codex-pro。
- [x] 2.3 (Design D5 — drift-guard 重塑) Verify: model-generation-sync GREEN;全 plugin sweep 0 fail;spectra validate clean。
4 changes: 4 additions & 0 deletions plugins/issue-driven-dev/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
{
"name": "parallel-ai-agents",
"marketplace": "parallel-ai-agents"
},
{
"name": "codex-pro",
"marketplace": "codex-pro"
}
]
}
Loading
Loading