CodeMender Skills & Hooks for Antigravity

1. Introduzione

In questo codelab, configurerai un agente di programmazione AI (Antigravity) in modo che la sicurezza faccia parte del suo normale ciclo di sviluppo anziché essere un passaggio di revisione separato. Installerai un insieme di competenze dell'agente che lo guideranno attraverso un ciclo Pianifica → Rosso → Verde → Rifattorizza e un hook PreToolUse che intercetta git push, scansiona i file modificati con CodeMender e restituisce eventuali risultati all'agente con istruzioni per correggerli prima del test.

Le skill e l'hook provengono dal framework Secure TDD Agent open source. Le installerai nello stesso workspace ~/codemender-lab che hai creato in Nozioni di base sull'interfaccia a riga di comando di CodeMender.

Cosa imparerai a fare

  • In che modo Antigravity rileva regole, skill e hook dello spazio di lavoro in .agents/.
  • Cosa fanno le sei competenze di Secure TDD e quale fase del ciclo possiede ciascuna.
  • In che modo un hook PreToolUse riceve la chiamata allo strumento dell'agente su stdin e restituisce una decisione di autorizzazione/negazione.
  • Come l'hook del controllo di sicurezza (security_gate_hook.sh) esegue cm find, classifica i risultati in base alla gravità, monitora i tentativi di correzione e li scala con cm verify.
  • Come verificare l'intera pipeline di hook offline con scanner fittizi prima di indirizzarla al cm reale.

Prerequisiti

  • Completamento delle nozioni di base sull'interfaccia a riga di comando di CodeMender. Questo lab continua nella directory ~/codemender-lab e riutilizza i relativi sample_app/, CONTEXT.md, cronologia Git e ~/.codemender/config.yaml.
  • Antigravity installato, con la possibilità di aprire una cartella locale come area di lavoro.
  • git, jq e bash installate. Gli script hook sono in formato bash semplice e vengono eseguiti su bash 3.2 standard di macOS e su versioni successive.
  • L'ambiente virtuale Python di CodeMender CLI Basics (~/codemender-lab/.venv) con Flask installato.
  • Conoscenza di base degli script shell.

2. Configurazione di Workspace

Passaggio 1: torna alla directory del lab

Tutti i comandi di questo lab vengono eseguiti da ~/codemender-lab con l'ambiente virtuale attivo:

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

Verifica che l'area di lavoro del lab precedente sia intatta e che l'albero di lavoro sia pulito:

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

git status --short non dovrebbe stampare nulla. Se sono presenti file, eseguine il commit prima di continuare.

Passaggio 2: assegna un nome al branch main

Il controllo di sicurezza confronta l'albero di lavoro con origin/main per decidere quali file analizzare. Se questo riferimento non esiste, viene utilizzato HEAD~1, che copre solo il commit più recente. Assicurati che il tuo branch si chiami main:

git branch -M main

Passaggio 3: aggiungi un entry point della suite di test

Il ciclo Secure TDD chiede all'agente di eseguire python3 -m unittest discover -s tests dopo ogni correzione, quindi l'area di lavoro deve contenere una directory tests/. Inizia con un test di caratterizzazione in modo che la suite abbia qualcosa di reale da eseguire:

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

Dovresti vedere Ran 1 test e OK.

Passaggio 4: estendi .gitignore ed esegui il commit

Aggiungi i file di runtime prodotti da questo lab a .gitignore, quindi esegui il commit della base di riferimento:

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

3. Installazione dei file del framework

Le competenze, la regola, l'hook e il test harness offline si trovano tutti in un'unica directory .agents/. Anziché digitare manualmente circa 800 righe di bash, clona il framework e copia la directory nel tuo workspace:

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

Conferma il layout:

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

Assicurati che l'entry point dell'hook sia eseguibile:

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

Il resto di questo lab illustra ciò che hai appena installato, un elemento alla volta.

4. La regola del workflow sempre attivo

Le skill vengono caricate on demand, quando l'agente decide che la descrizione di una skill corrisponde all'attività. Qualcosa deve indicare all'agente di raggiungerli nell'ordine corretto. Questo è il compito di .agents/rules/secure_tdd_workflow.md. Il suo frontmatter imposta trigger: always_on, quindi la regola viene inserita in ogni turno:

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

