Metadata-Version: 2.4
Name: norn-cli
Version: 0.12.0
Summary: Norn: a provider-neutral multi-agent development harness
License-Expression: Apache-2.0
Project-URL: Repository, https://github.com/uruca-kk/norn
Project-URL: Issues, https://github.com/uruca-kk/norn/issues
Project-URL: Changelog, https://github.com/uruca-kk/norn/blob/main/CHANGELOG.md
Keywords: agents,cli,codex,claude,testing
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML>=6.0
Requires-Dist: jsonschema>=4.10
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == "dev"
Requires-Dist: ruff<0.16,>=0.15; extra == "dev"
Dynamic: license-file

# Norn

ローカルのサブスクリプション認証型 CLI を利用する、プロバイダー非依存のマルチエージェント開発ハーネスです。名前は運命を紡ぐノルンに由来し、独立したエージェントを、上限が定められた成果へ向けて協調させます。

> ステータス: ベータ。`norn-cli` ディストリビューションは PyPI で公開していますが、ソースリポジトリはベータ期間中は非公開です。

Norn は Codex、Claude Code、Grok Build、および将来のコマンドベースのサブスクリプション CLI に対し、設定、CLI、実行状態、イベントジャーナル、復旧、人間が読めるエスカレーションレポート、プロバイダー非依存アダプター、実行可能なマルチロール開発パイプラインを提供します。

```bash
norn init
norn --version
norn doctor
norn validate-config
norn providers
norn models init
norn models list
norn verify plan --no-agent
norn verify run
norn plan "監査ログを追加する"
norn run "監査ログを追加する"
norn run "認証データを安全に移行する" --team auto
norn recover <run-id>
norn continue <run-id> --execution <execution-id>
```

`plan` と `run` はすぐに Run ID を表示し、追記専用のライフサイクル進捗を stderr へストリーミングします。表示されるのは現在のフェーズ、上限付きのラウンド数、ロールの開始と完了、ローカルゲート、E2E、品質判定、最終結果です。プロンプトやモデルの非公開推論は表示しません。ライフサイクル状態とイベントは `.norn/runs/state.sqlite3` へトランザクションとして記録され、各実行の `manifest.json` と `events.jsonl` に投影されます。自動化で stderr のライブ表示だけを抑制するには `--no-progress` を使用してください。

新規プロジェクトは設定と実行状態に `.norn` を使用します。古い Norn リリースで初期化されたリポジトリは、明示的に移行するまで状態を分割せず `.norf` を使い続けます。

```bash
norn migrate --project /path/to/repository
```

移行では終了済みの実行記録を保持し、同梱設定の `.norf/runs` 値を更新します。`.norn` と `.norf` の曖昧な共存、実行中のラン、シンボリックリンク、既存の detached worktree がある場合は拒否します。再試行する前に、ランを完了または復旧し、登録済み worktree を削除してください。ユーザーレベル設定に `paths.runs_dir: .norf/runs` が明示されている場合は、先にその共有設定を更新してください。

Codex と Claude Code の両方に、明示的に呼び出す同梱 Skill をインストールできます。

```bash
norn install-skill --target all --scope project --project /path/to/repository
```

Codex 用には `.agents/skills/norn`、Claude Code 用には `.claude/skills/norn` が作成されます。Codex では `$norn`、Claude Code では `/norn` を使用します。ユーザーレベルへ片方だけインストールする場合は `--target codex|claude --scope user` を指定してください。既存コピーを意図的に置き換える場合に限り `--force` を使用します。Skill を読み込むだけでは、ユーザーが `plan` または `run` を明示的に依頼しない限り、モデルを消費するライフサイクルは始まりません。

PyPI から `uv tool`、`pipx`、仮想環境へ分離インストールする方法は、[インストール手順](docs/installation.md)を参照してください。

`plan` はオーケストレーション、計画、計画レビューを実行します。`run` はさらに、実装、言語に応じたローカルテストと lint、テスターロール、トリアージ、最終ゲートまで進みます。テスターロールは、すべてのローカルプロジェクトゲートが成功した後にのみ開始します。ゲート失敗は直接トリアージと再実装へ戻り、ゲートを実行できない場合はテスト基盤障害として停止します。UI 変更には検証済みの E2E 実行が必要です。推奨方式はリポジトリ所有の managed runner です。従来ポリシーでは、各テスターに独立した E2E 実行を要求することもできます。必要な各結果には、実行した argv、終了コード、簡潔な結果要約、割り当てられた証跡ディレクトリ内の空でない成果物が少なくとも1つ必要です。Norn は欠損、古い、シンボリックリンク、またはディレクトリ外の証跡を拒否し、受理したファイルを `.norn/runs/<run-id>/artifacts/e2e/` に保管します。

トリアージが再実装を要求すると、Norn は各プロバイダー試行の前後で Git ワークスペースのフィンガープリントを取得します。追跡対象の内容やモードにも、ignore されていない未追跡ファイルにも変更がない試行は `implementation.noop` として記録され、ローカルゲート、テスターロール、E2E を再実行する前に拒否されます。既存のプロバイダー再試行とフォールバックの上限が適用され、次の試行には no-op の診断情報が渡されます。要求された動作がすでに存在する場合、最初の実装が正当な no-op になることはあります。

以前に承認された計画を、オーケストレーション、計画、計画レビューを再実行せず実装するには、同一の依頼文とともに成功した `plan` の Run ID を渡します。

```bash
norn plan "監査ログを追加する"
norn run "監査ログを追加する" --from-plan <plan-run-id>
```

