wendkeep 0.68.0 → 0.68.5
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 +67 -0
- package/README.en.md +14 -6
- package/README.md +14 -6
- package/docs/en/commands/changes-and-verification.md +12 -0
- package/docs/en/commands/memory.md +3 -1
- package/docs/en/commands/operating-profiles.md +11 -0
- package/docs/en/commands/sessions-and-import.md +15 -0
- package/docs/pt-BR/commands/changes-and-verification.md +12 -0
- package/docs/pt-BR/commands/memory.md +3 -1
- package/docs/pt-BR/commands/operating-profiles.md +11 -0
- package/docs/pt-BR/commands/sessions-and-import.md +15 -0
- package/hooks/brain-core.mjs +159 -159
- package/hooks/brain-recall.mjs +32 -32
- package/hooks/brain-reindex.mjs +13 -13
- package/hooks/change-guard.mjs +142 -103
- package/hooks/git-snapshot.mjs +25 -6
- package/hooks/obsidian-common.mjs +40 -0
- package/hooks/project-scope.mjs +435 -0
- package/hooks/session-backfill.mjs +1 -1
- package/hooks/session-ensure.mjs +23 -4
- package/hooks/session-iteration-outcome.mjs +143 -0
- package/hooks/session-start.mjs +15 -0
- package/hooks/session-stop.mjs +263 -42
- package/hooks/token-usage.mjs +13 -11
- package/package.json +3 -3
- package/packages/harness/src/flow-store.mjs +12 -3
- package/packages/integrations/src/host-hooks.mjs +7 -7
- package/packages/integrations/src/prompt-content.mjs +12 -0
- package/packages/integrations/src/transcripts.mjs +37 -8
- package/packages/vault/src/memory-store.mjs +63 -1
- package/packages/vault/src/vault-path-safety.mjs +50 -25
- package/src/init.mjs +3 -0
- package/src/memory.mjs +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,73 @@ 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.68.5] — 2026-08-14
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **O Stop passa a deixar um resultado durável por sessão, turno e estágio.** O ledger local,
|
|
12
|
+
append-only,
|
|
13
|
+
sanitizado distingue inserção, duplicata, caminho pulado, abortado, lock ocupado, falha e status
|
|
14
|
+
de observabilidade; o cursor só avança após confirmação da nota.
|
|
15
|
+
- **A importação Codex compartilha a normalização de conteúdo sintético e ferramentas.**
|
|
16
|
+
`subagent_notification` não vira prompt, `turn_aborted` é explícito e a saída de uma
|
|
17
|
+
`custom_tool_call` não é contada como uma segunda chamada.
|
|
18
|
+
- **O encerramento de uma sessão alinha a projeção e a autoridade causal.** O Stop marca a
|
|
19
|
+
activation e a sessão como `done` no `SESSION_REGISTRY.json` somente depois da publicação de
|
|
20
|
+
memória/observabilidade; `CURRENT_SESSION.md` continua sendo uma visão derivada e não lista
|
|
21
|
+
sessões já finalizadas.
|
|
22
|
+
- **O release automático publica no npm por OIDC antes de criar tag e GitHub Release.** O
|
|
23
|
+
`auto-tag.yml` usa Node 24, prepara o registry público, ignora versões já publicadas com
|
|
24
|
+
`--prefer-online` e deixa a provenance ser gerada pela própria publicação confiável.
|
|
25
|
+
|
|
26
|
+
## [0.68.4] — 2026-08-14
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **O guard de escopo do projeto passa a proteger mutações antes da ferramenta.** O `PreToolUse`
|
|
31
|
+
do Codex revalida sessão, projeto, raiz Git, remoto, branch/worktree e concorrência; mantém
|
|
32
|
+
`commit`, `push`, `pull`, `merge`, `publish` e operações destrutivas como capacidades
|
|
33
|
+
independentes, com bloqueio fail-closed para alvos ausentes ou divergentes.
|
|
34
|
+
|
|
35
|
+
## [0.68.3] — 2026-08-13
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **Deferred replay reancora candidates de memória na fonte causal final.** Depois de uma
|
|
40
|
+
promoção legacy válida, um assert moderno reaplicado pelo replay não deixa mais os
|
|
41
|
+
candidates posteriores presos à fonte intermediária. A promoção explícita continua
|
|
42
|
+
exigindo o guard causal e mantém o fail-closed para linhagens incompletas ou ambíguas;
|
|
43
|
+
o ledger permanece append-only.
|
|
44
|
+
|
|
45
|
+
## [0.68.2] — 2026-08-08
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- **O guard do `npm run release` deixa de bloquear a tag criada pelo `auto-tag.yml`.** Os dois
|
|
50
|
+
automatismos assumem ordens opostas: o script publica no npm e então cria a tag, enquanto o
|
|
51
|
+
workflow cria a tag no merge em `main`, antes de qualquer publish. Quando o merge precedia o
|
|
52
|
+
publish — o caminho normal de um PR — o release abortava num estado perfeitamente publicável.
|
|
53
|
+
O guard passa a proteger a unicidade da versão no registry, não a ausência da tag: publica e
|
|
54
|
+
preserva a tag existente quando ela aponta para o commit corrente, e continua abortando se a
|
|
55
|
+
versão já foi lançada ou se a tag aponta para outro commit. A decisão virou função pura, então
|
|
56
|
+
a matriz de estados é verificável sem publicar nem mutar o repositório.
|
|
57
|
+
|
|
58
|
+
## [0.68.1] — 2026-08-08
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- **A contenção de locks do Vault deixa de expor `VAULT_PATH_UNSAFE` no Windows.** A revalidação de
|
|
63
|
+
uma falha transiente de resolução do lock público passa a decidir por um walk fresco do
|
|
64
|
+
componente, e não pelo `errno` reportado pela plataforma. O Windows devolve `UNKNOWN`, `EBADF` ou
|
|
65
|
+
`EPERM` onde o Linux devolve `ENOENT`, então a guarda de retry nunca disparava lá e promoções FLOW
|
|
66
|
+
concorrentes falhavam de forma intermitente com o código de fronteira física em vez do conflito de
|
|
67
|
+
promoção. Sufixo ausente ou diretório canônico estabilizado autorizam o retry; junction, symlink,
|
|
68
|
+
reparse point, componente redirecionado ou estado irresolvível persistente continuam falhando
|
|
69
|
+
fechado, e o orçamento de retry permanece único e limitado por aquisição.
|
|
70
|
+
- **Falha de lock nos caminhos FLOW reporta o código do domínio.** `withFlowPromotionLock` e o store
|
|
71
|
+
de sessão passam a propagar `FLOW_VAULT_BOUNDARY` para a fronteira física, alinhando a superfície
|
|
72
|
+
de erro ao resto da saga de promoção.
|
|
73
|
+
|
|
7
74
|
## [0.68.0] — 2026-08-02
|
|
8
75
|
|
|
9
76
|
### Added
|
package/README.en.md
CHANGED
|
@@ -91,8 +91,11 @@ Decisions, dead ends, the reason you chose X over Y — gone next session. The p
|
|
|
91
91
|
|
|
92
92
|
## Requirements
|
|
93
93
|
|
|
94
|
+
The Codex scope guard treats `commit`, `push`, `pull`, `merge`, `publish`, and destructive
|
|
95
|
+
operations as independent capabilities, including inside compound commands.
|
|
96
|
+
|
|
94
97
|
- Node.js ≥ 18
|
|
95
|
-
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets
|
|
98
|
+
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets eight compatible hooks, including the scoped `PreToolUse` guard, and enumerates them untrusted, so approve its “Hooks need review” prompt once at startup (see [Notes & roadmap](#notes--roadmap))
|
|
96
99
|
- Obsidian (to view the graph) — optional but the point
|
|
97
100
|
|
|
98
101
|
## Install & set up
|
|
@@ -107,7 +110,7 @@ npx wendkeep init
|
|
|
107
110
|
|
|
108
111
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
109
112
|
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.
|
|
110
|
-
3. Wire the Codex
|
|
113
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — eight of the twelve: `brain-inject` + `session-start` on `SessionStart`, `session-ensure` + `change-context` on `UserPromptSubmit`, `session-stop` + `change-nag` on `Stop`, `subagent-stop` 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. 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**.
|
|
111
114
|
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`.)
|
|
112
115
|
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:
|
|
113
116
|
- **`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`.
|
|
@@ -379,8 +382,9 @@ it does not expose memory values or content. After human review,
|
|
|
379
382
|
new promotion accepts a later Stop from the same session/activation without recreating a conflict.
|
|
380
383
|
A promotion written by 0.66.1 remains historical: if the next Stop forms a new candidate, update
|
|
381
384
|
to 0.66.3 and run `memory repair`. During replay, a transient candidate is re-evaluated against the
|
|
382
|
-
final modern source
|
|
383
|
-
|
|
385
|
+
final modern source and, when causal supersession is proven, re-anchored to it; explicit promotion
|
|
386
|
+
uses that anchor and crosses only the physical predecessors required by replay. The same
|
|
387
|
+
session/activation/epoch and a higher turn advances; a lower turn is superseded. Repair migrates the checkpoint and mirror only when it proves the exact previous
|
|
384
388
|
replay, attempt identity, and absence of a real conflict; it creates a backup and audit without
|
|
385
389
|
appending or rewriting events. Ambiguity stays queued for explicit curation. Do not publish or
|
|
386
390
|
install 0.66.2; use 0.66.3 or later. Decisions survive repair/replay;
|
|
@@ -393,7 +397,11 @@ acknowledgement pending on 0.66.4 or later, first run the targeted dry run
|
|
|
393
397
|
registry/checkpoint. See syntax, preconditions, and fail-closed behavior in
|
|
394
398
|
[memory and curation](docs/en/commands/memory.md).
|
|
395
399
|
|
|
396
|
-
Session notes use one live `## Agentes, tokens e custos` snapshot. Main-agent and subagent hooks recompose it atomically, with costs, token dimensions, reasoning tokens and effort per model/source. On Codex, subagent prompts register their rollout for observability without advancing the main agent's sequence; `SubagentStop` reads the child from `agent_transcript_path` and persists its signal only when `parent_thread_id` matches a validated session root. The main Stop uses the registry's causal `turn_id` mapping before falling back to local transcript order. To recover missing markers while a conversation is open, `hook session-backfill` is a dry-run by default and never writes a Codex turn without `task_complete`. Every hook that rewrites a session note takes a per-file lock and writes through a temp file + rename, so the `SubagentStop` fan-out (one hook run per subagent) can never leave a note half-written; a note whose frontmatter reads back damaged is left untouched rather than patched.
|
|
400
|
+
Session notes use one live `## Agentes, tokens e custos` snapshot. Main-agent and subagent hooks recompose it atomically, with costs, token dimensions, reasoning tokens and effort per model/source. On Codex, subagent prompts register their rollout for observability without advancing the main agent's sequence; `SubagentStop` reads the child from `agent_transcript_path` and persists its signal only when `parent_thread_id` matches a validated session root. The main Stop uses the registry's causal `turn_id` mapping before falling back to local transcript order. Every terminal attempt writes a sanitized, idempotent receipt to `.brain/SESSION_ITERATION_OUTCOMES.jsonl`, distinguishing insertion, duplicate, skipped, aborted, busy-lock, failure, and observability status; the cursor advances only after note confirmation. `subagent_notification` is not a human prompt, `turn_aborted` is explicit, and custom tool output is not double-counted. To recover missing markers while a conversation is open, `hook session-backfill` is a dry-run by default and never writes a Codex turn without `task_complete`. Every hook that rewrites a session note takes a per-file lock and writes through a temp file + rename, so the `SubagentStop` fan-out (one hook run per subagent) can never leave a note half-written; a note whose frontmatter reads back damaged is left untouched rather than patched.
|
|
401
|
+
|
|
402
|
+
On definitive close, the activation and session become `done` in `SESSION_REGISTRY.json` only
|
|
403
|
+
after memory/observability publication; `CURRENT_SESSION.md` is a derived view, not the identity
|
|
404
|
+
authority, and does not list finalized sessions.
|
|
397
405
|
|
|
398
406
|
## Retroactive memory (`import`) — install today, remember yesterday
|
|
399
407
|
|
|
@@ -521,7 +529,7 @@ The archive **gate** blocks unless: the change scaffold is filled (G0), no task
|
|
|
521
529
|
- **Vault folder names default to Portuguese** (`02-Sessões`, `04-Decisões`, …). Pass `wendkeep init --locale en` for an English vault (`02-Sessions`, `04-Decisions`, English scaffold/skills). The locale is a vault property, locked at init; parsers are bilingual so mixed content never breaks.
|
|
522
530
|
- **Search is keyword/frontmatter scoring**, not on‑device embeddings (that's on the roadmap).
|
|
523
531
|
- **Transcript formats are agent‑internal** and can change between agent versions; parsing is isolated but may need updates.
|
|
524
|
-
- Installer wires **both agents**: `.claude/settings.json` + `.mcp.json` for Claude Code, `.codex/hooks.json` for Codex. **
|
|
532
|
+
- Installer wires **both agents**: `.claude/settings.json` + `.mcp.json` for Claude Code, `.codex/hooks.json` for Codex. **Eight Codex hooks are compatible**; `change-guard` validates the project lease in `PreToolUse` and denies mutations outside it. The four hooks without an equivalent remain Claude-only: `change-warn`, `plan-capture`, `decision-capture`, and `task-log`.
|
|
525
533
|
- **Codex hooks start untrusted.** They are enumerated but not executed until you approve the “Hooks need review” prompt; `init` cannot pre‑approve them (`--dangerously-bypass-hook-trust` is per‑invocation and stores no trusted hash). Trust is keyed to the hook's identity, so hand‑written wendkeep Codex hooks predating `0.46.0` — which ran at the 600s default because they used `timeout` instead of `timeoutSec` — cost one re‑review after `init` corrects the key. Expected, not a regression. `import --source codex` still backfills past Codex sessions either way.
|
|
526
534
|
|
|
527
535
|
---
|
package/README.md
CHANGED
|
@@ -91,8 +91,11 @@ Decisions, dead ends, the reason you chose X over Y — gone next session. The p
|
|
|
91
91
|
|
|
92
92
|
## Requirements
|
|
93
93
|
|
|
94
|
+
The Codex scope guard treats `commit`, `push`, `pull`, `merge`, `publish`, and destructive
|
|
95
|
+
operations as independent capabilities, including inside compound commands.
|
|
96
|
+
|
|
94
97
|
- Node.js ≥ 18
|
|
95
|
-
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets
|
|
98
|
+
- An AI coding agent with hooks. `init` wires **Claude Code** and **Codex** automatically — Codex gets eight compatible hooks, including the scoped `PreToolUse` guard, and enumerates them untrusted, so approve its “Hooks need review” prompt once at startup (see [Notes & roadmap](#notes--roadmap))
|
|
96
99
|
- Obsidian (to view the graph) — optional but the point
|
|
97
100
|
|
|
98
101
|
## Install & set up
|
|
@@ -107,7 +110,7 @@ npx wendkeep init
|
|
|
107
110
|
|
|
108
111
|
1. Create the vault folder taxonomy and a templated `README.md` (default vault: `<project>/.<project-name>-vault`, e.g. `.MyApp-vault`; override with `--vault`).
|
|
109
112
|
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.
|
|
110
|
-
3. Wire the Codex
|
|
113
|
+
3. Wire the Codex hooks in **`.codex/hooks.json`** — eight of the twelve: `brain-inject` + `session-start` on `SessionStart`, `session-ensure` + `change-context` on `UserPromptSubmit`, `session-stop` + `change-nag` on `Stop`, `subagent-stop` 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. 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**.
|
|
111
114
|
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`.)
|
|
112
115
|
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:
|
|
113
116
|
- **`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`.
|
|
@@ -379,8 +382,9 @@ it does not expose memory values or content. After human review,
|
|
|
379
382
|
new promotion accepts a later Stop from the same session/activation without recreating a conflict.
|
|
380
383
|
A promotion written by 0.66.1 remains historical: if the next Stop forms a new candidate, update
|
|
381
384
|
to 0.66.3 and run `memory repair`. During replay, a transient candidate is re-evaluated against the
|
|
382
|
-
final modern source
|
|
383
|
-
|
|
385
|
+
final modern source and, when causal supersession is proven, re-anchored to it; explicit promotion
|
|
386
|
+
uses that anchor and crosses only the physical predecessors required by replay. The same
|
|
387
|
+
session/activation/epoch and a higher turn advances; a lower turn is superseded. Repair migrates the checkpoint and mirror only when it proves the exact previous
|
|
384
388
|
replay, attempt identity, and absence of a real conflict; it creates a backup and audit without
|
|
385
389
|
appending or rewriting events. Ambiguity stays queued for explicit curation. Do not publish or
|
|
386
390
|
install 0.66.2; use 0.66.3 or later. Decisions survive repair/replay;
|
|
@@ -393,7 +397,11 @@ acknowledgement pending on 0.66.4 or later, first run the targeted dry run
|
|
|
393
397
|
registry/checkpoint. See syntax, preconditions, and fail-closed behavior in
|
|
394
398
|
[memory and curation](docs/en/commands/memory.md).
|
|
395
399
|
|
|
396
|
-
Session notes use one live `## Agentes, tokens e custos` snapshot. Main-agent and subagent hooks recompose it atomically, with costs, token dimensions, reasoning tokens and effort per model/source. On Codex, subagent prompts register their rollout for observability without advancing the main agent's sequence; `SubagentStop` reads the child from `agent_transcript_path` and persists its signal only when `parent_thread_id` matches a validated session root. The main Stop uses the registry's causal `turn_id` mapping before falling back to local transcript order. To recover missing markers while a conversation is open, `hook session-backfill` is a dry-run by default and never writes a Codex turn without `task_complete`. Every hook that rewrites a session note takes a per-file lock and writes through a temp file + rename, so the `SubagentStop` fan-out (one hook run per subagent) can never leave a note half-written; a note whose frontmatter reads back damaged is left untouched rather than patched.
|
|
400
|
+
Session notes use one live `## Agentes, tokens e custos` snapshot. Main-agent and subagent hooks recompose it atomically, with costs, token dimensions, reasoning tokens and effort per model/source. On Codex, subagent prompts register their rollout for observability without advancing the main agent's sequence; `SubagentStop` reads the child from `agent_transcript_path` and persists its signal only when `parent_thread_id` matches a validated session root. The main Stop uses the registry's causal `turn_id` mapping before falling back to local transcript order. Every terminal attempt writes a sanitized, idempotent receipt to `.brain/SESSION_ITERATION_OUTCOMES.jsonl`, distinguishing insertion, duplicate, skipped, aborted, busy-lock, failure, and observability status; the cursor advances only after note confirmation. `subagent_notification` is not a human prompt, `turn_aborted` is explicit, and custom tool output is not double-counted. To recover missing markers while a conversation is open, `hook session-backfill` is a dry-run by default and never writes a Codex turn without `task_complete`. Every hook that rewrites a session note takes a per-file lock and writes through a temp file + rename, so the `SubagentStop` fan-out (one hook run per subagent) can never leave a note half-written; a note whose frontmatter reads back damaged is left untouched rather than patched.
|
|
401
|
+
|
|
402
|
+
On definitive close, the activation and session become `done` in `SESSION_REGISTRY.json` only
|
|
403
|
+
after memory/observability publication; `CURRENT_SESSION.md` is a derived view, not the identity
|
|
404
|
+
authority, and does not list finalized sessions.
|
|
397
405
|
|
|
398
406
|
## Retroactive memory (`import`) — install today, remember yesterday
|
|
399
407
|
|
|
@@ -521,7 +529,7 @@ The archive **gate** blocks unless: the change scaffold is filled (G0), no task
|
|
|
521
529
|
- **Vault folder names default to Portuguese** (`02-Sessões`, `04-Decisões`, …). Pass `wendkeep init --locale en` for an English vault (`02-Sessions`, `04-Decisions`, English scaffold/skills). The locale is a vault property, locked at init; parsers are bilingual so mixed content never breaks.
|
|
522
530
|
- **Search is keyword/frontmatter scoring**, not on‑device embeddings (that's on the roadmap).
|
|
523
531
|
- **Transcript formats are agent‑internal** and can change between agent versions; parsing is isolated but may need updates.
|
|
524
|
-
- Installer wires **both agents**: `.claude/settings.json` + `.mcp.json` for Claude Code, `.codex/hooks.json` for Codex. **
|
|
532
|
+
- Installer wires **both agents**: `.claude/settings.json` + `.mcp.json` for Claude Code, `.codex/hooks.json` for Codex. **Eight Codex hooks are compatible**; `change-guard` validates the project lease in `PreToolUse` and denies mutations outside it. The four hooks without an equivalent remain Claude-only: `change-warn`, `plan-capture`, `decision-capture`, and `task-log`.
|
|
525
533
|
- **Codex hooks start untrusted.** They are enumerated but not executed until you approve the “Hooks need review” prompt; `init` cannot pre‑approve them (`--dangerously-bypass-hook-trust` is per‑invocation and stores no trusted hash). Trust is keyed to the hook's identity, so hand‑written wendkeep Codex hooks predating `0.46.0` — which ran at the 600s default because they used `timeout` instead of `timeoutSec` — cost one re‑review after `init` corrects the key. Expected, not a regression. `import --source codex` still backfills past Codex sessions either way.
|
|
526
534
|
|
|
527
535
|
---
|
|
@@ -70,6 +70,18 @@ npx wendkeep sensors add api-contracts "npm run test:contracts" --severity criti
|
|
|
70
70
|
An archived change promotes its delta into the living spec, preserves proposal/design/tasks/proof,
|
|
71
71
|
and mints an ADR. Archive passes only with closed tasks, green required sensors, and a fresh verdict.
|
|
72
72
|
|
|
73
|
+
## Tool-scope fence
|
|
74
|
+
|
|
75
|
+
`change-guard` is also projected to Codex `PreToolUse`. Before a Git mutation or supported writing
|
|
76
|
+
tool runs, it compares the session, project, Git root, remote, branch, and worktree with the lease
|
|
77
|
+
recorded in `SESSION_REGISTRY.json`. Missing, ambiguous, concurrent, or cross-project targets are
|
|
78
|
+
blocked before the tool.
|
|
79
|
+
|
|
80
|
+
Codex blocks with `permissionDecision: "deny"`; `ask` is not a valid `PreToolUse` decision.
|
|
81
|
+
`commit`, `push`, `pull`, `merge`, `publish`, and destructive operations remain separate capabilities,
|
|
82
|
+
including when one command contains multiple actions. Switching projects requires a new explicit
|
|
83
|
+
selection/lease; never carry authorization from another conversation.
|
|
84
|
+
|
|
73
85
|
## Common errors and diagnosis
|
|
74
86
|
|
|
75
87
|
- `no change`: select one with `change use <slug>` or pass `--change`.
|
|
@@ -108,7 +108,9 @@ npx wendkeep validate-memory --vault <v2-vault>
|
|
|
108
108
|
the already validated JSON value without string coercion and copies the selected event's
|
|
109
109
|
`canonical_session_id`, activation/epoch, `source_turn_id`, and `turn_sequence`. A later Stop
|
|
110
110
|
from the same session/activation therefore advances the value instead of opening another candidate.
|
|
111
|
-
During replay, a transient candidate is re-evaluated
|
|
111
|
+
During replay, a transient candidate is re-evaluated and, when causal supersession is proven,
|
|
112
|
+
re-anchored to the final modern source; explicit promotion uses that new anchor and includes only
|
|
113
|
+
the physical predecessors needed for replay. The same
|
|
112
114
|
session/activation/epoch and a higher turn applies the Stop; a lower turn is superseded. A
|
|
113
115
|
different, incomplete, or ambiguous identity keeps the candidate queued for curation. `memory
|
|
114
116
|
repair` compares the old and current replay and migrates checkpoint+mirror only with exact
|
|
@@ -33,6 +33,17 @@ change.
|
|
|
33
33
|
- For FLOW, a Git repository, a path allowlist, a reason, and at least one existing sensor in
|
|
34
34
|
`wendkeep.sensors.json`.
|
|
35
35
|
|
|
36
|
+
### Tool scope and Git authorization
|
|
37
|
+
|
|
38
|
+
Under `GOVERN`/`ASSURE`, Codex `PreToolUse` and the equivalent Claude gate validate the project lease
|
|
39
|
+
before mutations. The lease includes the session, `project_id`, project root, Git root, remote,
|
|
40
|
+
branch/worktree, and provider. `commit`, `push`, `pull`, `merge`, `publish`, and destructive operations
|
|
41
|
+
are independent capabilities, including in compound commands; authorization never crosses projects or
|
|
42
|
+
branches.
|
|
43
|
+
|
|
44
|
+
If the host does not expose the effective directory, or the session is conflicted, the mutation is
|
|
45
|
+
denied with a sanitized diagnostic. Read-only inspection may continue for investigation.
|
|
46
|
+
|
|
36
47
|
## Syntax
|
|
37
48
|
|
|
38
49
|
```bash
|
|
@@ -63,6 +63,13 @@ npx wendkeep import [options]
|
|
|
63
63
|
- Observability is tri-state: `complete` publishes the full snapshot; `none` means zero proven by
|
|
64
64
|
a causal Stop or stable offline scan; `degraded` preserves the previous snapshot and allowlisted
|
|
65
65
|
diagnostics. An isolated `SubagentStop` never publishes `none`.
|
|
66
|
+
- Every terminal `Stop`/`SubagentStop` attempt leaves a sanitized receipt in
|
|
67
|
+
`.brain/SESSION_ITERATION_OUTCOMES.jsonl`, keyed by session, `turn_id`, and stage. States
|
|
68
|
+
distinguish `inserted`, `duplicate`, `skipped`, `aborted`, `busy`, `failed`, and observability
|
|
69
|
+
statuses; the cursor advances only after the note is confirmed. The ledger is local, append-only,
|
|
70
|
+
idempotent, and never persists prompts, payloads, raw arguments, or raw errors.
|
|
71
|
+
- In Codex, `subagent_notification` remains synthetic, `turn_aborted` is an explicit terminal
|
|
72
|
+
state, and `custom_tool_call_output` closes the existing call without counting a second tool.
|
|
66
73
|
- When compacting conversations into `## Iterações`, the hook escapes code delimiters cut by the
|
|
67
74
|
size limit; inline backticks and fences never remain open and consume the following line.
|
|
68
75
|
- `session list` reads `SESSION_REGISTRY`; `show` displays one session and `use` only changes human
|
|
@@ -73,6 +80,10 @@ npx wendkeep import [options]
|
|
|
73
80
|
- `import` reconciles observability even when no `wk-turn` is missing: a legacy schema, stale
|
|
74
81
|
frontier, or unproven manifest triggers recomposition without duplicating iterations. A fresh
|
|
75
82
|
checkpoint remains byte-identical; `degraded` is reported and does not change the note.
|
|
83
|
+
- On definitive close, Stop marks the activation and session `done` in `SESSION_REGISTRY.json`
|
|
84
|
+
only after memory/observability publication; `CURRENT_SESSION.md` is a derived view and no
|
|
85
|
+
longer lists the finalized session. Hooks resolve identity from the registry and transcript,
|
|
86
|
+
never from the global pointer.
|
|
76
87
|
- `hook session-backfill` recovers missing `wk-turn` markers for the selected session. Without
|
|
77
88
|
`--write`, it only reports. On Codex, `missingTurns` contains only turns with `task_complete`;
|
|
78
89
|
open turns appear under `incompleteTurns` and are never written. `--write` applies only completed
|
|
@@ -105,6 +116,8 @@ only recognized generated fields under `Iterações` and `Encerramento` are migr
|
|
|
105
116
|
authored prose.
|
|
106
117
|
Duplicate/stale hooks converge on the same frontier, and imports may refresh only observability
|
|
107
118
|
without creating a new turn block.
|
|
119
|
+
The per-attempt receipt in `SESSION_ITERATION_OUTCOMES.jsonl` distinguishes a confirmed duplicate
|
|
120
|
+
from a busy lock or skipped path without reopening the original session.
|
|
108
121
|
|
|
109
122
|
## Common errors and diagnosis
|
|
110
123
|
|
|
@@ -122,6 +135,8 @@ without creating a new turn block.
|
|
|
122
135
|
- Contaminated cost: validate `session_id → session_file → transcript_path → provider`.
|
|
123
136
|
- `degraded` observability: preserve the note and run a targeted rebuild dry-run; never force a
|
|
124
137
|
partial snapshot over the last `complete` one.
|
|
138
|
+
- Missing or `busy` outcome ledger: preserve the transcript and note, inspect the Vault lock, and
|
|
139
|
+
retry the bounded hook/replay path; never mark the turn projected by hand.
|
|
125
140
|
|
|
126
141
|
## Next steps
|
|
127
142
|
|
|
@@ -70,6 +70,18 @@ npx wendkeep sensors add api-contracts "npm run test:contracts" --severity criti
|
|
|
70
70
|
A change arquivada move seu delta para o spec vivo, preserva proposta/design/tarefas/evidência e
|
|
71
71
|
gera um ADR. O archive só passa com tarefas fechadas, sensores exigidos verdes e verdict atual.
|
|
72
72
|
|
|
73
|
+
## Cerca de escopo para ferramentas
|
|
74
|
+
|
|
75
|
+
O `change-guard` também é projetado para o `PreToolUse` do Codex. Antes de uma mutação Git ou de
|
|
76
|
+
uma ferramenta de escrita suportada, ele compara sessão, projeto, raiz Git, remoto, branch e
|
|
77
|
+
worktree com a lease registrada no `SESSION_REGISTRY.json`. Um alvo ausente, ambíguo, concorrente ou
|
|
78
|
+
fora do projeto é bloqueado antes da ferramenta.
|
|
79
|
+
|
|
80
|
+
No Codex o bloqueio usa `permissionDecision: "deny"`; `ask` não é uma decisão válida de
|
|
81
|
+
`PreToolUse`. `commit`, `push`, `pull`, `merge`, `publish` e operações destrutivas continuam
|
|
82
|
+
capacidades separadas, inclusive quando um comando contém mais de uma ação. A troca de projeto
|
|
83
|
+
exige uma nova seleção/lease; não use autorização de outra conversa.
|
|
84
|
+
|
|
73
85
|
## Erros comuns e diagnóstico
|
|
74
86
|
|
|
75
87
|
- `no change`: selecione com `change use <slug>` ou informe `--change`.
|
|
@@ -106,7 +106,9 @@ npx wendkeep validate-memory --vault <cofre-v2>
|
|
|
106
106
|
A decisão conserva, sem coerção para string, o valor JSON já validado e copia do evento escolhido
|
|
107
107
|
`canonical_session_id`, activation/epoch, `source_turn_id` e `turn_sequence`. Por isso, um Stop
|
|
108
108
|
posterior da mesma sessão/activation avança o valor em vez de abrir outro candidate. Durante o
|
|
109
|
-
replay, um candidate transitório é reavaliado
|
|
109
|
+
replay, um candidate transitório é reavaliado e, quando a supersession causal é provada,
|
|
110
|
+
reancorado contra a fonte moderna final; a promoção explícita usa essa nova âncora e inclui
|
|
111
|
+
somente os predecessores físicos necessários. Mesma
|
|
110
112
|
sessão/activation/epoch e turno maior aplica o Stop; turno menor fica superseded. Identidade
|
|
111
113
|
divergente, incompleta ou ambígua mantém o candidate para curadoria. `memory repair` compara o
|
|
112
114
|
replay anterior e o atual e só migra checkpoint+espelho com identidade exata, backup, audit e
|
|
@@ -33,6 +33,17 @@ gates/policies do WendKeep; promova o trabalho para uma change.
|
|
|
33
33
|
- Para FLOW, repositório Git, allowlist de paths, motivo e ao menos um sensor existente em
|
|
34
34
|
`wendkeep.sensors.json`.
|
|
35
35
|
|
|
36
|
+
### Escopo de ferramenta e autorização Git
|
|
37
|
+
|
|
38
|
+
Em `GOVERN`/`ASSURE`, o `PreToolUse` do Codex e o gate equivalente do Claude validam a lease de
|
|
39
|
+
projeto antes de mutações. A lease inclui sessão, `project_id`, raiz do projeto, raiz Git, remoto,
|
|
40
|
+
branch/worktree e provider. `commit`, `push`, `pull`, `merge`, `publish` e operações destrutivas são
|
|
41
|
+
capacidades independentes, inclusive em comandos compostos; uma autorização não atravessa projetos
|
|
42
|
+
nem branches.
|
|
43
|
+
|
|
44
|
+
Se o host não expuser o diretório efetivo, ou se a sessão estiver em conflito, a mutação é negada
|
|
45
|
+
com diagnóstico sanitizado. Somente leitura pode continuar para investigação.
|
|
46
|
+
|
|
36
47
|
## Sintaxe
|
|
37
48
|
|
|
38
49
|
```bash
|
|
@@ -62,6 +62,13 @@ npx wendkeep import [opções]
|
|
|
62
62
|
- A observabilidade usa tri-state: `complete` publica o snapshot integral; `none` representa zero
|
|
63
63
|
comprovado por Stop causal ou scan offline estável; `degraded` preserva o snapshot anterior e
|
|
64
64
|
diagnostics allowlisted. `SubagentStop` isolado nunca publica `none`.
|
|
65
|
+
- Cada tentativa terminal de `Stop`/`SubagentStop` deixa um recibo sanitizado em
|
|
66
|
+
`.brain/SESSION_ITERATION_OUTCOMES.jsonl`, indexado por sessão, `turn_id` e estágio. Os estados
|
|
67
|
+
distinguem `inserted`, `duplicate`, `skipped`, `aborted`, `busy`, `failed` e os status de
|
|
68
|
+
observabilidade; o cursor só avança depois da confirmação da nota. O ledger é local, append-only,
|
|
69
|
+
idempotente e nunca persiste prompt, payload, argumento bruto ou erro bruto.
|
|
70
|
+
- No Codex, `subagent_notification` continua sintético, `turn_aborted` é terminal explícito e
|
|
71
|
+
`custom_tool_call_output` fecha a chamada existente sem contar uma segunda ferramenta.
|
|
65
72
|
- Ao compactar conversas em `## Iterações`, o hook escapa delimitadores de código cortados pelo
|
|
66
73
|
limite de tamanho; backticks inline ou fences nunca ficam abertos para engolir a linha seguinte.
|
|
67
74
|
- `session list` lê `SESSION_REGISTRY`; `show` exibe uma sessão e `use` muda apenas o foco humano
|
|
@@ -72,6 +79,10 @@ npx wendkeep import [opções]
|
|
|
72
79
|
- `import` reconcilia a observabilidade mesmo quando nenhum `wk-turn` está ausente: schema legado,
|
|
73
80
|
frontier stale ou manifest não comprovado disparam recomposição sem duplicar iterações. Um
|
|
74
81
|
checkpoint fresco permanece byte-idêntico; `degraded` é reportado e não altera a nota.
|
|
82
|
+
- No encerramento definitivo, o Stop fecha a activation e a sessão como `done` no
|
|
83
|
+
`SESSION_REGISTRY.json` depois de memória/observabilidade; `CURRENT_SESSION.md` é uma visão
|
|
84
|
+
derivada e deixa de listar a sessão finalizada. Hooks resolvem identidade pelo registry e pelo
|
|
85
|
+
transcript, nunca pelo ponteiro global.
|
|
75
86
|
- `hook session-backfill` recupera `wk-turn` ausente da sessão selecionada. Sem `--write`, apenas
|
|
76
87
|
relata. Em Codex, `missingTurns` contém somente turnos com `task_complete`; turnos ainda abertos
|
|
77
88
|
aparecem em `incompleteTurns` e nunca são gravados. `--write` aplica apenas os candidatos
|
|
@@ -104,6 +115,8 @@ ao finalizar uma nota antiga, somente campos gerados reconhecíveis em `Iteraç
|
|
|
104
115
|
`Encerramento` são migrados, sem reescrever a prosa autoral. Hooks
|
|
105
116
|
duplicados/stale convergem no mesmo frontier, e importações podem atualizar só a observabilidade
|
|
106
117
|
sem criar um novo bloco de turno.
|
|
118
|
+
O recibo de cada tentativa em `SESSION_ITERATION_OUTCOMES.jsonl` permite diferenciar uma duplicata
|
|
119
|
+
confirmada de um lock ocupado ou de um caminho que foi pulado, sem reabrir a sessão original.
|
|
107
120
|
|
|
108
121
|
## Erros comuns e diagnóstico
|
|
109
122
|
|
|
@@ -121,6 +134,8 @@ sem criar um novo bloco de turno.
|
|
|
121
134
|
- Custo contaminado: valide `session_id → session_file → transcript_path → provider`.
|
|
122
135
|
- Observabilidade `degraded`: preserve a nota e rode o rebuild direcionado em dry-run; não force
|
|
123
136
|
um snapshot parcial sobre o último `complete`.
|
|
137
|
+
- Ledger de resultado ausente ou com `busy`: preserve o transcript e a nota, confira o lock do Vault
|
|
138
|
+
e repita o hook/replay limitado; nunca marque o turno como projetado manualmente.
|
|
124
139
|
|
|
125
140
|
## Próximos passos
|
|
126
141
|
|