Antigravity 向けの CodeMender のスキルとフック

1. はじめに

この Codelab では、セキュリティが個別のレビュー ステップではなく、通常の開発ループの一部となるように、AI コーディング エージェント(Antigravity)を構成します。エージェントに Plan → Red → Green → Refactor サイクルを案内する一連のエージェント スキルと、git push をインターセプトして変更されたファイルを CodeMender でスキャンし、検出結果をエージェントに返してテストファーストで修正するよう指示する PreToolUse フックをインストールします。

スキルとフックは、オープンソースの Secure TDD Agent Framework から取得されます。これらは、CodeMender CLI の基本で作成したのと同じ ~/codemender-lab ワークスペースにインストールします。

学習内容

  • Antigravity が .agents/ でワークスペース ルール、スキル、フックを検出する方法。
  • 6 つのセキュア TDD スキルの役割と、各スキルが担当するループのフェーズ。
  • PreToolUse フックが stdin でエージェントのツール呼び出しを受け取り、許可 / 拒否の決定を返す方法。
  • セキュリティ ゲートフック(security_gate_hook.sh)が cm find を実行し、検出結果を重大度別に分類し、修正の試みを追跡し、cm verify でエスカレーションする方法。
  • 実際の cm を指定する前に、モックスキャナを使用してフック パイプライン全体をオフラインで検証する方法。

前提条件

  • CodeMender CLI の基本を完了していること。このラボは ~/codemender-lab ディレクトリで続行され、sample_app/、CONTEXT.md、git 履歴、~/.codemender/config.yaml が再利用されます。
  • Antigravity がインストールされ、ローカル フォルダをワークスペースとして開くことができる。
  • git、jq、bash がインストールされている。フック スクリプトはプレーンな bash で、macOS の標準の bash 3.2 と新しいバージョンで実行されます。
  • CodeMender CLI の基本(~/codemender-lab/.venv)の Python 仮想環境に Flask がインストールされていること。
  • シェル スクリプトに関する基本的な知識。

2. Workspace の設定

ステップ 1: ラボ ディレクトリに戻る

このラボのすべてのコマンドは、仮想環境がアクティブな状態で ~/codemender-lab から実行します。

cd ~/codemender-lab && source .venv/bin/activate

前のラボのワークスペースがそのまま残っており、作業ツリーがクリーンであることを確認します。

ls sample_app/data_service.py CONTEXT.md .gitignore
git status --short

git status --short は何も出力しません。ファイルが一覧表示された場合は、コミットしてから続行します。

ステップ 2: ブランチに main という名前を付ける

セキュリティ ゲートは、作業ツリーと origin/main の差分を比較して、スキャンするファイルを決定します。その ref が存在しない場合は、HEAD~1 にフォールバックします。これは最新の commit のみを対象とします。ブランチの名前が main であることを確認します。

git branch -M main

ステップ 3: テストスイートのエントリ ポイントを追加する

セキュアな TDD ループでは、修正のたびにエージェントに python3 -m unittest discover -s tests を実行するよう求めるため、ワークスペースには tests/ ディレクトリが必要です。スイートで実際に実行できるように、1 つの特性テストから始めます。

mkdir -p tests && touch tests/__init__.py
cat << 'EOF' > tests/test_data_service.py
import unittest

from sample_app.data_service import hash_password


class HashPasswordTests(unittest.TestCase):
    def test_returns_hex_digest(self):
        digest = hash_password("hunter2")
        self.assertIsInstance(digest, str)
        int(digest, 16)  # raises ValueError if not hexadecimal


if __name__ == "__main__":
    unittest.main()
EOF
python3 -m unittest discover -s tests

Ran 1 test と OK が表示されます。

ステップ 4: .gitignore を拡張して commit する

このラボで生成されたランタイム ファイルを .gitignore に追加し、ベースラインを commit します。

printf '.security-gate/\nusers.db\n*.bak\n' >> .gitignore
git add -A && git commit -m "Add test suite entry point for Secure TDD"

3. フレームワーク ファイルのインストール

スキル、ルール、フック、オフライン テストハーネスはすべて、1 つの .agents/ ディレクトリにあります。約 800 行の bash を手動で入力する代わりに、フレームワークのクローンを作成し、そのディレクトリをワークスペースにコピーします。

git clone --depth 1 https://github.com/h3xar0n/secure-tdd-agent-framework.git /tmp/secure-tdd
cp -R /tmp/secure-tdd/.agents ./.agents
rm -rf /tmp/secure-tdd

レイアウトを確認します。