Norn は実装用 worktree を作成する前に、元ランのモードと状態、プロジェクトルート、依頼文、保存済み成果物のスキーマを検証します。

Codex のテスターロールでは、アダプターは `workspace-write` のファイルシステム分離を維持し、ループバック限定のプロキシ許可リスト（`localhost` と `127.0.0.1`）を通じてコマンドのネットワーク通信を有効にします。計画ロールと実装ロールは、通常どおりネットワーク無効のポリシーを維持します。

Docker を利用するテストでは、ホストの Docker API ソケットへのアクセスも必要です。1回のランに対して明示的に許可してください。

```bash
norn run "タスク" --allow-tester-host-services
```

このフラグは `DOCKER_HOST`、アクティブな Docker context、または検出した rootless、Docker Desktop、システム既定のソケットからローカル Docker Unix ソケットを解決し、そのソケットだけを Codex TEST 呼び出しの書き込み可能ルートへ追加します。リモート TCP Docker エンドポイントはファイルシステムルートへ追加しません。このフラグはワークスペースのサンドボックスを解除せず、生の TCP クライアントがホストのループバックに bind されたサービスへ到達できることも保証しません。Docker ソケットへのアクセスは実質的にホスト制御を委譲するため、信頼できるリポジトリでのみ使用してください。解決したパスとオプトインはランの manifest とレポートに記録されます。

並列ブラウザーテスター向けに、共有するループバック URL を1つ設定します。プロジェクトローカルの開発サーバーでは、シェルを介さないコマンドも指定します。

```yaml
e2e:
  base_url: http://127.0.0.1:4173
  server:
    command: [pnpm, --filter, "@trato/marchant-admin", dev, --host, "127.0.0.1", --port, "4173", --strictPort]
    startup_timeout_seconds: 30
  tcp_forwards:
    - {listen: 4173, to: "127.0.0.1:4173"}
```

Norn は実装後にコマンドを開始し、URL の準備完了を待ち、すべてのテスターロールへ Vite を起動せず再利用するよう指示し、最後に必ず停止します。すでに起動中の Docker または外部 Web サーバーを再利用する場合は `server.command` を省略します。外部サーバーは一度だけ確認し、Norn は停止しません。`tcp_forwards` は、Norn ホストのループバックに bind されたサービスの明示的な許可リストです。各 E2E コマンドに対し、Norn はそのコマンドのサンドボックス内だけで listen し、ラン固有のファイルスプールを介してホストリレーとバイトストリームを交換する Python argv ラッパーを渡します。ホストは、宣言済みポートに対する厳密な名前の通常ファイル要求だけを受け付けます。listen ポートの重複、ループバック以外の転送先、未宣言のホストポートは拒否されます。ランタイムファイルはモード `0700` の一時ディレクトリに収められ、テスト終了時に削除されます。

配布可能なプロジェクトでは、モデルへブラウザー権限やホスト権限を与えるより、レビュー済みでリポジトリ所有の E2E コマンドを推奨します。

```bash
# 検出された1つの Playwright/Cypress スイートへ適合させます。これは dry run です。
norn init-e2e --adapter existing --project /path/to/repository

# または、選択した workspace package に新しい Playwright エントリーポイントを生成します。
norn init-e2e --preset playwright --package packages/web --project /path/to/repository

# または、Playwright を使わない決定論的な Agent Browser smoke runner を生成します。
norn init-e2e --preset agent-browser --package packages/web --project /path/to/repository
```

`init-e2e` は npm、pnpm、yarn、bun、および一般的な E2E スクリプトや設定を検出します。リポジトリを変更せず、対象ファイル、最小限の Norn YAML、証跡上限、任意の `git.worktree_setup` copy ステップを表示します。確認後に `--write` を追加してください。すでに起動中の Docker または外部サーバーには `--external-server` を、プロジェクトのスクリプトが `dev`、`start`、`serve` ではない場合は `--server-script NAME` を使用します。`--base-url` はループバック HTTP(S) URL でなければなりません。

既存スイート用アダプターは、リポジトリ所有の runner を生成します。Playwright の場合は既存設定を拡張しつつ `webServer` を無効化する小さな設定も作り、サーバー所有者を Norn だけに保ちます。Playwright preset はさらに、上限付き証跡ヘルパー、smoke spec、JSON reporter、少量の成果物を既定とする設定を作成します。`--install-dependency` と `--write` を明示的に組み合わせない限り、Playwright はインストールしません。既存のフレームワークバージョンと fixture はプロジェクトの所有物として維持されます。

`agent-browser` preset は代わりに、安全なラッパーとユーザー所有の `tests/e2e/norn-agent-browser.json` に記述する、シェルを介さないコマンドシーケンスを生成します。各ランは分離セッションとループバック限定のドメイン許可リストを使用し、設定 URL を開き、アクセシビリティスナップショットとページ全体のスクリーンショットを取得し、構造化結果を書き込み、必ずセッションを閉じます。アプリ固有の意味的な `find`、`click`、`fill`、`wait` アサーションを JSON シーケンスへ追加してください。scaffold の再実行と `--force` は、そのシナリオを保持します。Agent Browser と Chromium は `npm install -g agent-browser && agent-browser install` で別途インストールします。`init-e2e --check` はブラウザーを起動せずコマンドを検証します。

`--write` の再実行は冪等です。既存の生成ファイル、package script、Norn 設定値が異なる場合は置き換えません。`--force` が明示的な移行経路です。ブラウザーを起動せず、チェックイン済みの契約を検証できます。

