ripen
AGENTS.md0 starsChanged 55 days agoMITView on GitHub
This file is for agents and people working on Ripen's own source. If you are looking for how an agent operates Ripen, that is docs/agents.md. Ripen updates container images and refuses to guess. Every design decision bends toward doing nothing when something is unclear. If you are about to make Ripen more capable and less certain, stop and reconsider. All three must be clean. CI runs the same, plus govulncheck and a cross-compile of the release matrix. If you changed…
We split this AGENTS.md into the rules it gives an agent
8 rules. About 2 are common, 4 are distinctive, and 2 are very specific to this project.
≈2
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 38
All three must be clean. CI runs the same, plus govulncheck and a cross-compile of the release matrix.
- Very specific: line 41
If you changed anything in internal/response, regenerate the published schemas:
- Distinctive: line 55
Every paging Event corresponds to a durable state change already written.
- Distinctive: line 61
No second Proposal while one is pending review.
- Common: line 63
No Event payload field can carry a secret.
- Distinctive: line 79
Absence over permission: When something must not be possible, do not add a check that could be misconfigured — arrange for there to be …
- Distinctive: line 104
Test names are sentences about behavior:
- Common: line 136
Do not commit a real policy, API key, token, state database, certificate, or anything from a private host.
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.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
Working on Ripen
This file is for agents and people working on Ripen's own source. If you are
looking for how an agent operates Ripen, that is docs/agents.md.
What this project is
Ripen updates container images and refuses to guess. Every design decision bends toward doing nothing when something is unclear. If you are about to make Ripen more capable and less certain, stop and reconsider.
Getting around
| Path | What lives there |
cmd/ripen | The entry point. Nothing but a call into internal/cli. |
internal/updater | The Transaction. The deep module; everything else serves it. |
internal/backend | The orchestrator port every backend implements. |
internal/portainer, internal/compose | The two backends. |
internal/registry | A minimal read-only OCI registry client. |
internal/composefile | Reading and pinning Compose files as text. |
internal/state | SQLite, schema v1. The system of record. |
internal/app | Assembly, and the read payloads every surface shares. |
internal/cli, internal/mcpserver, internal/webui, internal/daemon | The four surfaces. |
internal/response | The Response envelope and its generated schemas. |
internal/event, internal/notifier | The Event stream and the webhook sink. |
docs/rework/SPEC.md | The design, the behavior inventory, and the invariants. |
CONTEXT.md | The vocabulary. Capitalized terms mean exactly what it says. |
Before you change anything
go test -race ./...
golangci-lint run ./...
gofmt -l .All three must be clean. CI runs the same, plus govulncheck and a cross-compile
of the release matrix.
If you changed anything in internal/response, regenerate the published schemas:
RIPEN_UPDATE_SCHEMAS=1 go test ./internal/response/A test asserts ripen schema and docs/schema/v1/ are identical, so forgetting
this fails the build rather than shipping a schema that lies.
The rules that are not negotiable
These are invariants, each with a dedicated test. If a change makes one of them fail, the change is wrong — not the test.
- Every paging Event corresponds to a durable state change already written.
- Nothing but protocol frames is written to stdout by
ripen mcp. ripen daemonwrites nothing to stdout.- MCP read-only mode registers no write tools and constructs no network clients.
actoris set by the surface and can never be supplied by a caller.- An open breaker blocks Apply and Proposal creation; Monitor and reads continue.
- No second Proposal while one is pending review.
ripen schemamatchesdocs/schema/v1/.- No Event payload field can carry a secret.
- A Compose socket resolving to the privileged Docker socket refuses at config load.
The full list, with the test that holds each one, is in
docs/rework/SPEC.md.
How code here is written
Ports and adapters. internal/updater talks to interfaces and touches no
network or filesystem. Every adapter is faked in tests. If you find yourself
adding an HTTP call to the engine, add a port instead.
Fail closed. New behavior chooses the outcome that does less. An unreadable
file, an unexpected service, a digest that cannot be proven: all of them stop the
Transaction. Prefer INELIGIBLE over acting on a guess.
Absence over permission. When something must not be possible, do not add a check that could be misconfigured — arrange for there to be nothing to call. This is why the MCP write tools are never registered rather than refused.
Names are the ones in CONTEXT.md. Transaction, Baseline, Candidate, Circuit
breaker, Proposal, Event, Notifier, Actor, Agent surface, Web UI. Do not
introduce a synonym.
No comments. The code carries its own explanation: name the thing, extract the function, make the constraint a type or a test. A comment is where an unclear design goes to be excused instead of fixed. If a rule matters, there is a test that fails when it is broken, and that test is where you look.
The only comments in this repository are the ones a tool reads: //go: and
//go:embed directives, // #nosec and //nolint suppressions with their
justification, the blank-import justification revive requires, and doc comments
on exported Go identifiers and exported TypeScript declarations, which are the
package's published API documentation. Nothing else.
Errors are lowercase and specific. They are read by operators in a terminal and by agents in an envelope. Say what was refused and, where useful, what would fix it.
Tests
Test names are sentences about behavior:
func TestMonitorRefusesToBaselineWhenAnUpdateIsAlreadyPending(t *testing.T)
func TestAnUnhealthySiblingBlocksTheUpdateEntirely(t *testing.T)Arrange, act, assert, with a blank line between the three. Table tests only where the cases really are the same test with different data.
Fakes belong in the package's *_test.go, not in production code. The engine's
fake backend behaves like a real one — it deploys by replacing the document it
holds and re-reads running digests out of that document's pins — so the pinning,
drift, and rollback paths are exercised end to end.
Where a test proves an invariant or claims a behavior-inventory row, say so in
its name, not in a comment above it. docs/rework/SPEC.md names the test that
holds each row, so the mapping lives there and in the test name.
The behavior inventory
docs/rework/SPEC.md carries a row for every behavior the Python implementation
had, each claimed by a named Go test. It is fully claimed, and it stays that way:
if you change behavior a row describes, update the row and the test together.
Pull requests
One thing per pull request. Say what changed and why in the body, name the invariants or inventory rows involved, and confirm the fail-closed behavior still holds. Regression tests are expected for anything touching update, timeout, health, rollback, or breaker handling.
Do not commit a real policy, API key, token, state database, certificate, or anything from a private host.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
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.

