b9716a7cd6
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.3 KiB
5.3 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0109m | issues_api service: HTTP backend para issues+flows (skill_tree, kanban, dashboards) | pendiente | feature |
|
app-scoped | media |
|
|
2026-05-18 | 2026-05-18 |
|
0109m — issues_api service
Por que
skill_tree.exe corre en Windows nativo. Necesita leer dev/issues/*.md + dev/flows/*.md que viven en WSL ~/fn_registry/. Opciones:
| Solucion | Pro | Contra |
|---|---|---|
UNC \\wsl.localhost\Ubuntu\home\lucas\fn_registry |
Cero infra extra | Hardcodea distro/user. No funciona si WSL caido. |
| Service HTTP (este issue) | Robusto, reusable por otras apps (kanban, web dashboard) | Mas piezas que mantener |
| Embeber YAML parser + nested fields | Self-contained | Mucha logica duplicada |
Fix UNC ya esta hecho (0109l). Pero el patron canonico del registry son services (services_api, sqlite_api, registry_api). Este issue formaliza issues_api.
Spec
Service Go HTTP en puerto 8486. Patron identico a services_api (issue 0106).
Endpoints
GET /api/health→{"status":"ok"}GET /api/issues→ array JSON con TODOS los issues (open + completed)GET /api/issues/:id→ un issue concreto con body markdown completoGET /api/flows→ array JSON con todos los flowsGET /api/flows/:id→ un flow concretoGET /api/stats→ counts por status/domain/type (agregados para Dashboard)POST /api/issues→ crea nuevo issue (escribe.md). Body:{id, title, type, domain, depends, body, dod}. Devuelve{path}.POST /api/flows→ crea nuevo flow. Mismo shape adaptado a frontmatter de flows.
Schema JSON issue
{
"id": "0109",
"title": "...",
"status": "pendiente",
"status_eff": "pendiente_unlocked",
"type": "epic",
"domain": ["meta", "cpp-stack"],
"priority": "media",
"depends": [],
"blocks": [],
"related": ["0085"],
"tags": ["skill-tree"],
"created": "2026-05-17",
"updated": "2026-05-18",
"file_path": "dev/issues/0109-skill-tree-app-roadmap.md",
"body_md": "(opcional, solo en /api/issues/:id)",
"dod": [{"text":"App existe","done":true}, ...]
}
Implementacion
// apps/issues_api/main.go
package main
import (
"encoding/json"
"net/http"
"log"
"os"
// reusa funciones del registry:
// - extract_frontmatter (Go port; existe extract_frontmatter_py_core, pero
// en C++ existe parse_md_frontmatter_cpp_core — necesitamos Go port o
// reusar yaml.v3 directo aqui).
)
func main() {
root := os.Getenv("FN_REGISTRY_ROOT")
if root == "" { log.Fatal("FN_REGISTRY_ROOT not set") }
mux := http.NewServeMux()
mux.HandleFunc("/api/health", health)
mux.HandleFunc("/api/issues", listIssues(root))
mux.HandleFunc("/api/issues/", showIssue(root))
mux.HandleFunc("/api/flows", listFlows(root))
mux.HandleFunc("/api/flows/", showFlow(root))
mux.HandleFunc("/api/stats", stats(root))
log.Fatal(http.ListenAndServe(":8486", mux))
}
Frontmatter: existe extract_frontmatter_py_core (Python). Hace falta:
- Opcion A: crear
parse_md_frontmatter_go_core(port del C++). Reusable por otros services Go. - Opcion B: usar
gopkg.in/yaml.v3directo dentro deissues_api.
Recomiendo A — Go port reusable. Pattern: header parse_md_frontmatter.go en functions/core/.
Frontmatter service: block en app.md
service:
port: 8486
health_endpoint: /api/health
health_timeout_s: 3
systemd_unit: issues_api.service
systemd_scope: user
restart_policy: always
runtime: systemd-user
pc_targets:
- aurgi-pc
- home-wsl
is_local_only: false
Skill_tree consume
Cambio en skill_tree/main.cpp:
- Si
discover_registry_root()falla, intentar HTTPhttp://localhost:8486/api/issues. - Si responde 200 → parsear JSON y poblar
g_scan.nodes. - Fallback a UNC + file scan si no.
Cliente HTTP en C++:
- Linux:
libcurl(ya disponible) opopen("curl ..."). - Windows: WinHTTP nativo o curl.exe (Windows 10+ trae curl).
- Mas simple: spawn
curl.exe -s http://...y parsear stdout (nlohmann json — habria que vendor).
Sub-issues
- 0109m1 — crear
parse_md_frontmatter_go_coreport del C++ (mismas semanticas, mismos tests). - 0109m2 — scaffolder
issues_apiapp + service block + systemd unit. - 0109m3 — implementar endpoints GET (list, show, stats).
- 0109m4 — implementar POST issues + POST flows (escribir .md valido).
- 0109m5 — cliente HTTP en skill_tree + fallback chain (env > walk > UNC > HTTP).
Beneficios cross-app
Una vez issues_api existe, reutilizan:
kanban(issue 0058 sync) podria leer/sync issues.- Frontend web dashboard ya tendria backend.
- CI/automation puede crear issues via POST en lugar de editar .md a mano.
services_monitormostraraissues_apicomo service mas (auto viatag: service).
DoD
apps/issues_api/scaffoldada via/cpp-app?? no — Go service via/app.- Endpoints listed devuelven JSON valido.
- systemd unit instalado (
issues_api.service). - Visible en
services_monitorcomo service activo. - skill_tree consume HTTP cuando esta disponible, cae a UNC/file si no.
- Tests Go basicos (list, show, post).