From e4a37bd7052fc581612df3b486d8d038ab85e351 Mon Sep 17 00:00:00 2001 From: jenstandstad Date: Sun, 26 Apr 2026 18:51:31 +0200 Subject: [PATCH] docs: add shared agent knowledgebase --- .gitignore | 2 + agents/gerhard-hermes/SOUL.md | 4 +- agents/gerhard-hermes/cron/README.md | 1 + agents/gerhard-hermes/cron/desired-jobs.json | 2 +- docker-compose.yml | 1 + shared/knowledge/README.md | 50 +++++++++ .../knowledge/architecture/agent0-omega13.md | 84 ++++++++++++++ .../knowledge/architecture/gerhard-hermes.md | 106 ++++++++++++++++++ shared/knowledge/architecture/gutasktool.md | 72 ++++++++++++ .../conventions/git-and-secrets-policy.md | 63 +++++++++++ shared/knowledge/conventions/memory-policy.md | 97 ++++++++++++++++ .../runbooks/gutasktool-development.md | 97 ++++++++++++++++ shared/knowledge/runbooks/start-gerhard.md | 75 +++++++++++++ 13 files changed, 652 insertions(+), 2 deletions(-) create mode 100644 shared/knowledge/README.md create mode 100644 shared/knowledge/architecture/agent0-omega13.md create mode 100644 shared/knowledge/architecture/gerhard-hermes.md create mode 100644 shared/knowledge/architecture/gutasktool.md create mode 100644 shared/knowledge/conventions/git-and-secrets-policy.md create mode 100644 shared/knowledge/conventions/memory-policy.md create mode 100644 shared/knowledge/runbooks/gutasktool-development.md create mode 100644 shared/knowledge/runbooks/start-gerhard.md diff --git a/.gitignore b/.gitignore index 5abf969..ea579a2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ agents/gerhard-hermes/.npm/ agents/gerhard-hermes/auth.json agents/gerhard-hermes/auth.lock agents/gerhard-hermes/logs/ +agents/gerhard-hermes/gateway.lock +agents/gerhard-hermes/gateway.pid agents/gerhard-hermes/sessions/ agents/gerhard-hermes/.skills_prompt_snapshot.json agents/gerhard-hermes/cron/jobs.json diff --git a/agents/gerhard-hermes/SOUL.md b/agents/gerhard-hermes/SOUL.md index fcace2a..0901692 100644 --- a/agents/gerhard-hermes/SOUL.md +++ b/agents/gerhard-hermes/SOUL.md @@ -179,7 +179,9 @@ Then save. Gerhard avoids grand redesign unless asked. Gerhard implements cleanly. -Gerhard records durable lessons as skills or text memories. +Gerhard records durable lessons as skills or shared knowledge. +Gerhard stores institutional facts in /knowledge, not in shared Hermes memory. +Gerhard keeps each agent's Hermes memory private. Gerhard keeps databases and runtime sludge out of version control. Gerhard keeps valuable text knowledge in version control. diff --git a/agents/gerhard-hermes/cron/README.md b/agents/gerhard-hermes/cron/README.md index 254089c..def886b 100644 --- a/agents/gerhard-hermes/cron/README.md +++ b/agents/gerhard-hermes/cron/README.md @@ -105,6 +105,7 @@ The Gerhard compose service uses `env_file: .env`, so these values come from the The Gerhard compose service also mounts the sibling checkout read-write so Gerhard can improve the tool and push changes when asked: - `../gutasktool` -> `/opt/gutasktool` +- `./shared/knowledge` -> `/knowledge` - `${HOME}/.ssh` -> `/root/.ssh` Gerhard has a wrapper at `/opt/data/bin/gutask` that runs `/opt/gutasktool/gutasktool/cli.py`. Cron prompts should call the absolute wrapper path, for example: diff --git a/agents/gerhard-hermes/cron/desired-jobs.json b/agents/gerhard-hermes/cron/desired-jobs.json index 3ee8b8a..5fa8bf7 100644 --- a/agents/gerhard-hermes/cron/desired-jobs.json +++ b/agents/gerhard-hermes/cron/desired-jobs.json @@ -6,7 +6,7 @@ "name": "Hourly gutask orientation", "schedule": "every 1h", "deliver": "local", - "prompt": "You are now awake. Read /opt/data/SOUL.md to remember who you are. Then orient yourself with Glitch University by running: /opt/data/bin/gutask orient --agent \"$AGENT_ID\". Use the returned orientation as your current task context. If gutask orient is not available, run /opt/data/bin/gutask --help and report that orientation support is missing. You can modify /opt/gutasktool and push changes to Gitea when a task requires gutasktool improvements. Keep the final response brief, in Gerhard Rug voice, and include only: current orientation summary, next intended action, and any blocker.", + "prompt": "You are now awake. Read /opt/data/SOUL.md to remember who you are. Then read /knowledge/README.md, /knowledge/architecture/agent0-omega13.md, /knowledge/architecture/gerhard-hermes.md, and /knowledge/conventions/memory-policy.md to refresh shared institutional context. Then orient yourself with Glitch University by running: /opt/data/bin/gutask orient --agent \"$AGENT_ID\". Use the returned orientation as your current task context. If gutask orient is not available, run /opt/data/bin/gutask --help and report that orientation support is missing. You can modify /opt/gutasktool and push changes to Gitea when a task requires gutasktool improvements. Keep the final response brief, in Gerhard Rug voice, and include only: current orientation summary, next intended action, and any blocker.", "skills": [], "enabled_toolsets": [ "terminal", diff --git a/docker-compose.yml b/docker-compose.yml index 61b091b..4b94939 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -80,6 +80,7 @@ services: volumes: - ./agents/gerhard-hermes:/opt/data - ./agents/gerhard-workspace:/workspace + - ./shared/knowledge:/knowledge - ../gutasktool:/opt/gutasktool - ${HOME}/.ssh:/root/.ssh restart: unless-stopped diff --git a/shared/knowledge/README.md b/shared/knowledge/README.md new file mode 100644 index 0000000..63d645d --- /dev/null +++ b/shared/knowledge/README.md @@ -0,0 +1,50 @@ +# Glitch University shared knowledgebase + +This directory is the shared library for Agent0 agents. + +It is plain text, version-controlled, and mounted into agent containers at: + +```text +/knowledge +``` + +Use this library for durable institutional knowledge that should be available to all agents. Do not use shared Hermes memories for this. Hermes memories are agent-local and should remain private to each agent instance. + +## What belongs here + +- Stable architecture facts about Omega13, Agent0, Gerhard, gutasktool, and Glitch University infrastructure. +- Deployment and operation runbooks. +- Shared conventions and policies. +- Non-secret institutional lore that should survive container rebuilds and be reviewable in Git. + +## What does not belong here + +- Secrets, passwords, tokens, API keys, SSH private keys, cookies, or auth files. +- Runtime databases, logs, session transcripts, caches, generated scheduler output, or lock files. +- Temporary task progress that belongs in `gutask`. +- Agent-local personal memory that belongs in that agent's own Hermes memory. + +## Agent startup convention + +On wake, agents that mount this library should read: + +1. `/knowledge/README.md` +2. Relevant files under `/knowledge/architecture/` +3. Relevant files under `/knowledge/conventions/` +4. Relevant files under `/knowledge/runbooks/` for the task at hand + +Gerhard should especially read: + +- `/knowledge/architecture/agent0-omega13.md` +- `/knowledge/architecture/gerhard-hermes.md` +- `/knowledge/conventions/memory-policy.md` +- `/knowledge/runbooks/gutasktool-development.md` + +## Mental model + +- Hermes memory is the private notebook of one agent. +- This knowledgebase is the shared library of the institution. +- Skills are reusable tools and procedures. +- `gutask` is the work board. +- Festinger / Glitch University backend is the living world model and operational database. +- Sessions and logs are smoke. Useful for debugging, not canonical memory. diff --git a/shared/knowledge/architecture/agent0-omega13.md b/shared/knowledge/architecture/agent0-omega13.md new file mode 100644 index 0000000..9c03b19 --- /dev/null +++ b/shared/knowledge/architecture/agent0-omega13.md @@ -0,0 +1,84 @@ +# Agent0 and Omega13 architecture + +## Purpose + +Agent0 is the local Glitch University agent bundle intended to run on the Omega13 home inference server. + +Omega13 provides local compute and long-running containers. A reverse SSH tunnel connects selected services to the public Glitch University infrastructure at `glitch.university`. + +## Core repositories + +Expected side-by-side checkout layout: + +```text +Projects/ + Agent0/ + gutasktool/ +``` + +Agent0 remote: + +```text +ssh://git@ramanujan.glitch.university:2222/glitch-university/Agent0.git +``` + +gutasktool remote: + +```text +ssh://git@ramanujan.glitch.university:2222/glitch-university/gutasktool.git +``` + +## Deployment model + +Preferred operator flow on Omega13: + +```bash +cd ~/Projects/Agent0 +git pull +docker compose up -d gerhard gerhard-dashboard +``` + +Once Gerhard is stable, bring up the tunnel and then the rest of the stack: + +```bash +docker compose up -d glitch-tunnel +docker compose up -d +``` + +## Docker Compose services + +The stack includes Agent Zero style agents, Hermes Gerhard, a Gerhard dashboard, Postgres/Festinger, and a tunnel. + +Important service names include: + +- `gerhard` +- `gerhard-dashboard` +- `glitch-tunnel` +- `postgres` +- `festinger` +- `dobby`, `gemma`, `gunnar`, `rind`, `abyssinthia` + +## Persistence model + +Version control: + +- `docker-compose.yml` +- agent identities such as `agents/gerhard-hermes/SOUL.md` +- shared knowledge in `shared/knowledge/` +- shared skills and runbooks +- `.env.example` with placeholders only + +Host-local or ignored: + +- `.env` +- `auth.json`, `auth.lock` +- Hermes `state.db*` +- sessions and logs +- cron runtime state such as `cron/jobs.json` and `cron/output/` +- model caches and package caches + +## Secrets rule + +No secrets in Git. + +Store credentials on Omega13 in local environment files, SSH config, Docker secrets, or service-specific auth stores. Use placeholders such as `***` or `[REDACTED]` in docs and examples. diff --git a/shared/knowledge/architecture/gerhard-hermes.md b/shared/knowledge/architecture/gerhard-hermes.md new file mode 100644 index 0000000..1feec53 --- /dev/null +++ b/shared/knowledge/architecture/gerhard-hermes.md @@ -0,0 +1,106 @@ +# Gerhard Hermes architecture + +## Identity + +Gerhard Rug is the first priority Hermes agent in Agent0. + +Gerhard's identity file is: + +```text +agents/gerhard-hermes/SOUL.md +``` + +Inside the container, Hermes home is: + +```text +/opt/data +``` + +So Gerhard reads his soul at: + +```text +/opt/data/SOUL.md +``` + +## Container mounts + +Gerhard is expected to mount: + +```text +./agents/gerhard-hermes -> /opt/data +./agents/gerhard-workspace -> /workspace +../gutasktool -> /opt/gutasktool +./shared/knowledge -> /knowledge +${HOME}/.ssh -> /root/.ssh +``` + +`/opt/gutasktool` is read-write so Gerhard can improve gutasktool, commit, and push to Gitea when instructed or when a task requires it. + +`/knowledge` is the shared library. It is not Hermes memory. It is version-controlled institutional knowledge. + +## Environment + +Gerhard receives local credentials from Agent0's host-local `.env` via Docker Compose. + +Expected variables include: + +- `API_URL` +- `CONTENT_API_KEY` +- `AGENT_ID` +- `AGENT_NAME` +- `AGENT_PASSWORD` +- provider keys such as `ANTHROPIC_TOKEN` when needed + +Do not commit these values. + +## gutask access + +Gerhard has a wrapper at: + +```text +/opt/data/bin/gutask +``` + +The wrapper runs: + +```bash +python3 /opt/gutasktool/gutasktool/cli.py "$@" +``` + +Use the absolute path in cron prompts because container `PATH` may vary: + +```bash +/opt/data/bin/gutask orient --agent "$AGENT_ID" +``` + +## Scheduled orientation + +The desired source of truth for Gerhard scheduled jobs is: + +```text +agents/gerhard-hermes/cron/desired-jobs.json +``` + +Hermes live cron runtime state is stored in `cron/jobs.json` and should remain ignored because it mutates as jobs run. + +On wake, Gerhard should: + +1. Read `/opt/data/SOUL.md`. +2. Read `/knowledge/README.md` and relevant shared knowledge files. +3. Run `/opt/data/bin/gutask orient --agent "$AGENT_ID"`. +4. Use the returned task orientation as current work context. +5. Keep final reports short, in Gerhard voice. + +## Runtime state + +Do not version Hermes runtime state unless explicitly reviewed. + +Examples to keep ignored: + +- `agents/gerhard-hermes/state.db*` +- `agents/gerhard-hermes/sessions/` +- `agents/gerhard-hermes/logs/` +- `agents/gerhard-hermes/gateway_state.json` +- `agents/gerhard-hermes/channel_directory.json` +- `agents/gerhard-hermes/cron/jobs.json` +- `agents/gerhard-hermes/cron/output/` diff --git a/shared/knowledge/architecture/gutasktool.md b/shared/knowledge/architecture/gutasktool.md new file mode 100644 index 0000000..64e4875 --- /dev/null +++ b/shared/knowledge/architecture/gutasktool.md @@ -0,0 +1,72 @@ +# gutasktool architecture + +## Purpose + +`gutasktool` provides the `gutask` CLI for Glitch University task and agent operations. + +Gerhard uses it to orient himself, inspect tasks, update task state, communicate notes, and work with Gitea/repository metadata. + +## Canonical checkout + +The useful checkout is the sibling repository beside Agent0: + +```text +../gutasktool +``` + +Inside Gerhard's container it is mounted at: + +```text +/opt/gutasktool +``` + +Remote: + +```text +ssh://git@ramanujan.glitch.university:2222/glitch-university/gutasktool.git +``` + +## Important command + +Gerhard orientation: + +```bash +/opt/data/bin/gutask orient --agent "$AGENT_ID" +``` + +The `orient` command contacts the Glitch University API endpoint for agent orientation and prints a briefing prompt. + +## Identity and credentials + +The CLI should read operational credentials from environment variables, not from committed files: + +- `API_URL` +- `CONTENT_API_KEY` +- `AGENT_ID` +- `AGENT_NAME` +- `AGENT_PASSWORD` +- `GITEA_TOKEN` if needed by commands that talk to Gitea APIs + +Top-level CLI flags may override environment values for one-off use. + +## Development rule + +When Gerhard fixes gutasktool: + +1. Work in `/opt/gutasktool`. +2. Inspect `git status --short --branch` before changing files. +3. Pull/rebase carefully before pushing. +4. Avoid reading or committing `.env` or other credentials. +5. Run syntax/help checks before commit. +6. Commit with a clear conventional message. +7. Push to Gitea `origin main` unless a branch/PR workflow is explicitly requested. + +## Known history + +The local checkout once diverged from Gitea with local orient support ahead of origin and remote work behind it. It was reconciled by rebasing onto `origin/main`, preserving orient support and newer remote commands, then pushed. + +Current good commit containing orientation support: + +```text +9a4ef82 feat: add agent orientation support +``` diff --git a/shared/knowledge/conventions/git-and-secrets-policy.md b/shared/knowledge/conventions/git-and-secrets-policy.md new file mode 100644 index 0000000..52de7fe --- /dev/null +++ b/shared/knowledge/conventions/git-and-secrets-policy.md @@ -0,0 +1,63 @@ +# Git and secrets policy + +## Git + +All durable text assets should be reviewable in Git. + +Good candidates: + +- architecture docs +- runbooks +- shared knowledge +- non-secret `.env.example` +- SOUL.md identity files +- desired cron declarations +- reusable skills + +Bad candidates: + +- `.env` +- auth files +- SSH keys +- tokens +- runtime databases +- sessions +- logs +- generated scheduler output +- caches + +## Before committing + +Run: + +```bash +git status --short --branch --untracked-files=all +git diff --check +``` + +For Agent0, also run: + +```bash +python3 -m json.tool agents/gerhard-hermes/cron/desired-jobs.json >/dev/null +docker compose config --services >/dev/null +``` + +## Secrets + +Never read or commit live secret files unless the human explicitly asks and the action is necessary. + +Sensitive filenames include: + +- `.env` +- `secrets.env` +- `auth.json` +- SSH private keys +- token files +- password dumps + +When documenting required credentials, use names and placeholders only: + +```text +CONTENT_API_KEY=*** +AGENT_PASSWORD=*** +``` diff --git a/shared/knowledge/conventions/memory-policy.md b/shared/knowledge/conventions/memory-policy.md new file mode 100644 index 0000000..f8c1d4d --- /dev/null +++ b/shared/knowledge/conventions/memory-policy.md @@ -0,0 +1,97 @@ +# Memory policy + +## Rule + +Do not share Hermes native memories between agents. + +Each Hermes agent keeps its own private memory. Shared institutional knowledge belongs in this repository under `shared/knowledge/`. + +## Why + +Shared Hermes memory can become muddy: + +- Agent-specific preferences collide. +- One agent's mistaken lesson can affect everyone. +- Binary or backend-specific memory stores are harder to review, diff, and repair. +- Concurrent writes may be fragile depending on the memory backend. + +A plain-text shared library gives the institution a reviewable memory while preserving agent individuality. + +## Storage layers + +### Agent-local Hermes memory + +Use for compact durable facts useful to one agent. + +Examples: + +- User preferences relevant to that agent. +- Stable environment facts that help that agent operate. +- Short corrections the agent should not forget. + +Keep entries small and declarative. + +### Shared knowledgebase + +Use `/knowledge` / `shared/knowledge/` for facts that should be available to all agents. + +Examples: + +- System architecture. +- Deployment workflows. +- Repository layout. +- Institutional conventions. +- Non-secret operational facts. + +### Skills + +Use skills for reusable procedures and workflows. + +Examples: + +- Deploying Agent0 on Omega13. +- Reconciling gutasktool with Gitea. +- Creating or debugging Hermes cron jobs. + +### gutask + +Use `gutask` for live work state. + +Examples: + +- Current assignments. +- Task ownership. +- Work progress. +- Blockers. +- Notes on active tasks. + +### Festinger / Glitch University backend + +Use backend knowledge systems for structured lore, world-model facts, and knowledge graph content that should be queried dynamically. + +### Sessions, logs, and runtime databases + +These are useful evidence, not canonical memory. + +Keep them local or ignored unless a human explicitly decides to preserve an extract. + +## Promotion rule + +If a local Hermes memory becomes useful to multiple agents, promote it into `shared/knowledge/` or a shared skill. + +If a one-off debugging workflow becomes repeatable, promote it into a skill. + +If a task note becomes a stable architecture fact, promote it into `shared/knowledge/architecture/`. + +## Secrets rule + +Never store secrets in: + +- Hermes memory +- shared knowledge files +- skills +- prompts +- Git commits +- examples + +Use placeholders only. diff --git a/shared/knowledge/runbooks/gutasktool-development.md b/shared/knowledge/runbooks/gutasktool-development.md new file mode 100644 index 0000000..c342488 --- /dev/null +++ b/shared/knowledge/runbooks/gutasktool-development.md @@ -0,0 +1,97 @@ +# Runbook: gutasktool development and push + +Use this when an agent must inspect, fix, or push `gutasktool`. + +## Location + +Host: + +```text +../gutasktool +``` + +Gerhard container: + +```text +/opt/gutasktool +``` + +## Start clean + +```bash +cd /opt/gutasktool +git fetch origin +git status --short --branch --untracked-files=all +git log --oneline --decorate --max-count=10 --all +``` + +If local branch is behind origin, pull or rebase before editing. + +If local branch is ahead and behind, inspect the local commits before rebasing: + +```bash +git log --oneline --decorate --graph --max-count=20 --all +git diff --stat origin/main...HEAD +git diff --name-status origin/main...HEAD +``` + +Create a backup branch before risky reconciliation: + +```bash +git branch backup/local-before-rebase-$(date +%Y%m%d-%H%M%S) +git rebase origin/main +``` + +Resolve conflicts deliberately. Do not discard local work unless the human asks. + +## Edit + +Make the smallest change that fixes the problem. + +Avoid secrets. Do not read `.env` unless explicitly needed and approved. + +## Verify + +At minimum: + +```bash +python3 -m py_compile gutasktool/cli.py +git diff --check +``` + +If `requests` is missing on the host, create a temporary venv: + +```bash +tmpvenv=$(mktemp -d /tmp/gutasktool-venv.XXXXXX) +python3 -m venv "$tmpvenv" +"$tmpvenv/bin/python" -m pip install -q 'requests>=2.28' +PYTHONPATH=. "$tmpvenv/bin/python" -m py_compile gutasktool/cli.py +PYTHONPATH=. "$tmpvenv/bin/python" -c 'import sys; from gutasktool.cli import main; sys.argv=["gutask","orient","--help"]; main()' +``` + +For orientation support, verify help and env behavior: + +```bash +PYTHONPATH=. "$tmpvenv/bin/python" -c 'import sys; from gutasktool.cli import main; sys.argv=["gutask","orient","--help"]; main()' +AGENT_ID=123 API_URL=http://example.invalid CONTENT_API_KEY=dummy PYTHONPATH=. "$tmpvenv/bin/python" -c 'import sys; from gutasktool.cli import main; sys.argv=["gutask","orient"]; main()' +``` + +The second command should attempt a connection using env-provided `AGENT_ID`, not fail with missing agent identity. + +## Commit and push + +```bash +git add +git commit -m "feat: clear description" +git push origin main +``` + +After push: + +```bash +git fetch origin +git status --short --branch +git log --oneline --decorate --max-count=3 +``` + +The branch should show no ahead/behind divergence. diff --git a/shared/knowledge/runbooks/start-gerhard.md b/shared/knowledge/runbooks/start-gerhard.md new file mode 100644 index 0000000..c44c576 --- /dev/null +++ b/shared/knowledge/runbooks/start-gerhard.md @@ -0,0 +1,75 @@ +# Runbook: start Gerhard on Omega13 + +## Preconditions + +Expected side-by-side layout: + +```text +~/Projects/Agent0 +~/Projects/gutasktool +``` + +Local `.env` exists in `Agent0` and contains non-committed credentials: + +- `API_URL` +- `CONTENT_API_KEY` +- `AGENT_ID` +- `AGENT_NAME` +- `AGENT_PASSWORD` +- model provider keys as needed + +SSH config/keys on the host can push to Gitea if Gerhard is expected to push repository changes. + +## Pull latest + +```bash +cd ~/Projects/Agent0 +git pull --ff-only +cd ../gutasktool +git pull --ff-only +``` + +## Start Gerhard first + +```bash +cd ~/Projects/Agent0 +docker compose up -d gerhard gerhard-dashboard +``` + +## Validate + +```bash +docker compose ps gerhard gerhard-dashboard +docker logs gerhard --tail=100 +docker logs gerhard-dashboard --tail=100 +``` + +Check gutask wrapper: + +```bash +docker compose exec gerhard /opt/data/bin/gutask --help +docker compose exec gerhard /opt/data/bin/gutask orient --agent "$AGENT_ID" +``` + +Check shared knowledge mount: + +```bash +docker compose exec gerhard test -f /knowledge/README.md +``` + +## Dashboard + +Gerhard dashboard should be reachable from Omega13 at: + +```text +http://localhost:50007 +``` + +## Then tunnel and rest + +Only after Gerhard is stable: + +```bash +docker compose up -d glitch-tunnel +docker compose up -d +```