docs(05): create phase 5 plan — Hindsight Memory Provider

This commit is contained in:
2026-06-14 20:19:31 +08:00
parent 0c890a65d5
commit 6e02a00b54
3 changed files with 384 additions and 7 deletions

View File

@@ -37,7 +37,10 @@
2. Agent detects similar previous sessions via hindsight similarity search on session start 2. Agent detects similar previous sessions via hindsight similarity search on session start
3. Memory provider is set to `hindsight` (verifiable in config and agent state) 3. Memory provider is set to `hindsight` (verifiable in config and agent state)
4. No memory provider conflicts — only one external provider registered (Hindsight, not MEMORY.md+user) 4. No memory provider conflicts — only one external provider registered (Hindsight, not MEMORY.md+user)
**Plans**: TBD **Plans**: 1 plan
Plans:
- [ ] 05-01-PLAN.md — Hindsight Memory Provider: Create config.json, set env var, activate provider, verify
### Phase 6: Default Repos & SSH Mount ### Phase 6: Default Repos & SSH Mount
**Goal**: Default repos auto-cloned into every new session with secure credential mounting for git operations **Goal**: Default repos auto-cloned into every new session with secure credential mounting for git operations
@@ -83,7 +86,7 @@
| 2. Memory, Git & Session Management | v1.0 | — | Complete | 2026-06-14 | | 2. Memory, Git & Session Management | v1.0 | — | Complete | 2026-06-14 |
| 3. Telegram Gateway | v1.0 | — | Complete | 2026-06-14 | | 3. Telegram Gateway | v1.0 | — | Complete | 2026-06-14 |
| 4. Skills & Integrations | v1.0 | — | Complete | 2026-06-14 | | 4. Skills & Integrations | v1.0 | — | Complete | 2026-06-14 |
| 5. Hindsight Memory Provider | v1.1 | 0/TBD | Not started | - | | 5. Hindsight Memory Provider | v1.1 | 0/1 | Not started | - |
| 6. Default Repos & SSH Mount | v1.1 | 0/TBD | Not started | - | | 6. Default Repos & SSH Mount | v1.1 | 0/TBD | Not started | - |
| 7. Main Session Skill | v1.1 | 0/TBD | Not started | - | | 7. Main Session Skill | v1.1 | 0/TBD | Not started | - |
| 8. Cron Reporting | v1.1 | 0/TBD | Not started | - | | 8. Cron Reporting | v1.1 | 0/TBD | Not started | - |

View File

@@ -5,11 +5,11 @@ milestone_name: Session Lifecycle, Memory & Reporting
status: planning status: planning
stopped_at: Phase 5 context gathered stopped_at: Phase 5 context gathered
last_updated: "2026-06-14T10:18:04.833Z" last_updated: "2026-06-14T10:18:04.833Z"
last_activity: 2026-06-14 — Milestone v1.1 roadmap created last_activity: 2026-06-14 — Phase 5 plan created
progress: progress:
total_phases: 4 total_phases: 4
completed_phases: 0 completed_phases: 0
total_plans: 0 total_plans: 1
completed_plans: 0 completed_plans: 0
percent: 0 percent: 0
--- ---
@@ -26,9 +26,9 @@ See: .planning/PROJECT.md (updated 2026-06-14)
## Current Position ## Current Position
Phase: 5 of 8 (Hindsight Memory Provider) Phase: 5 of 8 (Hindsight Memory Provider)
Plan: — (not yet planned) Plan: 1 plan (05-01-PLAN.md)
Status: Not started — roadmap defined, ready to plan Status: Planned — ready to execute
Last activity: 2026-06-14 — Milestone v1.1 roadmap created Last activity: 2026-06-14 — Phase 5 plan created
Progress: [░░░░░░░░░░] 0% Progress: [░░░░░░░░░░] 0%

View File

