mcpField
I
immune

immune

github.com/mathews-tomエージェントワークフロー33789 回インストール2 日前に更新
リポジトリ

immune について

immune は、分野別の肯定的なパターンと既知の誤りを使い、テキストやコードなどを検査する適応型スキルです。記憶をタスクに合わせて絞り込み、検査結果を反映して更新します。

主な機能

  1. 01分野別コンテンツ検査
  2. 02肯定的な指針の注入
  3. 03記憶のホット・コールド分類
  4. 04タスクに応じたパターン検索
  5. 05脅威の重複排除と再有効化

活用シーン

  1. 01コードのよくある問題の確認
  2. 02保存済み指針に沿った文章レビュー
  3. 03複数分野にまたがる出力検査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mathews-tom/armory --skill immune

インストール後、Claude Code で/immuneを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

cheatsheet_memory.json
config.yaml
immune_memory.json
agents/
immune-scan.md
evals/
cases.yaml
scripts/
retrieve.py

詳細

免疫システム v3 — チートシート+免疫のハイブリッド

相互に補完する2つのメモリを備えた、ハイブリッド適応システムとして動作します。

  • チートシート(肯定的なパターン):出力品質を高めるため、生成の前に挿入されるドメイン固有の戦略です
  • 免疫(否定的なパターン):既知のエラーを検出し、生成の後に新たな脅威を発見する抗体です

どちらのメモリも、コンテキストを簡潔に保つためにHot/Cold階層化を使用します。

入力の解析

ユーザーはスキャン対象のコンテンツを指定して呼び出します。次のパラメーターを解析します。

  • input:スキャンするテキスト/コード/コンテンツ(必須。インラインまたはコンテキストから取得)
  • domain:次のいずれか:fitness、code、writing、research、strategy、webdesign、_global(デフォルト:自動検出)
  • domains:ドメインの配列(単一のdomainを上書き)。例:domains=fitness,code
  • constraints:出力が満たすべき具体的な要件(任意)
  • mode:full(チートシート+スキャン、デフォルト)|scan-only(チートシートを省略)|cheatsheet-only(チートシートを返し、スキャンしない)
/immune よくある落とし穴がないか、この関数を確認してください → domains=["code"](自動検出)、mode=full /immune domain=fitness この筋力トレーニングプログラムを確認してください → domains=["fitness"](明示的に指定) /immune domains=fitness,code このワークアウト生成APIを確認してください → domains=["fitness", "code"](複数ドメイン) /immune → 会話内の直近の出力をスキャンします

インラインテキストが指定されていない場合は、会話内で直近の実質的な出力をスキャンします。

ドメインの自動検出: このスキルと同じ場所にあるconfig.yamlを読み込み、コンテンツをdomain_keywordsと照合します。明確に一致するものがない場合は、["_global"]を使用します。単一のdomain文字列が指定された場合は、配列に格納します:domains = [domain]。

タスク条件付き検索(v3.1.0以降)

抗体とチートシートの戦略には、タスクごとのフィルタリングに使用する任意のtriggersフィールドを設定できます。これは、Memento-Skillsの内省ループ(arXiv 2603.18743)における読み取りフェーズを実装するもので、現在のタスクと過去のコンテキストとの語彙的な重複度に基づいてエントリを順位付けします。

スキーマ(追加項目、任意):

{
  "id": "AB-042",
  "domains": ["code"],
  "pattern": "SQL injection via string concatenation",
  "severity": "critical",
  "correction": "Use parameterized queries",
  "triggers": {
    "task_signatures": ["code query review sql", "audit code sql"],
    "domains": ["code"]
  }
}

後方互換性: triggersのないエントリは常に有効として動作します(v3.0.0の動作)。config.yamlのtask_conditioned_retrieval: trueフラグを有効にすると、フィルターが適用されます。無効の場合は、タスクにかかわらずすべてのエントリが読み込まれます。

ランキングヘルパー: scripts/retrieve.pyがスコアリングロジックを実装します。呼び出し元(スキャナーエージェント、P2のskill-librarian、P3のskill-routerを含む)は、階層分類の前にretrieve(prompt, entries, active_domains, historical_success)を呼び出して、順位付けされたサブセットを取得します。スコアリングでは、scripts/task_signature.pyの正規化されたタスクシグネチャに対するJaccard類似度に、evals/history.jsonlから算出されたエントリごとの任意の成功率を乗じます。

読み込み時(フェーズ0のチートシート、フェーズ1の抗体)は、ドメインフィルターの後、Hot/Cold階層分類の前にretrieveステップを適用します。

  1. 現在のタスクに対してtask_signature(prompt)を計算します。
  2. アクティブなドメインのセットを指定して、エントリをretrieve(...)に渡します。
  3. 返されたサブセットのみを、以下の階層分類に渡します。

検索時にフィルターで除外されたエントリは、Hot/Coldに到達しません。これにより、スキャンのコンテキストを簡潔に保ち、タスクに集中できます。

実行

ステップ 0 — チートシートの注入(有効なパターン)

