# VPS, Hermes, and DB Mapping - 2026-07-09

Generated UTC: `2026-07-09T21:49:34Z`

This document captures the current working understanding of the Leo-on-VPS runtime, the NousResearch Hermes agent installation, the `leoclean` profile, and the Teleo knowledge database. It separates confirmed current facts from inferred behavior and open questions.

## One-Line Model

Leo on the VPS is a NousResearch Hermes gateway process running the `leoclean` profile under systemd. The profile supplies runtime identity, sessions, skills, and tools, but the canonical knowledge base is Dockerized Postgres (`teleo-pg`, database `teleo`), not `.hermes` runtime memory and not Forgejo.

## Confirmed Current Surfaces

| Surface | Current role | Current location / identifier |
| --- | --- | --- |
| VPS host | Live runtime host | `77.42.65.182` |
| Service manager | Keeps Telegram gateway alive | `/etc/systemd/system/leoclean-gateway.service` |
| Service process | Active Hermes gateway | `hermes -p leoclean gateway run` |
| Service user/cwd | Runtime Unix boundary | user `teleo`, cwd `/home/teleo` |
| Upstream Hermes checkout | NousResearch Hermes agent code | `/home/teleo/.hermes/hermes-agent` |
| Active Hermes profile | Leo runtime profile | `/home/teleo/.hermes/profiles/leoclean` |
| Teleo deployment checkout | Live deploy/source workspace | `/opt/teleo-eval/workspaces/deploy-infra` |
| Canonical KB database | Applied collective knowledge | Docker container `teleo-pg`, Postgres database `teleo` |
| Staging/proposal schema | Review ledger and staged material | `teleo.kb_stage` |
| Canonical schema | Applied claims, evidence, graph, strategy | `teleo.public` |
| Repo evidence pack | Local committed July 9 truth | `docs/reports/leo-working-state-20260709/` |

Fresh VPS readback showed `leoclean-gateway.service` active/running with `MainPID=3252143`, `NRestarts=0`, and process command:

```text
/home/teleo/.hermes/hermes-agent/venv/bin/python3 /home/teleo/.hermes/hermes-agent/venv/bin/hermes -p leoclean gateway run
```

## Service Unit

The production gateway is systemd-managed:

```ini
[Service]
Type=simple
User=teleo
WorkingDirectory=/home/teleo
ExecStart=/home/teleo/.hermes/hermes-agent/venv/bin/hermes -p leoclean gateway run
Restart=always
RestartSec=5
Environment=HOME=/home/teleo
```

Implication: `systemctl` and the process table are the liveness source of truth. A generic Hermes CLI status readback can be stale or misleading if it does not understand the systemd-managed process.

## NousResearch Hermes Layer

Confirmed upstream runtime checkout:

```text
/home/teleo/.hermes/hermes-agent
origin: https://github.com/NousResearch/hermes-agent.git
branch: main
HEAD: b2f477a30b3c05d0f383c543af98496ae8a96070
```

This is the agent runtime. It provides the gateway, profile system, skills, terminal/browser/tooling surfaces, model routing, sessions, memories, and cron-style capabilities.

The active Leo-specific profile is not the upstream repository itself. It is:

```text
/home/teleo/.hermes/profiles/leoclean
```

The profile contains:

- `config.yaml`: model, terminal, browser, memory, gateway, display, and tool configuration.
- `SOUL.md`: runtime identity context rendered from Teleo Postgres.
- `state.db`, `state.db-wal`, `state.db-shm`: local Hermes runtime state.
- `sessions/`: prior Hermes session transcripts and runtime continuity.
- `memories/`: Hermes profile memory files.
- `skills/`: installed profile skills, including `teleo-kb-bridge` and `live-leo-telegram`.
- `bin/teleo-kb`, `bin/kb_tool.py`, `bin/cloudsql_memory_tool.py`: DB-facing KB bridge tools.
- `kb_stage/proposals`, `kb_stage/evaluations`, `kb_stage/reports`, `workspace/ingested`: local profile artifacts and synchronized reports, not the canonical DB.

Redacted config readback shows:

```text
model.provider: openrouter
model.default: anthropic/claude-sonnet-4-6
model.smart_routing: true
model.smart_routing_model: google/gemini-2.5-flash
agent.max_turns: 90
agent.gateway_timeout: 1800
terminal.backend: local
memory.enabled: true
memory.search: sqlite_fts5
```

Sensitive fields such as API keys, tokens, credentials, and voice keys are intentionally omitted from this report.

## Leo's SOUL File

The active profile has:

```text
/home/teleo/.hermes/profiles/leoclean/SOUL.md
```

The file begins:

```text
# Leo - SOUL

> Rendered from the Teleo Postgres DB.
> Renderer: 0013 Leo V2 Identity Graph.
> Canonical claim/source evidence depth stays on demand via `teleo-kb`;
> this file is runtime identity context, not a KB dump.
```

Current interpretation:

- `SOUL.md` is important runtime context for Leo's identity and behavior.
- It is not itself the canonical KB.
- It is generated or rendered from canonical Postgres surfaces and then loaded as profile context.
- When the DB changes, Leo may need a render/sync step for `SOUL.md` or reports to reflect the latest canonical identity graph.

The SOUL file also includes rules that matter for DB changes:

- Runtime model is set by the active Hermes profile config and must be checked from the profile, not guessed.
- Changes to Leo's own identity, beliefs, and positions require review; Leo should not self-merge or self-edit.
- Canonical truth is distinct from runtime memory.

## Identity Compilation From The Database

The two July 9 PDFs supplied for this pass sharpen the identity model:

- `LivingIP-Master-Build-Guide.pdf` says the architectural north star is database-first agent identity. Agent identities are durable database records; runtime context is assembled from DB-backed identity, mission, memory, knowledge, conversations, tasks, decisions, artifacts, and events.
- The same guide says the Leo V2 identity graph makes Leo's soul a graph in Postgres, not a static file.
- The identity graph surfaces named in the guide are `public.personas`, `public.shared_root`, `public.strategy_nodes`, `public.strategy_node_anchors`, `public.claims(type='concept')`, beliefs, blindspots, rules, peers, and source-backed claim/evidence rows.
- It says the intended renderer walks the graph into a fixed `SOUL.md` order: Telos, Guiding Policy, Role, Lens, Voice, Strategy, Beliefs, Blindspots, Behavioral Rules, Peers.
- It also says evidence depth stays on demand through `teleo-kb`; the SOUL file is identity context, not a KB dump.

Current working model:

```text
canonical Postgres identity graph
  -> renderer / sync step
  -> /home/teleo/.hermes/profiles/leoclean/SOUL.md
  -> Hermes/leoclean runtime prompt context
  -> Leo answers, using teleo-kb for deeper claim/source/evidence retrieval
```

Therefore:

- Editing `SOUL.md` directly changes a runtime profile artifact.
- Editing `SOUL.md` directly does not prove the canonical DB changed.
- A later render from Postgres can overwrite direct `SOUL.md` edits if those edits were not first represented in canonical DB rows.
- The durable fix for identity/strategy changes is canonical DB apply first, then render/sync `SOUL.md`, then verify Leo reads the new identity.

## SOUL Render Status On VPS

The intended apply-worker loop is explicit in `scripts/apply_worker.py`:

```text
Leo proposes -> HUMAN approves -> WORKER applies -> renderer runs -> Leo reads the new self
```

The current production readback does not prove that the loop is active:

- `/etc/systemd/system/teleo-kb-apply-worker.service` exists.
- The worker is `disabled` and `inactive (dead)`.
- The unit intentionally ships inert: without `KB_APPLY_WORKER_ENABLED=1`, it is report-only.
- The unit allows `KB_APPLY_RENDER_CMD=...`, but no active render command was found in systemd readback.
- Searches under `/home/teleo` and `/opt/teleo-eval` found `SOUL.md` and references to the intended renderer, but did not find a deployed `render-soul.sh`, `render_soul.py`, or equivalent live renderer script.

This means the correct current answer to the user's hypothesis is:

```text
It is plausible for SOUL.md to lag canonical DB rows if the renderer hook is absent.
It is also plausible for a direct SOUL.md patch to appear live while not being canonical.
But it is not currently proven that SOUL.md recomposes every 24 hours.
The PDF says restart can re-render from the already-canonical DB, but live service/timer evidence does not show an active scheduled 24-hour renderer.
```

Benchmark implication:

Leo must not answer "I changed my soul" as if it changed the DB. It must name whether the changed surface is:

1. `public.*` canonical identity/strategy rows;
2. `kb_stage.*` proposal/review rows;
3. `SOUL.md` runtime render artifact;
4. `.hermes` runtime memory/session state.

## Teleo Deployment / Repo Layer

Confirmed deployment checkout on the VPS:

```text
/opt/teleo-eval/workspaces/deploy-infra
github remote: https://github.com/living-ip/teleo-infrastructure.git
origin remote: http://localhost:3000/teleo/teleo-infrastructure.git
branch: main
HEAD: 2e2dcff4d30fde04cfa6f2a6fe9da67d42f70658
```

Current interpretation:

- This workspace is the live deploy/source area used by current work.
- It has both a local Forgejo remote and a GitHub remote.
- Forgejo appears to be a code/review/deploy provenance surface for this infrastructure, not the canonical KB database.
- The live KB does not come from reading files in this workspace at answer time; Leo answers by querying Postgres through `teleo-kb` or DB tooling.

## Forgejo Relationship

Confirmed current role:

- Forgejo exists as a containerized code hosting/review surface on the VPS.
- The deployment checkout still has a Forgejo-style `origin` remote at `http://localhost:3000/teleo/teleo-infrastructure.git`.
- Repo code and historical PR pipeline references use Forgejo for code provenance and source/archive links.

Not proven:

- It is not currently proven that the canonical live KB was built directly from the Forgejo database.
- It is not currently proven that Forgejo remains an authoritative source for claims/evidence/sources.

Best current wording:

```text
Forgejo is part of the code/deploy provenance story. Docker Postgres is the canonical KB authority. A one-time historical seed/import path from repo-managed files may exist, but current evidence does not prove that the live DB is built from Forgejo DB state.
```

## Docker Postgres KB

Confirmed current DB readback:

```text
container: teleo-pg
image: postgres:16
database: teleo
schemas: public, kb_stage
```

Current table counts from read-only VPS query:

| Object | Count |
| --- | ---: |
| `public` tables | 28 |
| `kb_stage` tables | 11 |
| `public.claims` | 1837 |
| `public.sources` | 4145 |
| `public.claim_edges` | 4916 |
| `public.claim_evidence` | 4670 |
| `kb_stage.kb_proposals` | 26 |

## Canonical DB Objects

The main canonical objects are in `public`.

### `public.claims`

Columns:

```text
id uuid
type text
text text
status text
confidence numeric
tags ARRAY
created_by uuid
superseded_by uuid
created_at timestamptz
updated_at timestamptz
```

Important: current `public.claims` does not have a canonical `body` column and does not have a general `metadata` JSONB column.

### `public.sources`

Columns:

```text
id uuid
source_type text
url text
storage_path text
excerpt text
hash text
captured_at timestamptz
created_by uuid
created_at timestamptz
```

`sources.excerpt`, `url`, `storage_path`, and `hash` carry much of the evidence provenance.

### `public.claim_evidence`

Columns:

```text
claim_id uuid
source_id uuid
role USER-DEFINED
weight numeric
created_by uuid
created_at timestamptz
```

This is the claim-to-source evidence join table.

### `public.claim_edges`

Columns:

```text
id uuid
from_claim uuid
to_claim uuid
edge_type USER-DEFINED
weight numeric
created_by uuid
created_at timestamptz
```

This is the canonical claim graph.

### `public.strategy_nodes`

Columns:

```text
id uuid
agent_id uuid
node_type text
title text
body text
rank integer
status text
horizon text
measure text
source_ref text
metadata jsonb
created_at timestamptz
updated_at timestamptz
```

Strategy nodes are richer than claims. They have `body` and `metadata`, which makes them a better canonical target for agent strategy, telos, objectives, and policy nodes.

### `public.strategy_node_anchors`

Columns:

```text
id uuid
from_node_id uuid
anchor_role text
to_node_id uuid
to_shared_root_id uuid
belief_id uuid
claim_id uuid
source_id uuid
weight numeric
note text
created_at timestamptz
```

Important live constraint discovered during clone proof: one anchor row can target exactly one of `to_node_id`, `to_shared_root_id`, `belief_id`, `claim_id`, or `source_id`.

## Staging / Proposal Objects

The main staging objects are in `kb_stage`.

### `kb_stage.kb_proposals`

Columns:

```text
id uuid
proposal_type text
status text
proposed_by_handle text
proposed_by_agent_id uuid
channel text
source_ref text
rationale text
payload jsonb
reviewed_by_handle text
reviewed_by_agent_id uuid
reviewed_at timestamptz
review_note text
applied_by_handle text
applied_by_agent_id uuid
applied_at timestamptz
created_at timestamptz
updated_at timestamptz
```

This is the durable proposal ledger. A row here can mean a change is proposed, approved, or applied, but the canonical proof is still whether matching `public.*` rows exist.

