Wiedii — Política de Configuración Cross-Platform
Todo repositorio debe tener .gitignore, .gitattributes y .editorconfig configurados para compatibilidad entre plataformas (Windows, Linux, macOS).
.gitignore
Combinar los templates oficiales de github/gitignore sin modificar su contenido interno. Cada sección se identifica con su fuente.
Estructura de secciones (en este orden)
1. Template del stack
| Stack | Template |
|---|---|
| Bun / Node.js | bun.gitignore |
| Python | Python.gitignore |
| Go | Go.gitignore |
| Java | Java.gitignore |
Nota: Para proyectos Bun usar
bun.gitignore, noNode.gitignore. Son diferentes.
2. Globales de herramientas del stack
Incluir los globales que correspondan a las herramientas que usa el proyecto:
| Herramienta | Template |
|---|---|
| Lefthook | Global/Lefthook.gitignore |
| mise | Global/mise.gitignore |
3. Globales de SO
Siempre incluir los tres:
4. Globales de editores
| Editor | Template | Notas |
|---|---|---|
| VS Code | Global/VisualStudioCode.gitignore | Usa whitelist — permite compartir settings.json, tasks.json, launch.json, extensions.json, *.code-snippets |
| JetBrains | Global/JetBrains.gitignore | Template completo con 30+ patrones por plugin/IDE |
No usar
.vscode/ni.idea/como entradas manuales — los templates oficiales son más completos y correctos.
5. Globales de seguridad y archivos
| Template | Qué cubre |
|---|---|
Global/GPG.gitignore | secring.* — claves GPG privadas |
Global/Backup.gitignore | *.bak, *.tmp, *.orig, etc. |
Global/Diff.gitignore | *.patch, *.diff |
6. Project-specific
Al final del archivo, solo entradas que no cubre ningún template oficial. Dos grupos:
a) Artefactos regenerables de herramientas AI autorizadas — nunca se commitean (se regeneran solos):
### Project-specific — AI tool artifacts (regenerables, never commit) ###
.claude/
graphify-out/
.playwright-mcp/
.context7/
b) Dirs de herramientas AI fuera del whitelist (dev-conventions #19 — solo se autorizan Claude Code y Cowork; actualizado 2026-07-15: Codex, Antigravity CLI y Kiro quedaron fuera). Gitignorearlos no autoriza su uso (sigue requiriendo aprobación del TL documentada en CONTRIBUTING.md); solo evita versionarlos por error si alguien los prueba en local:
### Project-specific — unauthorized AI tool dirs (block accidental commits; use still needs TL approval) ###
.cursor/
.cursorrules
.windsurf/
.amazonq/
.continue/
.codegpt/
.tabnine/
.codeium/
.junie/
.aiassistant/
.trae/
.copilot/
.github/copilot-instructions.md
WARP.md
.kiro/
GEMINI.md
Formato del archivo
Cada sección debe identificar su fuente:
### Bun — github/gitignore/bun.gitignore ###
<contenido del template sin modificar>
### Lefthook — github/gitignore/Global/Lefthook.gitignore ###
<contenido del template sin modificar>
### mise — github/gitignore/Global/mise.gitignore ###
<contenido del template sin modificar>
### macOS — github/gitignore/Global/macOS.gitignore ###
...
### Project-specific ###
...
Al actualizar .gitignore — refrescar el índice de git
Editar .gitignore no deja de trackear los archivos que ya estaban versionados: git los sigue siguiendo aunque ahora coincidan con un patrón ignorado. Tras cambiar .gitignore hay que refrescar el índice para que git deje de seguir lo que ahora corresponde ignorar.
Procedimiento estándar — refresco completo del índice:
git rm -r --cached . # vacía el índice — NO borra archivos del disco
git add . # re-añade solo lo que el nuevo .gitignore NO ignora
git status # revisar: los "deleted" son los que dejaron de trackearse
wietoo commit # commitear junto con el cambio de .gitignore
Para un único archivo puntual basta
git rm --cached ruta/al/archivo(sin vaciar todo el índice), pero el procedimiento estándar de Wiedii es el refresco completo de arriba.
Notas:
--cachedsolo afecta al índice: los archivos siguen en tu disco, solo dejan de versionarse.- Hacerlo sobre un working tree limpio (sin otros cambios a medias) para que el diff sea claro y no se mezclen cambios ajenos.
- Commitear el cambio de
.gitignorey el untrack en el mismo commit. Ejemplo:chore(gitignore): 🔨 stop tracking newly ignored files+ footerclosed #<id>(ver commits).
⚠️ Caso distinto — herramienta de IA NO autorizada ya presente en el repo.
--cachedsolo des-trackea: el archivo/carpeta sigue en disco, así que una tool fuera del whitelist (politicas-core #2 —.cursor/,.windsurf/, …) sigue usable en local y, al quedar gitignorada, se vuelve invisible parafd/rg(respetan.gitignore) → falsa sensación de limpieza. Para erradicarla de verdad no basta des-trackear:
- Preguntar primero a quien mantiene el repo: ¿borrar del disco o solo des-trackear? (no borrar archivos de alguien sin confirmar).
- Si se borra → eliminar del disco (
rm -rf <dir>/ borrar el archivo) y mantener la entrada en.gitignorecomo barrera anti-recommit.- Si no se borra → solo des-trackear (queda en disco); documentar la excepción del TL en
CONTRIBUTING.md.Esto no aplica a los artefactos regenerables de tools autorizadas (
.claude/,graphify-out/,.playwright-mcp/,.context7/): esos se des-trackean y se conservan en disco (se regeneran solos). Tampoco a los archivos de instrucciones de las tools autorizadas (AGENTS.md,CLAUDE.md), que se versionan y se conservan.
.gitattributes
Usar los templates oficiales de gitattributes/gitattributes.
Template base
Common.gitattributes — base para todos los proyectos. Cubre documentos, gráficos, scripts, serialización (JSON, TOML, YAML, XML), archivos comprimidos y exclusiones de export.
La regla global debe forzar siempre LF:
* text=auto eol=lf
Template de editor
Global/VisualStudioCode.gitattributes — linguist hints para archivos JSON-with-Comments de VS Code:
.vscode/*.json linguist-language=JSON-with-Comments
Reglas explícitas adicionales (project-specific)
Common.gitattributes no cubre algunos archivos comunes. Agregarlos explícitamente:
# Project-specific
# Explicit rules for files not covered by Common.gitattributes
.editorconfig text eol=lf
.gitattributes text eol=lf
.gitignore text eol=lf
# Lockfiles — a prueba de merge (sin corrupción) + colapsados pero expandibles en diffs
bun.lock text eol=lf -merge gitlab-generated linguist-generated linguist-language=JSON
bun.lockb binary
mise.lock text eol=lf -merge gitlab-generated linguist-generated linguist-language=TOML
# Terraform / OpenTofu provider lock — solo si el repo es IaC (Terraform/OpenTofu/Terragrunt)
.terraform.lock.hcl text eol=lf -merge gitlab-generated linguist-generated linguist-language=HCL
bun.lock— formato texto JSON desde Bun 1.1+. No es binario comobun.lockb(formato legacy).mise.lock— formato TOML autogenerado pormise lock..terraform.lock.hcl— provider lock de Terraform/OpenTofu (hashes de providers), autogenerado porterraform init. La regla genérica*.lockno lo captura (termina en.hcl), por eso necesita su propia línea; en conflicto se regenera (terraform init -upgrade), no se mergea a mano. Solo aplica a repos IaC.
⚠️
mergeydiffson atributos INDEPENDIENTES (git docs). Confundirlos es un error común — el macrobinaryagrupa ambos (-diff -merge -text), de ahí la confusión.
Evitar conflictos de merge → -merge (NO -diff)
Los lockfiles son autogenerados; no se editan a mano y no deberían producir conflictos de
contenido (a diferencia de package.json, que sí). El atributo que logra esto es -merge:
cuando dos ramas modifican el lockfile, git mantiene la versión "ours" y marca conflicto
sin inyectar marcadores <<<<<< ====== >>>>>> (que corromperían el JSON/TOML). Se
resuelve regenerando: bun install / mise install, luego git add.
❌
-diffno hace esto.-diffsolo controla la visualización (marca el archivo como binario para diffs): git emite "Binary files differ", GitLab muestra el mensaje engañoso de "Archivo eliminado por una entrada de .gitattributes", y el lockfile nunca se puede inspeccionar (impide auditar dependencias — riesgo de supply-chain). Y encima no protege contra conflictos de merge. Usar-mergepara eso, nunca-diff.
Colapsar el diff pero dejarlo expandible → gitlab-generated + linguist-generated
gitlab-generated lo honra GitLab (GA desde 16.11): colapsa el diff por defecto pero lo
deja expandible cuando el reviewer necesita auditarlo. Se acompaña de linguist-generated
para paridad si el repo se espeja a GitHub (GitLab no honra linguist-generated para
colapsar; solo GitHub lo hace). linguist-language mantiene el resaltado al expandir.
Validación
El repo gitattributes/gitattributes incluye check.sh para verificar que todos los archivos del repo tengan una regla explícita (no solo el catch-all *):
curl -s https://raw.githubusercontent.com/gitattributes/gitattributes/master/check.sh | sh
Correr después de modificar .gitattributes. Si algún archivo reporta text: auto, agregar una regla explícita para él.
Al agregar .gitattributes a un repo existente
git add --renormalize .
git commit -m "chore: normalize line endings with .gitattributes"
.editorconfig (requerido en todos los repos)
Base universal mínima — obligatoria en todo repo, independientemente del stack:
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
Secciones condicionales por lenguaje
Se agregan solo cuando el repo realmente contiene ese lenguaje. No forman parte de la base obligatoria, y su ausencia en un repo que no usa ese lenguaje no es un hallazgo — no debe marcarse como WARN en /wiedii-dev:audit-project.
# Solo si el repo tiene Python (.py)
[*.py]
indent_size = 4
Python usa indent de 4 (PEP 8) frente a los 2 espacios de la base. Si el repo no tiene
.py, no incluir esta sección: forzarla es ruido y genera WARNs espurios en la auditoría.
Referencias
- github/gitignore — templates oficiales de gitignore
- gitattributes/gitattributes — templates oficiales de gitattributes
- repo-setup — checklist de nuevo repositorio
- wiedii-configs — repo de configuraciones compartidas donde se implementó esta política