Depos

Dependency notes for Java and Kotlin

A pom.xml or a Gradle build file says which version of a library a service uses. It does not say that the Jackson modules have to move together, that the service is held on an older line until a migration lands, or which integration tests show an upgrade is safe. An XML comment or a // line has room for a phrase, not for that history.

Depos keeps a note for each dependency beside its build file — .depos/maven/DEPENDENCY-NOTES.md for Maven, .depos/gradle/DEPENDENCY-NOTES.md for Gradle — and shows it on the dependency in the editor. Gradle builds in the Groovy and the Kotlin DSL are both read.

What Depos reads

Maven

  • Manifest: pom.xml
  • Notes file: .depos/maven/DEPENDENCY-NOTES.md
  • Section heading: groupId:artifactId: ## org.slf4j:slf4j-api

Depos reads the <dependencies> of the project and its profiles, not <dependencyManagement> or plugin dependencies. Parent POMs are not read.

Gradle

  • Manifest: build.gradle, build.gradle.kts
  • Notes file: .depos/gradle/DEPENDENCY-NOTES.md
  • Section heading: group:name or the catalog alias: ## org.slf4j:slf4j-api, ## libs.junit.jupiter

Depos reads module coordinates and libs.* aliases in a dependencies block, not plugins, constraints, project(…), files(…) or catalog bundles. The script is never run, so a dependency added by code is not seen.

Depos never runs Maven or Gradle, and it does not resolve parent POMs, BOMs or libs.versions.toml. A note belongs to the dependency as the build file writes it.

Example

<dependencies>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.18.2</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.18.2</version>
  </dependency>
</dependencies>

.depos/maven/DEPENDENCY-NOTES.md:

## com.fasterxml.jackson.core:jackson-databind

JSON for the REST API and the Kafka payloads. Upgrade every Jackson artifact together.

### Agent notes

- purpose: JSON mapping for the REST API and the Kafka message payloads
- bump-with: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
- verify: `mvn -pl api test` and the contract tests (`mvn -Pcontract verify`)
- verified: 2.18.2

In a Gradle build, a version-catalog alias is a note key of its own:

dependencies {
    implementation("org.slf4j:slf4j-api:2.0.16")
    testImplementation(libs.junit.jupiter)
}

Its sections in .depos/gradle/DEPENDENCY-NOTES.md are ## libs.junit.jupiter and ## org.slf4j:slf4j-api.

Comments in pom.xml and Gradle builds

<dependencies>
  <!-- jackson-databind: upgrade every Jackson artifact together -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.18.2</version>
  </dependency>
</dependencies>

A comment in pom.xml is an XML comment, <!-- … -->, and it cannot contain --. A comment that mentions a command-line flag breaks the build: with <!-- build with --offline -->, Maven stops with Non-parseable POM … in comment after two dashes (--) next character must be > not o. For the same reason, a block that already holds a comment cannot be commented out.

Gradle build files take // and /* */ comments, and the version catalog, gradle/libs.versions.toml, takes #. Gradle can also carry a reason of its own, which gradle dependencyInsight prints as Was requested: …:

dependencies {
    implementation("org.slf4j:slf4j-api") {
        version { strictly("2.0.16") }
        because("the logging backend is certified against 2.0.16 (OPS-41)")
    }
}

Pinning a version

In Maven, <version>2.18.2</version> is a soft requirement. The nearest declaration in the dependency tree wins, so the version in your own pom beats the versions your dependencies ask for, unless one of them makes a hard requirement. [2.18.2] is a hard requirement: that version only, ahead of any soft one, and two hard requirements that disagree stop the build. <dependencyManagement> sets the version of a transitive dependency, but not of a direct one that names its own.

In Gradle, implementation("org.slf4j:slf4j-api:2.0.16") declares a required version, which conflict resolution may raise. strictly("2.0.16"), or the shorthand "org.slf4j:slf4j-api:2.0.16!!", rules out every other version; require, prefer and reject set softer limits, and the version catalog takes the same rich versions.

A hard requirement or a strictly says that a version is held, not why. The reason goes in the dependency's note as constraint:, with verify: for what to run once it moves.

For AI coding agents

An agent reads a dependency's section before it adds, upgrades or removes it. bump-with: lists the artifacts that have to move with it, and verify: the Maven or Gradle tasks to run afterwards. See the rules agents follow.