---
name: parse_issue_md
kind: function
lang: go
domain: infra
version: "0.1.0"
purity: impure
signature: "func ParseIssueMd(path string) (Issue, []byte, error)"
description: "Lee un archivo Markdown de issue (dev/issues/*.md), extrae el frontmatter YAML en un struct Issue y devuelve el body tal como esta en disco. Rellena FilePath, MtimeNs y Completed (deduce de si el path contiene /completed/)."
tags: [issue, parser, frontmatter, yaml, kanban, dev-ux, kanban]
uses_functions: []
uses_types: [issue_go_infra]
returns: [issue_go_infra]
returns_optional: false
error_type: "error_go_core"
imports: ["bytes", "fmt", "os", "strings", "gopkg.in/yaml.v3"]
params:
  - name: path
    desc: "Ruta absoluta o relativa al archivo .md del issue (ej: dev/issues/0130-kanban-cpp-v2.md)"
output: "Struct Issue con todos los campos del frontmatter, byte slice con el body MD, y error si el archivo no existe o el YAML es invalido"
tested: true
tests:
  - "parsea 0130-kanban-cpp-v2 correctamente"
  - "completed flag se deduce del path"
  - "error en archivo inexistente"
  - "fixture preserva campos"
test_file_path: "functions/infra/parse_issue_md_test.go"
file_path: "functions/infra/parse_issue_md.go"
---

## Ejemplo

```go
iss, body, err := infra.ParseIssueMd("dev/issues/0130-kanban-cpp-v2.md")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("ID=%s Status=%s Domain=%v\n", iss.ID, iss.Status, iss.Domain)
// body contiene el Markdown despues del segundo ---
```

## Cuando usarla

Cuando necesites leer el frontmatter de un issue del registry para mostrarlo, modificarlo o indexarlo. Usar como base de `scan_issues_dir_go_infra` (que la llama por cada archivo) o cuando necesites acceso al body MD ademas del struct.

## Gotchas

- El body devuelto incluye el `\n` inmediatamente posterior al segundo `---`. No se normaliza.
- Si el archivo tiene un solo `---` (sin segundo delimitador), retorna error. Issues sin frontmatter no son validos.
- `Completed` se infiere del path, no del campo `status` del YAML — un issue con `status: completado` que vive en `dev/issues/` (no en `completed/`) tendra `Completed=false`.
- Los campos `Depends`, `Blocks`, `Related`, `Tags`, `Domain` son `[]string` — si el YAML los omite quedan como `nil`, no slice vacio.
