From 8711840b264b9adbb610c748575269bc1674d85a Mon Sep 17 00:00:00 2001 From: Jerome Tabiri Date: Sun, 28 Jun 2026 13:20:27 -0400 Subject: [PATCH 1/7] Add memory-audit-maintenance prose contract --- memory-audit-maintenance.prose.md | 169 ++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 memory-audit-maintenance.prose.md diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md new file mode 100644 index 0000000..a816180 --- /dev/null +++ b/memory-audit-maintenance.prose.md @@ -0,0 +1,169 @@ +--- +kind: responsibility +name: memory-audit-maintenance +description: > + Systematic audit and reorganization of an agent's native memory (MEMORY.md, + USER.md, SOUL.md). Categorizes entries, redistributes to correct homes, + verifies live configs, and frees up char budget. Run when memory usage + exceeds 85% or on explicit user request ("memory audit", "memory maintenance"). +--- + +## Maintains + +- last_audit: timestamp — When the last full audit was completed +- memory_usage_pct: number — Current memory store usage percentage +- user_usage_pct: number — Current user store usage percentage +- total_entries_categorized: number — How many entries were audited +- entries_moved: number — How many entries changed location +- entries_deleted: number — How many stale entries were removed +- live_configs_verified: array — Which configs were verified against live systems +- known_issues: array — Problems found during audit (stale keys, dead services) + +## Parameters + +- memory_threshold: number — Usage % that triggers audit (default: 85, max: 95) +- verify_configs: boolean — Whether to live-check configs after audit (default: true) +- compress_entries: boolean — Whether to shorten verbose entries (default: true) +- remove_session_notes: boolean — Strip "currently doing X" markers (default: true) +- max_memory_chars: number — Target max chars for MEMORY.md after audit (default: 1100) +- max_user_chars: number — Target max chars for USER.md after audit (default: 500) + +## Continuity + +The audit cycle is **event-driven**, not just cron-based: + +- **On threshold breach**: If memory usage exceeds `memory_threshold`, wake immediately +- **On user request**: `"memory audit"`, `"memory maintenance"`, `"clean up memory"` — explicit trigger +- **Retrospective**: Every 2-4 weeks if no other trigger fired — check for gradual bloat +- **On config change**: After major provider swaps or infrastructure migrations, verify live configs +- **On new agent onboarding**: Run once as part of initialization to establish clean baseline + +## Success Criteria (What Makes a Memory Audit "Good") + +The audit is considered COMPLETE when ALL of these pass: + +### Inventory Complete +- MEMORY.md content read and categorized +- USER.md content read and categorized +- In-memory `memory` and `user` store usage percentages recorded +- Every entry tagged with: `Infrastructure | Identity | Preference | Operating Rule | Historical | Session Note` + +### Redistribution Correct +- Identity entries → USER.md +- Preference entries → USER.md +- Technical config entries → MEMORY.md +- Operating rules → Skill file or SOUL.md +- Historical snapshots (dated checkpoints) → Deleted +- Session notes ("currently doing X") → Deleted + +### Files Compact +- MEMORY.md ≤ `max_memory_chars` chars +- USER.md ≤ `max_user_chars` chars +- No duplicate information across files +- No frustration signals or verbose descriptions +- § separator between entries (standard convention) + +### Configs Verified +- API keys confirmed in `.env` file (grep, not read) +- Model names in memory match live `config.yaml` +- Endpoints in memory respond to curl/health checks +- Credential pairs (username/token, email/password) match deployed state +- Any mismatch corrected in memory with ✅/❌ labels + +### In-Memory Synced +- Summary marker added to `memory` store: "MEMORY.md rewritten . Holds only tech configs." +- Summary marker added to `user` store: "Home channel: . USER.md rewritten ." +- Usage confirmed dropped below 60% after sync + +### Skill Created/Updated (if applicable) +- Operating rules that belong in a skill → created via `skill_manage` +- Existing skills verified not to conflict with memory content +- Skill category appropriate and description searchable + +## Remembers + +Each audit stores: +- Entry categorization decisions (why X went to USER instead of MEMORY) +- What was deleted (stale snapshots, session notes) +- What was verified (configs that passed live checks) +- What failed verification (configs that need user attention) +- Known tool quirks (memory replace/remove failures) +- Compression patterns used (how verbose entries were shortened) + +## Audit Rules + +### Rule 1: Read Before Delete +Never delete an entry without first reading it and categorizing it. Show the user a summary of what will change if unsure about a categorization. + +### Rule 2: Categories Are Mutual Exclusive +Each entry belongs to exactly ONE category: +- **Identity** — "Jerome, Florida, Telegram @mejerome19" +- **Preference** — "Single-account first for AWS" +- **Technical Config** — "SearXNG on storepve:8888" +- **Operating Rule** — "Never go rogue on infrastructure" +- **Historical Snapshot** — "Baseline v30 from Jun 26" (DELETE) +- **Session Note** — "Currently performing memory audit" (DELETE) + +### Rule 3: Rules Belong in Skills +If an entry is a procedure, protocol, or mandate (`"do X this way"`, `"never do Y"`) — it belongs in a skill file, not MEMORY.md. Check `skills_list` first; create via `skill_manage` if no match exists. + +### Rule 4: Verify Live Before Trusting Memory +Every config entry in MEMORY.md must be verified against the live system: +- Model name → `grep config.yaml` +- API key → `grep .env` +- Service URL → `curl` health check +- Credentials → cross-reference with deployed state + +### Rule 5: Work Around the `memory` Tool +The `memory` tool's `remove` and `replace` actions use strict text matching that can fail on special characters. If a remove/replace fails repeatedly: +- Do not retry more than 2 times +- Add a new summary marker entry instead +- Report to user: "File on disk updated; in-memory store has stale leftovers" +- The file on disk (MEMORY.md, USER.md) is the source of truth regardless + +### Rule 6: Report Before Asking +Don't ask the user "should I delete X?" for session notes or historical snapshots — those are always safe to delete. Only ask about ambiguous categorizations or cross-file moves of preference data. + +## Execution + +1. **Read state** — Read MEMORY.md, USER.md, check in-memory usage via `memory` tool +2. **Categorize** — Tag every entry with its category +3. **Prepare rewrites** — Draft compressed MEMORY.md and USER.md: + - MEMORY.md: Technical configs only (800-1100 chars) + - USER.md: Identity + preferences only (300-500 chars) +4. **Write files** — Overwrite MEMORY.md and USER.md +5. **Verify live configs** — Check every config entry against actual system state +6. **Sync in-memory** — Add summary markers to `memory` and `user` stores +7. **Create/update skills** — Move operating rules to skill files if needed +8. **Report** — Output clean status table with before/after/verification + +## Example Output + +``` +## Memory Audit Complete ✅ + +| File | Before | After | Reduction | +|---|---|---|---| +| MEMORY.md | 1,653 chars | 1,077 chars | ~35% | +| USER.md | 860 chars | 418 chars | ~51% | + +### What Moved +| Entry | From | To | +|---|---|---| +| Identity + Preferences | MEMORY.md | USER.md | +| Agent boundary rule | MEMORY.md | SOUL.md (persona) | +| Baseline v30 snapshot | MEMORY.md | Deleted | + +### Config Verification +| Config | Live Check | Status | +|---|---|---| +| DeepSeek model | config.yaml: deepseek-chat | ✅ | +| DeepSeek key | .env found | ✅ | +| SearXNG endpoint | :8888 curl 200 | ✅ | + +### Memory Usage +| Store | Before | After | Status | +|---|---|---|---| +| memory | 91% | 59% | ✅ | +| user | 85% | 41% | ✅ | +``` From 6a8a2c61dac675476587fea2c5b68829dceb88a9 Mon Sep 17 00:00:00 2001 From: Jerome Tabiri Date: Sun, 28 Jun 2026 13:33:06 -0400 Subject: [PATCH 2/7] Add hermes-config-template prose contract with shared infra + flexible models --- hermes-config-template.prose.md | 246 ++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 hermes-config-template.prose.md diff --git a/hermes-config-template.prose.md b/hermes-config-template.prose.md new file mode 100644 index 0000000..ba077a3 --- /dev/null +++ b/hermes-config-template.prose.md @@ -0,0 +1,246 @@ +--- +kind: template +name: hermes-config-template +description: > + Standard Hermes configuration template for Syslog Solution LLC agents. + Enforces shared infrastructure setup (Firecrawl, SearXNG, local models, + RA-H OS MCP) while keeping model/provider choices flexible per agent role. + Every new agent profile should start from this template. +--- + +## Maintains + +- template_version: string — Current template version (e.g., "1.0.0") +- last_applied: timestamp — When any agent was last configured from this template +- agents_configured: array — Which agents/profiles were created from this template +- infra_endpoints_verified: array — Firecrawl, SearXNG, RA-H OS, LiteLLM endpoints last confirmed working +- known_deviations: array — Profiles that diverge from the template (and why) + +## Parameters + +- agent_name: string — Name of the agent/profile (e.g., "syslog-code", "syslog-devops") +- default_model: string — Agent's primary model (e.g., "qwen3.6-27B-code", "syslog-auto") +- default_provider: string — Inference provider for the primary model (default: "harness") +- fallback_model: string — Fallback model when primary is down (default: "gemma-4-12b") +- fallback_provider: string — Fallback provider (default: "harness") +- auxiliary_model: string — Model for vision/compression/extraction tasks (default: "gemma-4-12b") +- enable_firecrawl_searxng: boolean — Whether to configure web search/extract (default: true) +- enable_ra_h_os_mcp: boolean — Whether to wire up RA-H OS MCP bridge (default: true) +- enable_compression: boolean — Whether to enable context compression (default: true) +- custom_provider_name: string — Custom provider name (default: "harness") +- custom_provider_model: string — Custom provider model (default: same as default_model) +- custom_provider_url: string — LiteLLM base URL (default: "http://litellm.sysloggh.net/litellm/v1") +- extra_auxiliary: array — Additional auxiliary tasks to configure (vision, compression, etc.) +- output_dir: string — Where to write the config (default: "~/.hermes/profiles//config.yaml") + +## Infrastructure Stack + +This template provisions the following shared infrastructure. Every agent should point to the same endpoints unless explicitly overridden. + +| Component | Endpoint | Purpose | +|---|---|---| +| Firecrawl | `http://192.168.68.7:3002/` | Web content extraction | +| SearXNG | `http://storepve:8888` | Privacy-respecting web search | +| LiteLLM | `http://litellm.sysloggh.net/litellm/v1` | Unified model gateway | +| RA-H OS MCP | `http://192.168.68.65:3100/mcp` | Knowledge graph bridge | +| Context7 MCP | `http://localhost:8079/mcp` | Documentation queries | + +**API Key Rules:** +- `api_key: sk-_SW...B8nw` — Hardcoded LiteLLM master key for custom_providers and auxiliary tasks +- `api_key_env: DEEPSEEK_API_KEY` — Env-var based key for fallback provider +- Worker profiles should inherit proxy config via `harness` custom_provider, NOT hardcode LiteLLM keys + +**For workers that need API keys overridden:** Set `api_key: ''` in the model section (inherits from custom_providers), or use `api_key_env` for env-based auth. + +## Template Structure + +### Required Sections (every agent MUST have) + +```yaml +# ─── Model Selection (USER CHOOSES) ─── +model: + # !! CHANGE THIS for your agent !! + default: + provider: + # LiteLLM base URL (shared infra) + base_url: http://litellm.sysloggh.net/litellm/v1 + +fallback_providers: + # !! OPTIONAL: overridable fallback !! + provider: + model: + +# ─── Web Stack (SHARED INFRA — DO NOT CHANGE) ─── +web: + backend: firecrawl + search_backend: searxng + extract_backend: firecrawl + firecrawl: + base_url: http://192.168.68.7:3002/ + +# ─── MCP Servers (SHARED INFRA — DO NOT CHANGE) ─── +mcp_servers: + context7: + connect_timeout: 60 + timeout: 300 + url: http://localhost:8079/mcp + ra-h-os: + url: http://192.168.68.65:3100/mcp + timeout: 120 + connect_timeout: 60 + +# ─── Compression (SHARED — can override model) ─── +compression: + enabled: true + provider: harness + model: # default: gemma-4-12b + threshold: 0.5 + target_ratio: 0.25 + protect_last_n: 30 + hygiene_hard_message_limit: 400 + +# ─── Auxiliary Tasks (SHARED INFRA + MODEL) ─── +auxiliary: + vision: + provider: harness + model: + web_extract: + provider: harness + model: + session_search: + provider: harness + model: + max_concurrency: 3 + +# ─── Custom Provider (SHARED INFRA — LiteLLM) ─── +custom_providers: + - name: + model: + base_url: http://litellm.sysloggh.net/litellm/v1 + api_key: + api_mode: chat_completions +``` + +### Optional Sections (agent-specific) + +- **Platform configs** (Telegram, Discord, WhatsApp bot tokens) +- **Display/skin** options (compact mode, personality) +- **Plugin lists** (zulip-platform, etc.) +- **Terminal settings** (container image, timeouts) +- **Security/approvals** (command allowlists) +- **Kanban/worker** settings (if this profile is a Kanban worker) +- **Skills auto_load** list +- **Timezone** override + +## Continuity + +Configuration drift detection is **event-driven**: + +- **On agent onboarding**: Always scaffold from this template +- **On infra change**: If Firecrawl/SearXNG/LiteLLM endpoints change, update template + all profiles +- **On new model**: When a new model is deployed on Litellm, any agent can change their `default` independently +- **Periodic**: Every 2 weeks — check if any profile's infra section has drifted from the template +- **On connection failure**: If web search/extract fails, check if that agent has missing `web.*` config + +## Success Criteria + +The configuration is CONSIDERED GOOD when ALL of these pass: + +### Infra Connectivity +- `web.backend == "firecrawl"` — Firecrawl backend configured +- `web.search_backend == "searxng"` — SearXNG search configured +- `web.extract_backend == "firecrawl"` — Firecrawl extraction configured +- `web.firecrawl.base_url` points to `192.168.68.7:3002` +- `mcp_servers.ra-h-os.url` points to `192.168.68.65:3100/mcp` +- All endpoints respond to `curl` health checks + +### Model Flexibility +- `model.default` is settable per agent (not hardcoded) +- `model.provider` is settable per agent +- `custom_providers[0].model` matches the agent's workload (code vs general) + +### Completeness +- `auxiliary.vision` configured (even if provider=auto) +- `compression.enabled` set (true for most agents) +- Fallback provider configured (deepseek or another harness model) +- `_config_version` correctly set (currently `30`) + +### No Drift +- No duplicate infra endpoints (one canonical Firecrawl URL) +- No stale endpoints (old IPs, dead services) +- All profiles consistent on shared infra + +## Configuration Rules + +### Rule 1: Shared Infra Is Locked +The following MUST be identical across ALL profiles: +- `web.backend`, `web.search_backend`, `web.extract_backend` +- `web.firecrawl.base_url` +- `mcp_servers.ra-h-os.url` +- `custom_providers[0].base_url` + +### Rule 2: Model Choice Is Free +The following are OWNED by each agent and can differ: +- `model.default` — the primary model +- `model.provider` — where it runs +- `fallback_providers.model` — backup model +- `custom_providers[0].model` — what this agent uses LiteLLM for + +### Rule 3: Workers Inherit, Not Duplicate +Worker profiles (syslog-code, syslog-devops, etc.) generally inherit from the main config. Only override what's DIFFERENT: +- Different default model → override `model.default` +- Different auxiliary model → override auxiliary sections +- No web search needed → still keep the config (tools won't enable without it) + +### Rule 4: API Key Placement +- **Custom provider keys** (`custom_providers[0].api_key`): Must be hardcoded (the LiteLLM master key or a virtual key) +- **Model section keys** (`model.api_key`): Prefer empty. Workers inherit from custom_providers. +- **Environment keys** (`api_key_env`): For fallback providers that need separate auth (DeepSeek, OpenRouter) +- **Hardcoded keys in profile**: If a worker's `model.api_key` is set, it overrides custom_providers. Only use when the worker needs a DIFFERENT provider than Litellm. + +### Rule 5: Verify After Every Config Change +After changing a profile's config: +1. `curl` the model endpoint to confirm auth works +2. `curl` the web stack endpoints (Firecrawl, SearXNG) +3. Check that `hermes gateway --restart` reloads cleanly + +## Execution + +1. **Check current config** — Read the target agent's config.yaml +2. **Compare against template** — Identify missing or divergent sections +3. **Apply shared infra** — Lock the web/MCP/compression sections to template values +4. **Apply model choice** — Set default/fallback/auxiliary models per agent's workload +5. **Preserve agent-specific** — Keep platform configs, plugins, terminal settings, skills +6. **Remove stale** — Drop any old infra endpoints that don't match the template +7. **Verify** — curl all shared endpoints, test the model +8. **Report** — What was changed, what was preserved, what's still custom + +## Example Output + +``` +## Config Template Applied: syslog-code ✅ + +### Shared Infrastructure (Locked) +| Section | Before | After | +|---|---|---| +| web.backend | firecrawl | firecrawl ✅ | +| web.search_backend | NOT SET | searxng ✅ | +| web.firecrawl.base_url | NOT SET | http://192.168.68.7:3002/ ✅ | +| mcp_servers.ra-h-os | present | present ✅ | + +### Agent Model Choices (Preserved) +| Setting | Value | +|---|---| +| model.default | qwen3.6-27B-code (code agent) | +| fallback | gemma-4-12b (harness) | +| auxiliary | gemma-4-12b (harness) | +| compression | gemma-4-12b (harness) | + +### Endpoint Verification +| Endpoint | Status | +|---|---| +| Firecrawl :3002 | ✅ 200 OK | +| SearXNG :8888 | ✅ 200 OK | +| LiteLLM | ✅ 200 OK | +| RA-H OS MCP | ✅ Connected | +``` From 94b3bf84b4443c4f094f7d11ef8fd98d30a98e1a Mon Sep 17 00:00:00 2001 From: Jerome Tabiri Date: Sun, 28 Jun 2026 13:49:06 -0400 Subject: [PATCH 3/7] Add README + Quickstart sections for agent execution --- README.md | 97 +++++++++++++++++++++++++++++++ hermes-config-template.prose.md | 61 +++++++++++++++++++ memory-audit-maintenance.prose.md | 36 ++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d6e0b20 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# Prose Contracts — Syslog Solution LLC + +Operating contracts for Hermes agents. Each `.prose.md` file defines a **responsibility** (recurring duty) or **template** (scaffold) that agents can execute via OpenProse or follow manually. + +## How Agents Run These Contracts + +### Option A: Via OpenProse CLI (preferred) + +```bash +prose run [param1=value1 param2=value2 ...] +``` + +**Examples:** + +```bash +# Run a memory audit with default parameters +prose run memory-audit-maintenance + +# Run a memory audit with custom threshold +prose run memory-audit-maintenance memory_threshold=90 verify_configs=true + +# Configure a new agent with the template +prose run hermes-config-template agent_name=syslog-devops default_model=claude-sonnet-4 + +# Configure an agent with a different auxiliary model +prose run hermes-config-template agent_name=syslog-code default_model=qwen3.6-27B-code auxiliary_model=gemma-4-12b +``` + +### Option B: Manual Execution + +If `prose` CLI isn't available, any agent can: +1. Fetch the raw contract: `curl -sL https://git.sysloggh.net/SyslogSolution/prose-contracts/raw/branch/master/` +2. Read the **Execution** section +3. Follow the steps + +**Example for fetching:** +```bash +curl -sL https://git.sysloggh.net/SyslogSolution/prose-contracts/raw/branch/master/memory-audit-maintenance.prose.md +``` + +## Available Contracts + +### Responsibilities (Recurring Duties) + +| Contract | What It Does | When To Run | +|---|---|---| +| `memory-audit-maintenance` | Audits & reorganizes an agent's native memory (MEMORY.md, USER.md). Categorizes entries, moves rules to skills, verifies configs, frees up char budget. | Memory >85% usage or user request: "memory audit" | +| `zulip-health` | Checks Zulip connectivity, message flow, and bot responsiveness. | On Zulip issues or periodic health check | +| `litellm-health` | Verifies LiteLLM proxy connectivity, model availability, and key rotation. | On inference failures or periodic check | +| `litellm-self-heal` | Attempts to fix common LiteLLM issues (key rotation, restart, config reload). | When litellm-health reports failures | +| `zulip-mention-reliability` | Diagnoses and fixes @mention detection issues in Zulip. | On missed @mention reports | +| `pm2-self-heal` | Restarts crashed PM2 processes and verifies recovery. | On PM2 process failure | + +### Templates (Scaffolds) + +| Contract | What It Does | Parameters | +|---|---|---| +| `hermes-config-template` | Generates a standard Hermes config for any agent. Enforces shared infra (Firecrawl, SearXNG, RA-H OS MCP, LiteLLM) while keeping model choices flexible. | `agent_name` (required), `default_model`, `default_provider`, `fallback_model`, `auxiliary_model` | + +### Scripts + +| File | What It Does | +|---|---| +| `pm2-self-heal.sh` | Shell script to restart crashed PM2 processes (companion to the prose contract) | + +## Contract Structure + +Every `.prose.md` file has the same structure: + +``` +--- +kind: +name: +description: ... +--- + +## Maintains — What state the contract tracks +## Parameters — Tunable inputs (with defaults) +## Continuity — When to run (triggers & cadence) +## Success Criteria — How to know it worked +## Remembers — What to learn between runs +## Rules — Inviolable rules for execution +## Execution — Step-by-step instructions +## Example Output — What a good run looks like +``` + +## Adding New Contracts + +1. Create a `.prose.md` file following the structure above +2. Push to this repo +3. The contract is immediately available for any agent to `prose run` + +## Repository + +- **URL:** https://git.sysloggh.net/SyslogSolution/prose-contracts +- **Branch:** master +- **Auth:** mumuni-bot (write access via PAT) diff --git a/hermes-config-template.prose.md b/hermes-config-template.prose.md index ba077a3..873ad56 100644 --- a/hermes-config-template.prose.md +++ b/hermes-config-template.prose.md @@ -33,6 +33,67 @@ description: > - extra_auxiliary: array — Additional auxiliary tasks to configure (vision, compression, etc.) - output_dir: string — Where to write the config (default: "~/.hermes/profiles//config.yaml") +## Quickstart — How to Run This Contract + +### For the Agent Running This Contract + +Read this section first. It tells you exactly what to do. + +**When to run:** +- Setting up a **new agent profile** for the first time +- An **existing profile** is missing web search, firecrawl, or MCP configs +- User says: `"apply the config template"` or `"fix my infra config"` +- User says: `"configure with "` + +**How to run (via OpenProse CLI):** +```bash +# Minimal — only agent name required +prose run hermes-config-template agent_name=syslog-code + +# Full control +prose run hermes-config-template \ + agent_name=syslog-devops \ + default_model=claude-sonnet-4 \ + auxiliary_model=gemma-4-12b \ + fallback_model=deepseek-chat \ + fallback_provider=deepseek +``` + +### How to Follow the Template (Manual) + +If `prose` CLI is not available: + +1. **Fetch this contract:** `curl -sL https://git.sysloggh.net/SyslogSolution/prose-contracts/raw/branch/master/hermes-config-template.prose.md` +2. **Open the target config.yaml** — the profile you're updating +3. **Compare** each of the 5 required sections below against what exists in the profile +4. **For each section:** + - If it says **SHARED INFRA — DO NOT CHANGE**: Copy the value exactly as shown + - If it says **USER CHOOSES**: Use the agent's assigned model/provider + - If missing entirely: Add the full section +5. **Verify** every endpoint responds (see Verification section at the end) +6. **Restart** the gateway + +### Decision Tree + +``` +What kind of profile is this? +├── Main profile (~/.hermes/config.yaml) +│ └── Replace web.*, mcp_servers.*, compression.*, auxiliary.*, custom_providers.* +│ └── model.default + fallback: use current values (USER CHOOSES) +│ +├── Worker profile (~/.hermes/profiles//config.yaml) +│ ├── Does it have web.search_backend? +│ │ ├── NO → Add the full web.* section (copy exactly) +│ │ └── YES → Verify it points to the right IP +│ ├── Does it have mcp_servers.ra-h-os? +│ │ ├── NO → Add mcp_servers.* section (copy exactly) +│ │ └── YES → Verify URL +│ └── model.default: USE the worker's assigned model (don't copy main) +│ +└── Non-Syslog profile (personal/lifestyle agent) + └── Skip — use default Hermes config or Tanko's config instead +``` + ## Infrastructure Stack This template provisions the following shared infrastructure. Every agent should point to the same endpoints unless explicitly overridden. diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md index a816180..d154c2d 100644 --- a/memory-audit-maintenance.prose.md +++ b/memory-audit-maintenance.prose.md @@ -8,6 +8,42 @@ description: > exceeds 85% or on explicit user request ("memory audit", "memory maintenance"). --- +## Quickstart — How to Run This Contract + +### For the Agent Running This Contract + +Read this section first. It tells you exactly what to do. + +**When to run:** +- User says: `"memory audit"`, `"memory maintenance"`, `"clean up memory"`, `"memory is full"` +- You detect that your `memory` store usage exceeds 85% in a write attempt +- It's been 2+ weeks since the last audit + +**How to run (via OpenProse CLI):** +```bash +# Default — 85% threshold, verify configs, compress entries +prose run memory-audit-maintenance + +# Softer audit — only flag issues, don't rewrite files +prose run memory-audit-maintenance compress_entries=false + +# Hard audit — stricter limits +prose run memory-audit-maintenance memory_threshold=90 max_memory_chars=800 max_user_chars=300 +``` + +### How to Follow the Template (Manual) + +If `prose` CLI is not available: + +1. **Read both memory files:** `cat ~/.hermes/memories/MEMORY.md` and `cat ~/.hermes/memories/USER.md` +2. **Check in-memory usage:** Use the `memory` tool with no args +3. **Categorize every entry** using the Categorization Guide below +4. **Rewrite MEMORY.md** — technical configs only, 800–1,100 chars max +5. **Rewrite USER.md** — identity + preferences only, 300–500 chars max +6. **Verify live configs** — curl each endpoint, check each model +7. **Sync in-memory** — Add summary markers (or just leave file as source of truth) +8. **Report** using the Example Output template at the bottom + ## Maintains - last_audit: timestamp — When the last full audit was completed From 3e10988ccea555505bacf3beb3213e5fc4b1157e Mon Sep 17 00:00:00 2001 From: Jerome Date: Sun, 28 Jun 2026 19:23:52 +0000 Subject: [PATCH 4/7] Improve memory audit contract: autonomous execution, incremental patches, pre-flight checks, stale state thresholds, dry-run mode, success metrics --- memory-audit-maintenance.prose.md | 230 ++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 memory-audit-maintenance.prose.md diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md new file mode 100644 index 0000000..703f529 --- /dev/null +++ b/memory-audit-maintenance.prose.md @@ -0,0 +1,230 @@ +--- +name: memory-audit-maintenance +kind: responsibility +id: 067NC4KG01RG50R40M30E20918 +--- + +### Goal + +Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, SOUL.md), categorize entries, redistribute them to correct locations, verify live configurations, and free character budget all without user intervention unless a truly unresolvable ambiguity exists. + +### Requires + +(none this is a self-driven, autonomous node) + +### Maintains + +Memory health state current utilization, last audit timestamp, and any unresolved ambiguities. Postcondition: no entry is duplicated, no session note or stale snapshot survives, and no config is unverified. + +#### utilization +Current character utilization of MEMORY.md and USER.md. Material: the percentages. + +#### last_audit +Timestamp of the most recent successful audit. Material: the timestamp. + +#### unresolved +Any entries that could not be autonomously categorized. Material: the entry text and the reason for ambiguity. + +### Continuity + +- self-driven: re-audit every 14 days (2 weeks) +- input-driven: triggered by explicit user request ("memory audit", "memory maintenance", "clean up memory", "memory is full") +- threshold: trigger immediately if either store exceeds 85% utilization + +### Parameters + +- `memory_threshold`: percentage that triggers an immediate audit (default: 85) +- `max_memory_chars`: maximum allowed characters for MEMORY.md (default: 2200) +- `max_user_chars`: maximum allowed characters for USER.md (default: 1375) +- `compress_entries`: whether to rewrite entries for brevity (default: true) +- `dry_run`: whether to only report changes without applying them (default: false) + +### Strategies + +- **Autonomous first:** Never ask the user about entries that clearly belong in a deletion or move category. Only escalate on true ambiguity (e.g., an entry could be either a Preference or a Technical Config, and the choice affects which file it goes in). +- **Incremental over nuclear:** Always use patch-level edits (find-and-replace) rather than wholesale file rewrites. If the patch tool fails, fall back to rewrite only as a last resort. +- **Verify before trusting:** Every technical config in MEMORY.md must be verified against the live system. If a service is unreachable, mark it as `UNVERIFIED` rather than deleting it. +- **Stale state has a shelf life:** Any entry marked as "Temporary State" (e.g., "verbal offer", "deal pending", "negotiation phase") is deleted if older than 14 days. +- **Work around tool failures:** If the `memory` tool fails after 2 retries, add a summary marker and report the stale state in the unresolved list. + +### Invariants + +- No entry is deleted without being categorized first +- No duplicate entries survive across MEMORY.md and USER.md +- No session note or temporary state survives past 14 days +- No config is trusted without verification (or marked UNVERIFIED) + +### Execution + +```prose +# ============================================================ +# PHASE 1: Pre-flight +# ============================================================ + +# Verify the memory tool works +try: + memory_status = call check_memory_tool +catch: + memory_status = "BROKEN" + +# Read current state +memory_content = read_file("~/.hermes/memories/MEMORY.md") +user_content = read_file("~/.hermes/memories/USER.md") + +# Calculate current utilization +memory_util = len(memory_content) / max_memory_chars * 100 +user_util = len(user_content) / max_user_chars * 100 + +# Check if audit is needed +if last_audit > 14 days and memory_util < 75 and user_util < 75: + return {status: "SKIP", reason: "No audit needed"} + +# ============================================================ +# PHASE 2: Categorize every entry +# ============================================================ + +categorized = [] +for entry in split_entries(memory_content): + cat = call categorize_entry(entry) + categorized.append({entry, category: cat, source: "MEMORY.md"}) + +for entry in split_entries(user_content): + cat = call categorize_entry(entry) + categorized.append({entry, category: cat, source: "USER.md"}) + +# ============================================================ +# PHASE 3: Identify actions +# ============================================================ + +actions = [] +for item in categorized: + if item.category in ["Session Note", "Temporary State"]: + # Check age of temporary state + if item.category == "Temporary State" and item.age < 14 days: + continue # Too young to delete + actions.append({action: "DELETE", entry: item.entry, reason: item.category}) + elif item.category == "Historical Snapshot": + actions.append({action: "DELETE", entry: item.entry, reason: "Stale"}) + elif item.category == "Technical Config" and item.source == "USER.md": + actions.append({action: "MOVE", from: "USER.md", to: "MEMORY.md", entry: item.entry}) + elif item.category == "Identity" or item.category == "Preference" and item.source == "MEMORY.md": + actions.append({action: "MOVE", from: "MEMORY.md", to: "USER.md", entry: item.entry}) + elif item.category == "Operating Rule": + actions.append({action: "MOVE", from: "MEMORY.md", to: "Skill file", entry: item.entry}) + +# Check for duplicates +for entry_a, entry_b in find_duplicates(categorized): + actions.append({action: "DELETE", entry: entry_b.entry, reason: "Duplicate of " + entry_a.entry}) + +# ============================================================ +# PHASE 4: Verify live configs +# ============================================================ + +for item in categorized: + if item.category == "Technical Config" and item.entry contains URL: + result = call verify_endpoint(item.entry) + if result == "UNREACHABLE": + # Mark as UNVERIFIED, do not delete + actions.append({action: "MARK_UNVERIFIED", entry: item.entry}) + elif result == "VERIFIED": + pass # Good, nothing to do + +for item in categorized: + if item.category == "Technical Config" and item.entry contains "model:": + result = call verify_model(item.entry) + if result == "MISMATCH": + actions.append({action: "CORRECT", entry: item.entry, corrected: result.new_value}) + +# ============================================================ +# PHASE 5: Apply changes +# ============================================================ + +if dry_run: + return {status: "DRY_RUN", actions: actions, summary: generate_summary(actions)} + +# Apply deletions +for action in actions: + if action.action == "DELETE": + try: + memory action=remove target=action.source old_text=action.entry + catch after 2 retries: + patch path=action.source old_string=action.entry new_string="" + # Add summary marker since memory tool is broken + memory action=add target=action.source content="Entry deleted via patch: " + action.entry + +# Apply moves +for action in actions: + if action.action == "MOVE": + # Delete from source + patch path=action.from old_string=action.entry new_string="" + # Add to destination + append_file path=action.to content=action.entry + "\n" + +# Apply corrections +for action in actions: + if action.action == "CORRECT": + patch path="~/.hermes/memories/MEMORY.md" old_string=action.entry new_string=action.corrected + +# Apply UNVERIFIED marks +for action in actions: + if action.action == "MARK_UNVERIFIED": + patch path="~/.hermes/memories/MEMORY.md" old_string=action.entry new_string=action.entry + " [UNVERIFIED]" + +# ============================================================ +# PHASE 6: Post-audit verification +# ============================================================ + +new_memory_content = read_file("~/.hermes/memories/MEMORY.md") +new_user_content = read_file("~/.hermes/memories/USER.md") + +new_memory_util = len(new_memory_content) / max_memory_chars * 100 +new_user_util = len(new_user_content) / max_user_chars * 100 + +# Add summary markers to in-memory stores +memory action=add target=memory content="MEMORY.md rewritten. Utilization: " + new_memory_util + "%." +memory action=add target=user content="USER.md rewritten. Utilization: " + new_user_util + "%." + +# ============================================================ +# PHASE 7: Report +# ============================================================ + +return { + status: "COMPLETE", + memory_utilization: new_memory_util, + user_utilization: new_user_util, + actions_applied: len(actions), + deletions: count(actions, "DELETE"), + moves: count(actions, "MOVE"), + corrections: count(actions, "CORRECT"), + unverified: count(actions, "MARK_UNVERIFIED"), + unresolved: unresolved_entries, + last_audit: now(), + summary: generate_summary(actions) +} +``` + +### Shape + +- `self`: categorize, verify configs, apply incremental patches, generate reports +- `delegates`: + - `categorize_entry`: determine the category of a memory entry + - `check_memory_tool`: verify the memory tool is functional + - `verify_endpoint`: check if a URL is reachable + - `verify_model`: check if a model config matches live config.yaml + - `find_duplicates`: detect duplicate entries across files + - `generate_summary`: produce a human-readable summary of actions + +### Tools + +- `file:read`: read MEMORY.md and USER.md +- `file:patch`: incremental edits via find-and-replace +- `file:append`: append entries when moving between files +- `memory:action`: add/remove/replace entries in the in-memory store +- `network:curl`: verify endpoint reachability +- `cli:grep`: verify model configs against config.yaml + +### Environment + +- `MEMORY_PATH`: ~/.hermes/memories/MEMORY.md +- `USER_PATH`: ~/.hermes/memories/USER.md +- `CONFIG_PATH`: ~/.hermes/config.yaml \ No newline at end of file From 9ac383e812f0a5b247cb4c36c2c2781c8881a535 Mon Sep 17 00:00:00 2001 From: Jerome Date: Mon, 29 Jun 2026 00:42:54 +0000 Subject: [PATCH 5/7] v3: Add ledger, drift detection, canary checks, per-agent privacy, writer registry --- memory-audit-maintenance.prose.md | 111 +++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 9 deletions(-) diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md index 703f529..21d90e8 100644 --- a/memory-audit-maintenance.prose.md +++ b/memory-audit-maintenance.prose.md @@ -6,7 +6,7 @@ id: 067NC4KG01RG50R40M30E20918 ### Goal -Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, SOUL.md), categorize entries, redistribute them to correct locations, verify live configurations, and free character budget all without user intervention unless a truly unresolvable ambiguity exists. +Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, SOUL.md), categorize entries, redistribute them to correct locations, verify live configurations, and free character budget all without user intervention unless a truly unresolvable ambiguity exists. Every agent runs this contract for **its own** memory files only no cross-agent access, no shared state. ### Requires @@ -14,7 +14,7 @@ Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, ### Maintains -Memory health state current utilization, last audit timestamp, and any unresolved ambiguities. Postcondition: no entry is duplicated, no session note or stale snapshot survives, and no config is unverified. +Memory health state current utilization, last audit timestamp, drift alerts, and any unresolved ambiguities. Postcondition: no entry is duplicated, no session note or stale snapshot survives, no config is unverified, and the audit ledger is up-to-date. #### utilization Current character utilization of MEMORY.md and USER.md. Material: the percentages. @@ -25,6 +25,12 @@ Timestamp of the most recent successful audit. Material: the timestamp. #### unresolved Any entries that could not be autonomously categorized. Material: the entry text and the reason for ambiguity. +#### drift_alerts +Active alerts from drift detection (e.g., deletions accelerating, unverified configs growing). Material: the alert list. + +#### ledger +Persistent audit trail stored at `~/.hermes/memories/MEMORY_AUDIT_LEDGER.md`. Material: append-only, never modified or deleted. + ### Continuity - self-driven: re-audit every 14 days (2 weeks) @@ -41,11 +47,12 @@ Any entries that could not be autonomously categorized. Material: the entry text ### Strategies -- **Autonomous first:** Never ask the user about entries that clearly belong in a deletion or move category. Only escalate on true ambiguity (e.g., an entry could be either a Preference or a Technical Config, and the choice affects which file it goes in). +- **Autonomous first:** Never ask the user about entries that clearly belong in a deletion or move category. Only escalate on true ambiguity. - **Incremental over nuclear:** Always use patch-level edits (find-and-replace) rather than wholesale file rewrites. If the patch tool fails, fall back to rewrite only as a last resort. - **Verify before trusting:** Every technical config in MEMORY.md must be verified against the live system. If a service is unreachable, mark it as `UNVERIFIED` rather than deleting it. - **Stale state has a shelf life:** Any entry marked as "Temporary State" (e.g., "verbal offer", "deal pending", "negotiation phase") is deleted if older than 14 days. - **Work around tool failures:** If the `memory` tool fails after 2 retries, add a summary marker and report the stale state in the unresolved list. +- **Privacy isolation:** Each agent only reads and writes its own memory files. No cross-agent memory access, no shared ledger, no shared state. The contract is the standard; each agent runs it independently. ### Invariants @@ -53,14 +60,43 @@ Any entries that could not be autonomously categorized. Material: the entry text - No duplicate entries survive across MEMORY.md and USER.md - No session note or temporary state survives past 14 days - No config is trusted without verification (or marked UNVERIFIED) +- The audit ledger is append-only never modified or deleted +- The canary entry survives every audit unmodified ### Execution ```prose # ============================================================ -# PHASE 1: Pre-flight +# PHASE 0: Canaries & Privacy # ============================================================ +# Check canaries if either is missing or modified, raise CRITICAL alert +memory_canary = read_file_line("~/.hermes/memories/MEMORY.md", containing="CANARY: Do not modify this line") +user_canary = read_file_line("~/.hermes/memories/USER.md", containing="CANARY: Do not modify this line") + +if memory_canary is null or user_canary is null: + return { + status: "CRITICAL", + alert: "CANARY BREACH memory integrity compromised", + details: { + memory_canary_intact: memory_canary is not null, + user_canary_intact: user_canary is not null + } + } + +# This agent only touches its own files no cross-agent access +# Confirm we are operating on this agent's own memory directory +if not directory_exists("~/.hermes/memories"): + return {status: "ERROR", reason: "Memory directory not found for this agent"} + +# ============================================================ +# PHASE 1: Pre-flight & Ledger +# ============================================================ + +# Read the audit ledger for drift detection +ledger = read_file("~/.hermes/memories/MEMORY_AUDIT_LEDGER.md") +last_audit_entry = parse_last_entry(ledger) + # Verify the memory tool works try: memory_status = call check_memory_tool @@ -76,9 +112,36 @@ memory_util = len(memory_content) / max_memory_chars * 100 user_util = len(user_content) / max_user_chars * 100 # Check if audit is needed -if last_audit > 14 days and memory_util < 75 and user_util < 75: +if last_audit_entry.timestamp > 14 days and memory_util < 75 and user_util < 75: return {status: "SKIP", reason: "No audit needed"} +# ============================================================ +# PHASE 1b: Drift Detection (Compare to Last Audit) +# ============================================================ + +drift_alerts = [] + +if last_audit_entry exists: + # Deletions accelerating? (50% increase from last audit) + if last_audit_entry.deletions > 0: + deletion_increase = (memory_util - last_audit_entry.memory_util_after) / last_audit_entry.deletions * 100 + if deletion_increase > 50: + drift_alerts.append("ALERT: Memory bloat accelerating deletions increasing by " + deletion_increase + "% vs last audit") + + # Unverified configs growing? + if last_audit_entry.unverified > 0: + unverified_increase = count_entries(memory_content, "[UNVERIFIED]") - last_audit_entry.unverified + if unverified_increase > 2: + drift_alerts.append("ALERT: Unverified configs growing " + unverified_increase + " new unverified entries since last audit") + + # Audit missed? (No audit for >21 days) + if last_audit_entry.timestamp > 21 days: + drift_alerts.append("ALERT: Audit gap no audit completed in 21+ days") + + # Utilization not improving? (After audit, still >70%) + if last_audit_entry.memory_util_after > 70: + drift_alerts.append("ALERT: Previous audit failed to reduce MEMORY.md below 70% capacity issue") + # ============================================================ # PHASE 2: Categorize every entry # ============================================================ @@ -140,7 +203,7 @@ for item in categorized: # ============================================================ if dry_run: - return {status: "DRY_RUN", actions: actions, summary: generate_summary(actions)} + return {status: "DRY_RUN", actions: actions, drift_alerts: drift_alerts, summary: generate_summary(actions)} # Apply deletions for action in actions: @@ -180,12 +243,39 @@ new_user_content = read_file("~/.hermes/memories/USER.md") new_memory_util = len(new_memory_content) / max_memory_chars * 100 new_user_util = len(new_user_content) / max_user_chars * 100 +# Verify canaries survived the audit +post_canary_check = read_file_line("~/.hermes/memories/MEMORY.md", containing="CANARY: Do not modify this line") +if post_canary_check is null: + drift_alerts.append("CRITICAL: Canary destroyed during audit memory integrity compromised") + # Add summary markers to in-memory stores memory action=add target=memory content="MEMORY.md rewritten. Utilization: " + new_memory_util + "%." memory action=add target=user content="USER.md rewritten. Utilization: " + new_user_util + "%." # ============================================================ -# PHASE 7: Report +# PHASE 7: Append to Ledger +# ============================================================ + +ledger_entry = """ +## """ + now() + """ +- memory_util_before: """ + memory_util + """% +- memory_util_after: """ + new_memory_util + """% +- user_util_before: """ + user_util + """% +- user_util_after: """ + new_user_util + """% +- deletions: """ + count(actions, "DELETE") + """ +- moves: """ + count(actions, "MOVE") + """ +- corrections: """ + count(actions, "CORRECT") + """ +- unverified: """ + count(actions, "MARK_UNVERIFIED") + """ +- unresolved: """ + len(unresolved_entries) + """ +- drift_alerts: """ + len(drift_alerts) + """ +- canary_intact: """ + (post_canary_check is not null) + """ +- status: COMPLETE +""" + +append_file path="~/.hermes/memories/MEMORY_AUDIT_LEDGER.md" content=ledger_entry + +# ============================================================ +# PHASE 8: Report # ============================================================ return { @@ -198,14 +288,16 @@ return { corrections: count(actions, "CORRECT"), unverified: count(actions, "MARK_UNVERIFIED"), unresolved: unresolved_entries, + drift_alerts: drift_alerts, last_audit: now(), + ledger_updated: true, summary: generate_summary(actions) } ``` ### Shape -- `self`: categorize, verify configs, apply incremental patches, generate reports +- `self`: categorize, verify configs, apply incremental patches, generate reports, drift detection, ledger management, canary checks - `delegates`: - `categorize_entry`: determine the category of a memory entry - `check_memory_tool`: verify the memory tool is functional @@ -227,4 +319,5 @@ return { - `MEMORY_PATH`: ~/.hermes/memories/MEMORY.md - `USER_PATH`: ~/.hermes/memories/USER.md -- `CONFIG_PATH`: ~/.hermes/config.yaml \ No newline at end of file +- `CONFIG_PATH`: ~/.hermes/config.yaml +- `LEDGER_PATH`: ~/.hermes/memories/MEMORY_AUDIT_LEDGER.md \ No newline at end of file From 9cf428579c20d3b6cade3018cae99933549dc0ed Mon Sep 17 00:00:00 2001 From: Jerome Date: Mon, 29 Jun 2026 01:40:14 +0000 Subject: [PATCH 6/7] v4: Add Hermes agent roster (Mumuni, Tanko, Koby, Koonimo), per-agent isolation notes --- memory-audit-maintenance.prose.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md index 21d90e8..f2aed75 100644 --- a/memory-audit-maintenance.prose.md +++ b/memory-audit-maintenance.prose.md @@ -12,6 +12,16 @@ Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, (none this is a self-driven, autonomous node) +### Scope + +This contract is the **Hermes Agent standard** for memory maintenance. It is shared across all Hermes agents (Mumuni, Tanko, Koby, Koonimo). Each agent runs it against its own memory files only no cross-agent access, no shared state, no shared ledger. The contract is the standard; each agent enforces it independently. + +**Agent Roster:** +- Mumuni +- Tanko +- Koby +- Koonimo + ### Maintains Memory health state current utilization, last audit timestamp, drift alerts, and any unresolved ambiguities. Postcondition: no entry is duplicated, no session note or stale snapshot survives, no config is unverified, and the audit ledger is up-to-date. @@ -320,4 +330,8 @@ return { - `MEMORY_PATH`: ~/.hermes/memories/MEMORY.md - `USER_PATH`: ~/.hermes/memories/USER.md - `CONFIG_PATH`: ~/.hermes/config.yaml -- `LEDGER_PATH`: ~/.hermes/memories/MEMORY_AUDIT_LEDGER.md \ No newline at end of file +- `LEDGER_PATH`: ~/.hermes/memories/MEMORY_AUDIT_LEDGER.md + +### Per-Agent Notes + +Each Hermes agent (Mumuni, Tanko, Koby, Koonimo) runs this contract against its own `~/.hermes/memories/` directory. The contract is identical across agents, but the data is isolated. If a new agent is added to the roster, it must be listed in `### Scope` above. \ No newline at end of file From 9813c12895d06c2c850286ef393e10cf0329975e Mon Sep 17 00:00:00 2001 From: Jerome Date: Mon, 29 Jun 2026 01:47:10 +0000 Subject: [PATCH 7/7] v5: Full per-agent isolation separate ledgers, writer registries, canaries. No data crosses agent boundaries. --- memory-audit-maintenance.prose.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/memory-audit-maintenance.prose.md b/memory-audit-maintenance.prose.md index f2aed75..6703605 100644 --- a/memory-audit-maintenance.prose.md +++ b/memory-audit-maintenance.prose.md @@ -14,7 +14,7 @@ Autonomously audit and reorganize an agent's native memory (MEMORY.md, USER.md, ### Scope -This contract is the **Hermes Agent standard** for memory maintenance. It is shared across all Hermes agents (Mumuni, Tanko, Koby, Koonimo). Each agent runs it against its own memory files only no cross-agent access, no shared state, no shared ledger. The contract is the standard; each agent enforces it independently. +This contract is the **Hermes Agent standard** for memory maintenance. It is shared across all Hermes agents (Mumuni, Tanko, Koby, Koonimo). Each agent runs it against its own memory files only no cross-agent access, no shared state, no shared ledger, no shared canary. The contract is the standard; each agent enforces it independently with fully isolated data. **Agent Roster:** - Mumuni @@ -22,6 +22,13 @@ This contract is the **Hermes Agent standard** for memory maintenance. It is sha - Koby - Koonimo +**Isolation Principle:** Each agent has its own: +- `MEMORY.md` and `USER.md` +- `MEMORY_AUDIT_LEDGER.md` (audit trail) +- `MEMORY_WRITERS.md` (writer registry) +- Canary entries +- No data crosses agent boundaries + ### Maintains Memory health state current utilization, last audit timestamp, drift alerts, and any unresolved ambiguities. Postcondition: no entry is duplicated, no session note or stale snapshot survives, no config is unverified, and the audit ledger is up-to-date. @@ -39,7 +46,7 @@ Any entries that could not be autonomously categorized. Material: the entry text Active alerts from drift detection (e.g., deletions accelerating, unverified configs growing). Material: the alert list. #### ledger -Persistent audit trail stored at `~/.hermes/memories/MEMORY_AUDIT_LEDGER.md`. Material: append-only, never modified or deleted. +Persistent audit trail stored at the agent's own `~/.hermes/memories/MEMORY_AUDIT_LEDGER.md`. Material: append-only, never modified or deleted. Each agent has its own ledger no shared ledger across agents. ### Continuity @@ -70,8 +77,9 @@ Persistent audit trail stored at `~/.hermes/memories/MEMORY_AUDIT_LEDGER.md`. Ma - No duplicate entries survive across MEMORY.md and USER.md - No session note or temporary state survives past 14 days - No config is trusted without verification (or marked UNVERIFIED) -- The audit ledger is append-only never modified or deleted +- The audit ledger is append-only never modified or deleted, and is isolated per agent - The canary entry survives every audit unmodified +- No data crosses agent boundaries ### Execution @@ -334,4 +342,4 @@ return { ### Per-Agent Notes -Each Hermes agent (Mumuni, Tanko, Koby, Koonimo) runs this contract against its own `~/.hermes/memories/` directory. The contract is identical across agents, but the data is isolated. If a new agent is added to the roster, it must be listed in `### Scope` above. \ No newline at end of file +Each Hermes agent (Mumuni, Tanko, Koby, Koonimo) runs this contract against its own `~/.hermes/memories/` directory. The contract is identical across agents, but all data is fully isolated: separate ledgers, separate writer registries, separate canaries. If a new agent is added to the roster, it must be listed in `### Scope` above and given its own isolated memory directory. \ No newline at end of file