```bash
norn init-e2e --adapter existing --external-server --check --project /path/to/repository
norn init-e2e --preset playwright --package packages/web --check --project /path/to/repository
```

生成された runner は `NORN_E2E_BASE_URL` と `NORN_E2E_EVIDENCE_DIR` を受け取り、自身の結果レコードを書き込み、設定されたファイル数と合計サイズの上限内に証跡を収めます。対応する設定は、シェルを介さない argv リストです。

```yaml
e2e:
  require_all_testers: false
  evidence:
    max_files: 100
    max_total_mib: 128
  base_url: http://127.0.0.1:4173
  server:
    command: [pnpm, dev, --host, "127.0.0.1", --port, "4173", --strictPort]
  runner:
    command: [pnpm, test:e2e]
```

`e2e.evidence.max_files` の既定値は20、`e2e.evidence.max_total_mib` の既定値は64で、どちらも正の整数が必要です。プロジェクトで永続化するには `.norn/harness.yaml` に設定し、1回の実行だけ上書きするには `norn run "タスク" --max-evidence-files 100 --max-evidence-mib 128` を指定します。Norn は解決した値を `NORN_E2E_MAX_EVIDENCE_FILES` と `NORN_E2E_MAX_EVIDENCE_BYTES` として managed runner へ渡し、委譲されたテスターロールにも同じ上限を指示ペイロードで渡します。

選択された template に4つの静的テスターロールが含まれる場合、Norn はそれらを並列実行し、共有サーバーを開始または確認してから、`runner.command` をシェルを介さない argv リストとして正確に1回実行します。実装担当は E2E spec を追加または更新できますが、ブラウザーの起動、サーバーの開始、この runner の実行は禁止されます。

実装担当は詳細な結果をラン固有の Markdown 成果物へ書き込み、`status` と割り当てられた成果物パスだけを含む小さな構造化制御オブジェクトを返します。Norn は、欠損、空、古い、シンボリックリンク、ハードリンク、サイズ超過、契約外のレポートを、プロバイダー試行の受理前に拒否します。変更ファイルはモデル応答を信用せず Git から導出します。

コマンドは `NORN_E2E_BASE_URL`、`NORN_E2E_EVIDENCE_DIR`、`NORN_E2E_MAX_EVIDENCE_FILES`、`NORN_E2E_MAX_EVIDENCE_BYTES`、`NORN_RUN_ID`、`NORN_IMPLEMENTATION_ROUND` を受け取ります。`NORN_E2E_EVIDENCE_DIR` 配下に、空でないログ、スクリーンショット、trace、結果ファイルのいずれかを少なくとも1つ書き込む必要があります。Norn 自身の stdout と stderr ログは証跡に数えません。Norn は正式なコマンド、timeout、終了コード、証跡検証を所有し、その結果をコマンドツールなしの読み取り専用レビューとして `e2e_tester` へ渡します。レビュー担当は要約と指摘だけを返し、Norn が正式なテストと E2E の記録をラン成果物へ挿入します。同様に、静的テスターは固定 E2E placeholder や共有ゲート結果を構造化応答へ重複記載しません。レビュー担当が失敗したランを成功へ変更することはできません。managed runner は Norn のプロセス内かつテスタープロバイダーのサンドボックス外で実行されるため、`e2e.tcp_forwards` または `--allow-e2e-danger-full-access` と併用できません。

大規模リポジトリ向けには、上限付きながら余裕のある既定値を用意しています。モデルロールとプロジェクトのテストコマンドは各60分、managed または委譲 E2E は40分です。必要に応じてプロジェクト単位で上書きできます。

```yaml
limits:
  timeouts:
    role_seconds: 3600
    test_seconds: 3600
    e2e_seconds: 2400
```

これらは遅延ではなく timeout の上限です。古い値を明示している既存プロジェクト設定は、更新されるまでその値を維持します。

既定の `require_all_testers: true` は、spec、clean、security、chaos の各テスターに独立したブラウザー証跡を要求します。並列品質コマンドが監視中の開発サーバーと干渉するプロジェクトでは、専用ブラウザーロールを1つだけ使用できます。

```yaml
e2e:
  require_all_testers: false
roles:
  e2e_tester: {profile: e2e-browser}
```

選択された template に4つの非ブラウザーテスターロールが含まれる場合、Norn はまずそれらを並列実行し、その後に共有サーバーを開始または確認して `e2e_tester` だけを実行します。専用ロールにも有効なブラウザー証跡が必要です。profile は独立して設定できるため、Chromium が Codex TEST サンドボックスと互換性を持たない場合は Codex 以外のプロバイダーを選択できます。このモードでは、選択されたすべての静的ロールに対し、ブラウザーや開発サーバーの起動、E2E URL への接続、Norn の決定論的ゲートが所有するプロジェクト全体の lint、test、coverage、build コマンドの再実行を明示的に禁止します。

同梱の `e2e-browser` profile は Sonnet の medium effort を使用し、Grok 4.5 の medium effort をフォールバックにします。意図的に Codex と Fable の候補は含めていません。サンドボックス化された Grok ロールは、Grok が OS サンドボックスの適用を証明できない場合に fail closed し、次のプロバイダーへ進みます。信頼できる headless ホストで Grok の Linux `/dev/tty` Landlock エラーが発生する場合、`GROK_SANDBOX=off norn run "タスク"` を明示的なプロセス単位の回避策として使用できます。Norn は引き続き非対話 permission mode を使い、Git、GPG、credential、editor、pager の対話プロンプトを無効化しますが、カーネルレベルのファイルシステム分離はなくなります。信頼できないリポジトリでは使用しないでください。

