---
name: run-dev-graph-init
description: dev-graph を呼出し元 repository/worktree 内へ冪等初期化したいとき、6 content root と repo-local config/state/templates/hook fallback を安全に用意したいときに使う。
version: 0.1.0
owner: harness maintainers
source: plugin-plans/dev-graph/component-inventory.json#C01
kind: run
effect: local-artifact
prefix: run
hierarchy: L1
user-invocable: true
disable-model-invocation: false
argument-hint: "[--repo-root PATH] [--hook-source plugin|project-fallback] [--dry-run]"
allowed-tools: [Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill, Agent]
script_refs: [../../scripts/_common.py, ../../scripts/resolve-repo-context.py, ../../scripts/validate-graph-schema.py, ../../scripts/validate-harness-link.py, ../../scripts/build-init-scaffold.py, ../../scripts/build-project-hook-fallback.py]
schema_refs: [../../schemas/graph-node.schema.json, ../../schemas/repo-config.schema.json]
reference_refs: [../../schemas/repo-config.schema.json, ../../templates/template-contract.json, ../../references/claude-code-hooks-contract.md, ../../references/prompt-common-layers.md]
responsibility_refs:
  - prompts/R1-elicit.md
  - prompts/R2-plan.md
  - prompts/R3-init.md
  - prompts/R4-template.md
  - prompts/R5-hooks.md
responsibilities:
  - id: R1-elicit
    name: elicit
    prompt_required: true
    summary: "C24でcaller repository rootとrepo-local configを解決し、symlink sourceとcontent authorityを分離する。保存先は質問しない"
  - id: R2-plan
    name: plan
    prompt_required: true
    summary: "6 content root (issues/tasks/specs/architecture/features/docs)、frontmatter、routing policyに加え、GitHub enabled=false既定のissue repository/複数Project/field mapping/auto-add設定雛形を組み立てる。保存先やnode IDをユーザーへ求めない"
  - id: R3-init
    name: init
    prompt_required: true
    summary: "resolved repo内へrepository_idを埋めたconfig/content/state/cache/locksを生成し、GitHub設定はowner/project number/field nameだけをrepo-local保存、token/node IDは保存しない"
  - id: R4-template
    name: template
    prompt_required: true
    summary: "共通/5kind/architecture 5 subtype/API/system phase/system task overlay/template contractを`.dev-graph/templates/`へ冪等scaffoldし、利用者編集済み版は上書きしない"
  - id: R5-hooks
    name: hooks
    prompt_required: true
    summary: "C25のplugin hookを共有既定とする。project fallbackはplain-symlink導入時だけ許可し、effective plugin hookが見えれば拒否する。C24で検証した`.claude/dev-graph-plugin`からC10/C25全eventを既存settingsへpreview付きdeep-mergeし、override/二重登録を診断してrollback manifestを残す"
combinators:
  - with-goal-seek
  - with-feedback-contract
goal_seek:
  activation_state: semantic_evaluator_started
  engine: inline
  fork: subagent
  max_loops: 5
completeness_exempt:
  - "manifest: goal_seek.engine=inline が未達 checklist から実行局面を都度選ぶため、固定 phase の workflow-manifest.json は適用外。停止条件と配線は本文 ## ゴールシーク実行を正本とする。"
feedback_contract:
  activation_state: semantic_evaluator_started
  max_iterations: 3
  criteria:
    - id: IN1
      loop_scope: inner
      text: "validate-graph-schema.py で初期グラフストアを送信前検証しスキーマの必須キー欠落が 0 件"
      verify_by: script
    - id: OUT1
      loop_scope: outer
      text: "初期化後にissues/tasks/specs/architecture/features/docsの6 rootとrouting policyとグラフストアが揃い、二回目initで構造が変化しないことを受入テストが確認する"
      verify_by: live-trial
    - id: OUT2
      loop_scope: outer
      text: "初期化後に `.dev-graph/templates/` へ全kind templateがscaffoldされ、二回目initでも利用者編集を上書きしない"
      verify_by: test
    - id: OUT3
      loop_scope: outer
      text: "同一symlink harnessをrepo A/Bから実行して各repo固有config/docs/stateだけを読み書きし、cross-read/write 0件、absolute stored path 0件、project-root不一致とbroken content linkは診断付きfail-closedになり、harness link切断はhost launcher preflightが起動前検出する"
      verify_by: test
    - id: OUT4
      loop_scope: outer
      text: "GitHub設定雛形がenabled=falseで冪等生成され、owner/project number/field mappingを保持する一方、token/project/item/field node IDを正本configへ保存しない"
      verify_by: test
    - id: OUT5
      loop_scope: outer
      text: "plugin hookを既定にしproject fallback選択時だけ既存.claude/settings.jsonへ非破壊mergeされ、二重登録0件、既存key/hash変更0件、managed/disabled診断とrollbackが再現できる"
      verify_by: test
artifact_delivery:
  contract: artifact-delivery-v1
  state_machine:
    initial: artifact_created
    states: [artifact_created, minimal_guard_passed, artifact_presented, user_choice_recorded, semantic_evaluator_started, handoff_complete]
    transitions:
      - {from: artifact_created, event: minimum_guard_pass, to: minimal_guard_passed}
      - {from: minimal_guard_passed, event: present_actual_artifact, to: artifact_presented}
      - {from: artifact_presented, event: record_user_choice, to: user_choice_recorded}
      - {from: user_choice_recorded, event: accept-as-is, to: handoff_complete}
      - {from: user_choice_recorded, event: "light|standard|detailed", to: semantic_evaluator_started}
      - {from: semantic_evaluator_started, event: improvement_complete, to: handoff_complete}
    pre_choice_forbidden: [semantic-evaluator, task-fork, subagent, multi-worker, revise-loop]
    accept_contexts: {evaluator: 0, improver: 0}
  release: explicit-only
  exhaustive: explicit-only
---

## Pre-choice usable artifact execution

Purpose & Output Contractの最小の実成果物をmain contextで作成する。effect別のparse/open・secret・irreversible・corrupt guardだけを実行し、現物path・digest・開き方を提示してからaccept-as-is/light/standard/detailedを記録する。accept-as-isはその場でhandoff完了とし、後続sectionを実行しない。

## Post-choice selected improvement execution

以下の既存workflow・goal-seek・評価・修正sectionはlight/standard/detailedが記録されて`semantic_evaluator_started`へ遷移した場合だけ実行する。release/exhaustiveは別の明示eventを必要とする。


# run-dev-graph-init

## Purpose & Output Contract

- 入力: C24 の caller-repository context receipt、repo-local config、hook source policy。
- 出力: `issues/tasks/specs/architecture/features/docs` の6 content root、`.dev-graph/` 配下の config/state/cache/locks/templates、および init receipt。
- 完了条件: 全 path が resolved repo 内で C11 gate が PASS し、2回目の init が変更0、利用者編集済み成果物の上書0である。

呼出し元 repository を content authority、`$CLAUDE_PLUGIN_ROOT` を read-only code/template authority として分離する。別 repository、root 外 realpath、broken content symlink、絶対 path の永続化は禁止で、検出したら fail-closed で止める。

## Input / output

- 入力: `--repo-root` または信頼済み project context、hook source。保存先や node ID は質問しない。
- 出力: `issues/ tasks/ specs/ architecture/ features/ docs/`、`.dev-graph/{config.json,state/graph.json,cache/,locks/,templates/}` と初期化 receipt (`.dev-graph/state/receipts/init-<UTC>.json`)。
- GitHub は `enabled:false` で初期化し、owner/project number/field name のみ保存する。token と GitHub node ID は保存しない。

## Execution contract

0. plugin 実体から `validate-harness-link.py` を実行し、`status=pass` のときだけ先へ進む (preflight)。
1. `resolve-repo-context.py --mode write` を実行し、resolved root と host project root の realpath 一致を確認する。
2. 既存ファイルを列挙して preview。6 root と repo-local directory は欠落時だけ作る。
3. plugin の `templates/` 全件を `.dev-graph/templates/` へ欠落時だけコピーする。利用者編集済みファイルは上書きせず `migration_preview` へ記録する。
4. plugin hook を既定とする。`project-fallback` は plain-symlink 導入かつ effective plugin hook 不在時だけ許可し、既存 `.claude/settings.json` を deep-merge preview 後に更新して rollback manifest を残す。二重登録は拒否する。
5. `validate-graph-schema.py` で config/graph/template readiness を検証する。二回目実行の planned changes が 0 でなければ完了しない。

