Files
gopasspw--gopass/docs/adr/A-12-pkg-api-stability.md
2026-07-13 12:27:58 +08:00

4.1 KiB
Raw Permalink Blame History

A-12: pkg/gopass API Stability Contract

Status: accepted
Source: GitHub Issue #3414


Background

ARCHITECTURE.md (lines 3743) documents that gopass applies semantic versioning to the CLI tool only, not the Go module. pkg/gopass is the documented integration point for external consumers (gopass-hibp, gopass-jsonapi, git-credential-gopass, gopass-summon-provider, and others). There is currently no documented contract for what constitutes a breaking change or how consumers will be notified.

A breaking change to pkg/gopass.Store, pkg/gopass.Secret, or related types can affect consumers silently — the module version does not increment, no changelog entry was mandated, and go get would pull the break without warning.


Decision

Implement Options B and C. They are complementary and together give consumers both runtime/source-level signals (C) and a reliable notification channel (B).

Option A (full module semver / v2 path) is deferred — the current team size makes the coordination overhead infeasible.

Option D (separate repository) is deferred for the same reasons.


Option B — "Best-effort stable" policy with mandatory changelog tags

Policy

pkg/gopass and its sub-packages are declared best-effort stable:

  • Additive changes (new exported symbols, new optional parameters via functional options) may appear in any release without prior notice.
  • Breaking changes (removal or signature change of an exported symbol, change of error semantics, change of an interface method set) require:
    1. A [PKG-BREAK] entry in the ## Next section of CHANGELOG.md describing what changed and how consumers should migrate.
    2. A minimum deprecation window of two minor releases or three months, whichever is longer, between the first deprecation notice and removal. During this window the old symbol must remain available (possibly with a // Deprecated: GoDoc comment pointing to the replacement).

Changelog tag convention

Breaking changes to pkg/ are tagged [PKG-BREAK] in CHANGELOG.md:

[PKG-BREAK] pkg/gopass: Remove Store.GetRevision — use Store.History instead (deprecated since 1.17.0)

The existing helpers/changelog generator reads CHANGELOG.md verbatim; no changes to that tool are needed. The [PKG-BREAK] tag is a pure text convention, consistent with existing tags such as [SECURITY], [BUGFIX], and [FEATURE].

Enforcement

  • Code reviewers must reject PRs that remove or change exported pkg/ symbols without a corresponding [PKG-BREAK] changelog entry and a prior deprecation notice.
  • The golangci-lint godot and godox rules already catch missing doc-comment periods and stray TODO/FIXME markers; no additional tooling is introduced.

Option C — Explicit stability annotations in package doc comments

Each package under pkg/gopass/ carries a doc comment that states its stability level.

Package Level Rationale
pkg/gopass best-effort stable Core interfaces; multiple known consumers
pkg/gopass/api best-effort stable Primary API implementation
pkg/gopass/secrets best-effort stable Secret types consumed by integrations
pkg/gopass/apimock testing helper — no stability guarantee Internal test double; consumers should copy or vendor it

The standard // Deprecated: GoDoc convention is used to signal pending removal of individual symbols; godoc and pkg.go.dev render these prominently.


Affected packages

pkg/gopass/, pkg/gopass/api/, pkg/gopass/apimock/, pkg/gopass/secrets/


Consequences

  • External integrators get a documented, reasonable stability promise without requiring a module-path change today.
  • The changelog [PKG-BREAK] tag gives integrators a single place to scan for migration work when upgrading.
  • The deprecation window gives integrators time to adapt before a symbol is removed.
  • The policy can be upgraded to full module semver in the future if maintainer capacity grows, without breaking any existing convention.