managed runner が未設定で、プロバイダーの非対話 permission policy がブラウザーまたはループバックアクセスを引き続き拒否する場合、信頼できるリポジトリに限り `--allow-e2e-danger-full-access` を実行時に指定できます。この回避は専用 `e2e_tester` にだけ適用され、選択された静的テスターは通常の TEST サンドボックスを維持します。

モデルは安定した論理参照を持ち、必要に応じてプロバイダー固有の識別子へ対応づけられます。profile はモデルを参照し、effort を選択します。

```yaml
models:
  codex-sol:
    provider: codex-cli
    model: sol
    model_id: gpt-5.6-sol
    enabled: true
    efforts: [high, max]
    capabilities: [planning, coding, review, structured-output]
    diversity_group: openai

profiles:
  core-balanced-medium:
    candidates:
      - model_ref: claude-opus
        effort: high
        rank: 1
      - model_ref: codex-sol
        effort: high
        rank: 1
```

pre-1.0 の移行期間中は、従来の inline candidate も引き続き受理します。`norn models init` はユーザー単位の観測レジストリを作成または安全にマージします。`norn models refresh` は、見つからなくなった項目を削除せずにプロバイダー固有の discovery を再実行し、`norn models list --json` は有効な inventory を公開します。native discovery はモデルを呼び出しません。モデル一覧コマンドを持たないプロバイダーは、明示的に検証されるまで `declared` のままです。人間向け出力では、このような利用候補ではあるものの未検証の項目を `UNKNOWN` と表示し、プラン固有のアクセス権が確認済みだとは表現しません。

`norn models probe codex-sol` は、モデルを消費する独立した検証経路です。有効かつ設定済みの完全一致参照だけを、最小の設定 effort で、再試行、フォールバック、リポジトリコンテキストなしに1回呼び出します。複数参照を指定でき、すべての有効な設定モデルを選ぶには `--all` が必要です。最初の呼び出し前に対象全体の検証が完了します。各結果は `verified` または具体的な active failure として、timestamp、duration、usage、上限付き diagnostic とともにレジストリへ記録されます。生のプロンプトと応答は保存しません。その後のモデル非消費 refresh は、設定された provider、model、effort の identity が変わらない限り結果を保持します。

新しく discovery された未宣言の model ID は、team candidate pool へ黙って入るのではなく、無効な状態で記録されます。レジストリ初期化後は、その有効な設定項目が実行時の profile routing を制約します。レジストリ未初期化時は、互換性のため有効な宣言済み項目を候補として維持します。プロバイダーが `model_unavailable` を返した場合、Norn は次の設定候補へ進み、そのランの残りでは同じ論理モデルを再度呼び出しません。永続的な availability status を変更するのは、引き続き明示的な active probe だけです。

## チーム構成とモデルobjective

team composition は作成者のポリシーによって上限づけられます。`norn init`で作成した新規設定は`teams.default: auto`と`teams.objective: balanced`を使用します。`--team`を省略すると、設定済みの読み取り専用Architectがタスクのcomplexity、risk、必要なspecialistを評価します。固定teamを使用するには既知のtemplateを明示します。

```bash
norn plan "ドキュメント例を1つ更新する"
norn plan "ドキュメント例を1つ更新する" --team lean
norn run "認証データを安全に移行する" --team auto
norn run "固定互換ワークフローを使用する" --team standard
norn run "精度を優先する" --team-objective quality
norn run "実装profileだけ固定する" \
  --team-objective balanced \
  --role-profile implementer=implementer-high
norn team preview --team-objective balanced
norn team preview --complexity high --compare balanced,quality
```

templateとobjectiveは別の判断を所有します。

- templateはriskに応じたTester、Specialist、独立検証範囲を決めます。
- complexityはroleごとのprofile tierを決めます。自動選択ではArchitectの判定を使い、固定templateまたはfallbackでは決定論的判定を使います。
- objectiveは適格なモデル集合内でprofileと候補順を決めます。
- profileは既存どおりモデル、effort、fallback順を定義します。

同梱の`balanced`はprimary roleのlow complexityをmedium profileへ正規化します。core reasoningのmediumはOpus/Sol、highはFable/Opus/Solです。ImplementerのmediumはGrok/Sonnet/Terra、highは`Sol/high → Opus/high`だけを使用し、利用不能でも下位tierを暗黙追加しません。Clean TesterはLuna/Haiku、Spec TesterはTerra/Sonnet、Security/Chaos TesterはGrok/Sonnet/Terraを使用します。`balanced`はmax effortを使用しません。

同梱の`quality`は品質保証ではなく、高精度候補を優先するbest-effort policyです。短時間で読み取り専用の主要判断roleにはFable/Opus/Solのmax profileを使用できますが、Implementerは`Sol/high → Opus/high`を維持し、Fableやmaxへ昇格しません。`speed`と`cost`は同梱しません。価格やlatencyの前提をNornが推測せず、ユーザー定義policyが存在する場合だけ利用できます。未定義名は`balanced`へfallbackせず設定エラーになります。

再利用する構成は`teams.policies`へ定義します。roleには固定profile、または`low`、`medium`、`high`ごとのprofileを指定できます。一部を既存policyから継承する場合だけ`extends`を明示します。

```yaml
teams:
  objective: my-speed
  policies:
    my-speed:
      extends: balanced
      roles:
        implementer:
          medium: my-fast-implementer
          high: my-fast-implementer-high
```

