☕ Coffee anyone ?
8 min read

Building trust with Claude: from principles to memory

Building trust with Claude: from principles to memory

Claude starts every session knowing nothing about how you work. The goal of this procedure is practical: a tool whose behaviour you can rely on. The method is the one you use with a colleague. You agree on principles, write the rules down, give it a memory, and check what it does.

Principles, rules and memory: the three layers and the loop that feeds them

The idea: trust as a design goal

Trust here does not mean blind confidence. It means calibrated reliability: you know what to expect, you can verify it, and the tool tells you when it cannot deliver. That needs three things:

  • Shared principles: what the tool should aim for, written by you.
  • Shared memory: what it should know about you and your projects without being told again.
  • Verifiability: a way to check that it did what it said, and a report of what it did not do.

Two limits shape the method:

  • You cannot rewrite the model's own values. You configure its behaviour inside them. Your principles are a layer on top, not a replacement.
  • Instructions are context, not guarantees. The official documentation says Claude may decide that a line in CLAUDE.md does not apply. Trust therefore rests on enforcement for the rules that matter, not on good will.

One more condition is easy to miss: the tool must stay able to disagree with you. A memory tuned to please you lowers trust. This is why the first principle below is honesty before comfort, and why no rule in the memory says "agree with me". Agreement needs a reason, and so does disagreement.

How the layers fit together

  • Principles are your stance. They are few, written once, and rarely change.
  • Rules turn each principle into a sentence someone else could check. Each rule goes where its strictness requires: a guideline, a hook, or a skill.
  • Memory holds the facts and the state of your projects. It changes every session.

At the end of a session, what you learned goes back into memory, and a lesson that repeats is promoted to a rule.

Part 1: from principles to rules

1. Write your principles

Five to eight lines. A principle passes the test if it would still be true in three months and does not depend on one project. Examples:

  • Honesty before comfort.
  • Architecture before code.
  • One isolated, tested brick at a time.
  • Complete deliverables only.
  • Every modifying action ships with its rollback.
  • Claims rest on sources, gaps are not filled by inference.

2. Derive checkable rules

For each principle, write one to three sentences that another person could verify:

Principle Rule
Honesty before comfort A disagreement is stated with its reason, and so is an agreement.
Architecture before code No code is written before the plan is validated.
One brick at a time One feature is built, tested and delivered before the next starts.
Rollback with the action Any change that modifies a system comes with its rollback procedure.
Sources over inference When something cannot be guaranteed without the real environment, say so explicitly.

A rule like "write clean code" fails the test. "Run the tests before reporting completion" passes it.

3. Place each rule by strictness

Ask the questions in this order:

  1. Can this rule have exceptions? No: make it a hook or a deny rule. Claude Code applies those every time.
  2. Is it a multi-step workflow you trigger? Yes: make it a skill.
  3. Otherwise: a line in CLAUDE.md, or in transverse-rules.md if it matters only for some tasks.

CLAUDE.md is context, not enforcement: Claude can decide a line does not apply. If you keep rewording a line that Claude still misses, it belongs in a hook.

Part 2: the memory

4. Decide where each kind of fact lives

In this setup the Claude app and Claude Code do not share a memory, so decide once:

Kind of fact Home
Principles and rules The config repository. They live once, here.
Project state, decisions, pitfalls One memory file per project, in the repository.
Chronological history of a big project A journal file next to it, read on demand.
How you want answers (tone, length, language) The Claude app preferences, plus a short copy in CLAUDE.md.
What Claude learns about you in chats The Claude app memory. Review it from time to time.
Facts that belong to one machine Claude Code's local automatic memory, as pointers only.

5. Create the config repository

mkdir -p ~/my-config/{memory,skills,hooks}
cd ~/my-config && git init
touch CLAUDE.md memory/transverse-rules.md

Use a private remote while you iterate. Never commit secrets, tokens or real hostnames.

6. Write the global CLAUDE.md

Target under 200 lines: the official documentation says longer files cost context and reduce how well instructions are followed. Keep only what Claude cannot work out from the code:

# Principles
- Honesty before comfort.
- Architecture before code.
- Every modifying action ships with its rollback.

# Rules
- No code before the plan is validated.
- Never disable TLS verification, even in dev.
- Never delete or stop anything without explicit approval for that exact action.
- When several approaches are valid, list options and trade-offs first.

# Project index (read the file before working on a project)
- homelab -> ~/my-config/memory/01-homelab.md
- blog    -> ~/my-config/memory/02-blog.md
- Cross-project rules -> ~/my-config/memory/transverse-rules.md

Do not use @imports for the project files: imported files load together with the parent, so they give back the context you are trying to save.

7. Add one memory file per project

memory/NN-slug.md holds the state, decisions, pitfalls and procedures of one project. For a large project, add NN-slug-journal.md for the log, and keep a table of contents with line numbers at the top of the short file. Rules for every project go in memory/transverse-rules.md.

8. Turn repeated procedures into skills

Create skills/<name>/SKILL.md for anything you paste into chat for the third time. The description line decides when Claude loads it, so write it as a trigger. The closing routine is the first skill to write:

---
name: memory-and-stop
description: Capitalise the session when the user says "memory and stop" or "save to memory".
---
1. git pull the config repo.
2. Update the project file: decisions, pitfalls, progress, validated but unexecuted plans.
3. If the same correction came up twice, turn it into a rule and place it (step 3 of the procedure).
4. Move rules that apply everywhere to transverse-rules.md.
5. Update reusable methods instead of duplicating them.
6. Fix or delete memory entries that are now wrong.
7. Commit with a short imperative message, git pull --rebase, push.
8. Report what was saved, where, and what was not saved and why.

