wendkeep 0.58.1 → 0.59.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/README.en.md +70 -40
  3. package/README.md +70 -40
  4. package/bin/wendkeep.mjs +54 -6
  5. package/docs/en/commands/changes-and-verification.md +85 -0
  6. package/docs/en/commands/costs-and-observability.md +65 -0
  7. package/docs/en/commands/getting-started.md +86 -0
  8. package/docs/en/commands/maintenance-and-diagnostics.md +77 -0
  9. package/docs/en/commands/memory-migration.md +73 -0
  10. package/docs/en/commands/memory.md +102 -0
  11. package/docs/en/commands/notes-and-knowledge.md +70 -0
  12. package/docs/en/commands/operating-profiles.md +173 -0
  13. package/docs/en/commands/retroactive-import.md +67 -0
  14. package/docs/en/commands/sessions-and-import.md +89 -0
  15. package/docs/en/commands/verify.md +92 -0
  16. package/docs/pt-BR/commands/changes-and-verification.md +85 -0
  17. package/docs/pt-BR/commands/costs-and-observability.md +65 -0
  18. package/docs/pt-BR/commands/getting-started.md +87 -0
  19. package/docs/pt-BR/commands/maintenance-and-diagnostics.md +77 -0
  20. package/docs/pt-BR/commands/memory-migration.md +73 -0
  21. package/docs/pt-BR/commands/memory.md +99 -0
  22. package/docs/pt-BR/commands/notes-and-knowledge.md +69 -0
  23. package/docs/pt-BR/commands/operating-profiles.md +171 -0
  24. package/docs/pt-BR/commands/retroactive-import.md +67 -0
  25. package/docs/pt-BR/commands/sessions-and-import.md +89 -0
  26. package/docs/pt-BR/commands/verify.md +93 -0
  27. package/hooks/brain-core.mjs +159 -159
  28. package/hooks/brain-inject.mjs +83 -26
  29. package/hooks/brain-recall.mjs +32 -32
  30. package/hooks/brain-reindex.mjs +13 -13
  31. package/hooks/change-context.mjs +24 -10
  32. package/hooks/change-core.mjs +174 -37
  33. package/hooks/change-guard.mjs +115 -16
  34. package/hooks/change-nag.mjs +20 -5
  35. package/hooks/change-warn.mjs +27 -9
  36. package/hooks/decision-capture.mjs +1 -1
  37. package/hooks/derived-sections.mjs +1 -1
  38. package/hooks/flow-core.mjs +891 -0
  39. package/hooks/flow-protected-policy.mjs +218 -0
  40. package/hooks/frontmatter-repair.mjs +3 -1
  41. package/hooks/git-snapshot.mjs +722 -0
  42. package/hooks/import-sessions.mjs +10 -5
  43. package/hooks/memory-mode.mjs +63 -13
  44. package/hooks/memory-store.mjs +309 -69
  45. package/hooks/obsidian-common.mjs +119 -84
  46. package/hooks/operating-profile-runtime.mjs +157 -0
  47. package/hooks/plan-capture.mjs +14 -3
  48. package/hooks/sensors-core.mjs +15 -3
  49. package/hooks/session-backfill.mjs +7 -2
  50. package/hooks/session-ensure.mjs +21 -12
  51. package/hooks/session-iteration.mjs +65 -0
  52. package/hooks/session-memory-lifecycle.mjs +335 -0
  53. package/hooks/session-note-io.mjs +130 -15
  54. package/hooks/session-observability.mjs +4 -2
  55. package/hooks/session-stop.mjs +181 -59
  56. package/hooks/spec-core.mjs +91 -12
  57. package/hooks/subagent-stop.mjs +4 -1
  58. package/hooks/subagent-usage.mjs +2 -2
  59. package/hooks/task-log.mjs +3 -1
  60. package/hooks/token-usage.mjs +1 -1
  61. package/hooks/vault-health.mjs +268 -25
  62. package/hooks/vault-path-safety.mjs +558 -0
  63. package/hooks/vault-runtime-store.mjs +558 -0
  64. package/package.json +5 -3
  65. package/src/change.mjs +2 -1
  66. package/src/flow.mjs +232 -0
  67. package/src/init.mjs +26 -3
  68. package/src/memory.mjs +785 -35
  69. package/src/operating-profile.mjs +133 -0
  70. package/src/profile.mjs +224 -0
  71. package/src/project-vault.mjs +110 -5
  72. package/src/rebuild-costs.mjs +11 -4
  73. package/src/skills-seed.mjs +38 -16
  74. package/src/sync-defs.mjs +16 -7
  75. package/src/sync.mjs +9 -1
  76. package/src/taxonomy.mjs +9 -0
  77. package/src/validate-memory.mjs +21 -8
  78. package/src/verify.mjs +12 -2
package/src/sync-defs.mjs CHANGED
@@ -58,14 +58,23 @@ function renderAgentsSection(skills, sourceHash = '') {
58
58
  const list = skills.map((s) => `- **${s.name}** — ${s.description}`).join('\n');
59
59
  return `${AG_START}
60
60
  <!-- wendkeep-version: ${WENDKEEP_VERSION}; skills-sha256: ${sourceHash} -->
61
- ## wendkeep — process skills & loop
61
+ ## wendkeep — Keep Core & operating profiles
62
62
 
63
- This project uses the [wendkeep](https://github.com/rogersialves/wendkeep) harness. Work
64
- through its change loop: \`wendkeep change new <slug>\` implement tasks test-first
65
- (tag proof \`[sensor:id]\` and requirement \`[req:ID]\`) \`wendkeep verify\`
66
- \`wendkeep verify --deep\` + an independent read-only verification pass writing
67
- \`verdict.json\` \`wendkeep change archive\` (gated). Inspect with \`wendkeep change
68
- status\` / \`spec effective --change <slug>\` / \`sensors list\`. Author specs only in
63
+ This project uses the [wendkeep](https://github.com/rogersialves/wendkeep) harness. **Keep Core is always active**
64
+ in every profile: Vault, session, identity, memory, lessons, and persistence integrations.
65
+ The effective profile is selected explicitly; missing or invalid configuration uses **GOVERN as the default**.
66
+
67
+ Route work by the effective profile:
68
+ - **OFF** Wend Runtime is disabled and governance belongs to the native LLM harness; Keep Core stays active.
69
+ - **FLOW** — Execute → Validate through \`wendkeep flow start/finish\`, without creating a change.
70
+ - **GUIDE** — Plan → Execute → Validate through a compact change.
71
+ - **GOVERN** — the default a2 loop: \`wendkeep change new <slug>\` → review → implement tasks test-first
72
+ (tag proof \`[sensor:id]\` and requirement \`[req:ID]\`) → \`wendkeep verify\` →
73
+ \`wendkeep verify --deep\` + independent read-only verdict → \`wendkeep change archive\`.
74
+ - **ASSURE** — GOVERN plus explicit confirmation and handoff.
75
+
76
+ Inspect with \`wendkeep profile status\` / \`wendkeep change status\` /
77
+ \`spec effective --change <slug>\` / \`sensors list\`. Author specs only in
69
78
  \`08-Mudanças/<slug>/specs/\`; \`07-Specs\` is generated and must not be edited directly.
70
79
 
71
80
  Process skills (full text in \`.claude/skills/\`, \`.agents/skills/\`, and the vault's \`.brain/skills/\`):
package/src/sync.mjs CHANGED
@@ -22,6 +22,9 @@ const step = (n, label) => process.stdout.write(`\n[${n}/3] ${label}\n`);
22
22
  export async function runSync(argv) {
23
23
  const projectRaw = opt(argv, '--project');
24
24
  const vaultRaw = opt(argv, '--vault');
25
+ const hasProfile = argv.includes('--profile') || argv.some((a) => a.startsWith('--profile='));
26
+ const profileRaw = opt(argv, '--profile');
27
+ const profileArgs = hasProfile ? ['--profile', profileRaw] : [];
25
28
  const projectPath = resolve(projectRaw && !projectRaw.startsWith('--') ? projectRaw : process.cwd());
26
29
  const passthrough = argv.filter((a) => a === '--yes' || a === '-y' || a === '--force');
27
30
 
@@ -29,7 +32,12 @@ export async function runSync(argv) {
29
32
  step(1, 'init');
30
33
  const { runInit } = await import('./init.mjs');
31
34
  try {
32
- await runInit(['--project', projectPath, ...(vaultRaw ? ['--vault', vaultRaw] : []), ...passthrough]);
35
+ await runInit([
36
+ '--project', projectPath,
37
+ ...(vaultRaw ? ['--vault', vaultRaw] : []),
38
+ ...profileArgs,
39
+ ...passthrough,
40
+ ]);
33
41
  } catch (error) {
34
42
  process.stderr.write(`wendkeep sync: init falhou — ${error.message}\n`);
35
43
  return 1;
package/src/taxonomy.mjs CHANGED
@@ -37,6 +37,15 @@ export const HOOK_FILES = [
37
37
  'memory-schema.mjs',
38
38
  'memory-store.mjs',
39
39
  'memory-handoff.mjs',
40
+ 'session-memory-lifecycle.mjs',
41
+ 'session-note-io.mjs',
42
+ 'operating-profile-runtime.mjs',
43
+ 'git-snapshot.mjs',
44
+ 'flow-protected-policy.mjs',
45
+ 'session-iteration.mjs',
46
+ 'vault-path-safety.mjs',
47
+ 'vault-runtime-store.mjs',
48
+ 'flow-core.mjs',
40
49
  'change-core.mjs',
41
50
  'spec-core.mjs',
42
51
  'sensors-core.mjs',
@@ -1,16 +1,29 @@
1
- import { existsSync, readFileSync } from 'node:fs';
1
+ import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { validateMemoryEvent, validateSharedMemory } from '../hooks/memory-schema.mjs';
4
+ import { assertVaultPathSafe } from '../hooks/vault-path-safety.mjs';
4
5
  import { validateCore } from './validate-core.mjs';
5
6
 
6
7
  function failedComponent(errors, extra = {}) {
7
8
  return { ok: false, errors: Array.isArray(errors) ? errors : [errors], warnings: [], ...extra };
8
9
  }
9
10
 
10
- function readRequired(path, label) {
11
- if (!existsSync(path)) return { ok: false, error: `${label} ausente: ${path}` };
11
+ function readRequired(vaultBase, path, label) {
12
+ let checked;
12
13
  try {
13
- return { ok: true, content: readFileSync(path, 'utf8') };
14
+ checked = assertVaultPathSafe(vaultBase, path, {
15
+ expectedType: 'file', label: `artefato ${label}`,
16
+ });
17
+ } catch (error) {
18
+ return { ok: false, error: `${label} inseguro: ${error?.message || error}` };
19
+ }
20
+ if (!checked.exists) return { ok: false, error: `${label} ausente: ${path}` };
21
+ try {
22
+ // Deliberately adjacent to the open performed by readFileSync.
23
+ checked = assertVaultPathSafe(vaultBase, checked.target, {
24
+ allowMissing: false, expectedType: 'file', label: `artefato ${label}`,
25
+ });
26
+ return { ok: true, content: readFileSync(checked.target, 'utf8') };
14
27
  } catch (error) {
15
28
  return { ok: false, error: `${label} ilegível: ${error?.message || error}` };
16
29
  }
@@ -18,7 +31,7 @@ function readRequired(path, label) {
18
31
 
19
32
  export function readProjectForValidation(vaultBase) {
20
33
  const path = join(vaultBase, '.brain', 'PROJECT.json');
21
- const read = readRequired(path, 'PROJECT.json');
34
+ const read = readRequired(vaultBase, path, 'PROJECT.json');
22
35
  if (!read.ok) return failedComponent(read.error, { projectId: '', path });
23
36
  try {
24
37
  const marker = JSON.parse(read.content);
@@ -34,7 +47,7 @@ export function readProjectForValidation(vaultBase) {
34
47
  /** Read and validate the append-only JSONL authority without repairing or mutating it. */
35
48
  export function readLedgerForValidation(vaultBase, { projectId } = {}) {
36
49
  const path = join(vaultBase, '.brain', 'MEMORY_EVENTS.jsonl');
37
- const read = readRequired(path, 'MEMORY_EVENTS.jsonl');
50
+ const read = readRequired(vaultBase, path, 'MEMORY_EVENTS.jsonl');
38
51
  if (!read.ok) return failedComponent(read.error, { events: [], eventIds: new Set(), path });
39
52
 
40
53
  const errors = [];
@@ -79,14 +92,14 @@ export function readLedgerForValidation(vaultBase, { projectId } = {}) {
79
92
 
80
93
  function validateCoreArtifact(vaultBase) {
81
94
  const path = join(vaultBase, '.brain', 'CORE.md');
82
- const read = readRequired(path, 'CORE.md');
95
+ const read = readRequired(vaultBase, path, 'CORE.md');
83
96
  if (!read.ok) return failedComponent(read.error, { lineCount: 0, path });
84
97
  return { ...validateCore(read.content), path, content: read.content };
85
98
  }
86
99
 
87
100
  function validateSharedArtifact(vaultBase, eventIds) {
88
101
  const path = join(vaultBase, '.brain', 'SHARED_MEMORY.md');
89
- const read = readRequired(path, 'SHARED_MEMORY.md');
102
+ const read = readRequired(vaultBase, path, 'SHARED_MEMORY.md');
90
103
  if (!read.ok) return failedComponent(read.error, { path });
91
104
  return { ...validateSharedMemory(read.content, { eventIds }), path, content: read.content };
92
105
  }
package/src/verify.mjs CHANGED
@@ -4,7 +4,14 @@
4
4
  import { readFileSync, unlinkSync, writeFileSync } from 'node:fs';
5
5
  import { isAbsolute, join, resolve } from 'node:path';
6
6
  import { parseTasks, activeChange, appendFixTasks, healSpecBacklinks } from '../hooks/change-core.mjs';
7
- import { loadSensorsDetailed, findProjectRoot, requiredSensors, runSensors, evaluateGate } from '../hooks/sensors-core.mjs';
7
+ import {
8
+ loadSensorsDetailed,
9
+ findProjectRoot,
10
+ requiredSensors,
11
+ runSensors,
12
+ evaluateGate,
13
+ sensorProcessEnv,
14
+ } from '../hooks/sensors-core.mjs';
8
15
  import {
9
16
  buildEffectiveRequirementPackage,
10
17
  captureSpecBaseline,
@@ -54,7 +61,10 @@ export function runVerify(argv) {
54
61
  process.stderr.write(`wendkeep verify: wendkeep.sensors.json não encontrado em ${loaded.path} — rode da raiz do projeto ou use --project <raiz>\n`);
55
62
  }
56
63
  const sensors = loaded.sensors;
57
- const evidence = runSensors(sensors, ids, { cwd: projectRoot });
64
+ const evidence = runSensors(sensors, ids, {
65
+ cwd: projectRoot,
66
+ env: sensorProcessEnv(vaultBase),
67
+ });
58
68
  writeFileSync(join(changeDir, 'evidencia.json'), `${JSON.stringify(evidence, null, 2)}\n`, 'utf8');
59
69
  // Freshness seal: bind this evidence to the tarefas.md it was produced against, so the archive
60
70
  // gate can reject evidence gone stale (a sensor task added after this verify run).