CodeMender-Skills und ‑Hooks für Antigravity

1. Einführung

In diesem Codelab konfigurieren Sie einen KI-Programmier-Agenten (Antigravity) so, dass Sicherheit Teil des normalen Entwicklungszyklus ist und nicht ein separater Überprüfungsschritt. Sie installieren eine Reihe von Agent-Skills, die den Agent durch einen Plan → Rot → Grün → Refaktorieren-Zyklus führen, und einen PreToolUse-Hook, der git push abfängt, die geänderten Dateien mit CodeMender scannt und alle Ergebnisse mit Anweisungen zur Behebung an den Agent zurückgibt.

Die Skills und der Hook stammen aus dem Open-Source-Framework Secure TDD Agent Framework. Sie installieren sie im selben ~/codemender-lab-Arbeitsbereich, den Sie in „CodeMender CLI Basics“ erstellt haben.

Lerninhalte

  • Wie Antigravity Arbeitsbereichsregeln, Skills und Hooks unter .agents/ erkennt.
  • Was die sechs Secure TDD-Skills tun und welche Phase des Kreislaufs sie jeweils abdecken.
  • Wie ein PreToolUse-Hook den Toolaufruf des Agenten über stdin empfängt und eine Zulassungs-/Ablehnungsentscheidung zurückgibt.
  • Wie der Security Gate-Hook (security_gate_hook.sh) cm find ausführt, Ergebnisse nach Schweregrad klassifiziert, Fehlerbehebungsversuche verfolgt und mit cm verify eskaliert.
  • Wie Sie die gesamte Hook-Pipeline offline mit Mock-Scannern prüfen, bevor Sie sie auf die echte cm verweisen.

Vorbereitung

  • Abschluss von CodeMender CLI Basics. Dieses Lab wird im Verzeichnis ~/codemender-lab fortgesetzt. Die Dateien sample_app/, CONTEXT.md, der Git-Verlauf und ~/.codemender/config.yaml werden wiederverwendet.
  • Antigravity muss installiert sein und Sie müssen einen lokalen Ordner als Arbeitsbereich öffnen können.
  • git, jq und bash installiert. Die Hook-Scripts sind einfache Bash-Scripts und werden sowohl auf der Standard-Bash 3.2 von macOS als auch auf neueren Versionen ausgeführt.
  • Die virtuelle Python-Umgebung aus „CodeMender CLI Basics“ (~/codemender-lab/.venv) mit installiertem Flask.
  • Grundlegende Kenntnisse im Shell-Scripting

2. Google Workspace einrichten

Schritt 1: Zum Lab-Verzeichnis zurückkehren

Alle Befehle in diesem Lab werden in ~/codemender-lab mit aktivierter virtueller Umgebung ausgeführt:

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

Prüfen Sie, ob der Arbeitsbereich aus dem vorherigen Lab intakt und Ihr Arbeitsbaum sauber ist:

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

git status --short sollte nichts ausgeben. Wenn Dateien aufgeführt sind, müssen Sie sie committen, bevor Sie fortfahren.

Schritt 2: Zweigstelle main benennen

Das Security Gate vergleicht Ihren Arbeitsbaum mit origin/main, um zu entscheiden, welche Dateien gescannt werden sollen. Wenn diese Referenz nicht vorhanden ist, wird auf HEAD~1 zurückgegriffen, was nur den letzten Commit abdeckt. Achten Sie darauf, dass Ihr Zweig main heißt:

git branch -M main

Schritt 3: Einstiegspunkt für die Test-Suite hinzufügen

In der Secure TDD-Schleife wird der Agent aufgefordert, nach jeder Korrektur python3 -m unittest discover -s tests auszuführen. Daher benötigt der Arbeitsbereich ein tests/-Verzeichnis. Beginnen Sie mit einem Charakterisierungstest, damit die Suite etwas Reales ausführen kann:

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

Sie sollten Ran 1 test und OK sehen.

Schritt 4: .gitignore erweitern und commiten

Fügen Sie die in diesem Lab erstellten Laufzeitdateien zu .gitignore hinzu und führen Sie dann einen Commit für die Referenz aus:

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

3. Framework-Dateien installieren

