suemo 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/package.json +4 -2
- package/skills/suemo/SKILL.md +26 -1
- package/skills/suemo/references/agents-snippet.md +20 -9
- package/skills/suemo/references/cli-reference.md +7 -2
- package/skills/suemo/references/core-workflow.md +38 -10
- package/skills/suemo/references/manual-test-plan.md +17 -6
- package/skills/suemo/references/mcp-reference.md +9 -1
- package/skills/suemo/references/schema-retention-longevity.md +1 -1
- package/skills/suemo/references/sync-local-vps.md +1 -1
- package/src/AGENTS.md +84 -104
- package/src/cli/commands/believe.ts +3 -0
- package/src/cli/commands/health.ts +2 -2
- package/src/cli/commands/init.ts +27 -1
- package/src/cli/commands/recall.ts +29 -1
- package/src/cli/commands/serve.ts +12 -0
- package/src/cli/index.ts +20 -0
- package/src/cognitive/consolidate.ts +6 -1
- package/src/cognitive/health.ts +25 -3
- package/src/db/client.ts +29 -26
- package/src/db/engines.ts +113 -0
- package/src/db/preflight.ts +56 -27
- package/src/db/schema.surql +7 -0
- package/src/mcp/dispatch.ts +45 -9
- package/src/mcp/server.ts +14 -1
- package/src/mcp/stdio.ts +35 -6
- package/src/memory/episode.ts +153 -7
- package/src/memory/fsrs.ts +237 -0
- package/src/memory/read.ts +191 -23
- package/src/memory/write.ts +46 -22
- package/src/opencode/plugin.ts +226 -0
- package/src/sync.ts +20 -17
- package/src/types.ts +9 -2
package/README.md
CHANGED
|
@@ -11,6 +11,26 @@
|
|
|
11
11
|
|
|
12
12
|
suemo gives AI agents a memory that survives across sessions, models, and runtimes. Write observations from a Telegram bot, query them from OpenCode, consolidate overnight — all agents share one source of truth in SurrealDB.
|
|
13
13
|
|
|
14
|
+
Specifications:
|
|
15
|
+
|
|
16
|
+
- Index: **[`specs/SPEC.md`](./specs/SPEC.md)**
|
|
17
|
+
- Technical/runtime contract: **[`specs/SPEC-technical.md`](./specs/SPEC-technical.md)**
|
|
18
|
+
- Psychological/critique framing: **[`specs/SPEC-psychological.md`](./specs/SPEC-psychological.md)**
|
|
19
|
+
|
|
20
|
+
## For professional critique authors (longevity-focused)
|
|
21
|
+
|
|
22
|
+
If you're designing high-quality external critiques for suemo, evaluate it as **persistent coding-agent memory infrastructure**, not as a general AGI cognition claim.
|
|
23
|
+
|
|
24
|
+
Use this framing:
|
|
25
|
+
|
|
26
|
+
1. **Psychological intent** — what memory quality should hold over time?
|
|
27
|
+
2. **Technical mechanism** — what exact table/field/tool enforces that quality?
|
|
28
|
+
3. **Operational evidence** — what logs/tests/metrics prove it under drift and contradiction?
|
|
29
|
+
|
|
30
|
+
Questions are most useful when they stress long-horizon behavior (30–180 day operation), contradiction handling, consolidation quality, retrieval interference, and scope/session isolation.
|
|
31
|
+
|
|
32
|
+
For rigorous critique language and category framing, start from **[`specs/SPEC-psychological.md`](./specs/SPEC-psychological.md)**.
|
|
33
|
+
|
|
14
34
|
---
|
|
15
35
|
|
|
16
36
|
## Features
|
|
@@ -445,6 +465,27 @@ This prints your active target (`url`, `namespace`, `database`) and step-by-step
|
|
|
445
465
|
|
|
446
466
|
Agents never supply temporal fields (`valid_from`, `valid_until`). These are system-managed.
|
|
447
467
|
|
|
468
|
+
### Memory field semantics (quick reference)
|
|
469
|
+
|
|
470
|
+
- `content`: canonical memory payload.
|
|
471
|
+
- `summary`: optional condensed text for compact retrieval/consolidation. It does **not** replace `content`.
|
|
472
|
+
- `source`: optional provenance label (free-form string), e.g. `prompt-capture`, `consolidation:nrem`.
|
|
473
|
+
- `prompt_source`: optional pointer to the prompt memory record that originated a derived memory.
|
|
474
|
+
- `fsrs_next_review`: optional review timestamp; currently set on `recall()` (not on every ingest).
|
|
475
|
+
|
|
476
|
+
### Episode `memory_ids`
|
|
477
|
+
|
|
478
|
+
`episode.memory_ids` stores memory IDs attached to an open session, used for session reconstruction.
|
|
479
|
+
|
|
480
|
+
If you rarely see it populated, the typical reason is missing `sessionId` on write calls.
|
|
481
|
+
Current behavior: only write paths invoked with `sessionId` append to `memory_ids`.
|
|
482
|
+
`believe` now supports session linkage too:
|
|
483
|
+
|
|
484
|
+
- CLI: `suemo believe "..." --session <sessionId>`
|
|
485
|
+
- MCP: `believe({ content, sessionId, ... })`
|
|
486
|
+
|
|
487
|
+
See `specs/SPEC-technical.md` for full normative semantics and hardening targets.
|
|
488
|
+
|
|
448
489
|
### Scope and longevity notes
|
|
449
490
|
|
|
450
491
|
- Default inferred project scope now uses nearest `<projectDir>/suemo.json` with `main.projectDir` defaulting to `.ua`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suemo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Persistent semantic memory for AI agents — backed by SurrealDB.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Umar Alfarouk",
|
|
@@ -37,10 +37,11 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"dev": "bun run src/cli/index.ts",
|
|
39
39
|
"start": "bun run src/cli/index.ts",
|
|
40
|
+
"test": "bun test",
|
|
40
41
|
"ssot:check": "bun run scripts/ssot.ts check",
|
|
41
42
|
"ssot:sync": "bun run scripts/ssot.ts sync",
|
|
42
43
|
"fmt": "dprint fmt",
|
|
43
|
-
"check": "bun run fmt && bun tsc --noEmit && bun run ssot:check",
|
|
44
|
+
"check": "bun run fmt && bun tsc --noEmit && bun test && bun run ssot:check",
|
|
44
45
|
"sync": "bun run ssot:sync"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"zod": "^4.3.6"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
60
|
+
"@opencode-ai/plugin": "^1.3.0",
|
|
59
61
|
"@types/bun": "^1.3.11",
|
|
60
62
|
"typescript": "^5.9.3"
|
|
61
63
|
}
|
package/skills/suemo/SKILL.md
CHANGED
|
@@ -3,13 +3,38 @@ name: suemo
|
|
|
3
3
|
description: OpenCode-focused persistent memory workflow for suemo with CLI/MCP parity and versioned references.
|
|
4
4
|
license: GPL-3.0-only
|
|
5
5
|
compatibility: opencode
|
|
6
|
-
version: 0.1.
|
|
6
|
+
version: 0.1.8
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# suemo skill
|
|
10
10
|
|
|
11
11
|
Use suemo to persist technical context across sessions with minimal, project-scoped memory.
|
|
12
12
|
|
|
13
|
+
## Strict defaults (v0.1.8)
|
|
14
|
+
|
|
15
|
+
- Always run pre-checks before implementation:
|
|
16
|
+
- `goal_list({ scope })`
|
|
17
|
+
- `query({ input: "recent work on <topic>", scope })`
|
|
18
|
+
- `context({ scope, limit: 20 })`
|
|
19
|
+
- `observe.kind` accepts only: `observation | belief | question | hypothesis | goal`
|
|
20
|
+
- For non-trivial writes, prefer structured content:
|
|
21
|
+
- `**What**`, `**Why**`, `**Where**`, `**Learned**`
|
|
22
|
+
- End meaningful tasks with:
|
|
23
|
+
- `episode_end({ sessionId, summary, goal, discoveries, accomplished, files_changed })`
|
|
24
|
+
- `goal_resolve({ goalId })` when done
|
|
25
|
+
- `query({ input: "most recent observations", scope })`
|
|
26
|
+
- `health()`
|
|
27
|
+
|
|
28
|
+
## OpenCode plugin support
|
|
29
|
+
|
|
30
|
+
`suemo init opencode` now installs three things:
|
|
31
|
+
|
|
32
|
+
1. MCP config entry for suemo
|
|
33
|
+
2. AGENTS.md suemo block
|
|
34
|
+
3. OpenCode plugin at `~/.config/opencode/plugins/suemo.ts`
|
|
35
|
+
|
|
36
|
+
The plugin injects strict suemo protocol into system prompt and adds compaction checkpoint reminders.
|
|
37
|
+
|
|
13
38
|
## Quick use
|
|
14
39
|
|
|
15
40
|
- CLI latest skill: `suemo skill`
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agents-snippet
|
|
3
3
|
description: AGENTS.md snippet optimized for suemo skill discovery and usage.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# AGENTS.md snippet
|
|
8
8
|
|
|
9
9
|
```md
|
|
10
|
-
## suemo-first memory workflow
|
|
10
|
+
## suemo-first memory workflow (strict)
|
|
11
11
|
|
|
12
12
|
Before significant work:
|
|
13
13
|
|
|
14
|
-
-
|
|
14
|
+
- suemo_goal_list({ scope: "<active-scope>" })
|
|
15
|
+
- suemo_query({ input: "recent work on <topic>", scope: "<active-scope>" })
|
|
16
|
+
- suemo_context({ scope: "<active-scope>", limit: 20 })
|
|
17
|
+
- suemo_episode_start({ sessionId: "<session-id>" }) for new tasks
|
|
18
|
+
|
|
19
|
+
Schema guardrails:
|
|
20
|
+
|
|
21
|
+
- suemo_observe.kind must be one of: observation | belief | question | hypothesis | goal
|
|
22
|
+
- Never use discovery/architecture/bugfix as kind
|
|
15
23
|
|
|
16
24
|
If you need latest usage docs:
|
|
17
25
|
|
|
@@ -21,16 +29,19 @@ If you need latest usage docs:
|
|
|
21
29
|
|
|
22
30
|
During work:
|
|
23
31
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
32
|
+
- suemo_observe({ content: "**What**: ...\n**Why**: ...\n**Where**: ...\n**Learned**: ...", kind: "observation" })
|
|
33
|
+
- suemo_believe("...") for uncertain interpretations
|
|
34
|
+
- suemo_goal_set("...") for long tasks
|
|
27
35
|
|
|
28
36
|
After completion:
|
|
29
37
|
|
|
30
|
-
-
|
|
31
|
-
-
|
|
38
|
+
- suemo_episode_end({ sessionId, summary, goal, discoveries, accomplished, files_changed })
|
|
39
|
+
- suemo_goal_resolve({ goalId }) if applicable
|
|
40
|
+
- suemo_query({ input: "most recent observations", scope: "<active-scope>" })
|
|
41
|
+
- suemo_health()
|
|
32
42
|
|
|
33
43
|
After compaction/reset:
|
|
34
44
|
|
|
35
|
-
-
|
|
45
|
+
- suemo_session_context_set({ sessionId, summary: "<compacted summary>" })
|
|
46
|
+
- suemo_context({ scope: "<project-id>", limit: 20 })
|
|
36
47
|
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cli-reference
|
|
3
3
|
description: CLI command reference for suemo v0.0.6 including skill access.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# CLI reference
|
|
@@ -14,10 +14,15 @@ Core:
|
|
|
14
14
|
- `suemo serve [--stdio|--dev]`
|
|
15
15
|
- `suemo skill [reference]`
|
|
16
16
|
|
|
17
|
+
Aliases (deprecated, still accepted with warning):
|
|
18
|
+
|
|
19
|
+
- `suemo skills` → use `suemo skill`
|
|
20
|
+
- `suemo init surrealdb` → use `suemo init surreal`
|
|
21
|
+
|
|
17
22
|
Memory:
|
|
18
23
|
|
|
19
24
|
- `suemo observe <content>`
|
|
20
|
-
- `suemo believe <content
|
|
25
|
+
- `suemo believe <content> [--session <sessionId>]`
|
|
21
26
|
- `suemo query <input>`
|
|
22
27
|
- `suemo recall <nodeId>`
|
|
23
28
|
- `suemo wander`
|
|
@@ -1,40 +1,68 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: core-workflow
|
|
3
3
|
description: Canonical suemo operating loop for OpenCode agents.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Core workflow
|
|
8
8
|
|
|
9
|
-
1. Start with
|
|
9
|
+
1. Start with strict pre-check:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
|
|
12
|
+
goal_list({ scope: '<project-scope>' })
|
|
13
|
+
query({ input: 'recent work on <topic>', scope: '<project-scope>' })
|
|
14
|
+
context({ scope: '<project-scope>', limit: 20 })
|
|
15
|
+
episode_start({ sessionId: '<session-id>' }) // when beginning new task
|
|
13
16
|
```
|
|
14
17
|
|
|
15
18
|
2. During work, persist concrete discoveries:
|
|
16
19
|
|
|
17
20
|
```ts
|
|
18
|
-
observe(
|
|
19
|
-
|
|
21
|
+
observe({
|
|
22
|
+
content: '**What**: ...\n**Why**: ...\n**Where**: ...\n**Learned**: ...',
|
|
23
|
+
kind: 'observation',
|
|
24
|
+
scope: '<project-scope>',
|
|
25
|
+
})
|
|
26
|
+
believe({ content: '...', scope: '<project-scope>' })
|
|
20
27
|
```
|
|
21
28
|
|
|
22
|
-
3.
|
|
29
|
+
3. Kind schema is strict:
|
|
23
30
|
|
|
24
31
|
```ts
|
|
25
|
-
|
|
32
|
+
// valid only:
|
|
33
|
+
// observation | belief | question | hypothesis | goal
|
|
26
34
|
```
|
|
27
35
|
|
|
28
|
-
4.
|
|
36
|
+
4. For long tasks:
|
|
29
37
|
|
|
30
38
|
```ts
|
|
39
|
+
goal_set({ content: '...', scope: '<project-scope>' })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
5. If compaction/reset happened:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
session_context_set({
|
|
46
|
+
sessionId: '<session-id>',
|
|
47
|
+
summary: '<compacted summary>',
|
|
48
|
+
})
|
|
31
49
|
context({ scope: '<project-id>', limit: 20 })
|
|
32
50
|
```
|
|
33
51
|
|
|
34
|
-
|
|
52
|
+
6. Close session with structured fields:
|
|
35
53
|
|
|
36
54
|
```ts
|
|
37
|
-
episode_end(
|
|
55
|
+
episode_end({
|
|
56
|
+
sessionId: '<session-id>',
|
|
57
|
+
summary: '...',
|
|
58
|
+
goal: '...',
|
|
59
|
+
discoveries: ['...'],
|
|
60
|
+
accomplished: ['...'],
|
|
61
|
+
files_changed: ['path/to/file'],
|
|
62
|
+
})
|
|
63
|
+
goal_resolve({ goalId: '<goal-id>' }) // if completed
|
|
64
|
+
query({ input: 'most recent observations', scope: '<project-scope>' })
|
|
65
|
+
health()
|
|
38
66
|
```
|
|
39
67
|
|
|
40
68
|
Prefer project-scoped memory. Let suemo infer scope from nearest `{projectDir}/suemo.json` (recommended `main.projectDir = '.ua'`).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: manual-test-plan
|
|
3
3
|
description: Comprehensive manual test matrix for suemo features and commands.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Manual test plan
|
|
@@ -35,10 +35,11 @@ Expected:
|
|
|
35
35
|
|
|
36
36
|
1. `episode_start`
|
|
37
37
|
2. add observations with `sessionId`
|
|
38
|
-
3. `
|
|
39
|
-
4. `
|
|
40
|
-
5. `
|
|
41
|
-
6.
|
|
38
|
+
3. add belief with `sessionId` (`suemo believe "..." --session <id>` or MCP `believe({ sessionId })`)
|
|
39
|
+
4. `session_context_set`
|
|
40
|
+
5. `context`
|
|
41
|
+
6. `episode_end` with structured fields
|
|
42
|
+
7. verify episode fields persisted
|
|
42
43
|
|
|
43
44
|
## E. Goals
|
|
44
45
|
|
|
@@ -66,7 +67,17 @@ Expected:
|
|
|
66
67
|
2. `suemo skill core-workflow`
|
|
67
68
|
3. MCP `skill({})`, `skill({ reference: "cli-reference" })`
|
|
68
69
|
|
|
69
|
-
## I.
|
|
70
|
+
## I. OpenCode init + plugin install
|
|
71
|
+
|
|
72
|
+
1. `suemo init opencode --dry-run`
|
|
73
|
+
2. `suemo init opencode`
|
|
74
|
+
3. Verify files:
|
|
75
|
+
- `~/.config/opencode/opencode.jsonc` or `.json` contains `mcp.suemo`
|
|
76
|
+
- `~/.config/opencode/AGENTS.md` has `<!-- SUEMO:START --> ... <!-- SUEMO:END -->`
|
|
77
|
+
- `~/.config/opencode/plugins/suemo.ts` exists
|
|
78
|
+
4. Validate plugin appears under OpenCode loaded plugins
|
|
79
|
+
|
|
80
|
+
## J. Output modes
|
|
70
81
|
|
|
71
82
|
Repeat representative commands under:
|
|
72
83
|
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mcp-reference
|
|
3
3
|
description: MCP tool reference for suemo v0.0.6.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# MCP tools
|
|
8
8
|
|
|
9
|
+
Strictness notes (v0.1.7):
|
|
10
|
+
|
|
11
|
+
- `observe.kind` is strict enum: `observation | belief | question | hypothesis | goal`
|
|
12
|
+
- `episode_end` supports optional structured fields: `summary`, `goal`, `discoveries`, `accomplished`, `files_changed`
|
|
13
|
+
- For reliable agent adoption, pair `episode_end` with `goal_resolve` and post-check `query("most recent observations")`
|
|
14
|
+
|
|
9
15
|
Write/mutate:
|
|
10
16
|
|
|
11
17
|
- `observe`
|
|
@@ -42,5 +48,7 @@ Maintenance:
|
|
|
42
48
|
Notes:
|
|
43
49
|
|
|
44
50
|
- Optional `scope` defaults to inferred project id.
|
|
51
|
+
- `believe` accepts optional `sessionId` to attach created belief memories to an open episode.
|
|
45
52
|
- `update` re-embeds when `content` changes.
|
|
46
53
|
- `episode_end` accepts structured fields (`goal`, `discoveries`, `accomplished`, `files_changed`).
|
|
54
|
+
- `skill` returns inline references; use `skill({ reference: "core-workflow" })` for canonical loop.
|
package/src/AGENTS.md
CHANGED
|
@@ -1,150 +1,130 @@
|
|
|
1
|
-
|
|
1
|
+
**CRITICAL:** This protocol is mandatory. Start each new task with the checklist below. End each completed task with `suemo_episode_end` + `suemo_goal_resolve` (if applicable). Do not skip.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1) Pre-Session Checklist (required)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Before implementation:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- [ ] `suemo_goal_list({ scope: "<active-scope>" })`
|
|
8
|
+
- [ ] `suemo_query({ input: "recent work on <topic>", scope: "<active-scope>" })`
|
|
9
|
+
- [ ] `suemo_context({ scope: "<active-scope>", limit: 20 })`
|
|
10
|
+
- [ ] Resolve abandoned goals if any
|
|
11
|
+
- [ ] `suemo_episode_start({ sessionId: "<session-id>" })` for new tasks
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
- MCP: `skill({})`
|
|
13
|
+
Proceed only after all checks pass.
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
---
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
## 2) Strict schema rules (required)
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
### `suemo_observe` kind is strict
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
Valid `kind` values only:
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
- `observation`
|
|
24
|
+
- `belief`
|
|
25
|
+
- `question`
|
|
26
|
+
- `hypothesis`
|
|
27
|
+
- `goal`
|
|
21
28
|
|
|
22
|
-
###
|
|
29
|
+
### `suemo_episode_end` payload shape
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
goal_list(scope: "<active-scope>")
|
|
26
|
-
query("recent work on [topic]", scope: "<active-scope>")
|
|
27
|
-
```
|
|
31
|
+
Minimum schema requirement: `sessionId`.
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
Required by protocol when finishing meaningful work:
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
- `summary`
|
|
36
|
+
- `goal`
|
|
37
|
+
- `discoveries` (array)
|
|
38
|
+
- `accomplished` (array)
|
|
39
|
+
- `files_changed` (array)
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
Use exact field names above.
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
observe("[fact you learned or confirmed]")
|
|
37
|
-
believe("[interpretation or conclusion that might change]")
|
|
38
|
-
```
|
|
43
|
+
---
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
## 3) During work
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
Persist important information immediately (not only at the end).
|
|
43
48
|
|
|
44
|
-
|
|
49
|
+
Use this structure for non-trivial observations:
|
|
45
50
|
|
|
51
|
+
```md
|
|
52
|
+
**What**: <what changed>
|
|
53
|
+
**Why**: <reason>
|
|
54
|
+
**Where**: <files/paths>
|
|
55
|
+
**Learned**: <gotchas/decisions>
|
|
46
56
|
```
|
|
47
|
-
episode_end(<session_id>, summary="<one sentence of what was accomplished>")
|
|
48
|
-
goal_resolve(<goal_id>) # only if the goal is fully done
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
If the session is interrupted and you never reach this step, that is acceptable. Incomplete episodes are better than missing observations mid-session.
|
|
52
|
-
|
|
53
|
-
## observe vs believe
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
Guidance:
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
- Facts → `suemo_observe`
|
|
61
|
+
- Interpretations/uncertainty → `suemo_believe`
|
|
62
|
+
- Longer tasks → `suemo_goal_set`
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
---
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
## 4) After completion
|
|
63
67
|
|
|
64
|
-
|
|
68
|
+
Run in order:
|
|
65
69
|
|
|
66
|
-
|
|
70
|
+
1. `suemo_episode_end({ sessionId, summary, goal, discoveries, accomplished, files_changed })`
|
|
71
|
+
2. `suemo_goal_resolve({ goalId })` when done
|
|
72
|
+
3. `suemo_query({ input: "most recent observations", scope })`
|
|
73
|
+
4. `suemo_health()`
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
- Config or flags that took effort to figure out
|
|
70
|
-
- Errors encountered and how they were resolved
|
|
71
|
-
- Decisions made and the reasoning behind them
|
|
72
|
-
- Constraints or preferences the user stated
|
|
75
|
+
---
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
**Skip:** `"[library] supports [feature]"` ← already in the docs
|
|
77
|
+
## 5) Querying best practices
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- Transient state: current cursor position, open file, in-progress thought
|
|
80
|
-
- Exact code snippets from files — observe your _understanding_ of them instead
|
|
81
|
-
- Timestamps — suemo sets `valid_from` automatically
|
|
82
|
-
- Uncertain things stated as facts — use `kind: "hypothesis"` instead
|
|
83
|
-
|
|
84
|
-
## Querying
|
|
85
|
-
|
|
86
|
-
suemo uses hybrid retrieval (vector + BM25 + graph) with score gates.
|
|
87
|
-
Natural language often works, but broad prompts can still be noisy.
|
|
88
|
-
|
|
89
|
-
Use scoped, specific queries first:
|
|
79
|
+
Prefer specific, scoped queries:
|
|
90
80
|
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
```ts
|
|
82
|
+
suemo_query({
|
|
83
|
+
input: 'past decisions about auth middleware',
|
|
84
|
+
scope: '<project-id>',
|
|
85
|
+
})
|
|
86
|
+
suemo_query({
|
|
87
|
+
input: '"SURREAL_CAPS_ALLOW_FUNC" init fix',
|
|
88
|
+
scope: '<project-id>',
|
|
89
|
+
})
|
|
94
90
|
```
|
|
95
91
|
|
|
96
|
-
|
|
92
|
+
When weak ranking is suspected, run `--explain` from CLI to inspect scoring.
|
|
97
93
|
|
|
98
|
-
|
|
99
|
-
query('"SURREAL_CAPS_ALLOW_FUNC" init fix', scope: "<active-scope>")
|
|
100
|
-
```
|
|
94
|
+
---
|
|
101
95
|
|
|
102
|
-
|
|
96
|
+
## 6) Anti-patterns
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
- ❌ Storing transient state (cursor position, temporary thoughts)
|
|
99
|
+
- ❌ Storing raw code snippets instead of distilled understanding
|
|
100
|
+
- ❌ Querying on every small step
|
|
101
|
+
- ❌ Skipping `suemo_episode_end`
|
|
102
|
+
- ❌ Forgetting `suemo_goal_resolve`
|
|
103
|
+
- ❌ Using non-schema `kind` values
|
|
108
104
|
|
|
109
|
-
|
|
110
|
-
- Use `recall(<nodeId>)` when you have a node ID and want it plus neighbours
|
|
105
|
+
---
|
|
111
106
|
|
|
112
|
-
|
|
107
|
+
## 7) Compaction/reset handling
|
|
113
108
|
|
|
114
|
-
|
|
109
|
+
Immediately:
|
|
115
110
|
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
1. `suemo_session_context_set({ sessionId, summary: "<compacted summary>" })`
|
|
112
|
+
2. `suemo_context({ scope: "<project-id>", limit: 20 })`
|
|
113
|
+
3. Continue work
|
|
118
114
|
|
|
119
|
-
|
|
115
|
+
---
|
|
120
116
|
|
|
121
|
-
##
|
|
117
|
+
## 8) Documentation shortcuts
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
```bash
|
|
120
|
+
suemo skill
|
|
121
|
+
suemo skill core-workflow
|
|
122
|
+
suemo skill mcp-reference
|
|
123
|
+
suemo skill manual-test-plan
|
|
127
124
|
```
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
```
|
|
132
|
-
goal_resolve(<id>)
|
|
133
|
-
```
|
|
126
|
+
Load docs once per session unless requirements changed.
|
|
134
127
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
## What suemo handles automatically
|
|
138
|
-
|
|
139
|
-
- **Timestamps** — `valid_from` on write, `valid_until` on contradiction or invalidation
|
|
140
|
-
- **Deduplication** — identical writes merge; near-duplicates create a new linked node
|
|
141
|
-
- **Consolidation** — runs on a schedule; no manual trigger needed
|
|
142
|
-
- **Embeddings** — computed server-side via `fn::embed()`; never pass vectors yourself
|
|
143
|
-
|
|
144
|
-
## Health check
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
suemo health
|
|
148
|
-
```
|
|
128
|
+
---
|
|
149
129
|
|
|
150
|
-
|
|
130
|
+
_Version: 0.1.8 | Updated: 2026-03-24 | Summary: stricter schema + explicit completion contract_
|
|
@@ -12,6 +12,7 @@ export const believeCmd = app.sub('believe')
|
|
|
12
12
|
.flags({
|
|
13
13
|
scope: { type: 'string', short: 's', description: 'Scope label' },
|
|
14
14
|
confidence: { type: 'number', description: 'Confidence 0.0–1.0', default: 1.0 },
|
|
15
|
+
session: { type: 'string', description: 'Session ID (attach to open episode)' },
|
|
15
16
|
json: { type: 'boolean', description: 'Output JSON result' },
|
|
16
17
|
pretty: { type: 'boolean', description: 'Human-readable output (default)' },
|
|
17
18
|
})
|
|
@@ -32,12 +33,14 @@ export const believeCmd = app.sub('believe')
|
|
|
32
33
|
hasScope: Boolean(resolvedScope),
|
|
33
34
|
scope: resolvedScope,
|
|
34
35
|
confidence: flags.confidence,
|
|
36
|
+
hasSession: Boolean(flags.session),
|
|
35
37
|
contentLength: args.content.length,
|
|
36
38
|
})
|
|
37
39
|
const { node, contradicted } = await believe(db, {
|
|
38
40
|
content: args.content,
|
|
39
41
|
scope: resolvedScope,
|
|
40
42
|
confidence: flags.confidence,
|
|
43
|
+
sessionId: flags.session,
|
|
41
44
|
}, config)
|
|
42
45
|
if (outputMode === 'json') {
|
|
43
46
|
const out: Record<string, unknown> = { id: node.id, valid_from: node.valid_from }
|
|
@@ -29,7 +29,7 @@ const reportCmd = health.sub('report')
|
|
|
29
29
|
let db: Surreal | undefined
|
|
30
30
|
try {
|
|
31
31
|
db = await connect(config.surreal)
|
|
32
|
-
const report = await healthReport(db)
|
|
32
|
+
const report = await healthReport(db, { embeddingProvider: config.embedding.provider })
|
|
33
33
|
if (outputMode === 'json') {
|
|
34
34
|
printCliJson(report, flags)
|
|
35
35
|
} else {
|
|
@@ -129,7 +129,7 @@ export const healthCmd = health
|
|
|
129
129
|
let db: Surreal | undefined
|
|
130
130
|
try {
|
|
131
131
|
db = await connect(config.surreal)
|
|
132
|
-
const report = await healthReport(db)
|
|
132
|
+
const report = await healthReport(db, { embeddingProvider: config.embedding.provider })
|
|
133
133
|
if (outputMode === 'json') {
|
|
134
134
|
printCliJson(report, flags)
|
|
135
135
|
} else {
|