diff --git a/.aws/config b/.aws/config index 39599ff..6fa526a 100644 --- a/.aws/config +++ b/.aws/config @@ -25,3 +25,69 @@ sso_session = rzaws-sw-rai sso_account_id = 669031108410 sso_role_name = dev_Restricted region = us-east-1 + +[profile rzaws-sw-rai-ava-dev] +sso_session = rzaws-sw-rai +sso_account_id = 534546104464 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-ava-prod] +sso_session = rzaws-sw-rai +sso_account_id = 574548986353 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-ava-rc] +sso_session = rzaws-sw-rai +sso_account_id = 129898047946 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-cs-dev] +sso_session = rzaws-sw-rai +sso_account_id = 555292118981 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-cs-prod] +sso_session = rzaws-sw-rai +sso_account_id = 352821214080 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-cs-rc] +sso_session = rzaws-sw-rai +sso_account_id = 345692661332 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-preprod] +sso_session = rzaws-sw-rai +sso_account_id = 239732580264 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-qac-prod] +sso_session = rzaws-sw-rai +sso_account_id = 615471542132 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-voicekit-dev] +sso_session = rzaws-sw-rai +sso_account_id = 576393818327 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-voicekit-prod] +sso_session = rzaws-sw-rai +sso_account_id = 427880591172 +sso_role_name = dev_Restricted +region = us-east-1 + +[profile rzaws-sw-rai-voicekit-rc] +sso_session = rzaws-sw-rai +sso_account_id = 045861053828 +sso_role_name = dev_Restricted +region = us-east-1 diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 3f36bb9..d671816 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -1,6 +1,6 @@ # Roadmap: ngn-agent -**Current Phase:** None yet — start with Phase 1 +**Current Phase:** Phase 2 — Memory, Git & Session Management **Total Phases:** 4 **v1 Requirements:** 22 mapped — all covered ✓ diff --git a/.planning/research/hermes/AUTOMATION.md b/.planning/research/hermes/AUTOMATION.md new file mode 100644 index 0000000..75e5961 --- /dev/null +++ b/.planning/research/hermes/AUTOMATION.md @@ -0,0 +1,104 @@ +# Hermes Agent: Automation (Cron) + +## Capabilities + +Hermes has a full cron system built into the gateway daemon. Everything below is available through the `cronjob` tool — the agent can set it up via conversation. + +## Job Types + +| Type | Schedule | Example | +|------|----------|---------| +| One-shot | Relative delay | `30m`, `2h` | +| Recurring | Interval | `every 30m`, `every 2h` | +| Recurring | Cron expression | `0 9 * * *` | +| One-shot | ISO timestamp | `2026-03-15T09:00:00` | +| **No-agent mode** | Any schedule | Script-only, zero LLM cost | + +## Delivery Targets + +``` +origin → Back to where the job was created +local → Save to ~/.hermes/cron/output/ +telegram → Telegram home channel +discord → Discord +slack → Slack +email → Email +all → Every connected platform +"telegram:123:456" → Specific chat + thread +``` + +## No-Agent Mode (Script-Only) + +For watchdogs, disk checks, health pings — zero LLM cost: + +```bash +# Script at ~/.hermes/scripts/check-disk.sh +# Agent skips this entirely — just runs script, delivers stdout +hermes cron create "every 5m" --no-agent --script check-disk.sh --deliver telegram +``` + +- Empty stdout → silent tick (no delivery) +- Non-zero exit → error alert delivered +- `{"wakeAgent": false}` → silent tick + +## Skill-Backed Cron Jobs + +Load one or more skills before running the prompt: + +```python +cronjob(action="create", skill="blogwatcher", + prompt="Check configured feeds, summarize anything new.", + schedule="0 9 * * *", name="Morning Feeds") +``` + +## Job Chaining + +```python +cronjob(action="create", name="daily-digest", + schedule="every day 7am", + context_from=["ai-news-fetch", "github-prs-fetch"], + prompt="Write the daily digest using the outputs above.") +``` + +## Job Lifecycle + +``` +hermes cron list +hermes cron pause +hermes cron resume +hermes cron run +hermes cron edit --schedule "every 4h" +hermes cron remove +``` + +## Provider Recovery for Cron + +Cron jobs inherit fallback_providers and credential pool rotation. Per-job provider override: + +```python +cronjob(action="create", schedule="every 2h", + provider="openrouter", model="google/gemini-3-flash-preview", + prompt="Check server status") +``` + +## Scheduled Task (Chat) + +``` +/cron add "every 1h" "Summarize new feed items" --skill blogwatcher +``` + +## Key ngn-agent Use Cases + +| Use Case | How | +|----------|-----| +| Daily report | Cron + skill → delivered to Telegram | +| Stale session cleanup | Cron + no-agent script to list, archive old sessions | +| Jira summary | Cron + MCP Jira skill → delivered to Telegram | +| Infra health check | Cron + no-agent script, deliver only on error | +| S3 cleanup monitoring | Cron + AWS CLI script, wakeAgent only when issue found | + +## ngn-agent should NOT build + +- Custom scheduler (use Hermes cron) +- Report delivery system (use cron delivery targets) +- Script execution (use no-agent mode) \ No newline at end of file diff --git a/.planning/research/hermes/EXTENSIBILITY.md b/.planning/research/hermes/EXTENSIBILITY.md new file mode 100644 index 0000000..7511876 --- /dev/null +++ b/.planning/research/hermes/EXTENSIBILITY.md @@ -0,0 +1,109 @@ +# Hermes Agent: Extensibility (Plugins, MCP, Profiles) + +## Plugin System + +Plugins add tools, hooks, CLI commands, and slash commands without modifying Hermes core. + +### Structure +``` +~/.hermes/plugins/my-plugin/ +├── plugin.yaml # Manifest +├── __init__.py # register(ctx) — wires schemas to handlers +├── schemas.py # Tool schemas (what the LLM sees) +└── tools.py # Tool handlers (what runs when called) +``` + +### Capabilities + +| Capability | API | Use for ngn-agent | +|------------|-----|-------------------| +| Add tools | `ctx.register_tool()` | Jira/Confluence tools | +| Add hooks | `ctx.register_hook()` | Log infra commands, enforce guardrails | +| Add slash commands | `ctx.register_command()` | /jira, /confluence shortcuts | +| Add CLI commands | `ctx.register_cli_command()` | `ngn check-health`, `ngn report` | +| Inject messages | `ctx.inject_message()` | Alert the agent mid-conversation | +| Bundle skills | `ctx.register_skill()` | Ship infra skills with plugin | +| LLM access | `ctx.llm.complete()` | Run LLM calls from plugin code | +| Register platform | `ctx.register_platform()` | Custom gateway channels | + +### Plugin Lifecycle + +```bash +hermes plugins # Interactive toggle UI +hermes plugins list # Table: enabled/disabled/not enabled +hermes plugins install user/repo # Install from GitHub +hermes plugins enable my-plugin # Add to allow-list +``` + +Plugins are opt-in: `plugins.enabled` in config.yaml + +### Available Hooks + +| Hook | Fires | Use | +|------|-------|-----| +| pre_tool_call | Before any tool | Log all commands, check IAM scope | +| post_tool_call | After any tool | Capture tool results for audit | +| pre_llm_call | Once per turn | Inject context like current IAM role | +| post_llm_call | After LLM turn | Save learnings | +| on_session_start | New session | Set up context, load env facts | +| on_session_end | Session ends | Archive session, capture memory | + +## MCP (Model Context Protocol) + +MCP servers add external tools by declaring them in config.yaml: + +```yaml +mcp_servers: + github: + command: npx + args: ["-y", "@modelcontextprotocol/server-github"] + env: + GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_..." +``` + +**No plugin code needed** — just config. Tools are auto-discovered and registered alongside built-in tools. Perfect for Jira, Confluence, or any MCP-compatible service. + +## Profiles (Multi-Agent) + +Profiles are separate Hermes homes with their own config, .env, memory, skills, and gateway. + +```bash +hermes profile create coder # Create profile + "coder" CLI command +coder chat # Chat with coder profile +coder gateway start # Start coder's gateway separately + +hermes profile list # Show all profiles +hermes profile use coder # Set as sticky default +``` + +### Storage +``` +~/.hermes/ # Default profile +~/.hermes/profiles/coder/ # Named profile +~/.hermes/profiles/research/ # Another profile +``` + +### Profile Sharing +```bash +hermes profile export coder # Export as tar.gz +hermes profile install github.com/you/research-bot # Install from git +``` + +Each profile can have different: +- LLM providers/models +- Bot tokens (separate Telegram bot per profile) +- Skills +- Memory +- Cron jobs +- Security settings + +## ngn-agent Implications + +- **Don't build a plugin system** — Hermes already has one +- **Use MCP for Jira/Confluence** — no code, just config +- **Create a custom plugin** for ngn-agent-specific hooks: + - `pre_tool_call` hook to verify IAM scope before AWS commands + - `on_session_start` hook to inject current environment context + - `post_tool_call` hook to audit all infra actions +- **Use profiles** if ngn-agent needs separate identities (e.g., dev vs prod gateways) +- **Profile isolation** means we can run multiple ngn-agent instances independently \ No newline at end of file diff --git a/.planning/research/hermes/GATEWAY.md b/.planning/research/hermes/GATEWAY.md new file mode 100644 index 0000000..a3c939e --- /dev/null +++ b/.planning/research/hermes/GATEWAY.md @@ -0,0 +1,105 @@ +# Hermes Agent: Gateway System (Messaging) + +## Platform Support + +Hermes supports 20+ messaging platforms. Key ones for ngn-agent: + +| Platform | Voice | Images | Files | Threads | Reactions | Typing | Streaming | +|----------|-------|--------|-------|---------|-----------|--------|-----------| +| **Telegram** | ✅ | ✅ | ✅ | ✅ | — | ✅ | ✅ | +| **Discord** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| **Slack** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| **Microsoft Teams** | — | ✅ | — | ✅ | — | ✅ | — | +| **Email** | — | ✅ | ✅ | ✅ | — | — | — | + +## Telegram Setup + +```bash +# Interactive wizard +hermes gateway setup + +# Or manual: +# 1. Create bot via @BotFather → get token +# 2. Set TELEGRAM_BOT_TOKEN in ~/.hermes/.env +# 3. Set TELEGRAM_ALLOWED_USERS or use DM pairing +# 4. Start gateway: hermes gateway +# 5. Register as service: hermes gateway install +``` + +## Security & User Authorization + +**Default: deny all.** Every user must be in an allowlist or paired via DM. + +```yaml +# Allowlist (recommended for known users) +TELEGRAM_ALLOWED_USERS=123456789 + +# DM pairing (alternative — users get pairing codes) +# User DMs bot → gets code "XKGH5N7P" +# Admin approves: hermes pairing approve telegram XKGH5N7P +# Code expires 1hr, cryptographic randomness, rate-limited + +# Admin vs Regular user split +gateway: + platforms: + telegram: + extra: + allow_from: ["111", "222"] + allow_admin_from: ["111"] + user_allowed_commands: [status, model] +``` + +## Session Management + +```yaml +session_reset: + mode: both # both | idle | daily | none + idle_minutes: 1440 # 24 hours + at_hour: 4 # 4 AM daily +``` + +Per-platform overrides: +```json +{ + "reset_by_platform": { + "telegram": { "mode": "idle", "idle_minutes": 240 } + } +} +``` + +## Gateway Commands + +``` +hermes gateway # Run in foreground +hermes gateway setup # Configure platforms interactively +hermes gateway install # Install as service (launchd/systemd) +hermes gateway start/stop/status +``` + +## Gateway Slash Commands (inside chat) + +`/new /reset /model /retry /undo /status /stop /approve /deny /sethome` +`/compress /background /platform /skills /cron /help` + +## Multi-Platform Operations + +- `/platform list|pause|resume` — manage individual adapters without restart +- Automatic circuit breaker — pauses adapter on repeated failures +- Restart notifications — sends "agent is back" to home channels +- Session resume across restarts — auto-recovers interrupted sessions + +## Admin vs Regular Users + +Two tiers: admin (full access) and user (restricted slash commands). Configured per platform per scope (DM vs group). Use `/whoami` to check your access. + +## Background Sessions + +`/background Check all servers` spawns isolated async agent. Results delivered to originating chat when done. Non-blocking — main chat stays interactive. + +## Key ngn-agent Considerations + +- **Start with Telegram** — most accessible, mobile-friendly +- **Use DM pairing** for initial setup, switch to allowlist for stability +- **Set session_reset.mode: idle** with longer timeout for infra context retention +- **Background sessions** perfect for `"Check all prod servers"` type commands +- **Circuit breaker** auto-pauses Telegram if API goes down — monitor gateway logs \ No newline at end of file diff --git a/.planning/research/hermes/MEMORY.md b/.planning/research/hermes/MEMORY.md new file mode 100644 index 0000000..acb5fa7 --- /dev/null +++ b/.planning/research/hermes/MEMORY.md @@ -0,0 +1,81 @@ +# Hermes Agent: Memory System Deep Dive + +## Built-in Memory + +### MEMORY.md (Agent's Notes) +- Capacity: 2,200 chars (~800 tokens) +- Stores: environment facts, project conventions, lessons learned, completed work +- Format: frozen snapshot at session start in system prompt +- Tool: `memory` with actions add/replace/remove +- Auto-saves: agent proactively saves facts it discovers +- Compaction: when full, agent consolidates or removes entries + +### USER.md (User Profile) +- Capacity: 1,375 chars (~500 tokens) +- Stores: preferences, communication style, expectations +- Write gating: `memory.write_approval: true` requires approval before saves + +### Session Search +- FTS5 full-text search on all past conversations +- Unlimited storage (all sessions in SQLite) +- `session_search` tool for the agent; `hermes sessions list` for the user +- ~20ms queries, no LLM call cost for search + +## External Memory Providers (8 total) + +| Provider | Storage | Cost | Tools | Best For | +|----------|---------|------|-------|----------| +| **Honcho** | Cloud | Paid | 5 | Multi-agent, cross-session user modeling | +| **OpenViking** | Self-hosted | Free | 5 | Structured knowledge hierarchy | +| **Mem0** | Cloud | Paid | 3 | Hands-off auto extraction | +| **Hindsight** | Cloud/Local | Free/Paid | 3 | Knowledge graph + entity relationships | +| **Holographic** | Local SQLite | Free | 2 | No external deps, trust scoring | +| **RetainDB** | Cloud | $20/mo | 5 | Teams using RetainDB | +| **ByteRover** | Local/Cloud | Free/Paid | 3 | Portable CLI-based memory | +| **Supermemory** | Cloud | Paid | 4 | Semantic recall + session graph | + +## Recommended for ngn-agent + +**Phase 2 start:** Built-in memory only — sufficient for ~15 env facts + ~10 user preferences. + +**If more capacity needed:** Holographic (local SQLite + FTS5, zero external deps) or Honcho (cross-session user modeling with dialectic reasoning, good for platform engineering context that spans multiple projects). + +## Key Settings + +```yaml +memory: + memory_enabled: true + user_profile_enabled: true + memory_char_limit: 2200 + user_char_limit: 1375 + write_approval: false # true to require approval before saves + nudge_interval: 10 # turns between save nudges + flush_min_turns: 6 # save memories on exit/reset after N turns +``` + +## What the Agent Auto-Saves + +The agent proactively saves: +- User preferences ("prefers TypeScript" → USER.md) +- Environment facts ("this server runs Debian 12" → MEMORY.md) +- Corrections ("don't use sudo for Docker" → MEMORY.md) +- Conventions ("project uses tabs" → MEMORY.md) +- Completed work ("migrated DB from MySQL to PG" → MEMORY.md) + +## What It Skips + +- Trivial/obvious info +- Easily web-searchable facts +- Raw data dumps +- Session-specific ephemera +- Info already in context files + +## Memory Write Approval Flow + +```yaml +# When write_approval: true: +# CLI: prompts inline +# Gateway: stages for /memory pending → /memory approve +``` + +Toggle at runtime: `/memory approval on|off` \ No newline at end of file diff --git a/.planning/research/hermes/SECURITY.md b/.planning/research/hermes/SECURITY.md new file mode 100644 index 0000000..0786a54 --- /dev/null +++ b/.planning/research/hermes/SECURITY.md @@ -0,0 +1,150 @@ +# Hermes Agent: Security Model & Safety Features + +## 7-Layer Security Model + +1. User authorization (allowlists, DM pairing) +2. Dangerous command approval (manual/smart/off) +3. Container isolation (Docker with hardened settings) +4. MCP credential filtering (env stripping for subprocesses) +5. Context file scanning (prompt injection detection) +6. Cross-session isolation (no data sharing between sessions) +7. Input sanitization (working directory allowlist) + +## Dangerous Command Approval + +Three modes in `~/.hermes/config.yaml`: + +```yaml +approvals: + mode: manual # manual | smart | off + timeout: 60 # seconds to wait for response + cron_mode: deny # deny | approve — what cron does when hitting dangerous cmd +``` + +### Pattern Detection + +Hermes detects and prompts on these patterns (non-exhaustive): + +| Category | Patterns | +|----------|---------| +| Delete | `rm -r`, `rm --recursive`, `rm ... /` | +| Permissions | `chmod 777/666`, `o+w`, `a+w` | +| Filesystem | `mkfs`, `dd if=`, `> /dev/sd` | +| SQL | `DROP TABLE`, `DELETE FROM` (no WHERE), `TRUNCATE` | +| System | `> /etc/`, `systemctl stop/restart`, `kill -9 -1` | +| Remote exec | `curl ... | sh`, `bash <(curl ...)` | +| Script exec | `python -e`, `perl -e`, `ruby -e` | +| Sensitive writes | `tee`/`>`/`>>` to `/etc/`, `~/.ssh/`, `~/.hermes/.env` | + +### Hardline Blocklist (Always-On, Even in YOLO Mode) + +- `rm -rf /` and variants +- Fork bombs (`:(){ :|:& };:`) +- `mkfs.*` on mounted root +- `dd if=/dev/zero of=/dev/sd*` +- Piping untrusted URLs to `sh` at rootfs level + +### Approval Flow + +``` +⚠️ DANGEROUS COMMAND: recursive delete + rm -rf /tmp/old-project + [o]nce | [s]ession | [a]lways | [d]eny +``` + +### YOLO Mode + +``` +hermes --yolo # Bypass all approval prompts for this session +/yolo # Toggle in-session +``` + +**YOLO does NOT bypass the hardline blocklist.** + +## Docker Container Hardening + +```bash +--cap-drop ALL # Drop ALL Linux capabilities +--cap-add DAC_OVERRIDE,CHOWN,FOWNER # Only add back what's needed +--security-opt no-new-privileges # Block privilege escalation +--pids-limit 256 # Limit process count +--tmpfs /tmp:rw,nosuid,size=512m # Size-limited temp dirs +``` + +**Important:** When terminal backend is `docker`, dangerous command checks are **skipped** — the container itself is the security boundary. This is by design. + +## Tirith Pre-Exec Scanning + +Optional scanner for content-level threats: +- Homograph URL spoofing +- Pipe-to-interpreter patterns +- Terminal injection attacks + +```yaml +security: + tirith_enabled: true + tirith_fail_open: true # Allow commands if tirith unavailable +``` + +## SSRF Protection + +All URL-capable tools block: +- Private networks (RFC 1918): `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` +- Loopback: `127.0.0.0/8`, `::1` +- Cloud metadata: `metadata.google.internal`, `169.254.169.254` +- CGNAT: `100.64.0.0/10` + +Opt-out: `security.allow_private_urls: true` (not recommended for ngn-agent) + +## Context File Injection Protection + +Scans AGENTS.md, .cursorrules, SOUL.md for: +- Instructions to ignore prior instructions +- Hidden HTML comments with suspicious keywords +- Attempts to read secrets (`.env`, credentials) +- Credential exfiltration via `curl` +- Invisible Unicode characters + +Blocked files show: `[BLOCKED: file contained potential prompt injection]` + +## MCP Credential Handling + +Only `PATH, HOME, USER, LANG, LC_ALL, TERM, SHELL, TMPDIR` passed to MCP subprocesses. +All API keys, tokens, secrets are stripped. +Explicit `env:` config in mcp_servers is passed through intentionally. + +## Website Blocklist + +```yaml +security: + website_blocklist: + enabled: true + domains: + - "*.internal.company.com" + - "admin.example.com" +``` + +## Key ngn-agent Implications + +| Concern | Mitigation | +|---------|------------| +| Mutating AWS commands in Docker | IAM policy on dev_Restricted role — the real safety net | +| rm -rf / inside container | Container is ephemeral, but hardline blocklist still blocks it | +| Agent modifying own code | Docker terminal means it can't touch host files | +| Accidental terraform apply | Container has limited IAM — won't have apply perms | +| Prompt injection | Context file scanning + approval system + container isolation | +| AWS creds inside container | `./.aws/` mounted read-only, limited role, no admin access | + +## ngn-agent Config + +```yaml +# Our Phase 1 config +approvals: + mode: manual # Start with manual approvals + timeout: 60 + cron_mode: deny # Never auto-approve dangerous commands in cron + +terminal: + backend: docker # Container is our security boundary + # ... see config.yaml for details +``` \ No newline at end of file diff --git a/.planning/research/hermes/SKILLS.md b/.planning/research/hermes/SKILLS.md new file mode 100644 index 0000000..3f4bca2 --- /dev/null +++ b/.planning/research/hermes/SKILLS.md @@ -0,0 +1,79 @@ +# Hermes Agent: Skills System Deep Dive + +## What It Is + +Skills are on-demand knowledge documents (SKILL.md files) that the agent loads when needed. Progressive disclosure minimizes token usage — the agent only loads full content when actually executing a skill. + +## Architecture + +``` +Level 0: skills_list() → [{name, description, category}] (~3k tokens) +Level 1: skill_view(name) → Full content + metadata (varies) +Level 2: skill_view(name, path) → Specific reference file (varies) +``` + +## Storage + +``` +~/.hermes/skills/ # Single source of truth +├── devops/ +│ └── deploy-k8s/ +│ ├── SKILL.md # Main instructions (required) +│ ├── references/ +│ ├── templates/ +│ ├── scripts/ +│ └── assets/ +├── .hub/ # Skills Hub state +│ ├── lock.json +│ ├── quarantine/ +│ └── audit.log +└── .bundled_manifest # Tracks seeded bundled skills +``` + +## How ngn-agent Should Use This + +**DON'T BUILD a custom skill system** — Hermes already has it. Instead: + +1. **Author custom skills** as SKILL.md files in `~/.hermes/skills/` or via the skill hub tap system +2. **Use skill bundles** to group related infra workflows under one command +3. **Let the agent self-improve** — `skill_manage` tool creates/updates skills after complex tasks +4. **Publish as a tap** if sharing with a team: `hermes skills tap add myorg/ngn-skills` + +## SKILL.md Format + +```yaml +--- +name: my-skill +description: Brief description +version: 1.0.0 +platforms: [macos, linux] +metadata: + hermes: + tags: [python, automation] + category: devops + requires_toolsets: [terminal] +--- +# Skill Title +## Procedure +1. Step one +2. Step two +## Pitfalls +## Verification +``` + +## Key Capabilities for ngn-agent + +| Capability | Description | Use for ngn-agent | +|------------|-------------|-------------------| +| Skill Hub install | `hermes skills install openai/skills/k8s` | Install community infra skills | +| Agent-created skills | Agent auto-saves workflows as skills | Self-improving diagnostic skills | +| Skill bundles | `hermes bundles create infra --skill aws-diagnostics --skill jira` | Group related tools | +| External dirs | `skills.external_dirs: [~/.agents/skills]` | Share skills across tools | +| Conditional activation | `fallback_for_toolsets/frequires_toolsets` | Only show skills when needed | +| Write approval gating | `skills.write_approval: true` | Safety gate for agent-created skills | + +## Limitations + +- Skills are per-profile (each Hermes profile has its own `~/.hermes/skills/`) +- External dirs are not read-only by default (agent can modify shared skills) +- Skills Hub requires GitHub API (60 req/hr unauthenticated, 5000 with GITHUB_TOKEN) \ No newline at end of file diff --git a/.planning/research/hermes/SUMMARY.md b/.planning/research/hermes/SUMMARY.md new file mode 100644 index 0000000..a9414b6 --- /dev/null +++ b/.planning/research/hermes/SUMMARY.md @@ -0,0 +1,67 @@ +# Hermes Agent: Feature Research Summary + +**Context:** This research maps Hermes v0.16.0 capabilities so ngn-agent doesn't reimplement what Hermes already provides. All features listed are built-in — ngn-agent should leverage them, not rebuild them. + +**Date:** 2026-06-14 + +--- + +## What Hermes Does Out of the Box (Don't Reinvent) + +- Multi-session management with resume (hermes --continue, sessions list) +- Persistent memory (MEMORY.md + USER.md) with auto-learning +- Full-text session search (FTS5 on SQLite) +- 8 external memory providers (Honcho, Mem0, Hindsight, OpenViking, Holographic, RetainDB, ByteRover, Supermemory) +- Skills system with progressive disclosure (3-level loading) +- Skills Hub with 8 search sources (official, skills.sh, well-known, GitHub, ClawHub, LobeHub, browse.sh, direct URL) +- Git worktree isolation (hermes -w) +- Agent-created skills (skill_manage tool) - self-improving by default +- Skill bundles (group skills under one slash command) +- Cron/automation with 30+ delivery targets +- No-agent cron mode (script-only, zero LLM cost) +- Multi-provider fallback (credential pools + cross-provider) +- Docker container backend with security hardening +- Dangerous command approval (manual/smart/off modes) +- Hardline blocklist for catastrophic commands +- 20+ messaging platforms (Telegram, Discord, Slack, WhatsApp, Signal, Teams, etc.) +- DM pairing for gateway authorization +- Session isolation with configurable reset policies +- Profiles for multi-agent setups +- Plugin system (tools + hooks + commands) +- MCP server integration +- Context compression with configurable thresholds +- Worktree isolation for git parallel branch work +- SOUL.md for personality/identity +- Subagent delegation (delegate_task) +- Background sessions (/background) +- Kanban multi-agent board +- Docker sandbox with --cap-drop ALL, no-new-privileges, PID limits +- SSRF protection and tirith pre-exec scanning + +## What ngn-agent Needs to Build + +Based on initial-plan.md, these features are NOT built into Hermes: + +1. **Jira integration** — Hermes has no built-in Jira tool. Need custom skill or MCP server +2. **Confluence integration** — Same, need custom skill or MCP server +3. **Infrastructure-specific diagnostics** — Generic skills exist but no AWS/terraform-specific ones by default +4. **Read-only infra safety layer** — Hermes has dangerous command approval but nothing specific to cloud APIs +5. **Auto session cleanup (30d archive)** — Hermes has session reset policies but not our specific archive flow +6. **Telegram gateway** — Hermes supports it, just needs bot token config +7. **SSO session automation** — Need custom startup script (already created scripts/start-session.sh) +8. **Custom reporting pipeline** — Cron + skills can provide this + +## Key Limitations to Know + +| Area | Limitation | +|------|------------| +| Memory capacity | MEMORY.md: ~800 tokens, USER.md: ~500 tokens. External providers (Honcho, etc.) remove this limit. | +| Docker dangerous commands | Checks are skipped in Docker mode — container is the boundary | +| Cron provider recovery | Inherits fallback_providers; per-job provider override available | +| Gateway user authorization | Allowlists or DM pairing required — denies all by default | +| Skills are per-profile | Each Hermes profile has its own skills directory | +| Plugin discovery | User plugins opt-in via plugins.enabled in config.yaml | + +## Recommended Memory Strategy for ngn-agent + +Start with built-in memory (MEMORY.md + USER.md) — no external deps needed. If the ~1300 token limit is hit, add Honcho (cross-session user modeling) or Holographic (local SQLite with FTS5 search, no external deps). \ No newline at end of file diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_bootlocale.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_bootlocale.cpython-39.pyc new file mode 100644 index 0000000..ada84d9 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_bootlocale.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_collections_abc.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_collections_abc.cpython-39.pyc new file mode 100644 index 0000000..e1f9b8d Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_collections_abc.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_sitebuiltins.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_sitebuiltins.cpython-39.pyc new file mode 100644 index 0000000..78f0da3 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/_sitebuiltins.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/abc.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/abc.cpython-39.pyc new file mode 100644 index 0000000..e69752d Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/abc.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/codecs.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/codecs.cpython-39.pyc new file mode 100644 index 0000000..6297b0d Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/codecs.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/datetime.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/datetime.cpython-39.pyc new file mode 100644 index 0000000..7234b73 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/datetime.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/__init__.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/__init__.cpython-39.pyc new file mode 100644 index 0000000..222788b Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/__init__.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/aliases.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/aliases.cpython-39.pyc new file mode 100644 index 0000000..05c1ab4 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/aliases.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/cp437.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/cp437.cpython-39.pyc new file mode 100644 index 0000000..1a930b5 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/cp437.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/latin_1.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/latin_1.cpython-39.pyc new file mode 100644 index 0000000..9a4afaf Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/latin_1.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/utf_8.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/utf_8.cpython-39.pyc new file mode 100644 index 0000000..027a1f6 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/encodings/utf_8.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/genericpath.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/genericpath.cpython-39.pyc new file mode 100644 index 0000000..b2a97ae Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/genericpath.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/io.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/io.cpython-39.pyc new file mode 100644 index 0000000..d4d93ee Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/io.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/os.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/os.cpython-39.pyc new file mode 100644 index 0000000..e63c669 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/os.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/posixpath.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/posixpath.cpython-39.pyc new file mode 100644 index 0000000..4b7d879 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/posixpath.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site.cpython-39.pyc new file mode 100644 index 0000000..10543b6 Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/site.cpython-39.pyc differ diff --git a/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/stat.cpython-39.pyc b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/stat.cpython-39.pyc new file mode 100644 index 0000000..e7948fa Binary files /dev/null and b/Library/Caches/com.apple.python/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/stat.cpython-39.pyc differ