chore: sync from fn-registry agent
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: fn_match
|
||||
lang: go
|
||||
domain: infra
|
||||
description: "Fuzzy matcher entre un comando shell o snippet heredoc y funciones del registry. Devuelve las top-N funciones mas probables que cubren ese patron, con score normalizado. Consumido por el hook PreToolUse para sugerir funciones del registry en vez de codigo inline."
|
||||
tags: [discovery, hooks, match, fuzzy, registry]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
framework: ""
|
||||
entry_point: "cmd/fn/match.go"
|
||||
dir_path: "apps/fn_match"
|
||||
repo_url: ""
|
||||
params:
|
||||
- name: command
|
||||
desc: "Comando shell o snippet heredoc a analizar. Puede pasarse como argumento posicional o por stdin."
|
||||
- name: top
|
||||
desc: "Numero maximo de resultados a devolver (default 3)."
|
||||
- name: format
|
||||
desc: "Formato de salida: json (default) o text."
|
||||
- name: min-score
|
||||
desc: "Umbral minimo de score normalizado 0..1 (default 0.3). Resultados por debajo se descartan."
|
||||
output: "JSON o texto con las top-N funciones del registry ordenadas por score descendente. Score 1.0 = mejor match; resto son relativos al top."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
# Arg posicional — JSON por defecto
|
||||
./fn match "taskkill.exe /IM registry_dashboard.exe /F"
|
||||
|
||||
# Texto legible
|
||||
./fn match --format text --top 5 "rsync -avz src/ user@host:/opt/app"
|
||||
|
||||
# Stdin pipe (util en hooks)
|
||||
echo "curl -sf https://api.example.com/health | jq .status" | ./fn match
|
||||
|
||||
# Subir umbral para matches muy seguros solamente
|
||||
./fn match --min-score 0.7 "encrypt file sha256"
|
||||
```
|
||||
|
||||
Salida JSON:
|
||||
```json
|
||||
{
|
||||
"query": "taskkill.exe /IM registry_dashboard.exe /F",
|
||||
"top": [
|
||||
{
|
||||
"id": "deploy_cpp_exe_to_windows_bash_infra",
|
||||
"score": 1,
|
||||
"signature": "deploy_cpp_exe_to_windows(app_name: string, app_dir: string) -> void",
|
||||
"snippet": "Copia el .exe de Windows... Mata el proceso si esta corriendo (taskkill.exe pre-autorizado)..."
|
||||
}
|
||||
],
|
||||
"high_confidence": false
|
||||
}
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
**Hook PreToolUse (uso principal):** El hook intercepta comandos Bash antes de ejecutarse. Si el comando supera el umbral de score, el hook inyecta en el contexto:
|
||||
```
|
||||
USE: deploy_cpp_exe_to_windows_bash_infra [score=1.000] instead of inline
|
||||
```
|
||||
|
||||
**Debug manual:** Para entender por que Claude escribe cierto patron inline repetidamente, correr `fn match` con ese patron y ver si el registry ya cubre el caso.
|
||||
|
||||
**Auditoria de gaps:** Si `fn match` devuelve `top: []` para un patron que aparece >3 veces en sesiones, ese patron es candidato a nueva funcion del registry.
|
||||
|
||||
## Pipeline interno
|
||||
|
||||
1. **Tokenize**: split por no-alfanumericos + eliminacion de flags (`-v`, `/F`), paths absolutos (conserva basename sin extension), numeros puros, tokens < 3 chars, y stopwords del dominio (`registry`, `function`, `app`, `file`, `get`, `set`, ...).
|
||||
2. **FTS5 query**: `tok1 OR tok2 OR ...` sobre `functions_fts` con `bm25()`. Resultado: hasta 50 candidatos con rank BM25.
|
||||
3. **Fetch metadata**: segundo query `SELECT ... FROM functions WHERE id IN (...)` para obtener name, signature, description, tags.
|
||||
4. **Re-score aditivo**: cada token suma su mejor boost de campo (`name=+3.0`, `tags=+2.0`, `signature=+1.5`, `description=+1.0`). No multiplicativo — evita que tokens genericos saturen todos los resultados a 1.0.
|
||||
5. **Language penalty**: si query tiene markers Python (`def`, `import`, `class`) y el hit es bash → x0.5. Si tiene markers bash (`curl`, `rsync`, `taskkill`, `exe`) y hit es py → x0.5.
|
||||
6. **Normalizar**: el top score raw se convierte en 1.0; el resto es relativo.
|
||||
7. **Filtrar y limitar**: `--min-score` descarta ruido; `--top N` limita salida.
|
||||
8. **High confidence flag**: `top[0].score / top[1].score > 1.5` → `"high_confidence": true`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
**Latencia:** 6-7ms en WSL2 con 1255 funciones indexadas. Sin daemon — proceso fresh por invocacion. Bien por debajo del objetivo de 50ms.
|
||||
|
||||
**FTS5 WAL:** La conexion se abre en modo lectura normal (no `mode=ro`) porque bm25() con WAL no checkpointed falla con "missing row from content table". El binario nunca escribe.
|
||||
|
||||
**FTS5 rebuild:** Si `fn match` devuelve `top: []` para queries que deberias matchear, el indice FTS5 puede estar desincronizado. Solucion:
|
||||
```go
|
||||
// Rebuild manual del indice:
|
||||
INSERT INTO functions_fts(functions_fts, rank) VALUES('rebuild', NULL);
|
||||
INSERT INTO types_fts(types_fts, rank) VALUES('rebuild', NULL);
|
||||
INSERT INTO unit_tests_fts(unit_tests_fts, rank) VALUES('rebuild', NULL);
|
||||
```
|
||||
O simplemente `./fn index` — reindexar regenera el FTS5.
|
||||
|
||||
**Stopwords del dominio:** Tokens como `registry`, `function`, `app`, `file`, `get`, `set` se descartan del tokenizer porque matchean cientos de funciones igualmente y no aportan señal. Si un query solo tiene stopwords, `fn match` retorna error "no significant tokens".
|
||||
|
||||
**Scores normalizados:** El score 1.0 no significa "match perfecto" — es el mejor candidato relativo al batch. Un `high_confidence: false` con score 1.0 significa que el segundo candidato es similar. Para gates en hooks usar `high_confidence: true` como criterio.
|
||||
|
||||
**Implementacion:** `cmd/fn/match.go` en el modulo raiz `fn-registry`. Se compila junto al binario `fn` principal — no es un binario separado. Invocar como `./fn match ...`.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v1.0.0 (2026-05-14): scoring multiplicativo inicial — todos los hits clampean a 1.0 cuando varios tokens matchean
|
||||
- v1.1.0 (2026-05-14): scoring aditivo por token con normalizacion relativa + stopwords del dominio. FTS5 rebuild fix. Latencia: 6-7ms
|
||||
Reference in New Issue
Block a user