splice
AGENTS.md122 starsChanged 18 days agoApache-2.0View on GitHub
This document provides instructions for AI coding agents (GitHub Copilot, Claude Code, and others) to follow when assisting with development in this repository. Every contribution must be tested in an automated test. For further details see the Testing README.
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 31,542 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.
In this repository4 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ci-triageSkill
- project-conventionsSkill
- sarif-unused-symbolsSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
29 rules. About 0 are common, 6 are distinctive, and 23 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
23
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Every contribution must be tested in an automated test.
- Very specific: line 19
Run sbt inside the direnv/nix dev shell, e.g.
- Very specific: line 20
Test code compiles with -Xfatal-warnings and -Wunused:privates/-Wunused:params, so an unused private member or parameter fails Test/compile.
- Very specific: line 23
Start only what the test needs: ./start-canton.sh -d -w for wallclock tests, -s for simtime tests.
- Very specific: line 26
Run a single test with sbt "apps-app/testOnly <FullyQualifiedSuite> -- -z \"<test name>\"".
- Very specific: line 28
Do not run bare sbt test; use testOnly and leave the full suite to CI.
- Very specific: line 31
If dependency resolution fails with a 404 for a Canton snapshot artifact (e.g.
- Very specific: line 36
All test cases of a suite extending IntegrationTest share one environment (IntegrationTestWithIsolatedEnvironment creates one per test …
- Very specific: line 48
If you make intentional changes in Daml code, run sbt damlDarsLockFileUpdate and commit the updated dars.lock file along with your dar …
- Distinctive: line 52
All Daml changes must be backwards-compatible.
- Distinctive: line 54
When adding to enums, make sure to only add further nullary constructors to types that only have nullary constructors.
- Very specific: line 60
When you change a Daml package, bump the version of that package and of every package that (transitively) depends on it, e.g.
- Very specific: line 66
When interacting with the Ledger API, convert Scala BigDecimals to Java BigDecimals.
- Very specific: line 71
All Protobuf definitions must use proto3.
- Distinctive: line 72
Avoid wrapping primitive types in a message structure unless future extensibility will likely be required.
- Very specific: line 73
Use a plural name for repeated fields.
- Very specific: line 74
Use string fields with a suffix contract_id to store contract ids.
- Very specific: line 75
Use string fields with a suffix party_id to store party ids.
- Distinctive: line 81
Only environment variables are fully supported for overriding configuration, not system properties.
- Very specific: line 82
When adding an app config option, check whether it also needs wiring through cluster/images/*/app.conf, cluster/compose/, cluster/helm/, …
- Very specific: line 86
Place .proto files in src/main/protobuf.
- Very specific: line 87
Prefer having a single .proto definition per service.
- Very specific: line 92
Use listXXX, acceptXXX, rejectXXX, withdrawXXX for managing proposals, requests etc.
- Very specific: line 93
Use the term amount, not quantity or number.
- Very specific: line 94
Use sender/receiver, not payer/payee.
- Very specific: line 106
Add the new package to build.sbt.
- Very specific: line 107
Ensure the package contains at least the scripts build, fix, check, and start.
- Distinctive: line 116
Use Scala types wherever possible.
- Very specific: line 128
Every commit needs a DCO Signed-off-by: line.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 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
Agent Instructions
This document provides instructions for AI coding agents (GitHub Copilot, Claude Code, and others) to follow when assisting with development in this repository.
Repository Overview
apps/holds the Scala backends (packages underorg.lfdecentralizedtrust.splice) and React frontends:validator(also serves the wallet and ANS backends),sv,scan,splitwell, the sharedcommon(apps-common;apps/common/svis SV-specific), andapp(apps-app: the release bundle, entry pointSpliceApp.scala, and the integration tests).- Stores ingest the ledger update stream asynchronously. Automation runs as
*Triggerclasses that react to ledger state and submit follow-up commands. daml/holds the Daml packages, one sbt project each.token-standard/defines the CIP-0056 token standard APIs, whichdaml/splice-amuletimplements.canton/is a copy of open-source Canton, not Splice code. Avoid editing it; if you must, record the change inCANTON_CODE_CHANGES.md(see "Bumping Our Canton fork" in MAINTENANCE.md).cluster/holds the Helm charts, Pulumi deployment code, and Docker Compose setup.
Testing
Every contribution must be tested in an automated test. For further details see the Testing README.
Building and Running Tests
- Run
sbtinside the direnv/nix dev shell, e.g.direnv exec . sbt -batch "apps-scan/testOnly <FullyQualifiedSuite>".-batchavoids the interactive prompt; redirect output to a file and grep for^\[error\]andTests:. - Test code compiles with
-Xfatal-warningsand-Wunused:privates/-Wunused:params, so an unused private member or parameter failsTest/compile. - To format specific files:
sbt "scalafmtOnly <files...>". - Integration tests under
apps/app/src/testneed a running Canton from./start-canton.sh, including suites based onIntegrationTestWithIsolatedEnvironment. Without it they fail withjava.io.FileNotFoundException: canton.tokens.- Start only what the test needs:
./start-canton.sh -d -wfor wallclock tests,-sfor simtime tests. Add-p localto use a local Postgres instead of Docker. start-canton.shmanages Postgres itself; do not start it separately withscripts/postgres.sh. Stop with./stop-canton.sh(pass the same Postgres mode, e.g../stop-canton.sh local).- Restart Canton (
./stop-canton.shthen./start-canton.sh) whenevernix/canton-sources.jsonchanges, e.g. after a checkout or rebase: it pins the Canton version thatstart-canton.shruns. - Run a single test with
sbt "apps-app/testOnly <FullyQualifiedSuite> -- -z \"<test name>\"". - Suites named
*FrontendIntegrationTestdrive the frontends through Selenium and also need./start-frontends.sh.
- Start only what the test needs:
- Do not run bare
sbt test; usetestOnlyand leave the full suite to CI. - CI runs
sbt checkErrorsafter tests, which fails on WARN/ERROR lines in the logs underlog/that don't matchproject/ignore-patterns/. The logs are not rotated, so stale errors from earlier runs also show up; clearlog/before a run you want to check. The main logs arelog/canton_network_test.clog(test run and Splice apps) andlog/canton.clog/log/canton-simtime.clog(Canton). sbt formatFixapplies scalafmt, scalafix, npm fixes and copyright headers (make formatadditionally formats cluster code).sbt lintruns the static checks; note that itsscalafixAllstep can rewrite files.- If dependency resolution fails with a 404 for a Canton snapshot artifact (e.g.
com.daml:bindings-java:<version>-snapshot...), the pinned snapshot has likely expired; rebase onto the latestmainand reload direnv.
Writing Integration Tests
- Stores ingest asynchronously: never assert on store state immediately after an action. Use
actAndCheck,eventuallyoreventuallySucceeds. - All test cases of a suite extending
IntegrationTestshare one environment (IntegrationTestWithIsolatedEnvironmentcreates one per test case). UseperTestCaseName(...)for party and other names to avoid collisions between test cases. - Wrap actions that are expected to log warnings or errors in
loggerFactory.assertLogs(or a relatedSuppressingLoggermethod); otherwisecheckErrorsfails in CI. - Simulated-time tests mix in
TimeTestUtiland move the clock withadvanceTimeand related helpers.
DB Migrations
Refer to the main README on migrations. Most importantly, never modify a deployed migration script, not even its comments; add a new migration instead.
Daml Changes
Daml Lock Files
If you make intentional changes in Daml code, run sbt damlDarsLockFileUpdate and commit the updated dars.lock file along with your dar changes.
Backwards-compatible Daml changes
All Daml changes must be backwards-compatible. See the Smart Contract Upgrading Reference from the Canton docs.
When adding to enums, make sure to only add further nullary constructors to types that only have nullary constructors.
Backends must keep working while only an older Daml version is voted in. Guard version-specific behavior, and tag tests that need a newer package with the matching scalatest tag from org.lfdecentralizedtrust.splice.util.scalatesttags (e.g. SpliceAmulet_0_1_19) so that the compatibility runs skip them. See "Daml Version Bump" and the sections after it in DEVELOPMENT.md.
Package Versions
When you change a Daml package, bump the version of that package and of every package that (transitively) depends on it, e.g. with git fetch origin && sbt damlBumpPackageVersions. Then run sbt updateDarResources; CI checks that the generated DarResources.scala files are up to date.
Daml Numerics
- To represent Daml
Numerics for any user facing APIs (console commands), usescala.math.BigDecimal. - To represent Daml
Numerics in Protobuf, usestrings. Conversions to and fromstrings should occur viaorg.lfdecentralizedtrust.splice.util.Proto.encode/tryDecode. - When interacting with the Ledger API, convert Scala
BigDecimals to JavaBigDecimals. - Refer to the
wallet.tapcommand implementation for the canonical handling of Daml Numerics.
Message Definitions
- All Protobuf definitions must use
proto3. - Avoid wrapping primitive types in a message structure unless future extensibility will likely be required.
- Use a plural name for
repeatedfields. - Use
stringfields with a suffixcontract_idto store contract ids. - Use
stringfields with a suffixparty_idto store party ids.
Config Parameters
- Name flags as
enableXXXinstead ofdisableXXXto avoid a double negation. - Scala config fields are camelCase and map to kebab-case HOCON keys automatically.
- Only environment variables are fully supported for overriding configuration, not system properties.
- When adding an app config option, check whether it also needs wiring through
cluster/images/*/app.conf,cluster/compose/,cluster/helm/,cluster/pulumi/anddocs/src/. After cluster changes, regeneratecluster/expected/withmake update-expected.
Code Layout
- Place
.protofiles insrc/main/protobuf. - Prefer having a single
.protodefinition per service. - Refer to generated Protobuf classes with a package prefix, e.g.,
v0.MyMessageinstead ofMyMessage.
Domain Specific Naming
- Use
listXXX,acceptXXX,rejectXXX,withdrawXXXfor managing proposals, requests etc. - Use the term
amount, notquantityornumber. - Use
sender/receiver, notpayer/payee.
Frontend Code
Frontend code projects are managed via npm workspaces.
The generated Daml TS bindings (apps/common/frontend/daml.js) and OpenAPI clients (*/openapi-ts-client) are not npm dependencies or workspaces: apps/generated-packages.json lists them and apps/scripts/link-generated-packages.mjs links them into node_modules on npm install. A new OpenAPI client must be added to that file; a Daml version bump updates its aliases (sbt damlBumpPackageVersions does this).
New Packages
To add a new package to the workspace:
- Register its directory in the root-level
apps/package.jsonworkspaces key. The directory must contain its ownpackage.json. - Add the new package to
build.sbt. - Ensure the package contains at least the scripts
build,fix,check, andstart. - The new package will need its own
tsconfig.jsonfile that inherits from the root tsconfig.
Common Libs
The common-frontend package (@canton-network/splice-common-frontend) contains common code in apps/common/frontend. You can add reusable utility functions, React components, or shared config here. Ensure anything added is exposed via the library's entrypoint, index.ts.
Conversions between Java & Scala types
- Use Scala types wherever possible.
- Delay the conversion to Java types until the last possible point.
- Convert from Java to Scala as early as possible.
- To convert, import
scala.jdk.CollectionConverters.*and use theasScalaandasJavamethods.
Scala
- Production code bans partial
Iterablemethods such ashead,last,maxandreduce(wartremoverIterableOps); useheadOption,maxOption,foldLeftetc. instead. The exception is for theNonEmptytype, which features total versions of these such ashead1.
Contributing
- Every commit needs a DCO
Signed-off-by:line; usegit commit -s. - PRs are squash-merged, so the PR title and description become the commit message.
- On branches in this repository, CI only runs if the last commit message contains
[ci](or[static]for static checks only). See TESTING.md for other tags and for cluster tests.
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.