Die Skills, die Regel, der Hook und der Offline-Test-Harnisch befinden sich alle in einem einzigen .agents/-Verzeichnis. Anstatt etwa 800 Zeilen Bash-Code manuell einzugeben, klonen Sie das Framework und kopieren Sie das Verzeichnis in Ihren Arbeitsbereich:

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

Layout bestätigen:

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

Achten Sie darauf, dass der Hook-Einstiegspunkt ausführbar ist:

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

Im weiteren Verlauf dieses Labs werden die einzelnen Komponenten, die Sie gerade installiert haben, nacheinander erläutert.

4. Die Always-On-Workflow-Regel

Skills werden bei Bedarf geladen, wenn der Agent entscheidet, dass die Beschreibung eines Skills zur Aufgabe passt. Irgendetwas muss dem Agenten sagen, dass er sie in der richtigen Reihenfolge abrufen soll. Das ist die Aufgabe von .agents/rules/secure_tdd_workflow.md. Im Frontmatter ist trigger: always_on festgelegt, sodass die Regel in jede Runde eingefügt wird:

---
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.

Die Regel verweist auf CONTEXT.md, das Sie in „CodeMender-CLI – Grundlagen“ erstellt haben. Dieselbe Datei, die cm fix zu Ihrer Konvention für parametrisierte Abfragen geführt hat, steuert jetzt die Planung des KI-Agenten. Punkt 6 ist für dieses Lab am wichtigsten: Er beschreibt, was der Agent tut, wenn das Security Gate einen Push mit mehreren Ergebnissen gleichzeitig ablehnt.

5. Die sechs KI-Agenten-Skills

Jeder Skill ist ein Verzeichnis, das eine SKILL.md mit YAML-Frontmatter enthält. Zwei Felder sind erforderlich:

  • name: eine Kennung in Kleinbuchstaben mit Bindestrichen.
  • description: Was der Skill tut und wann er verwendet werden soll. Der KI-Agent liest nur dieses Feld, wenn er entscheidet, ob der vollständige Skill geladen werden soll. Daher wird in jeder Beschreibung unten auch angegeben, wofür der Skill nicht geeignet ist.

Skill

Phase

Zweck

threat-model-assessor

A: Planen

Funktion definieren, STRIDE ausführen, threat_model.md schreiben.

security-test-writer

B: Rot

Schreiben Sie Funktions- und Grenztests, die aus dem richtigen Grund fehlschlagen.

defensive-developer

C: Grün

Schreiben Sie den minimalen Code, der die Tests erfolgreich durchläuft, und verwenden Sie dabei sichere Muster.

local-refactor-scanner

D: Refaktorieren

Bereinigen, die vollständige Suite ausführen, lokale Scanner ausführen, Diff prüfen.

skill-evolution-updater

Kontinuierlich

Neue Konventionen in CONTEXT.md- und SKILL.md-Dateien aufzeichnen.

history-context-seeder

Onboarding

Git-Verlauf auswerten, um CONTEXT.md in einem vorhandenen Repository zu füllen.

Der vollständige Inhalt folgt, damit Sie sehen können, wie Frontmatter und Anleitung zusammenpassen.

1. threat-model-assessor (Phase 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 (Phase 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 (Phase 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 (Phase 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 (Kontinuierliche Weiterentwicklung)

.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 (Onboarding)

.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.

Sie werden diese Fähigkeit in den Labs nicht verwenden, da CONTEXT.md bereits vorhanden ist. Sie ist jedoch die richtige Wahl, wenn Sie das Framework in ein Repository einbinden, das jahrelange Verlaufsdaten und keine schriftlichen Konventionen hat.

6. Antigravity-Hook konfigurieren

.agents/hooks.json weist Antigravity an, die Sicherheitsprüfung vor jedem Terminalbefehl auszuführen, den der Agent ausführt:

{
  "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
          }
        ]
      }
    ]
  }
}