### `kb_stage.staged_claims`

Columns:

```text
run_id uuid
path text
legacy_id text
title text
body text
claim_type text
status text
confidence_numeric numeric
tags ARRAY
created_by_handle text
created_at_legacy timestamptz
source_ref text
sourced_from text
warnings ARRAY
raw_frontmatter jsonb
created_at timestamptz
```

This is where body-like text and raw frontmatter can exist before canonical apply. Applying a staged claim currently requires a mapping decision: body/frontmatter must be converted into canonical claim text, tags, sources, evidence, strategy-node body/metadata, or a future schema extension.

## Decision Matrix Status

The database reference PDF describes a target governance design:

```text
kb_stage.matrix_voters
kb_stage.proposal_votes
kb_stage.proposal_decisions
```

The target design is:

- voters key on `public.agents.id`;
- each proposal has one row per voter;
- vote rows retain weight snapshots, vote, and rationale;
- a proposal decision row stores the weighted tally and drives the `reviewed_by` outcome record;
- Leo cannot approve its own proposal because the proposer is excluded from the tally.

Fresh live schema readback on the VPS does not show those tables. The only matrix/proposal/document-adjacent tables currently visible are:

```text
kb_stage.canonical_mappings
kb_stage.document_evaluations
kb_stage.kb_proposals
kb_stage.pending_kb_proposals
kb_stage.telegram_file_refs
```

Therefore:

- The decision matrix is a designed target, not a shipped live approval table set on the current VPS.
- Current approval evidence lives in `kb_stage.kb_proposals` fields: `status`, `reviewed_by_*`, `reviewed_at`, `review_note`, `applied_by_*`, `applied_at`.
- A future matrix should point back to proposal rows by proposal ID and to voter identities by `agents.id`.
- Today, Leo must not claim "the decision matrix approved this" unless it first finds the matrix tables and a concrete vote/decision row.

## Pending Proposals And Document Artifacts

Current live status counts:

```text
applied        add_edge         1
applied        attach_evidence  1
approved       attach_evidence  3
canceled       attach_evidence  7
pending_review add_edge         4
pending_review attach_evidence 10
```

Current document workflow counts:

```text
kb_stage.telegram_file_refs.status=downloaded   4
kb_stage.telegram_file_refs.status=referenced  19
kb_stage.document_evaluations.decision=rejected_as_out_of_scope  1
```

Live pending/approved proposal inspection showed:

- all `approved` and `pending_review` rows have a `source_ref`;
- many `source_ref` values are Telegram labels, URLs, or local document paths;
- none of the inspected `source_ref` values directly matched a `public.sources.id`, `public.sources.url`, or `public.sources.storage_path`;
- most payloads contain UUID-like references, but some pending document/evidence proposals do not.

So the current answer is nuanced:

```text
The pending queue is not because nothing persisted. The queue is real DB state in kb_stage.kb_proposals.
It is also not simply because documents are totally unpointed; the proposals have source_ref strings.
The gap is that many proposals are only artifact/proposal-pointed, not canonical-source-pointed.
They still need review plus a mapping/apply step that creates or links public.sources, public.claim_evidence, public.claim_edges, public.claims, or strategy rows as appropriate.
```

Benchmark implication:

Leo should distinguish:

- `kb_stage.telegram_file_refs`: uploaded Telegram file metadata and download status;
- raw files under the profile cache or `kb_stage/evaluations`: document bytes/extracted text/evaluation packets;
- `kb_stage.document_evaluations`: records of evaluated docs that should not become canonical;
- `kb_stage.kb_proposals.source_ref`: a proposal-level pointer to a source, thread, file, or artifact;
- `public.sources`: canonical evidence source rows after approval/apply;
- `public.claim_evidence`: canonical attachment between a claim and a source.

The product failure is not merely "missing files." It is missing or incomplete conversion from artifact/proposal pointers into canonical source/evidence/claim/edge rows.

## The `teleo-kb` Bridge

Repo-local bridge files:

```text
hermes-agent/leoclean-bin/teleo-kb
hermes-agent/leoclean-bin/kb_tool.py
hermes-agent/leoclean-bin/cloudsql_memory_tool.py
hermes-agent/leoclean-skills/vps/teleo-kb-bridge/SKILL.md
```

VPS active profile target:

```text
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb
```

Bridge behavior:

- `teleo-kb context/search/show/evidence/edges/list-proposals/show-proposal` are the normal KB answer surface.
- In auto mode, `teleo-kb` tries the Cloud SQL bridge only when local dependencies and status checks are available; otherwise it falls back to local Docker Postgres on the VPS.
- On the VPS, local mode reaches Docker with `teleo-pg` and database `teleo`.
- The bridge can stage reviewable proposals in `kb_stage.kb_proposals`.
- The bridge is not the normal canonical write path into `public.*`.

The source code states the key rule:

```text
Canonical knowledge writes remain locked. The only write surface here is a
proposal ledger under kb_stage: agents can propose a mutation for review, but
this tool does not apply it to public.claims, public.claim_edges, or evidence.
```

## How Leo Loads Context

The live Telegram path is:

```text
Telegram group
  -> leoclean-gateway.service
  -> /home/teleo/.hermes/hermes-agent/venv/bin/hermes -p leoclean gateway run
  -> profile config, SOUL.md, memories, sessions, skills
  -> teleo-kb bridge when KB grounding is needed
  -> Docker Postgres teleo.public + teleo.kb_stage
  -> Telegram answer
```

For KB-specific answers, the intended path is:

```bash
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb context "<question>"
```

Then narrow follow-ups:

```bash
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb show <claim_id>
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb evidence <claim_id>
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb edges <claim_id>
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb show-proposal <proposal_id>
```

Raw `docker exec ... psql` is a fallback for operator/debug proof, not the normal Telegram answer path.

## How Leo Updates Knowledge

There are three different update classes. They must not be conflated.

### 1. Runtime continuity updates

These happen inside `.hermes`:

- session files;
- `state.db`;
- local memory files;
- profile caches.

They help Leo remember conversations and operate as a bot. They are not canonical collective truth.

### 2. Proposal/staging updates

These happen in `kb_stage`:

- `kb_stage.kb_proposals`;
- `kb_stage.staged_claims`;
- local profile artifacts under `kb_stage/proposals` and `kb_stage/reports`.

This is where Leo can safely propose a core change for review.

Normal proposal meaning:

```text
pending_review: proposed, not approved, not canonical
approved: reviewer accepted the proposed change, but public.* may still be unchanged
applied: proposal ledger says applied; must still be checked against canonical rows
```

### 3. Canonical DB updates

These happen in `public.*`:

- `public.claims`;
- `public.sources`;
- `public.claim_evidence`;
- `public.claim_edges`;
- `public.strategy_nodes`;
- `public.strategy_node_anchors`;
- related canonical strategy/belief/shared-root tables.

This is what Cory means when he expects the KB to actually change. The proof is a before/after row readback, not just chat language and not just `kb_stage.status='approved'`.

Current guarded apply approach:

1. Identify the approved proposal and its exact intended delta.
2. Normalize it into supported canonical rows.
3. Generate preflight, authorized commit, postflight, and rollback SQL.
4. Rehearse in a disposable clone or rollback transaction.
5. Apply only when authorized for production.
6. Read back exact rows and update the proposal ledger.
7. Confirm the service is stable and no disposable DB/files remain.

## How Leo Updates Itself

Current safe understanding:

- Leo does not silently rewrite its own identity or canonical beliefs from chat.
- Leo can stage a proposal about its identity, strategy, beliefs, or KB graph.
- Human/peer review is required for self-model changes.
- If approved and applied, canonical Postgres rows change first.
- `SOUL.md`, reports, and profile artifacts may then be regenerated or synchronized from the DB so future runtime context reflects the canonical change.
- The current renderer/apply-worker automation is not proven active; direct `SOUL.md` edits can drift from DB truth.

Practical loop:

```text
chat/source signal
  -> Leo audits current DB state
  -> Leo stages proposal or produces apply packet
  -> reviewer approves/edits/rejects
  -> guarded apply mutates canonical Postgres rows
  -> row-level proof retained
  -> SOUL/report/profile sync if the changed rows affect runtime identity
  -> Leo re-queries and answers from updated DB state
```

## What Counts As Working For Cory's Complaint

The July 9 complaint was not merely "the bot is offline." The important complaint was that agents were not able to manipulate the knowledge base and the KB looked the same as last night.

Working behavior therefore means:

1. Leo remembers the Telegram conversation and can answer the current thread.
2. Leo can query canonical DB state and tell proposed vs approved vs applied apart.
3. Leo can stage reviewable proposals without mutating canonical truth prematurely.
4. For explicitly approved changes, the system can create/apply canonical rows with exact before/after proof.
5. Leo can explain which surface changed: runtime memory, local profile artifact, `kb_stage`, or `public.*`.

