AGENTS.md — house rules for this repo

Read this before you write code here. It is short on purpose. If a rule needs a paragraph to justify it, it belongs in an ADR, not in this file.

Platform-specific rules live in platform/ and are additive. A language file plus a target file usually both apply:

Your diff touches Read
any .kt / .kts platform/AGENTS.kotlin.md
Android modules, Jetpack Compose + platform/AGENTS.android.md
shared/, expect/actual, wire contracts + platform/AGENTS.kmp.md
any .swift, Package.swift platform/AGENTS.swift.md
iosApp/, SwiftUI, UIKit, Xcode project + platform/AGENTS.ios.md
any .java, pom.xml platform/AGENTS.java.md
Spring Boot services (Java or Kotlin) + platform/AGENTS.spring.md
any .ts / .tsx / .js / .jsx, package.json platform/AGENTS.typescript.md
React components + platform/AGENTS.react.md

In this repo most work touches two of these at once. Read the base file plus every platform file your diff covers.

Where things live

Path What it is Room (blast radius)
shared/src/commonMain/ shared business logic, models, wire contracts Kitchen
shared/src/androidMain/ Android actual implementations Kitchen
shared/src/iosMain/ iOS actual implementations Kitchen
composeApp/ (or androidApp/) Android app shell, DI, navigation Living Room
iosApp/ Xcode project, SwiftUI shell, framework consumption Living Room
core/network/, core/auth/ HTTP, tokens, session Kitchen
core/wallet/, core/compliance/ balances, deposits, withdrawals, regulated flows Kitchen
core/designsystem/ tokens, Compose + SwiftUI style layer Living Room
feature/*/ one feature per module, Compose and/or shared Living Room
webApp/ (or web/) React / TypeScript front end Living Room
server/ Spring Boot services, Java or Kotlin Living Room
**/db/migration/ database migrations (Flyway / Liquibase) Kitchen
.claude/agent-memory/ agent memory; agents write here as they learn Living Room
agents/, skills/, .claude/, .codex/, .gemini/, .cursor/, .agents/ agent and skill definitions, one source plus generated copies per runtime Kitchen
docs/ the website shell (layout, CSS, one JS file, landing page); its content is the markdown next to it Living Room
sandbox/ spikes and prototypes Garage
tools/, scripts/oneoff/, analyses/, dashboards/ one-off scripts, dashboards, analyses Driveway
**/crypto/**, **/keystore/**, **/keychain/**, **/core-secure/**, … cryptography, secure storage, key material Safe-room (on top of its room)

Everything under shared/ is Kitchen by default. Two platforms and a server contract are downstream of every change in there, and a rename in commonMain is a production bug on a device you are not holding.

Rooms are defined in adr/0001-blast-radius-tiers.md and mapped, path by path, in .github/house/rooms.config.js. Kitchen and Safe-room paths have extra gates and cannot be changed by an agent without a named human reviewer.

Room labels are set by automation from the diff (ADR-0003). Tick every room your PR touches in the template; the only label you may add by hand is safe-room.

Before you say you are done

Run these. Not “the equivalent” — these.

./gradlew ktlintCheck detekt                              # all Kotlin, every target
./gradlew :shared:allTests                                # if you touched shared/
./gradlew :composeApp:testDebugUnitTest                   # Android side
./gradlew :shared:linkDebugFrameworkIosSimulatorArm64     # catches Swift-facing breakage
(cd iosApp && swiftformat --lint . && swiftlint --strict)  # if you touched Swift
swift test --package-path <package>                       # if you touched a Swift package
./gradlew spotlessCheck test                              # if you touched Java or a JVM service (Maven: ./mvnw -B verify)
(cd webApp && <pm> run lint && <pm> run typecheck && <pm> run format:check && <pm> test)  # if you touched JS/TS

If you changed shared/src/commonMain you run the iOS framework link too. Not optional: Kotlin that compiles for Android can still break the Swift API.

A change is done when: the commands above pass, the diff has no unrelated formatting churn, and you can state in one sentence why the change belongs in this repo.

Anti-patterns in THIS codebase

These are the mistakes that actually happen here, not general advice.

When you are unsure

Ask. Do not invent. Specifically: if you cannot find an existing pattern for what you are about to do, stop and open a question on the PR or in the issue rather than establishing a new pattern silently.

Never do without a human explicitly asking in the current conversation:

Provenance

Every PR states which model or tool produced the change and roughly how much of the diff is generated. See .github/pull_request_template.md. This is not a judgement, it is triage information for reviewers.