La regola fa riferimento a CONTEXT.md, che hai creato in Nozioni di base sull'interfaccia a riga di comando di CodeMender. Lo stesso file che ha indirizzato cm fix verso la convenzione delle query parametrizzate ora guida la pianificazione dell'agente. L'elemento 6 è il più importante per questo lab: è ciò che l'agente segue quando il controllo di sicurezza rifiuta un push con più risultati contemporaneamente.

5. Le sei skill dell'agente

Ogni skill è una directory contenente un file SKILL.md con front matter YAML. Sono obbligatori due campi:

  • name: un identificatore in minuscolo con trattini.
  • description: cosa fa la skill e quando utilizzarla. L'agente legge solo questo campo quando decide se caricare la skill completa, quindi ogni descrizione di seguito indica anche per cosa non è adatta la skill.

Skill

Fase

Finalità

threat-model-assessor

A: Plan

Definisci l'ambito della funzionalità, esegui STRIDE, scrivi threat_model.md.

security-test-writer

B: Rosso

Scrivere test funzionali e di confine che non vanno a buon fine per il motivo giusto.

defensive-developer

C: Verde

Scrivi il codice minimo che rende i test verdi, utilizzando pattern sicuri.

local-refactor-scanner

D: Rifattorizza

Eseguire la pulizia, eseguire la suite completa, eseguire gli scanner locali, esaminare le differenze.

skill-evolution-updater

Continua

Registra nuove convenzioni nei file CONTEXT.md e SKILL.md.

history-context-seeder

Onboarding

Estrai la cronologia Git per eseguire il seeding di CONTEXT.md in un repository esistente.

Di seguito sono riportati i contenuti completi, in modo da poter vedere come si combinano il frontmatter e le istruzioni.