find .agents -type f | sort
.agents/hooks.json
.agents/lib/README.md
.agents/lib/engine_codemender.sh
.agents/lib/engine_semgrep.sh
.agents/lib/gate_common.sh
.agents/rules/secure_tdd_workflow.md
.agents/security_gate_hook.sh
.agents/skills/defensive-developer/SKILL.md
.agents/skills/history-context-seeder/SKILL.md
.agents/skills/local-refactor-scanner/SKILL.md
.agents/skills/security-test-writer/SKILL.md
.agents/skills/skill-evolution-updater/SKILL.md
.agents/skills/threat-model-assessor/SKILL.md
.agents/tests/mocks/cm
.agents/tests/mocks/semgrep
.agents/tests/run_tests.sh

フック エントリ ポイントが実行可能であることを確認します。

chmod +x .agents/security_gate_hook.sh
ls -l .agents/security_gate_hook.sh

このラボの残りの部分では、インストールしたものを 1 つずつ確認していきます。

4. 常時稼働のワークフロー ルール

スキルは、エージェントがスキルの説明がタスクに一致すると判断した場合に、オンデマンドで読み込まれます。エージェントに、正しい順序でそれらにアクセスするよう指示する必要があります。これが .agents/rules/secure_tdd_workflow.md の役割です。フロントマターで trigger: always_on が設定されているため、このルールはすべてのターンに挿入されます。

---
trigger: always_on
---

# Test-Driven Development with Integrated Security (Secure TDD) Workflow Rule

You MUST strictly follow this 4-phase cyclical workflow for all feature implementations, refactors, and bug fixes:

1. **Phase A (Plan, Scope & Threat Model)**:
   - Ingest `CONTEXT.md` to review established project conventions, approved helpers, and trust zones.
   - Decompose feature requirements, user stories, and acceptance criteria.
   - Invoke the **Threat Model Assessor Skill** to perform a STRIDE evaluation and generate/update `threat_model.md`.

2. **Phase B (Functional & Security Test-First - RED)**:
   - Invoke the **Security Test Writer Skill**.
   - Author unit and integration tests asserting functional behavior (happy paths, business logic), edge cases, AND security boundaries (rejecting invalid inputs, unauthenticated requests, unauthorized role access).
   - Execute the tests and confirm they FAIL for the expected assertion reason (RED).

3. **Phase C (Feature Implementation & Defensive Code - GREEN)**:
   - Invoke the **Defensive Developer Skill**.
   - Author clean, modular production code strictly required to satisfy the functional tests and security assertions.
   - Apply input validation allow-lists, parameterized queries, and least-privilege payload returns.
   - Run the tests to confirm they are GREEN.

4. **Phase D (Refactor, Quality & Scan)**:
   - Invoke the **Local Refactor & Scanner Skill**.
   - Clean up code, eliminate duplication, and verify 100% passing test regressions.
   - Run fast deterministic checks (secrets, dependencies, local SAST).
   - Conduct a guided AI review to verify architectural boundaries and eliminate logic bypasses.
   - Ensure diffs remain small, surgical, and preserve baseline stability.

5. **Continuous Evolution**:
   - If a new pattern, helper function, or architectural convention was introduced, invoke the **Skill Evolution Updater Skill** to document the lesson into `CONTEXT.md` or the appropriate `SKILL.md`.

6. **Multi-Finding Remediation Protocol**:
   - When resolving multiple findings from a scan or security gate rejection, iterate sequentially one finding at a time:
     1. Author one discrete boundary test for the finding (RED).
     2. Implement the minimal defensive fix (GREEN).
     3. Verify local tests pass before moving to the next finding.
   - Avoid applying multi-finding changes in a single unverified edit. Run the full regression test suite only after all individual findings have passed their discrete TDD cycle.

このルールは、CodeMender CLI の基本で作成した CONTEXT.md を参照します。cm fix をパラメータ化されたクエリの規則に沿って動作させるために使用したファイルが、エージェントの計画を制御するようになります。このラボで最も重要なのは項目 6 です。セキュリティ ゲートが複数の検出結果を含む push を一度に拒否した場合に、エージェントが従うのはこの項目です。

5. 6 つのエージェント スキル

各スキルは、YAML フロントマターを含む SKILL.md を含むディレクトリです。次の 2 つのフィールドは必須です。

  • name: 小文字のハイフン付き識別子。
  • description: スキルの機能と使用するタイミング。エージェントは、スキル全体を読み込むかどうかを判断する際に、このフィールドのみを読み取ります。そのため、以下の各説明には、スキルが対象外とするものも記載されています。