mode == "scan-only" の場合は、このステップをスキップします。

0a. チートシートを読み込む: cheatsheet_memory.json を読み込みます(このスキルと同じ場所にあります)。

0b. ドメインで絞り込む: 各戦略の domains が検出された domains のいずれかと重複する戦略、または domains に "_global" が含まれる戦略を残します。

0c. ティアに分類する(抗体と同じロジック): 次のいずれかに該当する戦略はHOTです。

  • effectiveness >= 0.7
  • seen_count >= 3
  • last_seen が30日以内

それ以外はCOLDです。

0d. HOT戦略の上限を設定する: 有効性の降順、次に seen_count の降順で並べ替えます。 最大 15 件を残します(config.yaml → cheatsheet.max_hot)。

0e. チートシートブロックを作成する: HOT戦略をXML形式にします。

<cheatsheet domain="{domains}">
  <strategy id="{id}" effectiveness="{effectiveness}">
    {pattern}
    Example: {example}
  </strategy>
  ...
</cheatsheet>

COLD戦略がある場合は、次の1行を追加します。

<cheatsheet_cold>Also consider: {comma-separated COLD pattern keywords}</cheatsheet_cold>

mode == "cheatsheet-only" の場合は、チートシートブロックを出力してここで終了します。

ログ:

[IMMUNE] Cheatsheet: {n_hot} HOT + {n_cold} COLD strategies (domains: {domains})

0f. チートシートをユーザーに提示する: 単独で実行されている場合(/immune)、次の生成時に適用するコンテキストとしてチートシートを表示します。別のシステムから呼び出された場合は、プロンプトに挿入するXMLブロックを返します。

ステップ 1 — 抗体の読み込みと分類(HOT/COLD)

immune_memory.json と config.yaml を読み込みます(このスキルと同じ場所にあります)。

1a. ドメインで絞り込む: 各抗体の domains が検出された domains のいずれかと重複する抗体、または domains に "_global" が含まれる抗体を残します。

後方互換性: 抗体に "domains"(配列)の代わりに "domain"(文字列)がある場合、domains = [domain] として扱います。

1b. ティアに分類する: 絞り込んだ抗体ごとに、次のいずれかに該当する場合はHOTに分類します。

  • severity == "critical"
  • seen_count >= 3
  • last_seen が今日の日付から30日以内

それ以外はCOLDです。

1c. HOT抗体の上限を設定する: HOTを、severity(critical > warning > info)、次に seen_count の降順で並べ替えます。 最大 15 件を残します(config.yaml → tiers.hot.max_per_scan)。 HOTに該当するものが15件を超える場合、超過分はCOLDに移します。

1d. COLDの概要を作成する: 各COLD抗体について、pattern フィールドから短いキーワードを抽出します。 カンマ区切りのリストとして結合します。例:"SQL transactions, épicondylite, debug flags, tautologies"

ログ:

[IMMUNE] Tier split: {n_hot} HOT + {n_cold} COLD / {total} total (domains: {domains})
ステップ 2 — スキャン

次のXML形式のプロンプトを使って、immune-scan エージェント(Haiku)を起動します。

<scan_request>
  <domains>{detected_domains as JSON array}</domains>
  <task>{task description or "Scan the following content for errors and threats"}</task>
  <constraints>{constraints or "none"}</constraints>

  <content>
{the input text/code/content to scan}
  </content>

  <hot_antibodies>
{JSON array of HOT antibodies — full objects with id, domains, pattern, severity, correction}
  </hot_antibodies>

  <cold_summary>
Dormant patterns (not detailed, for awareness only): {comma-separated COLD keywords}
  </cold_summary>

  <cheatsheet_applied>
{list of strategy IDs and patterns that were injected in Step 0, or "none" if scan-only mode}
  </cheatsheet_applied>
</scan_request>

ログ:[IMMUNE] Scanning... ({n_hot} active antibodies) 結果を待ちます。

修正が適用された場合: ログ:[IMMUNE] Match {antibody_id}: {original} → {corrected} 新しい脅威が検出された場合: ログ:[IMMUNE] New threat: {pattern} 新しい戦略が検出された場合: ログ:[IMMUNE] New strategy: {pattern}

ステップ 3 — 免疫メモリを更新する(COLD の重複排除を含む)

現在の immune_memory.json を読み込みます。

3a. マッチした HOT 抗体: スキャナーでマッチした各抗体の seen_count をインクリメントし、last_seen を今日の日付に更新します。

3b. 新しい脅威 — COLD と重複排除する: new_threats_detected にある各新しい脅威について:

  1. pattern をすべての COLD 抗体と照合します(ファジーマッチ — 同じドメイン + 類似したキーワード)。
  2. COLD 抗体とマッチする場合 → 再有効化します:
    • COLD 抗体の seen_count をインクリメントします
    • last_seen を今日の日付に更新します
    • ログに記録します:[IMMUNE] Reactivated COLD antibody {id}: {pattern}
    • 新しい抗体は作成しません(重複を防止します)
  3. COLD とのマッチがなく、auto_add_threats が true の場合 → 新しい抗体を作成します:
    • id: "AB-{next_number}"
    • domains: 脅威の recommended_antibody.domains から取得(配列)
    • pattern、severity、correction: 脅威の recommended_antibody から取得
    • seen_count: 1
    • first_seen: 今日の日付
    • last_seen: 今日の日付
    • ログに記録します:[IMMUNE] + New antibody {id}: {pattern}

