Imported from hrmtz/claude-harness (
plugins/harness-magi/skills/dual-magi-review/SKILL.md). Install upstream withnpx skills add hrmtz/claude-harness --skill dual-magi-review. Copyright stays with the author.
dual-magi-review — independent multi-perspective design doc peer review
A "Magi" is a parallel set of independent sub-agent reviewers, each examining a doc from a distinct perspective. "Dual-Magi" pairs same-family Magi with a cross-family reviewer (different model family via external adapter) to subtract shared training-data bias.
Inspired by Evangelion's 三賢者 system + academic peer review compression.
Family routing policy
For design docs that will lead to implementation, reviewers should evaluate whether the design respects the default ultramagi routing:
Claude: planning / design plateau
Codex: implementation
Claude: adversarial design-intent review
Codex: final fixes + tests
This is not a substitute for cross-family review; it is a role contract. A design that asks the same family to design, implement, and approve its own interpretation should justify that choice or be marked for revision.
Fallback when a family is unavailable:
- If Claude is unavailable, Codex may continue design drafting, but the design remains "Claude review pending" and cannot claim plateau.
- If Codex is unavailable, implementation should be limited to reversible scaffolding/tests until Codex can perform the coding or final executable review.
- If either cross-family adapter is unavailable, write a
FAMILY_ROUTINGnote documenting preferred routing, actual routing, missing family/phase/reason, and what must run before ship.
Pattern essence (= core invariant、 unchanging)
1. independent multi-perspective critique (= N sub-agents、 perspectives 直交)
2. cross-family bias cancellation (= 異 model、 optional adapter)
3. iterative reroll (= round 毎に prior findings 反映 + 新 catch)
4. Claude-native campaign は Step 6 の散文 stop criteria、companion campaign は
`magi_design_convergence_gate.py` の bounded decision で stop / next action を決める
Variant detail (= adjustable):
- perspective count N (= 3 default、 2-5 OK)
- round count (= 2-4 typical、 domain で flex)
- cross-family vs same-family-only
- external transport (= mailbox / API webhook / shared file / etc; see § Adapters)
When to invoke
- Authoring or reviewing a design doc ≥ 500 lines (= architecture, ADR, migration plan, schema, retrieval framework, identity strategy)
- The doc is production-critical (= migration / deploy / data ingest / scoring algorithm / public-facing system)
- Single-model bias risk is high (= you wrote it, you're reviewing it, attachment bias expected)
- Triggers: "peer review this doc", "review iteratively", "independent review", "magi にかけて", "ブラッシュアップ", "production-grade review"
When NOT to invoke
- Code review of a PR diff →
/simplify - Single-function correctness →
Tasktool directly - Doc < 200 lines → manual review faster than skill overhead
- Time-critical hotfix → this takes hours
Modes (= default review-only)
| mode | flag | side effects | use case |
|---|---|---|---|
| review-only (default) | (none) | none — outputs report only | initial validation、 mutation 別工程 |
| apply-local | --apply-local |
edits doc in working tree、 no commit | reroll inline + manual review of diff |
| commit-push | --commit-push |
apply-local + commit on current branch + push | autonomous loop (= use with extreme caution) |
Mutation modes are opt-in. The skill never commits, pushes, or modifies files by default. This is to preserve user control over git state and the branch policy invariant (see § Prerequisites).
Args
/dual-magi-review <doc-path> \
[--rounds N] # default 3
[--perspectives p1,p2,p3] # default: algorithm,adversarial,business
[--external <adapter-id>] # default: codex-exec (= v0.6.0 mandate)
[--no-cross-family <reason>] # explicit opt-out, must justify
[--domain-preset <path>] # extra perspective definitions
[--freerange] # round 2+ only: add checklist-free 4th reviewer
[--apply-local | --commit-push] # opt-in mutation
[--round N] # resume at specific round (= 2-phase pattern)
<doc-path>: absolute path required--rounds N: max rounds 1-4 (= per-round invocation pattern recommended、 see § Loop strategy)--perspectives: 3 comma-separated keywords (= preset or custom)--external: see § Adapters。 defaultcodex-exec(= v0.6.0、 see § Cross-family mandate)--no-cross-family <reason>: opt-out cross-family、 reason string required (= telemetry + audit)。 valid reasons:quick-iteration(= rapid doc skeleton iteration、 followed by mandatory final round) /non-design-artifact(= not a design doc、 e.g., status report)--domain-preset: load additional perspective briefs from external file--freerange: round 2 以降で checklist-free reviewer を追加の 4 体目として起動する。 既存 3 perspective の置換には使わない。出力は${magi_dir}/round_<N>_freerange.json--apply-local/--commit-push: enable mutation (= mutually exclusive)--round N: explicit round number for resuming (= e.g.,--round 2after externall reply received)
Cross-family mandate (= v0.6.0、 gh #195 lesson)
Plateau CONFIRM definition updated:
- Claude same-family 3 round CONFIRM is NOT plateau
- plateau requires 1+ cross-family round (= codex exec or mailbox adapter) with REJECT/REVISE not blocking
- skill MUST refuse
plateaudeclaration until cross-family round recorded
Why (= 5/22 incident):
- gh #195: citation pipeline refactor v0.5、 4 Claude same-family round plateau CONFIRM 4.3/4.5/4.8 → Codex 1 round REJECT 1/5 + 6 NEW CRITICAL (= Claude 全 round で全 miss)
- root cause: same-family bias で integration / production-shape verify を skip、 doc internal coherence のみ確認
- structural fix: v0.5.0 schema-grounding mandate と同 pattern で、 cross-family round を skill default に baked-in
Invocation behavior (= v0.6.0):
--external未指定 →codex-execadapter で自動 final round 走らせる--no-cross-family <reason>指定 → log + warn、 「plateau CONFIRM」 を report に書けない- cross-family round で REJECT / 重大 CRITICAL → final verdict は cross-family verdict 優先 (= Claude 3 round CONFIRM があっても overrule)
Prerequisites
- doc exists at
<doc-path>(= absolute path) - git working tree clean OR
--apply-local/--commit-pushnot set - current branch is NOT main (= per project branch policy)
Tasktool available (= Anthropic CLI)- for
--external <adapter>: adapter-specific prerequisites (= see § Adapters) - for
--commit-push: project's pre-commit hook + branch protection respected
Protocol (= per-round = single invocation)
Key: 1 invocation = 1 round. Loop is user-driven (= re-invoke for next round). This avoids context exhaustion + makes state explicit in user transcript.
Step 1: Read doc + state setup
- Read
<doc-path>(= full content) - Compute artifact_sha = sha256 of doc content (= for correlation)
- Determine round number (= from
--roundflag、 default 1) - state dir は per-doc namespace (= v0.10.1):
${magi_dir} = ${doc_dir}/.dual-magi/<doc-stem>/(doc-stem = doc file 名から拡張子を除いたもの、例REVIEW_FLOW_PORT)。mkdir -p ${magi_dir}を親が先行実行 (= reviewer sub-agent は directory 作成に失敗しても 親に伝えられないため、spawn 前に必ず存在保証する)。 理由 (2026-07-28 実 incident):${doc_dir}/.dual-magi/直下は同 dir の全 doc + magi campaign (CAMPAIGN/PLATEAU/round__) が共有しており、flat 配置だと mergedround_<N>.json/state.jsonが他 doc・他 campaign の同名 state を clobber する (v0.10.0 初実戦で旧 campaign の merged file 3 本を上書き、per-persona 生存 file から再構成)。 mkdir 前にls ${doc_dir}/.dual-magi/で既存 state の有無を確認し、既存 flat 配置の round file が居る場合も自分の書込みは必ず subdir 側に行う - Load prior-round findings if round > 1 (= from
${magi_dir}/round_<N-1>.json)
Custom perspective label 予約語禁止: user が --perspectives で指定する label
(= file 名 round_<N>_<perspective>.json に使う)
として melchior / balthasar / caspar / hornet / gnat / wasp / codex /
xfamily / freerange は
使用禁止。ただし built-in --freerange だけはこの予約語を所有する明示的例外であり、
literal round_<N>_freerange.json を必ず使う。magi_campaign_guard.py (= harness-magi-codex) が同名 file
round_<N>_<persona>.json の存在で companion campaign の完了判定を行うため、この skill の
per-reviewer file が同名だと campaign 状態を誤判定する。default perspectives
(algorithm / adversarial / business) は非衝突。custom perspective 指定時も同様に検査し、
衝突する label は <label>-p 等に rename して file 名衝突を回避する。
Step 2: Spawn 3 sub-agents in parallel
Single message with 3 Task tool calls (= parallel execution):
- Each Task call MUST pass
model: "opus"explicitly (= review/批評系 child は opus 固定、 memoryfeedback_ultramagi_children_opus_max)。理由: 省略すると親 model を継承する。親が fable (Mythos-class) のとき子に fable がこぼれ、review 品質に寄与しないまま fable クォータを 無駄食いする(fable は親 orchestrator のみ、子に使うのは禁止)。opus 明示は親が opus/fable/sonnet の いずれでも安全側。 review 品質は multi-perspective + cross-family(codex) で担保、子 tier ではない。 - Headroom-aware tier (capacity-oracle、任意・fail-open): Claude は実運用で唯一 subscription 枠を
焼き切る family。Claude×3 の同一 family reviewer を spawn する前に
capacity-oracle substitute -q '.keep'で Claude の live headroom を確認 (CLI 不在なら fail-open で opus)。false(= Claude が offload floor 未満 = 熱い) のときは同一 family reviewer をmodel:"sonnet"に格下げして残枠を伸ばす — 上のとおり review 品質は child tier でなく multi-perspective + 必須 codex cross-family round が担保するので安全側 (sonnet も明示 tier、fable 継承 leak ではない)。cross-family(codex) round は絶対に薄めない (Codex は 枯渇しない、Claude が熱いときこそ full weight)。cf. capacity-oracle-mcp#92 / docs/WIRING.md §3。 - Each receives full doc as context
- Each receives one perspective brief
- Each must use structured finding schema (see § Finding schema)
- Each must end with: 「総合: GO / GO-WITH-REVISE / REJECT」
Reviewer file-return contract (= v0.10.0、claude-harness#218 token 削減)
背景 (実測 2026-07-28): reviewer の Task 返り値 30-43k chars × 3 並列 × 最大 8 round が session context に居座り、以降の全 turn で cache read され続ける = 肥大 tool_result の最大単一 クラス。findings 本体を file に落とし、返り値は要約のみにする。
spawn 指示に以下を 必ず含める:
- sub-agent は general-purpose type (=
Writetool 必須。read-only type では file を書けない) - full findings JSON (= § Finding schema の配列 +
verify_commands_executed+schema_grounding_verdict) を${magi_dir}/round_<N>_<perspective>.json(= per-doc subdir、Step 1 参照) に Write してから return する - 返り値契約 = ≤200 words: file path echo + 総合 verdict (GO / GO-WITH-REVISE / REJECT) + severity 別件数 (REJECT/HIGH/MED/LOW/nit) + 上位 3 finding の title のみ。 長文 findings・rationale・verify command 列挙を返り値に書くな — 本体は file が正、 返り値は receipt にすぎない
Optional fourth reviewer: --freerange (= v0.11.0)
--freerange は round 2 以降だけ有効。通常の 3 perspective を全て起動したうえで、
同じ parallel Task batch に 追加の 4 体目として general-purpose sub-agent を入れる。
既存 reviewer の置換・必要 reviewer 集合への算入は禁止。model tier は当該 round の
same-family reviewer と同じ明示 tier (opus、headroom 低下時は sonnet) を使う。
prompt は full doc、次の brief 1 行、出力契約だけで構成する。perspective checklist や 探索観点を追加して自由探索を狭めない:
この doc の問題点を自由に探せ。checklist はない。
出力契約は通常 Claude-native reviewer と同じ JSON object:
reviewer / round / verdict / schema_grounding_verdict /
verify_commands_executed と § Finding schema の findings 配列。
reviewer: "freerange" と当該 round を設定して
${magi_dir}/round_<N>_freerange.json に Write してから返すこと。
§ Finding schema は各 finding object の例であり、companion
plugins/harness-magi-codex/schemas/finding.schema.json の full envelope に
Claude-native 出力を適合させるという意味ではない。
返り値は通常 reviewer と同じく ≤200 words の receipt
(file path、総合 verdict、severity 別件数、上位 3 title) に限定する。
${doc_dir}/.dual-magi/ flat 域への書込みは禁止。
Schema-grounding mandate (= v0.5.0、 5/22 ADR-TPN v0.1 incident 学習)
以下の checklist inject は通常 3 perspective の契約。--freerange reviewer は
checklist-free を保つため inject 対象外だが、自由探索中に実行した verification は
verify_commands_executed に記録する。
doc に table 名 / column 名 / SQL 例 / 既存 code 挙動 premise が含まれる場合、 各 sub-agent prompt template に下記を 必ず inject (= AI 自起草 doc の 妄想 column / hallucinated schema を front-load catch):
SCHEMA GROUNDING (mandatory): The doc you are reviewing may reference real
tables, columns, SQL queries, or claims about how existing code (e.g.,
"filter X is applied to retrieve Y") behaves. For every such reference:
1. Verify table/column existence:
- `psql "$POSTGRES_URL" -c '\d <table>'` for live DB schema
- `grep -rn '<column_name>' migrations/` for schema-as-code
- `grep -rn '<column_name>' core/ api/ scripts/` for actual usage
2. Verify populate state for filter premises:
- `SELECT COUNT(*) FILTER (WHERE <col> IS NULL), COUNT(*) FROM <table>`
- if a filter assumes "this column is populated", surface NULL coverage
3. Verify existing-code-behavior premises:
- "ENV_FLAG_X gates Y" claim → `grep -rn 'ENV_FLAG_X' core/ api/` and
trace the actual code path, surface drift between doc narrative and
real behavior
Any drift found = CRITICAL finding (= schema-reality drift breaks impl).
Do NOT trust doc-internal SQL examples; the author may have written them
from memory or imagination without `\d`-verifying.
これにより design doc 起草の systematic hallucination bias (= AI is biased toward
narrative coherence and skips literal-existence verification) を structural rail で catch。
memory feedback_design_doc_schema_grounding_required の structural 上位対応 (=
behavioral rule の skill skeleton 焼付け)。
Reviewer artifact MUST-emit (= v0.5.1、 efficacy anecdotal → measurable)
Each sub-agent's output JSON MUST include verify_commands_executed field listing
the actual psql / grep / Read commands run during the review:
{
"reviewer": "MELCHIOR",
"round": 3,
"verdict": "GO-WITH-REVISE",
"verify_commands_executed": [
"psql ... -c '\\d papers'",
"psql ... -c '\\d medical_facts'",
"grep -rn 'recall_flag' /home/.../migrations/",
"grep -rn 'PRO_DOMAIN_FILTER' /home/.../core/ /home/.../api/",
"Read core/retriever_pg.py:370-390",
"..."
],
"schema_grounding_verdict": "PASS | PARTIAL | FAIL",
...
}
Rationale: v0.5.0 hook's claim "schema-grounding mandate baked-in" is otherwise self-reported. The explicit command list:
- Measures hook efficacy — comparing rounds shows whether reviewers actually
verify vs hand-wave; rounds with empty
verify_commands_executedare degraded regardless of stated verdict - Audit trail — when a v3 round passes but post-ship reveals schema drift, the command list shows whether the gap was un-verified or actively missed
- Force-functions the verify behavior — knowing the list will be emitted creates checklist-style discipline at review time
If verify_commands_executed is empty or only contains generic Read commands
without targeted psql/grep verification:
- mark reviewer-side
schema_grounding_verdict: FAIL - mark the whole round as "schema-grounding degraded" in synthesis
- consider re-running that reviewer with explicit instruction
This is the 「N+1 回目を待たない」 (don't wait for the next failure) structural rail — every round emits its own audit, no round is graded only on outcome.
例 (= 2026-05-22 PRS-LLM ADR-TPN v0.1 dual-magi v2 で実際に catch):
- doc:
medical_facts.layer LIKE '1c%'→ 実:layerはbook_catalog.layer、 JOIN 必要、 v0.1 SQL silently fail - doc:
papers.recall_flag = TRUE→ 実: column 不在、 hallucinated safety rail - doc:
paper_chunks.updated_at→ 実: column 不在、 pre-flight gate hard-error stub - doc: 「PRO_DOMAIN_FILTER は paper retrieve も絞る」 → 実: textbook retrieve only、 narrative completely false
dual-magi v1 → v2 の 同 doc round で 1 round 単独で 5 CRITICAL schema-drift を catch、 single-model self-review では同 doc 起草者 (= AI) が verify を skip するため miss 確実。
Step 3: Wait for required 3 outputs + optional freerange (= foreground block)
Task tool returns when sub-agent completes. Required 3 reviewers と、
--freerange 指定時の追加 reviewer は同じ batch で parallel block する。
返り受領後、reviewer ごと (--freerange 指定時は freerange も含む) に
per-reviewer file を検証 (= v0.10.0):
${magi_dir}/round_<N>_<perspective>.jsonが実在するか- JSON として parse できるか (=
jq empty <file>等)
required reviewer completeness は、起動時に確定した元の 3 perspective label が 全て返ったかを明示的に検査する。freerange は required 集合に入れず、required reviewer の欠落を埋めたものとして数えない。
欠落 / parse 不能時の fallback: その reviewer は 返り値 text で synthesize を続行
(= v0.9.0 挙動への後方互換。返り値契約違反で長文が返っていればそれが使える)。
merged round_<N>.json に reviewer_file_missing: ["<perspective>"] を記録し、
synthesis 出力に degraded を明記する。retry しない (= reviewer 再 spawn は round 全体の
walltime を倍にする割に、返り値 fallback で成果は保全されているため)。
Failure handling:
- 元の required 3 perspective のいずれかが未返却なら、freerange の成否に関係なく gap を 記録し、利用可能な出力で続行して report を degraded にする
--freerange指定時に freerange が未返却 / file 欠落 / parse 不能なら、required completeness は変えずoptional_freerange_missing: trueを merged file に記録し degraded を明記する- If any sub-agent times out: continue with remainders, retry budget = 1
Step 4: Synthesize
Synthesize 入力は per-reviewer JSON file の Read (= v0.10.0。返り値 text ではない — 返り値は receipt、本体は file)。context 節約のため jq projection 推奨:
jq '{findings: [.findings[] | {finding_id, severity, verdict, title, location, dup_flag}],
verdict, schema_grounding_verdict,
verify_commands_count: (.verify_commands_executed | length)}' \
${magi_dir}/round_<N>_<perspective>.json
(verify_commands_executed は件数のみ取る — 実行 command の全文列挙は audit 用に file に
残っていれば足り、synthesis context に流す必要はない。rationale / required_fix は severity
REJECT/HIGH のものだけ追加 Read する。)
Output structured finding matrix to user (Markdown table):
| field | description |
|---|---|
| finding_id | unique per round (= round-perspective-N) |
| severity | REJECT / HIGH / MED / LOW / nit |
| verdict | GO / REVISE / REJECT |
| title | short summary (= ≤ 80 chars) |
| location | doc line range or section anchor |
| rationale | why this is a finding |
| required_fix | specific change recommended |
| confidence | high / med / low |
| dup_flag | new / dup-from-round-N (= compared to prior rounds) |
| missed_angle | what previous rounds / single-model would miss |
Then aggregate:
- count per severity
- cross-perspective agreement (= 2+ perspectives flag same issue = high-confidence cluster)
- new-vs-duplicate ratio (= if > 80% dup → ship signal)
--freerange指定時は freerange findings も同じ matrix / severity aggregate に含める
Save to ${magi_dir}/round_<N>.json for next-round reference (= 親の merged json
write は v0.10.0 でも維持 — Step 1 の round 継続性はこの file が担う)。merged json に
reviewer_files 配列 (= per-reviewer file の path 一覧) を追加し、欠落があれば
reviewer_file_missing も記録する (= Step 3 参照)。retirement launch ledger 用に
campaign_id と、最初の reviewer batch 起動時に UTC で実測して以後の round へそのまま
引き継ぐ RFC3339 UTC campaign_launched_at (%Y-%m-%dT%H:%M:%SZ) も記録する。
--freerange round は reviewer artifact の .findings | length を
freerange_finding_count として記録する。さらに raw
round_<N>_freerange.json bytes の sha256 を freerange_artifact_digest、
severity 別件数を freerange_severity_counts
(REJECT / CRITICAL / HIGH / MED / LOW / nit) として merged file に必ず記録する。
schema_grounding_verdict=FAIL は artifact の破棄理由でなく round の HOLD signal。
親 synthesis は各 finding の evidence を確認し、${magi_dir}/verification.json に
verified / disputed / unreviewed を finding 単位で Write する。Step 3 で reviewer
artifact を parse する際、raw JSON bytes の sha256 も計算し artifact_digest として
sidecar に固定する。sidecar は次の形:
{
"canonical_repo": "/absolute/canonical/repo",
"campaign_id": "<doc-stem>",
"round": 2,
"written_by": "parent-synthesis",
"verifications": [
{
"source_relpath": "docs/designs/.dual-magi/example/round_2_freerange.json",
"artifact_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"reviewer": "freerange",
"finding_id": "r2-freerange-1",
"status": "verified",
"note": "confirmed during synthesis"
}
]
}
canonical_repo は worktree ではなく canonical checkout の absolute path、
source_relpath はその repo root から reviewer file への canonical relative path とする。
join は canonical_repo + source_relpath + artifact_digest + reviewer + finding_id の
完全形、または既知の sighting_key のみを使う。同じ relpath の別 worktree artifact を
digest なしで join しない。曖昧な campaign/reviewer tuple は書かない。
verdict の DB 反映は非同期: sidecar 自体は DB に接続せず、次回 harvest が finding upsert 後に適用する。撤去判定を今すぐ引く必要がある場合だけ、project の credential-safe な既存手順で harvester を手動実行する。skill は harvester の script 名や DB credential を仮定しない。
Step 5 (optional): External reviewer round
If --external <adapter> set:
- Invoke adapter (see § Adapters)
- Adapter publishes review request via its transport (= mailbox / webhook / API)
- Skill returns immediately (= non-blocking)
- User must re-invoke with
--round N --resumeafter external reply received
For non-async adapters (= synchronous API): adapter returns reviews inline.
Step 6: Convergence evaluation
Output to user:
total findings: REJECT N, HIGH N, MED N, LOW Nnew vs duplicate from prior round: <ratio>recommendation: continue → next round / converge → ship
Stop criteria (= user judges OR explicit flag for auto):
- ≥ 80% findings duplicate from prior round
- All new findings LOW severity / nit
- Cumulative rounds =
--rounds Nmax - User says "ship" / "stop"
- severity-gated terminal (= v0.7.0、 Fable-class reviewer 対応): latest round (cross-family
含む) に invariant を破る NEW CRITICAL/HIGH がない → converge。 MED/LOW は doc revision せず
caller の deferred ledger (=
DEFERRED.md) 行き、 実装 gate で解消。 zero-findings は Fable-class reviewer では到達不能 (2026-07-10 実測: 41 round 回しても毎 round 3-7 findings) — findings ゼロ待ち・criterion 1 の発火待ちで loop を回し続けない。
freerange の CRITICAL / HIGH は、他 reviewer と同様に plateau を止める。
「数えない」のは必要 reviewer 集合であって severity gate ではない。 この拘束は Claude-native state を読まない
機械 gate ではなく、この Step 6 の散文 gate が担う (未強制の convention)。
Runaway guard: Claude-native campaign の散文予算は 3 full fan-out/cross-family pairs (12 weighted launches)。これは wired enforcement ではない。境界で altitude checkpoint (= ship core / slice / descend to code) を取る。real requirement revision のみ remaining global allowance へ進め、最大 1 pair。user sign-off や fresh state directory で予算を延長しない。 Revision after re-review is diff-scoped (= diff + invariant を渡す、 unchanged text の再審は auto-dup 扱い)。 enumerable detail (= grant list / opclass / column list 等) を prose で列挙する doc は altitude 違反 — 修正は追記でなく executable gate 化 (= ultramagi § Convergence economics 参照)。
--freerange round は 3 perspective + cross-family + freerange = 5 launches。round 1 は
freerange 禁止なので、12 launch の campaign 累計は通常 round 1 の 4 + freerange round 2 の 5
= 9。残り 3 は retry 用で、2 回目の full freerange round は予算外。これは wired enforcement
ではなく discipline target (未強制の convention)。freerange は round 2 以降に統括が
明示した時だけ回す。
Step 7: Mutation (= only if --apply-local or --commit-push)
If mutation flag set:
- Read doc again (= check artifact_sha unchanged, fail if changed)
- Apply REJECT + HIGH REVISE findings via Edit
- Update doc's changelog section with version note
- If
--commit-push:- Verify branch policy (= current != main)
git pull --ff-only origin <current-branch>(= reject if non-FF)git add <doc-path>+git commitwith structured messagegit push origin <current-branch>- Verify pre-commit hook passed (= no
--no-verify)
If mutation flag NOT set (= default review-only):
- Output: 「No mutation applied. Run with --apply-local to integrate findings.」
Operational procedure: freerange retirement
これは ordinary review invocation の Step ではない。DB credential を要求せず review-only を 維持する。operator が periodic に全 repository を横断して実行する独立手順。
まず全 canonical repo の merged ${magi_dir}/round_<N>.json を走査する。正規表現
round_[0-9]+\.json に一致する merged file だけを対象にし、reviewer_files に
round_<N>_freerange.json がある campaign を「launched」と数える。zero-finding output も
ledger に残るため 1 campaign と数える。各 campaign は最初の該当 round だけを採り、
campaign_launched_at, campaign_id の順で global sort する。DB の finding row や
first_seen_at を launch count / order に使わない。latest 3 consecutive campaign の
canonical_repo + campaign_id を固定する。3 本未満なら KEEP_FLOOR。canonical repo
root を引数に渡す executable derivation:
set -euo pipefail
[ "$#" -gt 0 ] || {
echo "usage: retirement-ledger <canonical-repo-root>..." >&2
exit 2
}
{
for supplied_root in "$@"; do
common_dir=$(git -C "$supplied_root" rev-parse \
--path-format=absolute --git-common-dir)
canonical_root=$(dirname "$common_dir")
find "$canonical_root" -type f -name 'round_*.json' -print0
done
} |
while IFS= read -r -d '' merged; do
[[ $(basename "$merged") =~ ^round_[0-9]+\.json$ ]] || continue
common_dir=$(git -C "$(dirname "$merged")" rev-parse \
--path-format=absolute --git-common-dir)
canonical_root=$(dirname "$common_dir")
jq -r --arg repo "$canonical_root" --arg merged "$merged" '
select(any(.reviewer_files[]?; endswith("_freerange.json"))) |
[
(.campaign_launched_at // error("missing campaign_launched_at: " + $merged)),
$repo,
(.campaign_id // error("missing campaign_id: " + $merged)),
(.freerange_finding_count // error("missing freerange_finding_count: " + $merged)),
$merged
] | @tsv
' "$merged"
done |
sort -u |
awk -F '\t' '
{
key = $2 SUBSEP $3
if (!(key in launched) || $1 < launched[key]) {
launched[key] = $1
repo[key] = $2
campaign[key] = $3
}
expected[key] += $4
}
END {
for (key in launched)
print launched[key] "\t" repo[key] "\t" campaign[key] "\t" expected[key]
}
' |
sort -t "$(printf '\t')" -k1,1 -k2,2 -k3,3 |
tail -n 3 |
awk -F '\t' '
{ rows[NR] = $0 }
END {
if (NR < 3) {
print "KEEP_FLOOR: only " NR " campaign(s)" > "/dev/stderr"
exit 3
}
for (i = 1; i <= NR; i++) print rows[i]
}
'
linked worktree が引数でも --git-common-dir から canonical checkout に正規化する。
出力第 4 field は campaign 全 round の raw freerange finding 数。次に credential-safe な
既存 psql session へ、その正確な 3 row を parameter として渡す:
WITH selected(
canonical_repo, campaign_id, expected_findings, launch_order
) AS (
VALUES
(:'repo_1', :'campaign_1', :'expected_1'::bigint, 1),
(:'repo_2', :'campaign_2', :'expected_2'::bigint, 2),
(:'repo_3', :'campaign_3', :'expected_3'::bigint, 3)
),
campaign_stats AS (
SELECT
s.canonical_repo,
s.campaign_id,
s.expected_findings,
s.launch_order,
count(f.*) AS observed_findings,
count(f.*) FILTER (WHERE NOT f.dropped) AS finding_count,
count(f.*) FILTER (
WHERE NOT f.dropped
AND f.parent_verdict IN ('verified', 'disputed')
)::numeric / NULLIF(
count(f.*) FILTER (WHERE NOT f.dropped), 0
) AS verdict_coverage,
count(DISTINCT (f.title_norm, f.location_norm, f.severity_norm)) FILTER (
WHERE NOT f.dropped
AND f.severity_norm IN ('REJECT', 'CRITICAL', 'HIGH')
AND f.parent_verdict = 'verified'
) AS verified_blockers,
count(DISTINCT (f.title_norm, f.location_norm, f.severity_norm)) FILTER (
WHERE NOT f.dropped
AND f.severity_norm IN ('REJECT', 'CRITICAL', 'HIGH')
AND f.parent_verdict = 'disputed'
) AS disputed_blockers
FROM selected s
LEFT JOIN personal.magi_findings f
ON f.canonical_repo = s.canonical_repo
AND f.campaign_id = s.campaign_id
AND lower(f.reviewer) = 'freerange'
GROUP BY
s.canonical_repo, s.campaign_id, s.expected_findings, s.launch_order
)
SELECT
count(*) AS campaigns_observed,
bool_and(
observed_findings = expected_findings
AND (finding_count = 0 OR verdict_coverage = 1)
) AS coverage_complete,
coalesce(sum(verified_blockers), 0) AS verified_blockers,
coalesce(sum(disputed_blockers), 0) AS disputed_blockers,
CASE
WHEN count(DISTINCT (canonical_repo, campaign_id)) <> 3
OR bool_or(
coalesce(canonical_repo, '') = ''
OR coalesce(campaign_id, '') = ''
) THEN 'KEEP_FLOOR'
WHEN coalesce(sum(disputed_blockers), 0) > 0 THEN 'HOLD_DISPUTE'
WHEN bool_and(
observed_findings = expected_findings
AND (finding_count = 0 OR verdict_coverage = 1)
)
AND coalesce(sum(verified_blockers), 0) = 0 THEN 'RETIRE'
WHEN NOT bool_and(
observed_findings = expected_findings
AND (finding_count = 0 OR verdict_coverage = 1)
) THEN 'HOLD_COVERAGE'
ELSE 'KEEP_EFFECTIVE'
END AS decision
FROM campaign_stats;
coverage numerator は verified / disputed のみ。unreviewed は coverage に数えない。
ただし disputed な REJECT / CRITICAL / HIGH は HOLD_DISPUTE であり、coverage を満たしても
RETIRE へ進めない。各 disputed blocker は non-empty note、判定 round、freerange reviewer
とは別の検証者 identity を sidecar に残す。これらは自己申告 metadata なので operator が
根拠を確認する。
filesystem の expected count と DB の observed count が一致するまで未 harvest / 部分 harvest
として HOLD_COVERAGE。expected count が 0 の真正 zero-finding campaign だけ coverage
complete と扱う。
semantic blocker は campaign 内の
(title_norm, location_norm, severity_norm) distinct。判定は repository-local でなく global。
verification.json は authenticated でない (written_by は自己申告)。RETIRE は
advisory candidate にすぎず自動撤去権限を持たない。operator は対象 3 campaign を PR/review
履歴と照合し、未来 timestamp / v0.11.0 release 前 timestamp を拒否し、各 sidecar が親
synthesis の出力であることを確認してから人間判断する。HOLD_COVERAGE が 7 日を超えたら
measurement-path incident として escalation し、修復するまで撤去判定を凍結する。
v0.11.0 release 日 2026-07-28 から 6 か月後の 2027-01-28 に 3 campaign 未満なら、 「使われていない」を理由に撤去する。
Finding schema (= standardized)
{
"finding_id": "r1-algorithm-3",
"severity": "HIGH",
"verdict": "REVISE",
"title": "PageRank convergence criteria not auditable",
"location": "§3.3.1 lines 186-203",
"rationale": "L1 1e-8 threshold over 77.6M nodes is too strict; max-iter 100 has no fail behavior",
"required_fix": "tolerance 1e-6×N + top-k Jaccard + Kendall tau + explicit fail diagnostic + Discord alert",
"confidence": "high",
"dup_flag": "new",
"missed_angle": "single-model review treats convergence as solved; numerical rigor gap"
}
Perspective presets
Generic (= any design doc、 default)
algorithm: algorithm + statistical/numerical rigor, convergence, scale, memory, alternativesadversarial: security, abuse, supply chain, gaming, public-launch incentive, governancebusiness: GTM, buyer segments, brand, competitor counter, moat, timeline realism
Custom
Any 3 keywords accepted. Skill generates a brief from keyword (= 5-10 observation points, output format expectation).
Domain presets
For project-specific perspectives (= not in generic), use --domain-preset <path>:
/dual-magi-review docs/designs/foo.md \
--perspectives medical-informatics,production-retrieval,graph-theory \
--domain-preset ~/.claude/skills/dual-magi-review/examples/medical_rag_perspectives.md
Example presets:
examples/medical_rag_perspectives.md(= PRS-LLM / mafutsu)examples/web_app_perspectives.md(= future)examples/data_pipeline_perspectives.md(= future)examples/ml_training_perspectives.md(= future)examples/legal_document_perspectives.md(= future)
Adapters (= cross-family transport)
Cross-family reviewer integration is implemented via adapter modules in
adapters/<adapter-id>.md. Each adapter defines:
- transport mechanism
- request schema (= sender → reviewer)
- response schema (= reviewer → sender)
- correlation fields
- ACK / timeout / fallback policy
- prerequisites (= mailbox file / API key / pane id / etc)
Built-in adapters (= skeleton, implement per-project):
codex-exec (= default since v0.6.0、 non-interactive)
why default: zero-config、 synchronous、 no tmux pane / mailbox setup 不要、 5-10 min walltime で 1 round 完結。 gh #195 lesson (= 4 Claude same-family round CONFIRM → Codex 1 round REJECT 1/5 with 6 NEW CRITICAL) を構造 default に焼く。
invocation
codex exec --skip-git-repo-check - < /tmp/codex_review_prompt.md
skill 内動作:
- 通常 Claude 3 視点 round (= MELCHIOR / BALTHASAR / CASPAR) 完了後
codex execを final round として自動呼出、 prompt は v0.6.0 template 経由構築:- target doc full read
- prior round findings 同梱
- schema-grounding mandate explicit (= 「real grep/psql verification, NOT speculation」)
- integration drift focus (= production wire dict shape ↔ impl 入力 assumption)
- output format: REJECT/REVISE/GO-WITH-REVISE/APPROVED + CRITICAL/HIGH/MED findings
- Codex output を round N+1 として記録、 final verdict は Codex verdict 優先
- Codex REJECT または CRITICAL ≥ 1 → 「plateau」 declaration block、 round 続行
options
--codex-model <model>: default Codex CLI default (= GPT-5.5 系)--codex-timeout-s <sec>: default 600 (= 10 min)--codex-prompt-file <path>: prompt template override、 default skill 自動生成
prerequisites
codexCLI installed (=which codexで確認)codex login通過済 (=codex doctorで auth status)- 対象 repo 内に対象 doc 存在
error handling (= v0.6.1、 S1 stage。 詳細 docs/designs/CODEX_MAGI_MIRROR.md §7.1)
不変条件: cross-family round は plateau の 必要条件 (= v0.6.0)。 それが満たされないまま 「plateau」 を名乗ることはできない。 fail-open は cross-family が opt-in だった v0.5 以前の名残であり、 「skip が静かにできてしまう構造」 = gh #195 の root cause そのもの。
以下は 既存 workflow を止めないための移行段階 (= S1)。 継続するか否かの挙動は当面 fail-open のままだが、 plateau を名乗る資格は失われる:
codex execexit non-zero → log + retry 1 回、 失敗継続なら continue、 但し round にexternal-failedを mark- timeout → kill + retry なし、 continue、 但し
external-failed - output parse 失敗 → raw output を round N+1 entry に保存 (= 次 round の reviewer が現物を見られる位置。 v0.6.0 の挙動を維持) + warning、
external-failed
external-failed が付いた round を含む review は、 plateau / 「plateau CONFIRM」 を report に書いてはならない。
「internal-only で継続できた」 ことと 「cross-family round が走った」 ことは別物である。
移行段階: S1 (= 現在) = 止めない、 但し plateau 不可 → S2 = --no-cross-family <reason> 明示時のみ継続 →
S3 = fail-closed (= exit 非 0)。 「止める」 より先に 「plateau を名乗らせない」。 行動を壊さずに不変条件を回復する。
構造 rail (= 文ではなく script) は plugins/harness-magi-codex/scripts/magi_plateau_gate.sh に実装済 (= G1-G9)。
Design convergence は separately installed harness-magi-codex companion
の report-only rail magi_design_convergence_gate.py が担当する。ただし
Claude-native workflow の state だけを evaluator に渡してはならない。companion
の campaign guard / fanout / xfamily adapters が同じ ledger と artifact topology
を所有する campaign 全体でのみ実行する。各 phase 後に evaluate <doc> を実行する。同じ HIGH+
root の再発、同 subsystem の新 HIGH+ root 再発、3 revision の blocker mass
停滞、2 logical cycle、または reserved xfamily を含む unaffordable transition
で bounded terminal decision を返す。PLATEAU_CANDIDATE は G1-G9 gate へ渡せる
という意味だけで、plateau marker や shipping authority ではない。
The canonical guard's default per-campaign ceiling is 12 weighted model launches: three fan-out
plus mandatory cross-family pairs without retries. Requirement revision may roll into the fixed
global allowance of 16, but changing the state directory or asking for acknowledgement cannot reset
history. MAGI_MAX_AUTONOMOUS_MODEL_LAUNCHES may tighten 12 for a smaller target and cannot extend
it.
原典側にも同等の gate を入れるのが S2/S3 の作業 (= 原典は現在 provenance を一切記録していない)。
Codex 側 provenance は実在する: ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl の
session_meta + turn_context.model (= 実測、 380 files)。
codex-mailbox (= formation mailbox-based、 v0.3.0: per-project channel + spawn options)
options
--codex-pane <tmux-target>: target pane (= e.g.,0:2). defaultauto-detect(= search active codex pane)--mailbox-path <path>: mailbox jsonl path. default~/.formation/mailbox/<project-slug>.jsonl--spawn-via <method>:manual(= require pre-existing pane) /formation(= auto-spawn via formation skill) /none(= fail if not running). defaultmanual--codex-briefing <text>: briefing if spawning, e.g., "Magi reviewer for ". default skill-generated
isolation pattern (= recommended, β)
各 project に 専用 codex pane + 専用 mailbox channel で isolate:
# hippocampus session で初回 bootstrap (= 1 度 manual)
tmux new-window -n codex-hippocampus
codex # = 新 process、 hippocampus session 専用
# 同 session 内で mailbox 別 channel 用意
touch ~/.formation/mailbox/hippocampus.jsonl
# Codex CLI に briefing inject
# (= Codex 起動後 prompt で 「you are reviewer for hippocampus、 listen to ~/.formation/mailbox/hippocampus.jsonl」)
以降 hippocampus session で:
/dual-magi-review ~/projects/hippocampus-mcp/docs/foo.md \
--external codex-mailbox \
--codex-pane 0:3 \
--mailbox-path ~/.formation/mailbox/hippocampus.jsonl
= seq stream / context / state 完全分離、 PRS-LLM session ↔ hippocampus session 干渉ゼロ。
ephemeral spawn pattern (= 都度起動、 γ)
長期 use 不要なら formation skill で 都度 spawn → task 完了で kill:
/dual-magi-review ~/projects/foo/design.md \
--external codex-mailbox \
--spawn-via formation \
--codex-briefing "Magi reviewer, single doc, single round"
skill 内動作:
formation spawn codex --briefing "<briefing>" --mailbox <unique-mailbox>invoke- spawn 完了 ack 受領 → review request 送付
- review 完了後
formation stop <worker-id>で kill - mailbox 該当 entries archive
= task scope 明確、 起動忘れ防止、 resource 効率、 short-lived review に最適。
shared pane pattern (= v0.2.0 default、 deprecated for v0.3.0)
複数 project が 同一 Codex pane + 同一 mailbox 共有:
- seq stream 混在、 subject prefix で識別
推奨しない (= context bleed risk)
v0.3.0 で β / γ を canonical default、 shared pattern は v0.4.0 で削除候補。
request schema (= v0.3.0、 correlation fields 拡張)
{
"mailbox_seq": <int>,
"request_id": "<UUID v4>",
"project_slug": "<prs-llm|hippocampus|...>",
"round": <int>,
"artifact_path": "<absolute>",
"artifact_sha": "<sha256>",
"response_kind": "review",
"expected_count": 4,
"reviewer_id": "<codex-pane-id>",
"perspective": "<keyword>",
"ts": "<ISO 8601 UTC>",
"from": "<sender>",
"to": "<codex pane>",
"subject": "[<project_slug>] dual-magi-review request",
"body": "<request brief>"
}
project_slug で hippocampus / prs-llm / etc を 明示識別、 Codex 側 context 切替 自動化。
ACK / timeout / fallback
- ACK: subject prefix
[ACK]で response 内に echo、 5 min 以内 - response timeout: 60 min for first、 30 min between subsequent
- fallback: internal Magi only、 report に
external-skippedmark - tmux notify: best-effort (= 既)、 mailbox + ACK が source of truth
Codex side responsibility (= NOT Claude skill scope)
- Codex CLI 起動 + briefing 受領
- 指定 mailbox channel polling / tail
- request 受信時 sub-agent spawn + review output
- response の schema compliance (= request_id echo + structured findings)
Codex 側 implementation は別 skill / command (= 「codex-side dual-magi-reviewer」 等) を Codex repository で 維持、 Claude skill は schema + adapter contract only。
webhook (= future)
POST request to URL, sync response with timeout.
shared-file (= future)
write request to shared file, poll for response.
Loop strategy (= multi-round)
Recommended pattern: 1 skill invocation = 1 round, user re-invokes for next.
$ /dual-magi-review docs/foo.md --rounds 3
[round 1 output...]
"continue to round 2? re-invoke with --round 2"
$ /dual-magi-review docs/foo.md --round 2
[round 2 output, includes diff from round 1...]
"continue to round 3? re-invoke with --round 3"
$ /dual-magi-review docs/foo.md --round 3
[round 3 output, mostly nit, recommends ship]
Why not auto-loop:
- single-session context exhaustion (= 4 round × 3 sub-agent × 2K token = 24K context)
- user state visibility in transcript
- external reviewer async wait (= mailbox response may span hours / user session)
State persistence (= .dual-magi/<doc-stem>/、v0.10.1 per-doc namespace):
${magi_dir}/round_<N>.jsonper round findings (= merged、親が write)${magi_dir}/round_<N>_<perspective>.jsonper-reviewer full findings (= v0.10.0、reviewer 自身が Write。perspective label は予約語禁止 — Step 1 参照)${magi_dir}/state.jsonoverall progress- flat 配置 (
${doc_dir}/.dual-magi/直下) は v0.10.0 以前の legacy + magi campaign の 共有域 — 読取りは後方互換で許可、書込み禁止 (clobber 事故防止、Step 1 参照) - gitignore recommended (= meta-state, not artifact)
Failure modes (= troubleshooting)
| symptom | likely cause | resolution |
|---|---|---|
| Task tool fails / timeouts | rate limit / OOM / network | retry budget 1, then mark gap and proceed |
| < 3 sub-agents return | Task tool partial fail | continue with returned, mark report degraded, document in synthesis |
| mailbox write fails | file lock contention | wait + retry once; if still fail, abort external round, internal-only |
| tmux send-keys to dead pane | external pane closed | abort external round, continue internal-only |
| git push reject (= non-FF) | upstream conflict | abort mutation, prompt user git pull manually |
| Edit uniqueness violation | string non-unique in doc | log error, skip this finding's auto-apply, surface to user |
| sub-agent output schema violation | adversarial reviewer formatting | parse best-effort, log as degraded reviewer |
| reviewer file missing / unparseable | reviewer が Write を skip / 途中死 / JSON 壊れ | 返り値 text で synthesize 続行 (= v0.9.0 互換 fallback)、merged json に reviewer_file_missing 記録、retry しない |
| Codex offline (= --external set) | adapter prereq fail | fall back to internal-only, mark external-skipped |
| infinite loop in mutation step | unlikely (= no auto-loop) | user can Ctrl-C, state preserved in .dual-magi/ |
Anti-patterns
| anti-pattern | why bad | instead |
|---|---|---|
| invoking on < 200 line doc | overhead > value | manual review |
--commit-push without dirty-state check |
overwrites user work | review-only default, manual git after |
| auto-loop N rounds in 1 invocation | context exhaustion | per-round invocation pattern |
| using domain preset for unrelated project | preset assumes project-specific context | start with generic presets, add custom |
| treating Magi findings as ground truth | LLM reviewers have shared bias | dual-family OR human expert pass on critical decisions |
| running cross-family at scale without auth | exposes content to external system | check adapter security, scope to non-sensitive docs |
omitting --external then asking why no Codex |
adapter is opt-in | add --external codex-mailbox explicitly |
Cost estimate (= Claude-side only, excludes adapter costs)
| round type | walltime | cost (= LLM) |
|---|---|---|
| internal Magi only (= 3 sub-agent + synthesize) | 20-30 min | $3-5 |
| + cross-family adapter (= mailbox publish + parse reply) | + 5-15 min walltime, external reviewer cost separate | $0-1 (= API cost for mailbox transport) |
| reroll doc (= apply REJECT/HIGH) | 30-60 min | $0 |
| per round total | 30-90 min | $3-6 |
Typical 2-3 rounds: $10-20 Claude-side, plus adapter-specific external cost.
PRS-LLM observed datum (= 4 applications):
- IDENTITY_STRATEGY_V2: 2 rounds, ~5h, ~$15
- CITATION_AUTHOR_NETWORK: 2 rounds, ~5h, ~$15
- dual-magi-review (= self-application): 1 round so far, ~1h, ~$5
- PG_INFRA_HARDENING + provision_pg (= 2026-05-21): R1 (Claude 3 perspective) → R2 (codex cross-family) → R3 (codex on v2) → v4 (= hybrid gate pivot)、 ~4h compound、 ~$25
Empirical patterns (= field observation)
- cross-family round skip 不能: Claude 3 perspective 後 codex round で毎回 2-5 NEW finding (= 3 project 観測)
- 多段 round で framing pivot: 各 round で 1 段抽象高い primitive 発見 (= 例 provision_pg v1→v4: leak surface → atomicity → automation)、 線形 refine ではない
- ship gate = new/total<20%: R1=100%→R2≈20%→R3≈10% で収束、 但し REJECT 残れば次 round 必須、 production minimum = 3 round
- Fable-class reviewer では ratio gate 不発 (= 2026-07-10 company-shared-hippocampus 実測): 41 round 回しても毎 round 3-7 findings (全部 grounded、 捏造でない)、 new-vs-dup ratio が閾値を切らない。 加えて revision churn (= r34 の fix が r35 の CRITICAL drift になる) で REVISE↔GO-WITH-REVISE を往復。 → severity-gated terminal (= stop criteria 5) + round budget + diff-scoped re-review が対応 rail
Related skills
/simplify: small-diff code/doc review (= subset of single-perspective)formation: spawn long-running peer AI worker in tmux pane (= alternative transport for external reviewer)Tasktool directly: single-perspective review for small artifacts
Limits
- Same architecture bias: same-family Magi shares pre-training data; cross-family partially mitigates
- No human domain expert: medical / legal / engineering require domain-specific human review for critical decisions
- Doc artifact only: static text review; live system / db inspection out of scope
- External coordination cost: cross-family requires adapter setup + external system alive
- Endless abstraction guard: each round may erase useful project-specific constraints — review for over-generalization
Reference material (= optional, project-specific)
PRS-LLM-dev project internal memory pointers (= may not exist in other projects):
feedback_dual_magi_iterative_review(= this pattern's experience log)feedback_4_parallel_agents_disjoint_files(= 4-parallel agent pattern, related)feedback_magi_v1_review_process(= original Magi v1 single-family pattern)feedback_agentshield_independent_scan(= santa-method dual independent reviewer principle, parent)feedback_mailbox_ack_required_with_double_enter(= mailbox adapter detail)
These are not prerequisites for skill function. Pattern is self-contained in this SKILL.md.
Revision history
| date | version | change |
|---|---|---|
| 2026-07-30 | 0.11.1 | Activation review fixes — built-in freerange label の予約語例外を明文化、merged artifact に freerange digest/severity counts を追加、round 1 を含む 12-launch 算術を修正、disputed blocker を HOLD_DISPUTE 化、RETIRE を人間確認必須の advisory に限定 |
| 2026-07-28 | 0.11.0 | Optional free-range reviewer (claude-harness#233 slice ②) — round 2+ の --freerange で checklist-free reviewer を追加 4 体目として起動。per-doc file contract、≤200-word receipt、Step 6 severity-gated terminal、12-launch 散文予算、非同期 verification.json sidecar、3-campaign retirement SQL を追加。companion mechanical gate / persona set / fanout CLI は不変 |
| 2026-05-14 | 0.1.0 | Initial skeleton |
| 2026-05-14 | 0.3.0 | Isolation pattern canonical化、 user feedback 「session 濁る」 反映:- adapter codex-mailbox に --codex-pane / --mailbox-path / --spawn-via options 追加- β isolation pattern (= 専用 pane + 専用 mailbox channel) を recommended default- γ ephemeral spawn pattern (= formation skill 経由 都度 spawn / kill) 追加- shared pane pattern (= v0.2.0 default) deprecated、 v0.4.0 で削除候補- request schema に project_slug 追加 (= context 切替明示)- Codex side responsibility 明示 (= skill scope 外、 Codex repo で別 implement) |
| 2026-05-21 | 0.4.0 | Empirical patterns 3 件追加 (= 2026-05-21 PG hardening session 観測): (1) cross-family round skip 不能 (2) design pivot 連鎖 (3) ship gate = new/total<20%。 cost datum 4 件目 (= provision_pg ~4h ~$25) |
| 2026-05-22 | 0.5.0 | Schema-grounding mandate を Step 2 sub-agent prompt template に baked-in (= 5/22 PRS-LLM ADR-TPN v0.1 incident 学習)。 AI 自起草 doc の 妄想 column / hallucinated schema を front-load catch、 全 sub-agent が必ず psql \d + grep migrations/core/api で table.column 実在 verify + populate state + 既存 code 挙動 premise drift を CRITICAL finding 化。 memory feedback_design_doc_schema_grounding_required の structural 上位対応、 behavioral rule から skill skeleton への昇格 |
| 2026-05-22 | 0.5.1 | Reviewer verify_commands_executed MUST-emit 追加 (= 5/22 ADR-TPN v0.2 dual-magi v3 で MELCHIOR LOW #3 finding 即対応、 gh #194)。 v0.5.0 hook efficacy が anecdotal (= reviewer の self-report) だった問題を、 各 reviewer の output JSON に 実行 command 完全 list を MUST 含む で measurable 化。 空 list or generic Read のみ = schema_grounding_verdict FAIL 自動判定、 round 全体が degraded mark。 user instruction「N+1 回目を待たない、 100 回叩く前に構造で先回り」 の literal application、 incident → memory → skill skeleton → output-format-mandate の 4 段 escalation 完了 |
| 2026-05-22 | 0.6.0 | Cross-family default mandatory (= gh #195 incident 学習)。 v0.5.x までは --external opt-in flag、 同日 citation pipeline refactor v0.5 で 4 Claude same-family round plateau CONFIRM 4.3/4.5/4.8 到達後 Codex 1 round REJECT 1/5 + 6 NEW CRITICAL (= Claude 全 round 全 miss、 production-shape dict drift / paradigm 矛盾 / GLOBAL rewrite span 等)。 root cause = memory feedback_dual_magi_mandatory_for_scripts mandate と skill default の乖離、 私 (= AI) が flag 忘れて skip。 structural fix 3 点: (1) --external default = codex-exec adapter で auto final round (= zero-config sync invocation、 codex exec --skip-git-repo-check -)、 (2) plateau CONFIRM declaration block until cross-family round recorded、 (3) cross-family REJECT/CRITICAL → final verdict 優先 overrule Claude CONFIRM。 --no-cross-family <reason> opt-out は valid reason 限定 (= quick-iteration / non-design-artifact) + telemetry audit。 memory feedback_dual_magi_mandatory_for_scripts の behavioral rule を skill default に焼付け、 私 (= Claude) の self-discipline failure を structural rail で先回り。 v0.5.0 schema-grounding と同 escalation pattern (= behavioral → skill skeleton)、 incident → memory → skill default の 3 段昇格 完了 |
| 2026-07-10 | 0.7.0 | Severity-gated terminal + runaway guard (= company-shared-hippocampus 41-round run 学習)。 Fable-class reviewer は zero-findings に到達しない (実測: 41 round × 3-7 findings/round、 全部 grounded) ため ratio gate (= criterion 1) が不発、 加えて revision churn (= fix が次 round の CRITICAL になる) で verdict 往復。 structural fix: (1) stop criteria 5 = invariant を破る NEW CRITICAL/HIGH なし → converge、 MED/LOW は DEFERRED.md 行き (doc revision しない)、 (2) round 5 altitude checkpoint / round 8 hard stop、 (3) diff-scoped re-review、 (4) enumerable detail の prose 列挙は altitude 違反 → executable gate 化。 ultramagi v0.2.0 § Convergence economics と対 |
| 2026-07-28 | 0.10.1 | Per-doc state namespace (= v0.10.0 初実戦 incident 学習)。${doc_dir}/.dual-magi/ flat 配置は同 dir の他 doc + magi campaign と共有で、REVIEW_FLOW_PORT round 1 実走時に旧 campaign の merged round_1/2.json + state.json を clobber (per-persona 生存 file から reconstructed mark 付きで再構成済)。fix: 全書込みを ${magi_dir} = ${doc_dir}/.dual-magi/<doc-stem>/ に namespace 化、flat 域は読取り専用 legacy 扱い、Step 1 に事前 ls 確認を追加 |
| 2026-07-28 | 0.10.0 | Reviewer file-return contract (claude-harness#218) — 実測 (2026-07-28): reviewer の Task 返り値 30-43k chars × 3 並列 × 最大 8 round が session 肥大 tool_result の最大単一クラスで、multi-round campaign では数百 k chars が context に居座り全 turn で cache read され続けていた。structural fix: (1) reviewer は full findings JSON を round_<N>_<perspective>.json に Write してから return、返り値契約 = ≤200 words receipt (path + verdict + severity 件数 + 上位 3 title)、(2) 親は file 実在 + JSON parse 検証、欠落時は返り値 fallback で synthesize 続行 (= v0.9.0 後方互換、retry なし)、(3) synthesize 入力は per-reviewer file の jq projection Read (verify_commands_executed は件数のみ)、(4) merged round_<N>.json は維持 + reviewer_files 配列追加、(5) perspective label 予約語禁止 (melchior/balthasar/caspar/hornet/gnat/wasp/codex/xfamily = magi_campaign_guard.py の companion 完了判定 file 名と衝突)。期待効果: prior round の 3×30-43k 返り値が context に残らず compact merged json (2-3KB) だけ再流入、reviewer 出力も構造化 JSON 強制で ~60-70% 減 |
| 2026-07-21 | 0.9.0 | Headroom-aware reviewer tier (capacity-oracle #92 / claude-harness#97) — before spawning the Claude×3 same-family reviewers, consult capacity-oracle substitute -q '.keep' (fail-open if the CLI is absent). When Claude is below the offload floor (hot), downgrade the same-family reviewers opus→sonnet (explicit tier, not inherited fable); review quality is carried by multi-perspective + the mandatory Codex cross-family round, not child tier. The Codex cross-family round is never thinned (Codex rarely exhausts). |
| 2026-07-21 | 0.8.0 | Drift reconciliation (#98) — installed live 0.7.0 (opus-pin, severity-gated terminal) had never been committed to source, while source had independently gained the Family routing policy section and the plateau-gate script count grew G7→G9. Merged into one canonical superset (installed 0.7.0 as base + source-only routing section + G9 fix), re-established source as SoT. No behavior removed from either side. |
| 2026-05-14 | 0.2.0 | Round 1 dual-Magi review applied (= 12 findings consolidated from Claude Magi v1-1/2/3 + Codex Magi v1-1/2/3 + Codex synthesis). Key changes: - Tool name: Agent → Task (= Anthropic CLI canonical) - Mutation opt-in (= review-only default, --apply-local / --commit-push flags) - 1 invocation = 1 round pattern (= no in-skill loop, user re-invokes) - Structured finding schema (= 10 fields) - Standardized correlation fields (= request_id UUID + artifact_sha + round + response_kind + expected_count) - Adapter abstraction (= cross-family transport pluggable; codex-mailbox / webhook / shared-file) - Domain presets extracted to examples/ - Anti-patterns + Troubleshooting sections (= per formation template) - Compressed description for skill-list rendering - EN trigger keywords added - Memory references demoted to optional reference material - Created feedback_dual_magi_iterative_review.md memory (= dead reference fix) - Self-application: this v0.2.0 is the recursive output of v0.1.0 reviewed by the pattern it codifies |