thismoon
CLAUDE.md2 starsChanged 10 days agoBSD-3-ClauseView on GitHub
Monorepo for the *.this platform: local web services, CLI tools, the shared webkit package, and their ralph recipes. A macOS-first local development toolbox — every service is a web UI + CLI for the human and (where it makes sense) an MCP server for agents, all on local data. Public under the BSD-3-Clause LICENSE.
- Installs packages
In this repository13 other files it gives its agents.
- mods/CLAUDE.mdCLAUDE.md
- webkit/CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- askSkill
- golang-proSkill
- golang-styleSkill
- handoffSkill
- harvestSkill
- humanizerSkill
- loomSkill
- presentSkill
- upgrade-noteSkill
- worklogSkill
The file
We split this CLAUDE.md into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 79
Every CLAUDE.md in the repo has a sibling AGENTS.md symlink pointing at it, so non-Claude agents (Codex and others that read AGENTS.md) …
- Very specific: line 128
Fold into the module: Delete the imported go.mod/go.sum, rewrite module paths to github.com/mad01/thismoon/..., switch webkit imports to …
- Very specific: line 131
Drop webkit versioning: Delete webkit_version.go, remove the webkit field from /version, delete the update-webkit Makefile target — there …
- Very specific: line 141
Register for release: Add the component to the packages map in release-please-config.json — CI fails the PR if a Makefile-bearing component …
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md - thismoon
Monorepo for the *.this platform: local web services, CLI tools, the shared webkit package, and their ralph recipes. A macOS-first local development toolbox — every service is a web UI + CLI for the human and (where it makes sense) an MCP server for agents, all on local data. Public under the BSD-3-Clause LICENSE.
Quick reference
| Task | Command |
| Build all components | make build |
| Test everything | make test |
| Install all components | make install-all |
| List components | make components |
| Format only the Go files changed against origin/main | make fmt-changed |
| Render sandbox settings from the access manifests | make sandbox-settings |
| Check the renders and expansion layers the way CI does | make sandbox-verify |
Layout
services/ *.this local web services (one directory per service; present also
runs as a shared instance in Kubernetes)
tools/ CLI tools installed to the local bin
webkit/ shared Go web UI package (in-module, no separate versioning)
kit/ shared Go packages for cross-tool functionality (one subpackage
per concern, e.g. kit/repofind for git repo discovery)
buildinfo/ shared build-metadata package (ldflags targets, /version handler)
buildinfo.mk Makefile fragment every component includes to inject it
recipes/ ralph recipes, consumed remotely via [[recipe_sources]];
recipes/lib holds shell helpers the launchers source (no
recipe.toml, so ralph never loads it as a recipe)
mods/ Claude Code mods (in-process plugin modules), one directory per
mod, listed by the root .claude-plugin/marketplace.json
skills/ agent skills (Claude + Codex), one directory per skill; each is
symlinked into ~/.claude/skills and ~/.agents/skills by its
paired recipe (skill-only recipes for skills with no binary)
evals/harness/ harness eval runner (not a component): fixed tasks through
claude -p with the user's hooks and MCP servers, scored on outcome
and cost, stored to compare before and after a change
examples/ worked private-config-repo layout (overlay recipes, example
global CLAUDE.md) — the reference for the machine-private layer
docs/adr/ architecture decision records
docs/GETTING-STARTED.md install guide: one tool via mise vs the fleet via ralph
docs/HOW-IT-FITS-TOGETHER.md fleet pitch, ralph vocabulary, rollout order
docs/MEMORY-STACK.md memory stores (auto memory, agent-memory, worklog,
handoff, events, moondb) and the belt hooks that surface them
docs/RELEASING.md release process (release-please, tags, artifacts, verification)
docs/UPGRADING.md actions a change needs on consuming machines (newest
first), added in the same PR as the change
docs/SECURITY-UPDATES.md how a dependency advisory reaches a fix: govulncheck,
Dependabot security updates, and the Go version bump
docs/SANDBOXING.md srt sandboxing: a walkthrough for sandboxing a new process,
then the srt-run launcher, access manifests and the settings
files rendered from them, the machine-local expansion layer,
spawn wrappers, and denial triage for sandboxed services and
MCP servers
docs/CONTAINER-BUILDS.md package-manager build steps (npm, pip, gem) in a throwaway
Apple container VM: the export-only pattern and the runtime setupConventions
- Single Go module:
github.com/mad01/thismoon, go 1.27.4. No nested go.mod files. - A component is a directory under
services/ortools/with its own Makefile exposingbuild,test, andinstalltargets. The root Makefile discovers and delegates to them. - Releases are per-component semver with
name/vX.Y.Ztags, cut by release-please manifest mode on merge to main. Artifact builds are a plain CI matrix job. - Build metadata is shared: a component Makefile sets
COMPONENT := <name>, doesinclude ../../buildinfo.mk, and links with$(BUILDINFO_LDFLAGS). Every component then reports the same four-key object (version,commit,tag,build_time) fromGET /versionand<binary> version -o json, while plain<binary> versionstays a bare token that status parses. - Build targets: darwin/arm64 only — the platform is macOS-focused (see docs/adr/0007; supersedes the target list in 0004).
- Release artifacts ship with checksums.txt and cosign keyless signatures; local installs use the "mad01 Local Signing" codesign identity, which
recipes/codesigncreates. - Code imported from another repo comes in clean (no git history); the import commit message records the source repo and SHA it came from.
- Recipes under
recipes/must use absolute or~-prefixedworking_dirin builds/packages — ralph resolves remote recipe paths against its sources cache, not the consuming machine's checkout. - Recipes are the public layer only: portable build/install, t-man-guarded hooks, skills. Machine-private wiring (
[[recipe_sources]]pins, MCP registration, host enables, env/secrets, config overlays) lives in the consuming repo as companion recipes. Harddepends_onon the platform foundations t-man and d-man is allowed; on anything else cross-source deps are banned. See docs/adr/0006. - Mods under
mods/are additive, not components: no skill, hook, or service may require one, and they carry no Makefile or release line. The consuming repo registers their marketplace, never this one (docs/adr/0021). - Every change lands through a PR: branch, push, PR, CI green, merge. For CI green, wait on the
ci-okjob's conclusion, not the full check list:gh pr checks --watchcan exit before the matrix jobs register. Never push to main directly; a GitHub ruleset and belt'sgit-push-mainguard both refuse it, and merging to main is the deploy (ralph pulls main on everyralph up). - Stores are plain JSON or JSONL files: single-writer serve, full state in memory, atomic temp-and-rename saves. An embedded database solves nothing the fleet has and costs git-diffable files you can read with cat and jq; bbolt was assessed and declined in 2026-07. Revisit only if a store outgrows memory, such as an unbounded events history. When several services need the same load and save code, share a package instead.
- Discovery surfaces stay in step with the code. Three places tell search engines and agents what the repo holds:
- The root
llms.txtindexes the docs for agents and LLM crawlers. A new, renamed, or removed component, skill, ordocs/*.mdguide changes its line there in the same PR. CI fails the PR when a line is missing or a link is dead. Keep each line to what the component does, in the words of its row in the README tables. - The README opening names what the tools cover in plain search words. Update that sentence when a component adds or drops a whole area (a new kind of scanner, a new store).
- The GitHub description and topics are set by hand with
gh repo editand no check covers them. Revisit them when the README opening changes.
- The root
- Install the secret-scanning pre-commit hook after cloning:
suspenders hook install. - Every
CLAUDE.mdin the repo has a siblingAGENTS.mdsymlink pointing at it, so non-Claude agents (Codex and others that readAGENTS.md) discover the same instructions. New components get the symlink alongside theCLAUDE.md.
Skills
The repo ships ten agent skills under skills/, one directory per skill. Each is a SKILL.md that Claude Code and Codex load on demand. The paired recipe under recipes/<skill>/ symlinks it into ~/.claude/skills and ~/.agents/skills when the fleet applies recipes, so a provisioned machine has it in every session. Invoke one explicitly with /<skill-name>, or let the agent load it when the task matches the skill's description.
| Skill | What it does | Backed by |
ask | Answers a question from the brain vault and cites the notes behind the answer, with each note's evidence grade and status. Read-only. | the brain MCP, with the brain CLI as fallback |
golang-pro | Go concurrency, channels, generics depth, pprof profiling, and gRPC — the specialist scope golang-style defers to. Vendored from jeffallan/claude-skills under MIT; skills/golang-pro/LICENSE carries the notice. | nothing (guidance only) |
golang-style | Idiomatic Go review and authoring — naming, package layout, error handling, the HTTP/CLI/store patterns used across this codebase. Covers every Go component here. | nothing (guidance only) |
handoff | Writes a cold-start handoff document and persists key learnings to memory so the next agent or session can continue work without re-discovering context. | nothing (guidance only; writes to ~/.handoff/ and durable memory) |
harvest | Saves a session's findings to the brain vault inbox as raw captures, by hand with /harvest or automatically at session end through the harvest tool's SessionEnd hook. | the brain MCP or CLI, and the harvest tool (tools/harvest) |
humanizer | Strips AI-writing tells from prose before it lands in docs, PR descriptions, or commit bodies. | the humanizer MCP for detection and voice profiling, plus humanizer_judge (LLM backend, Haiku 5.5 via a LiteLLM proxy or OpenRouter) for holistic judgment |
loom | Coordinates parallel sessions on one repo with git worktrees: each session claims its own worktree under ~/.worktrees/ and commits there. A single weaver session rebases the finished branches and lands them in order. | nothing (guidance only; creates worktrees under ~/.worktrees/) |
present | Generates a scrollable briefing page with fixation reading, graphs, and inline charts for digesting a work summary or research. | the present service (services/present) |
upgrade-note | Writes and checks an entry in docs/UPGRADING.md: the input to collect, when an entry is needed, the entry form and the result to report. | nothing (guidance only; go test ./kit/upgradenotes/ checks the form from a checkout) |
worklog | Saves and resumes cross-session work state keyed by ticket or topic, not by working directory. | the worklog MCP, with the worklog CLI as fallback |
Prerequisites: golang-pro, golang-style, handoff, loom, and upgrade-note need nothing beyond the checkout. The other five need their backing MCP or service registered: that wiring is machine-private and lives in the consuming repo alongside the recipe (see docs/adr/0006), not here. Without the backing MCP the skill still loads, but its tool-backed steps are unavailable.
Release process
Full reference: docs/RELEASING.md. The short version for working here:
- release-please (manifest mode) runs on merge to main, keyed by the
packagesmap inrelease-please-config.json. Conventional commits scoped by path drive per-component bumps. Merging a release PR cuts thename/vX.Y.Ztag + GitHub Release. The artifacts matrix builds darwin/arm64 tarballs with checksums.txt + cosign keyless bundle, natively on a macOS arm64 runner. csl builds with cgo for its tree-sitter grammars; everything else stays CGO_ENABLED=0. - Release PRs merge themselves: release.yml turns on auto-merge, so one lands once its required checks pass, and merge = release. Never hand-edit
.release-please-manifest.json. - Merge with squash. A PR whose commits bump different components by different types lands with a rebase merge, so release-please reads each commit with its own files; merge commits are off.
- The workflow authenticates with a token minted from the
mad01-release-pleaseGitHub App (secretsRELEASE_APP_IDandRELEASE_APP_PRIVATE_KEY, via actions/create-github-app-token). "Error adding to tree" or a missing release PR usually means the App lost Contents or Pull requests write access on this repo. Or the private-key secret no longer matches the App. - New component → must be added to
release-please-config.jsonand tollms.txt; CI fails the PR otherwise.
Shipping a change to machines
Two delivery paths, independent of each other:
- Fleet (ralph): consuming machines point a
[[recipe_sources]]stanza at this repo (ref = "main",update = true), so recipes merge asthismoon/<recipe>and everyralph uppulls main, rebuilds from source, and restarts services via t-man. Merging to main IS the deploy; no release tag needed. After merging recipe changes, verify with the service's/version— ralph can report ok while an old binary keeps running. - Artifacts (releases): the per-component tags/tarballs above serve
go installand manual downloads; the fleet does not consume them. - Changes that need an action on consuming machines (a migration, a re-import, a new hook entry in the consuming repo's settings template, an ordered
ralph up) ship with three things in the same PR. An entry indocs/UPGRADING.md, newest first, in the form that page describes: a dated heading, thenChange,Run,VerifyandSince.Rungets a "With ralph:" and a "Without ralph:" part when the steps differ.Sincereadsunreleasedat merge, ormain onlywhen no component release carries the change. Theupgrade-noteskill walks through it, andgo test ./kit/upgradenotes/checks the form in CI. The same steps in the PR body. A doctor check when the missing action is detectable. The fleet pulls main without reading release notes, so a CHANGELOG line alone reaches nobody.
Machine-private wiring (which .this hosts exist, MCP registration, env/secrets, config overlays) lives in the consuming repo as companion recipes layered over these — never add it here (docs/adr/0006).
Importing a service from another repo
The migration playbook, applied to every service brought in so far. Follow it in order; each step earned its place:
- Import clean.
git archive HEAD:<svc>from the source repo, extract intoservices/<svc>(ortools/<name>). No git history comes along; the import commit message records the source repo and SHA. - Fold into the module. Delete the imported
go.mod/go.sum, rewrite module paths togithub.com/mad01/thismoon/..., switch webkit imports to the in-module package. - Drop webkit versioning. Delete
webkit_version.go, remove thewebkitfield from/version, delete theupdate-webkitMakefile target — there is no pin here, the service compiles against the webkit committed beside it. - Rewrite docs.
service-info.yamlgetsspec.system: thismoon. Strip pin/bump language from the service CLAUDE.md; scan for names and hosts that must not appear in a public repo (help text and code comments too, not just docs). - Gates. Root
go mod tidy, then per-service build/vet/test/lint, rootmake test, and a clean-checkout gate:git archive HEAD | tar -xinto a temp dir, build and test there. - Register for release. Add the component to the
packagesmap inrelease-please-config.json— CI fails the PR if a Makefile-bearing component is missing from it. Add its line tollms.txtand its row to the README table in the same commit; CI checksllms.txttoo. - Recipe beside the service.
recipes/<svc>/recipe.tomlwith a sources-cacheworking_dir(see Conventions). Then the scratch-configralph up --dry-rungate: commit first, move the real sources cache aside, remove the test cache between runs, and put aconfig.local.tomlwith the right profiles beside the scratch config. - Two commits per service: one for the import, one for the recipe.
Cutover happens in the consuming repo (dotfiles): delete the old source dir +
recipe in one PR, keep item keys identical so ralph state carries over. Then a
single ralph up swaps the fleet. After it, pull the sources cache manually if
the recipes are newly merged, and verify each service's /version — ralph can
report ok while leaving the old binary in place.
Domain language
See CONTEXT-MAP.md for the glossaries: the root CONTEXT.md holds the repo-wide terms, and a service or skill keeps its own terms in a CONTEXT.md beside it. Check docs/adr/ before changing anything structural: the founding decisions are recorded there and are deliberate.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