各policy profileは`teams.eligibility`でrole分類に許可された`model_ref`だけを含む必要があります。同梱分類は、主要判断roleがFable/Opus/Sol、ImplementerがSol/Opus/Grok/Sonnet/Terra、TesterがGrok/Sonnet/Terra/Luna/Haikuです。userまたはproject設定でこの集合を明示的に置き換えられます。inline candidateや適格modelを持たないprofileはobjective選択に使用できません。

profileの解決優先順位は次のとおりです。

1. CLIのrepeatableな`--role-profile role=profile`
2. project設定の明示的な`roles.<role>.profile`
3. user設定の明示的な`roles.<role>.profile`
4. CLIまたは設定で選択したobjective policy
5. 互換用のtemplate `profile_overrides`
6. 同梱のrole profile

`--role-profile`は統合済み設定に存在し、role分類の適格集合を満たすprofileだけを受理し、recomposition後もそのrunでは固定します。選択結果はobjective、complexity、profile、設定元とともにTeamPlan、manifest、イベント、レポートへ記録されます。

### 候補rankとモデル系列diversity

各論理modelには任意の`diversity_group`を設定できます。同梱設定ではOpenAI系を
`openai`、Claude系を`anthropic`、Grok系を`xai`として扱います。これは品質保証や
provider名の代用ではなく、PlannerとPlan Reviewer、Implementerとsemantic Tester、
主要な実装・検証roleとFinal Gateで、同じ見落としが相関しにくい組み合わせを優先する
ための相対metadataです。userまたはproject設定で上書きできます。

profile candidateの`rank`は正の整数で、候補列内を非減少順にします。profile内では全候補
にrankを指定するか、全候補で省略します。

- rankを省略した既存profileは、`diversity.mode: prefer`でも宣言順を厳密に維持します。
- `prefer`は同一rank内だけ異なる`diversity_group`を優先し、rankを越えません。
- `require`は異系列を適格条件とし、現在rankに候補がなければ次rankを探索します。全rank
  で満たせなければ、同系列へ黙ってfallbackせず停止します。
- 同条件の最終tie-breakerはYAMLの宣言順です。runtimeの利用不能fallbackも、同一rankの
  残り候補を終えてから次rankへ進みます。

```yaml
teams:
  diversity:
    mode: prefer  # off / prefer / require
    relationships:
      planning_review:
        sources: [planner]
        targets: [plan_reviewer]
```

TeamPlanは候補のrank、宣言位置、解決後priority、inventory状態、選択・除外理由、
`diversity_group`とrelationshipの充足状態を固定します。実行時routerは上流roleで実際に
成功したモデル系列を使って後続候補を同じ規則で並べ、provider attempt開始eventにも
rank、宣言位置、選択理由を残します。

### Implementation Advisorとモデル利用上限

objectiveを使用するrunでは、ローカルgate、Tester、Final Gateの失敗など、記録済みの
evidenceがある場合だけread-onlyの`implementation_advisor`を起動できます。Advisorは
診断、変更方針、守るべき契約、必要なtest、未解決事項を構造化artifactへ記録し、その
artifactを同じImplementer profileへ返します。Implementerを上位profileへ変更せず、
workspaceを編集せず、gate判定も上書きしません。候補解決ではImplementerと異なる
`diversity_group`を同一rank内で優先します。objectiveを持たない既存projectは従来動作を
維持し、Advisorを明示設定した場合だけこの経路を有効にします。

モデル利用上限は次の設定でrun単位に固定されます。

```yaml
limits:
  model_selection:
    max_effort_invocations_per_run: 3
    max_advisor_calls_per_round: 1
    max_advisor_calls_per_run: 2
```

max effortは候補をproviderへ起動する直前に予約し、起動した時点で1回と数えます。同じ
候補へのretryは追加せず、別のmax候補へのfallbackと別roundは追加します。disabled model、
inventory不一致、command未検出など起動前のskipは数えません。起動後の失敗やcancelは
消費済みです。上限到達後はprofileに明示された非max候補だけへ進み、候補がなければ
`max_effort_limit_reached`でactionableに停止します。同梱`core-quality-max`には
rank 2のhigh fallbackを明示しています。

Advisorの既定上限は1 roundに1回、1 runに2回です。上限を使い切った後も自動的なwriter
昇格を繰り返さず、`advisor_calls_exhausted`で人間の判断を求めます。`0`を指定すると
対応する利用を無効化できます。予約はSQLiteへ原子的に記録され、TeamPlan、provider
attempt、event、manifest、`norn status`、machine-readable／human-readable reportへ
消費数、残数、停止理由を投影します。`norn recover`や`norn continue`も元runの固定上限と
消費済み回数を復元します。

### モデルを消費しないteam preview

課金前に構成を確認するには`norn team preview`を使います。

```bash
# complexityを推測せずmedium/highを並べる
norn team preview --team-objective balanced

# 明示scenario
norn team preview --team-objective balanced --complexity high

# 依頼文を保存せず、決定論的assessmentだけを使う
norn team preview --team-objective balanced --request-file task.md

# 同じ条件でobjectiveを比較する
norn team preview --complexity high --compare balanced,quality --json
```

previewはprovider CLI、Architect、active probe、`models init / refresh`を起動しません。
model registryとrepository signalは読み取り専用で、`.norn/runs`、manifest、TeamPlan
artifact、task artifactを作りません。registry未初期化時は候補を`UNKNOWN`として表示し
ます。plain textと`--json`は同じresolver結果を使い、profile、effort、rank、inventory、
設定元、diversity、max effort候補数、warning/errorを返します。availability不明と
softなdiversity低下はwarning、設定不備、active roleの適格候補ゼロ、`require`不成立は
非ゼロです。limit欄にはmax effortの初期選択数、回避不能数、可能数、run上限と、
Advisorの`on-evidence` activation、round／run上限を表示します。preview自体は予約を
作らず、消費数を変更しません。

