Discipline. Execution. No excuses.
Shadow. Eye. Brain. Hands. It acts like me, but it is not me. Ask carefully once → act confidently forever.
SEAL is an autonomous Tech-Lead assistant. It watches your git activity, notices the patterns you repeat, drafts safe automations, asks you once, and then handles every future similar thing on its own. It also routes unknown data — an email, a message, a chat line — into a "I don't recognize this, teach me" loop that turns into a reusable handler after a single conversation.
SEAL only acts on things it's confident about and that you approved it to care about. When a pattern isn't clear enough, a proposal isn't safe enough, or incoming data doesn't match any teaching you've given it, SEAL stops and asks. The rule is simple: high confidence + prior approval → act; anything less → raise a hand. No surprise side effects, no silent escalations, no "I thought you meant…".
seal start # runner + dashboard in the background
seal open # http://localhost:3333
# That's it. Use your machine. SEAL watches and proposes.| Part | What it is | What it does |
|---|---|---|
| 👤 Shadow | The identity | Follows you silently. Mirrors your shape. Never acts without your nod. |
| 👁️ Eye | Observers | Sees what you do (git hooks, shell, file events) and what arrives for you (email, chat, calendar). |
| 🧠 Brain | Detector + LLM | Notices patterns. Interprets inputs. Drafts plans. Never decides alone. |
| 🖐️ Hands | Skill Factory + Flow Engine | Runs the automations you approved. Sandboxed. Every run is traceable to an approval. |
The ethical rule — "it acts like me, but it is not me" — is what separates SEAL from every other agent framework. SEAL learns, drafts, and executes on your behalf, but every output is labeled, every action traces back to an explicit approval, and nothing irreversible happens without you clicking a button once. When in doubt, SEAL asks. It never guesses.
The "ask" gates are concrete, not decorative:
- Pattern detector — only promotes a pattern to a proposal when
confidence >= 0.75 AND evidence_count >= 3. Weak patterns stay observing and never reach you. - Proposer — never auto-approves. Every drafted automation sits in the Proposals tab until you click one of the five decision buttons. 7-day TTL, max 3 per day.
- Ingest router — data that matches a taught handler runs automatically; anything unmatched lands in the Ingest queue with an LLM-drafted interpretation + handler proposal for you to approve or ignore.
- Drafted scripts themselves — the proposal prompt explicitly forbids auto-commit, auto-push, auto-send, and any irreversible default. Scripts echo commands, use
read -pconfirmations, save-as-draft instead of send, and surface risks in the Risk block of the proposal card.
Six capability pillars. Each one maps to a concrete component already shipped:
- Capture — Routes any unknown data (email, chat, event, arbitrary JSON) into a teaching conversation. (v0.10.0 ingest loop ·
POST /api/ingest) - Orchestrate — Declarative YAML flow engine or imperative shell scripts as skill backends. Step types:
llm.ask,shell.run,ask_user.prompt, adapter calls. (v0.7.0 flow engine · v0.6.0 skill factory) - Execute — Sandboxed skill runner with three invocation paths:
- Manual — you type
seal run <name>or click Run in the dashboard. - Auto (approved + confident) — once SEAL has learned a pattern and you approve the handler, every future similar event runs the skill automatically without re-asking. An email that matches the
newclient-proposal-reviewhandler fires through its flow and notifies you; a git event that matches adata_matchhandler runs the same way. The single approval moment pays for every future run. - Ask (unsure or unauthorized) — if a pattern is below the confidence threshold, an incoming event doesn't match any taught handler, or a drafted script contains a risk the TL hasn't explicitly approved, SEAL doesn't run. It drops the situation into Proposals or the Ingest queue and waits for you. The pillar is "high confidence + prior approval → act; anything less → ask". (v0.6.0 script runner · v0.10.0 handler router · the Permission Gate in every pipeline)
- Manual — you type
- Remember — Typed SQLite FTS5 memory layer. Four kinds (user / feedback / project / reference) following Claude Code's frontmatter pattern, plus daily scratch notes that a dreaming sweep consolidates into durable memories. (memory layer commit · the Brain's context on every turn)
- Learn — Observes your git activity, detects sequence and naming patterns, and drafts safe automations through the LLM for you to approve. Max 3 proposals per day, 7-day TTL, five decision shapes. (v0.4.0 detector · v0.5.0 proposer)
- Optimize — Token-aware execution. RTK compresses CLI output 60–90% before it hits the LLM context. The memory layer is pure
better-sqlite3+ FTS5 — no Python subprocess, no fallback chains. (RTK integration · native memory layer)
The loop is the payoff: Learn → (approve once) → Execute automatically forever. You teach SEAL once per pattern. After that it just does the thing.
git hooks → events → patterns → proposals → [approve once] → skill → future auto-runs
- v0.3.0 "SEAL sees" — passive observation. Git hooks installed per repo, events persisted 90 days, no inference.
- v0.4.0 "SEAL notices" — sequence detector (
A → B within 10m) and naming detector (branch/tag regex library). - v0.5.0 "SEAL proposes" — LLM drafts a shell/flow automation for patterns past the confidence threshold. Five decisions: approve + save / approve once / modify / deny / suppress. Max 3 per day. 7-day TTL.
- v0.6.0 "SEAL remembers" — approved proposals become persistent skills under
~/.config/seal/skills/<name>/. Invoke from CLI, dashboard, or chat. - v0.7.0 "SEAL follows steps" — skills can be declarative YAML flows instead of shell scripts. Step types:
llm.ask,shell.run,ask_user.prompt,set.<key>.
email/chat/event → handler match? → yes: run. no: LLM interprets → TL teaches once → handler born
- v0.10.0 "SEAL asks back" — data arriving at SEAL that no handler matches is parked in an
ingest_queue. The LLM drafts a complete handler proposal (match criteria +flow.yaml). You approve once, the handler skill is born, and every future similar event runs through it automatically.
Both loops go through the same Brain → Permission Gate → Hands pipeline. The Permission Gate is a human clicking a button. Once. No escalation ladder.
curl -fsSL https://raw.githubusercontent.com/ulisseshen/seal/main/install.sh | bashThe installer:
- Clones the repo to
~/projects/seal(or$SEAL_INSTALL_DIR) - Runs
npm install - Installs RTK (token compression) via brew or curl
- Installs MemPalace optionally (native SQLite FTS5 memory layer is the default)
- Copies the
/sealskill into Claude Code, Codex, Antigravity, and Cursor runtimes it detects - Symlinks
sealinto/usr/local/bin(or~/.local/bin) — a real binary, not a shell alias - Scrubs any prior SEAL shell aliases from your
.zshrc/.bashrc
# 1. Configure a chat provider (interactive menu, or use flags)
seal setup # interactive
seal setup provider gemini --token X # token-based
seal setup provider codex --login # delegates to codex login
seal setup status # summary
# 2. Start the services in the background
seal start # runner + dashboard
seal ps # verify both are running
seal open # http://localhost:3333
# 3. Give the Eye something to watch
# → Dashboard → Workspaces tab → "Add workspace" → pick a git folder
# (installs git hooks so commits/branches/tags flow into the events table)
# 4. Poke the ingest loop without waiting for real events
# → Dashboard → Ingest tab → "drop test data" formSEAL is now watching. As you work, the detector builds up patterns. Every ~15 minutes the proposer looks at what's ready, drafts up to 3 proposals per day, and drops them in the Proposals tab with approve / deny / modify buttons. Approved proposals become skills you can invoke from seal run <name>.
Daemon
seal start [runner|dashboard] start background services (default: both)
seal stop [runner|dashboard] stop background services
seal restart [runner|dashboard] stop + start
seal ps show running services + PIDs
seal logs [runner|dashboard] [-f] tail service logs
seal open open the dashboard in the browser
Setup
seal setup interactive menu
seal setup status show configured providers/channels
seal setup provider <name> interactive token / select default
seal setup provider <name> --token X [--model Y]
seal setup provider codex --login delegate to `codex login`
seal setup provider <name> --remove
seal setup channel <name> --set key=value
Skills
seal skills list installed skills
seal run <name> [args...] invoke a skill
SEAL supports five LLM backends behind a single interface — chat, proposal drafting, and ingest teaching all use the same abstraction:
| Provider | Auth | Notes |
|---|---|---|
| Claude | claude /login |
Delegates to the Claude Code CLI. Default model: claude-opus-4-6. |
| Codex | seal setup provider codex --login |
Delegates to the codex login CLI. Default: gpt-5. |
| Gemini | seal setup provider gemini --token <key> |
HTTP SSE against the Google Generative Language API. Default: gemini-2.5-pro. 1M context is the natural fit for the Brain's watcher role. |
| OpenAI | seal setup provider openai --token <sk-...> |
HTTP SSE against /v1/chat/completions. Default: gpt-4.1-mini. |
| Ollama | seal setup provider ollama --host http://... |
Local NDJSON stream. No credentials. Default: llama3.1. |
API keys live in the macOS Keychain (service seal) or a chmod 600 fallback at ~/.config/seal/secrets.json. They are never written into chat-config.json or any world-readable file.
Two flavors of channel, and they're not the same thing:
- Input channels are how you talk to SEAL — drop a bug report, a test message, a thought, a voice note, or arbitrary JSON at the ingest loop.
- Approval channels are where SEAL asks you back — pending proposals, unmatched ingest events, and any
ask_userstep a running flow hits.
On day one, both roles are fully covered by the dashboard. Proposal-approval UX through messaging-app buttons (Telegram inline keyboards, Discord components, WhatsApp keyword replies) is planned but not wired — so instead, SEAL sends a push alert through your configured channels whenever a proposal or ingest event lands, and the alert embeds the dashboard URL so you open, read, and approve from your phone browser in one tap. Configured via seal setup alerts. See below.
| Channel | Status | How it works |
|---|---|---|
| Dashboard Chat tab | ✅ working | Live-streaming chat against any configured provider. Markdown rendering, persisted history (chat_messages FTS5), provider switcher. Fastest feedback loop. |
POST /api/ingest |
✅ working | REST endpoint. Drop {source, data} and SEAL runs the ingest router (match → run, or interpret → queue for teaching). Curl-friendly, scriptable. |
/seal skill inside Claude Code / Codex / Antigravity / Cursor |
✅ working | install.sh copies the skill into the runtime's skill directory. Invoke with /seal <natural language> — creates tasks, reminders, notes, rituals. Works from any editor session. |
| Telegram bot | 🟡 receive only | Bot token via @BotFather, configured in ~/.config/seal/ingest.json. Incoming messages become SEAL tasks. Inline approval buttons not wired yet. |
| Discord bot | 🟡 receive only | Developer Portal bot, DM-only by default. Same status as Telegram. |
| WhatsApp (Baileys) | 🟡 receive only | Scans a QR on first run. Text-only — WhatsApp has no buttons, so approvals will eventually use keyword replies (/seal approve 42). |
| Gmail | 🟡 receive only | IMAP polling or a Cloudflare Worker webhook. Emails sent to your SEAL address become tasks. |
| Voice notes | 🟡 receive only | Drop an audio file, whisper-cli transcribes it, SEAL ingests the text. |
| Shell ingest (v0.12.0) | 🔲 planned | Opt-in .zshrc hook for shell-event patterns. |
SEAL only raises a hand when something isn't approved-and-confident. When that happens, the request needs to reach you on a channel you're willing to check. The approval surfaces today:
| Surface | Status | What you approve there |
|---|---|---|
| Dashboard → Proposals tab | ✅ working | LLM-drafted automations from observed patterns. Five decision buttons: Approve + save · Once only · Modify · Deny · Suppress. Edit the script inline before approving. 7-day TTL visible per card. |
| Dashboard → Ingest tab | ✅ working | Unmatched events with the LLM's interpretation + a drafted handler (match criteria + flow.yaml). Two buttons: Approve handler (→ skill is born and all future similar events run through it automatically) · Ignore. |
| Dashboard → Missions tab | ✅ working | Policy-blocked tasks (status: firing) wait here for your explicit ack. The existing v0.2.0 permission gate. |
| macOS notifications | ✅ working | nuclear / supernova levels fire alert dialogs and re-fire until acknowledged — the "you will see this" escalation. |
| Push alert → phone browser | ✅ working | New proposals and ingest events fire through seal setup alerts targets (macOS notification + Telegram + Discord webhook). Each alert embeds a deep link to /#proposals or /#ingest. You tap, the responsive dashboard opens, you approve there. Works from anywhere your phone has network access to the dashboard URL. |
| Telegram / Discord inline keyboard | 🔲 planned | Approve/deny/modify buttons on proposal delivery from inside the chat app, so you don't even open the dashboard. The alerting path above unblocks mobile reach today; inline buttons are the follow-up that skips the dashboard hop. |
| WhatsApp keyword reply | 🔲 planned | /seal approve 42 / /seal deny 42 since WhatsApp has no buttons. |
seal setup alerts status # show configured channels
seal setup alerts test # fire a test alert to every channel
seal setup alerts telegram --token X --chat-id Y
seal setup alerts discord --webhook https://...
seal setup alerts url https://seal.yourdomain # for phones outside localhost
seal setup alerts macos off # mute desktop notificationsAlert config lives at ~/.config/seal/alerts.json. Telegram alerts use raw HTTPS (no bot process needed), Discord uses a webhook URL (no bot process needed), macOS uses osascript. Fire-and-forget — alert failures never break the proposer or ingest router.
- Want to poke SEAL right now → Dashboard Chat tab or
curl POST /api/ingest. - Want to approve pending work → Dashboard Proposals or Ingest tab. That's the single source of truth until messaging-app buttons are wired.
- Want mobile reach → Telegram / Discord / WhatsApp / Gmail are already receiving. You'll use the dashboard on your phone's browser to approve, which works fine — the dashboard is responsive.
seal open launches the dashboard at http://localhost:3333. Tabs:
- Missions — the existing task queue (tasks, reminders, rituals, deadlines, decisions, people).
- Channels — notification targets (Telegram, Discord, Slack, system).
- Chat — live streaming chat against any configured provider. Markdown rendering, SQLite persistence, provider switcher.
- Logs — execution log of every task run.
- Calendar — 7-day view of scheduled tasks.
- Workspaces — git repos SEAL is watching. Native folder picker, one-click hook install.
- Events — live read-only tail of the events table (git commits, branches, tags, merges, pushes).
- Patterns — detected sequence + naming patterns with confidence scores. "Scan now" button.
- Proposals — LLM-drafted automations awaiting your approval. Five decision buttons.
- Skills — installed library. Per-skill run form, run history, counters.
- Ingest — unknown data queue, LLM interpretation, drafted handler, approve-to-create.
~/.config/seal/
tasks.db SQLite (tasks, events, patterns, proposals, decisions,
skills, handler_matchers, ingest_queue, memories, chat_messages)
secrets.json fallback secret store (macOS uses Keychain instead)
chat-config.json {provider, model, system_prompt}
channels.json notification channel config
ingest.json inbound channel config (telegram/whatsapp/discord/gmail)
run/ PID files for running daemons
logs/ daemon log files
skills/<name>/ installed skills
├── skill.json
├── script.sh or flow.yaml
├── README.md
└── runs.jsonl
┌─────────────────────────────────────────────────────────────────┐
│ SEAL (seal binary) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ Observers│ │ Brain │ │ Skill Factory│ │ Dashboard │ │
│ │ (Eye) │─▶│ Detector │─▶│ + Flow Eng. │◀─┤ + REST API │ │
│ │ │ │ Proposer │ │ (Hands) │ │ │ │
│ │ git.js │ │ Ingest │ │ │ │ Express │ │
│ │ + hooks │ │ │ │ │ │ │ │
│ └────┬─────┘ └─────┬────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └──────────────┴──────────────┴──────────────────┘ │
│ │ │
│ ┌─────────────────────────┴───────────────────────────────┐ │
│ │ SQLite (tasks.db) │ │
│ │ events · patterns · proposals · decisions · skills │ │
│ │ handler_matchers · ingest_queue · memories (FTS5) │ │
│ │ chat_messages (FTS5) · watched_repos · tasks │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────┴───────────────────────────────┐ │
│ │ Provider Abstraction (unified stream API) │ │
│ │ Claude · Codex · Gemini · OpenAI · Ollama │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
- Node.js 18+
- An AI coding CLI (optional) — Claude Code, Codex, Antigravity, or Cursor — if you want
/sealskill invocation from inside an assistant - macOS for full notification + Keychain support (Linux: degraded notifications, file-based secret fallback)
sqlite3CLI — only needed by the legacy/sealskill; the daemon usesbetter-sqlite3natively- Optional: RTK for token compression on task execution
- Optional:
ffmpeg+whisper-clifor voice-note transcription
SEAL's Brain pulls context before every task using a three-layer recall:
- Pinned memories — typed (
user/feedback/project/reference) from Claude Code's frontmatter pattern, always loaded for the task's project - FTS5 memory search — top-5 semantic-ish matches over the
memoriestable, porter-stemmed - FTS5 chat recall — top-3 matches over the persistent chat history
The sync side writes task outcomes into memory_scratch as daily ephemeral notes. A future dreaming sweep consolidates recurring scratch into durable memories — the OpenClaw pattern.
| Type | Description | Auto-executes? |
|---|---|---|
task |
Something Claude should do (with prompt) | Yes — via claude -p |
note |
Memory-only — idea, evaluation, context | No — stored for reference |
reminder |
Something you need to remember | No — fires notification |
ritual |
Recurring task or reminder | Yes — recalculates next run |
deadline |
Project deadline or freeze | No — fires notification |
person |
Info about a team member | No — searchable context |
decision |
Architectural or team decision | No — searchable context |
| Level | What happens | Can be ignored? |
|---|---|---|
silent |
Logs to SQLite only | Yes |
sound |
macOS notification + sound | Yes |
sticky |
Persistent notification + terminal bell | Harder |
nuclear |
Alert dialog + voice announcement | Blocks until clicked |
supernova |
Nuclear, but re-fires every 5 minutes until acknowledged | No |
- Claude Code — typed-frontmatter memory pattern (user / feedback / project / reference)
- Hermes Agent — prefetch-before-turn / sync-after-turn memory lifecycle, capacity-forced consolidation
- OpenClaw — daily-notes → durable promotion ("dreaming sweep")
- MemPalace — verbatim memory with vector search (SEAL's native FTS5 layer replaces the Python subprocess)
- RTK — token compression for CLI output
- Extreme Ownership — the leadership philosophy behind the name
"There are no bad teams, only bad leaders." — Jocko Willink
| Runtime | Status |
|---|---|
| Claude Code | Supported |
| Codex | Supported |
| Antigravity | Supported |
| Cursor | Supported |
MIT