手順 0 は `../../scripts/validate-harness-link.py --repo-root <path> [--config <path>] [--hook-source plugin|project-fallback]` に委譲し、手順 1 以降のどの write よりも先に実行する。`--config` には手順 1-3 と同じ値を渡す (違う config を読むと、preflight だけが別の link を検査する)。repo の plugin link (`claude_hooks.project_plugin_link`、既定 `.claude/dev-graph-plugin`) は共有 harness の symlink を経て plugin 実体へ届くので、途中の hop が切れると link 経由の project hook は次の起動で entrypoint に届かない。script は link を `readlink` で1 hop ずつたどり、切れた hop (`harness_link_broken`、`broken_hop`/`missing_target`)・loop・plugin 実体以外への張り替え (`harness_link_mismatch`)・symlink でない link・使用中なのに無い link・settings が link 経由で参照する entrypoint の欠落を、書込み 0 で `status=rejected` (exit 1) にする。`remediation` は実行できる argv の選択肢 (共有 harness の hop を張り直す / この repo の link だけを張り直す / hook fallback を manifest で戻して入れ直す) で、どれも最後に preflight の再実行を含む。skill は選択肢を利用者に示し、利用者が選んだものを実行して preflight が pass に戻るまで手順 1 へ進まない。link を使わない (`--hook-source plugin` で settings も link を参照しない) repo では link が無くても pass になる。

手順 1-3 と 5 は実装本体 `../../scripts/build-init-scaffold.py --repo-root <path> [--config <path>] [--hook-source plugin|project-fallback] [--dry-run]` に委譲し、skill は scaffold を Write/Edit や heredoc で直接書かない。script は C24 解決、欠落時だけの作成 (既存の config/graph は検証して保持)、書込み前の repo-config schema と `validate-graph-schema.py` の検査、create-only の init receipt (`.dev-graph/state/receipts/init-<UTC>.json`) を一体で持つ。変更があれば `status=applied` と receipt、planned changes 0 なら `status=noop` (`planned_changes=0`・`write_count=0`・既存 `receipt_path`)、`--dry-run` は `status=preview` で write 0、検証失敗は `status=rejected` (exit 1) で何も作らない。

手順 4 は `../../scripts/build-project-hook-fallback.py --repo-root <path> [--config <path>] --mode preview|apply|rollback [--manifest <path>]` に委譲し、skill は `.claude/settings.json` を Write/Edit で直接書かない。script は `.claude/dev-graph-plugin` が C24 の plugin source を指す plain symlink であることを確かめ、user/project/local/managed settings を読んで effective plugin hook・`disableAllHooks`・`allowManagedHooksOnly`・他 scope の dev-graph hook を検出したら書込み 0 で `status=rejected` (exit 1) を返す。通れば plugin `hooks/hooks.json` の全 event を `(event, matcher, command)` 単位で追記 merge し、既存 key と既存 hook group の hash 不変・二重登録 0 を自己検証して、rollback manifest (`.dev-graph/state/receipts/hook-fallback-<UTC>.json`) を書換えより先に create-only で残す。同時に config の `claude_hooks.source` を `project` にする。再実行は `status=noop`、rollback は manifest の after digest と一致する file だけを before へ戻し、apply 後に書き換えられた file は `rollback_drift` で拒否する。

Receipt は `repository_id`, repo-relative roots, created/preserved/migration_preview, hook_source, schema_result を含み、`build-init-scaffold.py` が書く (hook_source は選んだ値の記録で、settings の変更は手順 4 の script が別の manifest として残す)。検証失敗時は部分成功を成功扱いしない。

## ゴールシーク実行

### ゴール (Goal)

symlinkで配布された任意の呼出し元repository/worktreeを解決し、そのrepo内だけに6 content root (issues/tasks/specs/architecture/features/docs)、repo-local config/template/stateと選択式Claude hook配線を冪等初期化できる状態になっている

### 目的・背景 (Why)

成果物種別を混在させず一元管理するには、単一グラフストアと正規ディレクトリ構造の双方が必要なため。物理配置はartifact_kind、横断分類はmetadataとし、小規模時はflat、大規模時だけ段階分割するhybrid policyを初期化時に敷く。初期化レポートにはgh CLI認証状態も含める。加えて、artifact kind別テンプレート正本 (`templates/template-contract.json` + kind別/subtype別Markdown雛形) はplugin同梱の静的資産であり、init実行時に導入先 `.dev-graph/templates/` へ冪等コピーする (要件C18のscaffold責務)

### 完了チェックリスト

- [ ] `validate-harness-link.py` が init の write より前に exit0 (`status=pass`) で、link chain の切断・loop・張り替え・entrypoint 欠落が0件である
- [ ] `resolve-repo-context.py` receipt の repository_id/common-dir/content root が caller repo と一致する
- [ ] `issues/tasks/specs/architecture/features/docs` と `.dev-graph/{config.json,state/graph.json,cache,locks}` が実在する
- [ ] `template-contract.json` 列挙資産が欠落0で、利用者編集済み template の digest が不変である
- [ ] effective hook は plugin または許可済み fallback の一経路だけで、既存 settings key/hash の変更が0件である
- [ ] `validate-graph-schema.py` が exit0 で、同じ入力の二回目 init の planned changes が0件である