Einige Details zu dieser Datei erklären das Design des Skripts, das sie startet:

  • matcher ist ein regulärer Ausdruck für Toolnamen, nicht für Befehlstext. PreToolUse wird ausgelöst, bevor ein Tool ausgeführt wird, und der Matcher entscheidet, welche Tools ausgeführt werden. run_command ist das Terminal-Tool von Antigravity. Die anderen Alternativen umfassen Varianten mit Plugin-Namespaces und andere Agent-Plattformen, die diese Dateien gemeinsam nutzen. Ein Matcher wie git push* würde nie ausgelöst werden, da kein Tool so heißt. Die Filterung nach dem eigentlichen Befehl erfolgt im Skript.
  • Der Hook empfängt den Toolaufruf über stdin. Antigravity leitet eine JSON-Nutzlast wie {"toolCall": {"name": "run_command", "args": {"CommandLine": "git push origin main"}}, ...} weiter. Das Skript liest .toolCall.args.CommandLine und wird sofort mit einer Zulassungsentscheidung für alles beendet, was kein git push ist.
  • Das Arbeitsverzeichnis ist das Verzeichnis, das hooks.json enthält, sodass der Hook in .agents/ gestartet wird. Der bash -c 'if [ -x ./security_gate_hook.sh ] ...'-Wrapper verarbeitet sowohl diesen Fall als auch den Start aus dem Repository-Stammverzeichnis. Das Script wechseltcd dann zu git rev-parse --show-toplevel, bevor es irgendwelche Aufgaben ausführt.
  • Das Skript antwortet auf stdout mit JSON. {"decision": "allow"} führt den ursprünglichen Befehl aus. {"decision": "deny", "reason": "..."} blockiert sie und zeigt dem Kundenservicemitarbeiter den Grund an. Das Framework gibt auch einen booleschen Wert allow_tool für die Kompatibilität mit älteren Hook-Verträgen aus.
  • Hooks werden synchron ausgeführt und blockieren die Agentenschleife, bis sie abgeschlossen sind oder timeout erreichen (in Sekunden; der Standardwert ist 30, wenn nicht angegeben).

Das -i.bak-Formular funktioniert sowohl mit GNU als auch mit BSD (macOS) sed:

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

7. Funktionsweise des Sicherheitshakens für Tore

security_gate_hook.sh ist ein dünner Einstiegspunkt, der drei Module aus .agents/lib/ bezieht:

Modul

Rolle

gate_common.sh

Konfigurationsstandardwerte, allow/deny-Ausgabe, Schweregrad-Ranking, NDJSON-Audit-Log, Zählung der Versuche, Commit- und CONTEXT.md-Hilfsprogramme.

engine_semgrep.sh

Phase 1: Optionaler deterministischer Scan mit Semgrep. Wird übersprungen, wenn semgrep nicht auf PATH ist.

engine_codemender.sh

Phase 2: Semantischer Scan mit cm find, Klassifizierung, Tracking von Versuchen und Eskalation an cm verify.

Schritt 1: Entscheiden, ob es sich um einen Push handelt

Der Einstiegspunkt extrahiert den Befehl aus der stdin-Nutzlast und testet ihn mit einem regulären Ausdruck, der git push in seinen gängigen Formen (git -C /repo push, cd x && git push, sudo git push) erkennt, während Text in Anführungszeichen wie git commit -m "before git push" ignoriert wird. Alles, was kein Push ist, ist sofort zulässig:

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

Schritt 2: Scanner auswählen

SECURITY_GATE_SCANNER wählt die Pipeline aus. Der Standardwert auto führt Semgrep und CodeMender in dieser Reihenfolge aus, sofern sie installiert sind:

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

Wenn in Phase 1 im Pipeline-Modus blockierende Probleme gefunden werden, werden sie nicht direkt abgelehnt, sondern in eine temporäre Datei geschrieben, die in Phase 2 aufgenommen wird. CodeMender hat also das letzte Wort.

Schritt 3: Die CodeMender-Phase

