{"id":48543189,"url":"https://github.com/felirangelp/harness-driven-dev","last_synced_at":"2026-04-08T06:00:26.773Z","repository":{"id":349841316,"uuid":"1204151327","full_name":"felirangelp/harness-driven-dev","owner":"felirangelp","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-08T04:09:24.000Z","size":134,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-08T06:00:18.205Z","etag":null,"topics":["ai-agents","best-practices","claude-code","devops","github-actions","harness-driven-development","linear"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felirangelp.png","metadata":{"files":{"readme":"README.es.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-07T18:32:39.000Z","updated_at":"2026-04-08T04:09:28.000Z","dependencies_parsed_at":"2026-04-08T06:00:24.829Z","dependency_job_id":null,"html_url":"https://github.com/felirangelp/harness-driven-dev","commit_stats":null,"previous_names":["felirangelp/harness-driven-dev"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/felirangelp/harness-driven-dev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felirangelp%2Fharness-driven-dev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felirangelp%2Fharness-driven-dev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felirangelp%2Fharness-driven-dev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felirangelp%2Fharness-driven-dev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felirangelp","download_url":"https://codeload.github.com/felirangelp/harness-driven-dev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felirangelp%2Fharness-driven-dev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31542381,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"online","status_checked_at":"2026-04-08T02:00:06.127Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","best-practices","claude-code","devops","github-actions","harness-driven-development","linear"],"created_at":"2026-04-08T06:00:16.314Z","updated_at":"2026-04-08T06:00:26.767Z","avatar_url":"https://github.com/felirangelp.png","language":"Python","readme":"# Harness-Driven Development\n\n[![CI](https://github.com/felirangelp/harness-driven-dev/actions/workflows/ci.yml/badge.svg)](https://github.com/felirangelp/harness-driven-dev/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Linear](https://img.shields.io/badge/Linear-Integrated-5e6ad2)](https://linear.app)\n[![Claude Code](https://img.shields.io/badge/Claude_Code-Skills-orange)](https://docs.anthropic.com/en/docs/claude-code)\n\n\u003e Las buenas prácticas de software no fallan por falta de conocimiento — fallan por falta de enforcement. Un agente IA con harness cierra ese gap.\n\n[English](README.md) · [Guía de Setup](docs/setup-guide.md) · [Guía Linear](docs/guide-linear.es.md) · [Guía GitHub](docs/guide-github.es.md) · [Arquitectura](docs/architecture.md) · [FAQ](docs/faq.md) · [Sitio Web](https://felirangelp.github.io/harness-driven-dev/)\n\n---\n\n## El Problema\n\n| Lo que SABEMOS | Lo que HACEMOS | Lo que se CUMPLE |\n|---|---|---|\n| Commit conventions | A veces | Casi nunca |\n| No secrets en código | Después del incidente | Esporádicamente |\n| Tests antes de merge | En proyectos nuevos | Hasta que hay presión |\n| Issues trazables | En PRs \"importantes\" | Cuando hay auditoría |\n| Definition of Done | En retros | Nunca mecánicamente |\n\n**El gap entre saber y hacer no es un problema de conocimiento — es un problema de enforcement.**\n\n## La Solución\n\nHarness-Driven Development (HDD) conecta tres sistemas en un flujo automatizado:\n\n```\nLinear (planeación) → GitHub (código) → Agente IA (enforcement)\n```\n\nEl agente no solo escribe código — **hace cumplir automáticamente las reglas** que tu equipo ya conoce pero no logra cumplir consistentemente.\n\n## Cómo Funciona\n\n\u003e **Nota**: `DEMO-X` se usa como ejemplo de prefijo de issue en todo este documento. Reemplaza con la clave de tu equipo en Linear (ej., `HAR-1`, `EXP-1`). El prefijo lo determina la clave del team que eliges al crear tu equipo en Linear.\n\n```\nTÚ (3 comandos):                    EL SISTEMA (15+ acciones automáticas):\n─────────────────                    ──────────────────────────────────────\n1. /start-issue DEMO-1        →     Lee Linear, crea branch,\n                                     mueve a In Progress\n\n2. \"implementa dark mode\"     →     Escribe código, corre tests,\n                                     commitea con Refs DEMO-1,\n                                     hooks validan secrets + ref,\n                                     push + PR\n\n3. /close-issue DEMO-1        →     Corre 3 gates, posta evidencia,\n                                     mueve a Done, audit trail\n```\n\n## 4 Capas de Enforcement\n\n```\nCapa 1: Pre-commit (laptop del dev)\n  └─ gitleaks + issue-ref hook\n  └─ \"No te deja commitear mal\"\n\nCapa 2: CI (GitHub Actions)\n  └─ Tests + gitleaks\n  └─ \"Si falla, auto-crea bug en Linear\"\n\nCapa 3: Harness (agente IA)\n  └─ close_issue.sh con gates\n  └─ \"No te deja cerrar sin evidencia\"\n\nCapa 4: Webhook (GitHub → Linear)\n  └─ PR → In Progress, merge → Done\n  └─ \"El estado se sincroniza solo\"\n```\n\n## Inicio Rápido\n\n### Prerrequisitos\n\n- [Node.js](https://nodejs.org/) 18+\n- [Python](https://python.org/) 3.9+\n- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI\n- [GitHub CLI](https://cli.github.com/) (`gh`)\n- Una cuenta de [Linear](https://linear.app/) con API key\n\n### Setup\n\n```bash\n# Clonar\ngit clone https://github.com/felirangelp/harness-driven-dev.git\ncd harness-driven-dev\n\n# Ambiente Python\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Dependencias Node\nnpm install\n\n# Variables de entorno\ncp .env.example .env\n# Edita .env y agrega tu LINEAR_API_KEY\n\n# Instalar pre-commit hooks\npip install pre-commit\npre-commit install --hook-type pre-commit --hook-type commit-msg\n\n# Verificar\nnpm test\n```\n\nConsulta la [Guía de Setup](docs/setup-guide.md) completa para integración con Linear y configuración de GitHub Actions.\n\n## Proyecto Demo: Task Board\n\nUn Kanban board de 1 página (To Do → In Progress → Done) construido con HTML/CSS/JS vanilla. Sin frameworks, sin backend — justo lo necesario para demostrar el harness en acción.\n\nCada feature es un issue de Linear. El harness hace cumplir el ciclo de vida completo:\n\n1. **Inicio** → `/start-issue DEMO-1` crea branch + mueve issue\n2. **Código** → El agente implementa, los hooks validan cada commit\n3. **Cierre** → `/close-issue DEMO-1` corre gates + posta evidencia\n\n## Estructura del Repositorio\n\n```\nharness-driven-dev/\n├── .claude/\n│   ├── settings.json              # Permisos + hooks\n│   └── skills/\n│       ├── start-issue/SKILL.md   # Comando /start-issue\n│       ├── close-issue/SKILL.md   # Comando /close-issue\n│       └── status/SKILL.md        # Comando /status\n├── .github/workflows/\n│   ├── ci.yml                     # Tests + escaneo de secrets\n│   └── linear-bridge.yml          # CI failure → bug en Linear\n├── scripts/\n│   ├── linear_client.py           # Cliente GraphQL para Linear\n│   ├── close_issue.sh             # Verificación de 3 gates\n│   ├── check_issue_ref.sh         # Hook de commit message\n│   └── ci_failure_bridge.py       # Bridge CI → Linear\n├── tests/test_app.js              # Tests DOM (jsdom)\n├── CLAUDE.md                      # Reglas del agente + skills\n├── index.html                     # Task Board UI\n├── styles.css                     # Tema oscuro\n└── app.js                         # Lógica del board\n```\n\n## El \"Momento Wow\": Secret Bloqueado en Vivo\n\n```\nMOMENTO 1: \"El error que todos hemos cometido\"\n  → Escribe LINEAR_API_KEY directamente en app.js\n  → git commit → BLOQUEADO por gitleaks\n  → \"Nunca llegó a GitHub\"\n\nMOMENTO 2: \"La corrección\"\n  → Crea .env (en .gitignore)\n  → Cambia a process.env.LINEAR_API_KEY\n  → git commit → PASA\n  → git push → PR creado\n\nMOMENTO 3: \"Segunda capa — CI\"\n  → Si alguien hace --no-verify\n  → GitHub Actions corre gitleaks\n  → PR bloqueado + bug auto-creado en Linear\n```\n\n## Lección Clave: API \u003e Abstracciones Mágicas\n\n```\nProblema con MCP:\n  - No asigna proyectos → issues huérfanos\n  - No preserva markdown → descripciones rotas\n  - No tiene retry → fallas silenciosas\n\nSolución: Cliente GraphQL propio (~380 líneas)\n  - Control total sobre payload\n  - Routing automático a proyectos\n  - Retry + error handling\n\nMensaje: \"Automatiza con APIs, no con abstracciones mágicas.\"\n```\n\n## Contribuir\n\nLee [CONTRIBUTING.md](CONTRIBUTING.md) para las guías de contribución.\n\n## Licencia\n\n[MIT](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelirangelp%2Fharness-driven-dev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelirangelp%2Fharness-driven-dev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelirangelp%2Fharness-driven-dev/lists"}