Skip to content

go-yfinance v1.6.1 Maintenance Progress

Last Updated: 2026-08-27

Overview

This document tracks the Go-specific v1.6.1 maintenance release built on the Python yfinance v1.6.0 parity baseline. It packages the authentication hardening already merged through go-yfinance PR #13 and adapts the valid parts of contributor PR #11 onto the current main before Python yfinance v1.7.0 parity work begins.

v1.6.1 does not claim Python yfinance v1.6.1 parity. Its purpose is to release bounded safety and correctness fixes without mixing them into the larger v1.7.0 upstream-parity change set.

Branch Structure

main
 └── feature/v1.6.1-maintenance

After v1.6.1 is merged, verified on main, and tagged, the v1.7.0 parity branch must start from that final main commit.

Source And Attribution

  • Source proposal: go-yfinance PR #11, refactor: add data immutability, implement timezone caching, and enhance ..., by shubhbham.
  • Current baseline: main at 164f6cb, including PR #13 authentication hardening after the v1.6.0 tag.
  • Preserve contributor attribution in the implementation commits and release notes. Do not merge PR #11 directly because its branch predates the current authentication implementation and its review findings require rework.

Scope Decision

Area Disposition Reason
Protobuf bounds Reimplement Compare lengths as uint64 before conversion and reject malformed varints without panicking on 32-bit or 64-bit targets.
WebSocket lifecycle Reimplement Make normal close idempotent and non-erroring; cancel reconnects and stop listener/heartbeat goroutines without channel-close races.
Holders/news cache immutability Reimplement Return independent values, including nested pointers and slices such as Thumbnail.Resolutions.
Multiple cookies Reassess and implement if representable Verify how CycleTLS represents repeated Set-Cookie headers; avoid newline-only parsing and Expires comma corruption. Integrate with current PR #13 auth behavior.
Timezone location cache Deferred This is an unmeasured optimization with global lifetime, growth, and test-isolation questions rather than a correctness fix. Track separately after benchmarking.

Implementation Plan

Phase 0: Baseline and test design

  • [x] Confirm the exact PR #11 diff and current-main overlap for every target file.
  • [x] Record current behavior with focused regression tests before changing implementation where practical.
  • [x] Keep protobuf, WebSocket, cache, and cookie work independently testable and independently committable.

Phase 1: Protobuf decoder hardening

  • [x] Reject overlong and overflowing varints.
  • [x] In readString and length-delimited skipField, compare the decoded uint64 length with the non-negative remaining byte count before converting to int.
  • [x] Add truncated, maximum-length, overflow, unknown-field, and no-panic regression tests; include architecture-sensitive cases where feasible.
  • [x] Commit independently with contributor attribution (5055a5b).

Phase 2: WebSocket lifecycle

  • [x] Define explicit states and contracts for connect, listen, reconnect, normal close, repeated close, and reuse after close.
  • [x] Ensure Close during reconnect delay prevents a later connection.
  • [x] Ensure normal close makes Listen return nil without invoking the error handler.
  • [x] Stop heartbeat and listener goroutines exactly once and avoid double channel close, blocked reads, and concurrent writes.
  • [x] Add deterministic local WebSocket-server tests, including race-focused close/reconnect cases.
  • [x] Commit independently with contributor attribution (31d72c4).

Phase 3: Cache immutability

  • [x] Add clone helpers or equivalent focused copying for holders and news return values.
  • [x] Copy all mutable nested state, including insider date pointers, NewsThumbnail, Thumbnail.Resolutions, and RelatedTickers where present.
  • [x] Test both first-fetch and cache-hit paths by mutating returned values and proving subsequent results are unchanged.
  • [x] Run focused race tests for the affected package and caller mutation.
  • [x] Commit independently with contributor attribution (7f9ae52).
  • [x] Inspect the pinned CycleTLS response-header implementation and create fixtures for its actual repeated-header representation.
  • [x] Determine whether Response.Headers map[string]string preserves all Set-Cookie values. If it cannot, fix the response boundary rather than guessing in extractCookies.
  • [x] Parse multiple cookies without splitting an Expires attribute at its comma, preserve distinct cookie names, and retain current error classification and sanitization.
  • [x] Add tests for multiple cookies, mixed header casing, cookie attributes, replacement, and auth strategy fallback.
  • [x] Commit independently with contributor attribution (42032e0). If the transport representation cannot be fixed safely within v1.6.1, document and defer this item rather than shipping a partial parser.