### Team selection telemetry（report-only）

Nornは完了・失敗・中断したrole実行から、role、model、effort、入力token帯、role全体の
経過時間、providerが明示したTTFTとtoken usage、retry、fallback、成功／失敗を
provider-neutralな観測値としてSQLiteへ保存します。providerがUSDを返した場合だけ
`cost_usd`を記録し、subscription利用枠と従量課金USDを同じcost指標として比較しません。
prompt、response、credential、providerの詳細errorは集計へ保存しません。runごとの安全な
projectionは`artifacts/team-selection-observations.json`です。
`telemetry.enabled: false`では新しいobservationの保存、report時のbackfill、既存観測の
snapshot／reportへの読み込みを行いません。
providerの`auth`文字列はcredentialとして転記せず、既知の`subscription`／従量課金分類
だけをbilling basisへ正規化し、それ以外は`unknown`として比較対象外にします。

観測値はrole／model／effort／入力token帯が一致する場合だけ比較候補になります。既定では
各候補3 sample、30日以内、role経過時間の変動係数1.0以下、失敗率0.5以下をreadinessの
基準にします。fallbackを含むsampleはroute全体の傾向には残しますが、単独modelの比較には
使いません。条件不足、stale、高分散、失敗率、比較候補不足、billing basis不一致は別の
reasonとして表示します。

この初期契約は観測・表示・readiness判定だけです。`selection.mode`は常に`authored`、
`observed_applied`は`false`で、観測値がprofile候補の宣言順、rank、diversity、fallbackを
変更することはありません。TeamPlanはteam作成時のsnapshotを固定し、`team preview`、
最終report、escalation report／JSONはsample数とreadinessを表示します。telemetryが
未取得または利用不能でもrunの主結果は変わりません。`speed`／`cost` policyは引き続き
ユーザーがmodel／effort構成を明示した場合だけ利用できます。

基準はprojectまたはuser設定で変更できます。

```yaml
telemetry:
  enabled: true
  max_groups: 500
  readiness:
    min_samples_per_candidate: 3
    max_age_days: 30
    max_duration_cv: 1.0
    max_failure_rate: 0.5
```

`teams.objective`を持たない既存projectは従来のtemplate profile overrideをそのまま維持します。旧版の`norn init`が生成した完全な設定には`roles.*.profile`が明示されているため、objectiveへ移行するときはpolicy管理に戻すrole entryを削除してから`teams.objective`を追加してください。新しい`norn init`はrole既定値を配布設定から継承するため、このロックを生成しません。

`--team auto`または`teams.default: auto`による初回compositionでは、タスク、上限付きrepository metadata、観測済みmodel inventory、設定済みtemplateだけをArchitectへ渡します。厳格な`TeamAssessment`はrole、モデル、コマンド、ツール、依存関係を新たに作れません。Nornは決定論的なrisk floorを適用して不変な`TeamPlan`へ展開し、Architectの出力が無効、低confidence、または利用不能なら設定済みfallbackを使用します。

自動ランでは、ローカル、Tester、最終品質の判定失敗も制御されたrecomposition checkpointになります。Nornは同じ読み取り専用Architectに上限付きの実行時指摘を再評価させ、新しいTeamPlan revisionを追加できます。recompositionは現在のtemplate、complexity、Tester、Specialistを維持または拡張することしかできません。同梱の`teams.max_recompositions: 1`が追加呼び出しを制限し、設定値は`0`から`3`です。固定templateは自動recompositionしません。

同梱templateは`lean`、`standard`、`deep`です。objective有効時は、deepを選んでもImplementer profileを`team-architect-max`へ変更しません。UI E2E、決定論的gate、最終品質しきい値、直列化されたworkspace writer、すべてのround limitは削除できません。`evals/team-composition.yaml`のoffline matrixはteam sizingと`balanced`のprofile境界を、`evals/team-selection-telemetry.yaml`は同一タスクのbalanced／quality／ユーザー定義speed／costとreport-only契約を、いずれもモデル非消費で検証します。

round limit は `limits` 配下で設定するか、呼び出し単位で上書きできます。

```bash
norn run "タスク" --max-rounds 5 --max-total-rounds 12 \
  --max-planner-retries 2 --max-final-replans 2
```

既知の Python、Node、Rust、Go ゲートは、一般的な Node typecheck script を含め自動検出されます。すべてのゲートはプロバイダーエージェントの外側で Norn が一度だけ実行します。プロジェクトは追加の test、lint、typecheck、build コマンドを、シェルを介さない argv リストとして定義できます。

```yaml
gates:
  enabled: true
  auto_detect: true
  commands:
    - name: integration
      kind: test
      command: [python3, -m, pytest, tests/integration]
    - name: frontend-types
      kind: typecheck
      command: [npm, run, typecheck]
      container:
        image: node:22-bookworm
        workdir: /workspace/apps/web
        network: none
```

`container` を指定すると、Norn はシェルを介さず `docker run` を直接構築します。detached implementation worktree を `/workspace` へ bind mount し、対応環境では現在の uid/gid を使用し、既定ではネットワークを無効にします。ゲートがサービスを必要とする場合だけ、レビュー済みの Docker network 名を設定してください。マシン間の再現性が重要な場合は image を digest で固定します。プロジェクト所有の Compose 環境では、`[docker, compose, exec, ...]` のようなシェルを介さない直接コマンドも利用できます。設定済みまたは自動検出された決定論的コマンドが成功しない場合は high severity の finding が作成されるため、同梱の quality policy では lint、typecheck、build の失敗が1件でもブロックします。