@@ -0,0 +1,374 @@
---
phase: 05-hindsight-memory-provider
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- ~/.hermes/hindsight/config.json
- ~/.hermes/.env
- ~/.hermes/config.yaml
autonomous: true
requirements:
- MEM-01
user_setup: []
must_haves:
truths:
- "`hermes config get memory.provider` returns `hindsight`"
- "`~/.hermes/hindsight/config.json` exists with all locked config keys from D-04 through D-10"
- "`grep HINDSIGHT_LLM_API_KEY ~/.hermes/.env` returns the env var with the same value as OPENROUTER_API_KEY"
- "Hindsight daemon starts on first session init (verifiable via `~/.hermes/logs/hindsight-embed.log`)"
- "Agent has all 3 hindsight tools available (hindsight_retain, hindsight_recall, hindsight_reflect) in hybrid mode"
artifacts:
- path: "~/.hermes/hindsight/config.json"
provides: "Hindsight memory provider configuration with latency-optimized settings"
contains: "mode: local_embedded, recall_budget: low, retain_every_n_turns: 5, retain_async: true, memory_mode: hybrid"
- path: "~/.hermes/.env"
provides: "HINDSIGHT_LLM_API_KEY env var for daemon LLM extraction"
contains: "HINDSIGHT_LLM_API_KEY=sk-or-v1-"
- path: "~/.hermes/config.yaml"
provides: "memory.provider set to hindsight"
key_links:
- from: "~/.hermes/hindsight/config.json"
to: "~/.hermes/.env"
via: "HINDSIGHT_LLM_API_KEY env var in daemon startup"
pattern: "HINDSIGHT_LLM_API_KEY"
- from: "~/.hermes/config.yaml"
to: "plugins/memory/hindsight/__init__.py"
via: "memory.provider: hindsight activates HindsightMemoryProvider"
pattern: "memory.provider.*hindsight"
---
<objective>
Activate Hindsight as the cross-session memory provider for ngn-agent in local embedded mode with latency-optimized settings.
**Purpose:** Replace the limited built-in MEMORY.md/USER.md (2.2k chars, frozen per-session) with Hindsight's entity-aware knowledge graph memory for persistent cross-session recall. Pure configuration change — no code, no infrastructure, no Docker image changes.
**Output:**
- `~/.hermes/hindsight/config.json` — Hindsight config with all latency-optimized settings per D-01 through D-10
- `~/.hermes/.env``HINDSIGHT_LLM_API_KEY` env var appended (reuses existing OpenRouter key)
- `~/.hermes/config.yaml``memory.provider` changed to `hindsight`
</objective>
<execution_context>
@/Users/bapung/.config/opencode/gsd-core/workflows/execute-plan.md
@/Users/bapung/.config/opencode/gsd-core/templates/summary.md
</execution_context>
<context>
@/Users/bapung/Razer/ngn-agent/.planning/phases/05-hindsight-memory-provider/05-CONTEXT.md
@/Users/bapung/Razer/ngn-agent/.planning/phases/05-hindsight-memory-provider/05-RESEARCH.md
# Existing state to read before modifying
@/Users/bapung/.hermes/config.yaml
@/Users/bapung/.hermes/.env
@/Users/bapung/.hermes/hermes-agent/plugins/memory/hindsight/README.md
# Critical constraint — single provider only
@/Users/bapung/.hermes/hermes-agent/plugins/memory/__init__.py
</context>
<tasks>
<task type="auto">
<name>Task 1: Create Hindsight config.json and add HINDSIGHT_LLM_API_KEY to .env</name>
<files>
~/.hermes/hindsight/config.json (create)
~/.hermes/.env (append)
</files>
<read_first>
@/Users/bapung/.hermes/hermes-agent/plugins/memory/hindsight/README.md (source of truth for all config keys)
@/Users/bapung/.hermes/.env (current state — must read before appending)
@/Users/bapung/Razer/ngn-agent/.planning/phases/05-hindsight-memory-provider/05-CONTEXT.md (verify locked decisions D-01 through D-10)
@/Users/bapung/Razer/ngn-agent/.planning/phases/05-hindsight-memory-provider/05-RESEARCH.md (verify exact config values)
</read_first>
<action>
Create `~/.hermes/hindsight/config.json` with the following EXACT content (per decisions D-01 through D-10):
```json
{
"mode": "local_embedded",
"llm_provider": "openrouter",
"llm_base_url": "https://openrouter.ai/api/v1",
"llm_model": "qwen/qwen3.5-9b",
"bank_id": "hermes",
"recall_budget": "low",
"recall_prefetch_method": "recall",
"auto_recall": true,
"recall_types": "observation",
"auto_retain": true,
"retain_async": true,
"retain_every_n_turns": 5,
"memory_mode": "hybrid"
}
```
Step-by-step:
1. Read `~/.hermes/.env` to get the current `OPENROUTER_API_KEY` value: `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`
2. Create directory: `mkdir -p ~/.hermes/hindsight`
3. Write the config.json above using Write tool (not heredoc)
4. Append `HINDSIGHT_LLM_API_KEY=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` to `~/.hermes/.env` ONLY if it doesn't already exist (grep first). Add a comment line above it: `# Hindsight — LLM API key for local embedded mode (reuses OpenRouter key)`
Key configuration rationale:
- `mode: local_embedded` (D-01): Local PostgreSQL daemon managed by Hermes. No external data send.
- `llm_provider: openrouter` (D-01): Use existing OpenRouter key. The `llm_base_url` matches OpenRouter's OpenAI-compatible endpoint.
- `llm_model: qwen/qwen3.5-9b` (D-01): Model per-provider default from plugin.
- `bank_id: hermes` (discretion): Default bank name from plugin.
- `recall_budget: low` (D-04): Fastest retrieval, minimal latency overhead per turn.
- `recall_prefetch_method: recall` (D-05): Raw fact search — no LLM synthesis in the hot path.
- `auto_recall: true` (D-06): Auto-inject context before each turn.
- `recall_types: observation` (D-07): Observations only, denser per token.
- `auto_retain: true` (D-10): Automatic retention active.
- `retain_async: true` (D-08): Processing in background, never blocks agent loop.
- `retain_every_n_turns: 5` (D-09): Extract memories every 5 turns (~80% overhead reduction).
- `memory_mode: hybrid` (D-02): Auto-inject relevant memories + expose all 3 hindsight tools (hindsight_retain, hindsight_recall, hindsight_reflect).
- No `bank_mission` or `bank_retain_mission` (discretion): Keep defaults (none).
- Do NOT set `api_url` (not needed for local_embedded mode — plugin defaults to localhost:9177).
- Do NOT set `HINDSIGHT_API_KEY` (not needed for local_embedded — that's for cloud mode).
</action>
<verify>
<automated>
test -f ~/.hermes/hindsight/config.json && echo "config.json EXISTS" || echo "config.json MISSING"
# Validate JSON syntax
python3 -c "import json; json.load(open('$HOME/.hermes/hindsight/config.json')); print('JSON VALID')"
# Verify all locked keys are present
python3 -c "
import json
c = json.load(open('$HOME/.hermes/hindsight/config.json'))
checks = {
'mode': c.get('mode') == 'local_embedded',
'llm_provider': c.get('llm_provider') == 'openrouter',
'llm_base_url': c.get('llm_base_url') == 'https://openrouter.ai/api/v1',
'llm_model': c.get('llm_model') == 'qwen/qwen3.5-9b',
'bank_id': c.get('bank_id') == 'hermes',
'recall_budget': c.get('recall_budget') == 'low',
'recall_prefetch_method': c.get('recall_prefetch_method') == 'recall',
'auto_recall': c.get('auto_recall') == True,
'recall_types': c.get('recall_types') == 'observation',
'auto_retain': c.get('auto_retain') == True,
'retain_async': c.get('retain_async') == True,
'retain_every_n_turns': c.get('retain_every_n_turns') == 5,
'memory_mode': c.get('memory_mode') == 'hybrid',
}
all_ok = all(checks.values())
for k, v in checks.items():
status = 'OK' if v else 'FAIL'
print(f' [{status}] {k}: {c.get(k)}')
assert all_ok, 'Config validation FAILED'
print('ALL CHECKS PASSED')
"
# Verify HINDSIGHT_LLM_API_KEY exists in .env and matches OPENROUTER_API_KEY
OR_KEY=$(grep '^OPENROUTER_API_KEY=' ~/.hermes/.env | cut -d= -f2-)
HL_KEY=$(grep '^HINDSIGHT_LLM_API_KEY=' ~/.hermes/.env | cut -d= -f2-)
if [ "$OR_KEY" = "$HL_KEY" ]; then echo "ENV KEY MATCH: $OR_KEY"; else echo "ENV KEY MISMATCH"; fi
</automated>
</verify>
<acceptance_criteria>
- `~/.hermes/hindsight/config.json` exists and is valid JSON
- All 13 config keys from D-01 through D-10 are present with correct values as verified by the python validation script
- `HINDSIGHT_LLM_API_KEY=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` is in `~/.hermes/.env`
- `HINDSIGHT_LLM_API_KEY` value is identical to `OPENROUTER_API_KEY` value
</acceptance_criteria>
<done>Hindsight config.json created with all 13 locked settings, env var added matching existing OpenRouter key</done>
</task>
<task type="auto">
<name>Task 2: Set memory.provider to hindsight, restart gateway, and verify full memory provider activation</name>
<files>
~/.hermes/config.yaml (modified via `hermes config set`)
</files>
<read_first>
@/Users/bapung/.hermes/hermes-agent/plugins/memory/__init__.py (read the single-provider constraint to understand the activation path)
@/Users/bapung/.hermes/config.yaml (read current memory.provider value — should be empty string before change)
</read_first>
<action>
Perform the following STEPS IN ORDER:
STEP 1 — Set memory provider:
Run: `hermes config set memory.provider hindsight`
This modifies `~/.hermes/config.yaml` setting `memory.provider: hindsight`.
NOTE: The current value at line 355 is `provider: ''` (empty string), meaning no external provider is set. After this command, it becomes `provider: hindsight`. The existing `memory.memory_enabled: true` and `memory.user_profile_enabled: true` remain unchanged — built-in memory continues as fallback (per D-03).
STEP 2 — Restart gateway:
Run: `hermes gateway restart`
This reloads config.yaml and activates the Hindsight provider. The plugin will:
- Detect `hindsight-all` is already installed in the venv (verified: 0.8.2)
- Read `~/.hermes/hindsight/config.json`
- Check existing `~/.hindsight/profiles/hermes.env` (already exists from previous attempt)
- Regenerate the profile env if it doesn't match config.json settings (per plugin __init__.py initialize() logic — Pitfall 5 prevention)
- The daemon will NOT start until the first session access (lazy init, not gateway restart)
STEP 3 — Verify provider is active:
Run: `hermes config get memory.provider`
Expected output: `hindsight`
Run: `hermes memory status`
Expected: Shows hindsight as the active memory provider. Output may say "not available" or similar for daemon status since daemon only starts on first session access (this is expected behavior — the provider IS registered, just the daemon hasn't been launched yet).
STEP 4 — Verify no provider conflict:
Run: `grep -i "Rejected memory provider" ~/.hermes/hermes-agent/logs/* 2>/dev/null || echo "No provider conflicts detected"`
Expected: No output (no rejections) since only one provider is set.
STEP 5 — Verify daemon readiness (check daemon binary exists in venv):
Run: `~/.hermes/hermes-agent/venv/bin/hindsight-embed --version 2>&1 || echo "(version flag not supported — this is fine)"`
Expected: Binary exists (no "not found" error).
STEP 6 — Final verification that all components are in place:
Run a comprehensive check combining config file, env var, and provider setting:
```
echo "=== Hindsight Phase 5 Verification ==="
echo "1. Config file: $(test -f ~/.hermes/hindsight/config.json && echo 'EXISTS' || echo 'MISSING')"
echo "2. Provider setting: $(hermes config get memory.provider)"
echo "3. Env var: $(grep -c '^HINDSIGHT_LLM_API_KEY=' ~/.hermes/.env | xargs -I{} echo 'FOUND ({})' )"
echo "4. Package: $(uv pip show hindsight-all --python ~/.hermes/hermes-agent/venv/bin/python 2>/dev/null | grep Version || echo 'NOT FOUND')"
echo "5. Daemon binary: $(ls ~/.hermes/hermes-agent/venv/bin/hindsight-embed 2>/dev/null && echo 'EXISTS' || echo 'NOT FOUND')"
echo "6. Daemon profile: $(ls ~/.hindsight/profiles/hermes.env 2>/dev/null && echo 'EXISTS' || echo 'NOT FOUND')"
echo "================================"
```
</action>
<verify>
<automated>
# Check provider is set correctly
[ "$(hermes config get memory.provider)" = "hindsight" ] && echo "Provider OK" || echo "Provider FAIL"
# Check no provider conflict in logs
LOG_DIR=~/.hermes/hermes-agent/logs
if [ -d "$LOG_DIR" ]; then
CONFLICT_COUNT=$(grep -c "Rejected memory provider" "$LOG_DIR"/*.log 2>/dev/null || echo 0)
if [ "$CONFLICT_COUNT" = "0" ]; then
echo "No provider conflict detected"
else
echo "WARNING: $CONFLICT_COUNT provider conflict(s) found"
fi
else
echo "No logs yet (no sessions started) — expected at this stage"
fi
# Full config validation using hermes config get (reads live config)
hermes config get memory.provider | grep -q hindsight || echo "CONFIG MISMATCH"
</automated>
</verify>
<acceptance_criteria>
- `hermes config get memory.provider` returns `hindsight`
- No "Rejected memory provider" warnings in logs (run `grep` check)
- `hindsight-embed` binary is present in the Hermes venv at `~/.hermes/hermes-agent/venv/bin/hindsight-embed`
- `hermes memory status` runs without errors and shows hindsight as the registered provider
</acceptance_criteria>
<done>Hindsight memory provider is set as the active external provider, gateway restarted, all verifications pass</done>
</task>
</tasks>
## Artifacts This Phase Produces
### New files
| Artifact | Path | Purpose |
|----------|------|---------|
| Hindsight config | `~/.hermes/hindsight/config.json` | All Hindsight configuration keys per D-01 through D-10 |
### Modified files
| Artifact | Path | Change |
|----------|------|--------|
| Env file | `~/.hermes/.env` | Added `HINDSIGHT_LLM_API_KEY` env var (same value as `OPENROUTER_API_KEY`) |
| Hermes config | `~/.hermes/config.yaml` | Changed `memory.provider` from `""` to `hindsight` |
### New env vars
| Env Var | Value | Source |
|---------|-------|--------|
| `HINDSIGHT_LLM_API_KEY` | `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` | Same as existing `OPENROUTER_API_KEY` in `~/.hermes/.env` |
### New config keys in `~/.hermes/config.yaml`
| Config Key | Value | Description |
|------------|-------|-------------|
| `memory.provider` | `hindsight` | Enables Hindsight as the active external memory provider |
### New config keys in `~/.hermes/hindsight/config.json`
| Key | Value | Decision |
|-----|-------|----------|
| `mode` | `local_embedded` | D-01 |
| `llm_provider` | `openrouter` | D-01 |
| `llm_base_url` | `https://openrouter.ai/api/v1` | D-01 |
| `llm_model` | `qwen/qwen3.5-9b` | D-01 |
| `bank_id` | `hermes` | Discretion |
| `recall_budget` | `low` | D-04 |
| `recall_prefetch_method` | `recall` | D-05 |
| `auto_recall` | `true` | D-06 |
| `recall_types` | `observation` | D-07 |
| `auto_retain` | `true` | D-10 |
| `retain_async` | `true` | D-08 |
| `retain_every_n_turns` | `5` | D-09 |
| `memory_mode` | `hybrid` | D-02 |
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Agent process ↔ OpenRouter API | LLM extraction calls (memory entity extraction) cross the process-to-internet boundary with conversation turn data |
| Agent process ↔ Local PostgreSQL (daemon) | Memory data persisted in local embedded PostgreSQL via localhost:9177 — no network boundary |
| Agent loop ↔ Hindsight provider | Plugin hooks (queue_prefetch, sync_turn) operate in-process with background threads |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-05-01 | Information Disclosure | OpenRouter API key reused as HINDSIGHT_LLM_API_KEY | mitigate | Key already stored in `~/.hermes/.env` with 0600 permissions (existing protection). Same key reused — no new secret to manage. Key is not logged beyond daemon startup. |
| T-05-02 | Denial of Service | Daemon startup failure / PostgreSQL embedded crash | mitigate | Daemon failure is non-fatal — agent continues with built-in memory fallback (D-03). Verify daemon log post-session-start. If daemon fails, memories are silently lost (async retain) but agent loop is unaffected. |
| T-05-03 | Elevation of Privilege | Daemon port localhost:9177 | mitigate | Daemon binds to localhost only (default). Not exposed to Docker container or network. Confirmed via README — no `HINDSIGHT_API_HOST` set means `0.0.0.0` is default but only reachable from host. |
| T-05-04 | Information Disclosure | Conversation data sent to OpenRouter for LLM extraction | accept | Local embedded mode means NO external data send to Hindsight Cloud. LLM extraction calls to OpenRouter carry only the conversation turn (~70-200 chars), not full history. This is the same OpenRouter endpoint already used for primary LLM calls. Equivalent risk to existing model calls. |
| T-05-05 | Tampering | Async retain silent failure | accept | Async retain failures are logged as warnings. Mitigation is monitoring (`grep "Hindsight retain failed"`). Not blocking the agent loop is intentional per D-08. |
| T-05-SC | Tampering | Python package installations (`hindsight-all`, `hindsight-client`, `hindsight-embed`, `hindsight-api-slim`) | mitigate | Package legitimacy verified in RESEARCH.md §Package Legitimacy Audit — all packages from Vectorize.io (same org as Hermes plugin). Already installed at version 0.8.2. No new install needed. |
### Residual Risk
| Risk | Why Accepted |
|------|--------------|
| LLM extraction timeout or error causes memory loss for that turn | Async retain swallows failures; memories from that turn are lost. Mitigated by `retain_every_n_turns: 5` — next retain window will capture subsequent turns. |
| OpenRouter rate limiting on extraction calls | Same key used for model calls and extraction; extraction happens every 5 turns (~70-200 chars), which is negligible compared to model call traffic. |
</threat_model>
<verification>
Run after all tasks complete:
```bash
echo "=== Phase 5 Full Verification ==="
echo "--- Step 1: Provider Check ---"
hermes config get memory.provider
echo "--- Step 2: Config File ---"
python3 -c "import json; c=json.load(open('$HOME/.hermes/hindsight/config.json')); print('mode:', c['mode']); print('budget:', c['recall_budget']); print('async retain:', c['retain_async']); print('every_n:', c['retain_every_n_turns']); print('memory_mode:', c['memory_mode'])"
echo "--- Step 3: Env Var ---"
grep '^HINDSIGHT_LLM_API_KEY=' ~/.hermes/.env | grep -o '^HINDSIGHT_LLM_API_KEY=sk-or-v1-' && echo "Format OK"
echo "--- Step 4: Package ---"
uv pip show hindsight-all --python ~/.hermes/hermes-agent/venv/bin/python 2>/dev/null | grep -E '(Name|Version)'
echo "--- Step 5: Daemon Binary ---"
ls -la ~/.hermes/hermes-agent/venv/bin/hindsight-embed 2>/dev/null
echo "--- Step 6: Daemon Profile (pre-existing) ---"
ls -la ~/.hindsight/profiles/hermes.env 2>/dev/null
echo "--- Step 7: Provider Conflict Check ---"
grep -i "Rejected memory provider" ~/.hermes/hermes-agent/logs/*.log 2>/dev/null || echo "No conflicts"
echo "=== Verification Complete ==="
```
</verification>
<success_criteria>
1. `hermes config get memory.provider` returns `hindsight` — provider activated
2. `~/.hermes/hindsight/config.json` exists with valid JSON containing all 13 locked settings — config complete
3. `grep HINDSIGHT_LLM_API_KEY ~/.hermes/.env` returns the env var matching OPENROUTER_API_KEY — LLM extraction configured
4. `~/.hermes/hermes-agent/venv/bin/hindsight-embed` binary exists — daemon ready for first session start
5. No "Rejected memory provider" warnings in gateway logs — no provider conflict
6. Built-in MEMORY.md/USER.md continues working in parallel (no config changes to memory_enabled/user_profile_enabled) — fallback preserved per D-03
</success_criteria>
<output>
Create `.planning/phases/05-hindsight-memory-provider/05-01-SUMMARY.md` when done
</output>