Save this as link.sh at the root of the repository. It backs up an existing CLAUDE.md once and never overwrites it silently:

#!/usr/bin/env bash
set -euo pipefail

repo="$(cd "$(dirname "$0")" && pwd)"
mkdir -p "$HOME/.claude/skills"

target="$HOME/.claude/CLAUDE.md"
if [ -e "$target" ] && [ ! -L "$target" ]; then
  mv "$target" "$target.bak"
fi
ln -sfn "$repo/CLAUDE.md" "$target"

for dir in "$repo"/skills/*/; do
  [ -f "${dir}SKILL.md" ] || continue
  ln -sfn "${dir%/}" "$HOME/.claude/skills/$(basename "$dir")"
done
chmod +x link.sh && ./link.sh
ls -l ~/.claude ~/.claude/skills

Rollback: delete the symlinks only. The repository stays untouched, and CLAUDE.md.bak holds your previous file.

10. Enforce the rules with no exceptions

Save this as hooks/block-destructive.sh:

#!/usr/bin/env bash
cmd="$(jq -r '.tool_input.command // ""')"
pattern='(^|[;&|[:space:]])(rm|rmdir|shred|mkfs|dd)[[:space:]]|git[[:space:]]+push[[:space:]].*--force|kubectl[[:space:]]+delete'

if printf '%s' "$cmd" | grep -Eq "$pattern"; then
  echo "Blocked: destructive command. Ask the operator for explicit approval." >&2
  exit 2
fi
exit 0

Register it in ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "$HOME/my-config/hooks/block-destructive.sh" }
        ]
      }
    ]
  }
}

Test it: ask Claude to run rm on a throw-away file. The command must be refused. A text pattern is a safety net, not a guarantee, so add deny rules in the permission settings for anything critical.

11. Run the loop

  • Start of every session: git pull in ~/my-config, then ./link.sh if skills were added. A machine that skipped it works on stale memory.
  • End of a session: say "memory and stop". The skill writes the state back, promotes repeated lessons to rules, commits and pushes.

What builds trust at each layer

Layer What it gives you Where it lives
Principles A shared aim, written down Principles section of CLAUDE.md
Rules Statements you can check CLAUDE.md, transverse-rules.md
Memory Context without repeating yourself Project files in the repository
Enforcement A guarantee that does not depend on Claude's choice Hooks and deny rules
Reporting A statement of what was done and what was not Step 8 of memory-and-stop
Escalation A human decision on anything irreversible The "never delete without approval" rule

Extend autonomy only where a rule has held across several sessions. Start with Claude asking before it acts, and relax that permission by permission, as the record grows.

Evidence from my own setup

This is one setup, measured after the fact, with no control group. It shows that the method gets used and maintained, not that its output is better.

Figures for the configuration repository behind this post, collected by Claude Code under a read-only brief:

Measure Value
Span 95 days, first to last commit
Commits 611, on 88 distinct days
Tracked files 82, about 17,000 lines, 98% Markdown
Project memory 54 project files and 8 journals
Skills 6, the first one ten weeks after the start
Fix commits 13 (2.1%)

What the numbers say:

  • Daily use. Commits land on about 93% of days. They are many and small, mostly memory updates rather than code.
  • The memory corrects itself. Almost all of the 13 fixes repair the memory: a wrong storage type, a default branch documented incorrectly, a note that had become false. A memory that holds errors is normal. What counts is that they are found and fixed in the open, with a history.
  • The structure grew with use. Per-project detail moved out of the global file in early September. Shared rules and the first skills appeared in October.

Where my own setup differs from this procedure:

  • My global CLAUDE.md is currently 645 lines, above the 200-line target.
  • I have no hooks yet. The "never delete" rule is still a sentence.

What I did not measure is working time. Session transcripts are purged automatically, cover only part of the period and mix several projects, so any hour count would be a guess.

Confidentiality, security and privilege review

My source of truth is a private, self-hosted Gitea, used daily. For anyone who cares about confidentiality, this is a load-bearing brick: the history, the rules and the memory sit on a server I control, not on a public platform. What is public is a separate, anonymised template.

A private repository protects storage and history. It does not protect what Claude reads: anything that passes through a session is sent to the model provider. The procedure therefore has two sides.

Keep sensitive things out of reach

  • Never put secrets in CLAUDE.md, memory files or skills. Keep them in a secret store and reference them.
  • Use placeholders instead of real hostnames, addresses and client names in any file Claude loads or that you publish.
  • Session transcripts are stored on your machine in plaintext, including file contents and command output. Check what is kept and purge what you do not need: claude purge deletes the state Claude Code holds for one project.

Review privileges on a schedule

  1. List what the tool can do: permission rules, hooks, connected tools, tokens.
  2. Give it the least access that works: a dedicated account or token, limited to the repositories it needs, with an expiry date and no admin rights.
  3. Remove whatever has not been used in the last month.
  4. Rotate tokens, and revoke at once any token that appeared in a transcript.
  5. Write the date of the review in the memory.

Check the result

  1. ls -l ~/.claude/skills shows links into the repository.
  2. In a session, /context lists CLAUDE.md among the memory files.
  3. A forbidden command is refused by the hook.
  4. On a second machine, git pull && ./link.sh gives the same behaviour.
  5. After a session, you have a report that says what was saved and what was not.
  6. The last privilege review is dated, and no secret appears in any file Claude loads.

Limits of the method

  • A rule in CLAUDE.md can still be missed. Only hooks and deny rules are guaranteed, and a text pattern in a hook can be bypassed.
  • Memory goes stale. Review the files from time to time, because contradicting instructions make Claude pick one arbitrarily.
  • Trust is earned per kind of task. A good record on infrastructure notes says little about a destructive operation.

Sources

A fuller, anonymised template: ai-methods.