### 検証プランと複数サービス

`norn verify` はリポジトリ調査と実行を分離します。

```bash
norn verify plan --no-agent --project /path/to/repository
norn verify plan --project /path/to/repository
norn verify run --project /path/to/repository
norn verify export --project /path/to/repository
```

`verify plan` は監査可能な Norn ラン状態を書き込みますが、プロジェクトのコマンド、サービス、ゲート、ブラウザーは開始しません。`--no-agent` は決定論的な調査だけを保証し、プロバイダー利用枠を消費しません。Norn は明示的な設定、workspace package script、既知の Python/Rust/Go tooling、lockfile、E2E 設定を inventory 化し、canonical input を hash 化します。

計画には3つの異なる結果があります。

- 完全な plan は終了コード `0` となり、確認または実行できます。
- 決定論的な選択肢が残る場合は、stop reason `verification_plan_unresolved` と終了コード `50` になります。これは判断が必要な diagnostic であり、リポジトリが壊れていることや検証パイプラインが失敗したことを示す証拠ではありません。
- 古い candidate、シンボリックリンクされた作業ディレクトリ、ループバック以外の managed binding、型なし interpolation、dependency cycle など、無効または危険な設定は、プロセス開始前に終了コード `40` となります。

曖昧な workspace では、モデルを使わない diagnostic から始めます。

```bash
norn verify plan --no-agent --json --project /path/to/monorepo
```

JSON 応答と escalation report には、絶対パスの `review_artifact` が表示されます。その `x-norn-review.candidate_options` 項目には、現在の各 `candidate_id`、kind、cwd、シェルを介さない command、許可された argv suffix が含まれます。このファイルはレビュー補助であり、import や plan acceptance の仕組みではありません。この結果から、次のどちらかを選択します。

1. プロバイダー利用枠を使う権限がある場合は、`--no-agent` なしで再実行します。残った曖昧さだけが読み取り専用の `verification_architect` profile（同梱設定は `terra-medium`）へ渡されます。現在の candidate ID の選択や省略理由の説明、型付き service reference の使用はできますが、実行可能 argv、credential、host binding を作ることはできません。論理的な architect resolution には、設定済みの provider retry/fallback policy が適用されます。
2. モデルを使わないまま進める場合は、対応する `verification.services`、`checks`、`e2e` 項目をプロジェクト設定へ追加し、`--no-agent` 付きで再実行します。`command_ref` は candidate が報告した `cwd` を維持し、残るすべての check choice を処理する必要があります。一部だけを選択しても、他の discovery 済み check の省略は記録されません。意図した plan に省略理由の説明が必要な場合は、`candidate_options` を受理済み plan とみなさず architect 経路を使用してください。

たとえば review artifact に次の2つの test choice だけがあり、両方を実行する意図なら、argv をコピーまたは書き換えず、candidate ID と cwd を明示できます。

```yaml
verification:
  checks:
    - id: root-tests
      kind: test
      command_ref: package-script:root:test
      cwd: .
    - id: api-tests
      kind: test
      command_ref: package-script:apps/api:test
      cwd: apps/api
```

`verify plan --no-agent` を再実行すると、完全な明示的 plan が確認されます。他に discovery 済みの test、lint、typecheck、build choice が残っている場合は、それらも設定する必要があります。この構文は2項目以外を黙って省略する意味ではありません。

resolution は明示的な `gates`、`e2e`、`verification` 項目を保持し、完全一致 fingerprint の受理済み plan、曖昧さのない discovery、architect の順に試行します。`verify export` はランごとの review artifact とは異なります。モデルを使用せず、完全な deterministic plan または fingerprint が完全一致する受理済み plan からのみ、上書きしない `.norn/verification-plan.yaml` proposal を作成します。`init-e2e` からの自動移行として扱わず、内容をレビューしてプロジェクト設定へ統合してください。

明示的な multi-service 設定では、discovery が推論できないシェルを介さないコマンドを許可できます。

```yaml
verification:
  services:
    - id: database
      external: true
      ports: [{id: postgres, bind: 127.0.0.1, value: 55432, scheme: tcp}]
      readiness:
        type: tcp
        url: {ref: service.database.url.postgres}
    - id: api
      command: [python, -m, example_api]
      allowed_argv_append: [--port]
      ports: [{id: http, bind: 127.0.0.1, value: auto}]
      argv_append: [--port, {ref: service.api.port.http}]
      readiness:
        type: http
        url: {ref: service.api.url.http}
        path: /health
    - id: web
      command: [npm, run, dev]
      allowed_argv_append: [--, --host, --port, --strictPort, 127.0.0.1]
      depends_on: [api]
      ports: [{id: http, bind: 127.0.0.1, value: auto}]
      argv_append:
        [--, --host, 127.0.0.1, --port, {ref: service.web.port.http}, --strictPort]
      env:
        API_URL: {ref: service.api.url.http}
      readiness:
        type: http
        url: {ref: service.web.url.http}
  checks:
    - id: integration
      kind: test
      command: [python, -m, unittest, discover, -s, tests/integration, -v]
      depends_on: [database, api]
      env:
        TEST_DATABASE_URL: postgresql://norn_test:norn_test@127.0.0.1:55432/norn_test
  e2e:
    command: [npm, run, test:e2e]
    base_url: {ref: service.web.url.http}
    depends_on: [web]
```

