1. Introduction
Dans cet atelier de programmation, vous allez configurer un agent de codage IA (Antigravity) afin que la sécurité fasse partie de sa boucle de développement normale, plutôt que d'être une étape d'examen distincte. Vous allez installer un ensemble de compétences d'agent qui guident l'agent tout au long d'un cycle Plan → Rouge → Vert → Refactorisation, ainsi qu'un hook PreToolUse qui intercepte git push, analyse les fichiers modifiés avec CodeMender et transmet les résultats à l'agent avec des instructions pour les corriger en priorité.
Les compétences et le hook proviennent du framework d'agent TDD sécurisé Open Source. Vous les installerez dans l'espace de travail ~/codemender-lab que vous avez créé dans l'atelier "CodeMender : principes de base de la CLI".
Objectifs de l'atelier
- Comment Antigravity découvre les règles, les compétences et les hooks de l'espace de travail sous
.agents/. - Le rôle des six compétences du TDD sécurisé et la phase de la boucle à laquelle chacune d'elles appartient.
- Comment un hook
PreToolUsereçoit l'appel d'outil de l'agent sur stdin et renvoie une décision d'autorisation/de refus. - Comment le hook de la barrière de sécurité (
security_gate_hook.sh) exécutecm find, classe les résultats par gravité, suit les tentatives de correction et les escalade aveccm verify. - Comment valider l'ensemble du pipeline de hooks hors connexion avec des scanners fictifs avant de le pointer vers le véritable
cm.
Prérequis
- Vous avez terminé le module "Principes de base de la CLI CodeMender". Cet atelier se poursuit dans le répertoire
~/codemender-labet réutilise ses fichierssample_app/,CONTEXT.md, l'historique Git et~/.codemender/config.yaml. - Antigravity installé, avec la possibilité d'ouvrir un dossier local en tant qu'espace de travail.
git,jqetbashinstallés. Les scripts de hook sont des scripts bash standards et s'exécutent sur la version bash 3.2 de macOS ainsi que sur les versions plus récentes.- L'environnement virtuel Python des principes de base de la CLI CodeMender (
~/codemender-lab/.venv) avec Flask installé. - Connaissances de base en écriture de scripts shell.
2. Configuration Workspace
Étape 1 : Revenez au répertoire de l'atelier
Toutes les commandes de cet atelier s'exécutent à partir de ~/codemender-lab avec l'environnement virtuel actif :
cd ~/codemender-lab && source .venv/bin/activate
Vérifiez que l'espace de travail de l'atelier précédent est intact et que votre arbre de travail est propre :
ls sample_app/data_service.py CONTEXT.md .gitignore
git status --short
git status --short ne doit rien afficher. Si des fichiers sont listés, effectuez un commit avant de continuer.
Étape 2 : Nommez la branche main
La barrière de sécurité compare votre arborescence de travail à origin/main pour décider des fichiers à analyser. Si cette référence n'existe pas, il utilise HEAD~1, qui ne couvre que le commit le plus récent. Assurez-vous que votre branche s'appelle main :
git branch -M main
Étape 3 : Ajouter un point d'entrée de suite de tests
La boucle TDD sécurisée demande à l'agent d'exécuter python3 -m unittest discover -s tests après chaque correction. L'espace de travail a donc besoin d'un répertoire tests/. Commencez par un test de caractérisation pour que la suite ait quelque chose de réel à exécuter :
mkdir -p tests && touch tests/__init__.py
cat << 'EOF' > tests/test_data_service.py
import unittest
from sample_app.data_service import hash_password
class HashPasswordTests(unittest.TestCase):
def test_returns_hex_digest(self):
digest = hash_password("hunter2")
self.assertIsInstance(digest, str)
int(digest, 16) # raises ValueError if not hexadecimal
if __name__ == "__main__":
unittest.main()
EOF
python3 -m unittest discover -s tests
Ran 1 test et OK doivent s'afficher.
Étape 4 : Étendre .gitignore et effectuer un commit
Ajoutez les fichiers d'exécution produits par cet atelier à .gitignore, puis effectuez un commit de la référence :
printf '.security-gate/\nusers.db\n*.bak\n' >> .gitignore
git add -A && git commit -m "Add test suite entry point for Secure TDD"
3. Installer les fichiers du framework
Les compétences, la règle, le hook et l'atelier de test hors connexion se trouvent tous dans un seul répertoire .agents/. Plutôt que de saisir manuellement environ 800 lignes de code bash, clonez le framework et copiez ce répertoire dans votre espace de travail :
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
Confirmez la mise en page :
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
Assurez-vous que le point d'entrée du hook est exécutable :
chmod +x .agents/security_gate_hook.sh
ls -l .agents/security_gate_hook.sh
Le reste de cet atelier vous guide à travers ce que vous venez d'installer, un élément à la fois.
4. La règle de workflow Always-On
Les compétences sont chargées à la demande, lorsque l'agent décide que la description d'une compétence correspond à la tâche. Quelque chose doit indiquer à l'agent de les atteindre dans le bon ordre. C'est le rôle de .agents/rules/secure_tdd_workflow.md. Son frontmatter définit trigger: always_on, de sorte que la règle est injectée à chaque tour :
---
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 règle fait référence à CONTEXT.md, que vous avez créé dans "Principes de base de la CLI CodeMender". Le même fichier qui a orienté cm fix vers votre convention de requête paramétrée oriente désormais la planification de l'agent. L'élément 6 est le plus important pour cet atelier : c'est ce que l'agent suit lorsque la barrière de sécurité rejette un push contenant plusieurs résultats à la fois.
5. Les six compétences agentiques
Chaque compétence est un répertoire contenant un fichier SKILL.md avec un frontmatter YAML. Deux champs sont obligatoires :
name: identifiant en minuscules, avec des traits d'union.description: ce que fait la compétence et quand l'utiliser. L'agent ne lit que ce champ lorsqu'il décide de charger ou non la compétence complète. Par conséquent, chaque description ci-dessous indique également ce pour quoi la compétence n'est pas conçue.
Compétence | Phase | Objectif |
| A: La planification | Définir le champ d'application de la fonctionnalité, exécuter STRIDE, écrire |
| B: Rouge | Écrivez des tests fonctionnels et de limites qui échouent pour la bonne raison. |
| C: Vert | Écrivez le code minimal qui fait passer les tests au vert, en utilisant des modèles sûrs. |
| D: Refactorisation | Nettoyez, exécutez la suite complète, exécutez les scanners locaux, examinez les différences. |
| Continue | Enregistrez les nouvelles conventions dans les fichiers |
| Intégration | Exploitez l'historique Git pour amorcer |
Le contenu complet suit afin que vous puissiez voir comment le frontmatter et les instructions s'articulent.
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 (Évolution constante)
.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.
Vous n'utiliserez pas cette compétence dans les ateliers, car CONTEXT.md existe déjà. Toutefois, vous devrez y recourir lorsque vous appliquerez le framework à un dépôt qui existe depuis des années et qui ne comporte aucune convention écrite.
6. Configurer le hook Antigravity
.agents/hooks.json indique à Antigravity d'exécuter la barrière de sécurité avant toute commande de terminal exécutée par l'agent :
{
"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
}
]
}
]
}
}
Voici quelques détails sur ce fichier qui expliquent la conception du script qu'il lance :
matcherest une expression régulière sur les noms d'outils, et non sur le texte de la commande.PreToolUsese déclenche avant l'exécution d'un outil, et l'outil de mise en correspondance décide des outils.run_commandest l'outil de terminal d'Antigravity. Les autres alternatives couvrent les variantes d'espace de noms de plug-in et d'autres plates-formes d'agent qui partagent ces fichiers. Un outil de mise en correspondance tel quegit push*ne se déclencherait jamais, car aucun outil ne porte ce nom. Le filtrage de la commande réelle s'effectue dans le script.- Le hook reçoit l'appel d'outil sur stdin. Antigravity transmet une charge utile JSON telle que
{"toolCall": {"name": "run_command", "args": {"CommandLine": "git push origin main"}}, ...}. Le script lit.toolCall.args.CommandLineet se ferme immédiatement avec une décision d'autorisation pour tout ce qui n'est pas ungit push. - Le répertoire de travail est le répertoire contenant
hooks.json, de sorte que le hook démarre dans.agents/. Le wrapperbash -c 'if [ -x ./security_gate_hook.sh ] ...'gère à la fois ce cas et le lancement à partir de la racine du dépôt. Le scriptcdensuite versgit rev-parse --show-toplevelavant d'effectuer une action. - Le script répond sur stdout au format JSON.
{"decision": "allow"}permet d'exécuter la commande d'origine.{"decision": "deny", "reason": "..."}le bloque et indique la raison à l'agent. Le framework émet également une valeur booléenneallow_toolpour assurer la compatibilité avec les anciens contrats de hook. - Les hooks s'exécutent de manière synchrone et bloquent la boucle d'agent jusqu'à ce qu'ils se terminent ou atteignent
timeout(en secondes ; la valeur par défaut est 30 si elle est omise).
La forme -i.bak fonctionne avec GNU et BSD (macOS) sed :
sed -i.bak 's/"timeout": 120/"timeout": 900/' .agents/hooks.json && rm .agents/hooks.json.bak
7. Fonctionnement du crochet de la barrière de sécurité
security_gate_hook.sh est un point d'entrée léger qui extrait trois modules de .agents/lib/ :
Module | Rôle |
| Valeurs de configuration par défaut, sortie |
| Étape 1. Analyse déterministe facultative avec Semgrep. Ignoré si |
| Étape 2 : Analyse sémantique avec |
Étape 1 : Déterminer s'il s'agit d'un push
Le point d'entrée extrait la commande de la charge utile stdin et la teste par rapport à une expression régulière qui reconnaît git push dans ses formes courantes (git -C /repo push, cd x && git push, sudo git push) tout en ignorant le texte entre guillemets tel que git commit -m "before git push". Tout ce qui n'est pas un push est autorisé immédiatement :
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
Étape 2 : Choisissez les scanners
SECURITY_GATE_SCANNER sélectionne le pipeline. La valeur par défaut, auto, exécute Semgrep et CodeMender s'ils sont installés, dans cet ordre :
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
Lorsque l'étape 1 détecte des problèmes bloquants en mode pipeline, elle ne les refuse pas d'elle-même. Elle les écrit dans un fichier temporaire que l'étape 2 récupère, de sorte que CodeMender ait le dernier mot.
Étape 3 : Étape CodeMender
run_codemender_gate dans engine_codemender.sh effectue les opérations suivantes, dans l'ordre :
- Recherchez les fichiers modifiés avec
git diff --name-only origin/main(en revenant àHEAD~1). S'il n'y a aucune modification, cela signifie que l'accès est autorisé. - Analysez chaque fichier avec
cm find "$file" -y --bypass-warning, puis récupérez tout aveccm report --format json. Sicm reportéchoue ou renvoie un JSON non valide, il s'agit d'une erreur d'analyse, et non d'un résultat propre. - Filtrez les résultats dont l'état est
OPENouREOPENEDet dont lefile_pathse termine par l'un des fichiers modifiés. Les résultats que vous avez déjà corrigés ou ignorés dans "Principes de base de la CLI CodeMender" sont ignorés. - Classifiez chaque résultat. La gravité supérieure ou égale à
SECURITY_GATE_BLOCK_SEVERITY(HIGHpar défaut) est bloquante. Tout niveau inférieur est consultatif, consigné et imprimé, mais n'arrête pas le push. - Autoriser si rien ne bloque. Si un résultat qui bloquait un push précédent a disparu, la porte d'accès l'enregistre en tant que
FIXED, ajoute une convention àCONTEXT.mdsous## 4. Continuous Evolutionet valide cette modification. - Compter les tentatives par résultat bloquant en lisant son propre journal d'audit. Chaque refus correspond à une tentative. Lors des tentatives 1 à
SECURITY_GATE_MAX_RETRIES(par défaut 3), la porte d'accès consigneDENIED_TO_AGENTet ajoute le résultat à un message de refus. - Escaladez le problème une fois le budget épuisé. À la quatrième tentative pour le même résultat, la porte d'évaluation exécute
cm verify. Si le résultat n'est pas exploitable (code de sortie 1 ou étatDISMISSED), il est rétrogradé au niveau "Avis". Si elle est confirmée, ou sicm verifyplante, la porte d'entrée consigneBLOCKEDet refuse la requête en demandant un examen manuel. - Refuser avec des instructions. Si des résultats restent exploitables, la porte d'entrée renvoie la raison suivante à l'agent :
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
C'est le passage de l'accroche aux compétences. Le hook n'appelle pas cm fix. Il nomme les compétences que l'agent doit utiliser, l'agent effectue la correction en testant d'abord, et le git push suivant réexécute la porte.
Documentation de référence sur la configuration
Tous les paramètres sont des variables d'environnement avec des valeurs par défaut définies dans gate_common.sh :
Variable | Par défaut | Effet |
|
|
|
|
| Niveau de gravité le plus faible qui bloque. |
|
| Refus par résultat avant que |
|
|
|
|
| Commande de test citée dans les prompts de refus et les messages de commit. |
|
| Ajoutez les conventions validées à |
|
| Journal d'audit en mode ajout uniquement. |
| (vide) | Commande facultative qui reçoit chaque événement de porte en tant que JSON sur stdin. |
8. Vérifier le hook hors connexion
Avant que la porte ne touche le véritable cm, vérifiez qu'elle se comporte correctement avec les simulations. Le framework fournit un faisceau de test avec de faux binaires cm et semgrep qui couvrent les chemins d'autorisation, d'avis, de refus, d'erreur et d'escalade :
bash .agents/tests/run_tests.sh
L'exécution prend quelques secondes et se termine par :
-- test_pipeline_tools_missing_passes_smoothly
-- test_skills_frontmatter_valid
60 passed, 0 failed
Le dernier test valide également le frontmatter de chaque compétence sous .agents/skills/. C'est donc la commande à réexécuter après avoir modifié un SKILL.md.
Ensuite, simulez ce qu'Antigravity envoie pour une commande qui n'est pas un push. Le script doit répondre allow sans toucher à aucun scanner :
echo '{"toolCall":{"name":"run_command","args":{"CommandLine":"git status"}}}' \
| bash .agents/security_gate_hook.sh
{"allow_tool": true, "decision": "allow"}
Simulez maintenant un push sans modifications locales sur origin/main. Comme il n'y a pas encore de dépôt distant, la porte d'accès utilise HEAD~1 et analyse les fichiers de votre dernier commit. Pour que cette étape reste hors connexion, faites-la pointer vers les simulations cm et 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"}
Les deux étapes ont été exécutées, car le répertoire fictif contient un faux semgrep ainsi qu'un faux cm. Les messages de progression sont envoyés à stderr et seule la décision JSON est envoyée à stdout, ce qui permet à Antigravity d'analyser le résultat.
Enfin, effectuez un commit des fichiers du framework pour qu'ils soient inclus dans le dépôt :
git add -A && git commit -m "Add Secure TDD skills, rule, and security gate hook"
9. Ouvrir l'espace de travail dans Antigravity
Ouvrez ~/codemender-lab en tant que dossier dans Antigravity. Une fois chargé, l'agent dispose des éléments suivants :
- La règle
secure_tdd_workflowà chaque tour. - Les six compétences disponibles à la demande.
- Le hook
security-gateenregistré surrun_command.
Pour vérifier rapidement que les compétences sont visibles, demandez à l'agent, dans une nouvelle conversation, "Quelles sont les compétences Workspace dont tu disposes et à quoi sert chacune d'elles ?". Il doit lister les six par leur nom.
Autorisations
Le hook lui-même est lancé par Antigravity, et non par l'agent. Il ne passe donc pas par les invites d'autorisation de l'outil. Les commandes de l'agent, elles, le sont. Dans le prochain atelier de programmation, vous verrez des demandes d'approbation pour la commande de test, les opérations git et toutes les commandes cm que l'agent décide d'exécuter directement. Approuvez-les lorsqu'on vous le demande. Si Antigravity propose de mémoriser la décision pour un préfixe de commande, accepter cette option évite d'avoir à répondre à nouveau à la question au cours de la boucle.
Que se passe-t-il le git push ?
- L'agent appelle son outil de terminal avec
git push origin main. - Antigravity met en correspondance
run_commandavechooks.jsonet exécutesecurity_gate_hook.shavec l'appel d'outil sur stdin. - Le script reconnaît un push, recherche les fichiers modifiés, les analyse avec
cm findet litcm report. - Si rien ne bloque, il affiche
{"decision": "allow"}et le push se poursuit. - Si le bloc de résultats est présent, il affiche
{"decision": "deny", "reason": "..."}. Le push n'est pas exécuté, l'agent voit la raison, et la règle toujours activée ainsi que les compétences nommées lui indiquent ce qu'il doit faire ensuite : un test échoué, un correctif minimal, réexécuter la suite, effectuer un nouveau push.
Félicitations ! Vous avez terminé l'atelier de programmation "Compétences et hooks CodeMender pour Antigravity". Dans le prochain atelier de programmation, vous allez envoyer une demande de fonctionnalité à l'agent et observer l'exécution de cette boucle de bout en bout, du modèle des menaces au push qui passe le contrôle.