スキル

フェーズ

目的

threat-model-assessor

A: 計画

機能のスコープを設定し、STRIDE を実行して、threat_model.md を作成します。

security-test-writer

B: 赤

適切な理由で失敗する機能テストと境界テストを作成する。

defensive-developer

C: 緑

安全なパターンを使用して、テストをグリーンにする最小限のコードを記述します。

local-refactor-scanner

D: リファクタリング

クリーンアップ、スイート全体の実行、ローカル スキャナの実行、差分の確認。

skill-evolution-updater

継続的

新しい規則を CONTEXT.md ファイルと SKILL.md ファイルに記録します。

history-context-seeder

オンボーディング

Git 履歴をマイニングして、既存のリポジトリに CONTEXT.md をシードします。

以下に、フロントマターと手順がどのように組み合わされているかを示す完全なコンテンツを示します。

1. threat-model-assessor(フェーズ A)

.agents/skills/threat-model-assessor/SKILL.md:

---
name: threat-model-assessor
description: Plans feature architecture, functional requirements, and evaluates STRIDE security boundaries in Phase A Plan. Use when scoping new features or bug fixes, defining user stories and acceptance criteria, identifying trust boundaries, and generating or updating threat_model.md. Do not use for writing test assertions, implementing production code, or running local scanners.
---

# Planning, Requirements & Threat Model Assessor Skill (Phase A: Plan Phase)

## Overview
Decompose feature requirements, establish functional acceptance criteria, and map trust boundaries before any production code is authored. This skill pairs functional engineering scoping with STRIDE threat modeling at the planning stage, establishing the functional and security acceptance criteria consumed by downstream test writers.

## System Sequence
1. **Ingest Context**: Read `CONTEXT.md` to identify existing architecture, trust boundaries, approved libraries, and conventions.
2. **Decompose Requirements**:
   - Define user stories, input/output data contracts, and functional acceptance criteria.
   - Break complex tasks into bite-sized, testable implementation stages.
3. **Apply STRIDE Threat Modeling**:
   - **Spoofing**: Authentication boundaries, session validation, caller identity checks.
   - **Tampering**: Input payload validation, integrity checks, parameter tampering.
   - **Repudiation**: Audit logging of critical state transitions.
   - **Information Disclosure**: Restrict error responses, prevent stack trace leaks, mask PII/secrets.
   - **Denial of Service**: Resource limits, payload size constraints, timeout limits.
   - **Elevation of Privilege**: Role-Based Access Control (RBAC), caller authorization checks.
4. **Generate/Update `threat_model.md`**:
   - Store or update `threat_model.md` at the workspace root with both Functional & Security Acceptance Criteria.

## Target Output Artifact (`threat_model.md`)
```markdown
# Feature Plan & Threat Model: [Feature Name]

## 1. Functional Scope & Requirements
- **Goal**: [Description of feature or bug fix]
- **Deliverables**: [Endpoints, functions, or modules to create/modify]
- **Functional Acceptance Criteria**: [Expected behaviors and outputs]

## 2. Entry Points & Data Inputs
- Endpoint / Input: [Path / Name]
- Format & Constraints: [Schema / Type]

## 3. Trust Boundaries & Access Controls
- Authentication: [Required / Public]
- Authorization Role: [User / Admin]

## 4. STRIDE Threat Matrix & Security Acceptance Criteria
- [STRIDE Category]: [Threat Description] -> [Required Mitigation & Test Assertion]
```

2. security-test-writer(フェーズ B)

.agents/skills/security-test-writer/SKILL.md:

---
name: security-test-writer
description: Authors test-first unit and integration tests covering functional behavior, edge cases, and security boundaries in Phase B RED. Use when creating failing automated tests before writing production code, asserting HTTP status codes and contract responses, establishing boundary limits, or asserting that exploit payloads are rejected cleanly. Do not use for threat modeling during initial planning, writing production feature code, or running refactor sweeps.
---

# QA & Security Test Writer Skill (Phase B: RED Phase)

## Overview
Translate functional requirements and security criteria from `threat_model.md` and `CONTEXT.md` into executable test cases that fail initially (RED), asserting expected business logic, edge-case handling, and security boundaries before production code is authored.

## Three Verification Pillars
1. **Behavior-Driven Outcomes**:
   - Assert strictly on API/HTTP outcomes (status codes 200/302 for valid requests, 400/401/403 for invalid/unauthorized, expected JSON responses) rather than mocking internal private methods.
