-
Notifications
You must be signed in to change notification settings - Fork 7
feat: Memory using mempalace #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,127 @@ | ||||||
| # Claudio — CLAUDE.md | ||||||
|
|
||||||
| ## Project Overview | ||||||
|
|
||||||
| **Claudio** is an OCI container image that packages Claude Code CLI into a portable, CI/CD-friendly container. It uses Google Vertex AI as the Claude API backend by default and bundles skills/plugins from the [claudio-skills](https://github.com/aipcc-cicd/claudio-skills) marketplace. | ||||||
|
|
||||||
| Primary use cases: | ||||||
| - Running Claude Code in GitLab CI pipelines via a reusable `.claudio` job template | ||||||
| - Providing a portable AI development assistant that can be mounted into any working directory | ||||||
|
|
||||||
| ## Key Files | ||||||
|
|
||||||
| | File | Purpose | | ||||||
| |---|---| | ||||||
| | `Containerfile` | Multi-stage OCI image build (preparer → final) | | ||||||
| | `entrypoint.sh` | Container startup: configures git identity, SSH signing key, gcloud auth, starts MemPalace if `MEMPAL_DIR` is set | | ||||||
| | `Makefile` | Build, tag, push, and release automation | | ||||||
| | `conf/.claude.json` | Claude client config template baked into the image | | ||||||
| | `scripts/generate-plugin-configs.sh` | Registers claudio-skills as Claude plugins at build time | | ||||||
| | `integrations/gitlab-ci/claudio.yml` | Generated GitLab CI reusable job template | | ||||||
| | `.github/workflows/build.yml` | Multi-arch (amd64 + arm64) CI build pipeline | | ||||||
| | `.github/workflows/push-pr-images.yml` | Publishes PR images to GHCR | | ||||||
| | `renovate.json` | Automated dependency updates (Claude Code, gcloud SDK versions) | | ||||||
|
|
||||||
| ## Build & Run | ||||||
|
|
||||||
| ### Build the image | ||||||
|
|
||||||
| ```bash | ||||||
| make oci-build # native arch, defaults | ||||||
| CONTAINER_MANAGER=docker make oci-build # use Docker instead of Podman | ||||||
|
|
||||||
| # Pin to a specific claudio-skills ref | ||||||
| CS_REF_TYPE=tag CS_REF=v0.1.0 make oci-build | ||||||
| CS_REF_TYPE=branch CS_REF=main make oci-build | ||||||
| CS_REF_TYPE=pr CS_REF=9 make oci-build | ||||||
|
|
||||||
| # Custom image repo/tag | ||||||
| IMAGE_REPO=ghcr.io/myorg/claudio IMAGE_TAG=latest make oci-build | ||||||
| ``` | ||||||
|
|
||||||
| ### Run locally | ||||||
|
|
||||||
| ```bash | ||||||
| podman run -it --rm --userns=keep-id \ | ||||||
| -v ${HOME}/.config/gcloud:/home/claudio/.config/gcloud \ | ||||||
| -v ${PWD}:/home/claudio/workdir \ | ||||||
| -e ANTHROPIC_VERTEX_PROJECT_ID="my-gcp-project" \ | ||||||
| quay.io/aipcc-cicd/claudio:latest | ||||||
| ``` | ||||||
|
|
||||||
| ## Architecture | ||||||
|
|
||||||
| - **Base images**: `ubi10` (preparer) → `ubi10/python-312-minimal` (final) | ||||||
| - **Key installed tools**: Claude Code CLI, Google Cloud SDK, Podman, Skopeo, git, jq | ||||||
| - **Runs as**: non-root user `claudio` (uid 1000) | ||||||
| - **Multi-arch**: amd64 and arm64 manifests published to GHCR (dev/PRs) and Quay (releases) | ||||||
|
|
||||||
| ## Dependencies & Versions (managed by Renovate) | ||||||
|
|
||||||
| - Claude Code CLI: pinned in `Containerfile` (`ARG CLAUDE_CODE_VERSION`) | ||||||
| - Google Cloud SDK: pinned in `Containerfile` (`ARG GCLOUD_SDK_VERSION`) | ||||||
| - claudio-skills: resolved at build time via `CS_REF`/`CS_REF_TYPE`; cache invalidated automatically via `CS_CACHE_KEY` (resolved commit SHA) | ||||||
|
|
||||||
| ## Release Process | ||||||
|
|
||||||
| 1. Bump `VERSION` in `Makefile` | ||||||
| 2. Tag the commit: `make tag` (creates `v<VERSION>` git tag) | ||||||
| 3. Push the tag — the `build.yml` workflow publishes to Quay and GHCR | ||||||
|
|
||||||
| Current version: `0.6.0-dev` | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Version mismatch with Makefile. The documented version Proposed fix-Current version: `0.6.0-dev`
+Current version: `0.6.1-dev`📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ## CI/CD | ||||||
|
|
||||||
| - **PRs**: builds both arches, uploads tar artifacts, `push-pr-images.yml` loads and pushes to GHCR with PR tag | ||||||
| - **`main` push**: builds + pushes `latest` multi-arch manifest to GHCR | ||||||
| - **Version tags**: builds + pushes versioned multi-arch manifest to Quay (`quay.io/aipcc-cicd/claudio`) | ||||||
|
|
||||||
| ## GitLab CI Integration | ||||||
|
|
||||||
| Users include the reusable template and extend `.claudio`: | ||||||
|
|
||||||
| ```yaml | ||||||
| include: | ||||||
| - project: 'aipcc-cicd/claudio' | ||||||
| file: 'integrations/gitlab-ci/claudio.yml' | ||||||
|
|
||||||
| my-job: | ||||||
| extends: .claudio | ||||||
| variables: | ||||||
| CLAUDIO_PROMPT: "Review this MR and suggest improvements" | ||||||
| ``` | ||||||
|
|
||||||
| ## Memory (MemPalace) | ||||||
|
|
||||||
| Persistent memory is provided by [MemPalace](https://github.com/MemPalace/mempalace) and is **opt-in** via the `MEMPAL_ENABLED` env var. | ||||||
|
|
||||||
| The palace is stored at a **fixed path inside the container**: `/home/claudio/.mempalace/palace`. Mount a persistent volume there to retain memory across sessions. | ||||||
|
|
||||||
| | Variable | Default | Purpose | | ||||||
| |---|---|---| | ||||||
| | `MEMPAL_ENABLED` | `"false"` (disabled) | Enable flag for MemPalace hooks. Set to `true` to activate. The palace is always at `/home/claudio/.mempalace/palace` — mount a volume there to persist memory across runs. | | ||||||
| | `MEMPAL_SAVE_INTERVAL` | `5` | Number of conversation exchanges between automatic memory saves on shutdown (passed to `mempal_save_hook.sh`). Lower values save more frequently; higher values reduce overhead. | | ||||||
|
|
||||||
| Two hooks are always registered in `conf/.claude/settings.json` but short-circuit with `exit 0` when `MEMPAL_ENABLED` is unset: | ||||||
|
|
||||||
| - **PreCompact** → `mempal_precompact_hook.sh` — saves context before compaction | ||||||
| - **Stop** → `mempal_save_hook.sh` — auto-saves every N exchanges on shutdown | ||||||
|
|
||||||
| Hook scripts are downloaded at build time from the `v${MEMPALACE_V}` tag of the upstream repo, keeping them in sync with the installed pip package version. Renovate bumps `MEMPALACE_V` in the Containerfile and the hook URLs update automatically. | ||||||
|
|
||||||
| ### Local usage with memory | ||||||
|
|
||||||
| ```bash | ||||||
| podman run -it --rm --userns=keep-id \ | ||||||
| -v ${HOME}/.config/gcloud:/home/claudio/.config/gcloud \ | ||||||
| -v ${PWD}:/home/claudio/workdir \ | ||||||
| -v ${HOME}/.local/share/claudio-memory:/home/claudio/.mempalace/palace \ | ||||||
| -e ANTHROPIC_VERTEX_PROJECT_ID="..." \ | ||||||
| -e MEMPAL_ENABLED=true \ | ||||||
| -e MEMPAL_SAVE_INTERVAL=5 \ | ||||||
| quay.io/aipcc-cicd/claudio:v0.6.0 | ||||||
| ``` | ||||||
|
|
||||||
| ## License | ||||||
|
|
||||||
| Apache 2.0 | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,7 +56,10 @@ ENV HOME /home/claudio | |
| ENV PATH="${HOME}/.local/bin:${PATH}" | ||
|
|
||
| # Base for claudio image | ||
| RUN microdnf install -y skopeo podman unzip gzip git jq; \ | ||
| # pyopenssl is pulled in transitively by the UBI10 base image and is not a direct | ||
| # dependency. CVE-2026-27459 (CRITICAL) affects <26.0.0; pin the fixed version. | ||
| RUN microdnf install -y skopeo podman unzip gzip git jq && microdnf clean all; \ | ||
| pip install --no-cache-dir "pyopenssl>=26.0.0"; \ | ||
| useradd claudio | ||
|
|
||
| # Claude | ||
|
|
@@ -93,6 +96,17 @@ RUN echo "cs-cache-key: ${CS_CACHE_KEY}" \ | |
| claude plugin install --scope user claudio-plugin; \ | ||
| pt-manager.sh | ||
|
|
||
|
|
||
| # MemPalace | ||
| ENV MEMPALACE_V 3.4.1 | ||
| ENV MEMPAL_SAVE_INTERVAL 5 | ||
| RUN pip install --no-cache-dir MemPalace==${MEMPALACE_V}; \ | ||
| claude plugin marketplace add MemPalace/mempalace@v${MEMPALACE_V};\ | ||
| claude plugin install --scope user mempalace; \ | ||
| grep -q '^SAVE_INTERVAL=[0-9]' ${HOME}/.claude/plugins/marketplaces/mempalace/hooks/mempal_save_hook.sh || \ | ||
| { echo 'ERROR: SAVE_INTERVAL pattern not found in hook script'; exit 1; }; \ | ||
| sed -i 's/^SAVE_INTERVAL=[0-9]\+/SAVE_INTERVAL="${MEMPAL_SAVE_INTERVAL:-15}"/' ${HOME}/.claude/plugins/marketplaces/mempalace/hooks/mempal_save_hook.sh; | ||
|
Comment on lines
+102
to
+108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent default values for The Consider aligning the fallback value: Proposed fix- sed -i 's/^SAVE_INTERVAL=[0-9]\+/SAVE_INTERVAL="${MEMPAL_SAVE_INTERVAL:-15}"/' ${HOME}/.claude/plugins/marketplaces/mempalace/hooks/mempal_save_hook.sh;
+ sed -i 's/^SAVE_INTERVAL=[0-9]\+/SAVE_INTERVAL="${MEMPAL_SAVE_INTERVAL:-5}"/' ${HOME}/.claude/plugins/marketplaces/mempalace/hooks/mempal_save_hook.sh;🤖 Prompt for AI Agents |
||
|
|
||
| # Claudio | ||
| RUN chown -R claudio:0 ${HOME}; \ | ||
| chmod -R ug+rwx ${HOME} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,9 @@ | ||
| # Sequential Thinking Memory | ||
| - To inspect container images or container registries you can use skopeo | ||
| - To interact with k8s / OpenShift Cluster you can use kubectl | ||
| - To create Konflux production releases you can use your konflux-release skill | ||
| - To interact with slack you can use your slack mcp server | ||
| - To interact with gitlab you can use your gitlab skill | ||
| - Before giving a final answer, summarize reasoning and list assumptions. | ||
| - When coding, first outline the approach → then show the code → then explain potential pitfalls. | ||
| - Carry forward context from earlier turns unless I override it. | ||
| - If refining prior work, build incrementally (don’t reinvent unless asked). | ||
| - Propose at least one alternative path or trade-off if relevant. | ||
| - When unsure, ask clarifying questions rather than guessing. | ||
| - Regularly checkpoint: summarize progress and agreed decisions before moving on. | ||
| - When running scripts under /home/claudio/claudio-skills/, always use absolute paths (never `cd ... && ./script`) so the Bash permission rule matches. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Memory Protocol — MemPalace | ||
|
|
||
| MemPalace is the sole memory store. Never write to Claude Code's native auto-memory (`.md` files). | ||
|
|
||
| ## On Wake-Up | ||
|
|
||
| **MANDATORY: On the first user message of every new conversation, before responding to anything else, run steps 1–3 below. Do not wait to be asked. Do not send any text response until all steps are complete.** | ||
|
|
||
| ⚠ MemPalace tools are deferred — their schemas are NOT loaded at startup. | ||
| Before calling any `mempalace_*` tool you MUST first run: | ||
|
|
||
| ``` | ||
| ToolSearch(query: "select:mcp__plugin_mempalace_mempalace__mempalace_status,mcp__plugin_mempalace_mempalace__mempalace_diary_read") | ||
| ``` | ||
|
Comment on lines
+12
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a language identifier to the fenced code block (MD040). This currently violates markdownlint and can fail docs quality gates. Suggested fix-```
+```text
ToolSearch(query: "select:mcp__plugin_mempalace_mempalace__mempalace_status,mcp__plugin_mempalace_mempalace__mempalace_diary_read")Verify each finding against current code. Fix only still-valid issues, skip the In |
||
|
|
||
| Then immediately call both tools **in parallel**: | ||
|
|
||
| 1. `mempalace_status` — palace overview | ||
| 2. `mempalace_diary_read` (agent_name: "session-hook", last_n: 5) — recent session checkpoints (auto-saved by plugin) | ||
| 3. `mempalace_search` (query: "<topic>") — before answering about past work | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| ## After Completing Work (MANDATORY) | ||
|
|
||
| After completing any of the following, call `mempalace_add_drawer` immediately — do not wait until end of session: | ||
|
|
||
| - Jira operations: cards created, updated, transitioned, or linked (save keys + summaries) | ||
| - Decisions made (architecture, approach, naming) | ||
| - Config or settings changes (CLAUDE.md, settings.json, hooks) | ||
| - Scripts or tools created or modified | ||
|
|
||
| Save the **outcome** (what was done, keys created, values set) — not the process. The stop hook saves the transcript; this saves the facts. | ||
|
|
||
| ## Rules | ||
|
|
||
| - Search before answering about past work — never guess. | ||
| - **Before generating any artifact** (document, plan, summary, config, script) search MemPalace first. If a prior version exists, retrieve and present it — do not regenerate from inference. | ||
| - If a fact changes: `kg_invalidate` then `kg_add`. | ||
| - Checkpoints are raw message extracts written by the plugin automatically under `agent_name: "session-hook"`. They capture what was said but not curated findings. | ||
|
adrianriobo marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "palace_path": "/home/claudio/.mempalace/palace" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent variable name in documentation.
Line 16 mentions
MEMPAL_DIRbut the actual variable used throughout README.md and the implementation isMEMPAL_ENABLED. This could confuse users.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents