REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
1
V2 Migration Plan
ScuroNeko edited this page 2026-08-19 14:59:10 +03:00

DRAFT: Laniakea v2 Migration Plan

Russian version: V2-Migration-Plan-RU

Status: DRAFT. This page describes a possible v2 direction, not an implemented or committed public API. Names, signatures, defaults, and release scope are subject to change.

Laniakea v1.2.0 preserves the v1 public API while adding compatibility bridges for stricter, context-aware, and bounded behavior. A future v2 can use those bridges to remove ambiguous contracts and legacy aliases through a mostly mechanical migration instead of mixing breaking cleanup into a minor release.

Decisions already made

  • v1.2.0 must remain source-compatible with v1 wherever the existing feature works.
  • Breaking changes listed here are deferred to a new major version.
  • New v1.2 code should prefer the compatibility APIs shown below to reduce future migration work.
  • Telegram wire compatibility is not intentionally broken; corrected JSON field names are already a v1.2 bug fix.
  • This draft does not define a v2 release date or guarantee that every proposal will ship.

Compatibility preparation in v1.2.0

Area Preferred v1.2 API Compatibility retained in v1.2
Poll voters PollAnswer.VoterUser() and VoterChatInfo() User and VoterChat remain value fields
Runners NewContextRunner(...) RunnerFn and NewRunner(...) remain available
Callback payloads CallbackData.EncodeValidated(...) Encode(...) keeps its error-free signature
Keyboard construction button Build()/Validate() and keyboard GetValidated()/Validate() Existing fluent builders and Get() remain available
Rich messages UnmarshalRichMessageStrict(...) for untrusted input UnmarshalRichMessage(...) remains permissive for an empty root
File downloads GetFileByLinkLimit(...) or OpenFileByLink(...) Unbounded GetFileByLink(...) remains available
Reaction cleanup DeleteAllMessageReactionsWithContext(...) Misspelled singular alias remains deprecated
Telegram field names Use the existing Go fields with corrected wire keys Source-level field names remain unchanged

Adopting the preferred column in v1.2 should make most v2 changes compile-time-visible and straightforward to apply.

Proposed breaking changes

1. Make optional poll voters explicit

Change PollAnswer.User and PollAnswer.VoterChat from value fields to pointers. Telegram sends exactly one voter variant, and pointers represent absence without relying on a zero ID.

Migration direction:

// v1.2-compatible preparation
user, ok := answer.VoterUser()
if ok {
	use(user)
}

// possible v2 form
if answer.User != nil {
	use(answer.User)
}

2. Make runner cancellation mandatory

Make context.Context part of the primary runner callback contract. Long-running and I/O-bound work should stop with polling or webhook runtime cancellation.

Illustrative API only:

runner := laniakea.NewRunner("sync", func(ctx context.Context, bot *laniakea.Bot[*App]) error {
	return app.Sync(ctx)
})

The final names may instead retain NewContextRunner; this draft commits to context-aware behavior, not constructor spelling.

3. Make invalid keyboards unrepresentable by default

Move callback-data length checks, payload validation, and row-size validation into the normal construction path. Error-free fluent methods may be replaced or complemented by a builder that returns an error. Unlimited rows should require an explicit option rather than overloading maxRow <= 0.

The exact builder shape is still open. Existing v1.2 Build, Validate, EncodeValidated, and GetValidated methods are the migration bridge.

4. Use strict and bounded defaults

  • Make UnmarshalRichMessage(...) reject null, {}, and a missing or null blocks field by default.
  • Preserve unknown rich block objects losslessly instead of reducing them to a known text wrapper.
  • Remove or replace unbounded GetFileByLink(...); prefer a required byte limit or a streaming body.

These changes make untrusted input and remote downloads safer, but their exact error and fallback types remain open.

5. Remove deprecated compatibility names

  • Remove DeleteAllMessageReactionWithContext(...) in favor of DeleteAllMessageReactionsWithContext(...).
  • Consider the following exported field renames:
    • ChatFullInfo.AvailableReactionAvailableReactions;
    • ReplyParameters.QuoteParsingModeQuoteParseMode;
    • InputChecklist.OtherCanAddTasksOthersCanAddTasks;
    • InputChecklist.OtherCanMarkTasksAsDoneOthersCanMarkTasksAsDone.

The wire keys are already correct in v1.2. These proposals affect Go source names only.

Expected migration work

v1 call or field Preferred preparation now Possible v2 migration
answer.User.ID != 0 answer.VoterUser() nil-check answer.User
NewRunner(name, func(*Bot) error) NewContextRunner(name, func(context.Context, *Bot) error) use the primary context-aware constructor
keyboard.Get() keyboard.GetValidated() handle construction error from the default path
data.Encode(kind) data.EncodeValidated(kind) handle the returned validation error
UnmarshalRichMessage(data) for external data UnmarshalRichMessageStrict(data) strict behavior becomes the default
GetFileByLink(link) GetFileByLinkLimit(link, max) or OpenFileByLink(link) use bounded or streaming download only
singular reaction alias plural method no further source change

Open design decisions

  • What public type should preserve unknown rich objects for lossless round trips?
  • Should buffered file downloads require a caller-provided limit, provide a documented default, or be removed in favor of streaming?
  • Should any deprecated aliases survive one additional major cycle?
  • Should keyboard validation use immutable builders, error-returning mutation, or a final validation step?
  • Should renamed fields receive temporary accessors during v2 prereleases?
  • Which proposals belong in the first v2 release rather than a later v2 minor release?

Release gates

Before the first stable v2 release:

  1. Freeze the proposed public API and publish paired English/Russian migration guidance.
  2. Generate and review a complete public API diff against the latest v1 release.
  3. Add compile-focused migration examples and regression tests for every removed compatibility path.
  4. Verify Telegram JSON fixtures and unknown rich-object round trips.
  5. Define bounded download defaults and ownership rules for streaming response bodies.
  6. Resolve or explicitly defer every open decision on this page.
  7. Mark completed framework backlog items consistently in Framework-Backlog and the main repository CHANGELOG.md.