@dogfood-lab/study-swarm 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -15,17 +15,17 @@
15
15
 
16
16
  **引用された研究に基づいて設計上の決定を行い、その後、そのすべての内容が公式なものになる前に、*別の*モデルファミリーを使用して引用を検証する。**
17
17
 
18
- `study-swarm`はツールではなくプロトコルである。大規模言語モデル(LLM)を用いて重要な設計上の決定を行う場合(新しい製品レイヤー、アーキテクチャの選択、「ここでモデルを信頼すべきか」という判断など)、最初の原則から即興で進めることは、時代遅れの設計につながり、記憶に基づいて論文を引用することは、存在しない情報源や、あなたが考えていることとは異なる内容の情報源に依存する設計につながる。`study-swarm`はこれら両方を置き換える:並行して研究エージェントを派遣し、特定の引用された調査結果を要求し、すべての引用を**別のモデルファミリーの外部検証者**を通じてゲートすることで、その情報が設計に影響を与えるようにする。
18
+ `study-swarm`はツールではなくプロトコルである。大規模言語モデル(LLM)を用いて重要な設計上の決定を行う場合(新しい製品レイヤー、アーキテクチャの選択、「ここでモデルを信頼すべきか」という判断など)、最初から即興で進めるのではなく、事前に研究に基づいて設計すると、時代遅れの設計になったり、記憶に基づいて論文を引用すると、存在しない情報源や、あなたが考えていることとは異なる内容の情報源に依存した設計になってしまう。`study-swarm`はこれら2つを置き換える:複数の研究エージェントを並行して派遣し、特定の引用された調査結果を要求し、すべての引用について、設計に影響を与える前に、**別のモデルファミリーの外部検証者**によって検証する。
19
19
 
20
- それは独自の治療法を適用する。このプロトコルは、支援するシステムの設計において、検証者によって保護されたエンベロープを規定するため、それ自体にもそれを適用する。**プロトコルを実行しているモデルを含め、どのモデルも自分の宿題を評価しない。**
20
+ これは、自らその方法を採用している。このプロトコルは、設計を支援するシステムに対して、検証者による保護された環境を規定するため、それ自体にも適用される。**プロトコルを実行するモデルであっても、自分の宿題を評価することはできない。**
21
21
 
22
- ## 5つのステップで構成されるプロトコル
22
+ ## プロトコルの5つのステップ
23
23
 
24
- 1. **特定する**:経験的証拠によって回答が変わる可能性のある3〜5個の重要な設計上の質問を特定する。
25
- 2. **派遣する**:各質問に対して、並行して1つの研究エージェントを派遣する。それぞれが論文タイトル+著者+年+URL+1文の調査結果を返す必要がある(網羅性よりも具体性を重視:「6〜8件の信頼できる調査結果は、20件の曖昧な記述よりも優れている」)。
26
- 3. **統合する**:調査結果を「研究による根拠」セクションに統合する:`N. **<調査結果>.** <著者> <年> (<arXiv/DOI>). <設計への影響>.`
27
- 4. **外部で検証する**:*別のモデルファミリー(推論機能を削除したもの)が、2つの段階ですべての引用をチェックする。まず、**検索オラクル**が論文が存在することを確認する(モデルの記憶ではなく)。次に、「根拠」レンズが、調査結果が情報源と一致することを確認する。**捏造または誤った帰属の場合、処理を停止する。検証者または検索オラクルが利用できない場合は、処理を停止してエスカレーションする(不在を「引用は問題ない」と解釈しないこと)。
28
- 5. **関連付ける**:各アーキテクチャの選択を、番号を使って調査結果に関連付ける。設計への影響がない引用はノイズである。
24
+ 1. **特定する:** 実証的な証拠によって回答が変わる可能性のある、3〜5個の重要な設計上の質問を特定する。
25
+ 2. **派遣する:** 各質問に対して、並行して1つの研究エージェントを派遣する。各エージェントは、論文タイトル+著者+年+URL+一文の調査結果を返す必要がある(広範囲よりも具体性重視。「6〜8件の信頼できる調査結果が、20件の曖昧な情報よりも優れている」)。
26
+ 3. **統合する:** 調査結果を「研究による根拠」セクションに統合する:「N.**<調査結果>。<著者><年>(<arXiv/DOI>)。<設計への影響>。」
27
+ 4. **外部で検証する:** *別のモデルファミリー*(推論機能を削除したもの)を使用して、すべての引用を2つの段階でチェックする。まず、**検索オラクル**が論文が存在することを確認する(モデルの記憶ではなく)。次に、「根拠」レンズが、調査結果が情報源と一致することを確認する。**捏造または誤った帰属の場合、処理を停止する。検証者または検索オラクルが利用できない場合は、処理を停止してエスカレーションする(不在を「引用は問題ない」と解釈しないこと)。
28
+ 5. **関連付ける:** 各アーキテクチャの選択を、番号を使って調査結果に関連付ける。設計への影響がない引用はノイズである。
29
29
 
30
30
  完全な実行可能な詳細(停止テーブル、情報源に関する標準、アンサンブルルール)は、**[PROTOCOL.md](PROTOCOL.md)**に記載されている。
31
31
 
@@ -35,37 +35,37 @@
35
35
 