Phase 5: Cross-verification and release documentation

  • [x] Run an independent Claude Code and Codex review when Claude availability is confirmed. Each verifier should derive findings from the current code and PR intent without seeing the other's report; reconcile findings against code and tests. Result: Claude independently reported eight actionable findings. Seven implementation findings were accepted and fixed in dec679e: bounded WebSocket writes without holding the lifecycle mutex, per-listener heartbeat cleanup, positive heartbeat-interval validation, known-field protobuf wire validation, count/tab-aware news caching, cookie collection at every CSRF stage, and deletion of expired empty-value cookies. Its CycleTLS delimiter fixture observation was also applied to the test. Focused race tests passed, and Claude's follow-up confirmed every accepted finding was resolved.

One follow-up suggestion was rejected: skipping a known protobuf field when its wire type conflicts with the schema would turn malformed or schema-incompatible input into a partial successful decode. The decoder intentionally returns an explicit error for a known field with an invalid wire type; unknown field numbers remain forward-compatible through skipField. - [x] Add docs/releases/RELEASE_NOTES_v1.6.1.md and state clearly that this is a Go-specific maintenance release on the Python yfinance v1.6.0 baseline. - [x] Update README/docs parity and release navigation only where required, regenerate GoDoc/API docs, and keep README.md and docs/index.md synced. - [x] Record deferred timezone caching and any deferred cookie limitation with reasons.

Verification And Release Gates

Before merging to main or tagging, follow docs/development/release-readiness-checklist.md in full:

  • [x] GOCACHE=/tmp/go-build-cache go test ./...
  • [x] GOCACHE=/tmp/go-build-cache go vet ./...
  • [x] GOLANGCI_LINT_CACHE=/tmp/golangci-lint-cache golangci-lint run ./...
  • [x] make lint
  • [x] GOCACHE=/tmp/go-build-cache go test -v -race -coverprofile=coverage.out ./...
  • [x] GOMARKDOC=/tmp/gobin/gomarkdoc make docs
  • [x] cp README.md docs/index.md
  • [x] make docs-build
  • [x] git diff --check
  • [x] Verify local commands still match .github/workflows/test.yml and .github/workflows/docs.yml.
  • [x] Keep generated documentation and workflow corrections in explicit, separate commits.
  • [x] Merge the verified branch to main, confirm remote CI on the final main commit, and only then create and publish v1.6.1.

Verification record

  • Local toolchain: Go 1.27.0; the module and CI minimum remain Go 1.22.
  • go test ./... and go vet ./...: passed, including live Yahoo integration tests when rerun outside the DNS-restricted sandbox.
  • Full race and coverage gate: passed for all packages, including live Yahoo integration tests.
  • Focused go test -race ./pkg/live, ./pkg/ticker, and ./pkg/client: passed.
  • Linux/386 pkg/live test binary cross-compilation: passed, covering the architecture-sensitive protobuf conversion path.
  • golangci-lint v2.13.1 and make lint: 0 issues.
  • API generation, README/docs sync, MkDocs build, and git diff --check: passed. MkDocs emitted only its upstream MkDocs 2.0 advisory and the existing unrecognized relative LICENSE link notice.
  • CI drift found and fixed separately in 556b559: both test jobs now use Go 1.22, matching go.mod and the docs workflow.
  • Claude/Codex cross-verification findings were reconciled in dec679e; the post-fix Claude review found no remaining accepted defect.
  • PR #15 merged to main as 5478a4b. The merge commit's Tests workflow (test and lint jobs) and Generate Documentation & Deploy Site workflow both completed successfully. The docs workflow then committed its canonical generated API output as 247a71e; that commit changes generated docs only.

Guardrails

  • Do not merge or cherry-pick PR #11 wholesale.
  • Do not include timezone caching in v1.6.1 without a separate measured design decision.
  • Do not weaken the PR #13 authentication classification or sanitization.
  • Do not treat a passing existing test suite as sufficient for the reviewed PR defects; each accepted behavior needs a regression test.
  • Do not move or recreate an existing tag, and do not tag from the feature branch.
  • Keep unrelated worktree changes out of maintenance and release commits.