wendkeep 0.73.0 → 0.75.0
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/CHANGELOG.md +66 -0
- package/README.en.md +13 -9
- package/README.md +13 -9
- package/docs/en/commands/memory.md +16 -1
- package/docs/en/commands/observer.md +29 -11
- package/docs/en/commands/operating-profiles.md +1 -1
- package/docs/pt-BR/commands/memory.md +16 -1
- package/docs/pt-BR/commands/observer.md +28 -11
- package/docs/pt-BR/commands/operating-profiles.md +1 -1
- package/hooks/brain-core.mjs +2 -0
- package/hooks/brain-recall.mjs +5 -1
- package/hooks/evidence-context.mjs +41 -0
- package/hooks/evidence-recall.mjs +1 -0
- package/hooks/memory-scope.mjs +1 -0
- package/package.json +2 -2
- package/packages/cli/src/index.mjs +2 -2
- package/packages/integrations/src/host-hooks.mjs +1 -0
- package/packages/vault/src/evidence-recall.mjs +343 -0
- package/packages/vault/src/index.mjs +2 -0
- package/packages/vault/src/memory-handoff.mjs +58 -3
- package/packages/vault/src/memory-schema.mjs +12 -2
- package/packages/vault/src/memory-scope.mjs +119 -0
- package/packages/vault/src/memory-store.mjs +86 -24
- package/schema/observer/004-evidence-recall.sql +25 -0
- package/schema/observer/005-project-scoped-identities.sql +217 -0
- package/src/change.mjs +41 -1
- package/src/doctor.mjs +5 -0
- package/src/init.mjs +2 -2
- package/src/memory.mjs +95 -2
- package/src/note.mjs +8 -1
- package/src/observer-publish.mjs +9 -34
- package/src/observer-server.mjs +38 -63
- package/src/observer-sql-migrate.mjs +1 -1
- package/src/observer-sql-publish.mjs +372 -12
- package/src/observer-sql-store.mjs +248 -32
- package/src/observer-store.mjs +15 -3
- package/src/observer.mjs +104 -14
- package/src/taxonomy.mjs +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,72 @@ All notable changes to **wendkeep** are documented here. Format based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.75.0] — 2026-08-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Identidades SQL escopadas por projeto.** Sessões, agentes, rollups, chamadas e transcripts
|
|
12
|
+
mantêm chaves internas derivadas de `project_id` + identificador externo, constraints compostas
|
|
13
|
+
e foreign keys que carregam o projeto. Colisões deliberadas entre projetos ficam isoladas.
|
|
14
|
+
- **Migrações comprováveis.** Cada arquivo de schema recebe checksum; uma migração estrutural de
|
|
15
|
+
base existente cria backup consistente antes da transação e pode ser retomada com segurança.
|
|
16
|
+
- **Reconciliação explícita.** `observer reconcile` reserva a varredura integral para bootstrap,
|
|
17
|
+
reparo e comprovação de paridade por hash, localmente ou contra o serviço.
|
|
18
|
+
- **Outbox observável.** `doctor` informa lotes, eventos, bytes e idade; uma lease admite apenas um
|
|
19
|
+
publisher e batches do mesmo escopo são coalescidos.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Publicação incremental nos hooks.** `SessionStart` apenas drena, `Stop` lê uma sessão e
|
|
24
|
+
`SubagentStop` somente o transcript afetado. `note new` e `change archive` enfileiram diretamente
|
|
25
|
+
os documentos que escreveram. O file store antigo deixa de receber publicação viva e permanece
|
|
26
|
+
apenas como fonte de migração.
|
|
27
|
+
- **Schema SQL 5.** O mesmo `session_id`, `agent_id`, `call_id`, `transcript_id` ou `rollup_key`
|
|
28
|
+
pode existir em projetos diferentes sem disputar uma linha global.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **Ingest atômico por evento.** Cada evento usa `SAVEPOINT ingest_one`; qualquer falha reverte o
|
|
33
|
+
registro de ingestão e todas as projeções antes de o batch continuar. Retry permanece idempotente.
|
|
34
|
+
- **Chamadas incrementais estáveis.** Turnos concluídos usam identidade causal estável, evitando
|
|
35
|
+
duplicação quando um transcript cresce após a primeira publicação.
|
|
36
|
+
|
|
37
|
+
### Performance
|
|
38
|
+
|
|
39
|
+
- O caminho de hook não varre mais o Vault. A fixture de publicação incremental comprova
|
|
40
|
+
`p95 < 200 ms`, uma sessão lida por `Stop` e zero documentos lidos por `SessionStart`.
|
|
41
|
+
|
|
42
|
+
## [0.74.0] — 2026-08-20
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- **Registradores de memória escopados.** Eventos novos declaram escopo de projeto, work session,
|
|
47
|
+
change, branch ou worktree. HEADs de branches paralelas coexistem, enquanto decisões,
|
|
48
|
+
constraints e blockers realmente incompatíveis continuam sob curadoria humana.
|
|
49
|
+
- **Migração append-only de escopo.** `memory rescope` mostra uma prévia sem valores e
|
|
50
|
+
`memory rescope --apply` anexa eventos de reescopo sem reescrever o ledger histórico; retry é
|
|
51
|
+
idempotente e candidates ambíguos não recebem vencedor automático.
|
|
52
|
+
- **Recall baseado em evidências.** O índice `.brain/EVIDENCE_INDEX.jsonl` divide Markdown por
|
|
53
|
+
headings, parágrafos, decisões, tarefas, requisitos e evidências, preservando origem, heading,
|
|
54
|
+
autoridade, validade, sessão, work session, change e hash.
|
|
55
|
+
- **Context broker por prompt.** `UserPromptSubmit` consulta o índice local, aplica ranking lexical
|
|
56
|
+
BM25 com frase exata, peso por campo, autoridade, validade, recência limitada e diversidade, e
|
|
57
|
+
injeta somente os melhores trechos dentro de um budget explícito.
|
|
58
|
+
- **FTS5 no Observer.** O schema SQL 4 mantém chunks por projeto, faz feature probe de FTS5 e usa o
|
|
59
|
+
mesmo ranking/proveniência do Keep Core com fallback lexical quando a extensão não está disponível.
|
|
60
|
+
|
|
61
|
+
### Changed
|
|
62
|
+
|
|
63
|
+
- **Ambiguidade fica isolada.** Uma chave conflitante é omitida da projeção operacional e recebe
|
|
64
|
+
marcador de revisão; CORE e registros independentes continuam disponíveis.
|
|
65
|
+
- **`/brain-recall` retorna passagens.** Resultados agora apontam para o trecho do match e incluem
|
|
66
|
+
arquivo, heading, autoridade, data e validade, em vez de retornar somente nomes de sessões.
|
|
67
|
+
|
|
68
|
+
### Performance
|
|
69
|
+
|
|
70
|
+
- Documentos excepcionalmente grandes usam amostragem distribuída limitada a 4 MiB no índice de
|
|
71
|
+
chunks, preservando o transporte gzip e evitando trabalho proporcional a transcripts gigantes.
|
|
72
|
+
|
|
7
73
|
## [0.73.0] — 2026-08-20
|
|
8
74
|
|
|
9
75
|
### Added
|
package/README.en.md
CHANGED
|
@@ -84,11 +84,11 @@ Decisions, dead ends, the reason you chose X over Y — gone next session. The p
|
|
|
84
84
|
|---|---|
|
|
85
85
|
| **Capture** — every turn, on disk | `SessionStart` / `Stop` hooks write each session to a dated Markdown note: prompts, iterations, files touched, wikilinks. |
|
|
86
86
|
| **Derive** — decisions, bugs, learnings | Pulled from the transcript into their own notes, backlinked to the session. Your history becomes navigable, not archival. |
|
|
87
|
-
| **Recall** — injected back | Canonical `CORE` + operational `SHARED_MEMORY
|
|
87
|
+
| **Recall** — injected back | Canonical `CORE` + operational `SHARED_MEMORY` enter on `startup`, `/clear`, and `/compact`; on every prompt, the local chunk index selects a few passages with source, authority, and validity under an explicit budget. |
|
|
88
88
|
| **Cost** — what it all cost | Per‑model, cache‑aware token pricing per session — plus `cost --trend` with a run‑rate projection across the whole vault; research previews without a final rate remain unestimated. |
|
|
89
89
|
| **Multi‑agent** — one vault, both agents | `init` wires the session hooks into `.claude/settings.json` *and* `.codex/hooks.json`, and every note is tagged with the agent that wrote it: Claude Code is detected from its environment, anything else is recorded as Codex. One shared graph, whichever agent you are in. |
|
|
90
90
|
| **Local‑first** — no cloud, no account | Everything is plain Markdown on your disk. An optional MCP server (`@bitbonsai/mcpvault`) lets the agent read/write the vault. |
|
|
91
|
-
| **Local Observer** — many projects, one view | `wendkeep observer` keeps documents, sessions, agents, tokens, costs, calls, and transcripts in
|
|
91
|
+
| **Local Observer** — many projects, one view | `wendkeep observer` keeps documents, FTS5 chunks, sessions, agents, tokens, costs, calls, and transcripts in SQLite. Identities and foreign keys are project-scoped; each event is atomic. Hooks publish only what changed, while `observer reconcile` reserves full scans for explicit recovery. |
|
|
92
92
|
|
|
93
93
|
During historical migration, the Observer preserves differences between frontmatter totals and the
|
|
94
94
|
ledger as explicit reconciliation rows, and disambiguates duplicate `session_id` values per file
|
|
@@ -100,7 +100,7 @@ The Codex scope guard treats `commit`, `push`, `pull`, `merge`, `publish`, and d
|
|
|
100
100
|
operations as independent capabilities, including inside compound commands.
|
|
101
101
|
|
|
102
102
|
- Node.js ≥ 18
|
|
103
|
-
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets
|
|
103
|
+
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets twelve compatible hooks, including per-prompt recall and the scoped `PreToolUse` guard, and enumerates them untrusted, so approve its “Hooks need review” prompt once at startup (see [Notes & roadmap](#notes--roadmap))
|
|
104
104
|
- Obsidian (to view the graph) — optional but the point
|
|
105
105
|
|
|
106
106
|
## Install & set up
|
|
@@ -115,7 +115,7 @@ npx wendkeep init
|
|
|
115
115
|
|
|
116
116
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
117
117
|
2. Write a provider-neutral **`.wendkeep.json`** binding at the project root and a matching `.brain/PROJECT.json` marker in the vault, then merge the session hooks into **`.claude/settings.json`**. The binding is provider-neutral by design: any agent resolves the same vault from its session `cwd`, with no machine-global environment variable. Older registrations already in `.claude/settings.json` are adopted automatically.
|
|
118
|
-
3. Wire the Codex hooks in **`.codex/hooks.json`** —
|
|
118
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
119
119
|
4. Add the **`wendkeep-vault`** MCP server to `.mcp.json` so the agent can read/write the vault. Skip with `--no-mcp` — e.g. when the agent already has a vault MCP. (`--no-mcp` skips *only wendkeep's own* MCP; companion MCPs still follow `--companions`.)
|
|
120
120
|
5. Offer to pin **companion** plugins/MCP (multi-choice; **none** pre-checked — wendkeep is a neutral harness and presumes no third-party plugin). Each is wired the most agent-agnostic way it supports:
|
|
121
121
|
- **`context-mode`** — context optimizer + FTS5 memory, wired as a Claude Code plugin. It ships its own MCP server, so wendkeep deliberately adds no `.mcp.json` entry (registering both cold-started two servers at once). On non-Claude agents, add the MCP by hand: `npx -y context-mode`.
|
|
@@ -125,7 +125,7 @@ npx wendkeep init
|
|
|
125
125
|
|
|
126
126
|
Control with `--companions <csv>` or `--no-companions`. The Claude Code plugin layer (`extraKnownMarketplaces` + `enabledPlugins`) is wired as a bonus where the companion has one.
|
|
127
127
|
6. Install a **color system** into the vault's `.obsidian/`: a CSS snippet that accents notes by type (session/decision/bug/learning, via the `cssclasses` the hooks emit) plus graph color groups by folder. Non-destructive merge into `appearance.json`/`graph.json`; skip with `--no-colors`. Re-apply it any time on an existing vault with `wendkeep theme sync` — Obsidian owns `graph.json` and can drop the color groups (a grey graph); the re-sync restores them without a full re-`init`.
|
|
128
|
-
7. Seed **Shared Project Memory v2** without overwriting existing artifacts: `.brain/CORE.md
|
|
128
|
+
7. Seed **Shared Project Memory v2** without overwriting existing artifacts: `.brain/CORE.md`, `.brain/SHARED_MEMORY.md`, `.brain/MEMORY_EVENTS.jsonl`, `.brain/MEMORY_CANDIDATES.jsonl`, and `.brain/COMPACTION_PROTOCOL.md`. The durable outbox appears under `.brain/memory-outbox/`; `EVIDENCE_INDEX.jsonl` is rebuilt locally from chunks while `DIGEST.md`/`index.jsonl` remain compatible. Everything stays in the vault.
|
|
129
129
|
8. Seed the **definitions + skills layer**: `.brain/agents/` + `.brain/skills/` (versioned source of truth), including the native process skills `wk-workflow` / `wk-tdd` / `wk-debugging` / `wk-brainstorming` / `wk-planning` / `wk-verify` (some ship templates — e.g. `wk-verify`'s `verdict-template.json` + reviewer prompt). `init` runs `wendkeep sync-defs` for you, delivering the skills to `.claude/skills/` and `.agents/skills/`, and the agent definitions (`.brain/agents/*.toml`) to `.codex/agents/`, plus a managed section in `AGENTS.md` that indexes the skills for Codex; `sync-defs --check` detects stale copies (re-run `sync-defs` after editing `.brain`).
|
|
130
130
|
9. Seed the **change/spec lifecycle**: the `07-Specs/` + `08-Mudanças/` folders and a native `wendkeep.sensors.json` — critical memory validation/health sensors plus one for each of `typecheck` / `test` / `lint` / `build` found in your `package.json`. `memory-health` blocks delivery on corruption or projection divergence; semantic conflicts degrade only the affected keys and await curation. Pending outbox events and ordinary candidates are warnings. Add sensors with `wendkeep sensors add`. Drives `wendkeep change` / `wendkeep verify` — see **Change lifecycle** below.
|
|
131
131
|
|
|
@@ -240,7 +240,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
240
240
|
| **Notes and knowledge** | BUG/APR/ADR, repairs, renumbering, lessons, and dashboard | [Notes and knowledge](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/notes-and-knowledge.md) |
|
|
241
241
|
| **Costs and observability** | safe dry-run, tri-state, aggregation, trends, and historical rebuild | [Costs and observability](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/costs-and-observability.md) |
|
|
242
242
|
| **Maintenance and diagnostics** | doctor, frontier/manifest freshness, drift, version, and help | [Maintenance and diagnostics](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/maintenance-and-diagnostics.md) |
|
|
243
|
-
| **Local Observer** | `observer serve`, registration,
|
|
243
|
+
| **Local Observer** | `observer serve`, registration, incremental publication, `reconcile`, outbox, and multi-project index | [Local Observer](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/observer.md) |
|
|
244
244
|
|
|
245
245
|
Operations that deserve step-by-step guidance: [verify and exits 0/1/2](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/verify.md),
|
|
246
246
|
[legacy-memory migration](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory-migration.md), and
|
|
@@ -332,9 +332,9 @@ spec, or ADR. If delivery requires a code/config edit, it pauses and work return
|
|
|
332
332
|
`implementation`:
|
|
333
333
|
|
|
334
334
|
```bash
|
|
335
|
-
npx wendkeep delivery start release-0-
|
|
336
|
-
npx wendkeep delivery status release-0-
|
|
337
|
-
npx wendkeep delivery finish release-0-
|
|
335
|
+
npx wendkeep delivery start release-0-74-0 --allow git:merge --allow git:push --allow publish --source-change <slug> --source-commit <sha>
|
|
336
|
+
npx wendkeep delivery status release-0-74-0
|
|
337
|
+
npx wendkeep delivery finish release-0-74-0 --target main --ci-url <url> --version 0.74.0 --npm-integrity <sha512> --release-url <url>
|
|
338
338
|
```
|
|
339
339
|
|
|
340
340
|
If the harness does not record a lease, a small fix remains under the configured profile —
|
|
@@ -369,6 +369,8 @@ Hot memory now separates human authorship, operational state, and evidence:
|
|
|
369
369
|
- **`SHARED_MEMORY.md` is generated operational state.** The `Stop` hook turns the session handoff into sanitized events; the projector deterministically reduces the ledger and publishes a verifiable revision, cursor, and hash. Facts are `verified` only with local evidence; unsupported reports remain `reported`, and disagreements become candidates for human judgment.
|
|
370
370
|
- **`MEMORY_EVENTS.jsonl` is the append-only authority.** `Stop` makes events durable in the outbox before acknowledging the attempt; the projector runs outside the registry lock and retries reuse the same IDs. Repeating an identical `event_id`/payload is a no-op; reusing the ID with different bytes is observable corruption.
|
|
371
371
|
- **`MEMORY_CANDIDATES.jsonl` is the curation queue.** Conflicts and legacy content are never silently promoted. `promote` and `reject` record the decision as a new event; promotion preserves the selected event's JSON type, session, activation/epoch, and source turn.
|
|
372
|
+
- **Registers are scoped.** `git.local-head`, handoffs, verdicts, and change status carry project, work-session, change, branch, or worktree scope. Two branches do not create a global conflict; only events in the same scope and causal lineage may advance automatically.
|
|
373
|
+
- **`EVIDENCE_INDEX.jsonl` is local recall.** Markdown is chunked by headings and blocks without requiring the Observer. Ranking combines BM25, exact phrases, field weights, authority, validity, bounded recency, and source diversity; `UserPromptSubmit` injects only relevant passages with provenance.
|
|
372
374
|
|
|
373
375
|
Artifacts stay under `.brain/` only. Sanitization strips secrets, tokens, local paths, transcripts, and harness payloads both before persistence and before injection. Events carry a `project_id`, and one vault never accepts another project's events.
|
|
374
376
|
|
|
@@ -390,6 +392,8 @@ Codex uses `session_id`/`turn_id` plus transcript order, with no artificial caus
|
|
|
390
392
|
npx --no-install wendkeep memory status --gate --vault .MyApp-vault
|
|
391
393
|
npx --no-install wendkeep memory migrate --vault .MyApp-vault # preview, zero writes
|
|
392
394
|
npx --no-install wendkeep memory migrate --apply --vault .MyApp-vault # backup + candidates + v2 bundle
|
|
395
|
+
npx --no-install wendkeep memory rescope --vault .MyApp-vault # preview without values
|
|
396
|
+
npx --no-install wendkeep memory rescope --apply --vault .MyApp-vault # append-only and idempotent
|
|
393
397
|
```
|
|
394
398
|
|
|
395
399
|
### Health and recovery
|
package/README.md
CHANGED
|
@@ -84,11 +84,11 @@ Decisions, dead ends, the reason you chose X over Y — gone next session. The p
|
|
|
84
84
|
|---|---|
|
|
85
85
|
| **Capture** — every turn, on disk | `SessionStart` / `Stop` hooks write each session to a dated Markdown note: prompts, iterations, files touched, wikilinks. |
|
|
86
86
|
| **Derive** — decisions, bugs, learnings | Pulled from the transcript into their own notes, backlinked to the session. Your history becomes navigable, not archival. |
|
|
87
|
-
| **Recall** — injected back | Canonical `CORE` + operational `SHARED_MEMORY
|
|
87
|
+
| **Recall** — injected back | Canonical `CORE` + operational `SHARED_MEMORY` enter on `startup`, `/clear`, and `/compact`; on every prompt, the local chunk index selects a few passages with source, authority, and validity under an explicit budget. |
|
|
88
88
|
| **Cost** — what it all cost | Per‑model, cache‑aware token pricing per session — plus `cost --trend` with a run‑rate projection across the whole vault; research previews without a final rate remain unestimated. |
|
|
89
89
|
| **Multi‑agent** — one vault, both agents | `init` wires the session hooks into `.claude/settings.json` *and* `.codex/hooks.json`, and every note is tagged with the agent that wrote it: Claude Code is detected from its environment, anything else is recorded as Codex. One shared graph, whichever agent you are in. |
|
|
90
90
|
| **Local‑first** — no cloud, no account | Everything is plain Markdown on your disk. An optional MCP server (`@bitbonsai/mcpvault`) lets the agent read/write the vault. |
|
|
91
|
-
| **Local Observer** — many projects, one view | `wendkeep observer` keeps documents, sessions, agents, tokens, costs, calls, and transcripts in
|
|
91
|
+
| **Local Observer** — many projects, one view | `wendkeep observer` keeps documents, FTS5 chunks, sessions, agents, tokens, costs, calls, and transcripts in SQLite. Identities and foreign keys are project-scoped; each event is atomic. Hooks publish only what changed, while `observer reconcile` reserves full scans for explicit recovery. |
|
|
92
92
|
|
|
93
93
|
During historical migration, the Observer preserves differences between frontmatter totals and the
|
|
94
94
|
ledger as explicit reconciliation rows, and disambiguates duplicate `session_id` values per file
|
|
@@ -100,7 +100,7 @@ The Codex scope guard treats `commit`, `push`, `pull`, `merge`, `publish`, and d
|
|
|
100
100
|
operations as independent capabilities, including inside compound commands.
|
|
101
101
|
|
|
102
102
|
- Node.js ≥ 18
|
|
103
|
-
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets
|
|
103
|
+
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets twelve compatible hooks, including per-prompt recall and the scoped `PreToolUse` guard, and enumerates them untrusted, so approve its “Hooks need review” prompt once at startup (see [Notes & roadmap](#notes--roadmap))
|
|
104
104
|
- Obsidian (to view the graph) — optional but the point
|
|
105
105
|
|
|
106
106
|
## Install & set up
|
|
@@ -115,7 +115,7 @@ npx wendkeep init
|
|
|
115
115
|
|
|
116
116
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
117
117
|
2. Write a provider-neutral **`.wendkeep.json`** binding at the project root and a matching `.brain/PROJECT.json` marker in the vault, then merge the session hooks into **`.claude/settings.json`**. The binding is provider-neutral by design: any agent resolves the same vault from its session `cwd`, with no machine-global environment variable. Older registrations already in `.claude/settings.json` are adopted automatically.
|
|
118
|
-
3. Wire the Codex hooks in **`.codex/hooks.json`** —
|
|
118
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — twelve compatible entries: `brain-inject` + `session-start` + `observer-publish` on `SessionStart`, `session-ensure` + `evidence-context` + `change-context` on `UserPromptSubmit`, `session-stop` + `observer-publish` + `change-nag` on `Stop`, `subagent-stop` + `observer-publish` on `SubagentStop`, and `change-guard` on `PreToolUse` for `Bash`, `exec_command`, `apply_patch`, and mutable MCP tools, always in the `npx wendkeep hook <name>` form. For the Observer, `SessionStart` only drains the outbox, `Stop` enqueues the changed session, and `SubagentStop` enqueues only the affected transcript; full scanning is explicit through `observer reconcile`. The guard accepts object, raw-string, and argv Codex payloads; before a mutation it compares the session with the project, Git root, remote, branch, and worktree, denying missing or divergent targets. The other four stay out because Codex offers no equivalent payload, tool, or event: `change-warn` (no reliable `tool_input.file_path`), `plan-capture` (no `ExitPlanMode`), `decision-capture` (`AskUserQuestion` is Claude-only), and `task-log` (`TaskCompleted` is not in Codex's event enum). Codex scope blocks use `permissionDecision: "deny"`; `ask` is never emitted in `PreToolUse`. The merge remains non-destructive, preserves third-party hooks, and migrates legacy `timeout` to `timeoutSec`. **Codex enumerates every hook as untrusted and runs none until you approve the “Hooks need review” prompt at startup — `init` cannot pre-approve them**.
|
|
119
119
|
4. Add the **`wendkeep-vault`** MCP server to `.mcp.json` so the agent can read/write the vault. Skip with `--no-mcp` — e.g. when the agent already has a vault MCP. (`--no-mcp` skips *only wendkeep's own* MCP; companion MCPs still follow `--companions`.)
|
|
120
120
|
5. Offer to pin **companion** plugins/MCP (multi-choice; **none** pre-checked — wendkeep is a neutral harness and presumes no third-party plugin). Each is wired the most agent-agnostic way it supports:
|
|
121
121
|
- **`context-mode`** — context optimizer + FTS5 memory, wired as a Claude Code plugin. It ships its own MCP server, so wendkeep deliberately adds no `.mcp.json` entry (registering both cold-started two servers at once). On non-Claude agents, add the MCP by hand: `npx -y context-mode`.
|
|
@@ -125,7 +125,7 @@ npx wendkeep init
|
|
|
125
125
|
|
|
126
126
|
Control with `--companions <csv>` or `--no-companions`. The Claude Code plugin layer (`extraKnownMarketplaces` + `enabledPlugins`) is wired as a bonus where the companion has one.
|
|
127
127
|
6. Install a **color system** into the vault's `.obsidian/`: a CSS snippet that accents notes by type (session/decision/bug/learning, via the `cssclasses` the hooks emit) plus graph color groups by folder. Non-destructive merge into `appearance.json`/`graph.json`; skip with `--no-colors`. Re-apply it any time on an existing vault with `wendkeep theme sync` — Obsidian owns `graph.json` and can drop the color groups (a grey graph); the re-sync restores them without a full re-`init`.
|
|
128
|
-
7. Seed **Shared Project Memory v2** without overwriting existing artifacts: `.brain/CORE.md
|
|
128
|
+
7. Seed **Shared Project Memory v2** without overwriting existing artifacts: `.brain/CORE.md`, `.brain/SHARED_MEMORY.md`, `.brain/MEMORY_EVENTS.jsonl`, `.brain/MEMORY_CANDIDATES.jsonl`, and `.brain/COMPACTION_PROTOCOL.md`. The durable outbox appears under `.brain/memory-outbox/`; `EVIDENCE_INDEX.jsonl` is rebuilt locally from chunks while `DIGEST.md`/`index.jsonl` remain compatible. Everything stays in the vault.
|
|
129
129
|
8. Seed the **definitions + skills layer**: `.brain/agents/` + `.brain/skills/` (versioned source of truth), including the native process skills `wk-workflow` / `wk-tdd` / `wk-debugging` / `wk-brainstorming` / `wk-planning` / `wk-verify` (some ship templates — e.g. `wk-verify`'s `verdict-template.json` + reviewer prompt). `init` runs `wendkeep sync-defs` for you, delivering the skills to `.claude/skills/` and `.agents/skills/`, and the agent definitions (`.brain/agents/*.toml`) to `.codex/agents/`, plus a managed section in `AGENTS.md` that indexes the skills for Codex; `sync-defs --check` detects stale copies (re-run `sync-defs` after editing `.brain`).
|
|
130
130
|
9. Seed the **change/spec lifecycle**: the `07-Specs/` + `08-Mudanças/` folders and a native `wendkeep.sensors.json` — critical memory validation/health sensors plus one for each of `typecheck` / `test` / `lint` / `build` found in your `package.json`. `memory-health` blocks delivery on corruption or projection divergence; semantic conflicts degrade only the affected keys and await curation. Pending outbox events and ordinary candidates are warnings. Add sensors with `wendkeep sensors add`. Drives `wendkeep change` / `wendkeep verify` — see **Change lifecycle** below.
|
|
131
131
|
|
|
@@ -240,7 +240,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
240
240
|
| **Notes and knowledge** | BUG/APR/ADR, repairs, renumbering, lessons, and dashboard | [Notes and knowledge](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/notes-and-knowledge.md) |
|
|
241
241
|
| **Costs and observability** | safe dry-run, tri-state, aggregation, trends, and historical rebuild | [Costs and observability](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/costs-and-observability.md) |
|
|
242
242
|
| **Maintenance and diagnostics** | doctor, frontier/manifest freshness, drift, version, and help | [Maintenance and diagnostics](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/maintenance-and-diagnostics.md) |
|
|
243
|
-
| **Local Observer** | `observer serve`, registration,
|
|
243
|
+
| **Local Observer** | `observer serve`, registration, incremental publication, `reconcile`, outbox, and multi-project index | [Local Observer](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/observer.md) |
|
|
244
244
|
|
|
245
245
|
Operations that deserve step-by-step guidance: [verify and exits 0/1/2](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/verify.md),
|
|
246
246
|
[legacy-memory migration](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/memory-migration.md), and
|
|
@@ -332,9 +332,9 @@ spec, or ADR. If delivery requires a code/config edit, it pauses and work return
|
|
|
332
332
|
`implementation`:
|
|
333
333
|
|
|
334
334
|
```bash
|
|
335
|
-
npx wendkeep delivery start release-0-
|
|
336
|
-
npx wendkeep delivery status release-0-
|
|
337
|
-
npx wendkeep delivery finish release-0-
|
|
335
|
+
npx wendkeep delivery start release-0-74-0 --allow git:merge --allow git:push --allow publish --source-change <slug> --source-commit <sha>
|
|
336
|
+
npx wendkeep delivery status release-0-74-0
|
|
337
|
+
npx wendkeep delivery finish release-0-74-0 --target main --ci-url <url> --version 0.74.0 --npm-integrity <sha512> --release-url <url>
|
|
338
338
|
```
|
|
339
339
|
|
|
340
340
|
If the harness does not record a lease, a small fix remains under the configured profile —
|
|
@@ -369,6 +369,8 @@ Hot memory now separates human authorship, operational state, and evidence:
|
|
|
369
369
|
- **`SHARED_MEMORY.md` is generated operational state.** The `Stop` hook turns the session handoff into sanitized events; the projector deterministically reduces the ledger and publishes a verifiable revision, cursor, and hash. Facts are `verified` only with local evidence; unsupported reports remain `reported`, and disagreements become candidates for human judgment.
|
|
370
370
|
- **`MEMORY_EVENTS.jsonl` is the append-only authority.** `Stop` makes events durable in the outbox before acknowledging the attempt; the projector runs outside the registry lock and retries reuse the same IDs. Repeating an identical `event_id`/payload is a no-op; reusing the ID with different bytes is observable corruption.
|
|
371
371
|
- **`MEMORY_CANDIDATES.jsonl` is the curation queue.** Conflicts and legacy content are never silently promoted. `promote` and `reject` record the decision as a new event; promotion preserves the selected event's JSON type, session, activation/epoch, and source turn.
|
|
372
|
+
- **Registers are scoped.** `git.local-head`, handoffs, verdicts, and change status carry project, work-session, change, branch, or worktree scope. Two branches do not create a global conflict; only events in the same scope and causal lineage may advance automatically.
|
|
373
|
+
- **`EVIDENCE_INDEX.jsonl` is local recall.** Markdown is chunked by headings and blocks without requiring the Observer. Ranking combines BM25, exact phrases, field weights, authority, validity, bounded recency, and source diversity; `UserPromptSubmit` injects only relevant passages with provenance.
|
|
372
374
|
|
|
373
375
|
Artifacts stay under `.brain/` only. Sanitization strips secrets, tokens, local paths, transcripts, and harness payloads both before persistence and before injection. Events carry a `project_id`, and one vault never accepts another project's events.
|
|
374
376
|
|
|
@@ -390,6 +392,8 @@ Codex uses `session_id`/`turn_id` plus transcript order, with no artificial caus
|
|
|
390
392
|
npx --no-install wendkeep memory status --gate --vault .MyApp-vault
|
|
391
393
|
npx --no-install wendkeep memory migrate --vault .MyApp-vault # preview, zero writes
|
|
392
394
|
npx --no-install wendkeep memory migrate --apply --vault .MyApp-vault # backup + candidates + v2 bundle
|
|
395
|
+
npx --no-install wendkeep memory rescope --vault .MyApp-vault # preview without values
|
|
396
|
+
npx --no-install wendkeep memory rescope --apply --vault .MyApp-vault # append-only and idempotent
|
|
393
397
|
```
|
|
394
398
|
|
|
395
399
|
### Health and recovery
|
|
@@ -30,6 +30,7 @@ Pass the vault explicitly in automation. Preserve backups and evidence before re
|
|
|
30
30
|
npx wendkeep memory status [--gate] --vault <vault>
|
|
31
31
|
npx wendkeep memory curate --vault <vault>
|
|
32
32
|
npx wendkeep memory candidates [--active] --vault <vault>
|
|
33
|
+
npx wendkeep memory rescope [--apply] --vault <vault>
|
|
33
34
|
npx wendkeep memory repair --vault <vault>
|
|
34
35
|
npx wendkeep memory recover-attempt <session> [--apply] --vault <vault>
|
|
35
36
|
npx wendkeep memory reconcile <ambiguous-session> --by-session <successor-session> --reason <reason> [--apply] --vault <vault>
|
|
@@ -51,7 +52,7 @@ npx wendkeep validate-memory --vault <v2-vault>
|
|
|
51
52
|
non-TTY environment it exits `2` without changing bytes and recommends the advanced fallback
|
|
52
53
|
`memory candidates --active`.
|
|
53
54
|
- `memory candidates` is read-only and prints deterministic JSON containing only `candidate_id`,
|
|
54
|
-
`reason`, `status`, `memory_key`, and `event_ids`; it does not expose memory values or content and
|
|
55
|
+
`reason`, `status`, `memory_key`, scope when present, and `event_ids`; it does not expose memory values or content and
|
|
55
56
|
does not create a lock or mutate the bundle. `--active` omits terminal candidates (`resolved`,
|
|
56
57
|
`rejected`, and `superseded`). A missing status is normalized to `active`.
|
|
57
58
|
- For `memory candidates`, exit `0` means a valid inventory (including empty or conflicted), exit
|
|
@@ -95,6 +96,18 @@ npx wendkeep validate-memory --vault <v2-vault>
|
|
|
95
96
|
and its successor. Replay is CORE-aware, checkpoints use the physical ledger cursor, and the
|
|
96
97
|
command neither rewrites ledger/CORE/notes nor consumes the outbox. Retrying the same applied
|
|
97
98
|
decision is idempotent.
|
|
99
|
+
- `memory rescope` is a dry run by default and lists only planned IDs, keys, and scopes. With
|
|
100
|
+
`--apply`, it appends explicit project, work-session, change, branch, or worktree events while
|
|
101
|
+
preserving historic bytes as the ledger prefix. Ambiguous candidates are neither migrated nor
|
|
102
|
+
assigned a winner; retry returns `unchanged`.
|
|
103
|
+
- Registers such as `git.local-head`, `handoff.latest`, `quality.latest-*`, and
|
|
104
|
+
`change.<slug>.status` compete only inside the same scope. Automatic resolution still requires
|
|
105
|
+
the same project and causal lineage; incompatible decisions, constraints, and blockers remain
|
|
106
|
+
human-curated. An ambiguous key is omitted from SHARED without removing CORE or independent keys.
|
|
107
|
+
- `.brain/EVIDENCE_INDEX.jsonl` chunks documents by heading and block and records file, heading,
|
|
108
|
+
type, change, session, work session, authority, date, validity, and hash. `/brain-recall` and the
|
|
109
|
+
`UserPromptSubmit` hook use BM25, exact phrase, field weights, authority, validity, bounded
|
|
110
|
+
recency, and diversity to return the matching passage with provenance.
|
|
98
111
|
- Every memory path validates the physical topology of `.brain`, ledger, outbox, CORE, SHARED,
|
|
99
112
|
candidates, registry, notes, backups, temporary files, and sidecars before reading or writing.
|
|
100
113
|
Junctions, symlinks, reparse points, or hardlinks fail closed without touching external bytes.
|
|
@@ -136,6 +149,8 @@ npx wendkeep validate-memory --vault <v2-vault>
|
|
|
136
149
|
npx wendkeep memory status --gate --vault .MyApp-vault
|
|
137
150
|
npx wendkeep memory curate --vault .MyApp-vault
|
|
138
151
|
npx wendkeep memory candidates --active --vault .MyApp-vault
|
|
152
|
+
npx wendkeep memory rescope --vault .MyApp-vault
|
|
153
|
+
npx wendkeep memory rescope --apply --vault .MyApp-vault
|
|
139
154
|
npx wendkeep memory recover-attempt session-123 --vault .MyApp-vault
|
|
140
155
|
npx wendkeep memory recover-attempt session-123 --apply --vault .MyApp-vault
|
|
141
156
|
npx wendkeep memory reconcile old --by-session current --reason "delivery continued" --vault .MyApp-vault
|
|
@@ -34,6 +34,7 @@ loopback reads remain open, while every mutation requires a Bearer token.
|
|
|
34
34
|
npx wendkeep observer status --data-dir <directory> --json
|
|
35
35
|
npx wendkeep observer register --project <project> --vault <vault> --data-dir <directory>
|
|
36
36
|
npx wendkeep observer publish --project <project> --vault <vault> --data-dir <directory>
|
|
37
|
+
npx wendkeep observer reconcile --project <project> --vault <vault> --data-dir <directory> [--url http://127.0.0.1:8787]
|
|
37
38
|
npx wendkeep observer memory import --project <project> --vault <vault> --url http://127.0.0.1:8787 --token <token> --json
|
|
38
39
|
npx wendkeep observer serve --host 127.0.0.1 --port 8787 --data-dir <directory> --token <token>
|
|
39
40
|
```
|
|
@@ -42,7 +43,7 @@ npx wendkeep observer serve --host 127.0.0.1 --port 8787 --data-dir <directory>
|
|
|
42
43
|
|
|
43
44
|
- `--data-dir` selects the local event and index directory; the default is
|
|
44
45
|
`WENDKEEP_OBSERVER_DATA_DIR` or `~/.wendkeep-observer`.
|
|
45
|
-
- `--project` and `--vault` identify a project for `register`, `publish`, and `memory import`.
|
|
46
|
+
- `--project` and `--vault` identify a project for `register`, `publish`, `reconcile`, and `memory import`.
|
|
46
47
|
- `--host` accepts only `127.0.0.1`, `localhost`, or `::1`; other hosts are rejected before
|
|
47
48
|
listening.
|
|
48
49
|
- `--token` or `WENDKEEP_OBSERVER_TOKEN` authenticates mutations; `--allow-non-loopback` fails without one.
|
|
@@ -84,8 +85,8 @@ If the browser shows the shell but the list fails, check the service health at
|
|
|
84
85
|
|
|
85
86
|
## Expected result
|
|
86
87
|
|
|
87
|
-
`register` stores `project_id`, name, version, and registration time. `publish`
|
|
88
|
-
|
|
88
|
+
`register` stores `project_id`, name, version, and registration time. `publish` and `reconcile`
|
|
89
|
+
perform an explicit full-vault scan and send idempotent events to SQLite containing the complete content
|
|
89
90
|
of sessions, decisions, bugs, learnings, specs, changes, CORE, DIGEST, SHARED_MEMORY, brain state,
|
|
90
91
|
agent sessions, cost rollups, and calls. Messages and transcripts are only sent by capture levels
|
|
91
92
|
that explicitly enable them. The container stores everything in
|
|
@@ -96,10 +97,26 @@ cost/token total recorded in frontmatter is preserved through an explicit reconc
|
|
|
96
97
|
the detailed ledger does not add up; that row does not invent calls. Historical sessions sharing
|
|
97
98
|
one `session_id` receive a canonical per-file identity so one rollup cannot overwrite the other.
|
|
98
99
|
|
|
100
|
+
In schema 5, sessions, agents, rollups, calls, and transcripts use internal identities derived from
|
|
101
|
+
`project_id` plus the external identifier, with project-scoped constraints and foreign keys. The
|
|
102
|
+
same `session_id`, `agent_id`, `call_id`, or `rollup_key` can exist in separate projects without a
|
|
103
|
+
collision. Every event runs inside its own savepoint; an intermediate failure rolls back the ingest
|
|
104
|
+
row and all projections before the batch continues. Migrations are checksummed and an existing
|
|
105
|
+
database receives a consistent backup before every structural migration.
|
|
106
|
+
|
|
107
|
+
Each ingested document is also projected into chunks carrying path, heading,
|
|
108
|
+
authority, time, and validity. The Observer feature-probes FTS5 and uses the index when the
|
|
109
|
+
extension is available; otherwise it preserves the same semantics through a lexical fallback.
|
|
110
|
+
Search returns the passage containing the match and its provenance rather than only the beginning
|
|
111
|
+
of the document.
|
|
112
|
+
|
|
99
113
|
`init` projects `observer-publish` into `SessionStart`, `Stop`, and `SubagentStop` after the primary
|
|
100
|
-
hooks.
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
hooks. `SessionStart` only drains the queue; `Stop` reads the changed session alone, and
|
|
115
|
+
`SubagentStop` reads only the affected subagent transcript. `note new` and `change archive` enqueue
|
|
116
|
+
the documents they wrote. Events are coalesced by scope and one lease admits a single publisher.
|
|
117
|
+
When the server is unavailable, `.brain/observer-sql-outbox/` remains durable without blocking the
|
|
118
|
+
session; full-vault scanning is reserved for `observer reconcile`. `doctor` reports queue batches,
|
|
119
|
+
events, bytes, and age. SQL batches use gzip so complete transcripts larger than 64 MB as plain JSON remain within
|
|
103
120
|
the transport limit; the Observer decompresses and validates the body before ingesting it. The
|
|
104
121
|
outbox is temporary transport, not authority.
|
|
105
122
|
|
|
@@ -107,12 +124,12 @@ outbox is temporary transport, not authority.
|
|
|
107
124
|
|
|
108
125
|
- `project_not_registered`: run `observer register` before publishing.
|
|
109
126
|
- `host loopback`: replace `0.0.0.0` or a LAN address with `127.0.0.1`.
|
|
110
|
-
- Pending outbox: the service was unavailable; preserve `.brain/observer-outbox/` and
|
|
111
|
-
|
|
112
|
-
`.brain/observer-sql-state.json
|
|
127
|
+
- Pending outbox: the service was unavailable; preserve `.brain/observer-sql-outbox/` and let a
|
|
128
|
+
later hook drain it or run `observer reconcile`. Also ignore
|
|
129
|
+
`.brain/observer-sql-state.json`, `.brain/observer-sql-outbox/`, and `.brain/observer-sql-publisher.lock` in a versioned vault. Do not delete events manually.
|
|
113
130
|
- `WENDKEEP_OBSERVER_NODE_UNSUPPORTED`: run the Observer on Node.js 22.13 or newer.
|
|
114
131
|
- If memory or usage is incomplete, check the Sync screen, preserve the outbox, and run
|
|
115
|
-
`observer
|
|
132
|
+
`observer reconcile` to rebuild the load and prove hash parity.
|
|
116
133
|
|
|
117
134
|
## Next steps
|
|
118
135
|
|
|
@@ -139,7 +156,8 @@ complete, archive, repair, or promote state.
|
|
|
139
156
|
rollups, calls, and transcripts.
|
|
140
157
|
- `GET /v1/projects/:project_id/memory/tree` — document tree and metadata.
|
|
141
158
|
- `GET /v1/projects/:project_id/memory/document?path=...` — complete Markdown content.
|
|
142
|
-
- `GET /v1/projects/:project_id/memory/search?q=...` —
|
|
159
|
+
- `GET /v1/projects/:project_id/memory/search?q=...` — ranked chunk search with matching passage
|
|
160
|
+
and provenance; uses a lexical fallback when FTS5 is unavailable.
|
|
143
161
|
- `GET /v1/projects/:project_id/sync` — mode, counts, conflicts, and latest event.
|
|
144
162
|
- `PUT /v1/projects/:project_id/sync` — compatibility configuration; SQL remains authoritative.
|
|
145
163
|
- `GET /v1/projects/:project_id/memory/export` — read-only export with complete content.
|
|
@@ -248,7 +248,7 @@ Deliver an approved version without manufacturing another change:
|
|
|
248
248
|
```bash
|
|
249
249
|
npx wendkeep delivery start release-0-73-0 --source-change proportional-governance --allow git:merge --allow git:push --allow publish
|
|
250
250
|
npx wendkeep delivery status release-0-73-0
|
|
251
|
-
npx wendkeep delivery finish release-0-
|
|
251
|
+
npx wendkeep delivery finish release-0-74-0 --target v0.74.0 --ci-url <run> --version 0.74.0 --npm-integrity <sha512> --release-url <release>
|
|
252
252
|
```
|
|
253
253
|
|
|
254
254
|
## Expected result
|
|
@@ -30,6 +30,7 @@ Informe o vault explicitamente em automações. Preserve backups e evidências a
|
|
|
30
30
|
npx wendkeep memory status [--gate] --vault <cofre>
|
|
31
31
|
npx wendkeep memory curate --vault <cofre>
|
|
32
32
|
npx wendkeep memory candidates [--active] --vault <cofre>
|
|
33
|
+
npx wendkeep memory rescope [--apply] --vault <cofre>
|
|
33
34
|
npx wendkeep memory repair --vault <cofre>
|
|
34
35
|
npx wendkeep memory recover-attempt <sessão> [--apply] --vault <cofre>
|
|
35
36
|
npx wendkeep memory reconcile <sessão-ambígua> --by-session <sessão-sucessora> --reason <motivo> [--apply] --vault <cofre>
|
|
@@ -51,7 +52,7 @@ npx wendkeep validate-memory --vault <cofre-v2>
|
|
|
51
52
|
não-TTY/terminal não interativo, ele retorna exit `2` sem alterar bytes e orienta usar o fallback
|
|
52
53
|
avançado `memory candidates --active`.
|
|
53
54
|
- `memory candidates` é read-only e imprime JSON determinístico com somente `candidate_id`,
|
|
54
|
-
`reason`, `status`, `memory_key
|
|
55
|
+
`reason`, `status`, `memory_key`, escopo quando presente e `event_ids`; não expõe valores nem conteúdo da memória e não
|
|
55
56
|
cria lock nem altera o bundle. `--active` omite candidates terminais (`resolved`, `rejected` e
|
|
56
57
|
`superseded`). Status ausente é normalizado para `active`.
|
|
57
58
|
- Em `memory candidates`, exit `0` indica inventário válido (inclusive vazio ou com conflitos),
|
|
@@ -95,6 +96,18 @@ npx wendkeep validate-memory --vault <cofre-v2>
|
|
|
95
96
|
do attempt exato, salva backup do registry e limita a mutação ao attempt ambíguo e à sucessora.
|
|
96
97
|
O replay é CORE-aware, usa cursor físico do ledger no checkpoint e não reescreve ledger, CORE ou
|
|
97
98
|
notas, nem consome a outbox. Repetir a mesma decisão aplicada é idempotente.
|
|
99
|
+
- `memory rescope` é dry-run por padrão e lista somente IDs, chaves e escopos planejados. Com
|
|
100
|
+
`--apply`, anexa eventos explícitos de projeto, work session, change, branch ou worktree e mantém
|
|
101
|
+
os bytes históricos como prefixo do ledger. Candidates ambíguos não são migrados nem recebem
|
|
102
|
+
vencedor; uma repetição retorna `unchanged`.
|
|
103
|
+
- Registradores como `git.local-head`, `handoff.latest`, `quality.latest-*` e
|
|
104
|
+
`change.<slug>.status` só competem dentro do mesmo escopo. Resolução automática ainda exige o
|
|
105
|
+
mesmo projeto e linhagem causal; decisões, constraints e blockers incompatíveis permanecem sob
|
|
106
|
+
curadoria. Uma chave ambígua é omitida de SHARED sem remover CORE ou chaves independentes.
|
|
107
|
+
- `.brain/EVIDENCE_INDEX.jsonl` divide documentos por headings e blocos e registra arquivo,
|
|
108
|
+
heading, tipo, change, sessão, work session, autoridade, data, validade e hash. `/brain-recall`
|
|
109
|
+
e o hook `UserPromptSubmit` usam BM25, frase exata, pesos por campo, autoridade, validade,
|
|
110
|
+
recência limitada e diversidade para retornar o trecho do match com proveniência.
|
|
98
111
|
- Toda rota de memória valida a topologia física de `.brain`, ledger, outbox, CORE, SHARED,
|
|
99
112
|
candidates, registry, notas, backups, temporários e sidecars antes de ler ou escrever. Junction,
|
|
100
113
|
symlink, reparse point ou hardlink falham fechados sem tocar bytes externos. Locks publicam owner
|
|
@@ -134,6 +147,8 @@ npx wendkeep validate-memory --vault <cofre-v2>
|
|
|
134
147
|
npx wendkeep memory status --gate --vault .MeuApp-vault
|
|
135
148
|
npx wendkeep memory curate --vault .MeuApp-vault
|
|
136
149
|
npx wendkeep memory candidates --active --vault .MeuApp-vault
|
|
150
|
+
npx wendkeep memory rescope --vault .MeuApp-vault
|
|
151
|
+
npx wendkeep memory rescope --apply --vault .MeuApp-vault
|
|
137
152
|
npx wendkeep memory recover-attempt sessao-123 --vault .MeuApp-vault
|
|
138
153
|
npx wendkeep memory recover-attempt sessao-123 --apply --vault .MeuApp-vault
|
|
139
154
|
npx wendkeep memory reconcile antiga --by-session atual --reason "entrega continuada" --vault .MeuApp-vault
|
|
@@ -34,6 +34,7 @@ continuam compatíveis com Node.js 18 ou mais recente. Registre explicitamente c
|
|
|
34
34
|
npx wendkeep observer status --data-dir <diretório> --json
|
|
35
35
|
npx wendkeep observer register --project <projeto> --vault <vault> --data-dir <diretório>
|
|
36
36
|
npx wendkeep observer publish --project <projeto> --vault <vault> --data-dir <diretório>
|
|
37
|
+
npx wendkeep observer reconcile --project <projeto> --vault <vault> --data-dir <diretório> [--url http://127.0.0.1:8787]
|
|
37
38
|
npx wendkeep observer memory import --project <projeto> --vault <vault> --url http://127.0.0.1:8787 --token <token> --json
|
|
38
39
|
npx wendkeep observer serve --host 127.0.0.1 --port 8787 --data-dir <diretório> --token <token>
|
|
39
40
|
```
|
|
@@ -42,7 +43,7 @@ npx wendkeep observer serve --host 127.0.0.1 --port 8787 --data-dir <diretório>
|
|
|
42
43
|
|
|
43
44
|
- `--data-dir` escolhe o diretório local de eventos e índice; o padrão é
|
|
44
45
|
`WENDKEEP_OBSERVER_DATA_DIR` ou `~/.wendkeep-observer`.
|
|
45
|
-
- `--project` e `--vault` identificam o projeto nos comandos `register`, `publish` e `memory import`.
|
|
46
|
+
- `--project` e `--vault` identificam o projeto nos comandos `register`, `publish`, `reconcile` e `memory import`.
|
|
46
47
|
- `--host` aceita somente `127.0.0.1`, `localhost` ou `::1`; outros hosts são recusados antes do
|
|
47
48
|
listen.
|
|
48
49
|
- `--token` ou `WENDKEEP_OBSERVER_TOKEN` autentica mutações; `--allow-non-loopback` falha sem token.
|
|
@@ -85,8 +86,8 @@ Se o navegador mostrar a tela mas a lista falhar, confirme a saúde em
|
|
|
85
86
|
|
|
86
87
|
## Resultado esperado
|
|
87
88
|
|
|
88
|
-
`register` grava `project_id`, nome, versão e data de registro. `publish`
|
|
89
|
-
|
|
89
|
+
`register` grava `project_id`, nome, versão e data de registro. `publish` e `reconcile` fazem a
|
|
90
|
+
varredura integral explícita do vault e enviam eventos idempotentes para o SQLite com o conteúdo integral das sessões,
|
|
90
91
|
decisões, bugs, aprendizados, specs, changes, CORE, DIGEST, SHARED_MEMORY, estado do brain,
|
|
91
92
|
sessões de agentes, rollups de custo e chamadas. Mensagens e transcripts só são enviados nos
|
|
92
93
|
níveis de captura que os habilitam. O container grava tudo em
|
|
@@ -98,10 +99,25 @@ reconciliação quando o ledger detalhado não fecha com ele; essa linha não in
|
|
|
98
99
|
Sessões históricas com o mesmo `session_id` recebem uma identidade canônica por arquivo para
|
|
99
100
|
evitar que um rollup sobrescreva o outro.
|
|
100
101
|
|
|
102
|
+
No schema 5, sessões, agentes, rollups, chamadas e transcripts usam identidades internas derivadas
|
|
103
|
+
de `project_id` + identificador externo, com constraints e foreign keys escopadas. O mesmo
|
|
104
|
+
`session_id`, `agent_id`, `call_id` ou `rollup_key` pode existir em projetos diferentes sem colisão.
|
|
105
|
+
Cada evento é aplicado em um savepoint próprio; falha intermediária reverte ingest e todas as
|
|
106
|
+
projeções antes de o batch continuar. Migrações têm checksum e toda migração estrutural de uma base
|
|
107
|
+
existente cria backup consistente antes da transação.
|
|
108
|
+
|
|
109
|
+
Cada documento ingerido também é projetado em chunks com caminho, heading,
|
|
110
|
+
autoridade, data e validade. O Observer faz um feature probe de FTS5 e usa o índice quando a
|
|
111
|
+
extensão está disponível; caso contrário, mantém a mesma semântica por fallback lexical. A busca
|
|
112
|
+
retorna o trecho em que houve o match e sua proveniência, não apenas o começo do documento.
|
|
113
|
+
|
|
101
114
|
O `init` projeta `observer-publish` para `SessionStart`, `Stop` e `SubagentStop` depois dos hooks
|
|
102
|
-
principais.
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
principais. `SessionStart` apenas drena a fila; `Stop` lê somente a sessão alterada e
|
|
116
|
+
`SubagentStop` somente o transcript do subagente afetado. `note new` e `change archive` enfileiram
|
|
117
|
+
diretamente os documentos que escreveram. Os eventos são coalescidos por escopo e uma lease garante
|
|
118
|
+
um único publisher. Sem servidor disponível, a outbox `.brain/observer-sql-outbox/` é preservada
|
|
119
|
+
sem bloquear a sessão; a varredura integral fica reservada a `observer reconcile`. O `doctor`
|
|
120
|
+
mostra lotes, eventos, bytes e idade da fila. Os lotes SQL são enviados com gzip para que transcripts completos maiores que
|
|
105
121
|
64 MB em JSON puro continuem dentro do limite do transporte; o Observer descomprime e valida o
|
|
106
122
|
corpo antes de ingerir. O outbox é transporte temporário, não autoridade.
|
|
107
123
|
|
|
@@ -109,12 +125,12 @@ corpo antes de ingerir. O outbox é transporte temporário, não autoridade.
|
|
|
109
125
|
|
|
110
126
|
- `project_not_registered`: rode `observer register` antes de publicar.
|
|
111
127
|
- `host loopback`: troque `0.0.0.0` ou endereço LAN por `127.0.0.1`.
|
|
112
|
-
- Outbox pendente: o serviço estava indisponível; preserve `.brain/observer-outbox/` e
|
|
113
|
-
|
|
114
|
-
`.brain/observer-sql-state.json
|
|
128
|
+
- Outbox pendente: o serviço estava indisponível; preserve `.brain/observer-sql-outbox/` e deixe
|
|
129
|
+
um hook posterior drená-la ou rode `observer reconcile`. Adicione também
|
|
130
|
+
`.brain/observer-sql-state.json`, `.brain/observer-sql-outbox/` e `.brain/observer-sql-publisher.lock` ao ignore do Vault. Não apague eventos manualmente.
|
|
115
131
|
- `WENDKEEP_OBSERVER_NODE_UNSUPPORTED`: execute o Observer em Node.js 22.13 ou mais recente.
|
|
116
132
|
- Se a memória ou o consumo ficarem incompletos, verifique a tela Sincronização, preserve o
|
|
117
|
-
outbox e rode `observer
|
|
133
|
+
outbox e rode `observer reconcile` para reconstruir e comprovar paridade por hash.
|
|
118
134
|
|
|
119
135
|
## Próximos passos
|
|
120
136
|
|
|
@@ -140,7 +156,8 @@ corte. As telas do Observer não concluem, arquivam, reparam ou promovem estado.
|
|
|
140
156
|
chamadas e transcripts.
|
|
141
157
|
- `GET /v1/projects/:project_id/memory/tree` — árvore e metadados dos documentos.
|
|
142
158
|
- `GET /v1/projects/:project_id/memory/document?path=...` — conteúdo Markdown integral.
|
|
143
|
-
- `GET /v1/projects/:project_id/memory/search?q=...` — busca
|
|
159
|
+
- `GET /v1/projects/:project_id/memory/search?q=...` — busca ranqueada por chunks, com trecho do
|
|
160
|
+
match e proveniência; usa fallback lexical quando FTS5 não está disponível.
|
|
144
161
|
- `GET /v1/projects/:project_id/sync` — modo, contagem, conflitos e último evento.
|
|
145
162
|
- `PUT /v1/projects/:project_id/sync` — compatibilidade de configuração; a autoridade continua SQL.
|
|
146
163
|
- `GET /v1/projects/:project_id/memory/export` — exportação read-only com conteúdo completo.
|
|
@@ -247,7 +247,7 @@ Entregar uma versão já aprovada sem fabricar outra change:
|
|
|
247
247
|
```bash
|
|
248
248
|
npx wendkeep delivery start release-0-73-0 --source-change governanca-proporcional --allow git:merge --allow git:push --allow publish
|
|
249
249
|
npx wendkeep delivery status release-0-73-0
|
|
250
|
-
npx wendkeep delivery finish release-0-
|
|
250
|
+
npx wendkeep delivery finish release-0-74-0 --target v0.74.0 --ci-url <run> --version 0.74.0 --npm-integrity <sha512> --release-url <release>
|
|
251
251
|
```
|
|
252
252
|
|
|
253
253
|
## Resultado esperado
|
package/hooks/brain-core.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { basename, join } from 'node:path';
|
|
|
5
5
|
import { ensureDir, stripYamlQuotes, toVaultRelative } from './obsidian-common.mjs';
|
|
6
6
|
import { getLocale } from './locale.mjs';
|
|
7
7
|
import { sanitizeMemoryText } from './memory-schema.mjs';
|
|
8
|
+
import { buildEvidenceIndex } from './evidence-recall.mjs';
|
|
8
9
|
|
|
9
10
|
export function brainDir(vaultBase) {
|
|
10
11
|
return join(vaultBase, '.brain');
|
|
@@ -85,6 +86,7 @@ export function buildBrainIndex(vaultBase) {
|
|
|
85
86
|
ensureDir(brainDir(vaultBase));
|
|
86
87
|
const out = rows.map((r) => JSON.stringify(r)).join('\n') + (rows.length ? '\n' : '');
|
|
87
88
|
writeFileSync(join(brainDir(vaultBase), 'index.jsonl'), out, 'utf8');
|
|
89
|
+
buildEvidenceIndex(vaultBase);
|
|
88
90
|
return rows;
|
|
89
91
|
}
|
|
90
92
|
|
package/hooks/brain-recall.mjs
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { getVaultBase } from './obsidian-common.mjs';
|
|
6
6
|
import { loadIndex } from './brain-core.mjs';
|
|
7
|
+
import { loadEvidenceIndex, recallEvidence } from './evidence-recall.mjs';
|
|
7
8
|
|
|
8
9
|
export { loadIndex };
|
|
9
10
|
|
|
10
11
|
export function scoreRows(rows, query, topK = 5) {
|
|
12
|
+
if (rows.some((row) => row?.chunk_id)) return recallEvidence(rows, query, { topK });
|
|
11
13
|
const terms = String(query).toLowerCase().split(/\s+/).filter(Boolean);
|
|
12
14
|
if (!terms.length) return [];
|
|
13
15
|
return rows
|
|
@@ -27,6 +29,8 @@ export function scoreRows(rows, query, topK = 5) {
|
|
|
27
29
|
|
|
28
30
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
29
31
|
const vaultBase = getVaultBase();
|
|
30
|
-
const
|
|
32
|
+
const query = process.argv.slice(2).join(' ');
|
|
33
|
+
const evidence = loadEvidenceIndex(vaultBase);
|
|
34
|
+
const hits = evidence.length ? recallEvidence(evidence, query, { topK: 5 }) : scoreRows(loadIndex(vaultBase), query);
|
|
31
35
|
process.stdout.write(JSON.stringify(hits, null, 2) + '\n');
|
|
32
36
|
}
|