ここで `database` はループバック上ですでに起動しています。Norn は readiness check しますが、開始、signal 送信、停止は行いません。固定 binding とテスト専用 DSN は意図的に人間が作成する値であり、architect はどちらも生成できません。この明示的な境界は、discovery 済みまたは architect が選択したリポジトリ candidate と組み合わせられます。

Norn は分離されたループバック port を予約し、dependency 順に service を開始し、型付きの argv/environment reference だけを解決し、HTTP または TCP readiness を待ち、check を直列実行し、E2E 証跡を検証し、すべての結果で managed process group を逆順に停止します。external service は readiness check しますが停止しません。`norn run` は実装 round ごとに inventory を再計算し、同じ engine を使用します。infrastructure mismatch に対して replacement plan を試せるのは最大1回です。lint、test、build、browser assertion、quality failure は product result であり、command selection を再実行しません。

各ランは不変な team-plan revision、role response、model selection、attempt、finding、test result、round history を `.norn/runs/<run-id>/` 配下へ記録します。共有データベース `.norn/runs/state.sqlite3` は、run、event、team-plan、role-graph、role-execution、provider-attempt、verification-plan、verification-execution の正式な store です。JSON と Markdown ファイルは、移植可能な projection と evidence として維持されます。最新 composition は `artifacts/team-plan.json` へ、assessment は `artifacts/team-assessment.json` へ、invocation state は `artifacts/role-executions.json` へ、順序付き fallback/retry state は `artifacts/provider-attempts.json` へ投影されます。verification revision と解決済みの正確な argv/log record は `artifacts/verification-plan*.json` と `artifacts/verification-executions.json` へ投影されます。移植可能な run file は書き込み後に、安全な相対パス、kind、media type、byte size、SHA-256 digest、timestamp、該当する場合は所有 role execution とともに登録されます。再構築可能な catalog は `artifacts/artifact-manifest.json` へ投影され、登録済み JSON の読み取りは、内容が SQLite の audit digest と一致しなくなると fail closed します。

TeamPlan の dependency は DAG として検証され、選択された読み取り専用 role は、dependency の準備ができた安定した wave 単位で実行されます。復旧では、停止したプロセスが実行中のまま残した invocation と provider attempt を interrupted として記録し、部分的な model call を黙って再開することはありません。このバージョンで作成されたランでは、通常の `read-only` invocation に hash 化された request envelope を保存します。復旧後、`norn continue <run-id> --execution <execution-id>` を明示的に実行すると、envelope、記録済み workspace path、取得可能な Git workspace fingerprint が引き続き一致する場合に限り、同一 request を新しい parent-linked invocation として再発行します。workspace-writing、TEST、danger-full-access、変換済み、legacy の invocation は対象になりません。continuation は終了済みランを再オープンせず、後続 pipeline work を推測しません。結果は人間がレビューできるよう escalation artifact へ追加されます。成功以外のすべての停止では、人間の判断用に `escalation-report.md` と `escalation.json` も作成されます。

既定では、`run` は clean な Git リポジトリを要求し、detached `.norn/worktrees/<run-id>/` worktree 内で実装します。選択したプロジェクトディレクトリへ直接変更する意図がある場合に限り、`git.worktree: false` を設定してください。

新しい Git worktree には追跡対象ファイルだけが含まれます。テストに ignore 済み依存関係、ローカル環境ファイル、準備済みデータベースが必要なプロジェクトでは、どのプロバイダーロールも開始する前に worktree を provision できます。

```yaml
git:
  worktree: true
  worktree_setup:
    - name: php-dependencies
      copy: laravel/vendor
    - name: node-dependencies
      copy: node_modules
      optional: true
    - name: test-database
      command: [scripts/setup-norn-database, --template]
      timeout_seconds: 900
```

各ステップは action を1つだけ持ちます。`copy` は source checkout から project-relative path を実体化し、`command` は新しい worktree 内で実行するシェルを介さない argv リストです。コマンドには `NORN_SOURCE_ROOT`、`NORN_WORKTREE`、`NORN_RUN_ID` が渡されます。必須ステップの失敗はモデル呼び出し前にランを停止します。

## 開発とパッケージング

ローカル開発ツールをインストールし、CI と同じチェックを実行します。

```bash
python3 -m pip install --editable ".[dev]"
ruff format --check .
ruff check .
python3 -m unittest discover -v
python3 -m build
python3 scripts/package_smoke.py dist/norn_cli-0.12.0-py3-none-any.whl
```

CI は Python 3.12、3.13、3.14 で quality suite を実行し、clean な仮想環境へ build 済み wheel をインストールして、Codex と Claude の両方の Skill copy を検証します。ディストリビューションは短期間保持される workflow artifact としてアップロードされます。GitHub Release の公開時は、同じ決定論的ゲートを通した後、検証済み artifact を OIDC Trusted Publishing で PyPI へ送信します。どちらの workflow もサブスクリプションモデルを呼び出しません。

リリース受け入れは意図的に2つへ分離しています。CI は決定論的な package check を行い、ローカル acceptance は認証済み subscription CLI を呼び出します。リリースを昇格する前に[リリース受け入れ手順](docs/acceptance.md)へ従ってください。バージョン履歴は [CHANGELOG](CHANGELOG.md)、非公開の脆弱性報告は[セキュリティポリシー](SECURITY.md)を参照してください。

canonical command は `norn` です。legacy の `norf-harness` executable は pre-1.0 の移行期間中、alias として維持されます。新しい自動化では `norn` を使用してください。

## ライセンス

Copyright 2026 uruca-kk. [Apache License 2.0](LICENSE) の条件で提供します。