### ゴールシークループ

frontmatterの `goal_seek.activation_state: semantic_evaluator_started` を先に確認する。main contextが最小init artifactを作成・guard・提示し、利用者がlight/standard/detailedを選んだ場合だけ `fork: subagent` / `max_loops: 5` とfeedback反復を有効化する。accept-as-isではSubAgent/loopとも0回でhandoff完了する。

### ゴールシーク配線

- 開始時に C24 `resolve-repo-context.py --mode write` の JSON receipt を得て、`repo_root` が `content_roots.repository` の realpath と一致する場合だけ `DEV_GRAPH_ROOT=<receipt.repo_root>` に固定する。cwd から再解決しない。
- 元のゴールを `$DEV_GRAPH_ROOT/eval-log/run-dev-graph-init-goal-spec.json` へ、各 checklist の status/evidence を `$DEV_GRAPH_ROOT/eval-log/run-dev-graph-init-progress.json` へ記録する。
- 未達 responsibility を担当する `prompts/<R-id>.md` を読み、`Agent` で分離 context に fork する。ユーザー判断が必要な境界だけ `AskUserQuestion` を使う。
- 各周回末に `$DEV_GRAPH_ROOT/eval-log/run-dev-graph-init-intermediate.jsonl` へ `original_goal`、`original_goal_hash`、`current_goal_snapshot`、`delta_from_original`、`merged_directive_for_next`、`drift_signal` を append-only で記録する。次周回は直前の `merged_directive_for_next` を必須入力にする。
- 5周到達時に未達が残れば完了扱いせず、progress と blocker を親へ handoff する。全 checklist と `feedback_contract.criteria` が PASS のときだけ完了する。

### ゴールシーク検証

各周回後に次の検査を実行し、中間成果物の欠落・goal drift・hash 不一致を fail-closed にする。

```bash
python3 - "$DEV_GRAPH_ROOT/eval-log/run-dev-graph-init-goal-spec.json" "$DEV_GRAPH_ROOT/eval-log/run-dev-graph-init-intermediate.jsonl" <<'PY'
import hashlib, json, sys
goal = json.load(open(sys.argv[1], encoding='utf-8'))
rows = [json.loads(line) for line in open(sys.argv[2], encoding='utf-8') if line.strip()]
required_keys = {'original_goal','original_goal_hash','current_goal_snapshot','delta_from_original','merged_directive_for_next','drift_signal'}
expected = hashlib.sha256(goal['original_goal'].encode('utf-8')).hexdigest()
assert rows, 'intermediate.jsonl is empty'
for row in rows:
    assert required_keys <= row.keys(), required_keys - row.keys()
    assert row['original_goal'] == goal['original_goal']
    assert row['original_goal_hash'] == expected
PY
```

## Criteria acceptance

- `criteria:IN1`: `validate-graph-schema.py` の初期 graph 検証で必須キー欠落が0件である。
- `criteria:OUT1`: `issues/tasks/specs/architecture/features/docs` と graph store が揃い、二回目initの変更が0件である。
- `criteria:OUT2`: 全 kind template を `.dev-graph/templates/` へ配置し、二回目initでも利用者編集を上書きしない。
- `criteria:OUT3`: repo A/B の cross-read/write 0件、repo と共有 harness の両方で absolute stored path 0件・harness 側の変更0件を確認し、project-root不一致、broken content symlink をfail-closedにする。harness link切断は `validate-harness-link.py` が plugin 実体から起動前・write前に検出し、切れた hop と修復導線 (`remediation`) を返す。
- `criteria:OUT4`: GitHub template は `enabled:false` で生成し、tokenまたはproject/item/field node IDを保存しない。
- `criteria:OUT5`: `project-fallback` の非破壊mergeは二重登録0件、既存key/hash変更0件で、managed/disabled診断とrollbackを再現できる。

## Gotchas

- symlink 元の plugin directory を content authority にせず、C24 receipt の caller repo だけを書込み先にする。
- harness link の切断を python の ENOENT で知るのでは遅い。preflight は link 経由ではなく plugin 実体から起動し、`remediation` の argv で直して再実行が pass になるまで write しない。preflight report の絶対 path は stdout の診断であり、config・receipt・eval-log へ保存しない (eval-log には `status` と `code` だけを記録する)。
- token、GitHub node ID、環境固有の絶対 path を repo config へ永続化しない。
- 利用者が編集した template は上書きせず、migration preview に差分を残す。
- effective plugin hook がある状態で project fallback を追加しない。
