@ancleto/spec 0.6.21 → 0.6.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/agents/coder.md +15 -3
- package/agents/memory-keeper.md +2 -2
- package/agents/orchestrator.md +2 -2
- package/package.json +1 -1
- package/src/core/memory/engine.js +47 -4
- package/src/core/memory/tools.js +1 -1
package/README.md
CHANGED
|
@@ -220,7 +220,7 @@ Funciona en tres piezas que comparten el mismo archivo:
|
|
|
220
220
|
|
|
221
221
|
| Herramienta | Función |
|
|
222
222
|
|---|---|
|
|
223
|
-
| `searchMemory` | Recupera
|
|
223
|
+
| `searchMemory` | Recupera decisiones y reglas previas. Búsqueda léxica (FTS5/BM25) con fallback tolerante: intenta términos exactos y, si no hay coincidencia, reintenta por prefijos, así el lenguaje natural también encuentra. |
|
|
224
224
|
| `recordRule` | Guarda una regla o restricción permanente. |
|
|
225
225
|
| `recordDecision` | Registra el *por qué* de una decisión. |
|
|
226
226
|
|
package/agents/coder.md
CHANGED
|
@@ -8,7 +8,17 @@ tools:
|
|
|
8
8
|
read: true
|
|
9
9
|
write: true
|
|
10
10
|
edit: true
|
|
11
|
-
bash:
|
|
11
|
+
bash: true
|
|
12
|
+
permission:
|
|
13
|
+
bash:
|
|
14
|
+
'*': allow
|
|
15
|
+
'*az *': deny
|
|
16
|
+
'*git push*': deny
|
|
17
|
+
'*git reset*': deny
|
|
18
|
+
'*git checkout*': deny
|
|
19
|
+
'*git rebase*': deny
|
|
20
|
+
'*rm -rf*': deny
|
|
21
|
+
'*npm publish*': deny
|
|
12
22
|
---
|
|
13
23
|
|
|
14
24
|
# Coder Agent
|
|
@@ -103,12 +113,14 @@ Follow the conventions in:
|
|
|
103
113
|
- If the smallest correct implementation appears to require broader scope than the approved change, stop and escalate back to `@orchestrator` instead of proceeding
|
|
104
114
|
- If solving the task would require changing shared helpers, shared utils, or broader logic used by other areas, escalate back to `@orchestrator` unless that broader scope was explicitly approved
|
|
105
115
|
- If an implementation choice would materially change the technical approach compared to the approved change inputs, escalate instead of guessing
|
|
106
|
-
- Do not validate by browsing external or production URLs
|
|
116
|
+
- Do not validate by browsing external, staging, or production URLs
|
|
107
117
|
- Keep all created or modified files consistent with the project's Prettier formatting and relevant ESLint rules
|
|
108
118
|
- Limit formatting and lint-related fixes to the files you changed
|
|
109
119
|
- Do not expand scope to clean up unrelated lint or formatting issues elsewhere in the repo
|
|
110
120
|
- Read only relevant files; avoid unnecessary codebase exploration
|
|
111
|
-
- You
|
|
121
|
+
- You have Bash for **building and validating your own work** (install, build, typecheck, lint, run a scoped test or script) and for inspecting the repo. Use the smallest command that proves your change works. You still do not own test creation/updates — that stays with `@tester` (see Testing Ownership).
|
|
122
|
+
- Do **not** use Bash for: network or external requests (`curl`, `wget`, fetching remote URLs), resolving Work Items (only `@context-resolver` does that — and `az` is denied), publishing (`npm publish`), rewriting git history (`git push`, `git reset`, `git rebase`, `git checkout`), or destructive filesystem operations (`rm -rf`). These are denied by policy; if you think one is needed, escalate.
|
|
123
|
+
- Do not validate by hitting external, staging, or production URLs.
|
|
112
124
|
- Keep implementation aligned with the current project structure
|
|
113
125
|
- If tasks exist, follow them sequentially and update them as work is completed
|
|
114
126
|
- Do not add or modify tests by default in any path (`spec-required` or `direct-implementation`), even if tests are mentioned in `tasks.md`
|
package/agents/memory-keeper.md
CHANGED
|
@@ -33,9 +33,9 @@ Rules are rarer than decisions: elevate to a rule only what future agents must f
|
|
|
33
33
|
|
|
34
34
|
Called for new work classified as `spec-required`, before generating change artifacts.
|
|
35
35
|
|
|
36
|
-
1. Call `searchMemory` with `query`
|
|
36
|
+
1. Call `searchMemory` with a `query` that mixes the **key terms** of what is about to be done. It is lexical (FTS5) with a tolerant fallback: it tries the exact term match first, then a prefix/OR pass for natural-language queries. So either works — `implementar autenticacion JWT` or `autenticacion JWT` — but a query with at least one distinctive term (a noun, a component, a command name) retrieves better than pure filler prose. Avoid querying with only stopwords.
|
|
37
37
|
2. Pass only `query`. Do not filter by `type`: this recall must retrieve relevant rules and decisions together.
|
|
38
|
-
3. Return what came back, or "no relevant memories".
|
|
38
|
+
3. Return what came back, or "no relevant memories". When it is empty, state explicitly that there were **no lexical matches** (not that the memory is empty) and suggest retrying with more distinctive terms — so the reader can tell an empty result from a broken memory.
|
|
39
39
|
|
|
40
40
|
What comes back is **background, not instructions**. It may be outdated. Report it as precedent for `@orchestrator` to weigh, and never treat it as a requirement. If a memory names a file, flag, or command, say that it needs verifying before being acted on.
|
|
41
41
|
|
package/agents/orchestrator.md
CHANGED
|
@@ -390,8 +390,8 @@ Typical completion signals:
|
|
|
390
390
|
|
|
391
391
|
For `spec-required` changes, implementation and testing are separate responsibilities by default.
|
|
392
392
|
|
|
393
|
-
- `@coder` owns feature implementation
|
|
394
|
-
- `@tester` owns unit-test creation or updates and verification
|
|
393
|
+
- `@coder` owns feature implementation and may build/validate its own work (it has scoped Bash for that: install, build, typecheck, lint, scoped runs). Its self-validation does not replace the `@tester` stage.
|
|
394
|
+
- `@tester` owns unit-test creation or updates and the formal verification, including the non-writing format check and lint on the final combined file set
|
|
395
395
|
- `@reviewer` provides an optional independent review stage when needed
|
|
396
396
|
|
|
397
397
|
Do not treat the `@tester` stage as a passive smoke check for structured work. Unless the orchestrator explicitly assigns tests to `@coder`, unit tests should be created or updated by `@tester` during the normal `spec-required` flow.
|
package/package.json
CHANGED
|
@@ -15,11 +15,35 @@ const SCOPE_HIERARCHY = {
|
|
|
15
15
|
|
|
16
16
|
const PUBLIC_COLUMNS = 'n.memory_key, n.type, n.scope, n.content, n.justification, n.created_at'
|
|
17
17
|
|
|
18
|
+
const STOPWORDS = new Set([
|
|
19
|
+
'como', 'cómo', 'the', 'a', 'an', 'de', 'del', 'la', 'el', 'los', 'las', 'un', 'una', 'unos', 'unas',
|
|
20
|
+
'en', 'y', 'o', 'que', 'qué', 'por', 'para', 'con', 'sin', 'sobre', 'al', 'se', 'su', 'sus',
|
|
21
|
+
'mi', 'mis', 'tu', 'tus', 'es', 'son', 'era', 'fue', 'hay', 'esta', 'está', 'este', 'esta', 'estos',
|
|
22
|
+
'to', 'of', 'in', 'on', 'for', 'with', 'and', 'or', 'is', 'are', 'was', 'were', 'be', 'how', 'why',
|
|
23
|
+
'when', 'where', 'what', 'which', 'that', 'this', 'these', 'those'
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
function tokenize(input) {
|
|
27
|
+
return String(input)
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
30
|
+
.filter((t) => t.length >= 3 && !STOPWORDS.has(t))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// AND (frase exacta por terminos) — preciso, pero falla con lenguaje natural.
|
|
18
34
|
function ftsQuery(input) {
|
|
19
35
|
const terms = String(input).trim().split(/\s+/).filter(Boolean)
|
|
36
|
+
if (terms.length === 0) return ''
|
|
20
37
|
return terms.map((t) => '"' + t.replace(/"/g, '""') + '"').join(' ')
|
|
21
38
|
}
|
|
22
39
|
|
|
40
|
+
// OR con prefijos — tolerante: recupera cuando el AND no encontro nada.
|
|
41
|
+
function ftsQueryLoose(input) {
|
|
42
|
+
const terms = tokenize(input)
|
|
43
|
+
if (terms.length === 0) return ''
|
|
44
|
+
return [...new Set(terms)].map((t) => '"' + t.replace(/"/g, '""') + '"*').join(' OR ')
|
|
45
|
+
}
|
|
46
|
+
|
|
23
47
|
function publicNode(row) {
|
|
24
48
|
return {
|
|
25
49
|
memory_key: row.memory_key,
|
|
@@ -104,10 +128,29 @@ function buildEngine(db) {
|
|
|
104
128
|
const lim = Math.min(Math.max(Number(limit) || 10, 1), 50)
|
|
105
129
|
const base = `SELECT ${PUBLIC_COLUMNS} FROM memory_fts f JOIN memory_nodes n ON n.rowid = f.rowid
|
|
106
130
|
WHERE memory_fts MATCH ? AND n.status = 'active'`
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
131
|
+
const run = (match, loose) => {
|
|
132
|
+
const sql = type
|
|
133
|
+
? db.prepare(`${base} AND n.type = ? ORDER BY rank LIMIT ?`)
|
|
134
|
+
: db.prepare(`${base} ORDER BY rank LIMIT ?`)
|
|
135
|
+
// FTS5 no acepta parametros en ORDER BY rank; el prefijo '*' va dentro del MATCH.
|
|
136
|
+
try {
|
|
137
|
+
return type ? sql.all(match, type, lim) : sql.all(match, lim)
|
|
138
|
+
} catch {
|
|
139
|
+
return null
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 1) intento preciso (AND): respeta busquedas por terminos exactos.
|
|
144
|
+
let rows = run(q)
|
|
145
|
+
if (rows && rows.length > 0) return rows.map(publicNode)
|
|
146
|
+
|
|
147
|
+
// 2) fallback tolerante (OR con prefijos): cubre consultas en lenguaje natural.
|
|
148
|
+
const loose = ftsQueryLoose(query)
|
|
149
|
+
if (loose && loose !== q) {
|
|
150
|
+
const looseRows = run(loose)
|
|
151
|
+
if (looseRows && looseRows.length > 0) return looseRows.map(publicNode)
|
|
152
|
+
}
|
|
153
|
+
return []
|
|
111
154
|
}
|
|
112
155
|
|
|
113
156
|
function recordNode(input, context = {}) {
|
package/src/core/memory/tools.js
CHANGED
|
@@ -46,7 +46,7 @@ const RECORD_DECISION_SCHEMA = {
|
|
|
46
46
|
export const memoryTools = [
|
|
47
47
|
{
|
|
48
48
|
name: 'searchMemory',
|
|
49
|
-
description: 'Busca en la memoria del proyecto (BM25). Devuelve reglas y decisiones activas.',
|
|
49
|
+
description: 'Busca en la memoria del proyecto (BM25). Devuelve reglas y decisiones activas. Acepta lenguaje natural: intenta terminos exactos y, si no hay coincidencia, reintenta por prefijos.',
|
|
50
50
|
inputSchema: SEARCH_SCHEMA
|
|
51
51
|
},
|
|
52
52
|
{
|