Your data never leaves your machine. Memories, preferences, boards, and scheduled jobs live in
~/.waywiser/β a SQLite database you own, files you can edit by hand, and a whole home you can nuke in onerm -rf. No telemetry, no cloud sync. Your LLM runs on your hardware or behind your own API key.
A proactive personal AI agent built on pi. Waywiser doesn't wait to be spoken to β it monitors your boards, goals, deadlines, and calendar, alerts you when something needs attention, adapts to your communication style, and learns from corrections in real time. Extends pi with persistent memory, a proactive cognition engine, behavioral meta-skills, task delegation, project boards, Google Calendar integration, MCP integrations, scheduled jobs, notifications, and a permission engine β all as in-process TypeScript extensions. Nothing patches pi's core.
waywiser/
βββ extensions/ β Core agent extensions
β βββ permissions.ts β Permission engine (9 risk classes, extensible classifiers, approval leases)
β βββ soul.ts β SOUL.md identity persistence (append-only)
β βββ memory.ts β Cross-session memory (FTS5, RecallProvider, deterministic gate)
β βββ memrules.ts β Memory rules (gate patterns, Jaccard, validation)
β βββ mem-dream.ts β Memory consolidation (dedup, merge, conflicts)
β βββ proactive.ts β Proactive cognition engine (OODA loop, signal gathering, calendar awareness)
β βββ meta-skills.ts β Behavioral engines (EQ, discretion, adaptability, multi-tasking)
β βββ brain/ β Persistent memory with procedural preferences (core β always loaded)
β β βββ index.ts β Brain lifecycle (session, learning boundary, vault sync)
β β βββ store.ts β BrainStore (SQLite, migrations, CRUD)
β β βββ recall.ts β Reciprocal rank fusion (lexical + scope + usage + confidence + recency + semantic)
β β βββ embeddings.ts β Embedding API (CPU-isolated, LRU cache, batch /api/embed)
β β βββ learner.ts β Two-pass learning (deterministic + LLM reflection)
β β βββ procedures.ts β Procedural preferences with evidence tracking
β β βββ evolve.ts β Auto-evolution pipeline (procedures β candidates β skills)
β β βββ cognition.ts β Cognition pool (pi RPC children for reflection)
β β βββ consolidate.ts β Dedup, merge, contradiction detection
β β βββ vault.ts β Obsidian-native markdown sync (wikilinks, Properties, MOCs)
β β βββ trace.ts β Experience trace (observations, outcomes)
β β βββ prompts.ts β Brain context rendering
β β βββ config.ts β Brain config loader
β β βββ policy.ts β Project-key detection, scoping
β β βββ eval.ts β Competitive skill evaluation
β β βββ provenance.ts β Memory provenance tracking
β β βββ recovery.ts β Crash recovery
β β βββ skills.ts β Skill discovery, promotion, rollback
β β βββ types.ts β Brain type definitions
β βββ kanban/ β Project boards (4 modules)
β β βββ index.ts β Extension wiring, /kanban command, kanban tool
β β βββ ops.ts β 25+ board/card CRUD operations
β β βββ worker.ts β Subagent card workers (spawnCard, waitCard)
β β βββ shared.ts β Types, constants, DB helpers, nextCardId (UUID)
β βββ kanban-server.ts β Localhost HTTP dashboard (token-authenticated, no CORS)
β βββ kanban-html.ts β Board HTML/CSS generation (live + static snapshot)
β βββ delegate.ts β Task delegation via RPC subprocesses (warm pool, depth-2)
β βββ execute-code.ts β Programmatic tool calling (vm.createContext sandbox + optional gondolin)
β βββ cronjob.ts β Scheduled jobs (cron parser, quiet hours, auto-pause on failure)
β βββ notify.ts β Desktop/Telegram/webhook notifications (spawn, no shell)
β βββ mcp.ts β MCP server loader (JSON-RPC 2.0 stdio, lazy connect, reconnect)
β βββ web.ts β Web search + extract (SSRF-guarded, HTML entity decoding)
β βββ commands.ts β Slash commands, goals (with budgets), /trace export, /journey
β βββ skills-manage.ts β Playbook catalog (tier badges, auto-onboard trigger)
β βββ todo-compat.ts β /todo β kanban compatibility shim
β βββ clarify.ts β User interaction tool
β βββ index.ts β Extension loader (fault-isolated, prompt assembly handler)
β βββ utils/
β βββ state.ts β Shared DB (SQLite WAL), registry, config, RecallProvider interface
β βββ tool-policy.ts β Extensible tool risk classifiers (plugin registration)
β βββ rpc.ts β Pi RPC client + warm pool (lane-versioned, TTL-evicted)
β βββ llmcall.ts β One-shot LLM child (queue-based semaphore, no deadlock)
β βββ prompt-budget.ts β Priority-based prompt injection manager (cache telemetry)
β βββ trace.ts β Structured trace events (TraceEvent, logTrace, logLegacy)
β βββ url-guard.ts β SSRF protection (RFC1918, link-local, loopback, IPv6)
β
βββ plugins/
β βββ google-workspace/ β Google Calendar integration via gog CLI
β β βββ shared/ β Shared infra (reusable for future Gmail, Drive, etc.)
β β β βββ gog-runner.ts β GogRunner interface + ProductionGogRunner (shell:false, caps, abort)
β β β βββ gog-contract.ts β Runtime capability probe (gog schema, contract cache)
β β β βββ gog-errors.ts β Exit code β CalendarErrorCode semantic mapping
β β β βββ accounts.ts β Account routing (alias, default, multi-account)
β β βββ extensions/calendar/ β Calendar semantic capability (loaded by bin/waywiser plugin discovery)
β β β βββ index.ts β Plugin entry (risk classifier, projection, tool registration)
β β β βββ tool.ts β Semantic `calendar` tool β 30+ actions dispatched
β β β βββ operations.ts β Operation manifest β single source of truth (dispatch + permissions)
β β β βββ types.ts β CalendarAction, CalendarEvent, CalendarStatus, OperationSpec
β β β βββ invocation.ts β Safety flag assembly (--readonly, --exact, --wrap-untrusted)
β β β βββ normalize.ts β Raw gog JSON β CalendarEvent normalization
β β β βββ idempotency.ts β Operation journal + Google-compatible event ID generation
β β β βββ projection.ts β Materialized SQLite projection for proactive SENSE
β β βββ skills/google-workspace/
β β β βββ SKILL.md β PA skill (safety rules, operations catalog, patterns)
β β βββ config/
β β βββ google-workspace.example.json β Default config (accounts, timeouts, safety)
β β
β βββ obsidian/ β Obsidian integration (optional add-on)
β βββ src/ β Plugin source (dashboard, commands, graph, watcher)
β βββ main.js β Built plugin
β βββ manifest.json
β βββ styles.css
β βββ sql-wasm.wasm
β
βββ skills/
β βββ waywiser/SKILL.md β Core operating skill (always loaded)
β βββ brain/SKILL.md β Brain operating skill (always loaded)
β βββ pa-*/SKILL.md β 19 PA playbooks (bootstrapped to ~/.waywiser/skills/)
β βββ pa-time-manage/ β
verified
β βββ pa-doc-writer/ β
verified
β βββ pa-stakeholder-comm/ β
verified
β βββ pa-research/ β
verified
β βββ pa-lifestyle/ β
verified
β βββ pa-onboard/ β
verified
β βββ pa-project-coord/ β οΈ experimental
β βββ pa-event-manage/ β οΈ experimental
β βββ pa-finance/ β οΈ experimental
β βββ pa-travel/ β οΈ experimental
β βββ pa-procurement/ β οΈ experimental
β βββ pa-decision-support/ β οΈ experimental
β βββ pa-process-improve/ β οΈ experimental
β βββ pa-tech-ops/ β οΈ experimental
β βββ pa-records/ β οΈ experimental
β βββ pa-hr-support/ π¬ untested
β βββ pa-compliance/ π¬ untested
β βββ pa-governance/ π¬ untested
β βββ pa-protocol/ π¬ untested
β
βββ bin/
β βββ waywiser β Launcher (core extensions, plugin discovery for extras)
β
βββ config/
β βββ SOUL.md β Default identity template
β βββ mcp.example.json β MCP server config example
β βββ notify.example.json β Notification channel config example
β βββ brain.example.json β Brain config example (recall, embeddings, vault, evolution)
β
βββ test/
β βββ waywiser.test.ts β Core unit tests (memory, gate, recall, goals, traces, meta-skills)
β βββ smoke.test.ts β Extension registration smoke test
β βββ permissions.test.ts β Permission engine tests (classifier, policy, budget, planning, plugins)
β βββ prompt-budget.test.ts β Prompt budget manager tests (ordering, trimming, cache)
β βββ brain/ β Brain unit tests (18 files, 332 tests)
β βββ google-workspace/ β Google Calendar plugin tests (8 files, 306 tests)
β β βββ gog-runner.test.ts β FakeGogRunner, shell injection safety
β β βββ gog-contract.test.ts β Capability probe, schema validation
β β βββ calendar-operations.test.ts β All 30 actions, risk mapping, manifest completeness
β β βββ calendar-safety.test.ts β Read path defense-in-depth (140 assertions)
β β βββ calendar-normalize.test.ts β Event normalization (timed, all-day, conference, recurring)
β β βββ calendar-errors.test.ts β Exit code β error code mapping
β β βββ calendar-idempotency.test.ts β Event ID generation, operation journal
β β βββ calendar-projection.test.ts β Transactional snapshot, stale handling, isolation
β βββ security/
β β βββ execute-code-sandbox.test.ts β vm.createContext sandbox escape prevention
β β βββ url-guard.test.ts β SSRF URL blocking
β β βββ kanban-auth.test.ts β Session token auth verification
β β βββ notify-spawn.test.ts β Shell injection prevention
β βββ e2e/ β End-to-end evals (require WAYWISER_E2E_MODEL)
β βββ helpers.ts β Test home, model gate, paths
β βββ memory-roundtrip.test.ts β Remember β recall preference
β βββ kanban-lifecycle.test.ts β Card new β move β done
β βββ delegation.test.ts β Spawn leaf β collect report
β βββ cron-fire.test.ts β Schedule one-shot β verify fire
β βββ adversarial.test.ts β Injection, oversized write, escape
β
βββ docs/
β βββ specs/ β Design specs (01-07)
β βββ audits/ β 4 audit reports + remediation plan
β βββ research/ β Proactive capabilities, Ollama contention, memory latency
β
βββ package.json β 1 production dep (typebox), Node β₯22.5
βββ SPEC.md β Original design spec
βββ LICENSE β MIT
Node >= 22.5, pi on PATH.
git clone git@github.com:yoda-digital/waywiser.git
cd waywiser
npm install
bin/waywiserThat's it. Brain (persistent memory with procedural preferences, RRF recall, auto-evolution, and vault sync) is a core component β it loads automatically on every launch. On first run, Waywiser walks you through setup: timezone, working hours, daily/weekly reviews, notification channels.
What you get out of the box:
Proactive intelligence:
- Proactive cognition engine β OODA loop ticks every 15 min, monitors boards/goals/deadlines/calendar, alerts without consuming GPU
- Calendar awareness β meeting-soon alerts, conflict detection, overloaded-day warnings from materialized projection (SQL-only, zero network in SENSE)
- Emotional intelligence β detects frustration from message patterns, adapts communication style in real time
- Discretion β suppresses low-value alerts during deep focus, caps notifications, respects quiet hours
- Adaptability β catches corrections instantly ("no, use X"), creates memories and adjusts same-session
- Multi-tasking β spawns background subagents for queued work during idle periods
Memory & learning:
- Cross-session memory (FTS5 + Brain's reciprocal rank fusion recall)
- Deterministic memory extraction per turn (CPU, ~1ms β no GPU contention)
- LLM-powered reflective learning at conversation boundaries
- Procedural preferences ("when X, prefer Y over Z") with evidence tracking
- Auto-evolution: mature procedures β candidate skills β competitive eval
- Embedding on CPU (
num_gpu: 0), LRU cache, batch API β zero GPU contention with generation - Memory export/import for data portability
- SOUL.md identity with consolidation
Tools & integrations:
- Google Calendar via gog β semantic
calendartool with 30+ operations (events, freebusy, conflicts, create, update, respond, focus-time, OOO, working-location), defense-in-depth read safety, write idempotency, materialized projection for proactive - Task delegation (3 concurrent subagents, depth-capped at 2)
- Kanban boards (authenticated web dashboard + TUI + markdown)
- MCP integrations (Gmail, Drive, Notion, etc.)
- Scheduled jobs (cron + one-shot timers, auto-pause on repeated failures)
- Desktop/Telegram/webhook notifications
- 19 PA playbooks covering time management, writing, communication, research, finance, travel, procurement, governance, and more
Safety & observability:
- Permission engine (9 risk classes including
unclassifiedfail-closed, extensible plugin classifiers, configurable policy, /permissions) - Approval leases β scoped preauthorization for headless/proactive operations (tool + action + account + time window + max executions)
- Planning mode (/plan blocks writes, /plan approve re-enables; allows read_only + network + mcp_read)
- Session budgets (200 tool calls, 10 subagent spawns)
- Calendar read safety β exact command allowlist + readonly transport guard + untrusted content wrapping on every live read
- Sandboxed code execution (vm.createContext + optional Gondolin micro-VM)
- SSRF protection on web tools
- Structured trace events (/trace export)
- Goal budgets (/goal --max-steps --deadline --done)
- Prompt cache telemetry (/waywiser status)
Requires gog (v0.37.0+, schema_version 1).
# Install gog, then authenticate
gog auth add
# Configure Waywiser
cat ~/.waywiser/google-workspace.json
# β Add your account(s) to "accounts" array:
# { "email": "you@example.com", "alias": "personal", "default": true }The calendar tool auto-discovers via plugin loading β no code changes
needed. Capabilities are validated at runtime via gog schema, not pinned
to a version string. The proactive engine picks up calendar signals
(meeting-soon, conflicts, overloaded-day) automatically from the
materialized SQLite projection.
Architecture:
Pi / LLM β calendar(action=events, ...) (semantic tool, no CLI knowledge)
β
Waywiser β permissions (risk classify β planning gate β approval)
β
Plugin β operation manifest β invocation builder β safety flags
β
GogRunner β spawn("gog", argv, { shell: false })
β
gog CLI β Google Calendar API
The Brain vault at ~/.waywiser/brain/ is already Obsidian-compatible
(wikilinks, Properties, callouts, mermaid). For a richer experience β
dashboard sidebar, command palette, graph coloring, confidence bars:
cd plugins/obsidian
npm install && npm run build
cp main.js manifest.json styles.css sql-wasm.wasm \
/path/to/vault/.obsidian/plugins/waywiser-brain/Enable in Obsidian β Settings β Community Plugins.
Waywiser runs a continuous OODA loop (Observe-Orient-Decide-Act) between user interactions. Every 15 minutes (30 during quiet hours), it:
- Senses β SQL-only signal gathering (zero LLM cost): overdue kanban cards, goals past deadline, goals near budget, cron failures, evolution candidates, user absence, calendar meeting-soon, calendar conflicts, calendar overloaded-day (from materialized projection)
- Orients β priority scores each signal (P0 interrupt β P3 background), deduplicates (1-hour window), applies discretion filter
- Decides + Acts β P0 alerts via desktop/Telegram (no GPU); P1-P2
triggers agent turn via
sendUserMessagefollowUp; P3 runs silently
The engine pauses during active conversation and re-arms when the agent
settles. /proactive controls it (on/off/tick/signals/status). Config
via ~/.waywiser/config.json:
{
"proactive": {
"enabled": true,
"tickActiveMs": 900000,
"tickQuietMs": 1800000
}
}Six cross-cutting meta-skills implemented as runtime behavioral engines:
| Meta-Skill | Engine | How it works |
|---|---|---|
| Emotional Intelligence | meta-skills.ts |
Analyzes message patterns at turn_end (short replies, corrections, caps); injects communication guidance into system prompt |
| Discretion | meta-skills.ts |
Filters proactive notifications; max 3/hour; suppresses during deep conversations (>5 turns); never sends sensitive content externally |
| Anticipatory Thinking | proactive.ts |
OODA loop scans boards, goals, calendar projection every 15 min; detects upcoming meetings, conflicts, overloaded days; prepares before deadlines hit |
| Adaptability | meta-skills.ts |
Detects corrections instantly; creates memories and injects one-turn adjustment notes ("no, use X" β immediate memory + style shift) |
| Multi-tasking | meta-skills.ts |
Spawns background subagents for kanban cards assigned to "subagent" during idle periods |
| Continuous Learning | Brain learner.ts |
Two-pass learning at conversation boundaries: deterministic extraction (CPU, ~1ms) + LLM reflection (nuanced signals) |
Manage via /meta-skills (status/emotional/discretion/corrections).
19 domain-specific playbooks. Each embeds a professional methodology (GTD,
Minto Pyramid, OODA Loop, DMAIC, etc.), few-shot examples, and tool
integration. They load on-demand via skill_view (progressive disclosure).
| Badge | Tier | Meaning |
|---|---|---|
| β | verified | Tested with β₯60% accuracy. Few-shot examples tuned. |
| experimental | Methodology-based but not yet empirically validated. | |
| π¬ | untested | Domain-expert playbook awaiting evaluation. |
| Tier | Playbooks |
|---|---|
| β Verified (6) | pa-time-manage pa-doc-writer pa-stakeholder-comm pa-research pa-lifestyle pa-onboard |
pa-project-coord pa-event-manage pa-finance pa-travel pa-procurement pa-decision-support pa-process-improve pa-tech-ops pa-records |
|
| π¬ Untested (4) | pa-hr-support pa-compliance pa-governance pa-protocol |
On first run, the pa-onboard setup wizard triggers automatically β captures
working hours, timezone, quiet hours, creates daily/weekly review crons,
initializes the PA kanban board.
- Permission engine β 9 risk classes (read_only, write_local,
process_exec, communication, network, scheduling, mcp_read, mcp_write,
unclassified). Policy per class: allow, block, ask_user, log_only.
Unknown tools β
unclassifiedβblock(fail-closed)./permissions - Extensible classifiers β plugins register per-tool risk classifiers
via
registerToolRiskClassifier(). Calendar plugin classifies each action (events β read_only, create β scheduling, respond β communication) - Approval leases β scoped preauthorization for headless/proactive
operations. Constrained by tool, action, account, calendar, time window,
and max executions. No global
allow calendar - Planning mode β
/planblocks writes;/plan approvere-enables. Allows read_only + network + mcp_read. Allowlist never bypasses planning - Session budgets β 200 tool calls, 10 spawns (configurable)
- Calendar read safety β every live read uses
--readonly+--enable-commands-exact+--no-input+--wrap-untrusted+--json. Model cannot construct arbitrary gog argv - Write idempotency β deterministic Google-compatible event IDs + operation journal prevents duplicate creation on retry
- Sandbox β
vm.createContext(Object.create(null))+ 5s timeout; optional gondolin micro-VM - SSRF guard β blocks RFC1918, link-local, loopback, IPv6 ULA in web_extract
- Kanban auth β per-session Bearer token, no CORS
- Notifications β
spawn()with argument arrays (no shell)
All config lives in ~/.waywiser/:
| File | Purpose |
|---|---|
waywiser.db |
SQLite database (memory, boards, cron, goals, brain, calendar projection, approval leases) |
brain.json |
Brain config (recall, embeddings, vault, evolution) |
google-workspace.json |
Google Calendar config (accounts, timeouts, projection, safety flags) |
config.json |
Global config (prompt budget, execute_code backend, proactive engine) |
permissions.json |
Permission policy (risk class defaults, per-tool overrides, allowlist) |
SOUL.md |
Agent identity and preferences (append-only) |
MEMORY.md |
Append-only memory log (human-readable mirror) |
USER.md |
User profile |
mcp.json |
MCP server configuration |
notify.json |
Notification channel setup (desktop, Telegram, webhook) |
mem.json |
Memory subsystem tuning (auto, recall mode, gate timeout) |
quiet.json |
Quiet hours window (HH:MM-HH:MM) |
brain/ |
Brain vault (Obsidian-compatible markdown) |
boards/ |
Kanban board markdown exports |
skills/ |
PA playbooks + evolved skills (active/candidates/retired) |
# Everything β core + security + proactive + meta-skills + Brain + Calendar
npm test # 760+ tests
# Google Calendar plugin only (8 suites, 306 tests)
node --test test/google-workspace/*.test.ts
# Brain only (76 suites)
npm run test:brain # 332 tests
# End-to-end evals (requires a running LLM)
WAYWISER_E2E_MODEL=qwen3:latest npm run test:e2e # 6 testsMIT
Built on pi. MIT.