1. threat-model-assessor (Fase 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 (Fase 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 (Fase 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 (Fase 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 (Evoluzione costante)

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

Non utilizzerai questa skill nei lab perché CONTEXT.md esiste già, ma è quella da utilizzare quando porti il framework in un repository con anni di storia e nessuna convenzione scritta.

6. Configurazione dell'hook Antigravity

.agents/hooks.json indica ad Antigravity di eseguire il controllo di sicurezza prima di qualsiasi comando del terminale eseguito dall'agente:

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

Alcuni dettagli su questo file spiegano il design dello script che avvia:

  • matcher è un'espressione regolare sui nomi degli strumenti, non sul testo del comando. PreToolUse viene attivato prima dell'esecuzione di uno strumento e il matcher decide quali strumenti. run_command è lo strumento terminale di Antigravity; le altre alternative coprono le varianti con spazio dei nomi dei plug-in e altre piattaforme di agenti che condividono questi file. Un matcher come git push* non si attiverebbe mai perché nessuno strumento ha questo nome. Il filtro sul comando effettivo avviene all'interno dello script.
  • L'hook riceve la chiamata allo strumento su stdin. Antigravity invia un payload JSON come {"toolCall": {"name": "run_command", "args": {"CommandLine": "git push origin main"}}, ...}. Lo script legge .toolCall.args.CommandLine ed esce immediatamente con una decisione di autorizzazione per tutto ciò che non è un git push.
  • La directory di lavoro è quella contenente hooks.json, quindi l'hook viene avviato all'interno di .agents/. Il wrapper bash -c 'if [ -x ./security_gate_hook.sh ] ...' gestisce sia questo caso sia l'avvio dalla directory principale del repository. Lo script esegue quindi il comando cd per passare a git rev-parse --show-toplevel prima di eseguire qualsiasi operazione.
  • Lo script risponde su stdout con JSON. {"decision": "allow"} consente l'esecuzione del comando originale. {"decision": "deny", "reason": "..."} lo blocca e mostra il motivo all'agente. Il framework genera anche un valore booleano allow_tool per la compatibilità con i contratti hook precedenti.
  • Gli hook vengono eseguiti in modo sincrono e bloccano il loop dell'agente fino al completamento o al raggiungimento di timeout (in secondi; il valore predefinito è 30 se omesso).

Il formato -i.bak funziona sia con GNU che con BSD (macOS) sed:

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

7. Come funziona il gancio del cancello di sicurezza

security_gate_hook.sh è un entry point leggero che genera tre moduli da .agents/lib/:

Modulo

Ruolo

gate_common.sh

Valori predefiniti della configurazione, output allow/deny, ranking della gravità, audit log NDJSON, conteggio dei tentativi, commit e helper CONTEXT.md.

engine_semgrep.sh

Fase 1. Analisi deterministica facoltativa con Semgrep. Ignorato se semgrep non è su PATH.

engine_codemender.sh

Fase 2. Scansione semantica con cm find, classificazione, monitoraggio dei tentativi e riassegnazione a cm verify.

Passaggio 1: decidi se si tratta di un push

L'entry point estrae il comando dal payload stdin e lo testa rispetto a una regex che riconosce git push nelle sue forme comuni (git -C /repo push, cd x && git push, sudo git push) ignorando il testo tra virgolette come git commit -m "before git push". Tutto ciò che non è un push è consentito immediatamente:

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

Passaggio 2: scegli gli scanner

SECURITY_GATE_SCANNER seleziona la pipeline. Il valore predefinito, auto, esegue Semgrep e CodeMender, se installati, in questo ordine:

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

Quando la Fase 1 rileva problemi di blocco in modalità pipeline, non li rifiuta autonomamente, ma li scrive in un file temporaneo che viene acquisito dalla Fase 2, in modo che CodeMender abbia l'ultima parola.

Passaggio 3: la fase CodeMender

run_codemender_gate in engine_codemender.sh esegue le seguenti operazioni, nell'ordine indicato:

  1. Trova i file modificati con git diff --name-only origin/main (con fallback a HEAD~1). Se non ci sono modifiche, l'accesso è consentito.
  2. Scansiona ogni file con cm find "$file" -y --bypass-warning, quindi recupera tutto con cm report --format json. Se cm report non va a buon fine o restituisce un JSON non valido, si tratta di un errore di scansione, non di un risultato pulito.
  3. Filtra i risultati il cui stato è OPEN o REOPENED e il cui file_path termina con uno dei file modificati. I risultati che hai già corretto o ignorato in Nozioni di base sull'interfaccia a riga di comando di CodeMender vengono ignorati.
  4. Classifica ogni risultato. La gravità pari o superiore a SECURITY_GATE_BLOCK_SEVERITY (valore predefinito HIGH) è bloccante; qualsiasi valore inferiore è informativo, registrato e stampato, ma non interrompe il push.
  5. Consenti se non ci sono blocchi. Se un risultato che ha bloccato un push precedente non è più presente, il gate lo registra come FIXED, aggiunge una convenzione a CONTEXT.md in ## 4. Continuous Evolution ed esegue il commit della modifica.
  6. Conteggia i tentativi per bloccare i risultati leggendo il proprio audit log. Ogni rifiuto corrisponde a un tentativo. Ai tentativi da 1 a SECURITY_GATE_MAX_RETRIES (valore predefinito 3), il gate registra DENIED_TO_AGENT e aggiunge il risultato a un messaggio di rifiuto.
  7. Riassegna il caso dopo che il budget è stato speso. Al quarto tentativo per lo stesso risultato, il gate esegue cm verify. Se il risultato non è sfruttabile (codice di uscita 1 o stato DISMISSED), viene declassato ad avviso. Se viene confermato o se cm verify si arresta in modo anomalo, il gate registra BLOCKED e nega con una richiesta di revisione umana.
  8. Nega con istruzioni. Se alcuni risultati rimangono utilizzabili, il gate restituisce questo motivo all'agente:
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

Questo è il passaggio tra l'hook e le competenze. L'hook non chiama cm fix. Indica le competenze che l'agente deve utilizzare, l'agente esegue la correzione test-first e il git push successivo esegue nuovamente il gate.

Riferimento per la configurazione

Tutte le impostazioni sono variabili di ambiente con valori predefiniti impostati in gate_common.sh:

Variabile

Predefinito

Effetto

SECURITY_GATE_SCANNER

auto

auto, codemender (o cm) o semgrep.

SECURITY_GATE_BLOCK_SEVERITY

HIGH

Gravità minima che blocca. CRITICAL, HIGH, MEDIUM o LOW.

SECURITY_GATE_MAX_RETRIES

3

Rifiuti per risultato prima di consultare cm verify.

SECURITY_GATE_ALLOW_ON_ERROR

false

true consente un push quando uno scanner non viene eseguito, aggiungendo il tag unverified-scan- al commit.

SECURITY_GATE_TEST_CMD

python3 -m unittest discover -s tests

Comando di test citato nei prompt di rifiuto e nei messaggi di commit.

SECURITY_GATE_EVOLVE_CONTEXT

true

Aggiungi le convenzioni verificate a CONTEXT.md.

SECURITY_GATE_LOG

.security-gate/findings-log.ndjson

Audit log di sola aggiunta.

SECURITY_GATE_NOTIFY_CMD

(vuoto)

Comando facoltativo che riceve ogni evento gate come JSON su stdin.

8. Verifica dell'hook offline

Prima che il gate tocchi il cm reale, verifica che si comporti correttamente con i mock. Il framework include un test harness con file binari cm e semgrep fittizi che coprono i percorsi di autorizzazione, avviso, rifiuto, errore ed escalation:

bash .agents/tests/run_tests.sh

L'esecuzione richiede alcuni secondi e termina con:

-- test_pipeline_tools_missing_passes_smoothly
-- test_skills_frontmatter_valid
60 passed, 0 failed

L'ultimo test convalida anche il frontmatter di ogni skill in .agents/skills/, quindi questo è il comando da eseguire nuovamente dopo aver modificato un SKILL.md.

Ora simula ciò che Antigravity invia per un comando che non è un push. Lo script deve rispondere allow senza toccare nessuno scanner:

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

Ora simula un push senza modifiche locali rispetto a origin/main. Poiché non esiste ancora un repository remoto, il gate torna a HEAD~1 ed esegue la scansione dei file dell'ultimo commit. Per mantenere questo passaggio offline, indirizzalo verso i mock cm e 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"}

Entrambe le fasi sono state eseguite perché la directory fittizia contiene un semgrep fittizio e un cm fittizio. I messaggi di avanzamento vengono inviati a stderr e solo la decisione JSON viene inviata a stdout, il che consente ad Antigravity di analizzare il risultato.

Infine, esegui il commit dei file del framework in modo che vengano trasferiti con il repository:

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

9. Apertura del workspace in Antigravity

Apri ~/codemender-lab come cartella in Antigravity. Una volta caricato, l'agente ha:

  • La regola secure_tdd_workflow in ogni turno.
  • Le sei skill disponibili on demand.
  • L'hook security-gate registrato su run_command.

Un modo rapido per verificare che le skill siano visibili è chiedere all'agente, in una nuova conversazione, "Quali skill di Workspace hai a disposizione e cosa fa ciascuna?" Dovrebbe elencare i sei per nome.

Autorizzazioni

L'hook stesso viene avviato da Antigravity, non dall'agente, quindi non passa attraverso i prompt di autorizzazione dello strumento. I comandi dell'agente sì. Durante il prossimo codelab, aspettati richieste di approvazione per il comando di test, le operazioni git e qualsiasi comando cm che l'agente decide di eseguire direttamente. Approvale quando richiesto. Se Antigravity offre di ricordare la decisione per un prefisso di comando, accettala per evitare ulteriori richieste durante il loop.

Cosa succede il giorno git push

  1. L'agente chiama il suo strumento terminale con git push origin main.
  2. Antigravity confronta run_command con hooks.json ed esegue security_gate_hook.sh con la chiamata allo strumento su stdin.
  3. Lo script riconosce un push, trova i file modificati, li scansiona con cm find e legge cm report.
  4. Se non ci sono blocchi, viene stampato {"decision": "allow"} e il push procede.
  5. Se i risultati bloccano, viene stampato {"decision": "deny", "reason": "..."}. Il push non viene eseguito, l'agente ne vede il motivo e la regola sempre attiva, insieme alle competenze denominate, gli dicono cosa fare dopo: un test non riuscito, una correzione minima, eseguire nuovamente la suite, eseguire nuovamente il push.

Complimenti! Hai completato il codelab CodeMender Skills & Hooks for Antigravity. Nel prossimo codelab, assegnerai all'agente una richiesta di funzionalità e osserverai l'esecuzione di questo loop end-to-end, dal modello di minacce a un push che supera il gate.