3c. 統計を更新する:

  • stats.outputs_checked をインクリメントします
  • stats.issues_caught を修正件数 + 新しい脅威の件数分インクリメントします
  • stats.antibodies_total を現在の抗体数に更新します

immune_memory.json に書き戻します。

ログに記録します:[IMMUNE] Memory: {total} antibodies ({n_hot} hot, {n_cold} cold) | +{new} added | Reactivated: {reactivated}

ステップ 3b — カンニングペーパーのメモリを更新する(肯定的なパターン)

mode == "scan-only" の場合、またはスキャン結果に new_strategies_detected がない場合はスキップします。

現在の cheatsheet_memory.json を読み込みます。

3b-i. 重複排除: new_strategies_detected にある各新しい戦略について:

  1. すべての既存の戦略と照合します(ファジーマッチ — 重複するドメイン + 類似したパターン)。
  2. 既存の戦略とマッチする場合 → 強化します:
    • seen_count をインクリメントします
    • last_seen を今日の日付に更新します
    • effectiveness を調整します:new_eff = old_eff * 0.8 + reported_eff * 0.2(指数移動平均)
    • ログに記録します:[IMMUNE] Reinforced strategy {id}: {pattern} (eff: {old}→{new})
  3. マッチするものがなく、auto_add_strategies が true の場合 → 新しい戦略を作成します:
    • id: "{prefix}-{next_number}"(config.yaml → cheatsheet.id_prefix.{domain} から prefix を取得)
    • domains: 戦略から取得(配列)
    • pattern、example: 戦略から取得
    • effectiveness: 戦略から取得(または config.yaml → cheatsheet.default_effectiveness)
    • seen_count: 1
    • first_seen: 今日の日付
    • last_seen: 今日の日付
    • ログに記録します:[IMMUNE] + New strategy {id}: {pattern}

3b-ii. 有効性の低い項目を削除する: effectiveness < config.cheatsheet.min_effectiveness かつ seen_count >= 5 の戦略がある場合:

  • 削除します
  • ログに記録します:[IMMUNE] - Pruned strategy {id}: {pattern} (eff: {eff})

3b-iii. 統計を更新する:

  • stats.outputs_assisted をインクリメントします
  • 使用されたカンニングペーパーの戦略数分、stats.strategies_applied をインクリメントします
  • stats.strategies_total を現在の件数に更新します

cheatsheet_memory.json に書き戻します。

ログに記録します:[IMMUNE] Cheatsheet: {total} strategies | +{new} added | Reinforced: {reinforced}

ステップ 4 — 出力

問題がない場合:

───
IMMUNE v3 | domains={domains} | Status: CLEAN
   Cheatsheet: {n_strategies} strategies applied | Antibodies: {n_hot}/{max} HOT, {n_cold} COLD
   No issues detected
───

修正または脅威が見つかった場合:

───
IMMUNE v3 | domains={domains} | Status: {CORRECTED|FLAGGED}

Corrections Applied:
  [AB-XXX] {pattern} → {correction}

New Threats Detected:
  [{severity}] {pattern} — {suggested_correction}

Reactivated:
  [AB-XXX] {pattern} (was COLD, now HOT)

New Strategies Learned:
  [CS-XXX] {pattern} (eff: {effectiveness})

───
Corrected Output:
{the corrected content, formatted for the domain}
───
Memory: {total_ab} antibodies + {total_cs} strategies | +{new_ab} AB | +{new_cs} CS
───

次に、修正済みの出力を、対象ドメインに適した人が読みやすい形式で提示します。

エラー処理

  • immune_memory.json が存在しない場合:{"version": 3, "antibodies": [], "stats": {"outputs_checked": 0, "issues_caught": 0, "antibodies_total": 0}} を作成します
  • cheatsheet_memory.json が存在しない場合:{"version": 3, "strategies": [], "stats": {"outputs_assisted": 0, "strategies_applied": 0, "strategies_total": 0}} を作成します
  • immune_memory.json の "version": 2 の場合:各抗体の "domain" を "domains": ["domain_value"] に変換し、バージョンを 3 に設定して自動移行します。すぐに書き戻します。
  • エージェントが無効な JSON を返した場合:1 回再試行します。それでも無効な場合は、警告を添えて生の出力を報告します。
  • 入力がなく、最近の出力も存在しない場合:何をスキャンするかユーザーに尋ねます。
  • すべての抗体が COLD の場合(HOT の条件を満たすものがない場合):hot_antibodies 配列を空にし、cold_summary 全体を含めてスキャンを実行します。Haiku は Phase 2 で新たな脅威を検出できます。

コメント