36
36
  - **LLMは、自分の出力を確実に検証できない。** Huang et al. 2023 ([arXiv:2310.01798](https://arxiv.org/abs/2310.01798)); Kambhampati et al. 2024 ([arXiv:2402.01817](https://arxiv.org/abs/2402.01817), LLM-Modulo); Stechly et al. 2024 ([arXiv:2402.08115](https://arxiv.org/abs/2402.08115)) — 外部検証者がメリットをもたらす。自己批判的な内容は効果がない。
37
37
  - **同じファミリーの評価者は、自分を高く評価する傾向がある。** Panickssery, Bowman & Feng 2024 ([arXiv:2404.13076](https://arxiv.org/abs/2404.13076)) — 自己認識は、自己選好と*線形に*相関するため、部分的なブラインド処理では効果がない。Verga et al. 2024 ([arXiv:2404.18796](https://arxiv.org/abs/2404.18796), PoLL) — 異なるファミリーのパネルを使用すると、約7分の1のコストで偏りが少なくなる。
38
- - **引用は、LLMが嘘をつく場所である。** Walters & Wilder 2023 ([doi:10.1038/s41598-023-41032-5](https://doi.org/10.1038/s41598-023-41032-5)) — GPT-3.5の55%、GPT-4の18%の引用が捏造されている。Onweller et al. 2026 ([arXiv:2605.06635](https://arxiv.org/abs/2605.06635)) —リンクは94%以上の確率で解決するが、引用されたコンテンツのわずか39〜77%しか主張を裏付けていない。したがって、存在は**検索によってチェックする必要があり、想起によってチェックしてはいけない。**
39
- - **生成者の推論を隠す。** Khalifa et al. 2026 ([arXiv:2601.14691](https://arxiv.org/abs/2601.14691), "Gaming the Judge") — 操作された連鎖思考だけでは、評価者の誤検出率が最大90%まで増加する(アクションは固定されている)。Turpin et al. 2023 ([arXiv:2305.04388](https://arxiv.org/abs/2305.04388)) — CoTは、事後的な合理化である。検証者は、単なる引用の主張のみを確認し、「なぜこれを含めたのか」は確認しない。
40
- - **多様性は数よりも重要である。** Rajan 2025 ([arXiv:2511.16708](https://arxiv.org/abs/2511.16708)) — ペアワイズ相関ρ∈[0.05, 0.25]の4つの検証者は、サブモジュールカバレッジによって、いずれか1つの優れた評価者よりも優れている。Kim et al. 2025 ([arXiv:2506.07962](https://arxiv.org/abs/2506.07962)) — LLMのエラーは*相関しているため、重要な変数はレンズの多様性であり、生の数ではない。
38
+ - **LLMは、引用において嘘をつく。** Walters & Wilder 2023 ([doi:10.1038/s41598-023-41032-5](https://doi.org/10.1038/s41598-023-41032-5)) — GPT-3.5の55%、GPT-4の18%の引用が捏造されている。Onweller et al. 2026 ([arXiv:2605.06635](https://arxiv.org/abs/2605.06635)) — リンクは94%以上の確率で解決するが、引用されたコンテンツのわずか39〜77%しか主張を裏付けていない。したがって、存在は**検索によって確認する必要があり、記憶に頼るべきではない。**
39
+ - **生成者の推論を隠す。** Khalifa et al. 2026 ([arXiv:2601.14691](https://arxiv.org/abs/2601.14691), "Gaming the Judge") — 操作された連鎖思考だけでは、評価者の誤検出率が最大90%まで増加する(アクションは固定)。Turpin et al. 2023 ([arXiv:2305.04388](https://arxiv.org/abs/2305.04388)) — CoTは、事後的な合理化である。検証者は、単なる引用の主張のみを確認し、「なぜこれを含めたのか」という理由は確認しない。
40
+ - **多様性は、数よりも重要である。** Rajan 2025 ([arXiv:2511.16708](https://arxiv.org/abs/2511.16708)) — ペアワイズ相関ρ∈[0.05, 0.25]の4つの検証者は、サブモジュラーカバレッジによって、いずれかの単一の検証者よりも優れた結果をもたらす。Kim et al. 2025 ([arXiv:2506.07962](https://arxiv.org/abs/2506.07962)) — LLMのエラーは*相関しているため、重要な変数はレンズの多様性であり、単純な数ではない。
41
41
 
42
42
  ## 実際に機能するのか?(証拠)
43
43
 
44
- テストとして、このプロトコルを自分の引用に対して実行した。2つの非相関性の高いClaude以外のファミリー(**Mistral** (`mistral-small:24b`)と**IBM Granite** (`granite4.1:30b`))を使用して、推論機能を削除し、2つのブラインドトラップで設定された引用セットをチェックした。
44
+ テストとして、このプロトコルを自分の引用に対して実行した。2つの非相関性の高いClaude以外のファミリー(**Mistral** (`mistral-small:24b`)と**IBM Granite** (`granite4.1:30b`))を使用して、推論機能を削除し、2つのブラインドトラップを埋め込んだ引用セットをチェックした。
45
45
 
46
- | 仕掛けられた罠 | Mistral | IBM Granite | 真実 |
46
+ | 仕掛けられたトラップ | Mistral | IBM Granite | 真実 |
47
47
  |---|---|---|---|
48
48
  | 「Nakamura & Olsen」に帰属された連鎖思考プロンプト | 見逃した | **検出(誤った帰属→実際にはWei et al. 2022、arXiv:2201.11903)** | 誤って帰属された |
49
- | 「98%のエラーが除去され、オラクルは不要」という捏造された論文 | **caught** (fabricated) | **caught** (fabricated) | 捏造された |
49
+ | 「98%のエラーが解消され、オラクルは不要」という捏造された論文 | **caught** (fabricated) | **caught** (fabricated) | 捏造された |
50
50
 
51
- どちらのファミリーも単独では両方の罠を検出できなかったが、**それらの組み合わせで2/2を検出した。** 単一の評価者は、誤った帰属を認めてしまうだろう。別途、検索オラクルは、当社の設計ドキュメントにある2つの*実際の*誤った帰属(間違った最初の著者に引用された論文)を検出し、どのパラメトリックLLMも検出できなかった。また、両方のLLMが、トレーニング後の論文であるという理由だけで、捏造されたと誤ってフラグを立てた真の2026年の論文を正しく確認した。最後の点は、ステップ4の存在チェックが**検索オラクルでなければならず、LLMであってはならない**という理由そのものである。
51
+ どちらのファミリーも単独では両方のトラップを検出できなかったが、**組み合わせることで2/2を検出した。** 単一の評価者であれば、誤った帰属をそのまま採用していただろう。別途、検索オラクルは、当社の設計ドキュメントにある2つの*実際の*誤った帰属(間違った最初の著者に引用された論文)を検出し、どのパラメトリックLLMでも検出できなかった。また、両方のLLMが、トレーニングデータ以降に発表された論文を単純に捏造されたと誤ってフラグ付けしたため、正当な2026年の論文も正しく確認できた。最後の点が、ステップ4の存在チェックが**検索オラクルでなければならず、LLMであってはならない理由である。**
52
52
 
53
- この単一の実行は、ミニチュア版の論文である:**相関性の低いレンズ+存在を検証するための検索オラクルは、優れた評価者よりも優れている。**
53
+ この単一の実行は、ミニチュア版の仮説である:**相関性の低いレンズと、存在を確認するための検索オラクルがあれば、どんなに優れた単一の評価者よりも優れている。**
54
54
 
55
- ### …そして再び、v1.1の設計のために
55
+ ### …そして再び、v1.1を設計するために
56
56
 
57
- v1.1の改良は、同じ方法で選択された。つまり、「study-swarm」上で「study-swarm」を実行することによってだ。最初のリリースで「おそらく」という回答になった4つの質問(根拠チェックをどのように*機械化*するか、生成時に根拠を示すべきか、レンズをどのように*組み合わせるか、不確実性の評価において保留すべきかどうか)は、並行して研究を行うエージェントに割り当てられ、得られた**27件の参考文献**はすべて、設計に反映される前にステップ4で検証された。検索オラクルは、**27/27件が存在すること**を確認した。これには、パラメトリックモデルが捏造されたものとして誤ってフラグを立てるであろう6つの2025〜2026年の論文も含まれており、また、モデルでは確認できなかった5つの参考文献の帰属についても修正が行われた。その中には、研究エージェント自身が指摘した実際の最初の著者の誤った帰属も含まれている。推論を排除して実行すると、根拠を示すためのレンズは、私たちのシステムで文書化された自身の失敗モードを再現する。つまり、1つの論文を自信を持って誤って分類し、その*不一致*がエスカレーションを引き起こす。これはまさにカスケードで規定されていることだ。実際に動作するシステムは、[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)として提供される。このシステムで根拠が示された改良点(分解/三項の根拠、生成時の根拠、オラクルによって制御されるカスケード、および校正された保留)は、[PROTOCOL.md](PROTOCOL.md)に記載されている。
57
+ v1.1の改良は、同じ方法で選択されました。つまり、「study-swarm」上で「study-swarm」を実行することによってです。最初のリリースで「私はそう思う」という形で残された4つの質問(根拠チェックをどのように*機械化*するか、生成時に根拠を与えるかどうか、レンズをどのように*組み合わせるか、校正された不確実性に対して保留にするかどうか)は、並行研究エージェントに割り当てられ、すべての**27件の結果として得られた引用文献**は、設計に反映される前にステップ4で検証されました。検索オラクルは、**27/27件が存在すること**を確認しました。これには、パラメトリックモデルが捏造されたものと誤って判断する可能性のある6つの2025〜2026年の論文も含まれており、また、モデルでは確認できなかった5つの引用の誤りを修正しました。その中には、研究エージェント自身が指摘した実際の最初の著者の誤った引用が含まれています。推論を排除して実行すると、根拠レンズは、私たちのディスパッチで文書化された自身の失敗モードを再現します。つまり、1つの論文を自信を持って誤って分類し、それらの*不一致*がエスカレーションを引き起こします。これはまさにカスケードで規定されているとおりです。この動作するディスパッチは、[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)として提供されます。それに含まれる改良点(分解/三項根拠、生成時の根拠、オラクルによるカスケードの検証、校正された保留)は、[PROTOCOL.md](PROTOCOL.md)に記載されています。
58
58
 
59
59
  ## その仕組み
60
60
 
61
- このプロトコルを手動で実行することもできる。異なるモデルと、arXiv/DOIを自分で解決することでステップ4を満たすことができる。2つの関連ツールを使用すると、これを1つのコマンドにまとめることができる。
61
+ プロトコルを手動で実行できます。異なるモデルと、arXiv/DOIを自分で解決することでステップ4を満たすことができます。2つの関連ツールを使用すると、1つのコマンドで実行できます。
62
62
 
63
- - **[prism-verify](https://github.com/mcp-tool-shop-org/prism-verify)** — 実行時の検証ツール:異なるモデルファミリーへのルーティング、推論を排除した処理、複数のレンズによる判断、決定的な検索の存在確認(arXiv → Crossref)、および署名されたレシート。
64
- - **[role-os](https://github.com/mcp-tool-shop-org/role-os)** — `roleos verify-citations <dispatch>`コマンドを提供し、このコマンドはディスパッチから参考文献を抽出し、prismを通じて検証する。
63
+ - **[prism-verify](https://github.com/mcp-tool-shop-org/prism-verify)** — 実行時の検証ツール:異なるモデルファミリーへのルーティング、推論の排除、マルチレンズによる仲裁、決定的な検索存在性の下限(arXiv → Crossref)、署名されたレシート。
64
+ - **[role-os](https://github.com/mcp-tool-shop-org/role-os)** — `roleos verify-citations <dispatch>`を提供します。これは、ディスパッチの引用文献を抽出し、prismを通じて検証するランナーです。
65
65
 
66
- 引き継ぎのプロセスは、ディスパッチ形式そのものである。`N. **finding.** Authors year (arXiv|DOI). implication.`という形式で記述された結果(**各結果に対して1つの解決可能な識別子**)が、`roleos verify-citations`によって読み込まれ、検証される。lintチェックに合格したディスパッチは、問題なく引き継がれる。形式が正しくない参考文献は、実行時に解析不能としてフラグが立てられる。この契約内容は、`study-swarm lint`によってローカルでチェックされるため、ステップ3とステップ4では、参考文献の定義について合意が得られる。
66
+ ハンドオフは、ディスパッチ形式自体です。`N. **finding.** Authors year (arXiv|DOI). implication.`という形式で記述された発見(**各発見に対して1つの解決可能な識別子**)は、まさに`roleos verify-citations`が読み取り、検証するものです。`lint`によってクリーンなディスパッチは問題なくハンドオフされます。不正な形式の引用文献は、ランナーによって解析不能としてフラグが立てられます。この契約内容は、`study-swarm lint`がローカルでチェックするため、ステップ3とステップ4では、引用文献が何であるかについて合意します。
67
67
 
68
- ## CLI(コマンドラインインターフェース)
68
+ ## CLI
69
69
 
70
70
  ```bash
71
71
  npm i -g @dogfood-lab/study-swarm # or run ad-hoc: npx @dogfood-lab/study-swarm <command>
@@ -73,11 +73,13 @@ npm i -g @dogfood-lab/study-swarm # or run ad-hoc: npx @dogfood-lab/study-sw
73
73
 
74
74
  | コマンド | その機能 |
75
75
  |---|---|
76
- | `study-swarm protocol` | 完全なプロトコル(5つのステップ、停止テーブル、ソースの標準)を表示する。 |
77
- | `study-swarm new <slug>` | 5つのステップで構成されたスケルトンを含む`<slug>.dispatch.md`ファイルを生成し、内容を埋めることができるようにする。 |
78
- | `study-swarm lint [--json] <path…>` | ディスパッチの*研究における根拠*をソース標準と比較してチェックする。すべての結果には、著者、年、および解決可能な識別子(arXiv / DOI / URL)が必要であり、「研究によると…」という曖昧な表現は拒否される。違反があった場合、終了コード1で処理が停止するため、CI(継続的インテグレーション)のゲートとして機能する。<path>はファイル、ディレクトリ(`*.dispatch.md`ファイルを再帰的にlintチェック)、またはstdinを表す`-`とすることができる。`--json`オプションを使用すると、機械可読形式のレポートが出力される。 |
76
+ | `study-swarm protocol` | 完全なプロトコル(5つのステップ、停止テーブル、ソース標準)を出力します。 |
77
+ | `study-swarm new <slug>` | 5つのステップのスケルトンを含む`<slug>.dispatch.md`を作成し、それを埋めるためのテンプレートを提供します。 |
78
+ | `study-swarm lint [--json] <path…>` | ディスパッチの*研究根拠*をソース標準と比較してチェックします。すべての発見には、著者、年、および解決可能な識別子(arXiv / DOI / URL)が必要です。「研究によると…」という曖昧な表現は拒否されます。違反があった場合、終了コード`1`を返し、CIでゲートとして機能します。`<path>`はファイル、ディレクトリ(`.dispatch.md`ファイルを再帰的にlint)、または`-`(標準入力)のいずれかになります。`--json`オプションを使用すると、機械可読形式のレポートが出力されます。 |
79
+ | `study-swarm lock <dispatch> --from <orchestration.json>` | ディスパッチをリプレイ用に固定します。`<dispatch>.lock.json`ファイルに、ステップ2のエージェントごとに、**解決されたモデルID** + **正確なバイト単位のプロンプトのSHA-256ハッシュ** + **ツールスキーマのSHA-256ハッシュ**、およびステップ4の**検証レシート**をまとめて書き込みます。これらを1つの`lock_sha256`にまとめます。 |
80
+ | `study-swarm lock --verify <dispatch> [--from …]` | これらのハッシュを再計算し、ロックファイルと一致することを確認します。いずれかのハッシュが異なる場合、終了コード`1`を返し、CIでゲートとして機能します(パッケージのロックファイルと同様)。`--from`オプションがない場合は、ロックファイルの整合性をチェックします。 |
79
81
 
80
- `lint`は決定的な処理であり、モデル呼び出しは行わないため、CI環境で安全に使用できる。ローカルで**ステップ3のソース標準**を適用する。モデルベースの**ステップ4**の検証は、[`roleos verify-citations`](https://github.com/mcp-tool-shop-org/role-os) → prismに委ねられる。
82
+ `lint`は決定論的であり、モデル呼び出しはゼロであるため、CIでの使用に安全です。ローカルで**ステップ3のソース標準**を適用し、モデルベースの**ステップ4**検証は引き続き[`roleos verify-citations`](https://github.com/mcp-tool-shop-org/role-os) → prismに委ねます。
81
83
 
82
84
  典型的なループ:
83
85
 
@@ -88,11 +90,11 @@ study-swarm lint my-decision.dispatch.md # enforce the sourcing standard
88
90
  roleos verify-citations my-decision.dispatch.md # model-based Step 4 (different family, via prism)
89
91
  ```
90
92
 
91
- 2つの完全で、lintチェックに合格した動作するディスパッチが参照として提供される:[`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md)(プロトコルの中心的な決定であり、簡潔)と[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)(完全なv1.1の設計パスであり、27件の参考文献があり、そのすべてが外部で検証されている)。
93
+ 以下に示す3つの完全な、不要な情報を削除して整理されたドキュメントを参考として提供します。[`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md)(プロトコルの主要な決定事項、簡潔にまとめたもの)、[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)(完全なv1.1設計、27件の引用があり、すべて外部で検証済み)、および[`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md)(v1.2ロック設計、39件の引用があり、実行環境を通じて管理され、独自のロックを実装した最初のドキュメント)。
92
94
 
93
- ### CI環境でのゲートとして使用する
95
+ ### CIでゲートとして使用する
94
96
 
95
- `lint`は、ファイル、ディレクトリ(`*.dispatch.md`ファイルを再帰的にlintチェック)、またはstdinを表す`-`を受け取り、`--json`オプションを使用すると、機械可読形式のレポートが出力される。これをリポジトリに組み込むことで、各PR(プルリクエスト)でディスパッチのソースを検証することができる(コピー&ペーストできるサンプルは、[`examples/study-swarm-ci.yml`](examples/study-swarm-ci.yml)にも含まれている)。
97
+ `lint`は、ファイル、ディレクトリ(`.dispatch.md`ファイルを再帰的にlint)、または`-`(標準入力)を受け取り、`--json`オプションを使用すると、機械可読形式のレポートが出力されます。これをリポジトリに追加して、各PRでディスパッチのソースをゲートします(コピー&ペーストできるサンプルは[`examples/study-swarm-ci.yml`](examples/study-swarm-ci.yml)にもあります)。
96
98
 
97
99
  ```yaml
98
100
  # .github/workflows/dispatches.yml
@@ -114,19 +116,25 @@ jobs:
114
116
  - run: npx @dogfood-lab/study-swarm@latest lint dispatches/
115
117
  ```
116
118
 
117
- ## その仕組みを簡潔に説明する
119
+ ### ディスパッチをリプレイ用に固定する(`dispatch.lock.json`)
118
120
 
119
- **最新性** この分野は急速に進展しているため、特定の研究と年を指定することで、設計が18か月遅れて公開されるのを防ぐことができる。**機能性** — 証拠は、何が*成功するか*だけでなく、何が*失敗する*かを示す(説明は、*間違った*AIへの過度の依存を高める可能性がある—Bansal et al. 2021、[arXiv:2006.14779](https://arxiv.org/abs/2006.14779))。**安全性** — 検証ツールによって保護された範囲は、証拠が裏付けるアーキテクチャであり、プロトコルはその出力を強制する。ソースの明示は学術的な儀式ではなく、証拠の追跡である。
121
+ 根拠があり、検証されたディスパッチは、それがどのように生成されたかを説明できれば、監査可能になります。`study-swarm lock`は、コンパニオンのロックファイルを書き込みます。このファイルには、研究エージェントごとに、**解決されたモデルID**(浮動するエイリアスではありません)、**正確なバイト単位のプロンプトのSHA-256ハッシュ**、および与えられた**ツールスキーマのSHA-256ハッシュ**、さらに外部の**検証レシート**が記録されます。これらはすべて1つの`lock_sha256`にまとめられます。`study-swarm lock --verify`は、これらのハッシュを再計算し、いずれかのハッシュが異なる場合、エラーを表示します。したがって、プロンプトが変更されたり、モデルが切り替えられたり、ツールのバージョンが変更されたりすると、検知されます。[PIN_PER_STEP](https://github.com/dogfood-lab/study-swarm)再現性標準を実際に実行できます。この処理は、レコードを出力し、CLIはゼロ依存でネットワークにアクセスする必要がなく、単に正規化(RFC 8785)、ハッシュ化、および検証を行います。
122
+
123
+ **入力は固定し、出力は固定しません。** モデル、プロンプト、温度を固定しても、LLMの出力が完全に同一になるわけではありません。バッチ不変性、浮動小数点演算の非結合性、混合エキスパートルーティング、およびサイレントプロバイダドリフトなど、オフラインツールで制御できない要素が存在するためです。したがって、この仕組みは、**再現可能な入力とドリフトを検出可能な出力を提供し、「決定的な再現」を実現するものではありません。** この設計は、[`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) に記載されているように、個々の要素に基づいて構築されており、独自のロック機能を備えた最初のバージョン ([`examples/study-swarm-lock.lock.json`](examples/study-swarm-lock.lock.json)) として提供されます。
124
+
125
+ ## その仕組みを簡潔に説明します
126
+
127
+ **最新性** — この分野は急速に進歩しており、特定の研究(数年間の期間が必要)に固執すると、設計が18か月遅れてしまう可能性があります。**機能性** — 証拠は、何が「うまくいく」かだけでなく、何が「うまくいかない」かを示しています(説明を加えることで、誤ったAIへの過度な依存が生じる可能性があります—Bansal et al. 2021, [arXiv:2006.14779](https://arxiv.org/abs/2006.14779))。**安全性** — 検証者によって保護された範囲は、証拠が裏付けるアーキテクチャであり、プロトコルによってその出力に強制されます。情報源の提示は学術的なパフォーマンスではなく、証拠の追跡です。
120
128
 
121
129
  ## セキュリティ
122
130
 
123
- `study-swarm`は、**軽量で依存関係のないCLI(コマンドラインインターフェース)** (`study-swarm`)と、その方法論を組み合わせて提供する。**ネットワークまたはモデルへの呼び出しは行わず**、**テレメトリも収集しない**。ソースコードには秘密や認証情報は含まれていない。実行時には、`lint`に渡されたファイルのみを読み取り、現在のディレクトリに単一の`<slug>.dispatch.md`ファイルを書き込む(上書きはせず、作業ディレクトリ外には書き込まない)。方法論で説明されているモデルベースの検証(ステップ4)は、このパッケージではなく、関連ツールによって実行される。詳細は[SECURITY.md](SECURITY.md)を参照のこと。
131
+ `study-swarm` は、この手法とともに、**軽量で依存関係のないCLI(コマンドラインインターフェース)** (`study-swarm`) を提供します。**ネットワーク接続やモデルへのアクセスは行わず、テレメトリデータも収集しません。** ソースコードには、秘密情報や認証情報は含まれていません。実行時には、`lint` に渡されたファイルのみを読み取り、現在のディレクトリに `<slug>.dispatch.md` という名前のファイルを1つだけ書き込みます(上書きは行わず、作業ディレクトリ外への書き込みも行いません)。この手法で説明されているモデルベースの検証(ステップ4)は、このパッケージではなく、関連するツールによって実行されます。詳細は [SECURITY.md](SECURITY.md) を参照してください。
124
132
 
125
133
  ## ステータス
126
134
 
127
- 動作するプロトコルであり、その独自のメカニズムによって外部で検証されている。異なるモデルファミリーがその参考文献をチェックしている(上記の証明を参照)。**v1.1**では、最初のリリースでは言及されていなかった点を強化している。具体的には、分解/三項の根拠、生成時の根拠、レンズを組み合わせるためのオラクル制御カスケード、および校正された保留である。これらの要素はすべて、検証済みのv1.1ディスパッチに基づいて根拠が示されている。このリポジトリは公開参照であり、[PROTOCOL.md](PROTOCOL.md)は実行可能な形式である。これは、[dogfood-lab](https://github.com/dogfood-lab)ファミリーの一部であり、AI時代における構築のための方法と事例を紹介するものである。
135
+ 動作するプロトコルであり、独自の仕組みによって外部から検証されています—異なるモデルファミリーがその引用をチェックします(上記の証拠を参照)。**v1.1** では、最初のリリースでは明示されていなかった検証機能を強化しています。具体的には、分解/三値の根拠付け、生成時の根拠付け、レンズを組み合わせるためのオラクルゲート付きカスケード、およびキャリブレーションされた棄権などです。これらの要素はすべて、検証済みの v1.1 ディスパッチに基づいて構築されています。**v1.2** では、ディスパッチをバイト単位で再現可能にするために、`study-swarm lock` を使用して、各ステップで使用される解決済みのモデル、プロンプト、およびツールスキーマに加えて、検証者のレシートを固定します。また、`lock --verify` コマンドを使用すると、ドリフトが発生した場合に処理が停止します。このリポジトリは公開参照であり、[PROTOCOL.md](PROTOCOL.md) に実行可能な形式で記述されています。これは、[dogfood-lab](https://github.com/dogfood-lab) ファミリーの一部であり、AI時代における構築のための方法と事例を紹介しています。
128
136
 
129
- MITライセンスで提供される。
137
+ MITライセンス。
130
138
 
131
139
  ---
132
140
 
package/README.md CHANGED
@@ -76,6 +76,8 @@ npm i -g @dogfood-lab/study-swarm # or run ad-hoc: npx @dogfood-lab/study-sw
76
76
  | `study-swarm protocol` | Print the full protocol — the five steps, the halt table, the sourcing standard. |
77
77
  | `study-swarm new <slug>` | Scaffold a `<slug>.dispatch.md` with the five-step skeleton to fill in. |
78
78
  | `study-swarm lint [--json] <path…>` | Check a dispatch's *Research grounding* against the sourcing standard — every finding needs an author, a year, and a resolvable identifier (arXiv / DOI / URL); "studies show…" hand-waving is rejected. Exit `1` on violations, so it gates CI. A `<path>` may be a file, a directory (linted recursively for `*.dispatch.md`), or `-` for stdin; `--json` emits a machine-readable report. |
79
+ | `study-swarm lock <dispatch> --from <orchestration.json>` | Pin a dispatch for replay — write `<dispatch>.lock.json` content-addressing, per Step-2 agent, the **resolved model id** + the **SHA-256 of the byte-exact prompt** + the **SHA-256 of the tool schema**, plus the Step-4 **verifier receipt**, rolled into one `lock_sha256`. |
80
+ | `study-swarm lock --verify <dispatch> [--from …]` | Re-derive those hashes and assert they match the lock; any drift exits `1`, so it gates CI like a package lockfile. Without `--from`, checks the lock's own integrity. |
79
81
 
80
82
  `lint` is deterministic — zero model calls — so it's safe in CI. It enforces **Step 3's sourcing standard** locally; the model-based **Step 4** verification still defers to [`roleos verify-citations`](https://github.com/mcp-tool-shop-org/role-os) → prism.
81
83
 
@@ -88,7 +90,7 @@ study-swarm lint my-decision.dispatch.md # enforce the sourcing standard
88
90
  roleos verify-citations my-decision.dispatch.md # model-based Step 4 (different family, via prism)
89
91
  ```
90
92
 
91
- Two complete, lint-clean worked dispatches ship as references: [`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md) (the protocol's central decision, compact) and [`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md) (the full v1.1 design pass — 27 citations, every one externally verified).
93
+ Three complete, lint-clean worked dispatches ship as references: [`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md) (the protocol's central decision, compact), [`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md) (the full v1.1 design pass — 27 citations, every one externally verified), and [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) (the v1.2 lock design — 39 citations, gated through the runner, and the first dispatch to ship its own lock).
92
94
 
93
95
  ### Gate it in CI
94
96
 
@@ -114,6 +116,12 @@ jobs:
114
116
  - run: npx @dogfood-lab/study-swarm@latest lint dispatches/
115
117
  ```
116
118
 
119
+ ### Pin a dispatch for replay (`dispatch.lock.json`)
120
+
121
+ A grounded, verified dispatch is only auditable if you can say *what produced it*. `study-swarm lock` writes a companion lockfile that content-addresses, per research agent, the **resolved model id** (never a floating alias), the **SHA-256 of the byte-exact prompt**, and the **SHA-256 of the tool schema** it was given, plus the external **verifier receipt** — rolled into one `lock_sha256`. `study-swarm lock --verify` re-derives those hashes and fails closed on any drift, so a changed prompt, a swapped model, or a shifted tool surface is caught — the [PIN_PER_STEP](https://github.com/dogfood-lab/study-swarm) reproducibility standard, made executable. The harness emits the record; the CLI stays zero-dependency and network-free, only canonicalizing (RFC 8785), hashing, and validating it.
122
+
123
+ **It pins inputs, not outputs.** Pinning model + prompt + temperature does *not* make an LLM's output bit-identical — batch-invariance, floating-point non-associativity, mixture-of-experts routing, and silent provider drift are all outside an offline tool's control. So the lock gives you **replayable inputs and drift-detectable outputs**, never "deterministic replay." The design is grounded, citation by citation, in [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) — the first dispatch to ship its own lock ([`examples/study-swarm-lock.lock.json`](examples/study-swarm-lock.lock.json)).
124
+
117
125
  ## Why it works, in one breath
118
126
 
119
127
  **Current** — the field moves fast; demanding specific studies-with-years keeps designs from shipping 18 months behind. **Functional** — evidence shows what *fails*, not just what works (explanations can increase over-reliance on *wrong* AI — Bansal et al. 2021, [arXiv:2006.14779](https://arxiv.org/abs/2006.14779)). **Safe** — the verifier-protected envelope is the architecture the evidence supports, and the protocol enforces it on its own output. Sourcing isn't academic theater; it's the evidence trail.
@@ -124,7 +132,7 @@ jobs:
124
132
 
125
133
  ## Status
126
134
 
127
- A working protocol, externally verified by its own machinery — a different model family checks its citations (see the proof above). **v1.1** sharpens the verifier where the first release was silent: decomposed/ternary groundedness, generation-time grounding, an oracle-gated cascade for combining lenses, and calibrated abstention — each grounded in the verified v1.1 dispatch. This repo is the public reference; [PROTOCOL.md](PROTOCOL.md) is the executable shape. Part of the [dogfood-lab](https://github.com/dogfood-lab) family — methods and showcases for building in the AI era.
135
+ A working protocol, externally verified by its own machinery — a different model family checks its citations (see the proof above). **v1.1** sharpens the verifier where the first release was silent: decomposed/ternary groundedness, generation-time grounding, an oracle-gated cascade for combining lenses, and calibrated abstention — each grounded in the verified v1.1 dispatch. **v1.2** makes a dispatch byte-replayable: `study-swarm lock` pins the resolved model, prompt, and tool schema per step plus the verifier receipt, and `lock --verify` fails closed on drift. This repo is the public reference; [PROTOCOL.md](PROTOCOL.md) is the executable shape. Part of the [dogfood-lab](https://github.com/dogfood-lab) family — methods and showcases for building in the AI era.
128
136
 
129
137
  MIT licensed.
130
138
 
package/README.pt-BR.md CHANGED
@@ -76,6 +76,8 @@ npm i -g @dogfood-lab/study-swarm # or run ad-hoc: npx @dogfood-lab/study-sw
76
76
  | `study-swarm protocol` | Imprime o protocolo completo – as cinco etapas, a tabela de interrupção e o padrão de referência. |
77
77
  | `study-swarm new <slug>` | Cria um arquivo `<slug>.dispatch.md` com o esqueleto das cinco etapas para preencher. |
78
78
  | `study-swarm lint [--json] <path…>` | Verifica a *fundamentação da pesquisa* de uma análise em relação ao padrão de referência – cada achado precisa de um autor, um ano e um identificador resolvível (arXiv / DOI / URL); “estudos mostram…” sem embasamento é rejeitado. Sai com `1` em caso de violações, para que valide o CI. Um `<path>` pode ser um arquivo, um diretório (analisado recursivamente para `*.dispatch.md`) ou `-` para stdin; `--json` emite um relatório legível por máquina. |
79
+ | `study-swarm lock <dispatch> --from <orchestration.json>` | Fixe um envio para reprodução – crie o arquivo `<dispatch>.lock.json` com informações de conteúdo, conforme o agente da Etapa 2, incluindo o **ID do modelo resolvido** + o **SHA-256 do prompt exato em bytes** + o **SHA-256 do esquema da ferramenta**, mais o **comprovante do verificador** da Etapa 4, tudo reunido em um único arquivo `lock_sha256`. |
80
+ | `study-swarm lock --verify <dispatch> [--from …]` | Recalcule esses hashes e verifique se correspondem ao bloqueio; qualquer desvio resulta em saída `1`, portanto, controla o CI como um arquivo de bloqueio de pacote. Sem `--from`, verifica a própria integridade do bloqueio. |
79
81
 
80
82
  `lint` é determinístico – sem chamadas de modelo – portanto, é seguro no CI. Ele aplica o **padrão de referência da Etapa 3** localmente; a verificação baseada em modelo da **Etapa 4** ainda depende de [`roleos verify-citations`](https://github.com/mcp-tool-shop-org/role-os) → prism.
81
83
 
@@ -88,7 +90,7 @@ study-swarm lint my-decision.dispatch.md # enforce the sourcing standard
88
90
  roleos verify-citations my-decision.dispatch.md # model-based Step 4 (different family, via prism)
89
91
  ```
90
92
 
91
- Duas análises completas e “limpas” são fornecidas como referência: [`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md) (a decisão central do protocolo, concisa) e [`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md) (o projeto completo da v1.1 – 27 citações, todas validadas externamente).
93
+ Três envios completos e validados são enviados como referência: [`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md) (a decisão central do protocolo, concisa), [`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md) (o design completo da versão 1.1 – 27 citações, todas verificadas externamente) e [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) (o design do bloqueio da versão 1.2 – 39 citações, controlado pelo executor, e o primeiro envio a incluir seu próprio bloqueio).
92
94
 
93
95
  ### Valide no CI
94
96
 
@@ -114,6 +116,12 @@ jobs:
114
116
  - run: npx @dogfood-lab/study-swarm@latest lint dispatches/
115
117
  ```
116
118
 
119
+ ### Fixe um envio para reprodução (`dispatch.lock.json`)
120
+
121
+ Um envio validado e comprovado só pode ser auditado se você puder dizer *o que o gerou*. `study-swarm lock` cria um arquivo de bloqueio complementar que, por meio do agente de pesquisa, contém informações sobre o **ID do modelo resolvido** (nunca um alias flutuante), o **SHA-256 do prompt exato em bytes** e o **SHA-256 do esquema da ferramenta** fornecido, mais o **comprovante externo do verificador** – tudo reunido em um único arquivo `lock_sha256`. `study-swarm lock --verify` recalcula esses hashes e falha se houver qualquer desvio, portanto, um prompt alterado, um modelo substituído ou uma ferramenta modificada são detectados – o padrão de reprodutibilidade [PIN_PER_STEP](https://github.com/dogfood-lab/study-swarm), que pode ser executado. O sistema emite o registro; a CLI permanece sem dependências e independente da rede, apenas normalizando (RFC 8785), calculando hashes e validando.
122
+
123
+ **Ele fixa as entradas, não as saídas.** Fixar modelo + prompt + temperatura *não* torna a saída de um LLM bit a bit idêntica – invariância em lote, não associatividade de ponto flutuante, roteamento de mistura de especialistas e desvio silencioso do provedor estão todos fora do controle de uma ferramenta offline. Portanto, o bloqueio fornece **entradas reproduzíveis e saídas com detecção de desvio**, nunca "reprodução determinística". O design é fundamentado, citação por citação, em [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) – o primeiro envio a incluir seu próprio bloqueio ([`examples/study-swarm-lock.lock.json`](examples/study-swarm-lock.lock.json)).
124
+
117
125
  ## Por que funciona, em poucas palavras
118
126
 
119
127
  **Atual** – o campo evolui rapidamente; exigir estudos específicos com anos evita que os projetos sejam lançados com 18 meses de atraso. **Funcional** – a evidência mostra o que *falha*, não apenas o que funciona (explicações podem aumentar a dependência excessiva em IA *incorreta* – Bansal et al. 2021, [arXiv:2006.14779](https://arxiv.org/abs/2006.14779)). **Seguro** – o envelope protegido pelo verificador é a arquitetura que a evidência suporta, e o protocolo a aplica em sua própria saída. A referência não é um exercício acadêmico; é o rastro da evidência.
@@ -124,7 +132,7 @@ jobs:
124
132
 
125
133
  ## Status
126
134
 
127
- Um protocolo funcional, validado externamente por sua própria ferramenta – uma família de modelos diferente verifica suas citações (veja a prova acima). A **v1.1** aprimora o verificador onde a primeira versão estava em silêncio: fundamentação decomposta/ternária, fundamentação no momento da geração, uma cascata validada pelo oráculo para combinar lentes e abstinência calibrada – cada um com base na análise v1.1 validada. Este repositório é a referência pública; [PROTOCOL.md](PROTOCOL.md) é a forma executável. Faz parte da família [dogfood-lab](https://github.com/dogfood-lab) – métodos e exemplos para construir na era da IA.
135
+ Um protocolo funcional, verificado externamente por sua própria estrutura – uma família de modelos diferente verifica suas citações (veja a prova acima). A **versão 1.1** aprimora o verificador, onde a primeira versão era silenciosa: fundamentação decomposta/ternária, fundamentação no momento da geração, uma cascata controlada por um oráculo para combinar lentes e abstinência calibrada – cada um fundamentado no envio verificado da versão 1.1. A **versão 1.2** torna um envio reproduzível em bytes: `study-swarm lock` fixa o modelo resolvido, o prompt e o esquema da ferramenta por etapa, mais o comprovante do verificador, e `lock --verify` falha se houver desvio. Este repositório é a referência pública; [PROTOCOL.md](PROTOCOL.md) é a forma executável. Parte da família [dogfood-lab](https://github.com/dogfood-lab) – métodos e demonstrações para construir na era da IA.
128
136
 
129
137
  Licenciado sob MIT.
130
138
 
package/README.zh.md CHANGED
@@ -76,6 +76,8 @@ npm i -g @dogfood-lab/study-swarm # or run ad-hoc: npx @dogfood-lab/study-sw
76
76
  | `study-swarm protocol` | 打印完整的协议——五个步骤、停止表以及来源标准。 |
77
77
  | `study-swarm new <slug>` | 创建一个`<slug>.dispatch.md`文件,其中包含五步流程的框架,以便进行填充。 |
78
78
  | `study-swarm lint [--json] <path…>` | 根据来源标准检查工作流程的*研究扎实性*——每条研究结果都需要作者、年份和一个可解析的标识符(arXiv / DOI / URL);“研究表明……”这种含糊其辞的方式将被拒绝。如果存在违规行为,则退出代码为`1`,以便在CI中进行筛选。`<path>`可以是文件、目录(递归地检查所有`.dispatch.md`文件),或者`-`表示标准输入;`--json`会输出机器可读的报告。 |
79
+ | `study-swarm lock <dispatch> --from <orchestration.json>` | 将一个调度固定下来以便重放——编写 `<dispatch>.lock.json`,其中包含基于内容的哈希值,按照步骤 2 中的代理进行操作,包括**已解析的模型 ID** + **字节级精确提示的 SHA-256 值** + **工具模式的 SHA-256 值**,以及步骤 4 中的**验证者凭证**,并将它们组合成一个 `lock_sha256`。 |
80
+ | `study-swarm lock --verify <dispatch> [--from …]` | 重新计算这些哈希值并确认它们与锁匹配;如果出现任何偏差,则退出并返回 1,因此它就像软件包的 lock 文件一样,可以控制 CI 流程。如果不使用 `--from` 参数,则会检查锁自身的完整性。 |
79
81
 
80
82
  `lint`是确定性的——不调用任何模型——因此可以在CI中安全使用。它在本地强制执行**第3步的来源标准**;基于模型的**第4步**验证仍然依赖于[`roleos verify-citations`](https://github.com/mcp-tool-shop-org/role-os) → prism。
81
83
 
@@ -88,7 +90,7 @@ study-swarm lint my-decision.dispatch.md # enforce the sourcing standard
88
90
  roleos verify-citations my-decision.dispatch.md # model-based Step 4 (different family, via prism)
89
91
  ```
90
92
 
91
- 两个完整的、符合“lint”规范的工作流程示例以供参考:[`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md)(协议的核心决策,简洁)和[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)(完整的v1.1设计流程——27条引用,每一条都经过外部验证)。
93
+ 三个完整的、经过清理的调度文件作为参考发布:[`examples/study-swarm-self.dispatch.md`](examples/study-swarm-self.dispatch.md)(协议的核心决策,简洁),[`examples/study-swarm-v1_1.dispatch.md`](examples/study-swarm-v1_1.dispatch.md)(完整的 v1.1 设计版本——27 处引用,每一处都经过外部验证),以及 [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md)(v1.2 的锁设计——39 处引用,通过运行器进行控制,并且是第一个发布其自身锁的调度文件)。
92
94
 
93
95
  ### 在CI中进行筛选
94
96
 
@@ -114,6 +116,12 @@ jobs:
114
116
  - run: npx @dogfood-lab/study-swarm@latest lint dispatches/
115
117
  ```
116
118
 
119
+ ### 将一个调度固定下来以便重放 (`dispatch.lock.json`)
120
+
121
+ 只有当你能够说明*是什么产生了它*时,才能对经过验证的调度进行审计。`study-swarm lock` 编写一个配套的锁文件,该文件基于内容进行哈希处理,按照研究代理进行操作,包括**已解析的模型 ID(绝不使用浮动别名)**、**字节级精确提示的 SHA-256 值**以及**工具模式的 SHA-256 值**,以及外部**验证者凭证**——所有这些都组合成一个 `lock_sha256`。`study-swarm lock --verify` 重新计算这些哈希值,并且如果出现任何偏差,则会失败并停止,因此,如果提示、模型或工具发生更改,系统都会检测到——这是 [PIN_PER_STEP](https://github.com/dogfood-lab/study-swarm) 可重复性标准的可执行版本。该框架会输出记录;CLI 保持零依赖和无网络状态,仅进行规范化(RFC 8785)、哈希处理和验证。
122
+
123
+ **它固定输入,而不是输出。** 固定模型 + 提示 + 温度并不能使 LLM 的输出完全相同——批处理不变性、浮点数非结合律、混合专家路由以及无声提供者漂移都超出了离线工具的控制范围。因此,该锁为您提供**可重放的输入和可检测偏差的输出**,而不是“确定性重放”。该设计基于 [`examples/study-swarm-lock.dispatch.md`](examples/study-swarm-lock.dispatch.md) 中的每一处引用,并且是第一个发布其自身锁([`examples/study-swarm-lock.lock.json`](examples/study-swarm-lock.lock.json))的调度文件。
124
+
117
125
  ## 用一句话概括其工作原理
118
126
 
119
127
  **及时性**——该领域发展迅速;要求提供具体的带有年份的研究,可以防止设计落后18个月。**功能性**——证据表明哪些*方法失败*,而不仅仅是哪些有效(解释可能会增加对*错误*人工智能的过度依赖——Bansal等人,2021年,[arXiv:2006.14779](https://arxiv.org/abs/2006.14779))。**安全性**——受验证器保护的范围是证据支持的架构,并且协议对其自身的输出进行强制执行。来源不是学术上的形式主义;它是证据链。
@@ -124,7 +132,7 @@ jobs:
124
132
 
125
133
  ## 状态
126
134
 
127
- 一个可用的协议,其自身的机制对其进行了外部验证——不同的模型系列检查其引用(参见上面的证明)。**v1.1**改进了验证器,弥补了第一个版本中存在的不足:分解/三元扎实性、生成时扎实性、由预言机控制的级联机制以及经过校准的弃权——每项都基于经过验证的v1.1工作流程。此仓库是公共参考;[PROTOCOL.md](PROTOCOL.md)是可执行的形式。它是[dogfood-lab](https://github.com/dogfood-lab)系列的一部分——用于在人工智能时代构建方法和示例。
135
+ 一个可工作的协议,由其自身的机制进行外部验证——不同的模型系列会检查其引用(参见上面的证明)。**v1.1** 改进了验证器,而第一个版本是静默的:分解/三元接地、生成时接地、用于组合透镜的 oracle 门控级联以及校准后的弃权——所有这些都基于经过验证的 v1.1 调度。**v1.2** 使调度可以进行字节级别的重放:`study-swarm lock` 会按照步骤固定已解析的模型、提示和工具模式,并添加验证者凭证,而 `lock --verify` 则会在出现偏差时失败并停止。此仓库是公共参考;[PROTOCOL.md](PROTOCOL.md) 是可执行的形式。它是 [dogfood-lab](https://github.com/dogfood-lab) 系列的一部分——用于在人工智能时代构建的各种方法和示例。
128
136
 
129
137
  采用MIT许可证。
130
138
 
@@ -22,6 +22,13 @@ COMMANDS
22
22
  lint [--json] <path...> Check dispatches' citations against the sourcing standard.
23
23
  A <path> may be a file, a directory (linted recursively for
24
24
  *.dispatch.md), or "-" to read one dispatch from stdin.
25
+ lock <dispatch> --from <orchestration.json>
26
+ Emit <dispatch>.lock.json — pin (per Step-2 agent) the resolved
27
+ model + SHA-256 of the byte-exact prompt + SHA-256 of the tool
28
+ schema, plus the verifier receipt, rolled into one lock_sha256.
29
+ lock --verify <dispatch> [--from <orchestration.json>]
30
+ Re-derive the deterministic hashes and assert they match the lock;
31
+ drift exits 1 (gates CI). Without --from, checks lock self-integrity.
25
32
  help Show this help.
26
33
  version Print the version.
27
34
 
@@ -47,7 +54,7 @@ function fail(code, msg) {
47
54
  // Short hash of the vendored PROTOCOL.md, so a scaffolded dispatch records the exact
48
55
  // methodology version it was authored against (the package vendors PROTOCOL.md for this).
49
56
  function protocolHash() {
50
- try { return createHash('sha256').update(readFileSync(PROTOCOL_PATH)).digest('hex').slice(0, 16); }
57
+ try { return createHash('sha256').update(normText(readFileSync(PROTOCOL_PATH, 'utf8'))).digest('hex').slice(0, 16); }
51
58
  catch { return 'unknown'; }
52
59
  }
53
60
 
@@ -257,12 +264,187 @@ function cmdLint(args) {
257
264
  process.exit(anyFail ? 1 : 0);
258
265
  }
259
266
 
267
+ // --- lock core (dispatch.lock.json — the PIN_PER_STEP feature) ------------------
268
+ // Design + research grounding: examples/study-swarm-lock.dispatch.md (choices L1-L11).
269
+ // The CLI is a PURE FUNCTION of provided bytes: the orchestration harness emits the record
270
+ // (resolved models + byte-exact prompts + tool schemas + verifier receipt); the CLI only
271
+ // canonicalizes + hashes + validates it. No network, no model calls (L2).
272
+
273
+ const LOCK_SCHEMA = 'dispatch.lock/v1';
274
+
275
+ // Self-describing digest "sha256-<base64>" — the W3C Subresource Integrity form: algorithm-
276
+ // prefixed (so it's algorithm-agile) and used fail-closed on mismatch (L9; lock dispatch finding 38).
277
+ function sriBytes(buf) { return 'sha256-' + createHash('sha256').update(buf).digest('base64'); }
278
+ // Normalize TEXT before hashing so the same content hashes identically across platforms — strip a
279
+ // BOM, fold CRLF/CR -> LF, NFC-normalize. Without this, a CRLF working tree (Windows) and an LF
280
+ // checkout (git/CI) produce different hashes — the exact cross-platform drift our Q2 findings warn
281
+ // about (RFC 8259 BOM, UAX #15 NFC, and CRLF/LF). Applied to every text input that gets hashed.
282
+ function normText(s) { s = String(s); if (s.charCodeAt(0) === 0xFEFF) s = s.slice(1); return s.replace(/\r\n?/g, '\n').normalize('NFC'); }
283
+ function sriText(str) { return sriBytes(Buffer.from(normText(str), 'utf8')); }
284
+
285
+ // RFC 8785 (JCS) canonical JSON, for the structured JSON the CLI assembles ITSELF (the tool
286
+ // surface and the lock body): NFC-normalize strings, sort object keys by UTF-16 code unit (JS
287
+ // default string sort), no inter-token whitespace, ECMAScript-shortest numbers, UTF-8 (L4).
288
+ // The PROMPT is NOT JCS-restructured — it is the literal string the model conditioned on, so it is
289
+ // hashed as text (L3; JWS/DSSE hash-known-bytes rule, findings 12/23) under the SAME newline/BOM/NFC
290
+ // normalization (normText) so the same prompt hashes identically across platforms (findings 10/11).
291
+ function jcs(value) {
292
+ const ser = (v) => {
293
+ if (v === null) return 'null';
294
+ const t = typeof v;
295
+ if (t === 'boolean') return v ? 'true' : 'false';
296
+ if (t === 'number') {
297
+ if (!Number.isFinite(v)) throw new Error('JCS: non-finite number not allowed');
298
+ return JSON.stringify(v); // ECMAScript Number->String shortest round-trip
299
+ }
300
+ if (t === 'string') return JSON.stringify(normText(v));
301
+ if (Array.isArray(v)) return '[' + v.map(ser).join(',') + ']';
302
+ if (t === 'object') {
303
+ return '{' + Object.keys(v).sort()
304
+ .map((k) => JSON.stringify(normText(k)) + ':' + ser(v[k])).join(',') + '}';
305
+ }
306
+ throw new Error(`JCS: unsupported type ${t}`);
307
+ };
308
+ return ser(value);
309
+ }
310
+ function jcsDigest(value) { return sriBytes(Buffer.from(jcs(value), 'utf8')); }
311
+
312
+ // The lock sits beside its dispatch: <dir>/<stem>.lock.json (stem strips a trailing .dispatch.md).
313
+ function lockPathFor(dispatch) {
314
+ const base = dispatch.split(/[\\/]/).pop().replace(/(\.dispatch)?\.md$/i, '');
315
+ return join(dirname(dispatch), `${base}.lock.json`);
316
+ }
317
+
318
+ // Build the lock object from the dispatch bytes + the harness-emitted orchestration record.
319
+ function buildLockObject(dispatchPath, orchestration) {
320
+ const dispatchText = readFileSync(dispatchPath, 'utf8');
321
+ const protocolText = readFileSync(PROTOCOL_PATH, 'utf8');
322
+ if (!orchestration || !Array.isArray(orchestration.steps) || orchestration.steps.length === 0) {
323
+ fail(2, 'orchestration record has no non-empty "steps" array');
324
+ }
325
+ const steps = orchestration.steps.map((s, i) => {
326
+ const need = (k) => {
327
+ if (s == null || s[k] === undefined || s[k] === null) fail(2, `orchestration step ${i + 1} is missing "${k}"`);
328
+ return s[k];
329
+ };
330
+ const rec = {
331
+ question_id: String(need('question_id')),
332
+ resolved_model: String(need('resolved_model')), // L6 — the resolved id, never an alias
333
+ prompt_sha256: sriText(String(need('prompt'))), // L3 — text-normalized (LF/NFC/BOM), not JCS-restructured
334
+ tool_schema_sha256: jcsDigest(need('tool_schema')), // L5 — canonicalized tool surface
335
+ };
336
+ if (s.schema_dialect) rec.schema_dialect = String(s.schema_dialect); // L5 — dialect is contract
337
+ if (s.params && typeof s.params === 'object') rec.params = s.params;
338
+ // L7 — output hash for DRIFT DETECTION only (not determinism). The harness may ship the raw
339
+ // output (the CLI hashes it) OR a pre-computed output_sha256 (large outputs needn't be shipped).
340
+ if (typeof s.output_sha256 === 'string') rec.output_sha256 = s.output_sha256;
341
+ else if (s.output !== undefined) rec.output_sha256 = typeof s.output === 'string' ? sriText(s.output) : jcsDigest(s.output);
342
+ return rec;
343
+ });
344
+ const lock = {
345
+ schema: LOCK_SCHEMA,
346
+ study_swarm_version: VERSION,
347
+ protocol_sha256: sriText(protocolText), // pins the methodology version (text-normalized)
348
+ dispatch_sha256: sriText(dispatchText), // pins the dispatch text (text-normalized)
349
+ steps,
350
+ };
351
+ if (orchestration.verification && typeof orchestration.verification === 'object') {
352
+ lock.verification = orchestration.verification; // L10 — the external-verifier receipt
353
+ }
354
+ // L1/L9 — rollup over the whole body (this object, before lock_sha256 is added) as ONE flat
355
+ // canonical object: distinct keys give domain separation, the steps array's explicit length
356
+ // commits to exactly N steps (no odd-leaf duplication).
357
+ lock.lock_sha256 = jcsDigest(lock);
358
+ return lock;
359
+ }
360
+
361
+ // Verify a lock: self-integrity always; source-drift too when an orchestration record is supplied.
362
+ // Strict-match, fail-closed (L8): returns a list of problems (empty = clean).
363
+ function verifyLockObject(dispatchPath, lockPath, orchestration) {
364
+ let stored;
365
+ try { stored = JSON.parse(readFileSync(lockPath, 'utf8')); }
366
+ catch (err) { fail(2, `cannot read lock ${lockPath}: ${err && err.code ? err.code : err.message}`); }
367
+ const problems = [];
368
+ // 1) Self-integrity — recompute lock_sha256 over the stored body (detects a hand-edited lock).
369
+ if (!stored || typeof stored !== 'object' || typeof stored.lock_sha256 !== 'string') {
370
+ problems.push('lock has no lock_sha256 string');
371
+ } else {
372
+ const { lock_sha256, ...body } = stored;
373
+ const recomputed = jcsDigest(body);
374
+ if (lock_sha256 !== recomputed) {
375
+ problems.push(`lock_sha256 mismatch (the lock body was edited): stored ${lock_sha256} != recomputed ${recomputed}`);
376
+ }
377
+ }
378
+ // 2) Source drift — re-derive the deterministic hashes from the live inputs and strict-compare.
379
+ if (orchestration) {
380
+ const fresh = buildLockObject(dispatchPath, orchestration);
381
+ const cmp = (label, a, b) => { if (a !== b) problems.push(`${label} drift: lock ${b} != re-derived ${a}`); };
382
+ cmp('lock_sha256', fresh.lock_sha256, stored.lock_sha256); // the authoritative rollup guard
383
+ cmp('protocol_sha256', fresh.protocol_sha256, stored.protocol_sha256);
384
+ cmp('dispatch_sha256', fresh.dispatch_sha256, stored.dispatch_sha256);
385
+ const a = fresh.steps || [], b = Array.isArray(stored.steps) ? stored.steps : [];
386
+ if (a.length !== b.length) problems.push(`step count drift: re-derived ${a.length} != lock ${b.length}`);
387
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
388
+ for (const k of ['question_id', 'resolved_model', 'prompt_sha256', 'tool_schema_sha256']) {
389
+ cmp(`steps[${i}].${k}`, a[i][k], b[i][k]);
390
+ }
391
+ if (a[i].output_sha256 || b[i].output_sha256) cmp(`steps[${i}].output_sha256`, a[i].output_sha256, b[i].output_sha256);
392
+ }
393
+ }
394
+ return problems;
395
+ }
396
+
397
+ function cmdLock(args) {
398
+ const verify = args.includes('--verify');
399
+ const rest = args.filter((a) => a !== '--verify');
400
+ let orchPath = null;
401
+ const fromIdx = rest.indexOf('--from');
402
+ if (fromIdx !== -1) {
403
+ orchPath = rest[fromIdx + 1];
404
+ if (!orchPath) fail(2, 'usage: --from <orchestration.json>');
405
+ rest.splice(fromIdx, 2);
406
+ }
407
+ const dispatch = rest[0];
408
+ if (!dispatch) {
409
+ fail(2, 'usage: study-swarm lock <dispatch> --from <orchestration.json> | study-swarm lock --verify <dispatch> [--from <orchestration.json>]');
410
+ }
411
+ if (!existsSync(dispatch)) fail(2, `dispatch not found: ${dispatch}`);
412
+ let orchestration = null;
413
+ if (orchPath) {
414
+ if (!existsSync(orchPath)) fail(2, `orchestration record not found: ${orchPath}`);
415
+ try { orchestration = JSON.parse(readFileSync(orchPath, 'utf8')); }
416
+ catch (err) { fail(2, `orchestration record is not valid JSON: ${err.message}`); }
417
+ }
418
+ const lockPath = lockPathFor(dispatch);
419
+
420
+ if (verify) {
421
+ if (!existsSync(lockPath)) fail(2, `no lock at ${lockPath} — create it with: study-swarm lock ${dispatch} --from <orchestration.json>`);
422
+ const problems = verifyLockObject(dispatch, lockPath, orchestration);
423
+ if (problems.length === 0) {
424
+ const scope = orchestration ? 'lock integrity verified + no source drift' : 'lock self-integrity verified (pass --from to also check source drift)';
425
+ process.stdout.write(`ok ${lockPath}: ${scope}.\n`);
426
+ process.exit(0);
427
+ }
428
+ process.stderr.write(`x ${lockPath}: ${problems.length} drift/integrity issue(s)\n`);
429
+ for (const p of problems) process.stderr.write(` - ${p}\n`);
430
+ process.exit(1);
431
+ }
432
+
433
+ if (!orchestration) {
434
+ fail(2, 'study-swarm lock <dispatch> requires --from <orchestration.json> — the harness-emitted record of resolved models + byte-exact prompts + tool schemas + the verifier receipt');
435
+ }
436
+ const lock = buildLockObject(dispatch, orchestration);
437
+ writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\n', 'utf8');
438
+ process.stdout.write(`Created ${lockPath}\nlock_sha256: ${lock.lock_sha256}\nVerify with: study-swarm lock --verify ${dispatch} --from ${orchPath}\n`);
439
+ }
440
+
260
441
  function main(argv) {
261
442
  const [cmd, ...rest] = argv;
262
443
  switch (cmd) {
263
444
  case 'protocol': return cmdProtocol();
264
445
  case 'new': return cmdNew(rest[0]);
265
446
  case 'lint': return cmdLint(rest);
447
+ case 'lock': return cmdLock(rest);
266
448
  case 'version': case '--version': case '-v':
267
449
  return void process.stdout.write(VERSION + '\n');
268
450
  case 'help': case '--help': case '-h': case undefined: