Ir al contenido

F06 — AI-Assisted Build

AI-First Engineering Framework — Baseline v6.5

Sección titulada «AI-First Engineering Framework — Baseline v6.5»

Versión: 3.0.0 | Estado: Activo | Fecha: Marzo 2026 | Tipo: Framework Baseline


1. Branch Strategy — Trunk-Based para Equipos de 3

Sección titulada «1. Branch Strategy — Trunk-Based para Equipos de 3»

Para equipos de máximo 3 personas, Git Flow (develop, release, hotfix branches) es overhead innecesario. Trunk-Based Development mantiene la velocidad:

AspectoGit FlowTrunk-Based (nuestro)
Branches vivas5+ (main, develop, feature/, release/, hotfix/*)2-3 (main + 1-2 feature)
Merge conflictsFrecuentesRaros (branches cortas)
Time-to-deployDías/semanasHoras
Overhead de gestiónAltoMínimo
Ideal paraEquipos 10+Equipos 1-3
main (siempre deployable a staging automático)
├── feat/dofa-analysis ← Dev A (max 2 días)
│ └── PR → review por Dev B o C → merge → auto-deploy staging
├── fix/tax-calculation ← Dev B (max 1 día)
│ └── PR → review por Dev A o C → merge → auto-deploy staging
└── feat/mcp-invoicing ← Dev C (max 2 días)
└── PR → review por Dev A o B → merge → auto-deploy staging
Deploy a producción: manual approval después de smoke tests en staging
branch_rules:
main:
protection: true
requires_pr: true
min_reviewers: 1 # 1 de los 2 compañeros
require_ci_pass: true # Los 9 quality gates deben pasar
auto_deploy: "staging" # Merge → staging automático
feature_branches:
naming: "feat/{ticket-or-description}" # feat/dofa-analysis
max_lifetime: "2 days" # Si pasa de 2 días, es muy grande → dividir
from: "main" # Siempre desde main (actualizado)
merge_to: "main" # Directo a main
squash_merge: true # 1 commit limpio por feature
delete_on_merge: true # Limpiar branch automáticamente
fix_branches:
naming: "fix/{ticket-or-description}" # fix/tax-rounding
max_lifetime: "1 day"
same_rules_as: "feature_branches"
hotfix:
naming: "hotfix/{description}" # hotfix/critical-auth-bypass
from: "main"
merge_to: "main"
deploy: "production (inmediato)"
requires_review: true # Sí, incluso para hotfix
prohibited:
- "develop" # No existe en trunk-based
- "release/*" # No existe — main es siempre releasable
- "branches > 2 días sin merge"
MAÑANA (15 min standup async o sync):
1. Pull main → actualizar tu feature branch
2. Revisar PRs pendientes de compañeros (prioridad: no bloquear a nadie)
3. Continuar tu feature branch
DURANTE EL DÍA:
- Commits frecuentes en tu feature branch
- Si tu branch tiene > 1 día: hacer PR parcial (feature flag si necesario)
- Si necesitas trabajo de un compañero: comunícalo, no esperes al PR
ANTES DE TERMINAR:
- Push tu branch
- Si está listo: crear PR
- Si NO está listo: rebasa sobre main para evitar divergencia
// Ejemplo de feature flags (adaptar al stack elegido)
// Opciones: env vars, config service, KV store, database
const FEATURE_FLAGS = {
DOFA_ANALYSIS_V2: env.FF_DOFA_V2 === 'true', // Desactivado en prod
MCP_INVOICING: env.FF_MCP_INVOICING === 'true', // Solo staging
};
// En el código:
if (FEATURE_FLAGS.DOFA_ANALYSIS_V2) {
return await newDofaAnalysis(request);
} else {
return await currentDofaAnalysis(request);
}

Developer push → PR creado
[CI] 9 Quality Gates (ver Doc 07)
[REVIEW] Code review humano
Merge a main
[CD] Deploy a Staging
[TEST] Smoke tests + E2E + AI eval
[APPROVE] Manual approval para producción
[CD] Deploy a Producción (Blue-Green / Canary)
[MONITOR] Observabilidad + alertas activas

2. Pipeline Completo (ejemplo GitHub Actions + Python)

Sección titulada «2. Pipeline Completo (ejemplo GitHub Actions + Python)»

Nota: Este ejemplo usa GitHub Actions con Python/pytest. Adaptar al stack elegido.\n> Los stages (quality gates, security scan, build, deploy) son universales.

.github/workflows/main.yml
name: la organización AI-First CI/CD
on:
push:
branches: [main] # Solo main — trunk-based
pull_request:
branches: [main] # Quality gates en todo PR
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# ──────────────────────────────
# QUALITY GATES
# ──────────────────────────────
quality-gates:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: pip install -r requirements-dev.txt
# Gate 1 & 2: Type + Lint
- name: Type Check (mypy)
run: mypy src/ --strict --ignore-missing-imports
- name: Lint (ruff)
run: ruff check src/ --output-format=github
# Gate 3: Format
- name: Format Check
run: |
black --check src/
isort --check-only src/
# Gate 4: Tests
- name: Unit Tests
run: |
pytest tests/unit/ \
--cov=src \
--cov-report=xml \
--cov-fail-under=80 \
--junitxml=test-results.xml
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
# Gate 5: Dependencies
- name: Dependency Audit
run: pip-audit --strict --output=json > audit-report.json
# Gate 6: Secrets
- name: Secrets Scan (TruffleHog)
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
extra_args: --only-verified
# Gate 7: SAST
- name: SAST (Semgrep)
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/python
p/secrets
p/supply-chain
# Gate 8: Prompt Security
- name: Prompt Injection Tests
run: pytest tests/security/ -v --tb=short
# Gate 9: UX Accessibility
- name: Build Frontend
run: cd frontend && npm ci && npm run build
- name: Accessibility Check (axe)
run: npx @axe-core/cli frontend/dist --tags wcag2a,wcag2aa --exit
# ──────────────────────────────
# SECURITY SCANNING
# ──────────────────────────────
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Container scanning
- name: Build Docker image
run: docker build -t test-image:${{ github.sha }} .
- name: Container Scan (Trivy)
uses: aquasecurity/trivy-action@master
with:
image-ref: test-image:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
exit-code: '1'
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
# ──────────────────────────────
# BUILD & PUSH
# ──────────────────────────────
build:
needs: [quality-gates, security-scan]
runs-on: ubuntu-latest
if: github.event_name == 'push'
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
image-digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=,suffix=,format=short
type=ref,event=branch
- name: Build and push (multi-arch)
id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true # SLSA provenance
sbom: true # Software Bill of Materials
# ──────────────────────────────
# DEPLOY STAGING
# ──────────────────────────────
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: |
kubectl set image deployment/app-backend \
backend=${{ needs.build.outputs.image-tag }} \
-n ${K8S_NAMESPACE}-staging
kubectl rollout status deployment/app-backend -n ${K8S_NAMESPACE}-staging
- name: Smoke Tests
run: |
sleep 30 # Wait for pods to be ready
pytest tests/smoke/ --base-url=${STAGING_URL} -v
- name: AI Quality Evaluation
run: |
python scripts/run_ai_eval.py \
--env=staging \
--eval-suite=full \
--min-faithfulness=0.8 \
--min-recall=0.85
# ──────────────────────────────
# DEPLOY PRODUCCIÓN
# ──────────────────────────────
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: ${APP_URL}
steps:
- uses: actions/checkout@v4
- name: Blue-Green Deploy
run: |
# Crear nuevo deployment (green)
kubectl apply -f k8s/deployments/backend-green.yaml
kubectl set image deployment/app-backend-green \
backend=${{ needs.build.outputs.image-tag }} \
-n ${K8S_NAMESPACE}
# Esperar que esté listo
kubectl rollout status deployment/app-backend-green -n ${K8S_NAMESPACE} --timeout=300s
# Verificar health
./scripts/health-check.sh https://green.${APP_DOMAIN}
# Switch tráfico a green
kubectl patch service app-backend -n ${K8S_NAMESPACE} \
-p '{"spec":{"selector":{"version":"green"}}}'
echo "✅ Deploy exitoso: ${{ needs.build.outputs.image-tag }}"

#VulnerabilidadControl Implementado
LLM01Prompt InjectionInputGuard + PromptGuard + tests automatizados
LLM02Insecure Output HandlingOutputValidator + JSON schema validation
LLM03Training Data PoisoningReview manual de datasets, checksums
LLM04Model Denial of ServiceCostGuard + rate limiting + timeouts
LLM05Supply Chain Vulnerabilitiespip-audit + Trivy + SBOM
LLM06Sensitive Info DisclosurePIIGuard + anonimización + RLS
LLM07Insecure Plugin DesignTool schemas validados + Tool Execution Guard
LLM08Excessive AgencyLeast privilege + HITL para acciones críticas
LLM09OverrelianceFuentes citadas obligatorias + hallucination monitoring
LLM10Model TheftAPI keys rotadas + rate limits por tenant

.github/dependabot.yml
version: 2
updates:
# Python dependencies
- package-ecosystem: "pip"
directory: "/backend"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
groups:
security-updates:
applies-to: security-updates
update-types: ["minor", "patch"]
# Node dependencies
- package-ecosystem: "npm"
directory: "/frontend"
schedule:
interval: "weekly"
# Docker base images
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

Nota: Este ejemplo usa Python. Los principios (multi-stage, non-root, no secrets, health check, minimal image) aplican a cualquier runtime.

# Dockerfile — Hardened para producción
# Usar imagen con versión exacta (no latest)
FROM python:3.12.4-slim-bookworm AS builder
WORKDIR /app
# Instalar dependencias en capa separada (cache)
COPY pyproject.toml ./
RUN pip install --no-cache-dir build && \
pip install --no-cache-dir ".[production]"
# Stage de producción
FROM python:3.12.4-slim-bookworm AS production
# Actualizar paquetes del SO (security patches)
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Usuario no-root
RUN groupadd -r appuser && useradd -r -g appuser -u 1000 appuser
WORKDIR /app
# Copiar solo lo necesario
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --chown=appuser:appuser src/ ./src/
USER appuser
# Health check
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# Puerto sin privilegios
EXPOSE 8000
# No shell por seguridad
ENTRYPOINT ["python", "-m", "uvicorn", "src.main:app"]
CMD ["--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

# scripts/release.py — Automatización de releases semánticos
import subprocess
import re
from datetime import datetime
def bump_version(bump_type: str) -> str:
"""bump_type: major | minor | patch"""
current = get_current_version()
major, minor, patch = map(int, current.split('.'))
if bump_type == "major":
return f"{major+1}.0.0"
elif bump_type == "minor":
return f"{major}.{minor+1}.0"
else:
return f"{major}.{minor}.{patch+1}"
def create_release(version: str, notes: str):
# 1. Actualizar version en pyproject.toml
update_version_file(version)
# 2. Commit y tag
subprocess.run(["git", "add", "pyproject.toml"])
subprocess.run(["git", "commit", "-m", f"chore: release v{version}"])
subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"Release {version}"])
subprocess.run(["git", "push", "--follow-tags"])
# 3. Crear GitHub Release con notas automáticas
subprocess.run([
"gh", "release", "create", f"v{version}",
"--title", f"v{version}",
"--notes", notes,
"--target", "main"
])

.claude/settings.json
# Configuración de Claude Code para CI
{
"model": "claude-sonnet-4-5",
"permissions": {
"allow": [
"Read(*)",
"Write(src/**, tests/**)",
"Bash(pytest:*, ruff:*, mypy:*, git:status, git:diff)"
],
"deny": [
"Bash(rm -rf:*, git:push, git:commit)",
"Write(.github/**, .env*)"
]
},
"hooks": {
"pre_tool_use": ["validate_tool_call"],
"post_tool_use": ["log_tool_execution"]
}
}

AI-First Engineering Framework — Baseline v6.5