run_codemender_gate in engine_codemender.sh führt folgende Schritte nacheinander aus:

  1. Geänderte Dateien finden mit git diff --name-only origin/main (Fallback auf HEAD~1). Keine Änderungen bedeutet, dass die Dateien zulässig sind.
  2. Scannen Sie jede Datei mit cm find "$file" -y --bypass-warning und rufen Sie dann alles mit cm report --format json ab. Wenn cm report fehlschlägt oder ungültiges JSON zurückgibt, ist das ein Scanfehler und kein Ergebnis, das als „sauber“ eingestuft wird.
  3. Filtern Sie nach Ergebnissen, deren Status OPEN oder REOPENED ist und deren file_path mit einer der geänderten Dateien endet. Ergebnisse, die Sie bereits in den Grundlagen der CodeMender-Befehlszeile behoben oder verworfen haben, werden ignoriert.
  4. Klassifizieren Sie jedes Ergebnis. Ein Schweregrad von SECURITY_GATE_BLOCK_SEVERITY oder höher (Standard: HIGH) ist blockierend. Alles darunter ist ein Hinweis, wird protokolliert und ausgegeben, stoppt aber den Push nicht.
  5. Zulassen, wenn nichts blockiert wird. Wenn ein Ergebnis, das einen vorherigen Push blockiert hat, nicht mehr vorhanden ist, wird es vom Gate als FIXED protokolliert, eine Konvention an CONTEXT.md unter ## 4. Continuous Evolution angehängt und diese Änderung übernommen.
  6. Zählt die Versuche pro blockierendem Ergebnis, indem das eigene Audit-Log gelesen wird. Jede Ablehnung ist ein Versuch. Bei den Versuchen 1 bis SECURITY_GATE_MAX_RETRIES (Standard: 3) protokolliert das Gate DENIED_TO_AGENT und fügt das Ergebnis einer Ablehnungsnachricht hinzu.
  7. Eskalieren Sie, nachdem das Budget aufgebraucht ist. Beim vierten Versuch für dasselbe Ergebnis wird das Gate cm verify ausgeführt. Wenn das Ergebnis nicht ausnutzbar ist (Exitcode 1 oder Status DISMISSED), wird es auf „Hinweis“ herabgestuft. Wenn dies bestätigt wird oder cm verify abstürzt, protokolliert das Gate BLOCKED und lehnt die Anfrage mit der Bitte um eine manuelle Überprüfung ab.
  8. Ablehnen mit Anleitung Wenn noch Ergebnisse vorhanden sind, die bearbeitet werden können, gibt das Gate diesen Grund an den Agenten zurück:
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

Hier erfolgt die Übergabe zwischen Hook und Fähigkeiten. Der Hook ruft cm fix nicht auf. Darin werden die Fähigkeiten genannt, die der KI-Agent verwenden soll. Der KI-Agent führt die Test-First-Korrektur durch und der nächste git push führt das Gate noch einmal aus.

Konfigurationsreferenz

Alle Einstellungen sind Umgebungsvariablen mit Standardwerten, die in gate_common.sh festgelegt sind:

Variable

Standard

Effekt

SECURITY_GATE_SCANNER

auto

auto, codemender (oder cm) oder semgrep.

SECURITY_GATE_BLOCK_SEVERITY

HIGH

Niedrigster Schweregrad, der blockiert. CRITICAL, HIGH, MEDIUM oder LOW.

SECURITY_GATE_MAX_RETRIES

3

Ablehnungen pro Ergebnis, bevor cm verify konsultiert wird.

SECURITY_GATE_ALLOW_ON_ERROR

false

true lässt einen Push zu, wenn ein Scanner nicht ausgeführt werden kann, und kennzeichnet den Commit mit unverified-scan-.

SECURITY_GATE_TEST_CMD

python3 -m unittest discover -s tests

Testbefehl, der in Ablehnungsaufforderungen und Commit-Nachrichten zitiert wird.

SECURITY_GATE_EVOLVE_CONTEXT

true

Hängen Sie verifizierte Konventionen an CONTEXT.md an.

SECURITY_GATE_LOG

.security-gate/findings-log.ndjson

Audit-Log, das nur angehängt werden kann.

SECURITY_GATE_NOTIFY_CMD

(leer)

Optionaler Befehl, der jedes Gate-Ereignis als JSON über stdin empfängt.

8. Hook offline überprüfen

Bevor das Gate die echte cm berührt, sollten Sie prüfen, ob es sich mit Mocks korrekt verhält. Das Framework enthält einen Test-Harnisch mit gefälschten cm- und semgrep-Binärdateien, die die Pfade „Zulassen“, „Hinweis“, „Ablehnen“, „Fehler“ und „Eskalation“ abdecken:

bash .agents/tests/run_tests.sh

Die Ausführung dauert einige Sekunden und endet mit:

-- test_pipeline_tools_missing_passes_smoothly
-- test_skills_frontmatter_valid
60 passed, 0 failed

Im letzten Test wird auch der Frontmatter jedes Skills unter .agents/skills/ validiert. Diesen Befehl müssen Sie also nach dem Bearbeiten einer SKILL.md-Datei noch einmal ausführen.

Als Nächstes simulieren Sie, was Antigravity für einen Befehl sendet, der kein Push ist. Das Skript sollte allow beantworten, ohne einen Scanner zu berühren:

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

Simulieren Sie jetzt einen Push ohne lokale Änderungen an origin/main. Da noch kein Remote-Repository vorhanden ist, greift das Gate auf HEAD~1 zurück und scannt die Dateien aus Ihrem letzten Commit. Wenn Sie diesen Schritt offline ausführen möchten, verweisen Sie auf die simulierten cm und 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"}

Beide Phasen wurden ausgeführt, da das Mock-Verzeichnis sowohl eine gefälschte semgrep als auch eine gefälschte cm enthält. Fortschrittsmeldungen werden an stderr und nur die JSON-Entscheidung an stdout gesendet. So kann Antigravity das Ergebnis parsen.

Führen Sie schließlich einen Commit für die Framework-Dateien durch, damit sie mit dem Repository übertragen werden:

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

9. Arbeitsbereich in Antigravity öffnen

Öffnen Sie ~/codemender-lab als Ordner in Antigravity. Nach dem Laden hat der KI-Agent:

  • Die secure_tdd_workflow-Regel in jeder Runde.
  • Die sechs On-Demand-Fähigkeiten.
  • Der security-gate-Hook wurde am run_command registriert.

Sie können schnell prüfen, ob die Skills sichtbar sind, indem Sie den Agenten in einer neuen Unterhaltung fragen: „Welche Workspace-Skills stehen dir zur Verfügung und was macht jeder einzelne?“ Die sechs sollten namentlich aufgeführt sein.

Berechtigungen

Der Hook selbst wird von Antigravity und nicht vom Agenten gestartet. Daher werden keine Tool-Berechtigungsaufforderungen angezeigt. Die eigenen Befehle des KI-Agenten hingegen schon. Im nächsten Codelab werden Sie aufgefordert, den Testbefehl, git-Vorgänge und alle cm-Befehle zu genehmigen, die der KI-Agent direkt ausführen möchte. Genehmigen Sie sie, wenn Sie dazu aufgefordert werden. Wenn Antigravity anbietet, sich die Entscheidung für ein Befehlspräfix zu merken, können Sie dies akzeptieren, um wiederholte Aufforderungen während der Schleife zu vermeiden.

Was passiert am git push?

  1. Der KI-Agent ruft sein Terminal-Tool mit git push origin main auf.
  2. Antigravity gleicht run_command mit hooks.json ab und führt security_gate_hook.sh mit dem Toolaufruf in stdin aus.
  3. Das Script erkennt einen Push, findet geänderte Dateien, scannt sie mit cm find und liest cm report.
  4. Wenn nichts blockiert, wird {"decision": "allow"} ausgegeben und der Push wird fortgesetzt.
  5. Wenn Ergebnisse blockiert werden, wird {"decision": "deny", "reason": "..."} ausgegeben. Der Push wird nicht ausgeführt, der Agent sieht den Grund und die Always-On-Regel sowie die benannten Skills geben ihm vor, was als Nächstes zu tun ist: ein fehlgeschlagener Test, eine minimale Korrektur, die Suite noch einmal ausführen, noch einmal pushen.

Glückwunsch! Sie haben das Codelab „CodeMender-Skills und ‑Hooks für Antigravity“ abgeschlossen. Im nächsten Codelab geben Sie dem KI-Agenten eine Feature Request und sehen sich an, wie diese Schleife von Anfang bis Ende ausgeführt wird – vom Bedrohungsmodell bis zu einem Push, der das Gate passiert.