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
PreToolUsericeve 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) eseguecm find, classifica i risultati in base alla gravità, monitora i tentativi di correzione e li scala concm verify. - Come verificare l'intera pipeline di hook offline con scanner fittizi prima di indirizzarla al
cmreale.
Prerequisiti
- Completamento delle nozioni di base sull'interfaccia a riga di comando di CodeMender. Questo lab continua nella directory
~/codemender-labe riutilizza i relativisample_app/,CONTEXT.md, cronologia Git e~/.codemender/config.yaml. - Antigravity installato, con la possibilità di aprire una cartella locale come area di lavoro.
git,jqebashinstallate. 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à |
| A: Plan | Definisci l'ambito della funzionalità, esegui STRIDE, scrivi |
| B: Rosso | Scrivere test funzionali e di confine che non vanno a buon fine per il motivo giusto. |
| C: Verde | Scrivi il codice minimo che rende i test verdi, utilizzando pattern sicuri. |
| D: Rifattorizza | Eseguire la pulizia, eseguire la suite completa, eseguire gli scanner locali, esaminare le differenze. |
| Continua | Registra nuove convenzioni nei file |
| Onboarding | Estrai la cronologia Git per eseguire il seeding di |
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.PreToolUseviene 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 comegit 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.CommandLineed esce immediatamente con una decisione di autorizzazione per tutto ciò che non è ungit push. - La directory di lavoro è quella contenente
hooks.json, quindi l'hook viene avviato all'interno di.agents/. Il wrapperbash -c 'if [ -x ./security_gate_hook.sh ] ...'gestisce sia questo caso sia l'avvio dalla directory principale del repository. Lo script esegue quindi il comandocdper passare agit rev-parse --show-toplevelprima 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 booleanoallow_toolper 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 |
| Valori predefiniti della configurazione, output |
| Fase 1. Analisi deterministica facoltativa con Semgrep. Ignorato se |
| Fase 2. Scansione semantica con |
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:
- Trova i file modificati con
git diff --name-only origin/main(con fallback aHEAD~1). Se non ci sono modifiche, l'accesso è consentito. - Scansiona ogni file con
cm find "$file" -y --bypass-warning, quindi recupera tutto concm report --format json. Secm reportnon va a buon fine o restituisce un JSON non valido, si tratta di un errore di scansione, non di un risultato pulito. - Filtra i risultati il cui stato è
OPENoREOPENEDe il cuifile_pathtermina 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. - Classifica ogni risultato. La gravità pari o superiore a
SECURITY_GATE_BLOCK_SEVERITY(valore predefinitoHIGH) è bloccante; qualsiasi valore inferiore è informativo, registrato e stampato, ma non interrompe il push. - 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 aCONTEXT.mdin## 4. Continuous Evolutioned esegue il commit della modifica. - 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 registraDENIED_TO_AGENTe aggiunge il risultato a un messaggio di rifiuto. - 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 statoDISMISSED), viene declassato ad avviso. Se viene confermato o secm verifysi arresta in modo anomalo, il gate registraBLOCKEDe nega con una richiesta di revisione umana. - 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 |
|
|
|
|
| Gravità minima che blocca. |
|
| Rifiuti per risultato prima di consultare |
|
|
|
|
| Comando di test citato nei prompt di rifiuto e nei messaggi di commit. |
|
| Aggiungi le convenzioni verificate a |
|
| Audit log di sola aggiunta. |
| (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_workflowin ogni turno. - Le sei skill disponibili on demand.
- L'hook
security-gateregistrato surun_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
- L'agente chiama il suo strumento terminale con
git push origin main. - Antigravity confronta
run_commandconhooks.jsoned eseguesecurity_gate_hook.shcon la chiamata allo strumento su stdin. - Lo script riconosce un push, trova i file modificati, li scansiona con
cm finde leggecm report. - Se non ci sono blocchi, viene stampato
{"decision": "allow"}e il push procede. - 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.