sanook-cli 0.5.1 → 0.5.2
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/.env.example +161 -3
- package/CHANGELOG.md +57 -8
- package/README.md +240 -23
- package/README.th.md +87 -6
- package/dist/approval.js +6 -0
- package/dist/bin.js +3026 -196
- package/dist/brain-context.js +223 -0
- package/dist/brain-doctor.js +318 -0
- package/dist/brain-eval.js +186 -0
- package/dist/brain-final.js +371 -0
- package/dist/brain-review.js +382 -0
- package/dist/brain.js +12 -1
- package/dist/brand.js +1 -1
- package/dist/cli-args.js +152 -0
- package/dist/cli-option-values.js +16 -0
- package/dist/commands.js +172 -13
- package/dist/compaction.js +96 -11
- package/dist/config.js +118 -28
- package/dist/context-compression.js +191 -0
- package/dist/cost.js +49 -15
- package/dist/first-run.js +21 -0
- package/dist/gateway/auth.js +37 -8
- package/dist/gateway/bluebubbles.js +205 -0
- package/dist/gateway/config.js +929 -0
- package/dist/gateway/deliver.js +357 -0
- package/dist/gateway/discord.js +124 -0
- package/dist/gateway/email.js +472 -0
- package/dist/gateway/googlechat.js +207 -0
- package/dist/gateway/homeassistant.js +256 -0
- package/dist/gateway/ledger.js +18 -0
- package/dist/gateway/line.js +171 -0
- package/dist/gateway/lock.js +3 -1
- package/dist/gateway/matrix.js +366 -0
- package/dist/gateway/mattermost.js +322 -0
- package/dist/gateway/ntfy.js +218 -0
- package/dist/gateway/schedule.js +31 -4
- package/dist/gateway/serve.js +267 -7
- package/dist/gateway/server.js +253 -19
- package/dist/gateway/service.js +224 -0
- package/dist/gateway/session.js +343 -0
- package/dist/gateway/signal.js +351 -0
- package/dist/gateway/slack.js +124 -0
- package/dist/gateway/sms.js +169 -0
- package/dist/gateway/targets.js +576 -0
- package/dist/gateway/teams.js +106 -0
- package/dist/gateway/telegram.js +38 -15
- package/dist/gateway/webhooks.js +220 -0
- package/dist/gateway/whatsapp.js +230 -0
- package/dist/hooks.js +13 -2
- package/dist/insights-args.js +35 -0
- package/dist/insights.js +86 -0
- package/dist/loop.js +123 -24
- package/dist/lsp/index.js +23 -5
- package/dist/mcp-registry.js +350 -0
- package/dist/mcp-server.js +1 -1
- package/dist/mcp.js +44 -6
- package/dist/memory.js +100 -33
- package/dist/orchestrate.js +49 -19
- package/dist/personality.js +58 -0
- package/dist/providers/codex.js +70 -36
- package/dist/providers/keys.js +1 -1
- package/dist/providers/models.js +1 -1
- package/dist/providers/registry.js +14 -47
- package/dist/search/chunk.js +7 -8
- package/dist/search/cli.js +75 -0
- package/dist/search/embed-store.js +3 -0
- package/dist/search/indexer.js +44 -1
- package/dist/search/store.js +23 -1
- package/dist/session.js +93 -7
- package/dist/skill-install.js +29 -12
- package/dist/support-dump.js +175 -0
- package/dist/tools/edit.js +45 -15
- package/dist/tools/git.js +10 -5
- package/dist/tools/homeassistant.js +106 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/list.js +19 -6
- package/dist/tools/permission.js +923 -9
- package/dist/tools/read.js +16 -4
- package/dist/tools/schedule.js +19 -3
- package/dist/tools/search.js +217 -13
- package/dist/tools/task.js +18 -7
- package/dist/tools/timeout.js +21 -3
- package/dist/trust.js +11 -1
- package/dist/ui/app.js +48 -8
- package/dist/ui/history.js +37 -5
- package/dist/ui/mentions.js +3 -2
- package/dist/ui/setup.js +17 -4
- package/dist/update.js +24 -11
- package/dist/worktree.js +175 -4
- package/package.json +4 -4
- package/second-brain/AGENTS.md +6 -4
- package/second-brain/CLAUDE.md +7 -1
- package/second-brain/Evals/_Index.md +10 -2
- package/second-brain/Evals/quality-ledger.md +9 -1
- package/second-brain/Evals/second-brain-benchmarks.md +62 -0
- package/second-brain/GEMINI.md +5 -4
- package/second-brain/Home.md +1 -1
- package/second-brain/Projects/_Index.md +3 -1
- package/second-brain/Projects/sanook-cli/_Index.md +26 -0
- package/second-brain/Projects/sanook-cli/second-brain-feature-roadmap.md +156 -0
- package/second-brain/README.md +1 -1
- package/second-brain/Research/2026-06-17-ai-second-brain-method-experiment.md +108 -0
- package/second-brain/Research/2026-06-18-ai-token-reduction-frameworks.md +55 -0
- package/second-brain/Research/2026-06-18-hermes-cli-second-brain-expansion-research.md +160 -0
- package/second-brain/Research/2026-06-18-sanook-mcp-ecosystem-and-ux-roadmap.md +181 -0
- package/second-brain/Research/_Index.md +6 -1
- package/second-brain/Reviews/2026-06-18-auto-improve-maintenance.md +54 -0
- package/second-brain/Reviews/_Index.md +1 -1
- package/second-brain/Runbooks/_Index.md +6 -1
- package/second-brain/Runbooks/ai-second-brain-operating-sequence.md +108 -0
- package/second-brain/SANOOK.md +45 -0
- package/second-brain/Sessions/2026-06-17-ai-framework-additional-zones.md +68 -0
- package/second-brain/Sessions/2026-06-17-ai-second-brain-sequence-experiment.md +63 -0
- package/second-brain/Sessions/2026-06-18-cli-args-release-readiness.md +59 -0
- package/second-brain/Sessions/2026-06-18-final-gate-template-final.md +192 -0
- package/second-brain/Sessions/2026-06-18-final-gate-template.md +71 -0
- package/second-brain/Sessions/2026-06-18-framework-dogfood-permission-and-memory.md +58 -0
- package/second-brain/Sessions/2026-06-18-hermes-second-brain-expansion-research.md +52 -0
- package/second-brain/Sessions/2026-06-18-mcp-ecosystem-and-sanook-ux-scan.md +81 -0
- package/second-brain/Sessions/2026-06-18-sanook-brain-cli-p0-implementation.md +86 -0
- package/second-brain/Sessions/2026-06-18-sanook-brain-final-cli-final.md +246 -0
- package/second-brain/Sessions/2026-06-18-sanook-brain-final-cli.md +78 -0
- package/second-brain/Sessions/2026-06-18-sanook-cli-second-brain-roadmap-correction.md +54 -0
- package/second-brain/Sessions/2026-06-18-token-reduction-framework-integration.md +69 -0
- package/second-brain/Sessions/_Index.md +15 -1
- package/second-brain/Shared/AI-Context-Index.md +22 -0
- package/second-brain/Shared/Context-Packs/_Index.md +9 -1
- package/second-brain/Shared/Context-Packs/coding-release.md +51 -0
- package/second-brain/Shared/Context-Packs/research-to-framework.md +51 -0
- package/second-brain/Shared/Context-Packs/second-brain-maintenance.md +41 -0
- package/second-brain/Shared/Operating-State/current-state.md +22 -3
- package/second-brain/Shared/Scripts/_Index.md +3 -1
- package/second-brain/Shared/Scripts/ai-second-brain-method-eval.mjs +198 -0
- package/second-brain/Shared/Tech-Standards/_Index.md +4 -1
- package/second-brain/Shared/Tech-Standards/mcp-integration-roadmap.md +86 -0
- package/second-brain/Shared/Tech-Standards/verification-standard.md +24 -0
- package/second-brain/Shared/User-Memory/_Index.md +4 -1
- package/second-brain/Shared/User-Memory/response-examples.md +98 -0
- package/second-brain/Shared/User-Memory/user-preferences.md +1 -0
- package/second-brain/Templates/_Index.md +9 -0
- package/second-brain/Templates/final-lite.md +111 -0
- package/second-brain/Templates/final.md +231 -0
- package/second-brain/Vault Structure Map.md +2 -1
- package/skills/structured-output-llm/SKILL.md +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [context-pack, second-brain, maintenance]
|
|
3
|
+
note_type: context-pack
|
|
4
|
+
created: 2026-06-17
|
|
5
|
+
updated: 2026-06-17
|
|
6
|
+
parent: "[[Shared/Context-Packs/_Index]]"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Context Pack: Second-Brain Maintenance
|
|
10
|
+
|
|
11
|
+
> Use when editing vault structure, routing rules, memory policy, indexes, runbooks, or agent adapters.
|
|
12
|
+
|
|
13
|
+
## Load Order
|
|
14
|
+
|
|
15
|
+
1. [[Shared/AI-Context-Index]]
|
|
16
|
+
2. [[Runbooks/ai-second-brain-operating-sequence]]
|
|
17
|
+
3. [[Vault Structure Map]]
|
|
18
|
+
4. [[Shared/Rules/context-assembly-policy]]
|
|
19
|
+
5. Destination `_Index.md`
|
|
20
|
+
6. [[Shared/Rules/memory-write-protocol]] if changing memory/facts
|
|
21
|
+
7. [[Evals/second-brain-benchmarks]] before and after framework edits
|
|
22
|
+
|
|
23
|
+
## Required Role
|
|
24
|
+
|
|
25
|
+
- Primary: Librarian
|
|
26
|
+
- Secondary: Scientist
|
|
27
|
+
|
|
28
|
+
## Output Artifacts
|
|
29
|
+
|
|
30
|
+
- Updated target note/index
|
|
31
|
+
- Quality/evidence note when non-trivial: [[Evals/quality-ledger]] or [[Sessions/_Index]]
|
|
32
|
+
- No new root folder unless [[Vault Structure Map]] is updated and drift tests are considered
|
|
33
|
+
|
|
34
|
+
## Done Criteria
|
|
35
|
+
|
|
36
|
+
- New/changed notes have `parent` and `up::`
|
|
37
|
+
- Index links make the artifact discoverable
|
|
38
|
+
- Benchmark or explicit verification is recorded
|
|
39
|
+
- Context bloat is checked; do not preload every rule
|
|
40
|
+
|
|
41
|
+
up:: [[Shared/Context-Packs/_Index]]
|
|
@@ -13,11 +13,24 @@ ai_surface: starter
|
|
|
13
13
|
|
|
14
14
|
## Now
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- 2026-06-17: ปรับ second-brain ให้ใช้ [[Runbooks/ai-second-brain-operating-sequence]] เป็น default AI operating sequence หลังทดลองเทียบ methods แล้ว
|
|
17
|
+
- 2026-06-17: เพิ่ม [[Evals/second-brain-benchmarks]], [[Shared/User-Memory/response-examples]], และ context packs ใน [[Shared/Context-Packs/_Index]]
|
|
18
|
+
- 2026-06-18: dogfood context packs กับงานจริง 3 task-family แล้ว: coding-release, second-brain-maintenance, research-to-framework
|
|
19
|
+
- 2026-06-18: ตรวจ cli-args serve port UX change แล้ว; targeted/full tests, typecheck, build, diff check ผ่าน
|
|
20
|
+
- 2026-06-18: วิจัย Hermes CLI second-brain expansion ไว้เป็น reference; เจ้าของ clarify ว่าเป้าจริงคือทำใน Sanook CLI
|
|
21
|
+
- 2026-06-18: Sanook-native P0 implemented: `sanook brain doctor`, `sanook brain context`, `sanook brain eval`
|
|
22
|
+
- 2026-06-18: เพิ่ม `sanook brain review` เป็น curator review แบบ read-only สำหรับ inbox/context-packs/sessions/evals/note hygiene
|
|
23
|
+
- 2026-06-18: เพิ่ม [[Templates/final]] เป็น final gate / evidence matrix ก่อนปิดงาน non-trivial
|
|
24
|
+
- 2026-06-18: เพิ่ม `sanook brain final`, [[Templates/final-lite]], final-gate validator ใน `brain review`, และ `SB-FINAL` ใน `brain eval` แล้ว
|
|
25
|
+
- 2026-06-18: MCP P0 implemented ใน Sanook CLI แล้ว: registry-backed `mcp search/info/install/preset/test/doctor/list --tools`; verification ผ่าน และพบว่า GitLab remote ต้อง auth header ก่อน probe ผ่าน
|
|
26
|
+
- 2026-06-18: เพิ่ม [[Research/2026-06-18-ai-token-reduction-frameworks]], default query-aware selective context compression, adaptive stale-tool budgets, และ optional Headroom framework mode ใน Sanook CLI
|
|
17
27
|
|
|
18
28
|
## Active Bets
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
- Scientific Loop Sequence: single retrieval path + JIT task rules + explicit write routing + eval/consolidation loop
|
|
31
|
+
- AI จะเก่งขึ้นแบบวัดได้เมื่อมี benchmark + taste examples + reusable context packs
|
|
32
|
+
- Final gate ที่มี evidence และ CLI scaffold จะลดการ claim done เกินจริงตอนปิดงาน
|
|
33
|
+
- Token/cost จะลดได้อย่างปลอดภัยที่สุดจาก stale tool-output compression ก่อน ไม่ใช่บีบ user intent หรือ recent evidence
|
|
21
34
|
|
|
22
35
|
## Blockers
|
|
23
36
|
|
|
@@ -25,6 +38,12 @@ _(ติดอะไรอยู่)_
|
|
|
25
38
|
|
|
26
39
|
## Next Actions
|
|
27
40
|
|
|
28
|
-
- [ ]
|
|
41
|
+
- [ ] Review remaining worktree diff before commit/release
|
|
42
|
+
- [ ] Dogfood `sanook brain final --task "..." --from-diff` ในงาน implementation ถัดไป
|
|
43
|
+
- [x] ทำ MCP P0: `sanook mcp search`, `sanook mcp info`, `sanook mcp install`, `sanook mcp test`
|
|
44
|
+
- [ ] MCP follow-up: auth hints for hosted remotes that return `401`, risk labels, and richer install preview/cache
|
|
45
|
+
- [ ] Token compression follow-up: benchmark real multi-step traces and smoke test Headroom mode with a real proxy/cloud setup
|
|
46
|
+
- [ ] ถ้าจะต่อ second-brain CLI รอบถัดไป: ทำ `sanook brain pack list|show`, `sanook brain new <type>`, หรือ `sanook brain repair`
|
|
47
|
+
- [ ] เพิ่ม good/bad examples ใหม่ใน [[Shared/User-Memory/response-examples]] เมื่อมี feedback จริงรอบถัดไป
|
|
29
48
|
|
|
30
49
|
up:: [[Shared/Operating-State/_Index]]
|
|
@@ -25,6 +25,8 @@ one-off ที่ retired (→Scripts-Archive)
|
|
|
25
25
|
|
|
26
26
|
> รายละเอียดทุกโฟลเดอร์ + decision rules → [[Vault Structure Map]]
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Scripts
|
|
29
|
+
|
|
30
|
+
- `Shared/Scripts/ai-second-brain-method-eval.mjs` — reproducible eval เปรียบเทียบ AI second-brain operating methods; ใช้เป็น evidence ของ [[Research/2026-06-17-ai-second-brain-method-experiment]]
|
|
29
31
|
|
|
30
32
|
up:: [[Shared/_Index]]
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const vault = process.argv[2] ?? 'second-brain';
|
|
6
|
+
|
|
7
|
+
const files = {
|
|
8
|
+
aiIndex: 'Shared/AI-Context-Index.md',
|
|
9
|
+
user: 'USER.md',
|
|
10
|
+
currentState: 'Shared/Operating-State/current-state.md',
|
|
11
|
+
preferences: 'Shared/User-Memory/user-preferences.md',
|
|
12
|
+
decisions: 'Shared/Decision-Memory/decision-log.md',
|
|
13
|
+
structureMap: 'Vault Structure Map.md',
|
|
14
|
+
contextPolicy: 'Shared/Rules/context-assembly-policy.md',
|
|
15
|
+
noteRule: 'Shared/Rules/contextual-note-rule.md',
|
|
16
|
+
formatting: 'Shared/Rules/rules-formatting.md',
|
|
17
|
+
memoryWrite: 'Shared/Rules/memory-write-protocol.md',
|
|
18
|
+
frontmatter: 'Shared/Rules/frontmatter-standard.md',
|
|
19
|
+
ingest: 'Runbooks/ingest-quarantine.md',
|
|
20
|
+
sleep: 'Runbooks/sleep-time-consolidation.md',
|
|
21
|
+
evalLoop: 'Runbooks/eval-loop.md',
|
|
22
|
+
retrievalEval: 'Evals/retrieval-eval.md',
|
|
23
|
+
qualityLedger: 'Evals/quality-ledger.md',
|
|
24
|
+
verification: 'Shared/Tech-Standards/verification-standard.md',
|
|
25
|
+
coordinationNow: 'Shared/Coordination/NOW.md',
|
|
26
|
+
taskBoard: 'Shared/Coordination/task-board.md',
|
|
27
|
+
agentRegistry: 'Shared/Coordination/agent-registry.md',
|
|
28
|
+
sessionsIndex: 'Sessions/_Index.md',
|
|
29
|
+
runbooksIndex: 'Runbooks/_Index.md',
|
|
30
|
+
scriptsIndex: 'Shared/Scripts/_Index.md',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function fileTokens(path) {
|
|
34
|
+
const full = join(vault, path);
|
|
35
|
+
if (!existsSync(full)) return { exists: false, tokens: 0 };
|
|
36
|
+
return { exists: true, tokens: Math.ceil(readFileSync(full, 'utf8').length / 4) };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const scenarios = [
|
|
40
|
+
{
|
|
41
|
+
id: 'start-session',
|
|
42
|
+
label: 'เริ่มงานกับ AI โดยไม่หลุด source of truth',
|
|
43
|
+
required: [files.aiIndex, files.user, files.currentState, files.preferences, files.decisions],
|
|
44
|
+
capabilities: ['retrieval', 'state', 'preference'],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'write-durable-note',
|
|
48
|
+
label: 'สร้าง/แก้ durable note ให้ถูกที่และค้นเจอภายหลัง',
|
|
49
|
+
required: [files.aiIndex, files.structureMap, files.contextPolicy, files.noteRule, files.formatting],
|
|
50
|
+
capabilities: ['retrieval', 'routing', 'write-contract', 'graph-linking'],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: 'write-memory',
|
|
54
|
+
label: 'บันทึก preference/decision/fact โดยไม่ append ซ้ำ',
|
|
55
|
+
required: [files.aiIndex, files.memoryWrite, files.frontmatter, files.preferences, files.decisions],
|
|
56
|
+
capabilities: ['memory-op', 'dedupe', 'verification'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'ingest-source',
|
|
60
|
+
label: 'นำข้อมูลภายนอกเข้า vault แบบปลอด prompt injection',
|
|
61
|
+
required: [files.aiIndex, files.ingest, files.frontmatter, files.structureMap],
|
|
62
|
+
capabilities: ['ingest-safety', 'provenance', 'routing'],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'consolidate',
|
|
66
|
+
label: 'ทำ sleep-time consolidation และปิด loop ความจำ',
|
|
67
|
+
required: [files.aiIndex, files.sleep, files.memoryWrite, files.retrievalEval, files.qualityLedger],
|
|
68
|
+
capabilities: ['consolidation', 'memory-op', 'eval'],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'multi-agent',
|
|
72
|
+
label: 'กันหลาย agent ชนกันและส่งต่องานได้',
|
|
73
|
+
required: [files.aiIndex, files.coordinationNow, files.taskBoard, files.agentRegistry, files.sessionsIndex],
|
|
74
|
+
capabilities: ['coordination', 'handoff', 'session-log'],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'technical-work',
|
|
78
|
+
label: 'งานเทคนิคที่ต้อง verify ก่อนสรุป',
|
|
79
|
+
required: [files.aiIndex, files.verification, files.evalLoop, files.sessionsIndex],
|
|
80
|
+
capabilities: ['verification', 'eval', 'session-log'],
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
const methods = [
|
|
85
|
+
{
|
|
86
|
+
id: 'session-log-only',
|
|
87
|
+
label: 'Session-log only',
|
|
88
|
+
filesFor: () => [files.sessionsIndex],
|
|
89
|
+
capabilities: ['session-log'],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'folder-map-only',
|
|
93
|
+
label: 'Folder map + destination indexes',
|
|
94
|
+
filesFor: (scenario) => [files.structureMap, files.sessionsIndex, ...scenario.required.filter((p) => p.endsWith('_Index.md'))],
|
|
95
|
+
capabilities: ['routing', 'session-log'],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 'single-context-index',
|
|
99
|
+
label: 'Single retrieval index',
|
|
100
|
+
filesFor: () => [files.aiIndex, files.user, files.currentState, files.preferences, files.decisions],
|
|
101
|
+
capabilities: ['retrieval', 'state', 'preference'],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'jit-context-policy',
|
|
105
|
+
label: 'Index + JIT context policy',
|
|
106
|
+
filesFor: (scenario) => [files.aiIndex, files.contextPolicy, ...scenario.required.slice(0, 3)],
|
|
107
|
+
capabilities: ['retrieval', 'state', 'preference', 'routing', 'write-contract', 'graph-linking', 'verification'],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'scientific-loop-sequence',
|
|
111
|
+
label: 'Scientific loop sequence',
|
|
112
|
+
filesFor: (scenario) => [files.aiIndex, files.contextPolicy, ...scenario.required],
|
|
113
|
+
capabilities: [
|
|
114
|
+
'retrieval',
|
|
115
|
+
'state',
|
|
116
|
+
'preference',
|
|
117
|
+
'routing',
|
|
118
|
+
'write-contract',
|
|
119
|
+
'graph-linking',
|
|
120
|
+
'memory-op',
|
|
121
|
+
'dedupe',
|
|
122
|
+
'verification',
|
|
123
|
+
'ingest-safety',
|
|
124
|
+
'provenance',
|
|
125
|
+
'consolidation',
|
|
126
|
+
'eval',
|
|
127
|
+
'coordination',
|
|
128
|
+
'handoff',
|
|
129
|
+
'session-log',
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
function uniq(items) {
|
|
135
|
+
return [...new Set(items.filter(Boolean))];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function scoreScenario(method, scenario) {
|
|
139
|
+
const contextFiles = uniq(method.filesFor(scenario));
|
|
140
|
+
const fileStats = contextFiles.map((path) => ({ path, ...fileTokens(path) }));
|
|
141
|
+
const tokens = fileStats.reduce((sum, stat) => sum + stat.tokens, 0);
|
|
142
|
+
const requiredHits = scenario.required.filter((path) => contextFiles.includes(path) && fileTokens(path).exists).length;
|
|
143
|
+
const existingRequired = scenario.required.filter((path) => fileTokens(path).exists).length;
|
|
144
|
+
const fileCoverage = existingRequired ? requiredHits / existingRequired : 1;
|
|
145
|
+
const capabilityHits = scenario.capabilities.filter((cap) => method.capabilities.includes(cap)).length;
|
|
146
|
+
const capabilityCoverage = scenario.capabilities.length ? capabilityHits / scenario.capabilities.length : 1;
|
|
147
|
+
const economy = tokens <= 2200 ? 1 : Math.max(0, 1 - (tokens - 2200) / 2200);
|
|
148
|
+
const score = Math.round((fileCoverage * 70 + capabilityCoverage * 20 + economy * 10) * 10) / 10;
|
|
149
|
+
return { score, fileCoverage, capabilityCoverage, economy, tokens, contextFiles };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const rows = methods.map((method) => {
|
|
153
|
+
const perScenario = scenarios.map((scenario) => scoreScenario(method, scenario));
|
|
154
|
+
const avgScore = perScenario.reduce((sum, s) => sum + s.score, 0) / perScenario.length;
|
|
155
|
+
const avgTokens = perScenario.reduce((sum, s) => sum + s.tokens, 0) / perScenario.length;
|
|
156
|
+
const avgFileCoverage = perScenario.reduce((sum, s) => sum + s.fileCoverage, 0) / perScenario.length;
|
|
157
|
+
const avgCapabilityCoverage = perScenario.reduce((sum, s) => sum + s.capabilityCoverage, 0) / perScenario.length;
|
|
158
|
+
return {
|
|
159
|
+
method,
|
|
160
|
+
avgScore: Math.round(avgScore * 10) / 10,
|
|
161
|
+
avgTokens: Math.round(avgTokens),
|
|
162
|
+
avgFileCoverage: Math.round(avgFileCoverage * 100),
|
|
163
|
+
avgCapabilityCoverage: Math.round(avgCapabilityCoverage * 100),
|
|
164
|
+
perScenario,
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
rows.sort((a, b) => b.avgScore - a.avgScore);
|
|
169
|
+
|
|
170
|
+
console.log('# AI Second-Brain Method Eval');
|
|
171
|
+
console.log('');
|
|
172
|
+
console.log(`vault: ${vault}`);
|
|
173
|
+
console.log(`scenarios: ${scenarios.length}`);
|
|
174
|
+
console.log('');
|
|
175
|
+
console.log('| rank | method | score | file coverage | capability coverage | avg tokens |');
|
|
176
|
+
console.log('|---:|---|---:|---:|---:|---:|');
|
|
177
|
+
rows.forEach((row, idx) => {
|
|
178
|
+
console.log(
|
|
179
|
+
`| ${idx + 1} | ${row.method.label} | ${row.avgScore} | ${row.avgFileCoverage}% | ${row.avgCapabilityCoverage}% | ~${row.avgTokens} |`,
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
console.log('');
|
|
183
|
+
console.log('## Scenario Detail');
|
|
184
|
+
console.log('');
|
|
185
|
+
for (const row of rows) {
|
|
186
|
+
console.log(`### ${row.method.label}`);
|
|
187
|
+
console.log('| scenario | score | tokens |');
|
|
188
|
+
console.log('|---|---:|---:|');
|
|
189
|
+
row.perScenario.forEach((result, idx) => {
|
|
190
|
+
console.log(`| ${scenarios[idx].label} | ${result.score} | ~${result.tokens} |`);
|
|
191
|
+
});
|
|
192
|
+
console.log('');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const best = rows[0];
|
|
196
|
+
console.log('## Winner');
|
|
197
|
+
console.log('');
|
|
198
|
+
console.log(`${best.method.label} (${best.method.id})`);
|
|
@@ -25,6 +25,9 @@ MCP/stack/DoD/verification rulebook
|
|
|
25
25
|
|
|
26
26
|
> รายละเอียดทุกโฟลเดอร์ + decision rules → [[Vault Structure Map]]
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## Standards
|
|
29
|
+
|
|
30
|
+
- [[Shared/Tech-Standards/verification-standard]] — verification ladder, evidence format, and final gate contract
|
|
31
|
+
- [[Shared/Tech-Standards/mcp-integration-roadmap]] — MCP registry/install/test UX roadmap
|
|
29
32
|
|
|
30
33
|
up:: [[Shared/_Index]]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [standard, mcp, integration, roadmap]
|
|
3
|
+
note_type: standard-reference
|
|
4
|
+
created: 2026-06-18
|
|
5
|
+
updated: 2026-06-18
|
|
6
|
+
parent: "[[Shared/Tech-Standards/_Index]]"
|
|
7
|
+
source:
|
|
8
|
+
- "[[Research/2026-06-18-sanook-mcp-ecosystem-and-ux-roadmap]]"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# MCP Integration Roadmap
|
|
12
|
+
|
|
13
|
+
> Technical roadmap for making MCP easier and safer to use inside Sanook CLI.
|
|
14
|
+
|
|
15
|
+
## Current Baseline
|
|
16
|
+
|
|
17
|
+
- `src/mcp.ts` supports stdio MCP and remote Streamable HTTP.
|
|
18
|
+
- `src/mcp-server.ts` exposes Sanook's brain as an MCP server.
|
|
19
|
+
- `src/bin.ts` supports `mcp add/list/remove`, `mcp serve`, registry-backed `mcp search/info/install`, curated `mcp preset`, and `mcp test/doctor`.
|
|
20
|
+
- `src/mcp-registry.ts` maps official registry remotes/packages into Sanook `mcp.json`.
|
|
21
|
+
- Project MCP config remains behind `sanook trust`.
|
|
22
|
+
|
|
23
|
+
## Target UX
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
sanook mcp search github
|
|
27
|
+
sanook mcp info com.gitlab/mcp
|
|
28
|
+
sanook mcp install com.gitlab/mcp --name gitlab
|
|
29
|
+
sanook mcp test gitlab
|
|
30
|
+
sanook mcp doctor
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## P0 Requirements
|
|
34
|
+
|
|
35
|
+
1. Registry search - implemented
|
|
36
|
+
- Query official registry.
|
|
37
|
+
- Show latest versions only by default.
|
|
38
|
+
- Show server name, description, version, transport, package runtime, and source URL.
|
|
39
|
+
2. Server info - implemented
|
|
40
|
+
- Show remotes/packages.
|
|
41
|
+
- Show required env/header inputs.
|
|
42
|
+
- Mark secret inputs.
|
|
43
|
+
- Show install command preview.
|
|
44
|
+
3. Install - implemented
|
|
45
|
+
- Convert selected remote/package into Sanook `mcp.json`.
|
|
46
|
+
- Write explicit user-requested config only.
|
|
47
|
+
- Preserve `0600` permissions.
|
|
48
|
+
- Never inherit ambient provider API keys into MCP child env.
|
|
49
|
+
4. Test - implemented
|
|
50
|
+
- Initialize one server.
|
|
51
|
+
- Run `tools/list`.
|
|
52
|
+
- Report tool count and tool names.
|
|
53
|
+
- Print clear failure reason and setup hints.
|
|
54
|
+
|
|
55
|
+
## P1 Requirements
|
|
56
|
+
|
|
57
|
+
- `sanook mcp doctor`: validate config shape, missing commands, missing env, unreachable remote, duplicate tool names.
|
|
58
|
+
- `sanook mcp list --tools`: grouped tools by server.
|
|
59
|
+
- `sanook mcp remove` should support exact server names and show config path.
|
|
60
|
+
- Support `--project` install only if project is trusted.
|
|
61
|
+
- Add auth hints when hosted remotes return `401 Unauthorized`.
|
|
62
|
+
- Add registry result caching and risk labels for write-capable servers.
|
|
63
|
+
|
|
64
|
+
## Safety Policy
|
|
65
|
+
|
|
66
|
+
- Default to read-only where a server offers read-only or scoped modes.
|
|
67
|
+
- Show risk class before enabling:
|
|
68
|
+
- read-only
|
|
69
|
+
- file-write
|
|
70
|
+
- network-write
|
|
71
|
+
- database-write
|
|
72
|
+
- infra/admin
|
|
73
|
+
- Dangerous servers must remain subject to existing approval gates in ask mode.
|
|
74
|
+
- Do not run package installs implicitly during `search` or `info`.
|
|
75
|
+
- For package metadata with `fileSha256`, verify downloaded MCPB packages before running.
|
|
76
|
+
|
|
77
|
+
## First Presets
|
|
78
|
+
|
|
79
|
+
| Preset | Servers to consider | Use case |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `dev` | GitHub/GitLab, Sentry, Context7/docs | coding, PRs, releases, error debugging |
|
|
82
|
+
| `research` | fetch, Brave/web search, docs, Obsidian/GDrive | grounded external research |
|
|
83
|
+
| `pm` | Linear/Jira, Slack/Discord, Notion | task and team workflows |
|
|
84
|
+
| `ops` | Postgres read-only, Docker/Kubernetes, Sentry | operational debugging |
|
|
85
|
+
|
|
86
|
+
up:: [[Shared/Tech-Standards/_Index]]
|
|
@@ -31,6 +31,30 @@ Verification:
|
|
|
31
31
|
- Smoke: <command/result>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Final Gate
|
|
35
|
+
|
|
36
|
+
For non-trivial work, multi-file changes, framework changes, releases, or anything the owner may later audit, instantiate [[Templates/final]] before the final owner-facing answer. Use [[Templates/final-lite]] for smaller tasks that still need evidence, or run:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
sanook brain final --task "<objective>" --from-diff
|
|
40
|
+
sanook brain final --task "<objective>" --lite
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The final gate must prove all eight closeout requirements:
|
|
44
|
+
|
|
45
|
+
1. Objective / DoD is restated and matched.
|
|
46
|
+
2. Checklist items have evidence, not only checked boxes.
|
|
47
|
+
3. Status uses `PASS`, `PARTIAL`, `FAIL`, `N/A`, or `BLOCKED`.
|
|
48
|
+
4. Evidence matrix lists commands, files, artifacts, and sources.
|
|
49
|
+
5. Residual risk and skipped checks are explicit.
|
|
50
|
+
6. Change summary distinguishes changed vs untouched work.
|
|
51
|
+
7. Final answer draft does not overclaim beyond evidence.
|
|
52
|
+
8. Second-brain routing / memory closeout is handled.
|
|
53
|
+
|
|
54
|
+
If a row has no evidence, it cannot be `PASS`.
|
|
55
|
+
|
|
56
|
+
`sanook brain review` checks final-gate notes in `Sessions/` for missing sections, unfilled placeholders, `TODO` rows, and `PASS` rows without evidence. `sanook brain eval` checks that the final-gate templates remain bundled and wired into this standard.
|
|
57
|
+
|
|
34
58
|
## Never Claim Done If
|
|
35
59
|
|
|
36
60
|
- Tests were skipped without saying why.
|
|
@@ -25,6 +25,9 @@ identity static (→User-Persona)
|
|
|
25
25
|
|
|
26
26
|
> รายละเอียดทุกโฟลเดอร์ + decision rules → [[Vault Structure Map]]
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## User-Memory Notes
|
|
29
|
+
|
|
30
|
+
- [[Shared/User-Memory/user-preferences]] — durable preferences ของเจ้าของ
|
|
31
|
+
- [[Shared/User-Memory/response-examples]] — examples/taste signals ว่าคำตอบ AI แบบไหนดีหรือไม่ดี
|
|
29
32
|
|
|
30
33
|
up:: [[Shared/_Index]]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [user-memory, response-examples, taste]
|
|
3
|
+
note_type: response-examples
|
|
4
|
+
created: 2026-06-17
|
|
5
|
+
updated: 2026-06-17
|
|
6
|
+
parent: "[[Shared/User-Memory/_Index]]"
|
|
7
|
+
related:: [[Shared/User-Memory/user-preferences]]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Response Examples & Taste Signals
|
|
11
|
+
|
|
12
|
+
> Mutable examples of what "good AI behavior" feels like for {{OWNER_NAME}}. These examples are initial working defaults inferred from current vault work; update when the owner gives stronger feedback.
|
|
13
|
+
|
|
14
|
+
## Preferred Shape
|
|
15
|
+
|
|
16
|
+
- Thai first, with natural tech English where useful.
|
|
17
|
+
- Lead with the answer or status.
|
|
18
|
+
- Be proactive when the action is safe; ask only when the next step is genuinely risky or ambiguous.
|
|
19
|
+
- Summarize verification evidence without dumping full logs.
|
|
20
|
+
- For framework work, think like Scientist first, then implement like Operator/Librarian.
|
|
21
|
+
|
|
22
|
+
## Good Pattern: Work Completed
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
เสร็จแล้วครับ ผมเพิ่ม benchmark, taste examples, และ context packs เข้า framework แล้ว
|
|
26
|
+
|
|
27
|
+
หลัก ๆ คือ:
|
|
28
|
+
- Evals/second-brain-benchmarks.md สำหรับวัดคุณภาพ AI
|
|
29
|
+
- Shared/User-Memory/response-examples.md สำหรับ style/taste
|
|
30
|
+
- Shared/Context-Packs/... สำหรับโหลด context ตามงานซ้ำ
|
|
31
|
+
|
|
32
|
+
ตรวจแล้ว: script/runbook links อยู่ใน index และ git diff --check ผ่าน
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Why good:
|
|
36
|
+
|
|
37
|
+
- Starts with status.
|
|
38
|
+
- Names files.
|
|
39
|
+
- Mentions verification.
|
|
40
|
+
- Does not over-explain unless asked.
|
|
41
|
+
|
|
42
|
+
## Bad Pattern: Too Vague
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
ผมได้ปรับปรุงระบบให้ดีขึ้นแล้ว มีหลายส่วนที่ช่วยให้ AI ทำงานดีขึ้น และน่าจะใช้งานได้ดีมากขึ้นในอนาคต
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Why bad:
|
|
49
|
+
|
|
50
|
+
- No files.
|
|
51
|
+
- No evidence.
|
|
52
|
+
- No next action.
|
|
53
|
+
|
|
54
|
+
## Good Pattern: Recommendation Before Edit
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
ผมไม่แนะนำให้เพิ่ม root folder ใหม่ตอนนี้ครับ เพราะ vault มี zone รองรับอยู่แล้ว
|
|
58
|
+
ทางที่คุ้มกว่าคือเติม benchmark ใน Evals, taste examples ใน User-Memory, และ context packs ใน Shared/Context-Packs
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Why good:
|
|
62
|
+
|
|
63
|
+
- Gives a point of view.
|
|
64
|
+
- Protects the framework from unnecessary complexity.
|
|
65
|
+
- Offers concrete implementation path.
|
|
66
|
+
|
|
67
|
+
## Good Pattern: Act On All Clear Recommendations
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
รับครับ ผมจะทำครบตาม 4 ข้อที่แนะนำไว้: ตรวจ worktree, รัน tests, ใช้ benchmark/framework จริง, แล้วอัปเดต memory/session evidence ให้ครบ
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Why good:
|
|
74
|
+
|
|
75
|
+
- Mirrors the requested scope.
|
|
76
|
+
- Commits to action when the work is safe and clear.
|
|
77
|
+
- Keeps the owner looped in without asking for unnecessary confirmation.
|
|
78
|
+
|
|
79
|
+
## Good Pattern: Uncertainty
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
ผมยังยืนยัน claim นี้ไม่ได้จาก vault ปัจจุบันครับ หลักฐานที่มีบอกได้แค่ว่า X ผ่าน แต่ยังไม่ได้พิสูจน์ Y
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Why good:
|
|
86
|
+
|
|
87
|
+
- Does not pretend certainty.
|
|
88
|
+
- Separates evidence from inference.
|
|
89
|
+
|
|
90
|
+
## Update Rule
|
|
91
|
+
|
|
92
|
+
When owner reacts positively/negatively to a response:
|
|
93
|
+
|
|
94
|
+
1. Classify the signal as style, autonomy, detail level, or evidence expectation.
|
|
95
|
+
2. Update this file or [[Shared/User-Memory/user-preferences]] with ADD/UPDATE/NOOP.
|
|
96
|
+
3. Do not duplicate the same preference in multiple places.
|
|
97
|
+
|
|
98
|
+
up:: [[Shared/User-Memory/_Index]]
|
|
@@ -16,6 +16,15 @@ template ไว้ instantiate (session/bug/handoff/project)
|
|
|
16
16
|
## ไม่ใส่ที่นี่
|
|
17
17
|
โน้ตจริง
|
|
18
18
|
|
|
19
|
+
## Templates
|
|
20
|
+
|
|
21
|
+
- [[Templates/session]] — session log หลังจบงานหรือ checkpoint สำคัญ
|
|
22
|
+
- [[Templates/handoff]] — ส่งต่องานค้างให้ session/agent ถัดไป
|
|
23
|
+
- [[Templates/project]] — project overview
|
|
24
|
+
- [[Templates/bug]] — bug report
|
|
25
|
+
- [[Templates/final]] — final gate เต็มก่อนบอกว่าเสร็จแล้ว; checklist ต้องมี evidence
|
|
26
|
+
- [[Templates/final-lite]] — final gate แบบสั้นสำหรับงานเล็กถึงกลาง; ใช้เกณฑ์ evidence เดียวกัน
|
|
27
|
+
|
|
19
28
|
## AI Routing Contract
|
|
20
29
|
|
|
21
30
|
- ก่อนเขียน: เช็กว่าเนื้อหาตรง "ใส่ที่นี่" และไม่เข้า "ไม่ใส่ที่นี่"; ถ้าก้ำกึ่งอ่าน [[Vault Structure Map]] ก่อน
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [template, final-gate, verification, lite]
|
|
3
|
+
note_type: template
|
|
4
|
+
created: YYYY-MM-DD
|
|
5
|
+
updated: YYYY-MM-DD
|
|
6
|
+
parent: "[[Templates/_Index]]"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# YYYY-MM-DD - <task/topic> - Final Gate Lite
|
|
10
|
+
|
|
11
|
+
> Final gate แบบสั้นสำหรับงานเล็กถึงกลาง: ยังต้องล็อก objective, evidence, risk, final answer, และ memory routing; ถ้า row ไม่มี evidence ห้าม mark `PASS`
|
|
12
|
+
|
|
13
|
+
## 0. Final Gate Rule
|
|
14
|
+
|
|
15
|
+
- [ ] Created before the owner-facing final answer.
|
|
16
|
+
- [ ] Every `PASS` has evidence.
|
|
17
|
+
- [ ] If a row has no evidence, it cannot be `PASS`.
|
|
18
|
+
|
|
19
|
+
Status: `PASS`, `PARTIAL`, `FAIL`, `N/A`, `BLOCKED`, `TODO`.
|
|
20
|
+
|
|
21
|
+
## 1. Objective / DoD Lock
|
|
22
|
+
|
|
23
|
+
Original request:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
<paste owner request or goal text here>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| DoD item | Status | Evidence |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Objective is concrete. | TODO | |
|
|
32
|
+
| Deliverable exists in the right place. | TODO | |
|
|
33
|
+
| Owner-facing answer can be backed by evidence. | TODO | |
|
|
34
|
+
|
|
35
|
+
## 2. Evidence-Backed Checklist
|
|
36
|
+
|
|
37
|
+
| Gate | Status | Evidence |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| Relevant context was read. | TODO | |
|
|
40
|
+
| No unrelated worktree changes were reverted. | TODO | |
|
|
41
|
+
| Verification ran at the right scope. | TODO | |
|
|
42
|
+
|
|
43
|
+
## 3. Status Matrix
|
|
44
|
+
|
|
45
|
+
| Work item / phase | Status | Evidence |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Implement/write/edit | TODO | |
|
|
48
|
+
| Verify | TODO | |
|
|
49
|
+
| Close memory/session if needed | TODO | |
|
|
50
|
+
|
|
51
|
+
## 4. Evidence Matrix
|
|
52
|
+
|
|
53
|
+
Commands:
|
|
54
|
+
|
|
55
|
+
| Command | Status | Important output | Scope proven |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| `<command>` | TODO | | |
|
|
58
|
+
|
|
59
|
+
Changed files:
|
|
60
|
+
|
|
61
|
+
| File | Change summary | Evidence |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `<file>` | | |
|
|
64
|
+
|
|
65
|
+
## 5. Residual Risk
|
|
66
|
+
|
|
67
|
+
| Risk or skipped check | Status | Evidence / reason |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| `<risk>` | TODO | |
|
|
70
|
+
|
|
71
|
+
## 6. Change Summary Audit
|
|
72
|
+
|
|
73
|
+
What changed:
|
|
74
|
+
|
|
75
|
+
- <short summary>
|
|
76
|
+
|
|
77
|
+
What did not change:
|
|
78
|
+
|
|
79
|
+
- <important non-change or unrelated worktree file>
|
|
80
|
+
|
|
81
|
+
## 7. Final Answer Draft
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
<short final answer>
|
|
85
|
+
|
|
86
|
+
Verified:
|
|
87
|
+
- <command/result>
|
|
88
|
+
|
|
89
|
+
Residual risk:
|
|
90
|
+
- <risk or "none known">
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 8. Second-Brain Routing / Memory Closeout
|
|
94
|
+
|
|
95
|
+
| Routing item | Status | Evidence |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| Session/index/current-state update needed? | TODO | |
|
|
98
|
+
| Durable memory/decision update needed? | TODO | |
|
|
99
|
+
| Search/index refresh needed? | TODO | |
|
|
100
|
+
|
|
101
|
+
## Final Verdict
|
|
102
|
+
|
|
103
|
+
| Verdict | Status | Evidence |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| Ready to close / caveat / blocked | TODO | |
|
|
106
|
+
|
|
107
|
+
One-line final state:
|
|
108
|
+
|
|
109
|
+
> <state + evidence>
|
|
110
|
+
|
|
111
|
+
up:: [[Templates/_Index]]
|