## Current Known Good Proofs

Retained July 9 evidence proves:

- live Telegram memory canary passed;
- open-ended Cory-style Telegram triage passed;
- live Telegram-to-`kb_stage` staged-write canary passed;
- strict canonical `add_edge` apply canary passed;
- rich proposal creation/apply packets are clone/rehearsal-proven for supported subsets;
- Helmer 7 Powers packet and ledger update are clone-proven;
- cross-surface strategy anchor packet is clone-proven;
- production application of broad rich proposal packets has not been run.

## Current Unknowns / Do Not Overclaim

- The exact historical seed path from repo/Forgejo-managed files into the current Postgres DB is not yet proven.
- The current SOUL renderer identity is visible in `SOUL.md` (`Renderer: 0013 Leo V2 Identity Graph`), but no active renderer script/timer/hook is proven deployed in this readback.
- The PDF says restart can re-render SOUL from DB, but the live system readback did not prove a 24-hour scheduled recomposition.
- The decision-matrix schema is described in the database reference PDF, but the current VPS schema does not contain `kb_stage.matrix_voters`, `kb_stage.proposal_votes`, or `kb_stage.proposal_decisions`.
- Forgejo is still present in the deploy/code topology, but it is not proven to be the live KB authority.
- GCP parity remains a separate surface; VPS truth should not be assumed to equal GCP truth until Cloud SQL readback/auth is fixed.
- Current broad production apply for old approved rich proposals remains intentionally not executed.

## Safe Operator Checks

Service liveness:

```bash
systemctl is-active leoclean-gateway.service
systemctl show leoclean-gateway.service -p MainPID -p ActiveState -p SubState -p NRestarts -p User -p WorkingDirectory -p FragmentPath --no-pager
ps -p "$(systemctl show leoclean-gateway.service -p MainPID --value)" -o pid,user,etime,cmd
```

DB liveness:

```bash
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' | grep -E 'teleo-pg|forgejo'
docker exec teleo-pg psql -U postgres -d teleo -c "select schemaname, count(*) from pg_tables where schemaname in ('public','kb_stage') group by schemaname order by schemaname;"
```

KB bridge:

```bash
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb status
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb context "what changed in the KB since last night?"
/home/teleo/.hermes/profiles/leoclean/bin/teleo-kb list-proposals
```

Profile identity:

```bash
sed -n '1,40p' /home/teleo/.hermes/profiles/leoclean/SOUL.md
sed -E 's/([A-Za-z0-9_ -]*(token|key|secret|password|credential)[A-Za-z0-9_ -]*:[[:space:]]*).*/\1<redacted>/Ig' /home/teleo/.hermes/profiles/leoclean/config.yaml | sed -n '1,120p'
```

Do not print `.env`, auth JSON contents, token files, credential files, or raw private keys.

## Mental Model For Future Agents

Use this hierarchy:

```text
1. public.* Postgres rows = canonical applied KB truth
2. kb_stage.* rows = proposed/reviewed/applied ledger and staged material
3. SOUL.md = rendered runtime identity context, not the source DB
4. .hermes state/memory/sessions = runtime continuity, not collective truth
5. teleo-infrastructure repo = code, scripts, skills, reports, apply packets
6. Forgejo = code/deploy provenance unless bootstrap evidence proves more
```

When answering "did Leo update the DB?", always name which level changed.

## Related Artifacts

- Current truth index: `docs/reports/leo-working-state-20260709/current-truth-index.md`
- DB/workspace diagram: `docs/reports/leo-working-state-20260709/leo-db-state-18-db-vs-workspace.svg`
- Claim/body/metadata diagram: `docs/reports/leo-working-state-20260709/leo-db-state-19-claims-body-metadata.svg`
- Forgejo/load/agent loop diagram: `docs/reports/leo-working-state-20260709/leo-db-state-21-forgejo-load-agent-loop.svg`
- Live Telegram proof: `docs/reports/leo-working-state-20260709/telegram-live-canary-current.md`
- Live staged-write proof: `docs/reports/leo-working-state-20260709/telegram-live-db-write-canary-20260709.md`
- Cross-surface anchor proof: `docs/reports/leo-working-state-20260709/cross-surface-resolution-current.md`
- Source PDF used for this update: `/Users/user/Downloads/Telegram Desktop/LivingIP-Master-Build-Guide.pdf`
- Source PDF used for this update: `/Users/user/Downloads/Telegram Desktop/LivingIP-KB-Database-Reference.pdf`