2. **Strict Test Isolation**:
   - Ensure test setup and teardown cleanly isolate state (e.g., transaction rollbacks, fresh test contexts) so state never bleeds between test runs.
3. **Integration Over Fragile Mocking**:
   - Utilize local test databases or real server contexts rather than fragile fake mocks to verify realistic functional and security behavior.

## Execution Sequence
1. **Consume Requirements & Threat Model**: Read the task scope, `threat_model.md`, and `CONTEXT.md` for functional requirements and security acceptance criteria.
2. **Author Test Cases**:
   - **Functional Happy Path**: Test validating standard user workflows and expected output payloads.
   - **Functional Edge Cases**: Test missing optional/required parameters, boundary limits, and unexpected data types.
   - **Authentication Boundary**: Assert requests without valid credentials return `401 Unauthorized`.
   - **Authorization Boundary**: Assert requests with insufficient role/scope return `403 Forbidden`.
   - **Input Validation**: Assert malformed, oversized, or un-whitelisted data returns `400 Bad Request`.
   - **Exploit Payloads**: Assert dangerous inputs (SQLi, path traversal `../../`, XSS) are rejected cleanly.
3. **Execute & Verify RED**:
   - Run the project's test command (e.g., `pytest`, `python3 -m unittest discover -s tests`).
   - **Requirement**: Confirm the tests fail due to the expected missing feature logic/boundary assertion and not due to a syntax or import error.
4. **Multi-Finding Handling**:
   - When remediating multiple scanner findings, write and verify one boundary test for one finding at a time before proceeding to defensive implementation.

3. defensive-developer(フェーズ C)

.agents/skills/defensive-developer/SKILL.md:

---
name: defensive-developer
description: Implements clean, maintainable production code to deliver features and satisfy functional and security test assertions in Phase C GREEN. Use when writing minimal, modular production code to turn failing RED tests GREEN, applying input validation allow-lists, enforcing explicit caller authorization, and using parameterized sinks and least-privilege payloads. Do not use for authoring initial tests, performing initial threat modeling, or running post-implementation security scans.
---

# Feature Implementation & Defensive Developer Skill (Phase C: GREEN Phase)

## Overview
Implement clean, modular production code that delivers the requested feature or bug fix and satisfies all functional, edge-case, and security assertions from Phase B while adhering to defensive design principles and project conventions in `CONTEXT.md`.

## Three Defensive Pillars
1. **Simple Input Validation**:
   - Enforce type, size, and strict allow-list validation on all incoming data.
   - Prefer structured parsing libraries (`pydantic`, `urllib.parse`) over complex regex which may be vulnerable to ReDoS.
2. **Explicit Authorization**:
   - Validate caller identity and match required permissions before invoking business logic.
3. **Least Privilege & Safe Operations**:
   - Parameterize all SQL/database queries.
   - Use canonical path checks (`os.path.realpath`) with prefix boundary validation.
   - Return only the minimal data payload required by the client.
   - Mask credentials, PII, and omit internal stack traces in error messages.

## Execution Sequence
1. **Inspect Failing Tests & Rules**: Review the functional requirements, failing tests from Phase B, and conventions in `CONTEXT.md`.
2. **Author Clean Production Code**:
   - Implement the business logic and algorithms required to satisfy the functional feature requirements.
   - Apply defensive patterns (e.g. `utils.security.resolve_safe_path`, parameterized SQL statements, `pydantic` schemas).
3. **Confirm GREEN State**:
   - Run the project test suite.
   - Verify that all functional and security tests pass cleanly without errors.
4. **Multi-Finding Handling**:
   - When remediating multiple scanner findings, apply the minimal fix for the current failing boundary test, confirm GREEN, then proceed to the next finding's test-fix cycle.

4. local-refactor-scanner(フェーズ D)

.agents/skills/local-refactor-scanner/SKILL.md:

---
name: local-refactor-scanner
description: Refactors code for quality and maintainability, executes full test suite regression passes, and runs local deterministic security and lint scans in Phase D REFACTOR. Use when cleaning up code structure and eliminating duplication after tests pass, running local linters and fast offline scanners for secrets or dependencies, executing full regression test suites, and performing guided code reviews. Do not use for implementing initial feature logic, writing failing test-first suites, or modifying architectural threat models.
---

# Code Refactoring, Quality & Local Scanner Skill (Phase D: REFACTOR Phase)

## Overview
Refactor implementation for clean code structure, modularity, and maintainability while ensuring 100% passing test regressions and blocking pattern-based security flaws locally prior to commit.

## Verification Guardrails
1. **Code Quality & Refactoring**:
   - Clean up boilerplate, eliminate dead code, and centralize common utilities.
   - Improve variable naming, modularity, and type annotations without altering verified behavior.
2. **Deterministic Scans (Fast & Offline)**:
   - **Secrets**: Check diffs for plaintext credentials, tokens, or private keys.
   - **Dependencies**: Flag unpinned dependencies or known CVEs in new packages.
   - **Rules-Based SAST**: Run local SAST rules on modified files (`semgrep scan --config auto --json` or `cm find`).
3. **Guided AI Review**:
   - Audit architecture and design issues that static tools miss.
   - Review business logic and edge cases for bypasses or regression risks.
4. **Small Diffs & Regression QA**:
   - Run the complete project test suite to verify zero regressions across existing and new tests.
   - Ensure the diff contains only surgical changes directly related to the task scope.

## Execution Sequence
1. Review the git diff of modified files (`git diff`).
2. Refactor code for clarity, maintainability, and helper reuse.
3. Run local linters and security scanners on changed files.
4. Run the full test suite to guarantee 100% passing tests.
5. **Continuous Evolution**: Capture new conventions in `CONTEXT.md` and suggest/apply updates to `SKILL.md` instructions via `skill-evolution-updater` to permanently prevent recurrence of issues.

5. skill-evolution-updater(継続的な進化)

.agents/skills/skill-evolution-updater/SKILL.md:

---
name: skill-evolution-updater
description: Extracts systemic conventions from resolved bugs, patterns, and refactors to update CONTEXT.md and agent skills for continuous evolution. Use when capturing durable coding rules, architectural conventions, or recurring fix patterns into CONTEXT.md after a task or bug fix, updating skill instructions to prevent recurrence of errors, and logging gate findings to findings-log.ndjson. Do not use for writing feature code, authoring unit tests, or running pre-push scanner pipelines.
---

# Skill & Conventions Evolution Updater (Continuous Evolution)

## Overview
Ensure the development team and agent fleet continuously learn from local fixes, architecture decisions, and refactoring patterns so that systemic quality and security standards are retained permanently.

## Continuous Feedback Mechanism
```
+-----------------------------------------------------------------+
|                    CONTINUOUS FEEDBACK LOOP                     |
|                                                                 |
|   1. Local Fix / Feature Verified (Refactor Phase)              |
|                               v                                 |
|   2. Systemic Lesson Extracted (Best practices & conventions)   |
|                               v                                 |
|   3. Feed Back to Shared Specs (Update SKILL.md/CONTEXT.md)     |
|                               v                                 |
|   4. Context Seeding (All future agents inherit rules upfront)  |
+-----------------------------------------------------------------+
```

## Execution Sequence
1. **Analyze Remediation Diff**: Review the code change or bug fix just completed.
2. **Extract the Systemic Rule**:
   - Formulate an actionable, project-specific rule.
   - Example: *"When implementing redirects, always use `utils.security.safe_redirect()` with allow-listed domains."*
   - Example: *"All JSON endpoints must validate request body using Pydantic schemas."*
3. **Update Shared Specifications**:
   - **Update `CONTEXT.md`**: Append the rule under `## 4. Continuous Evolution: Auto-Evolved Conventions`.
   - **Update Skills (if applicable)**: If a general coding anti-pattern or QA procedure was refined, update the relevant `SKILL.md`.
4. **Persist Insight**: Append the raw structured event to `.security-gate/findings-log.ndjson` for audit traceability.

6. history-context-seeder(オンボーディング)

.agents/skills/history-context-seeder/SKILL.md:

---
name: history-context-seeder
description: Analyzes repository Git history for past bug fixes, architectural conventions, and security patterns to seed CONTEXT.md on onboarding. Use when first adopting the framework in an existing repository, mining historical commits and bug fixes for recurring risk areas, or populating the initial CONTEXT.md baseline with established conventions and helpers. Do not use for routine feature development, authoring test suites, or running the inner TDD loop on active tasks.
---

# History & Architectural Context Seeder Skill (Repository Onboarding)

## Overview
Analyzes the repository's Git history and past fix commits to extract recurring bug patterns, architectural conventions, and security patterns, seeding `CONTEXT.md` during initial repository onboarding.

## Execution Sequence
1. **Analyze Git Log**:
   - Inspect commits touching bug fixes, refactors, and sensitive modules:
     `git log --grep="fix\|bug\|refactor\|vuln\|security\|patch" -n 50 --oneline`
2. **Extract Historical Lessons**:
   - Identify which files and modules have historically been prone to bugs or regressions.
   - Extract past patterns and architectural conventions established by maintainers.
3. **Seed `CONTEXT.md`**:
   - Populate `CONTEXT.md` with known architectural risk areas, sensitive directories, approved helpers, and custom project conventions.

CONTEXT.md はすでに存在するため、ラボではこのスキルを使用しませんが、何年もの履歴があり、記述された規則がないリポジトリにフレームワークを導入する際に、このスキルが必要になります。

6. Antigravity フックの構成

.agents/hooks.json は、エージェントが実行するターミナル コマンドの前にセキュリティ ゲートを実行するよう Antigravity に指示します。

{
  "security-gate": {
    "PreToolUse": [
      {
        "matcher": "run_command|.*:run_command|run_shell_command|Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'if [ -x ./security_gate_hook.sh ]; then exec ./security_gate_hook.sh; else exec ./.agents/security_gate_hook.sh; fi'",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

このファイルの詳細から、起動するスクリプトの設計がわかります。

  • matcher は、コマンドテキストではなく、ツール名の正規表現です。PreToolUse はツールが実行される前に起動し、マッチャーがどのツールを実行するかを決定します。run_command は Antigravity のターミナル ツールです。他の代替ツールは、プラグインの名前空間付きバリアントと、これらのファイルを共有する他のエージェント プラットフォームをカバーしています。git push* のようなマッチャーは、そのような名前のツールがないため、実行されません。実際のコマンドのフィルタリングはスクリプト内で行われます。
  • フックは stdin でツール呼び出しを受け取ります。Antigravity は、{"toolCall": {"name": "run_command", "args": {"CommandLine": "git push origin main"}}, ...} などの JSON ペイロードをパイプします。スクリプトは .toolCall.args.CommandLine を読み取り、git push 以外のものに対して許可の判定を行い、すぐに終了します。
  • 作業ディレクトリは hooks.json を含むディレクトリであるため、フックは .agents/ 内で開始されます。bash -c 'if [ -x ./security_gate_hook.sh ] ...' ラッパーは、そのケースと、リポジトリのルートから起動されるケースの両方を処理します。次に、スクリプトは作業を行う前に git rev-parse --show-toplevel に cd します。
  • スクリプトは stdout で JSON を使用して応答します。{"decision": "allow"} は、元のコマンドを実行します。{"decision": "deny", "reason": "..."} は、その操作をブロックし、エージェントに理由を表示します。フレームワークは、以前のフック契約との互換性を保つために allow_tool ブール値も出力します。
  • フックは同期的に実行され、終了するか timeout(秒単位、省略した場合のデフォルトは 30)に達するまでエージェント ループをブロックします。

-i.bak 形式は、GNU と BSD(macOS)の sed の両方で機能します。

sed -i.bak 's/"timeout": 120/"timeout": 900/' .agents/hooks.json && rm .agents/hooks.json.bak

7. セキュリティ ゲートフックの仕組み

security_gate_hook.sh は、.agents/lib/ から 3 つのモジュールをソースとするシン エントリ ポイントです。

モジュール

ロール

gate_common.sh

構成のデフォルト、allow/deny 出力、重大度ランキング、NDJSON 監査ログ、試行回数、commit、CONTEXT.md ヘルパー。

engine_semgrep.sh

ステージ 1. Semgrep を使用したオプションの決定的スキャン。semgrep が PATH にない場合はスキップされます。

engine_codemender.sh

ステージ 2. cm find によるセマンティック スキャン、分類、試行のトラッキング、cm verify エスカレーション。

ステップ 1: プッシュかどうかを判断する

エントリ ポイントは、stdin ペイロードからコマンドを抽出し、git push を一般的な形式(git -C /repo push、cd x && git push、sudo git push)で認識する正規表現に対してテストします。git commit -m "before git push" などの引用符で囲まれたテキストは無視されます。push 以外のものはすぐに許可されます。

CMD_TO_CHECK=$(printf '%s\n' "$STDIN_INPUT" | jq -r '
  .toolCall?.args?.CommandLine? //
  .toolCall?.args?.command? //
  .tool_input?.command? //
  .CommandLine? //
  .command? //
  empty
')
...
if ! is_git_push_command "$CMD_TO_CHECK"; then
  allow
fi

ステップ 2: スキャナを選択する

SECURITY_GATE_SCANNER はパイプラインを選択します。デフォルトの auto では、Semgrep と CodeMender のうちインストールされているものが、この順序で実行されます。

case "$SCANNER" in
  codemender|cm) run_codemender_gate false ;;
  semgrep)       run_semgrep_gate false ;;
  auto|pipeline|"")
    command -v semgrep >/dev/null && run_semgrep_gate true
    command -v cm      >/dev/null && run_codemender_gate true
    allow ;;
esac

ステージ 1 がパイプライン モードでブロッキングの問題を検出しても、独自に拒否することはありません。ステージ 2 が取得する一時ファイルに書き込み、CodeMender が最終的な判断を下します。

ステップ 3: CodeMender ステージ

engine_codemender.sh の run_codemender_gate は、次の処理を順番に行います。

  1. git diff --name-only origin/main(HEAD~1 にフォールバック)を使用して変更されたファイルを検索します。変更がない場合は許可されます。
  2. cm find "$file" -y --bypass-warning を使用して各ファイルをスキャンし、cm report --format json ですべてをプルします。cm report が失敗するか、無効な JSON を返した場合、それはスキャンエラーであり、クリーンな結果ではありません。
  3. ステータスが OPEN または REOPENED で、file_path が変更されたファイルのいずれかで終わる検出結果をフィルタします。CodeMender CLI の基本で修正または無視した検出結果は無視されます。
  4. 各検出結果を分類します。SECURITY_GATE_BLOCK_SEVERITY(デフォルトは HIGH)以上の重大度はブロックされます。それより低い重大度は、アドバイザリとしてログに記録され、出力されますが、push は停止されません。
  5. ブロックする要素がない場合は許可する。以前の push をブロックした検出結果がなくなった場合、ゲートはそれを FIXED としてログに記録し、## 4. Continuous Evolution の CONTEXT.md に規則を追加して、その変更を commit します。
  6. 独自の監査ログを読み取って、ブロック検出結果ごとに試行回数をカウントします。拒否されるたびに 1 回の試行とみなされます。1 回目から SECURITY_GATE_MAX_RETRIES 回目(デフォルトは 3 回)の試行では、ゲートは DENIED_TO_AGENT をログに記録し、拒否メッセージに検出結果を追加します。
  7. 予算を使い切った後にエスカレーションする。同じ検出結果に対する 4 回目の試行では、ゲートは cm verify を実行します。検出結果が悪用可能でない場合(終了コード 1 またはステータス DISMISSED)、アドバイザリにダウングレードされます。確認された場合、または cm verify がクラッシュした場合、ゲートは BLOCKED をログに記録し、人間による審査をリクエストして拒否します。
  8. 手順を案内して拒否する。対応可能な検出結果が残っている場合、ゲートは次の理由をエージェントに返します。
Security Gate blocked push (1 unresolved finding(s)).

Action Required: Execute the Secure TDD Loop sequentially for each finding:
For each finding below (one at a time):
  1. Invoke 'security-test-writer' to author one failing boundary test in tests/ (assert RED).
  2. Invoke 'defensive-developer' to apply the minimal defensive fix (assert GREEN).
  3. Run the local test to confirm it passes before moving to the next finding.
Once all findings are resolved, run the full regression test suite (python3 -m unittest discover -s tests) and retry 'git push'.

Open Findings:
- [80bdddd6-...] (CRITICAL) in /home/you/codemender-lab/sample_app/data_service.py (Attempt 1/3): OS Command Injection in ping_host endpoint

これは、フックとスキルの間の引き継ぎです。フックは cm fix を呼び出しません。エージェントが使用すべきスキルを指定し、エージェントがテストファーストの修正を行い、次の git push がゲートを再実行します。

構成リファレンス

すべての設定は、gate_common.sh でデフォルトが設定されている環境変数です。

変数

デフォルト

効果

SECURITY_GATE_SCANNER

auto

auto、codemender(または cm)、semgrep。

SECURITY_GATE_BLOCK_SEVERITY

HIGH

ブロックする最も低い重大度。CRITICAL、HIGH、MEDIUM、LOW。

SECURITY_GATE_MAX_RETRIES

3

cm verify がコンサルトされる前の検出結果あたりの拒否数。

SECURITY_GATE_ALLOW_ON_ERROR

false

true は、スキャナの実行に失敗したときに push を許可し、commit に unverified-scan- のタグを付けます。

SECURITY_GATE_TEST_CMD

python3 -m unittest discover -s tests

不承認プロンプトと commit メッセージで引用されたテストコマンド。

SECURITY_GATE_EVOLVE_CONTEXT

true

検証済みの規則を CONTEXT.md に追加します。

SECURITY_GATE_LOG

.security-gate/findings-log.ndjson

追加専用の監査ログ。

SECURITY_GATE_NOTIFY_CMD

(空白)

各ゲートイベントを stdin で JSON として受け取るオプションのコマンド。

8. フックをオフラインで検証する

ゲートが実際の cm に触れる前に、モックで正しく動作することを確認します。このフレームワークには、許可、アドバイザリ、拒否、エラー、エスカレーションのパスをカバーする、偽の cm バイナリと semgrep バイナリを含むテストハーネスが付属しています。

bash .agents/tests/run_tests.sh

実行には数秒かかり、次のように終了します。

-- test_pipeline_tools_missing_passes_smoothly
-- test_skills_frontmatter_valid
60 passed, 0 failed

最後のテストでは、.agents/skills/ のすべてのスキルのフロントマターも検証されるため、SKILL.md の編集後に再実行するコマンドはこれになります。

次に、プッシュではないコマンドに対して Antigravity が送信する内容をシミュレートします。スクリプトは、スキャナに触れることなく allow に応答する必要があります。

echo '{"toolCall":{"name":"run_command","args":{"CommandLine":"git status"}}}' \
  | bash .agents/security_gate_hook.sh
{"allow_tool": true, "decision": "allow"}

次に、origin/main に対してローカルの変更がない push をシミュレートします。リモートがまだないため、ゲートは HEAD~1 にフォールバックし、最後の commit のファイルをスキャンします。このステップをオフラインに保つには、モックの cm と semgrep を参照するようにします。

echo '{"toolCall":{"name":"run_command","args":{"CommandLine":"git push origin main"}}}' \
  | PATH="$PWD/.agents/tests/mocks:$PATH" bash .agents/security_gate_hook.sh
Stage 1: Running Deterministic AST Scan (semgrep) on: sample_app/data_service.py ...
Deterministic scan clean. No AST vulnerabilities found.
Stage 2: Running Semantic Analysis & Verification (CodeMender)...
No blocking vulnerabilities detected. Code verified clean.
{"allow_tool": true, "decision": "allow"}

モック ディレクトリには、偽の semgrep と偽の cm が含まれているため、両方のステージが実行されました。進行状況メッセージは stderr に送信され、JSON の決定のみが stdout に送信されます。これにより、Antigravity は結果を解析できます。

最後に、フレームワーク ファイルを commit して、リポジトリとともに移動するようにします。

git add -A && git commit -m "Add Secure TDD skills, rule, and security gate hook"

9. Antigravity でワークスペースを開く

Antigravity で ~/codemender-lab をフォルダとして開きます。読み込まれると、エージェントには次のものが含まれます。

  • すべてのターンの secure_tdd_workflow ルール。
  • オンデマンドで利用できる 6 つのスキル。
  • run_command に登録された security-gate フック。

スキルが表示されていることを簡単に確認するには、新しい会話でエージェントに「利用可能な Workspace スキルと、それぞれの機能について教えてください」と尋ねます。6 つの名前を挙げてください。

権限

フック自体はエージェントではなく Antigravity によって起動されるため、ツールの権限プロンプトは表示されません。エージェント独自のコマンドは、承認を必要とします。次の Codelab では、テストコマンド、git オペレーション、エージェントが直接実行することを決定した cm コマンドの承認プロンプトが表示されます。承認を求められたら承認します。Antigravity がコマンド プレフィックスの決定を記憶することを提案した場合は、それを受け入れることで、ループ全体で再プロンプトを回避できます。

git pushに予定されていること

  1. エージェントは git push origin main を使用してターミナル ツールを呼び出します。
  2. Antigravity は run_command を hooks.json と照合し、stdin でツール呼び出しを使用して security_gate_hook.sh を実行します。
  3. スクリプトは push を認識し、変更されたファイルを検出して cm find でスキャンし、cm report を読み取ります。
  4. ブロックするものがない場合は、{"decision": "allow"} が出力され、push が続行されます。
  5. 検出結果がブロックされると、{"decision": "deny", "reason": "..."} が出力されます。プッシュは実行されず、エージェントはその理由を確認します。常時稼働のルールと名前付きスキルにより、次に何をすべきかが指示されます。1 つのテストが失敗し、1 つの最小限の修正が行われ、スイートが再実行され、再度プッシュされます。

おめでとうございます!「CodeMender のスキルとフック(Antigravity)」の Codelab を完了しました。次の Codelab では、エージェントに機能リクエストを渡し、脅威モデルからゲートを通過する push まで、このループがエンドツーエンドで実行される様子を確認します。