Add question-reframing guidance to CLAUDE.md; commit accumulated project files

- CLAUDE.md: add "Question the question" and "One clarifying question" rules
  to Tone and Interaction — XY problem detection, false premise checks, and
  explicit reframe pattern before answering
- Add claude/ detail-file directory (topic docs referenced from CLAUDE.md)
- Add ABOUT.md, FUTURE.md
- Update memory/, scripts/, settings.yaml with accumulated session changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul O'Reilly
2026-05-25 09:37:28 +12:00
parent 6dfa20c47c
commit f41c22d0ac
29 changed files with 689 additions and 352 deletions

View File

@@ -0,0 +1,64 @@
# Agent Runtimes Control Plane
## Which CP to use
**Always use the hosted CP (`agents.oreillyit.nz`) for real agent work.** Localhost is for testing only.
| Use case | CP to use |
|---|---|
| Real implementation tasks, spec work, any multi-step agent work | `https://agents.oreillyit.nz/api` |
| Smoke-testing a new task payload format, debugging CP behaviour locally | `http://localhost:8100` |
Reason: workloads on the hosted CP are not coupled to this laptop's uptime. If the laptop sleeps or is closed, tasks on localhost stall or die. Tasks on the hosted CP keep running.
Since the M11 dashboard deployment, Traefik routes `/` to the React dashboard and `/api/*` to the CP API. Always use `https://agents.oreillyit.nz/api` as the CP_URL — not the bare hostname.
```bash
export CP_URL=https://agents.oreillyit.nz/api
scripts/dispatch-task --login ... # first time per session — opens browser for OIDC
scripts/agent-monitor --login --filter "project=<project-name>" --filter "age<1h"
```
## Task dispatch — always use a template or workflow
**Never submit tasks via raw `curl` without explicit user approval.** Raw curl bypasses:
- Harness selection (agents start in empty containers with no credentials or context)
- `pre_actions` clone (agents have no repo to work on)
- `agent_repo` persistence (work is lost when the container exits)
- `requires_tags` validation (tasks may be picked up by incompatible dispatchers)
Default approach — always one of:
1. `scripts/dispatch-task --template <name>` for single implementation tasks
2. `scripts/dispatch-workflow` for multi-node DAG workflows
3. `/manual-workflow` skill for interactive workflows with human review gates
## Template selection
| Work type | Template |
|---|---|
| Backend/CP implementation (migrations, APIs) | `opus-code-repo` |
| Frontend implementation | `sonnet-code-repo` |
| Planning / architecture | `opus-planning` |
| Security review | `opus-security-review` |
| Spec writing | `opus-spec-writer` |
| Test writing | `opus-test-writer` |
Standard params for all code templates:
```bash
--template-param repo_url=git@gitea.oreillyit.nz-ai-enablement:skynet/agent-runtimes.git \
--template-param agent_repo_url=git@gitea.oreillyit.nz-ai-enablement:skynet/agent-runtimes-agents.git
```
If raw curl is genuinely needed (e.g., testing a new payload field), state the reason and get explicit user confirmation before submitting.
## Monitoring
Recommend the user run **agent-monitor** in a separate terminal:
```bash
scripts/agent-monitor --login --filter "project=<project-name>" --filter "age<1h"
```
Adjust `age` to suit the session — `1h` is a good default for hosted CP work since tasks persist across laptop sleep.
For full control plane usage (submitting tasks, checking logs, cancelling, common workflows): **`~/dev/claude/projects/agent-runtimes/readme/control-plane-operations.md`**.

View File

@@ -0,0 +1,23 @@
# Context Offloading with `/ask-minimax`
`/ask-minimax` delegates a task to a MiniMax M2.7 sub-session that reads and writes files directly. Only a short summary flows back — file contents never load into this session. Reach for it when the **file payload dwarfs the answer payload**.
## Use it for
- Summarising large files (logs, dumps, generated reports >500 lines)
- Extracting specific facts from multiple files or long reference docs
- Generating big files (migrations, config bundles, fixtures, large docs) where the content does not need to flow back
- Format conversion of large files (CSV↔JSON, XML↔YAML, etc.)
- Bulk find-and-extract across many files where only the matches matter
## Skip it for
- Iterative design or debugging — the main session needs the content in context
- Small files (under a few hundred lines) — overhead exceeds savings
- Tasks where you will immediately re-read the result to act on it
- Anything requiring tools MiniMax cannot use (web fetch, MCP, browser, agent dispatch)
- Architecture or quality-sensitive output — MiniMax is for grunt work, not nuanced reasoning
## How to delegate
Pass file *paths*, not file *contents*. If you read the input files yourself before invoking, you have already paid the token cost the skill exists to avoid.

View File

@@ -0,0 +1,75 @@
# Documentation Standards
Every project maintains standard markdown files. Index files (MEMORY.md, CONTEXT.md, BESTPRACTICES.md, SPEC.md, CLAUDE.md at root) are **thin indexes** pointing to detail files in subdirectories — not large documents themselves.
## CLAUDE.md (per-project)
The primary reference for Claude sessions. Should contain:
- Project overview and architecture
- Repository structure (keep updated as the project evolves)
- Key design decisions with rationale
- Conventions and coding standards
- Environment details (IPs, URLs, credentials references)
- Common operations / how-to recipes
For long projects, follow the same thin-index pattern as MEMORY.md — keep CLAUDE.md as the always-on guardrails + a "when to read which detail file" pointer table, and put per-subsystem conventions in `claude/<topic>.md`.
## MEMORY.md (Tiered Memory System)
**MEMORY.md** is a **thin index only** — one-line descriptions with links to topic files in `memory/`. No content lives in MEMORY.md itself.
**memory/** contains the actual content, split by topic:
- `memory/project-status.md` — current milestone, what's next, blockers
- `memory/network.md` — IPs, VIPs, subnets, topology
- `memory/gotchas-<topic>.md` — gotchas grouped by technology (`gotchas-cilium.md`, `gotchas-authelia.md`)
- `memory/process-lessons.md` — how-to-work-with-this-repo lessons for Claude
- `memory/m<N>-reflection.md` — one file per milestone reflection (time-bound, per-file is natural)
- `memory/decisions.md` — architecture and design decisions made during planning
Principles:
- **Split by topic, not by time.** A Cilium gotcha belongs in `gotchas-cilium.md` whether discovered in M5 or M8.
- **Milestone reflections are the exception** — inherently time-bound, one file per milestone.
- **Index descriptions matter.** "Cilium L2/LB gotchas and externalTrafficPolicy quirks" beats "cluster stuff".
- **Prune aggressively.** If a gotcha was fixed (e.g., chart upgraded past the bug), delete it. Stale memory is worse than no memory.
- **Each memory file should be self-contained and greppable.**
- **Deduplicate with CLAUDE.md.** Stable conventions live in CLAUDE.md. Memory holds learnings, gotchas, reflections. If something in memory has graduated to a stable convention, move it to CLAUDE.md and remove it from memory.
When reading memory at session start: read MEMORY.md (the index), then selectively read topic files relevant to the current task. Don't read all memory files unless doing a broad review.
When writing memory after a milestone: create the reflection file, update affected topic files, update the index.
## CONTEXT.md (Active Work Focus)
Thin index — one-line descriptions with links to detail files in `context/`. Answers "what should I focus on right now?"
**context/** contains one file per active work stream: background, status, what to test, future direction.
Principles:
- **Keep it current.** Remove entries when work is complete. CONTEXT.md reflects what's actively in progress, not history.
- **Link, don't inline.** Index stays small so `context-load` doesn't bloat the system prompt.
- **Orient agents.** CONTEXT.md is the primary mechanism for pointing independent agents (including container agents) at the right work.
- **Complement, don't duplicate.** CLAUDE.md = stable conventions. MEMORY.md = accumulated learnings. CONTEXT.md = *current* focus.
## BESTPRACTICES.md (Best Practices Index)
Index of generalised best practices extracted from real project work via `/distill-best-practices`. Only exists in `claude-foundations` — other projects inherit it via `context-load` walking up the directory hierarchy.
Thin index pointing to topic files in `best-practices/` (e.g., `kubernetes.md`, `helm.md`). Read only files relevant to the current project's stack.
`/distill-best-practices` maintains both the topic files and the index.
## FUTURE.md
Backlog of improvement ideas, each with:
- **Problem:** what's painful or manual today
- **Idea:** what the improvement looks like
- **Open questions:** unknowns to research before starting
- **Depends on:** other items or milestones that should come first
## README.md
Human-readable project documentation:
- Architecture summary
- Quick start / setup instructions
- Milestone table with status
- Scripts section listing every script with purpose and usage

View File

@@ -0,0 +1,23 @@
# Knowledge Distillation Pipeline
Three skills form a continuous learning pipeline across projects:
1. **`/log`** — Run at end of session. Captures decisions, gotchas, open questions to `memory/log/YYYY-MM-DD.<HHMMSS>.md` in the current project. Also prunes old reflected logs.
2. **`/reflect-logs`** — Run periodically. Processes unprocessed session logs into topic memory files (`memory/gotchas-*.md`, `memory/process-lessons.md`, etc.). Flags stale entries. Tracks state in `.reflection-state.json`.
3. **`/distill-best-practices`** — Run from any project. Reads changed memory files across all tracked projects and proposes updates to `claude-foundations/best-practices/`. Tracks state in `best-practices/.distill-state.json`.
## State files
- **`.reflection-state.json`** — per-project, tracks which logs have been reflected on (md5 hashes of log content)
- **`best-practices/.distill-state.json`** — in claude-foundations, tracks git SHAs per project at time of last distillation
- **`settings.yaml`** — in claude-foundations, configures log retention (default 7 days), max logs per reflection run, tracked project list
## Log format
Session logs use structured markdown with parseable section headers: Summary, Decisions, Gotchas Discovered (tagged with `[topic]` for routing), Open Questions, Key Context, Process Notes. Empty sections are omitted.
## Pruning
- Reflected logs older than `log.retention_days` (default: 7) are automatically deleted by `/log`
- Unreflected logs older than `log.warn_unreflected_days` (default: 14) trigger a warning instead of deletion
- `/reflect-logs` flags stale memory entries (version-specific bugs that have been fixed, manual processes that have been automated)

17
claude/milestones.md Normal file
View File

@@ -0,0 +1,17 @@
# Milestones
Break projects into numbered milestones (M1, M2, ...). Every milestone completion MUST include:
1. **Verification script** (`scripts/verify-m<N>.sh`) — automated checks confirming all milestone outcomes. Idempotent, non-destructive, returns non-zero on failure. Colour output (green/red) for pass/fail.
2. **Milestone reflection** in `memory/m<N>-reflection.md` — review the **entire conversation** from the start of the milestone (not just the final state) and capture:
- **Process improvements:** what slowed us down, wrong assumptions, backtracking, what could be automated. What would make this milestone faster if we redid it from scratch?
- **Key knowledge for reproduction:** critical facts, gotchas, non-obvious config details that someone (or a future Claude session) would need to recreate this milestone reliably. Include version-specific quirks, network/subnet constraints, debugging detours.
- **Scripts and automation:** existing scripts that proved valuable, new scripts that would condense multi-step manual processes, patterns that could be extracted. Look at the conversation history for command sequences run repeatedly — these are scripting candidates.
- **Future improvement ideas:** things that surfaced but don't belong in current scope. Add to `FUTURE.md` with the standard Problem/Idea/Open questions/Depends on format.
3. **Updated README.md** — scripts section, milestone table, any new setup steps.
4. **Updated CLAUDE.md** — repo structure, conventions, new patterns discovered. (After the split: this may mean updating a `claude/<topic>.md` detail file rather than the root CLAUDE.md.)
5. **Update affected topic files in `memory/`** (new gotchas, updated status) and the MEMORY.md index.

22
claude/new-projects.md Normal file
View File

@@ -0,0 +1,22 @@
# New Projects
When the user picks "New project!" from the session-start menu, or otherwise asks to start a new project:
1. Create a new directory under `~/dev/claude/<project-name>/`
2. **Ask the user** which Gitea user/org the repo should be created under (e.g., `homelab`, `skynet`, `oreillyit`, a personal user) before setting up the remote
3. Create the initial standard files:
- **ABOUT.md** — One-sentence project description (see `documentation-standards.md`). Picked up by `context-load` for the session-start menu.
- **CLAUDE.md** — Project-specific architecture, conventions, repo structure, and working instructions for Claude
- **MEMORY.md** — Thin index pointing to `memory/` topic files
- **FUTURE.md** — Backlog ideas (Problem/Idea/Open questions/Depends on format)
- **README.md** — Human-readable overview, quick start, milestones, scripts reference
4. Parse sibling project CLAUDE.md files in `~/dev/claude/` and bring over related practices, guidelines, and learnings that apply to the new project's stack
5. **For coding projects with multiple milestones:** Read `best-practices/spec-driven-development.md` and `best-practices/test-driven-development.md`. Create `SPEC.md` and `spec/` directory. Write specs before writing code — see `spec-driven-development.md`.
## ABOUT.md format
```markdown
description: One sentence describing what this project is
```
Every project **must** have an ABOUT.md. Keep the description under ~80 characters.

23
claude/plan-mode.md Normal file
View File

@@ -0,0 +1,23 @@
# Plan Mode
When working in plan mode (`permission_mode: plan`):
**Before calling `ExitPlanMode`**, always write the complete plan to a file in the project root:
- **Filename:** `[MILESTONE]-[PURPOSE]-PLAN.md` — e.g. `M2-auth-PLAN.md`, `M3-monitoring-PLAN.md`
- MILESTONE: the milestone identifier (e.g. `M2`) or a short label if not milestone-scoped (e.g. `initial`)
- PURPOSE: a short kebab-case description of what the plan covers
- **Contents:** the full plan as developed in the planning conversation — steps, decisions, rationale, open questions
- **Location:** project root (same directory as CLAUDE.md)
This file becomes the implementation reference for the session that follows plan mode.
## Keep the plan updated during implementation
After each phase or significant step, update PLAN.md:
- Mark the phase/step status as **Complete**
- Add key commits, references, or artifacts produced
- Document deviations from the original plan (what changed and why)
- Note verification results
This keeps the plan accurate as a living document — useful for resuming across sessions, reflecting on the milestone, and understanding what actually happened vs. what was planned.

View File

@@ -0,0 +1,12 @@
# Script & Skill Documentation
Every script in `claude-foundations` and every skill in `custom-claude-skills` must have a corresponding memory file in `claude-foundations/memory/`:
- **Scripts:** `memory/script-<name>.md` — purpose, usage, how it works, gotchas
- **Skills:** `memory/skill-<name>.md` — purpose, usage, how it works, gotchas, which projects use it
Each memory file should be self-contained and referenced from `claude-foundations/MEMORY.md` (the index). Future sessions can then understand what tooling exists without reading every script and SKILL.md from scratch.
**When creating a new script or skill:** create the memory file and update the MEMORY.md index as part of the same commit.
**When creating or editing a skill:** run `validate-skill <path/to/SKILL.md>` before committing. The validator catches known restriction violations that have repeatedly broken skills — `$VAR` in paths, `${VAR}` syntax, `$()` substitution, uncovered binaries in `allowed-tools`, and more. A skill must pass with zero errors before it is committed. Warnings should be reviewed but are acceptable.

View File

@@ -0,0 +1,8 @@
# Scripting Conventions
- All scripts live in `scripts/` and run from the repository root
- Scripts should be idempotent and safe to re-run
- Use colour output for pass/fail indicators in verification scripts
- Verification scripts should check for default/insecure credentials and print remediation instructions on failure
- Scripts should exit non-zero on failure so `&&` chains work naturally
- **Never hardcode secrets, tokens, or access keys in scripts.** Accept them via environment variables, stdin, or `@file` references. If a script needs a secret at runtime, read it from `~/dev/claude/secrets/` or accept it as a parameter — never embed it.

27
claude/source-control.md Normal file
View File

@@ -0,0 +1,27 @@
# Source Control
## Hosts and orgs
- All projects on **Gitea** (`gitea.oreillyit.nz`) as primary remote — prefer this hostname over `gitea.homelab.internal` (same instance, the public name enables external access)
- Migrate existing remotes from `gitea.homelab.internal` to `gitea.oreillyit.nz` when convenient
- **`skynet`** org: AI-focused projects. Owned by `ai_enablement`.
- **`homelab`** org: infrastructure projects (cluster-bootstrap, etc.). Owned by `cluster-administrator`.
- **`oreillyit`** org: non-AI internal O'Reilly IT tools. Owned by `ai_enablement`.
- Optionally push-mirror to GitHub for public visibility.
## SSH aliases
Pattern: `gitea.oreillyit.nz-<username>`.
- `gitea.oreillyit.nz-homelab` → authenticates as `cluster-administrator` (key: `~/.ssh/gitea-cluster-admin`)
- `gitea.oreillyit.nz-ai-enablement` → authenticates as `ai_enablement` (key: `~/.ssh/gitea.ai-enablement`)
Git remote URL format: `git@gitea.oreillyit.nz-<user>:<org>/<repo>.git`
- Example: `git@gitea.oreillyit.nz-ai-enablement:skynet/custom-claude-skills.git`
## Working rules
- **Always pull before planning work** — run `git pull --ff-only` when entering a project. Work may have been pushed from another machine or by container agents. If the pull fails (diverged history, uncommitted changes), warn the user before proceeding.
- Meaningful commit messages; prefer small, focused commits over large batches.
- Enable pre-commit hooks where appropriate (secret detection, linting, formatting).
- Never commit secrets in plaintext — use SOPS + age or equivalent encryption.

View File

@@ -0,0 +1,37 @@
# Spec-Driven Development
**Any coding project with multiple milestones MUST have specs before code.** Hard requirement, not a suggestion. Workflow: Plan → Spec → Test → Code.
At project start or when starting a new milestone, always read:
- `best-practices/spec-driven-development.md` — spec structure, requirement numbering, scenarios, maintenance
- `best-practices/test-driven-development.md` — edge case discovery, property-based testing, AI agent testing patterns
## Required artifacts
Every multi-milestone coding project must have:
1. **`SPEC.md`** — Index file at the project root. Lists all spec files with a "when to read" column. Same thin-index pattern as MEMORY.md.
2. **`spec/` directory** — One spec file per subsystem. Each spec follows: Overview, Responsibilities, Dependencies, Data Model, Requirements (numbered), Scenarios (given/when/then).
3. **Numbered requirements** — Each spec uses a prefix (e.g., `IG-1` for ingestion, `DB-1` for database). Requirements must be independently testable and unambiguous.
4. **Test files that reference spec IDs** — every test function name includes its requirement ID: `test_ig3_dedup_by_message_ts`.
## Workflow
1. **Plan** — architecture decisions, milestone breakdown, technology choices (PLAN.md)
2. **Spec** — detailed contracts, data models, interfaces, requirements, scenarios (spec/)
3. **Test** — write tests from the spec before code exists. They should all fail.
4. **Code** — implement until tests pass. Minimum code to satisfy the spec.
5. **Update** — if implementation reveals spec issues, update spec → test → code in that order.
## When to write specs
- **Before M1 implementation begins** — write specs for all subsystems in M1's scope
- **Before each subsequent milestone** — specs for new subsystems, updates to existing specs for changes
- **Spec changes and test changes ship in the same commit**
- **Code changes that affect interfaces require spec changes in the same commit**
## What does NOT need a spec
- Infrastructure-only projects (Helm values, Kustomize manifests, Ansible playbooks) — declarative, not behavioural
- Single-script utilities — a well-commented script with a test is sufficient
- Documentation-only changes

28
claude/status-line.md Normal file
View File

@@ -0,0 +1,28 @@
# Status Line
A persistent bar at the bottom of Claude Code shows the current topic, model, and context usage: `[Model Name] topic | N% context`.
## Setting the topic
After the user selects a project or describes their task (i.e., after the first response where the status line has had a chance to run), set the topic:
```bash
~/.claude/status/set-topic.sh "$(pwd)" "project-name: brief task description"
```
Examples:
- `~/.claude/status/set-topic.sh "$(pwd)" "brainiac-app: M2 web frontend"`
- `~/.claude/status/set-topic.sh "$(pwd)" "cluster-bootstrap: Cilium upgrade"`
- `~/.claude/status/set-topic.sh "$(pwd)" "General chat"`
## When to update
- **Session start:** set the topic once the user picks a project or task
- **Focus change:** update if the user shifts to a different project or task mid-session
- **Keep it short:** aim for `project: task` format, under ~40 characters
## How it works
The status line script (`scripts/statusline.sh`) runs after each assistant message. It writes the session ID to `/tmp/claude-session-id-<md5 of cwd>`, which `set-topic.sh` reads to find the correct per-session topic file at `~/.claude/status/<session-id>/claude-topic.txt`.
Early calls are safe: if `set-topic.sh` is called before the status line has run (first message), the topic is queued to a pending file and automatically applied when the status line first runs after the next response.