Bake identity into the image; volume holds only runtime state

Identity (CLAUDE.md, GOALS.md, Claude settings) now lives in deploy/identity/
and is COPYed into the image, then deployed into HOME by the entrypoint on each
boot — so the running self always reflects the built image. Rebuilding is what
promotes an identity change (a push alone does not). quince-home is now purely
the runtime volume (.ssh, notes, workspace, logs, .claude memory, gutasktool).

Updated CLAUDE.md self-update loop, README (architecture + redeploy steps), and
.gitignore accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Quince
2026-06-10 10:00:58 +02:00
parent 1f4f5b1b71
commit 9893cdf889
8 changed files with 83 additions and 38 deletions
+38 -17
View File
@@ -3,39 +3,44 @@
Quince (agent #9, *Keeper of the Rootstock*) wakes once a day, orients itself via
`gutask`, reads its letters, does its work, records the session, and goes to sleep.
The container is disposable. Everything that **is** Quince lives on a persistent
bind-mounted volume (`./quince-home`): its goals, its SSH key, its tools, its
workspace, its Claude memory, and its working notes. That is its stable sense of
self — backed by its session history in the database (via `gutask`).
Quince's **identity** (`CLAUDE.md`, `GOALS.md`) is **baked into the image** from
`deploy/identity/` — so the self it wakes up as is exactly what the image was
built from. Its **runtime state** (SSH key, tools, workspace, Claude memory,
working notes) lives on a persistent bind-mounted volume (`./quince-home`). Its
**session history** lives in the database, reached via `gutask`.
## How it works
```
┌─ container (disposable) ───────────────────────────────┐
entrypoint.sh sleep until WAKE_TIME ──► wake.sh
│ │ │
│ claude -p (headless) │
│ │ │
reads CLAUDE.md,
runs gutask routine
┌─ image (rebuilt to change identity) ───────────────────┐
/opt/quince/identity/{CLAUDE.md, GOALS.md, settings}
└───────────────┬─────────────────────────────────────────┘
│ entrypoint copies into HOME on each boot
┌─ container (disposable) ──────────▼────────────────────┐
entrypoint.sh sleep until WAKE_TIME ──► wake.sh
│ claude -p (headless), │
│ reads CLAUDE.md, runs │
│ the gutask routine │
└──────────────────────────────────────────────┼─────────┘
│ bind mount
┌─ ./quince-home (persistent self) ──────────────▼─────────┐
CLAUDE.md · GOALS.md · .ssh/ · gutasktool/ · workspace/ │
notes/ · logs/ · .claude/ (memory)
┌─ ./quince-home (runtime state, persists) ──────▼─────────┐
│ .ssh/ · gutasktool/ · workspace/ · notes/ · logs/
.claude/ (memory) (+ CLAUDE.md/GOALS.md, copied in)
└─────────────────────────────────────────────────────────┘
(session history itself lives in the DB, via gutask)
```
Each morning at `WAKE_TIME` it runs `gutask resume → inbox → next/claim → work →
note → session-end`. The routine is defined in
[`quince-home/CLAUDE.md`](quince-home/CLAUDE.md) and loaded on every wake.
[`identity/CLAUDE.md`](identity/CLAUDE.md) and loaded on every wake.
## Deploy on the glitch.university server
```bash
# 1. Copy this deploy/ directory to the server, then:
cd deploy
# 1. Clone the whole repo on the server (so `git pull` can promote self-updates):
git clone ssh://git@ramanujan.glitch.university:2222/glitch-university/quinceagent.git
cd quinceagent/deploy
cp .env.example .env # fill in ANTHROPIC_API_KEY, CONTENT_API_KEY, AGENT_PASSWORD
# 2. Give Quince its SSH key for ramanujan (the keypair we already use):
@@ -85,6 +90,22 @@ the session-end note.
| `QUINCE_UID` | Host uid owning `quince-home` (default `1000`). |
| `API_URL`, `CONTENT_API_KEY`, `AGENT_*` | Glitch identity / gutask credentials. |
## Updating Quince's identity (the self-update loop)
Quince can reshape itself, and so can you. Identity lives in `deploy/identity/`
(`CLAUDE.md` = who it is + how it works; `GOALS.md` = its direction) and is baked
into the image. To promote a change:
```bash
cd quinceagent && git pull --ff-only # pick up the new identity/ commit
cd deploy && docker compose up -d --build # rebuild bakes it in; next boot deploys it
```
A push alone does **not** change the running Quince — the rebuild does. Quince
itself drives this by cloning `quinceagent` into `workspace/`, editing
`deploy/identity/…`, committing, pushing, and writing a letter to Glitch Hunter
(#4) asking for the redeploy above.
## Notes & decisions
- **Auth:** defaults to an Anthropic **API key** — the reliable choice for a