Publish a stable iw-cli core API so downstream tools don't break on every change #398
Labels
No labels
bug
contract
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
iterative-works/iw-cli#398
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Downstream tools compile directly against iw-cli's internal
coresource treeand break, at the consumer's compile time, whenever any
coresignaturechanges. There is no published, versioned, stable API surface and no contract
about what is safe to depend on.
Concretely, kanon's
iw-pluginScala commands (batch-implement,implement,autonomous-bootstrap) and hooks wildcard-import three entire internalpackages:
They are built against the local
coresources (via using-directives), so thede-facto public API is "everything in those packages" — undocumented, unversioned,
and free to change.
Concrete incident that triggered this
IW-389 (Forgejo support) made a correct, intentional change to
core/model/ForgeType.scala:def cliTool: String→def cliTool: Option[String]def installUrl: String→def installUrl: Option[String]Forgejocase to theForgeTypeenumThat is the right model — Forgejo has no CLI binary. But it silently broke
kanon's
batch-implement.scala:Found: Option[String], Required: Stringat the forge-CLIpre-flight check;
match(the newForgejoenum case) in themerged-phase catch-up path → would have been a runtime
MatchError.Fixed downstream in kanon, but only after it broke in the field. Every future
corechange carries the same risk for every consumer.Root cause
No stability contract between
coreand its consumers:What we want
A stable, published API that downstream tools can pin, so internal refactors
do not break them with every change.
Options to explore (not prescribing a solution)
surface (the symbols plugins actually use — e.g.
ForgeType,IssueId,IssueTrackerType,ProjectContext,Output,ProcessAdapter,GitAdapter,ReviewStateAdapter,MarkdownTaskParser, theBatchImplementhelpers,
PhaseMergeduration parsing, …). Treat everything else asprivate/internal.on a released version instead of local
coresource via using-directives.compatibility check (e.g. MiMa) in CI so breaking changes are caught before
release.
exhaustive
matchin consumers. Document the additive-change policy and/orprovide helper combinators so consumers don't pattern-match raw enums.
Acceptance criteria
expected to depend on, with everything else marked internal.
version.
enum additions, etc.).
iw-plugincommands migrated to depend on the published surfaceinstead of local
coresource.References
iw-plugin/commands/batch-implement.scala— the broken consumer.